summaryrefslogtreecommitdiff
path: root/platform
diff options
context:
space:
mode:
Diffstat (limited to 'platform')
-rw-r--r--platform/android/SCsub20
-rw-r--r--platform/android/audio_driver_jandroid.cpp3
-rw-r--r--platform/android/audio_driver_jandroid.h3
-rw-r--r--platform/android/audio_driver_opensl.cpp1
-rw-r--r--platform/android/audio_driver_opensl.h1
-rw-r--r--platform/android/build.gradle.template11
-rw-r--r--platform/android/detect.py182
-rw-r--r--platform/android/dir_access_android.cpp1
-rw-r--r--platform/android/dir_access_android.h1
-rw-r--r--platform/android/dir_access_jandroid.cpp1
-rw-r--r--platform/android/dir_access_jandroid.h3
-rw-r--r--platform/android/export/export.cpp118
-rw-r--r--platform/android/export/export.h1
-rw-r--r--platform/android/file_access_android.cpp1
-rw-r--r--platform/android/file_access_android.h1
-rw-r--r--platform/android/file_access_jandroid.cpp1
-rw-r--r--platform/android/file_access_jandroid.h3
-rw-r--r--platform/android/globals/global_defaults.cpp5
-rw-r--r--platform/android/globals/global_defaults.h1
-rw-r--r--platform/android/godot_android.cpp33
-rw-r--r--platform/android/java/gradle.properties17
-rw-r--r--platform/android/java/gradle/wrapper/gradle-wrapper.jarbin49896 -> 53636 bytes
-rw-r--r--platform/android/java/gradle/wrapper/gradle-wrapper.properties4
-rwxr-xr-xplatform/android/java/gradlew10
-rw-r--r--platform/android/java/res/drawable/icon.pngbin12675 -> 11155 bytes
-rw-r--r--platform/android/java/src/com/android/vending/licensing/ILicenseResultListener.java16
-rw-r--r--platform/android/java/src/com/android/vending/licensing/ILicensingService.java16
-rw-r--r--platform/android/java/src/com/google/android/vending/expansion/downloader/Helpers.java6
-rw-r--r--platform/android/java/src/com/google/android/vending/expansion/downloader/impl/DownloaderService.java4
-rw-r--r--platform/android/java/src/org/godotengine/godot/Dictionary.java1
-rw-r--r--platform/android/java/src/org/godotengine/godot/Godot.java3
-rw-r--r--platform/android/java/src/org/godotengine/godot/GodotDownloaderAlarmReceiver.java1
-rw-r--r--platform/android/java/src/org/godotengine/godot/GodotDownloaderService.java1
-rw-r--r--platform/android/java/src/org/godotengine/godot/GodotIO.java1
-rw-r--r--platform/android/java/src/org/godotengine/godot/GodotLib.java1
-rw-r--r--platform/android/java/src/org/godotengine/godot/GodotPaymentV3.java1
-rw-r--r--platform/android/java/src/org/godotengine/godot/GodotView.java1
-rw-r--r--platform/android/java/src/org/godotengine/godot/input/GodotEditText.java1
-rw-r--r--platform/android/java/src/org/godotengine/godot/input/GodotTextInputWrapper.java1
-rw-r--r--platform/android/java/src/org/godotengine/godot/payments/ConsumeTask.java1
-rw-r--r--platform/android/java/src/org/godotengine/godot/payments/GenericConsumeTask.java1
-rw-r--r--platform/android/java/src/org/godotengine/godot/payments/HandlePurchaseTask.java1
-rw-r--r--platform/android/java/src/org/godotengine/godot/payments/PaymentsCache.java1
-rw-r--r--platform/android/java/src/org/godotengine/godot/payments/PaymentsManager.java48
-rw-r--r--platform/android/java/src/org/godotengine/godot/payments/PurchaseTask.java1
-rw-r--r--platform/android/java/src/org/godotengine/godot/payments/ReleaseAllConsumablesTask.java1
-rw-r--r--platform/android/java/src/org/godotengine/godot/payments/ValidateTask.java1
-rw-r--r--platform/android/java/src/org/godotengine/godot/utils/Crypt.java1
-rw-r--r--platform/android/java/src/org/godotengine/godot/utils/CustomSSLSocketFactory.java1
-rw-r--r--platform/android/java/src/org/godotengine/godot/utils/HttpRequester.java1
-rw-r--r--platform/android/java/src/org/godotengine/godot/utils/RequestParams.java1
-rw-r--r--platform/android/java_class_wrapper.cpp15
-rw-r--r--platform/android/java_class_wrapper.h1
-rw-r--r--platform/android/java_glue.cpp58
-rw-r--r--platform/android/java_glue.h5
-rw-r--r--platform/android/os_android.cpp193
-rw-r--r--platform/android/os_android.h9
-rw-r--r--platform/android/platform_config.h1
-rw-r--r--platform/android/power_android.cpp28
-rw-r--r--platform/android/power_android.h1
-rw-r--r--platform/android/run_icon.pngbin0 -> 636 bytes
-rw-r--r--platform/android/thread_jandroid.cpp7
-rw-r--r--platform/android/thread_jandroid.h5
-rw-r--r--platform/bb10/SCsub23
-rw-r--r--platform/bb10/audio_driver_bb10.cpp253
-rw-r--r--platform/bb10/audio_driver_bb10.h76
-rw-r--r--platform/bb10/bar/bar-descriptor.xml53
-rw-r--r--platform/bb10/bar/icon.pngbin8809 -> 0 bytes
-rw-r--r--platform/bb10/bbutil.c513
-rw-r--r--platform/bb10/bbutil.h72
-rw-r--r--platform/bb10/detect.py92
-rw-r--r--platform/bb10/export/export.cpp828
-rw-r--r--platform/bb10/godot_bb10.cpp47
-rw-r--r--platform/bb10/logo.pngbin1244 -> 0 bytes
-rw-r--r--platform/bb10/os_bb10.cpp613
-rw-r--r--platform/bb10/os_bb10.h154
-rw-r--r--platform/bb10/payment_service.cpp148
-rw-r--r--platform/bb10/payment_service.h63
-rw-r--r--platform/bb10/platform_config.h29
-rw-r--r--platform/haiku/audio_driver_media_kit.cpp3
-rw-r--r--platform/haiku/audio_driver_media_kit.h1
-rw-r--r--platform/haiku/context_gl_haiku.cpp1
-rw-r--r--platform/haiku/context_gl_haiku.h1
-rw-r--r--platform/haiku/detect.py51
-rw-r--r--platform/haiku/godot_haiku.cpp1
-rw-r--r--platform/haiku/haiku_application.cpp1
-rw-r--r--platform/haiku/haiku_application.h1
-rw-r--r--platform/haiku/haiku_direct_window.cpp81
-rw-r--r--platform/haiku/haiku_direct_window.h2
-rw-r--r--platform/haiku/haiku_gl_view.cpp1
-rw-r--r--platform/haiku/haiku_gl_view.h1
-rw-r--r--platform/haiku/key_mapping_haiku.cpp3
-rw-r--r--platform/haiku/key_mapping_haiku.h1
-rw-r--r--platform/haiku/os_haiku.cpp8
-rw-r--r--platform/haiku/os_haiku.h5
-rw-r--r--platform/haiku/platform_config.h1
-rw-r--r--platform/haiku/power_haiku.cpp1
-rw-r--r--platform/haiku/power_haiku.h1
-rw-r--r--platform/iphone/SCsub10
-rw-r--r--platform/iphone/app_delegate.h1
-rw-r--r--platform/iphone/app_delegate.mm797
-rw-r--r--platform/iphone/audio_driver_iphone.cpp6
-rw-r--r--platform/iphone/audio_driver_iphone.h1
-rw-r--r--platform/iphone/detect.py196
-rw-r--r--platform/iphone/export/export.cpp366
-rw-r--r--platform/iphone/export/export.h (renamed from platform/bb10/export/export.h)3
-rw-r--r--platform/iphone/game_center.h1
-rw-r--r--platform/iphone/game_center.mm172
-rw-r--r--platform/iphone/gl_view.h1
-rw-r--r--[-rwxr-xr-x]platform/iphone/gl_view.mm349
-rw-r--r--platform/iphone/globals/global_defaults.cpp5
-rw-r--r--platform/iphone/globals/global_defaults.h1
-rw-r--r--platform/iphone/godot_iphone.cpp1
-rw-r--r--platform/iphone/icloud.h1
-rw-r--r--platform/iphone/icloud.mm271
-rw-r--r--platform/iphone/in_app_store.h1
-rw-r--r--platform/iphone/in_app_store.mm261
-rw-r--r--platform/iphone/ios.h3
-rw-r--r--platform/iphone/ios.mm21
-rw-r--r--platform/iphone/main.m12
-rw-r--r--platform/iphone/os_iphone.cpp155
-rw-r--r--platform/iphone/os_iphone.h20
-rw-r--r--platform/iphone/platform_config.h1
-rw-r--r--platform/iphone/platform_refcount.h1
-rw-r--r--platform/iphone/power_iphone.cpp1
-rw-r--r--platform/iphone/power_iphone.h1
-rw-r--r--platform/iphone/rasterizer_iphone.cpp2584
-rw-r--r--platform/iphone/rasterizer_iphone.h880
-rw-r--r--platform/iphone/sem_iphone.cpp1
-rw-r--r--platform/iphone/sem_iphone.h1
-rw-r--r--platform/iphone/view_controller.h1
-rw-r--r--platform/iphone/view_controller.mm83
-rw-r--r--platform/javascript/SCsub41
-rw-r--r--platform/javascript/audio_driver_javascript.cpp1
-rw-r--r--platform/javascript/audio_driver_javascript.h1
-rw-r--r--platform/javascript/audio_server_javascript.cpp1
-rw-r--r--platform/javascript/audio_server_javascript.h1
-rw-r--r--platform/javascript/detect.py62
-rw-r--r--platform/javascript/dom_keys.h3
-rw-r--r--platform/javascript/export/export.cpp488
-rw-r--r--platform/javascript/export/export.h1
-rw-r--r--platform/javascript/godot_shell.html203
-rw-r--r--platform/javascript/javascript_eval.cpp1
-rw-r--r--platform/javascript/javascript_eval.h1
-rw-r--r--platform/javascript/javascript_main.cpp154
-rw-r--r--platform/javascript/os_javascript.cpp796
-rw-r--r--platform/javascript/os_javascript.h40
-rw-r--r--platform/javascript/platform_config.h1
-rw-r--r--platform/javascript/power_javascript.cpp1
-rw-r--r--platform/javascript/power_javascript.h1
-rw-r--r--platform/javascript/run_icon.pngbin0 -> 471 bytes
-rw-r--r--platform/osx/SCsub1
-rw-r--r--platform/osx/audio_driver_osx.cpp176
-rw-r--r--platform/osx/audio_driver_osx.h9
-rw-r--r--platform/osx/context_gl_osx.cpp102
-rw-r--r--platform/osx/context_gl_osx.h63
-rw-r--r--platform/osx/detect.py70
-rw-r--r--platform/osx/dir_access_osx.h1
-rw-r--r--platform/osx/dir_access_osx.mm8
-rw-r--r--platform/osx/export/export.cpp813
-rw-r--r--platform/osx/export/export.h1
-rw-r--r--platform/osx/godot_main_osx.mm39
-rw-r--r--platform/osx/godot_osx.h37
-rw-r--r--platform/osx/godot_osx.mm215
-rw-r--r--platform/osx/joypad_osx.cpp10
-rw-r--r--platform/osx/joypad_osx.h3
-rw-r--r--platform/osx/os_osx.h39
-rw-r--r--platform/osx/os_osx.mm1914
-rw-r--r--platform/osx/platform_config.h1
-rw-r--r--platform/osx/power_osx.cpp27
-rw-r--r--platform/osx/power_osx.h1
-rw-r--r--platform/osx/sem_osx.cpp1
-rw-r--r--platform/osx/sem_osx.h1
-rw-r--r--platform/server/detect.py78
-rw-r--r--platform/server/godot_server.cpp1
-rw-r--r--platform/server/os_server.cpp3
-rw-r--r--platform/server/os_server.h3
-rw-r--r--platform/server/platform_config.h1
-rw-r--r--platform/uwp/SCsub1
-rw-r--r--platform/uwp/app.cpp108
-rw-r--r--platform/uwp/app.h3
-rw-r--r--platform/uwp/detect.py114
-rw-r--r--platform/uwp/export/export.cpp2193
-rw-r--r--platform/uwp/export/export.h1
-rw-r--r--platform/uwp/gl_context_egl.cpp3
-rw-r--r--platform/uwp/gl_context_egl.h1
-rw-r--r--platform/uwp/joypad_uwp.cpp80
-rw-r--r--platform/uwp/joypad_uwp.h11
-rw-r--r--platform/uwp/os_uwp.cpp112
-rw-r--r--platform/uwp/os_uwp.h17
-rw-r--r--platform/uwp/platform_config.h1
-rw-r--r--platform/uwp/power_uwp.cpp (renamed from platform/bb10/power_bb10.cpp)32
-rw-r--r--platform/uwp/power_uwp.h (renamed from platform/bb10/power_bb10.h)20
-rw-r--r--platform/uwp/thread_uwp.cpp7
-rw-r--r--platform/uwp/thread_uwp.h5
-rw-r--r--platform/windows/context_gl_win.cpp1
-rw-r--r--platform/windows/context_gl_win.h1
-rw-r--r--platform/windows/ctxgl_procaddr.cpp1
-rw-r--r--platform/windows/ctxgl_procaddr.h1
-rw-r--r--platform/windows/detect.py281
-rw-r--r--platform/windows/export/export.cpp35
-rw-r--r--platform/windows/export/export.h1
-rw-r--r--platform/windows/godot.icobin370070 -> 110755 bytes
-rw-r--r--platform/windows/godot_win.cpp1
-rw-r--r--platform/windows/joypad.cpp39
-rw-r--r--platform/windows/joypad.h5
-rw-r--r--platform/windows/key_mapping_win.cpp3
-rw-r--r--platform/windows/key_mapping_win.h1
-rw-r--r--platform/windows/lang_table.h1
-rw-r--r--platform/windows/os_windows.cpp610
-rw-r--r--platform/windows/os_windows.h28
-rw-r--r--platform/windows/packet_peer_udp_winsock.cpp5
-rw-r--r--platform/windows/packet_peer_udp_winsock.h3
-rw-r--r--platform/windows/platform_config.h1
-rw-r--r--platform/windows/power_windows.cpp26
-rw-r--r--platform/windows/power_windows.h1
-rw-r--r--platform/windows/stream_peer_winsock.cpp1
-rw-r--r--platform/windows/stream_peer_winsock.h1
-rw-r--r--platform/windows/tcp_server_winsock.cpp3
-rw-r--r--platform/windows/tcp_server_winsock.h3
-rw-r--r--platform/x11/context_gl_x11.cpp3
-rw-r--r--platform/x11/context_gl_x11.h1
-rw-r--r--platform/x11/detect.py160
-rw-r--r--platform/x11/export/export.cpp6
-rw-r--r--platform/x11/export/export.h1
-rw-r--r--platform/x11/godot_x11.cpp4
-rw-r--r--platform/x11/joypad_linux.cpp16
-rw-r--r--platform/x11/joypad_linux.h13
-rw-r--r--platform/x11/key_mapping_x11.cpp6
-rw-r--r--platform/x11/key_mapping_x11.h1
-rw-r--r--platform/x11/os_x11.cpp409
-rw-r--r--platform/x11/os_x11.h17
-rw-r--r--platform/x11/platform_config.h1
-rw-r--r--platform/x11/power_x11.cpp37
-rw-r--r--platform/x11/power_x11.h1
235 files changed, 6784 insertions, 13265 deletions
diff --git a/platform/android/SCsub b/platform/android/SCsub
index 02a8c3bc42..b124a1a5a8 100644
--- a/platform/android/SCsub
+++ b/platform/android/SCsub
@@ -52,13 +52,13 @@ if len(env.android_maven_repos) > 0:
gradle_maven_repos_text += ""
for x in env.android_maven_repos:
gradle_maven_repos_text += "\tmaven {\n"
- gradle_maven_repos_text += "\t\t" + x + "\n"
+ gradle_maven_repos_text += "\t" + x + "\n"
gradle_maven_repos_text += "\t}\n"
gradle_maven_dependencies_text = ""
for x in env.android_dependencies:
- gradle_maven_dependencies_text += x + "\n"
+ gradle_maven_dependencies_text += x + "\n\t"
gradle_java_dirs_text = ""
@@ -92,9 +92,23 @@ gradle_asset_dirs_text = ""
gradle_default_config_text = ""
+minSdk = 14
+targetSdk = 23
+
for x in env.android_default_config:
+ if x.startswith("minSdkVersion") and int(x.split(" ")[-1]) < minSdk:
+ x = "minSdkVersion " + str(minSdk)
+ if x.startswith("targetSdkVersion") and int(x.split(" ")[-1]) > targetSdk:
+ x = "targetSdkVersion " + str(targetSdk)
+
gradle_default_config_text += x + "\n\t\t"
+if "minSdkVersion" not in gradle_default_config_text:
+ gradle_default_config_text += ("minSdkVersion " + str(minSdk) + "\n\t\t")
+
+if "targetSdkVersion" not in gradle_default_config_text:
+ gradle_default_config_text += ("targetSdkVersion " + str(targetSdk) + "\n\t\t")
+
gradle_text = gradle_text.replace("$$GRADLE_REPOSITORY_URLS$$", gradle_maven_repos_text)
gradle_text = gradle_text.replace("$$GRADLE_DEPENDENCIES$$", gradle_maven_dependencies_text)
gradle_text = gradle_text.replace("$$GRADLE_JAVA_DIRS$$", gradle_java_dirs_text)
@@ -127,6 +141,8 @@ if env['android_arch'] == 'armv6':
lib_arch_dir = 'armeabi'
elif env['android_arch'] == 'armv7':
lib_arch_dir = 'armeabi-v7a'
+elif env['android_arch'] == 'arm64v8':
+ lib_arch_dir = 'arm64-v8a'
elif env['android_arch'] == 'x86':
lib_arch_dir = 'x86'
else:
diff --git a/platform/android/audio_driver_jandroid.cpp b/platform/android/audio_driver_jandroid.cpp
index 5e30289310..d293f3ed30 100644
--- a/platform/android/audio_driver_jandroid.cpp
+++ b/platform/android/audio_driver_jandroid.cpp
@@ -6,6 +6,7 @@
/* http://www.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 */
@@ -28,8 +29,8 @@
/*************************************************************************/
#include "audio_driver_jandroid.h"
-#include "global_config.h"
#include "os/os.h"
+#include "project_settings.h"
#include "thread_jandroid.h"
#ifndef ANDROID_NATIVE_ACTIVITY
diff --git a/platform/android/audio_driver_jandroid.h b/platform/android/audio_driver_jandroid.h
index 4b5131cdc0..3697ca6f21 100644
--- a/platform/android/audio_driver_jandroid.h
+++ b/platform/android/audio_driver_jandroid.h
@@ -6,6 +6,7 @@
/* http://www.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 */
@@ -70,7 +71,7 @@ public:
virtual void set_pause(bool p_pause);
- static void setup(jobject act);
+ static void setup(jobject p_io);
static void thread_func(JNIEnv *env);
AudioDriverAndroid();
diff --git a/platform/android/audio_driver_opensl.cpp b/platform/android/audio_driver_opensl.cpp
index bba98dd623..acd94d2bdd 100644
--- a/platform/android/audio_driver_opensl.cpp
+++ b/platform/android/audio_driver_opensl.cpp
@@ -6,6 +6,7 @@
/* http://www.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 */
diff --git a/platform/android/audio_driver_opensl.h b/platform/android/audio_driver_opensl.h
index 306589aa23..f6270a3084 100644
--- a/platform/android/audio_driver_opensl.h
+++ b/platform/android/audio_driver_opensl.h
@@ -6,6 +6,7 @@
/* http://www.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 */
diff --git a/platform/android/build.gradle.template b/platform/android/build.gradle.template
index 24aab8e01f..1df56ce621 100644
--- a/platform/android/build.gradle.template
+++ b/platform/android/build.gradle.template
@@ -3,7 +3,7 @@ buildscript {
jcenter()
}
dependencies {
- classpath 'com.android.tools.build:gradle:2.1.0'
+ classpath 'com.android.tools.build:gradle:2.3.3'
$$GRADLE_CLASSPATH$$
}
}
@@ -12,6 +12,7 @@ apply plugin: 'com.android.application'
allprojects {
repositories {
+ jcenter()
mavenCentral()
$$GRADLE_REPOSITORY_URLS$$
}
@@ -30,7 +31,7 @@ android {
}
compileSdkVersion 23
- buildToolsVersion "23.0.3"
+ buildToolsVersion "26.0.1"
useLibrary 'org.apache.http.legacy'
packagingOptions {
@@ -38,8 +39,6 @@ android {
exclude 'META-INF/NOTICE'
}
defaultConfig {
- minSdkVersion 14
- targetSdkVersion 23
$$GRADLE_DEFAULT_CONFIG$$
}
// Both signing and zip-aligning will be done at export time
@@ -57,7 +56,6 @@ android {
'res'
$$GRADLE_RES_DIRS$$
]
- // libs.srcDirs = ['libs']
aidl.srcDirs = [
'aidl'
$$GRADLE_AIDL_DIRS$$
@@ -66,9 +64,6 @@ android {
'assets'
$$GRADLE_ASSET_DIRS$$
]
- jniLibs.srcDirs = [
- $$GRADLE_JNI_DIRS$$
- ]
}
debug.jniLibs.srcDirs = [
'libs/debug'
diff --git a/platform/android/detect.py b/platform/android/detect.py
index d1b33fe649..ad5bfb4949 100644
--- a/platform/android/detect.py
+++ b/platform/android/detect.py
@@ -14,22 +14,17 @@ def get_name():
def can_build():
- import os
- if (not os.environ.has_key("ANDROID_NDK_ROOT")):
- return False
-
- return True
+ return (os.environ.has_key("ANDROID_NDK_ROOT"))
def get_opts():
return [
- ('ANDROID_NDK_ROOT', 'the path to Android NDK',
- os.environ.get("ANDROID_NDK_ROOT", 0)),
- ('ndk_platform', 'compile for platform: (android-<api> , example: android-18)', "android-18"),
- ('android_arch', 'select compiler architecture: (armv7/armv6/x86)', "armv7"),
- ('android_neon', 'enable neon (armv7 only)', "yes"),
- ('android_stl', 'enable STL support in android port (for modules)', "no")
+ ('ANDROID_NDK_ROOT', 'Path to the Android NDK', os.environ.get("ANDROID_NDK_ROOT", 0)),
+ ('ndk_platform', 'Target platform (android-<api>, e.g. "android-18")', "android-18"),
+ ('android_arch', 'Target architecture (armv7/armv6/arm64v8/x86)', "armv7"),
+ ('android_neon', 'Enable NEON support (armv7 only)', "yes"),
+ ('android_stl', 'Enable Android STL support (for modules)', "no")
]
@@ -41,6 +36,7 @@ def get_flags():
def create(env):
+
tools = env['TOOLS']
if "mingw" in tools:
tools.remove('mingw')
@@ -54,7 +50,6 @@ def configure(env):
# Workaround for MinGW. See:
# http://www.scons.org/wiki/LongCmdLinesOnWin32
- import os
if (os.name == "nt"):
import subprocess
@@ -92,36 +87,33 @@ def configure(env):
env['SPAWN'] = mySpawn
- ndk_platform = env['ndk_platform']
+ ## Architecture
- if env['android_arch'] not in ['armv7', 'armv6', 'x86']:
+ if env['android_arch'] not in ['armv7', 'armv6', 'arm64v8', 'x86']:
env['android_arch'] = 'armv7'
- if env['android_arch'] == 'x86':
- env["x86_libtheora_opt_gcc"] = True
-
- if env['PLATFORM'] == 'win32':
- env.Tool('gcc')
- env['SHLIBSUFFIX'] = '.so'
-
neon_text = ""
if env["android_arch"] == "armv7" and env['android_neon'] == 'yes':
- neon_text = " (with neon)"
- print("Godot Android!!!!! (" + env['android_arch'] + ")" + neon_text)
-
- env.Append(CPPPATH=['#platform/android'])
+ neon_text = " (with NEON)"
+ print("Building for Android (" + env['android_arch'] + ")" + neon_text)
+ can_vectorize = True
if env['android_arch'] == 'x86':
+ env['ARCH'] = 'arch-x86'
env.extra_suffix = ".x86" + env.extra_suffix
target_subpath = "x86-4.9"
abi_subpath = "i686-linux-android"
arch_subpath = "x86"
+ env["x86_libtheora_opt_gcc"] = True
elif env['android_arch'] == 'armv6':
+ env['ARCH'] = 'arch-arm'
env.extra_suffix = ".armv6" + env.extra_suffix
target_subpath = "arm-linux-androideabi-4.9"
abi_subpath = "arm-linux-androideabi"
arch_subpath = "armeabi"
+ can_vectorize = False
elif env["android_arch"] == "armv7":
+ env['ARCH'] = 'arch-arm'
target_subpath = "arm-linux-androideabi-4.9"
abi_subpath = "arm-linux-androideabi"
arch_subpath = "armeabi-v7a"
@@ -129,6 +121,34 @@ def configure(env):
env.extra_suffix = ".armv7.neon" + env.extra_suffix
else:
env.extra_suffix = ".armv7" + env.extra_suffix
+ elif env["android_arch"] == "arm64v8":
+ env['ARCH'] = 'arch-arm64'
+ target_subpath = "aarch64-linux-android-4.9"
+ abi_subpath = "aarch64-linux-android"
+ arch_subpath = "arm64-v8a"
+ env.extra_suffix = ".armv8" + env.extra_suffix
+
+ ## Build type
+
+ if (env["target"].startswith("release")):
+ env.Append(LINKFLAGS=['-O2'])
+ env.Append(CPPFLAGS=['-O2', '-DNDEBUG', '-ffast-math', '-funsafe-math-optimizations', '-fomit-frame-pointer'])
+ if (can_vectorize):
+ env.Append(CPPFLAGS=['-ftree-vectorize'])
+ if (env["target"] == "release_debug"):
+ env.Append(CPPFLAGS=['-DDEBUG_ENABLED'])
+ elif (env["target"] == "debug"):
+ env.Append(LINKFLAGS=['-O0'])
+ env.Append(CPPFLAGS=['-O0', '-D_DEBUG', '-UNDEBUG', '-DDEBUG_ENABLED',
+ '-DDEBUG_MEMORY_ENABLED', '-g', '-fno-limit-debug-info'])
+
+ ## Compiler configuration
+
+ env['SHLIBSUFFIX'] = '.so'
+
+ if env['PLATFORM'] == 'win32':
+ env.Tool('gcc')
+ env.use_windows_spawn_fix()
mt_link = True
if (sys.platform.startswith("linux")):
@@ -138,14 +158,14 @@ def configure(env):
elif (sys.platform.startswith('win')):
if (platform.machine().endswith('64')):
host_subpath = "windows-x86_64"
+ if env["android_arch"] == "arm64v8":
+ mt_link = False
else:
mt_link = False
host_subpath = "windows"
- compiler_path = env["ANDROID_NDK_ROOT"] + \
- "/toolchains/llvm/prebuilt/" + host_subpath + "/bin"
- gcc_toolchain_path = env["ANDROID_NDK_ROOT"] + \
- "/toolchains/" + target_subpath + "/prebuilt/" + host_subpath
+ compiler_path = env["ANDROID_NDK_ROOT"] + "/toolchains/llvm/prebuilt/" + host_subpath + "/bin"
+ gcc_toolchain_path = env["ANDROID_NDK_ROOT"] + "/toolchains/" + target_subpath + "/prebuilt/" + host_subpath
tools_path = gcc_toolchain_path + "/" + abi_subpath + "/bin"
# For Clang to find NDK tools in preference of those system-wide
@@ -157,60 +177,57 @@ def configure(env):
env['RANLIB'] = tools_path + "/ranlib"
env['AS'] = tools_path + "/as"
- if env['android_arch'] == 'x86':
- env['ARCH'] = 'arch-x86'
- else:
- env['ARCH'] = 'arch-arm'
-
- sysroot = env["ANDROID_NDK_ROOT"] + \
- "/platforms/" + ndk_platform + "/" + env['ARCH']
+ sysroot = env["ANDROID_NDK_ROOT"] + "/platforms/" + env['ndk_platform'] + "/" + env['ARCH']
common_opts = ['-fno-integrated-as', '-gcc-toolchain', gcc_toolchain_path]
+ ## Compile flags
+
env.Append(CPPFLAGS=["-isystem", sysroot + "/usr/include"])
- env.Append(CPPFLAGS=string.split(
- '-Wno-invalid-command-line-argument -Wno-unused-command-line-argument'))
- env.Append(CPPFLAGS=string.split(
- '-fpic -ffunction-sections -funwind-tables -fstack-protector-strong -fvisibility=hidden -fno-strict-aliasing -Wa,--noexecstack'))
- env.Append(CPPFLAGS=string.split('-DANDROID -DNO_STATVFS -DGLES2_ENABLED'))
+ env.Append(CPPFLAGS=string.split('-fpic -ffunction-sections -funwind-tables -fstack-protector-strong -fvisibility=hidden -fno-strict-aliasing'))
+ env.Append(CPPFLAGS=string.split('-DNO_STATVFS -DGLES2_ENABLED'))
env['neon_enabled'] = False
if env['android_arch'] == 'x86':
- can_vectorize = True
target_opts = ['-target', 'i686-none-linux-android']
+ # The NDK adds this if targeting API < 21, so we can drop it when Godot targets it at least
+ env.Append(CPPFLAGS=['-mstackrealign'])
+
elif env["android_arch"] == "armv6":
- can_vectorize = False
target_opts = ['-target', 'armv6-none-linux-androideabi']
- env.Append(CPPFLAGS=string.split(
- '-D__ARM_ARCH_6__ -march=armv6 -mfpu=vfp -mfloat-abi=softfp'))
+ env.Append(CPPFLAGS=string.split('-D__ARM_ARCH_6__ -march=armv6 -mfpu=vfp -mfloat-abi=softfp'))
+
elif env["android_arch"] == "armv7":
- can_vectorize = True
target_opts = ['-target', 'armv7-none-linux-androideabi']
- env.Append(CPPFLAGS=string.split(
- '-D__ARM_ARCH_7__ -D__ARM_ARCH_7A__ -march=armv7-a -mfloat-abi=softfp'))
+ env.Append(CPPFLAGS=string.split('-D__ARM_ARCH_7__ -D__ARM_ARCH_7A__ -march=armv7-a -mfloat-abi=softfp'))
if env['android_neon'] == 'yes':
env['neon_enabled'] = True
env.Append(CPPFLAGS=['-mfpu=neon', '-D__ARM_NEON__'])
else:
env.Append(CPPFLAGS=['-mfpu=vfpv3-d16'])
+ elif env["android_arch"] == "arm64v8":
+ target_opts = ['-target', 'aarch64-none-linux-android']
+ env.Append(CPPFLAGS=['-D__ARM_ARCH_8A__'])
+ env.Append(CPPFLAGS=['-mfix-cortex-a53-835769'])
+
env.Append(CPPFLAGS=target_opts)
env.Append(CPPFLAGS=common_opts)
- env.Append(LIBS=['OpenSLES'])
- env.Append(LIBS=['EGL', 'OpenSLES', 'android'])
- env.Append(LIBS=['log', 'GLESv1_CM', 'GLESv2', 'GLESv3','z'])
-
- if (sys.platform.startswith("darwin")):
- env['SHLIBSUFFIX'] = '.so'
-
- env['LINKFLAGS'] = ['-shared', '--sysroot=' +
- sysroot, '-Wl,--warn-shared-textrel']
- env.Append(LINKFLAGS=string.split(
- '-Wl,--fix-cortex-a8'))
- env.Append(LINKFLAGS=string.split(
- '-Wl,--no-undefined -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now'))
- env.Append(LINKFLAGS=string.split(
- '-Wl,-soname,libgodot_android.so -Wl,--gc-sections'))
+ if (env['android_stl'] == 'yes'):
+ env.Append(CPPPATH=[env["ANDROID_NDK_ROOT"] + "/sources/cxx-stl/gnu-libstdc++/4.9/include"])
+ env.Append(CPPPATH=[env["ANDROID_NDK_ROOT"] + "/sources/cxx-stl/gnu-libstdc++/4.9/libs/" + arch_subpath + "/include"])
+ env.Append(LIBPATH=[env["ANDROID_NDK_ROOT"] + "/sources/cxx-stl/gnu-libstdc++/4.9/libs/" + arch_subpath])
+ env.Append(LIBS=["gnustl_static"])
+ else:
+ env.Append(CXXFLAGS=['-fno-rtti', '-fno-exceptions', '-DNO_SAFE_CAST'])
+
+ ## Link flags
+
+ env['LINKFLAGS'] = ['-shared', '--sysroot=' + sysroot, '-Wl,--warn-shared-textrel']
+ if env["android_arch"] == "armv7":
+ env.Append(LINKFLAGS=string.split('-Wl,--fix-cortex-a8'))
+ env.Append(LINKFLAGS=string.split('-Wl,--no-undefined -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now'))
+ env.Append(LINKFLAGS=string.split('-Wl,-soname,libgodot_android.so -Wl,--gc-sections'))
if mt_link:
env.Append(LINKFLAGS=['-Wl,--threads'])
env.Append(LINKFLAGS=target_opts)
@@ -221,45 +238,12 @@ def configure(env):
env.Append(LIBPATH=[env["ANDROID_NDK_ROOT"] +
'/toolchains/arm-linux-androideabi-4.9/prebuilt/' + host_subpath + '/' + abi_subpath + '/lib'])
- if (env["target"].startswith("release")):
- env.Append(LINKFLAGS=['-O2'])
- env.Append(CPPFLAGS=['-O2', '-DNDEBUG', '-ffast-math',
- '-funsafe-math-optimizations', '-fomit-frame-pointer'])
- if (can_vectorize):
- env.Append(CPPFLAGS=['-ftree-vectorize'])
- if (env["target"] == "release_debug"):
- env.Append(CPPFLAGS=['-DDEBUG_ENABLED'])
- elif (env["target"] == "debug"):
- env.Append(LINKFLAGS=['-O0'])
- env.Append(CPPFLAGS=['-O0', '-D_DEBUG', '-UNDEBUG', '-DDEBUG_ENABLED',
- '-DDEBUG_MEMORY_ALLOC', '-g', '-fno-limit-debug-info'])
-
- env.Append(CPPFLAGS=['-DANDROID_ENABLED',
- '-DUNIX_ENABLED', '-DNO_FCNTL', '-DMPC_FIXED_POINT'])
+ env.Append(CPPPATH=['#platform/android'])
+ env.Append(CPPFLAGS=['-DANDROID_ENABLED', '-DUNIX_ENABLED', '-DNO_FCNTL', '-DMPC_FIXED_POINT'])
+ env.Append(LIBS=['OpenSLES', 'EGL', 'GLESv3', 'android', 'log', 'z'])
# TODO: Move that to opus module's config
if("module_opus_enabled" in env and env["module_opus_enabled"] != "no"):
if (env["android_arch"] == "armv6" or env["android_arch"] == "armv7"):
env.Append(CFLAGS=["-DOPUS_ARM_OPT"])
env.opus_fixed_point = "yes"
-
- if (env['android_stl'] == 'yes'):
- env.Append(CPPPATH=[env["ANDROID_NDK_ROOT"] +
- "/sources/cxx-stl/gnu-libstdc++/4.9/include"])
- env.Append(CPPPATH=[env["ANDROID_NDK_ROOT"] +
- "/sources/cxx-stl/gnu-libstdc++/4.9/libs/" + arch_subpath + "/include"])
- env.Append(LIBPATH=[env["ANDROID_NDK_ROOT"] +
- "/sources/cxx-stl/gnu-libstdc++/4.9/libs/" + arch_subpath])
- env.Append(LIBS=["gnustl_static"])
- else:
- env.Append(CXXFLAGS=['-fno-rtti', '-fno-exceptions', '-DNO_SAFE_CAST'])
-
- import methods
- env.Append(BUILDERS={'GLSL120': env.Builder(
- action=methods.build_legacygl_headers, suffix='glsl.h', src_suffix='.glsl')})
- env.Append(BUILDERS={'GLSL': env.Builder(
- action=methods.build_glsl_headers, suffix='glsl.h', src_suffix='.glsl')})
- env.Append(BUILDERS={'GLSL120GLES': env.Builder(
- action=methods.build_gles2_headers, suffix='glsl.h', src_suffix='.glsl')})
-
- env.use_windows_spawn_fix()
diff --git a/platform/android/dir_access_android.cpp b/platform/android/dir_access_android.cpp
index 989bd02bd9..67aa7750cd 100644
--- a/platform/android/dir_access_android.cpp
+++ b/platform/android/dir_access_android.cpp
@@ -6,6 +6,7 @@
/* http://www.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 */
diff --git a/platform/android/dir_access_android.h b/platform/android/dir_access_android.h
index 640800584a..32986f524b 100644
--- a/platform/android/dir_access_android.h
+++ b/platform/android/dir_access_android.h
@@ -6,6 +6,7 @@
/* http://www.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 */
diff --git a/platform/android/dir_access_jandroid.cpp b/platform/android/dir_access_jandroid.cpp
index 68446302ff..34f4afa331 100644
--- a/platform/android/dir_access_jandroid.cpp
+++ b/platform/android/dir_access_jandroid.cpp
@@ -6,6 +6,7 @@
/* http://www.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 */
diff --git a/platform/android/dir_access_jandroid.h b/platform/android/dir_access_jandroid.h
index 096858ddf7..21d1f697b7 100644
--- a/platform/android/dir_access_jandroid.h
+++ b/platform/android/dir_access_jandroid.h
@@ -6,6 +6,7 @@
/* http://www.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 */
@@ -78,7 +79,7 @@ public:
//virtual FileType get_file_type() const;
size_t get_space_left();
- static void setup(jobject io);
+ static void setup(jobject p_io);
DirAccessJAndroid();
~DirAccessJAndroid();
diff --git a/platform/android/export/export.cpp b/platform/android/export/export.cpp
index 2342829965..3c52834d92 100644
--- a/platform/android/export/export.cpp
+++ b/platform/android/export/export.cpp
@@ -6,6 +6,7 @@
/* http://www.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 */
@@ -30,12 +31,13 @@
#include "editor/editor_export.h"
#include "editor/editor_node.h"
#include "editor/editor_settings.h"
-#include "global_config.h"
#include "io/marshalls.h"
#include "io/zip_io.h"
#include "os/file_access.h"
#include "os/os.h"
-#include "platform/android/logo.h"
+#include "platform/android/logo.gen.h"
+#include "platform/android/run_icon.gen.h"
+#include "project_settings.h"
#include "version.h"
#include <string.h>
#if 0
@@ -217,6 +219,7 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
bool use_32_fb;
bool immersive;
bool export_arm;
+ bool export_arm64;
bool export_x86;
String apk_expansion_salt;
String apk_expansion_pkey;
@@ -317,6 +320,8 @@ bool EditorExportPlatformAndroid::_set(const StringName& p_name, const Variant&
_signed=p_value;
else if (n=="architecture/arm")
export_arm=p_value;
+ else if (n=="architecture/arm64")
+ export_arm64=p_value;
else if (n=="architecture/x86")
export_x86=p_value;
else if (n=="screen/use_32_bits_view")
@@ -390,6 +395,8 @@ bool EditorExportPlatformAndroid::_get(const StringName& p_name,Variant &r_ret)
r_ret=_signed;
else if (n=="architecture/arm")
r_ret=export_arm;
+ else if (n=="architecture/arm64")
+ r_ret=export_arm64;
else if (n=="architecture/x86")
r_ret=export_x86;
else if (n=="screen/use_32_bits_view")
@@ -552,9 +559,9 @@ void EditorExportPlatformAndroid::_fix_resources(Vector<uint8_t>& p_manifest) {
} else {
String lang = str.substr(str.find_last("-")+1,str.length()).replace("-","_");
- String prop = "application/name_"+lang;
- if (GlobalConfig::get_singleton()->has(prop)) {
- str = GlobalConfig::get_singleton()->get(prop);
+ String prop = "application/config/name_"+lang;
+ if (ProjectSettings::get_singleton()->has(prop)) {
+ str = ProjectSettings::get_singleton()->get(prop);
} else {
str = get_project_name();
}
@@ -626,7 +633,7 @@ String EditorExportPlatformAndroid::get_project_name() const {
if (this->name!="") {
aname=this->name;
} else {
- aname = GlobalConfig::get_singleton()->get("application/name");
+ aname = ProjectSettings::get_singleton()->get("application/config/name");
}
@@ -1142,7 +1149,7 @@ Error EditorExportPlatformAndroid::export_project(const String& p_path, bool p_d
if (!found) {
- String appicon = GlobalConfig::get_singleton()->get("application/icon");
+ String appicon = ProjectSettings::get_singleton()->get("application/config/icon");
if (appicon!="" && appicon.ends_with(".png")) {
FileAccess*f = FileAccess::open(appicon,FileAccess::READ);
if (f) {
@@ -1162,6 +1169,10 @@ Error EditorExportPlatformAndroid::export_project(const String& p_path, bool p_d
skip=true;
}
+ if (file.match("lib/arm64*/libgodot_android.so") && !export_arm64) {
+ skip = true;
+ }
+
if (file.begins_with("META-INF") && _signed) {
skip=true;
}
@@ -1713,7 +1724,7 @@ Error EditorExportPlatformAndroid::run(int p_device, int p_flags) {
args.push_back("--remove-all");
err = OS::get_singleton()->execute(adb,args,true,NULL,NULL,&rv);
- int port = GlobalConfig::get_singleton()->get("network/debug/remote_port");
+ int port = (int)EditorSettings::get_singleton()->get("network/debug/remote_port");
args.clear();
args.push_back("reverse");
args.push_back("tcp:"+itos(port));
@@ -1761,7 +1772,7 @@ Error EditorExportPlatformAndroid::run(int p_device, int p_flags) {
String EditorExportPlatformAndroid::get_package_name() {
String pname = package;
- String basename = GlobalConfig::get_singleton()->get("application/name");
+ String basename = ProjectSettings::get_singleton()->get("application/config/name");
basename=basename.to_lower();
String name;
@@ -1799,6 +1810,7 @@ EditorExportPlatformAndroid::EditorExportPlatformAndroid() {
immersive=true;
export_arm=true;
+ export_arm64=false;
export_x86=false;
@@ -2041,12 +2053,14 @@ class EditorExportAndroid : public EditorExportPlatform {
GDCLASS(EditorExportAndroid, EditorExportPlatform)
Ref<ImageTexture> logo;
+ Ref<ImageTexture> run_icon;
struct Device {
String id;
String name;
String description;
+ int release;
};
struct APKExportData {
@@ -2120,6 +2134,7 @@ class EditorExportAndroid : public EditorExportPlatform {
if (ea->devices[j].id == ldevices[i]) {
d.description = ea->devices[j].description;
d.name = ea->devices[j].name;
+ d.release = ea->devices[j].release;
}
}
@@ -2140,6 +2155,7 @@ class EditorExportAndroid : public EditorExportPlatform {
String vendor;
String device;
d.description + "Device ID: " + d.id + "\n";
+ d.release = 0;
for (int j = 0; j < props.size(); j++) {
String p = props[j];
@@ -2150,7 +2166,9 @@ class EditorExportAndroid : public EditorExportPlatform {
} else if (p.begins_with("ro.build.display.id=")) {
d.description += "Build: " + p.get_slice("=", 1).strip_edges() + "\n";
} else if (p.begins_with("ro.build.version.release=")) {
- d.description += "Release: " + p.get_slice("=", 1).strip_edges() + "\n";
+ const String release_str = p.get_slice("=", 1).strip_edges();
+ d.description += "Release: " + release_str + "\n";
+ d.release = release_str.to_int();
} else if (p.begins_with("ro.product.cpu.abi=")) {
d.description += "CPU: " + p.get_slice("=", 1).strip_edges() + "\n";
} else if (p.begins_with("ro.product.manufacturer=")) {
@@ -2205,7 +2223,7 @@ class EditorExportAndroid : public EditorExportPlatform {
if (p_name != "") {
aname = p_name;
} else {
- aname = GlobalConfig::get_singleton()->get("application/name");
+ aname = ProjectSettings::get_singleton()->get("application/config/name");
}
if (aname == "") {
@@ -2218,7 +2236,7 @@ class EditorExportAndroid : public EditorExportPlatform {
String get_package_name(const String &p_package) {
String pname = p_package;
- String basename = GlobalConfig::get_singleton()->get("application/name");
+ String basename = ProjectSettings::get_singleton()->get("application/config/name");
basename = basename.to_lower();
String name;
@@ -2534,6 +2552,10 @@ class EditorExportAndroid : public EditorExportPlatform {
}*/
}
+ if (tname == "uses-feature" && /*nspace=="android" &&*/ attrname == "glEsVersion") {
+ print_line("version number: " + itos(decode_uint32(&p_manifest[iofs + 16])));
+ }
+
if (tname == "uses-permission" && /*nspace=="android" &&*/ attrname == "name") {
if (value.begins_with("godot.custom")) {
@@ -2747,9 +2769,9 @@ class EditorExportAndroid : public EditorExportPlatform {
} else {
String lang = str.substr(str.find_last("-") + 1, str.length()).replace("-", "_");
- String prop = "application/name_" + lang;
- if (GlobalConfig::get_singleton()->has(prop)) {
- str = GlobalConfig::get_singleton()->get(prop);
+ String prop = "application/config/name_" + lang;
+ if (ProjectSettings::get_singleton()->has(prop)) {
+ str = ProjectSettings::get_singleton()->get(prop);
} else {
str = get_project_name(package_name);
}
@@ -2823,11 +2845,17 @@ public:
public:
virtual void get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) {
- r_features->push_back("etc");
+ int api = p_preset->get("graphics/api");
+ if (api == 0)
+ r_features->push_back("etc");
+ else
+ r_features->push_back("etc2");
}
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::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"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_package/release", PROPERTY_HINT_GLOBAL_FILE, "apk"), ""));
@@ -2840,7 +2868,6 @@ public:
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/use_32_bits_view"), true));
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));
@@ -2872,6 +2899,11 @@ public:
virtual String get_name() const {
return "Android";
}
+
+ virtual String get_os_name() const {
+ return "Android";
+ }
+
virtual Ref<Texture> get_logo() const {
return logo;
}
@@ -2988,15 +3020,19 @@ public:
if (use_adb_over_usb) {
args.clear();
+ args.push_back("-s");
+ args.push_back(devices[p_device].id);
args.push_back("reverse");
args.push_back("--remove-all");
err = OS::get_singleton()->execute(adb, args, true, NULL, NULL, &rv);
- int port = GlobalConfig::get_singleton()->get("network/debug/remote_port");
+ int dbg_port = EditorSettings::get_singleton()->get("network/debug/remote_port");
args.clear();
+ args.push_back("-s");
+ args.push_back(devices[p_device].id);
args.push_back("reverse");
- args.push_back("tcp:" + itos(port));
- args.push_back("tcp:" + itos(port));
+ args.push_back("tcp:" + itos(dbg_port));
+ args.push_back("tcp:" + itos(dbg_port));
err = OS::get_singleton()->execute(adb, args, true, NULL, NULL, &rv);
print_line("Reverse result: " + itos(rv));
@@ -3004,6 +3040,8 @@ public:
int fs_port = EditorSettings::get_singleton()->get("filesystem/file_server/port");
args.clear();
+ args.push_back("-s");
+ args.push_back(devices[p_device].id);
args.push_back("reverse");
args.push_back("tcp:" + itos(fs_port));
args.push_back("tcp:" + itos(fs_port));
@@ -3019,7 +3057,10 @@ public:
args.push_back("shell");
args.push_back("am");
args.push_back("start");
- args.push_back("--user 0");
+ if ((bool)EditorSettings::get_singleton()->get("export/android/force_system_user") && devices[p_device].release >= 17) { // Multi-user introduced in Android 17
+ args.push_back("--user");
+ args.push_back("0");
+ }
args.push_back("-a");
args.push_back("android.intent.action.MAIN");
args.push_back("-n");
@@ -3027,7 +3068,7 @@ public:
err = OS::get_singleton()->execute(adb, args, true, NULL, NULL, &rv);
if (err || rv != 0) {
- EditorNode::add_io_error("Could not execute ondevice.");
+ EditorNode::add_io_error("Could not execute on device.");
device_lock->unlock();
return ERR_CANT_CREATE;
}
@@ -3035,6 +3076,10 @@ public:
return OK;
}
+ virtual Ref<Texture> get_run_icon() const {
+ return run_icon;
+ }
+
virtual bool can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const {
r_missing_templates = find_export_template("android_debug.apk") == String() || find_export_template("android_release.apk") == String();
@@ -3141,6 +3186,7 @@ public:
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("screen/use_32_bits_view");
bool immersive = p_preset->get("screen/immersive_mode");
@@ -3212,7 +3258,7 @@ public:
if (!found) {
- String appicon = GlobalConfig::get_singleton()->get("application/icon");
+ String appicon = ProjectSettings::get_singleton()->get("application/config/icon");
if (appicon != "" && appicon.ends_with(".png")) {
FileAccess *f = FileAccess::open(appicon, FileAccess::READ);
if (f) {
@@ -3232,6 +3278,10 @@ public:
skip = true;
}
+ if (file.match("lib/arm64*/libgodot_android.so") && !export_arm64) {
+ skip = true;
+ }
+
if (file.begins_with("META-INF") && _signed) {
skip = true;
}
@@ -3520,17 +3570,34 @@ public:
return OK;
}
+ virtual void get_platform_features(List<String> *r_features) {
+
+ r_features->push_back("mobile");
+ r_features->push_back("Android");
+ }
+
EditorExportAndroid() {
- Image img(_android_logo);
- logo = Ref<ImageTexture>(memnew(ImageTexture));
+ Ref<Image> img = memnew(Image(_android_logo));
+ logo.instance();
logo->create_from_image(img);
+ img = Ref<Image>(memnew(Image(_android_run_icon)));
+ run_icon.instance();
+ run_icon->create_from_image(img);
+
device_lock = Mutex::create();
device_thread = Thread::create(_device_poll_thread, this);
devices_changed = true;
quit_request = false;
}
+
+ ~EditorExportAndroid() {
+ quit_request = true;
+ Thread::wait_to_finish(device_thread);
+ memdelete(device_lock);
+ memdelete(device_thread);
+ }
};
void register_android_exporter() {
@@ -3548,6 +3615,7 @@ void register_android_exporter() {
EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::STRING, "export/android/debug_keystore", PROPERTY_HINT_GLOBAL_FILE, "keystore"));
EDITOR_DEF("export/android/debug_keystore_user", "androiddebugkey");
EDITOR_DEF("export/android/debug_keystore_pass", "android");
+ EDITOR_DEF("export/android/force_system_user", false);
EDITOR_DEF("export/android/timestamping_authority_url", "");
EDITOR_DEF("export/android/use_remote_debug_over_adb", false);
diff --git a/platform/android/export/export.h b/platform/android/export/export.h
index 468b484177..e3b0b4aab6 100644
--- a/platform/android/export/export.h
+++ b/platform/android/export/export.h
@@ -6,6 +6,7 @@
/* http://www.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 */
diff --git a/platform/android/file_access_android.cpp b/platform/android/file_access_android.cpp
index 4426af4dad..be19f056b0 100644
--- a/platform/android/file_access_android.cpp
+++ b/platform/android/file_access_android.cpp
@@ -6,6 +6,7 @@
/* http://www.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 */
diff --git a/platform/android/file_access_android.h b/platform/android/file_access_android.h
index de131f19bc..0ee8cd7efe 100644
--- a/platform/android/file_access_android.h
+++ b/platform/android/file_access_android.h
@@ -6,6 +6,7 @@
/* http://www.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 */
diff --git a/platform/android/file_access_jandroid.cpp b/platform/android/file_access_jandroid.cpp
index b3624e9f26..e20ffd4f8a 100644
--- a/platform/android/file_access_jandroid.cpp
+++ b/platform/android/file_access_jandroid.cpp
@@ -6,6 +6,7 @@
/* http://www.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 */
diff --git a/platform/android/file_access_jandroid.h b/platform/android/file_access_jandroid.h
index b78d5e603c..a04f28d0d7 100644
--- a/platform/android/file_access_jandroid.h
+++ b/platform/android/file_access_jandroid.h
@@ -6,6 +6,7 @@
/* http://www.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 */
@@ -70,7 +71,7 @@ public:
virtual bool file_exists(const String &p_path); ///< return true if a file exists
- static void setup(jobject io);
+ static void setup(jobject p_io);
virtual uint64_t _get_modified_time(const String &p_file) { return 0; }
diff --git a/platform/android/globals/global_defaults.cpp b/platform/android/globals/global_defaults.cpp
index 60d7d8cb6b..6bdc6b337c 100644
--- a/platform/android/globals/global_defaults.cpp
+++ b/platform/android/globals/global_defaults.cpp
@@ -6,6 +6,7 @@
/* http://www.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 */
@@ -27,7 +28,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "global_defaults.h"
-#include "global_config.h"
+#include "project_settings.h"
void register_android_global_defaults() {
@@ -36,6 +37,6 @@ void register_android_global_defaults() {
GLOBAL_DEF("display.Android/driver","GLES2");
//GLOBAL_DEF("rasterizer.Android/trilinear_mipmap_filter",false);
- GlobalConfig::get_singleton()->set_custom_property_info("display.Android/driver",PropertyInfo(Variant::STRING,"display.Android/driver",PROPERTY_HINT_ENUM,"GLES2"));
+ 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/globals/global_defaults.h b/platform/android/globals/global_defaults.h
index 49d7f6393c..d524b56af6 100644
--- a/platform/android/globals/global_defaults.h
+++ b/platform/android/globals/global_defaults.h
@@ -6,6 +6,7 @@
/* http://www.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 */
diff --git a/platform/android/godot_android.cpp b/platform/android/godot_android.cpp
index 9d300940b0..6fbd42d7b3 100644
--- a/platform/android/godot_android.cpp
+++ b/platform/android/godot_android.cpp
@@ -6,6 +6,7 @@
/* http://www.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 */
@@ -35,9 +36,9 @@
#include <GLES2/gl2.h>
#include "file_access_android.h"
-#include "global_config.h"
#include "main/main.h"
#include "os_android.h"
+#include "project_settings.h"
#include <android/log.h>
#include <android/sensor.h>
#include <android/window.h>
@@ -622,7 +623,7 @@ static void engine_handle_cmd(struct android_app *app, int32_t cmd) {
#else
Error err = Main::setup("apk", 0, NULL);
- String modules = GlobalConfig::get_singleton()->get("android/modules");
+ String modules = ProjectSettings::get_singleton()->get("android/modules");
Vector<String> mods = modules.split(",", false);
mods.push_back("GodotOS");
__android_log_print(ANDROID_LOG_INFO, "godot", "mod count: %i", mods.size());
@@ -738,21 +739,21 @@ static void engine_handle_cmd(struct android_app *app, int32_t cmd) {
}
}
-void android_main(struct android_app *state) {
+void android_main(struct android_app *app) {
struct engine engine;
// Make sure glue isn't stripped.
app_dummy();
memset(&engine, 0, sizeof(engine));
- state->userData = &engine;
- state->onAppCmd = engine_handle_cmd;
- state->onInputEvent = engine_handle_input;
- engine.app = state;
+ app->userData = &engine;
+ app->onAppCmd = engine_handle_cmd;
+ app->onInputEvent = engine_handle_input;
+ engine.app = app;
engine.requested_quit = false;
engine.os = NULL;
engine.display_active = false;
- FileAccessAndroid::asset_manager = state->activity->assetManager;
+ FileAccessAndroid::asset_manager = app->activity->assetManager;
// Prepare to monitor sensors
engine.sensorManager = ASensorManager_getInstance();
@@ -763,11 +764,11 @@ void android_main(struct android_app *state) {
engine.gyroscopeSensor = ASensorManager_getDefaultSensor(engine.sensorManager,
ASENSOR_TYPE_GYROSCOPE);
engine.sensorEventQueue = ASensorManager_createEventQueue(engine.sensorManager,
- state->looper, LOOPER_ID_USER, NULL, NULL);
+ app->looper, LOOPER_ID_USER, NULL, NULL);
- ANativeActivity_setWindowFlags(state->activity, AWINDOW_FLAG_FULLSCREEN | AWINDOW_FLAG_KEEP_SCREEN_ON, 0);
+ ANativeActivity_setWindowFlags(app->activity, AWINDOW_FLAG_FULLSCREEN | AWINDOW_FLAG_KEEP_SCREEN_ON, 0);
- state->activity->vm->AttachCurrentThread(&engine.jni, NULL);
+ app->activity->vm->AttachCurrentThread(&engine.jni, NULL);
// loop waiting for stuff to do.
@@ -789,7 +790,7 @@ void android_main(struct android_app *state) {
if (source != NULL) {
// LOGI("process\n");
- source->process(state, source);
+ source->process(app, source);
} else {
nullmax--;
if (nullmax < 0)
@@ -823,11 +824,11 @@ void android_main(struct android_app *state) {
}
// Check if we are exiting.
- if (state->destroyRequested != 0) {
+ if (app->destroyRequested != 0) {
if (engine.os) {
engine.os->main_loop_request_quit();
}
- state->destroyRequested = 0;
+ app->destroyRequested = 0;
}
if (engine.requested_quit) {
@@ -858,7 +859,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_Godot_registerSingleton(JNIEnv
s->set_instance(env->NewGlobalRef(p_object));
jni_singletons[singname] = s;
- GlobalConfig::get_singleton()->add_singleton(GlobalConfig::Singleton(singname, s));
+ ProjectSettings::get_singleton()->add_singleton(ProjectSettings::Singleton(singname, s));
}
static Variant::Type get_jni_type(const String &p_type) {
@@ -925,7 +926,7 @@ JNIEXPORT jstring JNICALL Java_org_godotengine_godot_Godot_getGlobal(JNIEnv *env
String js = env->GetStringUTFChars(path, NULL);
- return env->NewStringUTF(GlobalConfig::get_singleton()->get(js).operator String().utf8().get_data());
+ return env->NewStringUTF(ProjectSettings::get_singleton()->get(js).operator String().utf8().get_data());
}
JNIEXPORT void JNICALL Java_org_godotengine_godot_Godot_registerMethod(JNIEnv *env, jobject obj, jstring sname, jstring name, jstring ret, jobjectArray args) {
diff --git a/platform/android/java/gradle.properties b/platform/android/java/gradle.properties
new file mode 100644
index 0000000000..aac7c9b461
--- /dev/null
+++ b/platform/android/java/gradle.properties
@@ -0,0 +1,17 @@
+# Project-wide Gradle settings.
+
+# IDE (e.g. Android Studio) users:
+# Gradle settings configured through the IDE *will override*
+# any settings specified in this file.
+
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+org.gradle.jvmargs=-Xmx1536m
+
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. More details, visit
+# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
+# org.gradle.parallel=true
diff --git a/platform/android/java/gradle/wrapper/gradle-wrapper.jar b/platform/android/java/gradle/wrapper/gradle-wrapper.jar
index 8c0fb64a86..13372aef5e 100644
--- a/platform/android/java/gradle/wrapper/gradle-wrapper.jar
+++ b/platform/android/java/gradle/wrapper/gradle-wrapper.jar
Binary files differ
diff --git a/platform/android/java/gradle/wrapper/gradle-wrapper.properties b/platform/android/java/gradle/wrapper/gradle-wrapper.properties
index d57051703e..ee6901c9d7 100644
--- a/platform/android/java/gradle/wrapper/gradle-wrapper.properties
+++ b/platform/android/java/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
-#Wed Apr 10 15:27:10 PDT 2013
+#Sat Jul 29 16:10:03 ICT 2017
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip
diff --git a/platform/android/java/gradlew b/platform/android/java/gradlew
index 91a7e269e1..9d82f78915 100755
--- a/platform/android/java/gradlew
+++ b/platform/android/java/gradlew
@@ -42,11 +42,6 @@ case "`uname`" in
;;
esac
-# For Cygwin, ensure paths are in UNIX format before anything is touched.
-if $cygwin ; then
- [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
-fi
-
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
@@ -61,9 +56,9 @@ while [ -h "$PRG" ] ; do
fi
done
SAVED="`pwd`"
-cd "`dirname \"$PRG\"`/" >&-
+cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
-cd "$SAVED" >&-
+cd "$SAVED" >/dev/null
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
@@ -114,6 +109,7 @@ fi
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+ JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
diff --git a/platform/android/java/res/drawable/icon.png b/platform/android/java/res/drawable/icon.png
index a0a0f4af25..29c4a7b8fc 100644
--- a/platform/android/java/res/drawable/icon.png
+++ b/platform/android/java/res/drawable/icon.png
Binary files differ
diff --git a/platform/android/java/src/com/android/vending/licensing/ILicenseResultListener.java b/platform/android/java/src/com/android/vending/licensing/ILicenseResultListener.java
index d90d6eac7b..63720999a7 100644
--- a/platform/android/java/src/com/android/vending/licensing/ILicenseResultListener.java
+++ b/platform/android/java/src/com/android/vending/licensing/ILicenseResultListener.java
@@ -1,4 +1,20 @@
/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+
+/*
* This file is auto-generated. DO NOT MODIFY.
* Original file: aidl/ILicenseResultListener.aidl
*/
diff --git a/platform/android/java/src/com/android/vending/licensing/ILicensingService.java b/platform/android/java/src/com/android/vending/licensing/ILicensingService.java
index 95599544e4..36afc0537d 100644
--- a/platform/android/java/src/com/android/vending/licensing/ILicensingService.java
+++ b/platform/android/java/src/com/android/vending/licensing/ILicensingService.java
@@ -1,4 +1,20 @@
/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+*/
+
+/*
* This file is auto-generated. DO NOT MODIFY.
* Original file: aidl/ILicensingService.aidl
*/
diff --git a/platform/android/java/src/com/google/android/vending/expansion/downloader/Helpers.java b/platform/android/java/src/com/google/android/vending/expansion/downloader/Helpers.java
index ae3fe957cb..fb56f917be 100644
--- a/platform/android/java/src/com/google/android/vending/expansion/downloader/Helpers.java
+++ b/platform/android/java/src/com/google/android/vending/expansion/downloader/Helpers.java
@@ -221,7 +221,11 @@ public class Helpers {
static public String getSaveFilePath(Context c) {
File root = Environment.getExternalStorageDirectory();
- String path = Build.VERSION.SDK_INT >= 23 ? Constants.EXP_PATH_API23 : Constants.EXP_PATH;
+ // this makes several issues with Android SDK >= 23 devices.
+ // https://github.com/danikula/Google-Play-Expansion-File/commit/93a03bd34acad67c6ea34cfb6c3f02c93bdcea85
+ // https://issuetracker.google.com/issues/37075181
+ //String path = Build.VERSION.SDK_INT >= 23 ? Constants.EXP_PATH_API23 : Constants.EXP_PATH;
+ String path = Constants.EXP_PATH;
return root.toString() + path + c.getPackageName();
}
diff --git a/platform/android/java/src/com/google/android/vending/expansion/downloader/impl/DownloaderService.java b/platform/android/java/src/com/google/android/vending/expansion/downloader/impl/DownloaderService.java
index 627bf3eedd..e83faa2756 100644
--- a/platform/android/java/src/com/google/android/vending/expansion/downloader/impl/DownloaderService.java
+++ b/platform/android/java/src/com/google/android/vending/expansion/downloader/impl/DownloaderService.java
@@ -569,10 +569,10 @@ public abstract class DownloaderService extends CustomIntentService implements I
*/
void pollNetworkState() {
if (null == mConnectivityManager) {
- mConnectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
+ mConnectivityManager = (ConnectivityManager) getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE);
}
if (null == mWifiManager) {
- mWifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
+ mWifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
}
if (mConnectivityManager == null) {
Log.w(Constants.TAG,
diff --git a/platform/android/java/src/org/godotengine/godot/Dictionary.java b/platform/android/java/src/org/godotengine/godot/Dictionary.java
index 72f0b7a60e..b9501e0858 100644
--- a/platform/android/java/src/org/godotengine/godot/Dictionary.java
+++ b/platform/android/java/src/org/godotengine/godot/Dictionary.java
@@ -6,6 +6,7 @@
/* http://www.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 */
diff --git a/platform/android/java/src/org/godotengine/godot/Godot.java b/platform/android/java/src/org/godotengine/godot/Godot.java
index 0cec0c5773..d620b2b9c4 100644
--- a/platform/android/java/src/org/godotengine/godot/Godot.java
+++ b/platform/android/java/src/org/godotengine/godot/Godot.java
@@ -6,6 +6,7 @@
/* http://www.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 */
@@ -272,7 +273,7 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
mView = new GodotView(getApplication(),io,use_gl2,use_32_bits, this);
layout.addView(mView,new LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.FILL_PARENT));
- setKeepScreenOn(GodotLib.getGlobal("display/keep_screen_on").equals("True"));
+ setKeepScreenOn(GodotLib.getGlobal("display/driver/keep_screen_on").equals("True"));
edittext.setView(mView);
io.setEdit(edittext);
diff --git a/platform/android/java/src/org/godotengine/godot/GodotDownloaderAlarmReceiver.java b/platform/android/java/src/org/godotengine/godot/GodotDownloaderAlarmReceiver.java
index 5a07d680b3..6cdc6be793 100644
--- a/platform/android/java/src/org/godotengine/godot/GodotDownloaderAlarmReceiver.java
+++ b/platform/android/java/src/org/godotengine/godot/GodotDownloaderAlarmReceiver.java
@@ -6,6 +6,7 @@
/* http://www.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 */
diff --git a/platform/android/java/src/org/godotengine/godot/GodotDownloaderService.java b/platform/android/java/src/org/godotengine/godot/GodotDownloaderService.java
index fba082e80d..38d30c108c 100644
--- a/platform/android/java/src/org/godotengine/godot/GodotDownloaderService.java
+++ b/platform/android/java/src/org/godotengine/godot/GodotDownloaderService.java
@@ -6,6 +6,7 @@
/* http://www.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 */
diff --git a/platform/android/java/src/org/godotengine/godot/GodotIO.java b/platform/android/java/src/org/godotengine/godot/GodotIO.java
index d6ceef8768..ecb623452c 100644
--- a/platform/android/java/src/org/godotengine/godot/GodotIO.java
+++ b/platform/android/java/src/org/godotengine/godot/GodotIO.java
@@ -6,6 +6,7 @@
/* http://www.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 */
diff --git a/platform/android/java/src/org/godotengine/godot/GodotLib.java b/platform/android/java/src/org/godotengine/godot/GodotLib.java
index 57856cfd6b..1ed04d9d27 100644
--- a/platform/android/java/src/org/godotengine/godot/GodotLib.java
+++ b/platform/android/java/src/org/godotengine/godot/GodotLib.java
@@ -6,6 +6,7 @@
/* http://www.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 */
diff --git a/platform/android/java/src/org/godotengine/godot/GodotPaymentV3.java b/platform/android/java/src/org/godotengine/godot/GodotPaymentV3.java
index 6eee8da91b..3cb8fd3da8 100644
--- a/platform/android/java/src/org/godotengine/godot/GodotPaymentV3.java
+++ b/platform/android/java/src/org/godotengine/godot/GodotPaymentV3.java
@@ -6,6 +6,7 @@
/* http://www.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 */
diff --git a/platform/android/java/src/org/godotengine/godot/GodotView.java b/platform/android/java/src/org/godotengine/godot/GodotView.java
index a209bc7f5b..c6c68c36b0 100644
--- a/platform/android/java/src/org/godotengine/godot/GodotView.java
+++ b/platform/android/java/src/org/godotengine/godot/GodotView.java
@@ -6,6 +6,7 @@
/* http://www.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 */
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 f0dae03a81..bf5239aa77 100644
--- a/platform/android/java/src/org/godotengine/godot/input/GodotEditText.java
+++ b/platform/android/java/src/org/godotengine/godot/input/GodotEditText.java
@@ -6,6 +6,7 @@
/* http://www.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 */
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 3c8207fae1..1dbcb78ada 100644
--- a/platform/android/java/src/org/godotengine/godot/input/GodotTextInputWrapper.java
+++ b/platform/android/java/src/org/godotengine/godot/input/GodotTextInputWrapper.java
@@ -6,6 +6,7 @@
/* http://www.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 */
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 67293df2a8..c37821ffd9 100644
--- a/platform/android/java/src/org/godotengine/godot/payments/ConsumeTask.java
+++ b/platform/android/java/src/org/godotengine/godot/payments/ConsumeTask.java
@@ -6,6 +6,7 @@
/* http://www.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 */
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 dfa363ed75..72126a8f64 100644
--- a/platform/android/java/src/org/godotengine/godot/payments/GenericConsumeTask.java
+++ b/platform/android/java/src/org/godotengine/godot/payments/GenericConsumeTask.java
@@ -6,6 +6,7 @@
/* http://www.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 */
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 3850453a77..e223bbb8c0 100644
--- a/platform/android/java/src/org/godotengine/godot/payments/HandlePurchaseTask.java
+++ b/platform/android/java/src/org/godotengine/godot/payments/HandlePurchaseTask.java
@@ -6,6 +6,7 @@
/* http://www.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 */
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 4678dae1b3..fa5564a3f4 100644
--- a/platform/android/java/src/org/godotengine/godot/payments/PaymentsCache.java
+++ b/platform/android/java/src/org/godotengine/godot/payments/PaymentsCache.java
@@ -6,6 +6,7 @@
/* http://www.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 */
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 73d1cc3bc8..6f308af360 100644
--- a/platform/android/java/src/org/godotengine/godot/payments/PaymentsManager.java
+++ b/platform/android/java/src/org/godotengine/godot/payments/PaymentsManager.java
@@ -6,6 +6,7 @@
/* http://www.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 */
@@ -354,36 +355,35 @@ public class PaymentsManager {
tempList.add(s);
}
packs.add(tempList);
-
- for (ArrayList<String> skuPartList : packs) {
- Bundle querySkus = new Bundle();
- querySkus.putStringArrayList("ITEM_ID_LIST", skuPartList);
- Bundle skuDetails = null;
- try {
- skuDetails = mService.getSkuDetails(3, activity.getPackageName(), "inapp", querySkus);
- if (!skuDetails.containsKey("DETAILS_LIST")) {
- int response = getResponseCodeFromBundle(skuDetails);
- if (response != BILLING_RESPONSE_RESULT_OK) {
- godotPaymentV3.errorSkuDetail(getResponseDesc(response));
- } else {
- godotPaymentV3.errorSkuDetail("No error but no detail list.");
- }
- return;
+ }
+ for (ArrayList<String> skuPartList : packs) {
+ Bundle querySkus = new Bundle();
+ querySkus.putStringArrayList("ITEM_ID_LIST", skuPartList);
+ Bundle skuDetails = null;
+ try {
+ skuDetails = mService.getSkuDetails(3, activity.getPackageName(), "inapp", querySkus);
+ if (!skuDetails.containsKey("DETAILS_LIST")) {
+ int response = getResponseCodeFromBundle(skuDetails);
+ if (response != BILLING_RESPONSE_RESULT_OK) {
+ godotPaymentV3.errorSkuDetail(getResponseDesc(response));
+ } else {
+ godotPaymentV3.errorSkuDetail("No error but no detail list.");
}
+ return;
+ }
- ArrayList<String> responseList = skuDetails.getStringArrayList("DETAILS_LIST");
+ ArrayList<String> responseList = skuDetails.getStringArrayList("DETAILS_LIST");
- for (String thisResponse : responseList) {
- Log.d("godot", "response = "+thisResponse);
- godotPaymentV3.addSkuDetail(thisResponse);
- }
- } catch (RemoteException e) {
- e.printStackTrace();
- godotPaymentV3.errorSkuDetail("RemoteException error!");
+ for (String thisResponse : responseList) {
+ Log.d("godot", "response = "+thisResponse);
+ godotPaymentV3.addSkuDetail(thisResponse);
}
+ } catch (RemoteException e) {
+ e.printStackTrace();
+ godotPaymentV3.errorSkuDetail("RemoteException error!");
}
- godotPaymentV3.completeSkuDetail();
}
+ godotPaymentV3.completeSkuDetail();
}
})).start();
}
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 5ad96b35ee..81352b0cf4 100644
--- a/platform/android/java/src/org/godotengine/godot/payments/PurchaseTask.java
+++ b/platform/android/java/src/org/godotengine/godot/payments/PurchaseTask.java
@@ -6,6 +6,7 @@
/* http://www.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 */
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 60a43a9070..9d40371b9b 100644
--- a/platform/android/java/src/org/godotengine/godot/payments/ReleaseAllConsumablesTask.java
+++ b/platform/android/java/src/org/godotengine/godot/payments/ReleaseAllConsumablesTask.java
@@ -6,6 +6,7 @@
/* http://www.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 */
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 f09bcbf9a4..09f80df403 100644
--- a/platform/android/java/src/org/godotengine/godot/payments/ValidateTask.java
+++ b/platform/android/java/src/org/godotengine/godot/payments/ValidateTask.java
@@ -6,6 +6,7 @@
/* http://www.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 */
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 f8936bef2b..02a2fba854 100644
--- a/platform/android/java/src/org/godotengine/godot/utils/Crypt.java
+++ b/platform/android/java/src/org/godotengine/godot/utils/Crypt.java
@@ -6,6 +6,7 @@
/* http://www.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 */
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 823c75d186..7881754fb2 100644
--- a/platform/android/java/src/org/godotengine/godot/utils/CustomSSLSocketFactory.java
+++ b/platform/android/java/src/org/godotengine/godot/utils/CustomSSLSocketFactory.java
@@ -6,6 +6,7 @@
/* http://www.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 */
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 faefbbd2c6..b314fb721b 100644
--- a/platform/android/java/src/org/godotengine/godot/utils/HttpRequester.java
+++ b/platform/android/java/src/org/godotengine/godot/utils/HttpRequester.java
@@ -6,6 +6,7 @@
/* http://www.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 */
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 bb00f1f468..41d26ba70f 100644
--- a/platform/android/java/src/org/godotengine/godot/utils/RequestParams.java
+++ b/platform/android/java/src/org/godotengine/godot/utils/RequestParams.java
@@ -6,6 +6,7 @@
/* http://www.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 */
diff --git a/platform/android/java_class_wrapper.cpp b/platform/android/java_class_wrapper.cpp
index eb208f0ee0..bd266c76bf 100644
--- a/platform/android/java_class_wrapper.cpp
+++ b/platform/android/java_class_wrapper.cpp
@@ -6,6 +6,7 @@
/* http://www.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 */
@@ -189,7 +190,7 @@ bool JavaClass::_call_method(JavaObject *p_instance, const StringName &p_method,
argv[i].i = *p_args[i];
} break;
case ARG_TYPE_LONG: {
- argv[i].j = *p_args[i];
+ argv[i].j = (int64_t)*p_args[i];
} break;
case ARG_TYPE_FLOAT: {
argv[i].f = *p_args[i];
@@ -349,7 +350,7 @@ bool JavaClass::_call_method(JavaObject *p_instance, const StringName &p_method,
Array arr = *p_args[i];
jlongArray a = env->NewLongArray(arr.size());
for (int j = 0; j < arr.size(); j++) {
- jlong val = arr[j];
+ jlong val = (int64_t)arr[j];
env->SetLongArrayRegion(a, j, 1, &val);
}
argv[i].l = a;
@@ -459,9 +460,9 @@ bool JavaClass::_call_method(JavaObject *p_instance, const StringName &p_method,
case ARG_TYPE_LONG: {
if (method->_static) {
- ret = env->CallStaticLongMethodA(_class, method->method, argv);
+ ret = (int64_t)env->CallStaticLongMethodA(_class, method->method, argv);
} else {
- ret = env->CallLongMethodA(p_instance->instance, method->method, argv);
+ ret = (int64_t)env->CallLongMethodA(p_instance->instance, method->method, argv);
}
} break;
@@ -545,7 +546,7 @@ JavaObject::~JavaObject() {
void JavaClassWrapper::_bind_methods() {
- ClassDB::bind_method(D_METHOD("wrap:JavaClass", "name"), &JavaClassWrapper::wrap);
+ ClassDB::bind_method(D_METHOD("wrap", "name"), &JavaClassWrapper::wrap);
}
bool JavaClassWrapper::_get_type_sig(JNIEnv *env, jobject obj, uint32_t &sig, String &strsig) {
@@ -679,7 +680,7 @@ bool JavaClass::_convert_object_to_variant(JNIEnv *env, jobject obj, Variant &va
} break;
case ARG_TYPE_LONG | ARG_NUMBER_CLASS_BIT: {
- var = env->CallLongMethod(obj, JavaClassWrapper::singleton->Long_longValue);
+ var = (int64_t)env->CallLongMethod(obj, JavaClassWrapper::singleton->Long_longValue);
return true;
} break;
@@ -801,7 +802,7 @@ bool JavaClass::_convert_object_to_variant(JNIEnv *env, jobject obj, Variant &va
jlong val;
env->GetLongArrayRegion((jlongArray)arr, 0, 1, &val);
- ret.push_back(val);
+ ret.push_back((int64_t)val);
}
var = ret;
diff --git a/platform/android/java_class_wrapper.h b/platform/android/java_class_wrapper.h
index 12ef92c45b..f990708bdf 100644
--- a/platform/android/java_class_wrapper.h
+++ b/platform/android/java_class_wrapper.h
@@ -6,6 +6,7 @@
/* http://www.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 */
diff --git a/platform/android/java_glue.cpp b/platform/android/java_glue.cpp
index 06ef581813..683e1cfb22 100644
--- a/platform/android/java_glue.cpp
+++ b/platform/android/java_glue.cpp
@@ -6,6 +6,7 @@
/* http://www.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 */
@@ -35,11 +36,11 @@
#include "dir_access_jandroid.h"
#include "file_access_android.h"
#include "file_access_jandroid.h"
-#include "global_config.h"
#include "java_class_wrapper.h"
#include "main/input_default.h"
#include "main/main.h"
#include "os_android.h"
+#include "project_settings.h"
#include "thread_jandroid.h"
#include <unistd.h>
@@ -609,7 +610,7 @@ struct JAndroidPointerEvent {
};
static List<JAndroidPointerEvent> pointer_events;
-static List<InputEvent> key_events;
+static List<Ref<InputEvent> > key_events;
static List<OS_Android::JoypadEvent> joy_events;
static bool initialized = false;
static Mutex *input_mutex = NULL;
@@ -882,7 +883,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_initialize(JNIEnv *en
__android_log_print(ANDROID_LOG_INFO, "godot", "*****SETUP OK");
//video driver is determined here, because once initialized, it can't be changed
- String vd = GlobalConfig::get_singleton()->get("display/driver");
+ String vd = ProjectSettings::get_singleton()->get("display/driver");
env->CallVoidMethod(_godot_instance, _on_video_init, (jboolean) true);
@@ -894,7 +895,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_initialize(JNIEnv *en
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_resize(JNIEnv *env, jobject obj, jint width, jint height, jboolean reload) {
- __android_log_print(ANDROID_LOG_INFO, "godot", "^_^_^_^_^ resize %lld, %i, %i\n", Thread::get_caller_ID(), width, height);
+ __android_log_print(ANDROID_LOG_INFO, "godot", "^_^_^_^_^ resize %lld, %i, %i\n", Thread::get_caller_id(), width, height);
if (os_android)
os_android->set_display_size(Size2(width, height));
@@ -908,7 +909,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_resize(JNIEnv *env, j
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_newcontext(JNIEnv *env, jobject obj, bool p_32_bits) {
- __android_log_print(ANDROID_LOG_INFO, "godot", "^_^_^_^_^ newcontext %lld\n", Thread::get_caller_ID());
+ __android_log_print(ANDROID_LOG_INFO, "godot", "^_^_^_^_^ newcontext %lld\n", Thread::get_caller_id());
if (os_android) {
os_android->set_context_is_16_bits(!p_32_bits);
@@ -929,12 +930,12 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_back(JNIEnv *env, job
static void _initialize_java_modules() {
- if (!GlobalConfig::get_singleton()->has("android/modules")) {
+ if (!ProjectSettings::get_singleton()->has("android/modules")) {
print_line("ANDROID MODULES: Nothing to load, aborting");
return;
}
- String modules = GlobalConfig::get_singleton()->get("android/modules");
+ String modules = ProjectSettings::get_singleton()->get("android/modules");
modules = modules.strip_edges();
if (modules == String()) {
return;
@@ -994,7 +995,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_step(JNIEnv *env, job
ThreadAndroid::setup_thread();
- //__android_log_print(ANDROID_LOG_INFO,"godot","**STEP EVENT! - %p-%i\n",env,Thread::get_caller_ID());
+ //__android_log_print(ANDROID_LOG_INFO,"godot","**STEP EVENT! - %p-%i\n",env,Thread::get_caller_id());
suspend_mutex->lock();
input_mutex->lock();
@@ -1004,7 +1005,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_step(JNIEnv *env, job
// because of the way android forces you to do everything with threads
java_class_wrapper = memnew(JavaClassWrapper(_godot_instance));
- GlobalConfig::get_singleton()->add_singleton(GlobalConfig::Singleton("JavaClassWrapper", java_class_wrapper));
+ ProjectSettings::get_singleton()->add_singleton(ProjectSettings::Singleton("JavaClassWrapper", java_class_wrapper));
_initialize_java_modules();
Main::setup2();
@@ -1035,7 +1036,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_step(JNIEnv *env, job
while (key_events.size()) {
- InputEvent event = key_events.front()->get();
+ Ref<InputEvent> event = key_events.front()->get();
os_android->process_event(event);
key_events.pop_front();
@@ -1068,7 +1069,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_step(JNIEnv *env, job
jclass cls = env->FindClass("org/godotengine/godot/Godot");
jmethodID _finish = env->GetMethodID(cls, "forceQuit", "()V");
env->CallVoidMethod(_godot_instance, _finish);
- __android_log_print(ANDROID_LOG_INFO, "godot", "**FINISH REQUEST!!! - %p-%i\n", env, Thread::get_caller_ID());
+ __android_log_print(ANDROID_LOG_INFO, "godot", "**FINISH REQUEST!!! - %p-%i\n", env, Thread::get_caller_id());
}
suspend_mutex->unlock();
@@ -1076,7 +1077,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_step(JNIEnv *env, job
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_touch(JNIEnv *env, jobject obj, jint ev, jint pointer, jint count, jintArray positions) {
- //__android_log_print(ANDROID_LOG_INFO,"godot","**TOUCH EVENT! - %p-%i\n",env,Thread::get_caller_ID());
+ //__android_log_print(ANDROID_LOG_INFO,"godot","**TOUCH EVENT! - %p-%i\n",env,Thread::get_caller_id());
Vector<OS_Android::TouchPos> points;
for (int i = 0; i < count; i++) {
@@ -1418,30 +1419,23 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joyconnectionchanged(
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_key(JNIEnv *env, jobject obj, jint p_scancode, jint p_unicode_char, jboolean p_pressed) {
- InputEvent ievent;
- ievent.type = InputEvent::KEY;
- ievent.device = 0;
+ Ref<InputEventKey> ievent;
int val = p_unicode_char;
int scancode = android_get_keysym(p_scancode);
- ievent.key.scancode = scancode;
- ievent.key.unicode = val;
- ievent.key.pressed = p_pressed;
+ ievent->set_scancode(scancode);
+ ievent->set_unicode(val);
+ ievent->set_pressed(p_pressed);
- print_line("Scancode: " + String::num(p_scancode) + ":" + String::num(ievent.key.scancode) + " Unicode: " + String::num(val));
-
- ievent.key.mod.shift = false;
- ievent.key.mod.alt = false;
- ievent.key.mod.control = false;
- ievent.key.echo = false;
+ print_line("Scancode: " + String::num(p_scancode) + ":" + String::num(ievent->get_scancode()) + " Unicode: " + String::num(val));
if (val == '\n') {
- ievent.key.scancode = KEY_ENTER;
+ ievent->set_scancode(KEY_ENTER);
} else if (val == 61448) {
- ievent.key.scancode = KEY_BACKSPACE;
- ievent.key.unicode = KEY_BACKSPACE;
+ ievent->set_scancode(KEY_BACKSPACE);
+ ievent->set_unicode(KEY_BACKSPACE);
} else if (val == 61453) {
- ievent.key.scancode = KEY_ENTER;
- ievent.key.unicode = KEY_ENTER;
+ ievent->set_scancode(KEY_ENTER);
+ ievent->set_unicode(KEY_ENTER);
} else if (p_scancode == 4) {
go_back_request = true;
@@ -1510,8 +1504,8 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_singleton(JNIEnv *env
s->set_instance(env->NewGlobalRef(p_object));
jni_singletons[singname] = s;
- GlobalConfig::get_singleton()->add_singleton(GlobalConfig::Singleton(singname, s));
- GlobalConfig::get_singleton()->set(singname, s);
+ ProjectSettings::get_singleton()->add_singleton(ProjectSettings::Singleton(singname, s));
+ ProjectSettings::get_singleton()->set(singname, s);
}
static Variant::Type get_jni_type(const String &p_type) {
@@ -1584,7 +1578,7 @@ JNIEXPORT jstring JNICALL Java_org_godotengine_godot_GodotLib_getGlobal(JNIEnv *
String js = env->GetStringUTFChars(path, NULL);
- return env->NewStringUTF(GlobalConfig::get_singleton()->get(js).operator String().utf8().get_data());
+ return env->NewStringUTF(ProjectSettings::get_singleton()->get(js).operator String().utf8().get_data());
}
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_method(JNIEnv *env, jobject obj, jstring sname, jstring name, jstring ret, jobjectArray args) {
diff --git a/platform/android/java_glue.h b/platform/android/java_glue.h
index 51a2031867..bcb3304c3e 100644
--- a/platform/android/java_glue.h
+++ b/platform/android/java_glue.h
@@ -6,6 +6,7 @@
/* http://www.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 */
@@ -55,8 +56,8 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_focusout(JNIEnv *env,
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_singleton(JNIEnv *env, jobject obj, jstring name, jobject p_object);
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_method(JNIEnv *env, jobject obj, jstring sname, jstring name, jstring ret, jobjectArray args);
JNIEXPORT jstring JNICALL Java_org_godotengine_godot_GodotLib_getGlobal(JNIEnv *env, jobject obj, jstring path);
-JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_callobject(JNIEnv *env, jobject obj, jint ID, jstring method, jobjectArray params);
-JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_calldeferred(JNIEnv *env, jobject obj, jint ID, jstring method, jobjectArray params);
+JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_callobject(JNIEnv *env, jobject p_obj, jint ID, jstring method, jobjectArray params);
+JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_calldeferred(JNIEnv *env, jobject p_obj, jint ID, jstring method, jobjectArray params);
}
#endif
diff --git a/platform/android/os_android.cpp b/platform/android/os_android.cpp
index 1484ccfb8c..a027e78de9 100644
--- a/platform/android/os_android.cpp
+++ b/platform/android/os_android.cpp
@@ -6,6 +6,7 @@
/* http://www.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 */
@@ -28,8 +29,8 @@
/*************************************************************************/
#include "os_android.h"
-#include "core/global_config.h"
#include "core/io/file_access_buffered_fa.h"
+#include "core/project_settings.h"
#include "drivers/gles3/rasterizer_gles3.h"
#include "drivers/unix/dir_access_unix.h"
#include "drivers/unix/file_access_unix.h"
@@ -129,12 +130,12 @@ void OS_Android::initialize(const VideoMode &p_desired, int p_video_driver, int
RasterizerGLES3::make_current();
visual_server = memnew(VisualServerRaster);
-/* if (get_render_thread_mode() != RENDER_THREAD_UNSAFE) {
+ /* if (get_render_thread_mode() != RENDER_THREAD_UNSAFE) {
visual_server = memnew(VisualServerWrapMT(visual_server, false));
};*/
visual_server->init();
- visual_server->cursor_set_visible(false, 0);
+ // visual_server->cursor_set_visible(false, 0);
AudioDriverManager::get_driver(p_audio_driver)->set_singleton();
@@ -244,7 +245,7 @@ bool OS_Android::is_mouse_grab_enabled() const {
return false;
}
-Point2 OS_Android::get_mouse_pos() const {
+Point2 OS_Android::get_mouse_position() const {
return Point2();
}
@@ -343,25 +344,24 @@ void OS_Android::process_joy_event(OS_Android::JoypadEvent p_event) {
switch (p_event.type) {
case JOY_EVENT_BUTTON:
- last_id = input->joy_button(last_id, p_event.device, p_event.index, p_event.pressed);
+ input->joy_button(p_event.device, p_event.index, p_event.pressed);
break;
case JOY_EVENT_AXIS:
InputDefault::JoyAxis value;
value.min = -1;
value.value = p_event.value;
- last_id = input->joy_axis(last_id, p_event.device, p_event.index, value);
+ input->joy_axis(p_event.device, p_event.index, value);
break;
case JOY_EVENT_HAT:
- last_id = input->joy_hat(last_id, p_event.device, p_event.hat);
+ input->joy_hat(p_event.device, p_event.hat);
break;
default:
return;
}
}
-void OS_Android::process_event(InputEvent p_event) {
+void OS_Android::process_event(Ref<InputEvent> p_event) {
- p_event.ID = last_id++;
input->parse_input_event(p_event);
}
@@ -374,27 +374,24 @@ void OS_Android::process_touch(int p_what, int p_pointer, const Vector<TouchPos>
if (touch.size()) {
//end all if exist
- InputEvent ev;
- ev.type = InputEvent::MOUSE_BUTTON;
- ev.ID = last_id++;
- ev.mouse_button.button_index = BUTTON_LEFT;
- ev.mouse_button.button_mask = BUTTON_MASK_LEFT;
- ev.mouse_button.pressed = false;
- ev.mouse_button.x = touch[0].pos.x;
- ev.mouse_button.y = touch[0].pos.y;
- ev.mouse_button.global_x = touch[0].pos.x;
- ev.mouse_button.global_y = touch[0].pos.y;
- input->parse_input_event(ev);
+ {
+ Ref<InputEventMouseButton> ev;
+ ev.instance();
+ ev->set_button_index(BUTTON_LEFT);
+ ev->set_button_mask(BUTTON_MASK_LEFT);
+ ev->set_pressed(false);
+ ev->set_position(touch[0].pos);
+ ev->set_global_position(touch[0].pos);
+ input->parse_input_event(ev);
+ }
for (int i = 0; i < touch.size(); i++) {
- InputEvent ev;
- ev.type = InputEvent::SCREEN_TOUCH;
- ev.ID = last_id++;
- ev.screen_touch.index = touch[i].id;
- ev.screen_touch.pressed = false;
- ev.screen_touch.x = touch[i].pos.x;
- ev.screen_touch.y = touch[i].pos.y;
+ Ref<InputEventScreenTouch> ev;
+ ev.instance();
+ ev->set_index(touch[i].id);
+ ev->set_pressed(false);
+ ev->set_position(touch[i].pos);
input->parse_input_event(ev);
}
}
@@ -407,17 +404,15 @@ void OS_Android::process_touch(int p_what, int p_pointer, const Vector<TouchPos>
{
//send mouse
- InputEvent ev;
- ev.type = InputEvent::MOUSE_BUTTON;
- ev.ID = last_id++;
- ev.mouse_button.button_index = BUTTON_LEFT;
- ev.mouse_button.button_mask = BUTTON_MASK_LEFT;
- ev.mouse_button.pressed = true;
- ev.mouse_button.x = touch[0].pos.x;
- ev.mouse_button.y = touch[0].pos.y;
- ev.mouse_button.global_x = touch[0].pos.x;
- ev.mouse_button.global_y = touch[0].pos.y;
- input->set_mouse_pos(Point2(touch[0].pos.x,touch[0].pos.y));
+ Ref<InputEventMouseButton> ev;
+ ev.instance();
+ // ev.type = Ref<InputEvent>::MOUSE_BUTTON;
+ ev->set_button_index(BUTTON_LEFT);
+ ev->set_button_mask(BUTTON_MASK_LEFT);
+ ev->set_pressed(true);
+ ev->set_position(touch[0].pos);
+ ev->set_global_position(touch[0].pos);
+ input->set_mouse_position(Point2(touch[0].pos.x, touch[0].pos.y));
last_mouse = touch[0].pos;
input->parse_input_event(ev);
}
@@ -425,13 +420,11 @@ void OS_Android::process_touch(int p_what, int p_pointer, const Vector<TouchPos>
//send touch
for (int i = 0; i < touch.size(); i++) {
- InputEvent ev;
- ev.type = InputEvent::SCREEN_TOUCH;
- ev.ID = last_id++;
- ev.screen_touch.index = touch[i].id;
- ev.screen_touch.pressed = true;
- ev.screen_touch.x = touch[i].pos.x;
- ev.screen_touch.y = touch[i].pos.y;
+ Ref<InputEventScreenTouch> ev;
+ ev.instance();
+ ev->set_index(touch[i].id);
+ ev->set_pressed(true);
+ ev->set_position(touch[i].pos);
input->parse_input_event(ev);
}
@@ -440,17 +433,13 @@ void OS_Android::process_touch(int p_what, int p_pointer, const Vector<TouchPos>
if (p_points.size()) {
//send mouse, should look for point 0?
- InputEvent ev;
- ev.type = InputEvent::MOUSE_MOTION;
- ev.ID = last_id++;
- ev.mouse_motion.button_mask = BUTTON_MASK_LEFT;
- ev.mouse_motion.x = p_points[0].pos.x;
- ev.mouse_motion.y = p_points[0].pos.y;
- input->set_mouse_pos(Point2(ev.mouse_motion.x, ev.mouse_motion.y));
- ev.mouse_motion.speed_x = input->get_last_mouse_speed().x;
- ev.mouse_motion.speed_y = input->get_last_mouse_speed().y;
- ev.mouse_motion.relative_x = p_points[0].pos.x - last_mouse.x;
- ev.mouse_motion.relative_y = p_points[0].pos.y - last_mouse.y;
+ Ref<InputEventMouseMotion> ev;
+ ev.instance();
+ ev->set_button_mask(BUTTON_MASK_LEFT);
+ ev->set_position(p_points[0].pos);
+ input->set_mouse_position(Point2(ev->get_position().x, ev->get_position().y));
+ ev->set_speed(input->get_last_mouse_speed());
+ ev->set_relative(p_points[0].pos - last_mouse);
last_mouse = p_points[0].pos;
input->parse_input_event(ev);
}
@@ -473,14 +462,11 @@ void OS_Android::process_touch(int p_what, int p_pointer, const Vector<TouchPos>
if (touch[i].pos == p_points[idx].pos)
continue; //no move unncesearily
- InputEvent ev;
- ev.type = InputEvent::SCREEN_DRAG;
- ev.ID = last_id++;
- ev.screen_drag.index = touch[i].id;
- ev.screen_drag.x = p_points[idx].pos.x;
- ev.screen_drag.y = p_points[idx].pos.y;
- ev.screen_drag.relative_x = p_points[idx].pos.x - touch[i].pos.x;
- ev.screen_drag.relative_y = p_points[idx].pos.y - touch[i].pos.y;
+ Ref<InputEventScreenDrag> ev;
+ ev.instance();
+ ev->set_index(touch[i].id);
+ ev->set_position(p_points[idx].pos);
+ ev->set_relative(p_points[idx].pos - touch[i].pos);
input->parse_input_event(ev);
touch[i].pos = p_points[idx].pos;
}
@@ -490,28 +476,23 @@ void OS_Android::process_touch(int p_what, int p_pointer, const Vector<TouchPos>
if (touch.size()) {
//end all if exist
- InputEvent ev;
- ev.type = InputEvent::MOUSE_BUTTON;
- ev.ID = last_id++;
- ev.mouse_button.button_index = BUTTON_LEFT;
- ev.mouse_button.button_mask = BUTTON_MASK_LEFT;
- ev.mouse_button.pressed = false;
- ev.mouse_button.x = touch[0].pos.x;
- ev.mouse_button.y = touch[0].pos.y;
- ev.mouse_button.global_x = touch[0].pos.x;
- ev.mouse_button.global_y = touch[0].pos.y;
- input->set_mouse_pos(Point2(touch[0].pos.x,touch[0].pos.y));
+ Ref<InputEventMouseButton> ev;
+ ev.instance();
+ ev->set_button_index(BUTTON_LEFT);
+ ev->set_button_mask(BUTTON_MASK_LEFT);
+ ev->set_pressed(false);
+ ev->set_position(touch[0].pos);
+ ev->set_global_position(touch[0].pos);
+ input->set_mouse_position(Point2(touch[0].pos.x, touch[0].pos.y));
input->parse_input_event(ev);
for (int i = 0; i < touch.size(); i++) {
- InputEvent ev;
- ev.type = InputEvent::SCREEN_TOUCH;
- ev.ID = last_id++;
- ev.screen_touch.index = touch[i].id;
- ev.screen_touch.pressed = false;
- ev.screen_touch.x = touch[i].pos.x;
- ev.screen_touch.y = touch[i].pos.y;
+ Ref<InputEventScreenTouch> ev;
+ ev.instance();
+ ev->set_index(touch[i].id);
+ ev->set_pressed(false);
+ ev->set_position(touch[i].pos);
input->parse_input_event(ev);
}
touch.clear();
@@ -525,13 +506,12 @@ void OS_Android::process_touch(int p_what, int p_pointer, const Vector<TouchPos>
TouchPos tp = p_points[p_pointer];
touch.push_back(tp);
- InputEvent ev;
- ev.type = InputEvent::SCREEN_TOUCH;
- ev.ID = last_id++;
- ev.screen_touch.index = tp.id;
- ev.screen_touch.pressed = true;
- ev.screen_touch.x = tp.pos.x;
- ev.screen_touch.y = tp.pos.y;
+ Ref<InputEventScreenTouch> ev;
+ ev.instance();
+
+ ev->set_index(tp.id);
+ ev->set_pressed(true);
+ ev->set_position(tp.pos);
input->parse_input_event(ev);
} break;
@@ -540,13 +520,11 @@ void OS_Android::process_touch(int p_what, int p_pointer, const Vector<TouchPos>
for (int i = 0; i < touch.size(); i++) {
if (touch[i].id == p_pointer) {
- InputEvent ev;
- ev.type = InputEvent::SCREEN_TOUCH;
- ev.ID = last_id++;
- ev.screen_touch.index = touch[i].id;
- ev.screen_touch.pressed = false;
- ev.screen_touch.x = touch[i].pos.x;
- ev.screen_touch.y = touch[i].pos.y;
+ Ref<InputEventScreenTouch> ev;
+ ev.instance();
+ ev->set_index(touch[i].id);
+ ev->set_pressed(false);
+ ev->set_position(touch[i].pos);
input->parse_input_event(ev);
touch.remove(i);
i--;
@@ -627,8 +605,8 @@ void OS_Android::reload_gfx() {
if (gfx_init_func)
gfx_init_func(gfx_init_ud, use_gl2);
-// if (rasterizer)
-// rasterizer->reload_vram();
+ //if (rasterizer)
+ // rasterizer->reload_vram();
}
Error OS_Android::shell_open(String p_uri) {
@@ -699,7 +677,7 @@ String OS_Android::get_data_dir() const {
}
return ".";
- //return GlobalConfig::get_singleton()->get_singleton_object("GodotOS")->call("get_data_dir");
+ //return ProjectSettings::get_singleton()->get_singleton_object("GodotOS")->call("get_data_dir");
}
void OS_Android::set_screen_orientation(ScreenOrientation p_orientation) {
@@ -708,11 +686,11 @@ void OS_Android::set_screen_orientation(ScreenOrientation p_orientation) {
set_screen_orientation_func(p_orientation);
}
-String OS_Android::get_unique_ID() const {
+String OS_Android::get_unique_id() const {
if (get_unique_id_func)
return get_unique_id_func();
- return OS::get_unique_ID();
+ return OS::get_unique_id();
}
Error OS_Android::native_video_play(String p_path, float p_volume) {
@@ -746,9 +724,9 @@ void OS_Android::native_video_stop() {
void OS_Android::set_context_is_16_bits(bool p_is_16) {
-// use_16bits_fbo = p_is_16;
-// if (rasterizer)
-// rasterizer->set_force_16_bits_fbo(p_is_16);
+ //use_16bits_fbo = p_is_16;
+ //if (rasterizer)
+ // rasterizer->set_force_16_bits_fbo(p_is_16);
}
void OS_Android::joy_connection_changed(int p_device, bool p_connected, String p_name) {
@@ -763,6 +741,10 @@ String OS_Android::get_joy_guid(int p_device) const {
return input->get_joy_guid_remapped(p_device);
}
+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
+}
+
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, 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;
@@ -774,9 +756,8 @@ OS_Android::OS_Android(GFXInitFunc p_gfx_init_func, void *p_gfx_init_ud, OpenURI
gfx_init_func = p_gfx_init_func;
gfx_init_ud = p_gfx_init_ud;
main_loop = NULL;
- last_id = 1;
gl_extensions = NULL;
-// rasterizer = NULL;
+ //rasterizer = NULL;
use_gl2 = false;
open_uri_func = p_open_uri_func;
diff --git a/platform/android/os_android.h b/platform/android/os_android.h
index ad438d8626..54d7e562e0 100644
--- a/platform/android/os_android.h
+++ b/platform/android/os_android.h
@@ -6,6 +6,7 @@
/* http://www.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 */
@@ -94,7 +95,6 @@ private:
Vector<TouchPos> touch;
Point2 last_mouse;
- unsigned int last_id;
GFXInitFunc gfx_init_func;
void *gfx_init_ud;
@@ -171,7 +171,7 @@ public:
virtual void set_mouse_show(bool p_show);
virtual void set_mouse_grab(bool p_grab);
virtual bool is_mouse_grab_enabled() const;
- virtual Point2 get_mouse_pos() const;
+ virtual Point2 get_mouse_position() const;
virtual int get_mouse_button_state() const;
virtual void set_window_title(const String &p_title);
@@ -222,7 +222,7 @@ public:
virtual String get_model_name() const;
virtual int get_screen_dpi(int p_screen = 0) const;
- virtual String get_unique_ID() const;
+ virtual String get_unique_id() const;
virtual String get_system_dir(SystemDir p_dir) const;
@@ -231,7 +231,7 @@ public:
void process_gyroscope(const Vector3 &p_gyroscope);
void process_touch(int p_what, int p_pointer, const Vector<TouchPos> &p_points);
void process_joy_event(JoypadEvent p_event);
- void process_event(InputEvent p_event);
+ void process_event(Ref<InputEvent> p_event);
void init_video_mode(int p_video_width, int p_video_height);
virtual Error native_video_play(String p_path, float p_volume);
@@ -243,6 +243,7 @@ public:
virtual String get_joy_guid(int p_device) const;
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, 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/platform_config.h b/platform/android/platform_config.h
index cdef185ff0..48bcadcc29 100644
--- a/platform/android/platform_config.h
+++ b/platform/android/platform_config.h
@@ -6,6 +6,7 @@
/* http://www.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 */
diff --git a/platform/android/power_android.cpp b/platform/android/power_android.cpp
index aa37dc51e2..bb5a1db250 100644
--- a/platform/android/power_android.cpp
+++ b/platform/android/power_android.cpp
@@ -6,6 +6,7 @@
/* http://www.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 */
@@ -27,10 +28,35 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "core/error_macros.h"
+/*
+Adapted from corresponding SDL 2.0 code.
+*/
+
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
#include "power_android.h"
+#include "core/error_macros.h"
+
static void LocalReferenceHolder_Cleanup(struct LocalReferenceHolder *refholder) {
if (refholder->m_env) {
JNIEnv *env = refholder->m_env;
diff --git a/platform/android/power_android.h b/platform/android/power_android.h
index df4983bbf3..328a4506a1 100644
--- a/platform/android/power_android.h
+++ b/platform/android/power_android.h
@@ -6,6 +6,7 @@
/* http://www.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 */
diff --git a/platform/android/run_icon.png b/platform/android/run_icon.png
new file mode 100644
index 0000000000..e53f8e9da5
--- /dev/null
+++ b/platform/android/run_icon.png
Binary files differ
diff --git a/platform/android/thread_jandroid.cpp b/platform/android/thread_jandroid.cpp
index 854cdb1e34..924ae3fe43 100644
--- a/platform/android/thread_jandroid.cpp
+++ b/platform/android/thread_jandroid.cpp
@@ -6,6 +6,7 @@
/* http://www.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 */
@@ -31,7 +32,7 @@
#include "os/memory.h"
#include "script_language.h"
-Thread::ID ThreadAndroid::get_ID() const {
+Thread::ID ThreadAndroid::get_id() const {
return id;
}
@@ -65,7 +66,7 @@ Thread *ThreadAndroid::create_func_jandroid(ThreadCreateCallback p_callback, voi
return tr;
}
-Thread::ID ThreadAndroid::get_thread_ID_func_jandroid() {
+Thread::ID ThreadAndroid::get_thread_id_func_jandroid() {
return (ID)pthread_self();
}
@@ -106,7 +107,7 @@ void ThreadAndroid::make_default(JavaVM *p_java_vm) {
java_vm = p_java_vm;
create_func = create_func_jandroid;
- get_thread_ID_func = get_thread_ID_func_jandroid;
+ get_thread_id_func = get_thread_id_func_jandroid;
wait_to_finish_func = wait_to_finish_func_jandroid;
pthread_key_create(&jvm_key, _thread_destroyed);
setup_thread();
diff --git a/platform/android/thread_jandroid.h b/platform/android/thread_jandroid.h
index a8d8a4d8b1..5267329744 100644
--- a/platform/android/thread_jandroid.h
+++ b/platform/android/thread_jandroid.h
@@ -6,6 +6,7 @@
/* http://www.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 */
@@ -51,7 +52,7 @@ class ThreadAndroid : public Thread {
static void *thread_callback(void *userdata);
static Thread *create_func_jandroid(ThreadCreateCallback p_callback, void *, const Settings &);
- static ID get_thread_ID_func_jandroid();
+ static ID get_thread_id_func_jandroid();
static void wait_to_finish_func_jandroid(Thread *p_thread);
static void _thread_destroyed(void *value);
@@ -61,7 +62,7 @@ class ThreadAndroid : public Thread {
static JavaVM *java_vm;
public:
- virtual ID get_ID() const;
+ virtual ID get_id() const;
static void make_default(JavaVM *p_java_vm);
static void setup_thread();
diff --git a/platform/bb10/SCsub b/platform/bb10/SCsub
deleted file mode 100644
index c19f46d579..0000000000
--- a/platform/bb10/SCsub
+++ /dev/null
@@ -1,23 +0,0 @@
-#!/usr/bin/env python
-
-Import('env')
-
-bb10_lib = [
-
- 'bbutil.c',
- 'os_bb10.cpp',
- 'audio_driver_bb10.cpp',
- 'godot_bb10.cpp',
- 'payment_service.cpp',
-]
-
-env_bps = env.Clone()
-if env['bb10_payment_service'] == "yes":
- env_bps.Append(CPPFLAGS=['-DPAYMENT_SERVICE_ENABLED'])
-
-if env['bb10_lgles_override'] == "yes":
- env_bps.Append(CPPFLAGS=['-DBB10_LGLES_OVERRIDE'])
-
-
-prog = None
-prog = env_bps.Program('#bin/godot', bb10_lib)
diff --git a/platform/bb10/audio_driver_bb10.cpp b/platform/bb10/audio_driver_bb10.cpp
deleted file mode 100644
index 5416fc5f02..0000000000
--- a/platform/bb10/audio_driver_bb10.cpp
+++ /dev/null
@@ -1,253 +0,0 @@
-/*************************************************************************/
-/* audio_driver_bb10.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* http://www.godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
-/* */
-/* 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 "audio_driver_bb10.h"
-
-#include <errno.h>
-
-Error AudioDriverBB10::init() {
- return init(NULL);
-};
-
-Error AudioDriverBB10::init(const char *p_name) {
-
- active = false;
- thread_exited = false;
- exit_thread = false;
- pcm_open = false;
- samples_in = NULL;
- samples_out = NULL;
-
- mix_rate = 44100;
- speaker_mode = SPEAKER_MODE_STEREO;
-
- char *dev_name;
- if (p_name == NULL) {
- dev_name = "pcmPreferred";
- } else {
- dev_name = (char *)p_name;
- }
- printf("******** reconnecting to device %s\n", dev_name);
- int ret = snd_pcm_open_name(&pcm_handle, dev_name, SND_PCM_OPEN_PLAYBACK);
- ERR_FAIL_COND_V(ret < 0, FAILED);
- pcm_open = true;
-
- snd_pcm_channel_info_t cinfo;
- zeromem(&cinfo, sizeof(cinfo));
- cinfo.channel = SND_PCM_CHANNEL_PLAYBACK;
- snd_pcm_plugin_info(pcm_handle, &cinfo);
-
- printf("rates %i, %i, %i, %i, %i\n", cinfo.rates, cinfo.rates & SND_PCM_RATE_44100, cinfo.rates & SND_PCM_RATE_32000, cinfo.rates & SND_PCM_RATE_22050, cinfo.max_rate);
-
- mix_rate = cinfo.max_rate;
-
- printf("formats %i, %i, %i\n", cinfo.formats, cinfo.formats & SND_PCM_FMT_S16_BE, cinfo.formats & SND_PCM_FMT_S16_LE);
- ERR_FAIL_COND_V(!(cinfo.formats & SND_PCM_FMT_S16_LE), FAILED);
-
- printf("voices %i\n", cinfo.max_voices);
- speaker_mode = SPEAKER_MODE_STEREO;
-
- snd_pcm_channel_params_t cp;
- zeromem(&cp, sizeof(cp));
- cp.mode = SND_PCM_MODE_BLOCK;
- cp.channel = SND_PCM_CHANNEL_PLAYBACK;
- cp.start_mode = SND_PCM_START_DATA;
- cp.stop_mode = SND_PCM_STOP_STOP;
- //cp.buf.block.frag_size = cinfo.max_fragment_size;
- cp.buf.block.frag_size = 512;
- cp.buf.block.frags_max = 1;
- cp.buf.block.frags_min = 1;
- cp.format.interleave = 1;
- cp.format.rate = mix_rate;
- cp.format.voices = speaker_mode;
- cp.format.format = SND_PCM_SFMT_S16_LE;
-
- ret = snd_pcm_plugin_params(pcm_handle, &cp);
- printf("ret is %i, %i\n", ret, cp.why_failed);
- ERR_FAIL_COND_V(ret < 0, FAILED);
-
- ret = snd_pcm_plugin_prepare(pcm_handle, SND_PCM_CHANNEL_PLAYBACK);
- ERR_FAIL_COND_V(ret < 0, FAILED);
-
- snd_mixer_group_t group;
- zeromem(&group, sizeof(group));
- snd_pcm_channel_setup_t setup;
- zeromem(&setup, sizeof(setup));
- setup.channel = SND_PCM_CHANNEL_PLAYBACK;
- setup.mode = SND_PCM_MODE_BLOCK;
- setup.mixer_gid = &group.gid;
- ret = snd_pcm_plugin_setup(pcm_handle, &setup);
- ERR_FAIL_COND_V(ret < 0, FAILED);
-
- pcm_frag_size = setup.buf.block.frag_size;
- pcm_max_frags = 1;
-
- sample_buf_count = pcm_frag_size * pcm_max_frags / 2;
- printf("sample count %i, %i, %i\n", sample_buf_count, pcm_frag_size, pcm_max_frags);
- samples_in = memnew_arr(int32_t, sample_buf_count);
- samples_out = memnew_arr(int16_t, sample_buf_count);
-
- thread = Thread::create(AudioDriverBB10::thread_func, this);
-
- return OK;
-};
-
-void AudioDriverBB10::thread_func(void *p_udata) {
-
- AudioDriverBB10 *ad = (AudioDriverBB10 *)p_udata;
-
- int channels = speaker_mode;
- int frame_count = ad->sample_buf_count / channels;
- int bytes_out = frame_count * channels * 2;
-
- while (!ad->exit_thread) {
-
- if (!ad->active) {
-
- for (int i = 0; i < ad->sample_buf_count; i++) {
-
- ad->samples_out[i] = 0;
- };
- } else {
-
- ad->lock();
-
- ad->audio_server_process(frame_count, ad->samples_in);
-
- ad->unlock();
-
- for (int i = 0; i < frame_count * channels; i++) {
-
- ad->samples_out[i] = ad->samples_in[i] >> 16;
- }
- };
-
- int todo = bytes_out;
- int total = 0;
-
- while (todo) {
-
- uint8_t *src = (uint8_t *)ad->samples_out;
- int wrote = snd_pcm_plugin_write(ad->pcm_handle, (void *)(src + total), todo);
- if (wrote < 0) {
- // error?
- break;
- };
- total += wrote;
- todo -= wrote;
- if (wrote < todo) {
- if (ad->thread_exited) {
- break;
- };
- printf("pcm_write underrun %i, errno %i\n", (int)ad->thread_exited, errno);
- snd_pcm_channel_status_t status;
- zeromem(&status, sizeof(status));
- // put in non-blocking mode
- snd_pcm_nonblock_mode(ad->pcm_handle, 1);
- status.channel = SND_PCM_CHANNEL_PLAYBACK;
- int ret = snd_pcm_plugin_status(ad->pcm_handle, &status);
- //printf("status return %i, %i, %i, %i, %i\n", ret, errno, status.status, SND_PCM_STATUS_READY, SND_PCM_STATUS_UNDERRUN);
- snd_pcm_nonblock_mode(ad->pcm_handle, 0);
- if (ret < 0) {
- break;
- };
- if (status.status == SND_PCM_STATUS_READY ||
- status.status == SND_PCM_STATUS_UNDERRUN) {
- snd_pcm_plugin_prepare(ad->pcm_handle, SND_PCM_CHANNEL_PLAYBACK);
- } else {
- break;
- };
- };
- };
- };
-
- snd_pcm_plugin_flush(ad->pcm_handle, SND_PCM_CHANNEL_PLAYBACK);
-
- ad->thread_exited = true;
- printf("**************** audio thread exit\n");
-};
-
-void AudioDriverBB10::start() {
-
- active = true;
-};
-
-int AudioDriverBB10::get_mix_rate() const {
-
- return mix_rate;
-};
-
-AudioDriver::SpeakerMode AudioDriverBB10::get_speaker_mode() const {
-
- return speaker_mode;
-};
-
-void AudioDriverBB10::lock() {
-
- if (!thread)
- return;
- mutex->lock();
-};
-
-void AudioDriverBB10::unlock() {
-
- if (!thread)
- return;
- mutex->unlock();
-};
-
-void AudioDriverBB10::finish() {
-
- if (!thread)
- return;
-
- exit_thread = true;
- Thread::wait_to_finish(thread);
-
- if (pcm_open)
- snd_pcm_close(pcm_handle);
-
- if (samples_in) {
- memdelete_arr(samples_in);
- memdelete_arr(samples_out);
- };
-
- memdelete(thread);
- thread = NULL;
-};
-
-AudioDriverBB10::AudioDriverBB10() {
-
- mutex = Mutex::create();
-};
-
-AudioDriverBB10::~AudioDriverBB10() {
-
- memdelete(mutex);
- mutex = NULL;
-};
diff --git a/platform/bb10/audio_driver_bb10.h b/platform/bb10/audio_driver_bb10.h
deleted file mode 100644
index 2a0ed9c545..0000000000
--- a/platform/bb10/audio_driver_bb10.h
+++ /dev/null
@@ -1,76 +0,0 @@
-/*************************************************************************/
-/* audio_driver_bb10.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* http://www.godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
-/* */
-/* 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 "servers/audio_server.h"
-
-#include "core/os/mutex.h"
-#include "core/os/thread.h"
-
-#include <sys/asoundlib.h>
-
-class AudioDriverBB10 : public AudioDriver {
-
- Thread *thread;
- Mutex *mutex;
-
- snd_pcm_t *pcm_handle;
-
- int32_t *samples_in;
- int16_t *samples_out;
- int sample_buf_count;
-
- static void thread_func(void *p_udata);
-
- int mix_rate;
- SpeakerMode speaker_mode;
-
- int pcm_frag_size;
- int pcm_max_frags;
-
- bool active;
- bool thread_exited;
- mutable bool exit_thread;
- bool pcm_open;
-
-public:
- const char *get_name() const {
- return "BB10";
- };
-
- virtual Error init();
- virtual Error init(const char *p_name);
- virtual void start();
- virtual int get_mix_rate() const;
- virtual SpeakerMode get_speaker_mode() const;
- virtual void lock();
- virtual void unlock();
- virtual void finish();
-
- AudioDriverBB10();
- ~AudioDriverBB10();
-};
diff --git a/platform/bb10/bar/bar-descriptor.xml b/platform/bb10/bar/bar-descriptor.xml
deleted file mode 100644
index 0ba70b7180..0000000000
--- a/platform/bb10/bar/bar-descriptor.xml
+++ /dev/null
@@ -1,53 +0,0 @@
-<?xml version='1.0' encoding='utf-8' standalone='no'?>
-<qnx xmlns="http://www.qnx.com/schemas/application/1.0">
- <!-- BlackBerry® 10 application descriptor file.
-
- Specifies parameters for identifying, installing, and launching native applications on BlackBerry® 10 OS.
--->
- <!-- A universally unique application identifier. Must be unique across all BlackBerry applications.
- Using a reverse DNS-style name as the id is recommended. (Eg. com.example.ExampleApplication.) Required. -->
- <id>com.godot.game</id>
- <!-- The name that is displayed in the BlackBerry application installer.
- May have multiple values for each language. See samples or xsd schema file. Optional. -->
- <name>Godot Game</name>
- <!-- A string value of the format <0-999>.<0-999>.<0-999> that represents application version which can be used to check for application upgrade.
- Values can also be 1-part or 2-part. It is not necessary to have a 3-part value.
- An updated version of application must have a versionNumber value higher than the previous version. Required. -->
- <versionNumber>0.0.1</versionNumber>
- <!-- Fourth digit segment of the package version. First three segments are taken from the
- <versionNumber> element. Must be an integer from 0 to 2^16-1 -->
- <buildId>0</buildId>
- <!-- Description, displayed in the BlackBerry application installer.
- May have multiple values for each language. See samples or xsd schema file. Optional. -->
- <description>Game made with Godot Engine</description>
- <!-- Name of author which is used for signing. Must match the developer name of your development certificate. -->
- <author>You Name or Company</author>
- <authorId>authorIDherePlease</authorId>
- <!-- Unique author ID assigned by signing authority. Required if using debug tokens. -->
- <!-- <authorId>ABC1234YjsnUk235h</authorId> -->
- <initialWindow>
- <aspectRatio>landscape</aspectRatio>
- <autoOrients>false</autoOrients>
- <systemChrome>none</systemChrome>
- <transparent>false</transparent>
- </initialWindow>
- <!-- The category where the application appears. Either core.games or core.media. -->
- <category>core.games</category>
- <permission>read_device_identifying_information</permission>
- <permission>access_internet</permission>
- <asset path="data.pck">data.pck</asset>
- <configuration name="Device-Debug">
- <platformArchitecture>armle-v7</platformArchitecture>
- <asset type="Qnx/Elf" path="godot.bb10.debug.qnx.armle" entry="true">godot.bb10.debug.qnx.armle</asset>
- </configuration>
- <configuration name="Device-Release">
- <platformArchitecture>armle-v7</platformArchitecture>
- <asset type="Qnx/Elf" path="godot.bb10.opt.qnx.armle" entry="true">godot.bb10.opt.qnx.armle</asset>
- </configuration>
- <!-- The icon for the application. -->
- <icon>
- <image>icon.png</image>
- </icon>
- <!-- Ensure that shared libraries in the package are found at run-time. -->
- <env value="app/native/lib:/usr/lib/qt4/lib" var="LD_LIBRARY_PATH"/>
-</qnx>
diff --git a/platform/bb10/bar/icon.png b/platform/bb10/bar/icon.png
deleted file mode 100644
index 2161402438..0000000000
--- a/platform/bb10/bar/icon.png
+++ /dev/null
Binary files differ
diff --git a/platform/bb10/bbutil.c b/platform/bb10/bbutil.c
deleted file mode 100644
index ab3dcf69b2..0000000000
--- a/platform/bb10/bbutil.c
+++ /dev/null
@@ -1,513 +0,0 @@
-#include <assert.h>
-#include <ctype.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/keycodes.h>
-#include <time.h>
-
-#include "bbutil.h"
-
-EGLDisplay egl_disp;
-EGLSurface egl_surf;
-
-static EGLConfig egl_conf;
-static EGLContext egl_ctx;
-
-static screen_context_t screen_ctx;
-static screen_window_t screen_win;
-static screen_display_t screen_disp;
-
-
-static void
-bbutil_egl_perror(const char *msg) {
- static const char *errmsg[] = {
- "function succeeded",
- "EGL is not initialized, or could not be initialized, for the specified display",
- "cannot access a requested resource",
- "failed to allocate resources for the requested operation",
- "an unrecognized attribute or attribute value was passed in an attribute list",
- "an EGLConfig argument does not name a valid EGLConfig",
- "an EGLContext argument does not name a valid EGLContext",
- "the current surface of the calling thread is no longer valid",
- "an EGLDisplay argument does not name a valid EGLDisplay",
- "arguments are inconsistent",
- "an EGLNativePixmapType argument does not refer to a valid native pixmap",
- "an EGLNativeWindowType argument does not refer to a valid native window",
- "one or more argument values are invalid",
- "an EGLSurface argument does not name a valid surface configured for rendering",
- "a power management event has occurred",
- };
-
- fprintf(stderr, "%s: %s\n", msg, errmsg[eglGetError() - EGL_SUCCESS]);
-}
-EGLConfig bbutil_choose_config(EGLDisplay egl_disp, enum RENDERING_API api) {
- EGLConfig egl_conf = (EGLConfig)0;
- EGLConfig *egl_configs;
- EGLint egl_num_configs;
- EGLint val;
- EGLBoolean rc;
- EGLint i;
-
- rc = eglGetConfigs(egl_disp, NULL, 0, &egl_num_configs);
- if (rc != EGL_TRUE) {
- bbutil_egl_perror("eglGetConfigs");
- return egl_conf;
- }
- if (egl_num_configs == 0) {
- fprintf(stderr, "eglGetConfigs: could not find a configuration\n");
- return egl_conf;
- }
-
- egl_configs = malloc(egl_num_configs * sizeof(*egl_configs));
- if (egl_configs == NULL) {
- fprintf(stderr, "could not allocate memory for %d EGL configs\n", egl_num_configs);
- return egl_conf;
- }
-
- rc = eglGetConfigs(egl_disp, egl_configs,
- egl_num_configs, &egl_num_configs);
- if (rc != EGL_TRUE) {
- bbutil_egl_perror("eglGetConfigs");
- free(egl_configs);
- return egl_conf;
- }
-
- for (i = 0; i < egl_num_configs; i++) {
- eglGetConfigAttrib(egl_disp, egl_configs[i], EGL_SURFACE_TYPE, &val);
- if (!(val & EGL_WINDOW_BIT)) {
- continue;
- }
-
- eglGetConfigAttrib(egl_disp, egl_configs[i], EGL_RENDERABLE_TYPE, &val);
- if (!(val & api)) {
- continue;
- }
-
- eglGetConfigAttrib(egl_disp, egl_configs[i], EGL_DEPTH_SIZE, &val);
- if ((api & (GL_ES_1|GL_ES_2)) && (val == 0)) {
- continue;
- }
-
- eglGetConfigAttrib(egl_disp, egl_configs[i], EGL_RED_SIZE, &val);
- if (val != 8) {
- continue;
- }
- eglGetConfigAttrib(egl_disp, egl_configs[i], EGL_GREEN_SIZE, &val);
- if (val != 8) {
- continue;
- }
-
- eglGetConfigAttrib(egl_disp, egl_configs[i], EGL_BLUE_SIZE, &val);
- if (val != 8) {
- continue;
- }
-
- eglGetConfigAttrib(egl_disp, egl_configs[i], EGL_BUFFER_SIZE, &val);
- if (val != 32) {
- continue;
- }
-
- egl_conf = egl_configs[i];
- break;
- }
-
- free(egl_configs);
-
- if (egl_conf == (EGLConfig)0) {
- fprintf(stderr, "bbutil_choose_config: could not find a matching configuration\n");
- }
-
- return egl_conf;
-}
-
-int
-bbutil_init_egl(screen_context_t ctx, enum RENDERING_API api) {
- int usage;
- int format = SCREEN_FORMAT_RGBX8888;
- int nbuffers = 2;
- EGLint interval = 1;
- int rc;
- EGLint attributes[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
-
- if (api == GL_ES_1) {
- usage = SCREEN_USAGE_OPENGL_ES1 | SCREEN_USAGE_ROTATION;
- } else if (api == GL_ES_2) {
- usage = SCREEN_USAGE_OPENGL_ES2 | SCREEN_USAGE_ROTATION;
- } else if (api == VG) {
- usage = SCREEN_USAGE_OPENVG | SCREEN_USAGE_ROTATION;
- } else {
- fprintf(stderr, "invalid api setting\n");
- return EXIT_FAILURE;
- }
-
- //Simple egl initialization
- screen_ctx = ctx;
-
- egl_disp = eglGetDisplay(EGL_DEFAULT_DISPLAY);
- if (egl_disp == EGL_NO_DISPLAY) {
- bbutil_egl_perror("eglGetDisplay");
- bbutil_terminate();
- return EXIT_FAILURE;
- }
-
- rc = eglInitialize(egl_disp, NULL, NULL);
- if (rc != EGL_TRUE) {
- bbutil_egl_perror("eglInitialize");
- bbutil_terminate();
- return EXIT_FAILURE;
- }
-
- if ((api == GL_ES_1) || (api == GL_ES_2)) {
- rc = eglBindAPI(EGL_OPENGL_ES_API);
- } else if (api == VG) {
- rc = eglBindAPI(EGL_OPENVG_API);
- }
-
- if (rc != EGL_TRUE) {
- bbutil_egl_perror("eglBindApi");
- bbutil_terminate();
- return EXIT_FAILURE;
- }
-
- egl_conf = bbutil_choose_config(egl_disp, api);
- if (egl_conf == (EGLConfig)0) {
- bbutil_terminate();
- return EXIT_FAILURE;
- }
-
- if (api == GL_ES_2) {
- egl_ctx = eglCreateContext(egl_disp, egl_conf, EGL_NO_CONTEXT, attributes);
- } else {
- egl_ctx = eglCreateContext(egl_disp, egl_conf, EGL_NO_CONTEXT, NULL);
- }
-
- if (egl_ctx == EGL_NO_CONTEXT) {
- bbutil_egl_perror("eglCreateContext");
- bbutil_terminate();
- return EXIT_FAILURE;
- }
-
- rc = screen_create_window(&screen_win, screen_ctx);
- if (rc) {
- perror("screen_create_window");
- bbutil_terminate();
- return EXIT_FAILURE;
- }
-
- rc = screen_set_window_property_iv(screen_win, SCREEN_PROPERTY_FORMAT, &format);
- if (rc) {
- perror("screen_set_window_property_iv(SCREEN_PROPERTY_FORMAT)");
- bbutil_terminate();
- return EXIT_FAILURE;
- }
-
- rc = screen_set_window_property_iv(screen_win, SCREEN_PROPERTY_USAGE, &usage);
- if (rc) {
- perror("screen_set_window_property_iv(SCREEN_PROPERTY_USAGE)");
- bbutil_terminate();
- return EXIT_FAILURE;
- }
-
- rc = screen_get_window_property_pv(screen_win, SCREEN_PROPERTY_DISPLAY, (void **)&screen_disp);
- if (rc) {
- perror("screen_get_window_property_pv");
- bbutil_terminate();
- return EXIT_FAILURE;
- }
-
- int screen_resolution[2];
-
- rc = screen_get_display_property_iv(screen_disp, SCREEN_PROPERTY_SIZE, screen_resolution);
- if (rc) {
- perror("screen_get_display_property_iv");
- bbutil_terminate();
- return EXIT_FAILURE;
- }
-
- int angle = atoi(getenv("ORIENTATION"));
-
- screen_display_mode_t screen_mode;
- rc = screen_get_display_property_pv(screen_disp, SCREEN_PROPERTY_MODE, (void**)&screen_mode);
- if (rc) {
- perror("screen_get_display_property_pv");
- bbutil_terminate();
- return EXIT_FAILURE;
- }
-
- int size[2];
- rc = screen_get_window_property_iv(screen_win, SCREEN_PROPERTY_BUFFER_SIZE, size);
- if (rc) {
- perror("screen_get_window_property_iv");
- bbutil_terminate();
- return EXIT_FAILURE;
- }
-
- int buffer_size[2] = {size[0], size[1]};
-
- if ((angle == 0) || (angle == 180)) {
- if (((screen_mode.width > screen_mode.height) && (size[0] < size[1])) ||
- ((screen_mode.width < screen_mode.height) && (size[0] > size[1]))) {
- buffer_size[1] = size[0];
- buffer_size[0] = size[1];
- }
- } else if ((angle == 90) || (angle == 270)){
- if (((screen_mode.width > screen_mode.height) && (size[0] > size[1])) ||
- ((screen_mode.width < screen_mode.height && size[0] < size[1]))) {
- buffer_size[1] = size[0];
- buffer_size[0] = size[1];
- }
- } else {
- fprintf(stderr, "Navigator returned an unexpected orientation angle.\n");
- bbutil_terminate();
- return EXIT_FAILURE;
- }
-
- rc = screen_set_window_property_iv(screen_win, SCREEN_PROPERTY_BUFFER_SIZE, buffer_size);
- if (rc) {
- perror("screen_set_window_property_iv");
- bbutil_terminate();
- return EXIT_FAILURE;
- }
-
- rc = screen_set_window_property_iv(screen_win, SCREEN_PROPERTY_ROTATION, &angle);
- if (rc) {
- perror("screen_set_window_property_iv");
- bbutil_terminate();
- return EXIT_FAILURE;
- }
-
- rc = screen_create_window_buffers(screen_win, nbuffers);
- if (rc) {
- perror("screen_create_window_buffers");
- bbutil_terminate();
- return EXIT_FAILURE;
- }
-
- rc = screen_create_window_group(screen_win, get_window_group_id());
- if (rc) {
- perror("screen_create_window_group");
- bbutil_terminate();
- return EXIT_FAILURE;
- }
- /* if (screen_create_window_group(screen_win, get_window_group_id()) != 0) goto fail; */
-
- int idle_mode = SCREEN_IDLE_MODE_KEEP_AWAKE;
- screen_set_window_property_iv(screen_win, SCREEN_PROPERTY_IDLE_MODE, &idle_mode);
-
- egl_surf = eglCreateWindowSurface(egl_disp, egl_conf, screen_win, NULL);
- if (egl_surf == EGL_NO_SURFACE) {
- bbutil_egl_perror("eglCreateWindowSurface");
- bbutil_terminate();
- return EXIT_FAILURE;
- }
-
- rc = eglMakeCurrent(egl_disp, egl_surf, egl_surf, egl_ctx);
- if (rc != EGL_TRUE) {
- bbutil_egl_perror("eglMakeCurrent");
- bbutil_terminate();
- return EXIT_FAILURE;
- }
-
- rc = eglSwapInterval(egl_disp, interval);
- if (rc != EGL_TRUE) {
- bbutil_egl_perror("eglSwapInterval");
- bbutil_terminate();
- return EXIT_FAILURE;
- }
-
- return EXIT_SUCCESS;
-}
-
-int
-bbutil_init_gl2d() {
-#if 0
- EGLint surface_width, surface_height;
-
- if ((egl_disp == EGL_NO_DISPLAY) || (egl_surf == EGL_NO_SURFACE) ){
- return EXIT_FAILURE;
- }
-
- eglQuerySurface(egl_disp, egl_surf, EGL_WIDTH, &surface_width);
- eglQuerySurface(egl_disp, egl_surf, EGL_HEIGHT, &surface_height);
-
- glShadeModel(GL_SMOOTH);
-
- glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
-
- glViewport(0, 0, surface_width, surface_height);
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
-
- glOrthof(0.0f, (float)(surface_width) / (float)(surface_height), 0.0f, 1.0f, -1.0f, 1.0f);
-
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
-#endif
-
- return EXIT_SUCCESS;
-}
-
-int
-bbutil_init(screen_context_t ctx, enum RENDERING_API api) {
- if (EXIT_SUCCESS != bbutil_init_egl(ctx, api)) {
- return EXIT_FAILURE;
- }
-
- if ((GL_ES_1 == api) && (EXIT_SUCCESS != bbutil_init_gl2d())) {
- return EXIT_FAILURE;
- }
-
- return EXIT_SUCCESS;
-}
-
-int bbutil_is_flipped() {
-
- int ret;
- screen_get_window_property_iv(screen_win, SCREEN_PROPERTY_FLIP, &ret);
- return ret;
-};
-
-int bbutil_get_rotation() {
-
- int ret;
- screen_get_window_property_iv(screen_win, SCREEN_PROPERTY_ROTATION, &ret);
- return ret;
-};
-
-
-void
-bbutil_terminate() {
- //Typical EGL cleanup
- if (egl_disp != EGL_NO_DISPLAY) {
- eglMakeCurrent(egl_disp, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
- if (egl_surf != EGL_NO_SURFACE) {
- eglDestroySurface(egl_disp, egl_surf);
- egl_surf = EGL_NO_SURFACE;
- }
- if (egl_ctx != EGL_NO_CONTEXT) {
- eglDestroyContext(egl_disp, egl_ctx);
- egl_ctx = EGL_NO_CONTEXT;
- }
- if (screen_win != NULL) {
- screen_destroy_window(screen_win);
- screen_win = NULL;
- }
- eglTerminate(egl_disp);
- egl_disp = EGL_NO_DISPLAY;
- }
- eglReleaseThread();
-}
-
-void
-bbutil_swap() {
- int rc = eglSwapBuffers(egl_disp, egl_surf);
- if (rc != EGL_TRUE) {
- bbutil_egl_perror("eglSwapBuffers");
- }
-}
-
-void
-bbutil_clear() {
- glClear(GL_COLOR_BUFFER_BIT);
-}
-
-char *
-get_window_group_id()
-{
- static char s_window_group_id[16] = "";
-
- if (s_window_group_id[0] == '\0') {
- snprintf(s_window_group_id, sizeof(s_window_group_id), "%d", getpid());
- }
-
- return s_window_group_id;
-}
-
-
-int bbutil_rotate_screen_surface(int angle) {
- int rc, rotation, skip = 1, temp;
- EGLint interval = 1;
- int size[2];
-
- if ((angle != 0) && (angle != 90) && (angle != 180) && (angle != 270)) {
- fprintf(stderr, "Invalid angle\n");
- return EXIT_FAILURE;
- }
-
- rc = screen_get_window_property_iv(screen_win, SCREEN_PROPERTY_ROTATION, &rotation);
- if (rc) {
- perror("screen_set_window_property_iv");
- return EXIT_FAILURE;
- }
-
- rc = screen_get_window_property_iv(screen_win, SCREEN_PROPERTY_BUFFER_SIZE, size);
- if (rc) {
- perror("screen_set_window_property_iv");
- return EXIT_FAILURE;
- }
-
- switch (angle - rotation) {
- case -270:
- case -90:
- case 90:
- case 270:
- temp = size[0];
- size[0] = size[1];
- size[1] = temp;
- skip = 0;
- break;
- }
-
- if (!skip) {
- rc = eglMakeCurrent(egl_disp, NULL, NULL, NULL);
- if (rc != EGL_TRUE) {
- bbutil_egl_perror("eglMakeCurrent");
- return EXIT_FAILURE;
- }
-
- rc = eglDestroySurface(egl_disp, egl_surf);
- if (rc != EGL_TRUE) {
- bbutil_egl_perror("eglMakeCurrent");
- return EXIT_FAILURE;
- }
-
- rc = screen_set_window_property_iv(screen_win, SCREEN_PROPERTY_SOURCE_SIZE, size);
- if (rc) {
- perror("screen_set_window_property_iv");
- return EXIT_FAILURE;
- }
-
- rc = screen_set_window_property_iv(screen_win, SCREEN_PROPERTY_BUFFER_SIZE, size);
- if (rc) {
- perror("screen_set_window_property_iv");
- return EXIT_FAILURE;
- }
- egl_surf = eglCreateWindowSurface(egl_disp, egl_conf, screen_win, NULL);
- if (egl_surf == EGL_NO_SURFACE) {
- bbutil_egl_perror("eglCreateWindowSurface");
- return EXIT_FAILURE;
- }
-
- rc = eglMakeCurrent(egl_disp, egl_surf, egl_surf, egl_ctx);
- if (rc != EGL_TRUE) {
- bbutil_egl_perror("eglMakeCurrent");
- return EXIT_FAILURE;
- }
-
- rc = eglSwapInterval(egl_disp, interval);
- if (rc != EGL_TRUE) {
- bbutil_egl_perror("eglSwapInterval");
- return EXIT_FAILURE;
- }
- }
-
- rc = screen_set_window_property_iv(screen_win, SCREEN_PROPERTY_ROTATION, &angle);
- if (rc) {
- perror("screen_set_window_property_iv");
- return EXIT_FAILURE;
- }
-
- return EXIT_SUCCESS;
-}
-
diff --git a/platform/bb10/bbutil.h b/platform/bb10/bbutil.h
deleted file mode 100644
index 77f4402fbd..0000000000
--- a/platform/bb10/bbutil.h
+++ /dev/null
@@ -1,72 +0,0 @@
-#ifndef _UTILITY_H_INCLUDED
-#define _UTILITY_H_INCLUDED
-
-#include <EGL/egl.h>
-#include <GLES2/gl2.h>
-#include <screen/screen.h>
-#include <sys/platform.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-extern EGLDisplay egl_disp;
-extern EGLSurface egl_surf;
-
-enum RENDERING_API {
- GL_ES_1 = EGL_OPENGL_ES_BIT,
- GL_ES_2 = EGL_OPENGL_ES2_BIT,
- VG = EGL_OPENVG_BIT
-};
-
-/**
- * Initializes EGL, GL and loads a default font
- *
- * \param libscreen context that will be used for EGL setup
- * \return EXIT_SUCCESS if initialization succeeded otherwise EXIT_FAILURE
- */
-int bbutil_init(screen_context_t ctx, enum RENDERING_API api);
-
-/**
- * Initializes EGL
- *
- * \param libscreen context that will be used for EGL setup
- * \return EXIT_SUCCESS if initialization succeeded otherwise EXIT_FAILURE
- */
-int bbutil_init_egl(screen_context_t ctx, enum RENDERING_API api);
-
-/**
- * Initializes GL 1.1 for simple 2D rendering. GL2 initialization will be added at a later point.
- *
- * \return EXIT_SUCCESS if initialization succeeded otherwise EXIT_FAILURE
- */
-int bbutil_init_gl2d();
-
-int bbutil_is_flipped();
-int bbutil_get_rotation();
-
-char *get_window_group_id();
-
-int bbutil_rotate_screen_surface(int angle);
-
-/**
- * Terminates EGL
- */
-void bbutil_terminate();
-
-/**
- * Swaps default bbutil window surface to the screen
- */
-void bbutil_swap();
-
-/**
- * Clears the screen of any existing text.
- * NOTE: must be called after a successful return from bbutil_init() or bbutil_init_egl() call
- */
-void bbutil_clear();
-
-#ifdef __cplusplus
-};
-#endif
-
-#endif
diff --git a/platform/bb10/detect.py b/platform/bb10/detect.py
deleted file mode 100644
index d3ee9f0124..0000000000
--- a/platform/bb10/detect.py
+++ /dev/null
@@ -1,92 +0,0 @@
-import os
-import sys
-import string
-import methods
-
-
-def is_active():
- return True
-
-
-def get_name():
- return "BlackBerry 10"
-
-
-def can_build():
-
- import os
- if (not os.environ.has_key("QNX_TARGET")):
- return False
- return True
-
-
-def get_opts():
-
- return [
- ('QNX_HOST', 'path to qnx host', os.environ.get("QNX_HOST", 0)),
- ('QNX_TARGET', 'path to qnx target', os.environ.get("QNX_TARGET", 0)),
- ('QNX_CONFIGURATION', 'path to qnx configuration', os.environ.get("QNX_CONFIGURATION", 0)),
- ('qnx_target', 'Qnx target (armle or x86', 'armle'),
- ('bb10_payment_service', 'Enable Payment Service for BlackBerry10', 'yes'),
- ('bb10_lgles_override', 'Force legacy GLES (1.1) on iOS', 'no'),
- ('bb10_exceptions', 'Use exceptions when compiling on bb10', 'no'),
- ]
-
-
-def get_flags():
-
- return [
- ('tools', 'no'),
- ('module_theora_enabled', 'no'),
- ]
-
-
-def configure(env):
-
- if env['PLATFORM'] == 'win32':
- env.Tool('mingw')
- env['SPAWN'] = methods.win32_spawn
-
- env['qnx_target_ver'] = env['qnx_target']
- if env['qnx_target'] == "armle":
- env['qnx_prefix'] = 'ntoarmv7'
- env['qnx_target_ver'] = 'armle-v7'
- else:
- env['qnx_prefix'] = 'ntox86'
-
- env['OBJSUFFIX'] = ".qnx.${qnx_target}.o"
- env['LIBSUFFIX'] = ".qnx.${qnx_target}.a"
- env['PROGSUFFIX'] = ".qnx.${qnx_target}"
- print("PROGSUFFIX: " + env['PROGSUFFIX'] + " target: " + env['qnx_target'])
-
- env.PrependENVPath('PATH', env['QNX_CONFIGURATION'] + '/bin')
- env.PrependENVPath('PATH', env['QNX_CONFIGURATION'] + '/usr/bin')
- env['ENV']['QNX_HOST'] = env['QNX_HOST']
- env['ENV']['QNX_TARGET'] = env['QNX_TARGET']
- env['ENV']['QNX_CONFIGURATION'] = env['QNX_CONFIGURATION']
-
- env['CC'] = '$qnx_prefix-gcc'
- env['CXX'] = '$qnx_prefix-g++'
- env['AR'] = '$qnx_prefix-ar'
- env['RANLIB'] = '$qnx_prefix-ranlib'
-
- env.Append(CPPPATH=['#platform/bb10'])
- env.Append(LIBPATH=['#platform/bb10/lib/$qnx_target', '#platform/bb10/lib/$qnx_target_ver'])
- env.Append(CCFLAGS=string.split('-DBB10_ENABLED -DUNIX_ENABLED -DGLES2_ENABLED -DGLES1_ENABLED -D_LITTLE_ENDIAN -DNO_THREADS -DNO_FCNTL'))
- if env['bb10_exceptions'] == "yes":
- env.Append(CCFLAGS=['-fexceptions'])
- else:
- env.Append(CCFLAGS=['-fno-exceptions'])
-
- # env.Append(LINKFLAGS = string.split()
-
- if (env["target"] == "release"):
-
- env.Append(CCFLAGS=['-O3', '-DRELEASE_BUILD'])
-
- elif (env["target"] == "debug"):
-
- env.Append(CCFLAGS=['-g', '-O0', '-DDEBUG_ENABLED', '-D_DEBUG'])
- env.Append(LINKFLAGS=['-g'])
-
- env.Append(LIBS=['bps', 'pps', 'screen', 'socket', 'EGL', 'GLESv2', 'GLESv1_CM', 'm', 'asound'])
diff --git a/platform/bb10/export/export.cpp b/platform/bb10/export/export.cpp
deleted file mode 100644
index c958bf7ff4..0000000000
--- a/platform/bb10/export/export.cpp
+++ /dev/null
@@ -1,828 +0,0 @@
-/*************************************************************************/
-/* export.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* http://www.godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
-/* */
-/* 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 "export.h"
-#include "editor/editor_export.h"
-#include "editor/editor_node.h"
-#include "editor/editor_settings.h"
-#include "global_config.h"
-#include "io/marshalls.h"
-#include "io/xml_parser.h"
-#include "io/zip_io.h"
-#include "os/file_access.h"
-#include "os/os.h"
-#include "platform/bb10/logo.h"
-#include "version.h"
-
-#define MAX_DEVICES 5
-#if 0
-class EditorExportPlatformBB10 : public EditorExportPlatform {
-
- GDCLASS( EditorExportPlatformBB10,EditorExportPlatform );
-
- String custom_package;
-
- int version_code;
- String version_name;
- String package;
- String name;
- String category;
- String description;
- String author_name;
- String author_id;
- String icon;
-
-
-
- struct Device {
-
- int index;
- String name;
- String description;
- };
-
- Vector<Device> devices;
- bool devices_changed;
- Mutex *device_lock;
- Thread *device_thread;
- Ref<ImageTexture> logo;
-
- volatile bool quit_request;
-
-
- static void _device_poll_thread(void *ud);
-
- void _fix_descriptor(Vector<uint8_t>& p_manifest);
-protected:
-
- bool _set(const StringName& p_name, const Variant& p_value);
- bool _get(const StringName& p_name,Variant &r_ret) const;
- void _get_property_list( List<PropertyInfo> *p_list) const;
-
-public:
-
- virtual String get_name() const { return "BlackBerry 10"; }
- virtual ImageCompression get_image_compression() const { return IMAGE_COMPRESSION_ETC1; }
- virtual Ref<Texture> get_logo() const { return logo; }
-
-
- virtual bool poll_devices();
- virtual int get_device_count() const;
- virtual String get_device_name(int p_device) const;
- virtual String get_device_info(int p_device) const;
- virtual Error run(int p_device,int p_flags=0);
-
- virtual bool requires_password(bool p_debug) const { return !p_debug; }
- virtual String get_binary_extension() const { return "bar"; }
- virtual Error export_project(const String& p_path,bool p_debug,int p_flags=0);
-
- virtual bool can_export(String *r_error=NULL) const;
-
- EditorExportPlatformBB10();
- ~EditorExportPlatformBB10();
-};
-
-bool EditorExportPlatformBB10::_set(const StringName& p_name, const Variant& p_value) {
-
- String n=p_name;
-
- if (n=="version/code")
- version_code=p_value;
- else if (n=="version/name")
- version_name=p_value;
- else if (n=="package/unique_name")
- package=p_value;
- else if (n=="package/category")
- category=p_value;
- else if (n=="package/name")
- name=p_value;
- else if (n=="package/description")
- description=p_value;
- else if (n=="package/icon")
- icon=p_value;
- else if (n=="package/custom_template")
- custom_package=p_value;
- else if (n=="release/author")
- author_name=p_value;
- else if (n=="release/author_id")
- author_id=p_value;
- else
- return false;
-
- return true;
-}
-
-bool EditorExportPlatformBB10::_get(const StringName& p_name,Variant &r_ret) const{
-
- String n=p_name;
-
- if (n=="version/code")
- r_ret=version_code;
- else if (n=="version/name")
- r_ret=version_name;
- else if (n=="package/unique_name")
- r_ret=package;
- else if (n=="package/category")
- r_ret=category;
- else if (n=="package/name")
- r_ret=name;
- else if (n=="package/description")
- r_ret=description;
- else if (n=="package/icon")
- r_ret=icon;
- else if (n=="package/custom_template")
- r_ret=custom_package;
- else if (n=="release/author")
- r_ret=author_name;
- else if (n=="release/author_id")
- r_ret=author_id;
- else
- return false;
-
- return true;
-}
-void EditorExportPlatformBB10::_get_property_list( List<PropertyInfo> *p_list) const{
-
- p_list->push_back( PropertyInfo( Variant::INT, "version/code", PROPERTY_HINT_RANGE,"1,65535,1"));
- p_list->push_back( PropertyInfo( Variant::STRING, "version/name") );
- p_list->push_back( PropertyInfo( Variant::STRING, "package/unique_name") );
- p_list->push_back( PropertyInfo( Variant::STRING, "package/category") );
- p_list->push_back( PropertyInfo( Variant::STRING, "package/name") );
- p_list->push_back( PropertyInfo( Variant::STRING, "package/description",PROPERTY_HINT_MULTILINE_TEXT) );
- p_list->push_back( PropertyInfo( Variant::STRING, "package/icon",PROPERTY_HINT_FILE,"png") );
- p_list->push_back( PropertyInfo( Variant::STRING, "package/custom_template", PROPERTY_HINT_GLOBAL_FILE,"zip"));
- p_list->push_back( PropertyInfo( Variant::STRING, "release/author") );
- p_list->push_back( PropertyInfo( Variant::STRING, "release/author_id") );
-
- //p_list->push_back( PropertyInfo( Variant::INT, "resources/pack_mode", PROPERTY_HINT_ENUM,"Copy,Single Exec.,Pack (.pck),Bundles (Optical)"));
-
-}
-
-void EditorExportPlatformBB10::_fix_descriptor(Vector<uint8_t>& p_descriptor) {
-
- String fpath = EditorSettings::get_singleton()->get_settings_path().plus_file("tmp_bar-settings.xml");
- {
- FileAccessRef f = FileAccess::open(fpath,FileAccess::WRITE);
- f->store_buffer(p_descriptor.ptr(),p_descriptor.size());
- }
-
- Ref<XMLParser> parser = memnew( XMLParser );
- Error err = parser->open(fpath);
- ERR_FAIL_COND(err!=OK);
-
- String txt;
- err = parser->read();
- Vector<String> depth;
-
- while(err!=ERR_FILE_EOF) {
-
- ERR_FAIL_COND(err!=OK);
-
- switch(parser->get_node_type()) {
-
- case XMLParser::NODE_NONE: {
- print_line("???");
- } break;
- case XMLParser::NODE_ELEMENT: {
- String e="<";
- e+=parser->get_node_name();
- for(int i=0;i<parser->get_attribute_count();i++) {
- e+=" ";
- e+=parser->get_attribute_name(i)+"=\"";
- e+=parser->get_attribute_value(i)+"\" ";
- }
-
-
-
- if (parser->is_empty()) {
- e+="/";
- } else {
- depth.push_back(parser->get_node_name());
- }
-
- e+=">";
- txt+=e;
-
- } break;
- case XMLParser::NODE_ELEMENT_END: {
-
- txt+="</"+parser->get_node_name()+">";
- if (depth.size() && depth[depth.size()-1]==parser->get_node_name()) {
- depth.resize(depth.size()-1);
- }
-
-
- } break;
- case XMLParser::NODE_TEXT: {
- if (depth.size()==2 && depth[0]=="qnx" && depth[1]=="id") {
-
- txt+=package;
- } else if (depth.size()==2 && depth[0]=="qnx" && depth[1]=="name") {
-
- String aname;
- if (this->name!="") {
- aname=this->name;
- } else {
- aname = GlobalConfig::get_singleton()->get("application/name");
-
- }
-
- if (aname=="") {
- aname=_MKSTR(VERSION_NAME);
- }
-
- txt+=aname;
-
- } else if (depth.size()==2 && depth[0]=="qnx" && depth[1]=="versionNumber") {
- txt+=itos(version_code);
- } else if (depth.size()==2 && depth[0]=="qnx" && depth[1]=="description") {
- txt+=description;
- } else if (depth.size()==2 && depth[0]=="qnx" && depth[1]=="author") {
- txt+=author_name;
- } else if (depth.size()==2 && depth[0]=="qnx" && depth[1]=="authorId") {
- txt+=author_id;
- } else if (depth.size()==2 && depth[0]=="qnx" && depth[1]=="category") {
- txt+=category;
- } else {
- txt+=parser->get_node_data();
- }
- } break;
- case XMLParser::NODE_COMMENT: {
- txt+="<!--"+parser->get_node_name()+"-->";
- } break;
- case XMLParser::NODE_CDATA: {
- //ignore
- //print_line("cdata");
- } break;
- case XMLParser::NODE_UNKNOWN: {
- //ignore
- txt+="<"+parser->get_node_name()+">";
- } break;
- }
-
- err = parser->read();
- }
-
-
- CharString cs = txt.utf8();
- p_descriptor.resize(cs.length());
- for(int i=0;i<cs.length();i++)
- p_descriptor[i]=cs[i];
-
-}
-
-
-
-Error EditorExportPlatformBB10::export_project(const String& p_path, bool p_debug, int p_flags) {
-
-
- EditorProgress ep("export","Exporting for BlackBerry 10",104);
-
- String src_template=custom_package;
-
- if (src_template=="") {
- String err;
- src_template = find_export_template("bb10.zip", &err);
- if (src_template=="") {
- EditorNode::add_io_error(err);
- return ERR_FILE_NOT_FOUND;
- }
- }
-
- FileAccess *src_f=NULL;
- zlib_filefunc_def io = zipio_create_io_from_file(&src_f);
-
- ep.step("Creating FileSystem for BAR",0);
-
- unzFile pkg = unzOpen2(src_template.utf8().get_data(), &io);
- if (!pkg) {
-
- EditorNode::add_io_error("Could not find template zip to export:\n"+src_template);
- return ERR_FILE_NOT_FOUND;
- }
-
- DirAccessRef da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
- da->change_dir(EditorSettings::get_singleton()->get_settings_path());
-
-
- if (da->change_dir("tmp")!=OK) {
- da->make_dir("tmp");
- if (da->change_dir("tmp")!=OK)
- return ERR_CANT_CREATE;
- }
-
- if (da->change_dir("bb10_export")!=OK) {
- da->make_dir("bb10_export");
- if (da->change_dir("bb10_export")!=OK) {
- return ERR_CANT_CREATE;
- }
- }
-
-
- String bar_dir = da->get_current_dir();
- if (bar_dir.ends_with("/")) {
- bar_dir=bar_dir.substr(0,bar_dir.length()-1);
- }
-
- //THIS IS SUPER, SUPER DANGEROUS!!!!
- //CAREFUL WITH THIS CODE, MIGHT DELETE USERS HARD DRIVE OR HOME DIR
- //EXTRA CHECKS ARE IN PLACE EVERYWERE TO MAKE SURE NOTHING BAD HAPPENS BUT STILL....
- //BE SUPER CAREFUL WITH THIS PLEASE!!!
- //BLACKBERRY THIS IS YOUR FAULT FOR NOT MAKING A BETTER WAY!!
-
- bool berr = bar_dir.ends_with("bb10_export");
- if (berr) {
- if (da->list_dir_begin()) {
- EditorNode::add_io_error("Can't ensure that dir is empty:\n"+bar_dir);
- ERR_FAIL_COND_V(berr,FAILED);
- };
-
- String f = da->get_next();
- while (f != "") {
-
- if (f == "." || f == "..") {
- f = da->get_next();
- continue;
- };
- Error err = da->remove(bar_dir + "/" + f);
- if (err != OK) {
- EditorNode::add_io_error("Can't ensure that dir is empty:\n"+bar_dir);
- ERR_FAIL_COND_V(err!=OK,err);
- };
- f = da->get_next();
- };
-
- da->list_dir_end();
-
- } else {
- print_line("ARE YOU CRAZY??? THIS IS A SERIOUS BUG HERE!!!");
- ERR_FAIL_V(ERR_OMFG_THIS_IS_VERY_VERY_BAD);
- }
-
-
- ERR_FAIL_COND_V(!pkg, ERR_CANT_OPEN);
- int ret = unzGoToFirstFile(pkg);
-
-
-
- while(ret==UNZ_OK) {
-
- //get filename
- unz_file_info info;
- char fname[16384];
- ret = unzGetCurrentFileInfo(pkg,&info,fname,16384,NULL,0,NULL,0);
-
- String file=fname;
-
- Vector<uint8_t> data;
- data.resize(info.uncompressed_size);
-
- //read
- unzOpenCurrentFile(pkg);
- unzReadCurrentFile(pkg,data.ptr(),data.size());
- unzCloseCurrentFile(pkg);
-
- //write
-
- if (file=="bar-descriptor.xml") {
-
- _fix_descriptor(data);
- }
-
- if (file=="icon.png") {
- bool found=false;
-
- if (this->icon!="" && this->icon.ends_with(".png")) {
-
- FileAccess *f = FileAccess::open(this->icon,FileAccess::READ);
- if (f) {
-
- data.resize(f->get_len());
- f->get_buffer(data.ptr(),data.size());
- memdelete(f);
- found=true;
- }
-
- }
-
- if (!found) {
-
- String appicon = GlobalConfig::get_singleton()->get("application/icon");
- if (appicon!="" && appicon.ends_with(".png")) {
- FileAccess*f = FileAccess::open(appicon,FileAccess::READ);
- if (f) {
- data.resize(f->get_len());
- f->get_buffer(data.ptr(),data.size());
- memdelete(f);
- }
- }
- }
- }
-
-
- if (file.find("/")) {
-
- da->make_dir_recursive(file.get_base_dir());
- }
-
- FileAccessRef wf = FileAccess::open(bar_dir.plus_file(file),FileAccess::WRITE);
- wf->store_buffer(data.ptr(),data.size());
-
- ret = unzGoToNextFile(pkg);
- }
-
- ep.step("Adding Files..",2);
-
- FileAccess* dst = FileAccess::open(bar_dir+"/data.pck", FileAccess::WRITE);
- if (!dst) {
- EditorNode::add_io_error("Can't copy executable file to:\n "+p_path);
- return ERR_FILE_CANT_WRITE;
- }
- save_pack(dst, false, 1024);
- dst->close();
- memdelete(dst);
-
- ep.step("Creating BAR Package..",104);
-
- String bb_packager=EditorSettings::get_singleton()->get("export/blackberry/host_tools");
- bb_packager=bb_packager.plus_file("blackberry-nativepackager");
- if (OS::get_singleton()->get_name()=="Windows")
- bb_packager+=".bat";
-
-
- if (!FileAccess::exists(bb_packager)) {
- EditorNode::add_io_error("Can't find packager:\n"+bb_packager);
- return ERR_CANT_OPEN;
- }
-
- List<String> args;
- args.push_back("-package");
- args.push_back(p_path);
- if (p_debug) {
-
- String debug_token=EditorSettings::get_singleton()->get("export/blackberry/debug_token");
- if (!FileAccess::exists(debug_token)) {
- EditorNode::add_io_error("Debug token not found!");
- } else {
- args.push_back("-debugToken");
- args.push_back(debug_token);
- }
- args.push_back("-devMode");
- args.push_back("-configuration");
- args.push_back("Device-Debug");
- } else {
-
- args.push_back("-configuration");
- args.push_back("Device-Release");
- }
- args.push_back(bar_dir.plus_file("bar-descriptor.xml"));
-
- int ec;
-
- Error err = OS::get_singleton()->execute(bb_packager,args,true,NULL,NULL,&ec);
-
- if (err!=OK)
- return err;
- if (ec!=0)
- return ERR_CANT_CREATE;
-
- return OK;
-
-}
-
-bool EditorExportPlatformBB10::poll_devices() {
-
- bool dc=devices_changed;
- devices_changed=false;
- return dc;
-}
-
-int EditorExportPlatformBB10::get_device_count() const {
-
- device_lock->lock();
- int dc=devices.size();
- device_lock->unlock();
-
- return dc;
-
-}
-String EditorExportPlatformBB10::get_device_name(int p_device) const {
-
- ERR_FAIL_INDEX_V(p_device,devices.size(),"");
- device_lock->lock();
- String s=devices[p_device].name;
- device_lock->unlock();
- return s;
-}
-String EditorExportPlatformBB10::get_device_info(int p_device) const {
-
- ERR_FAIL_INDEX_V(p_device,devices.size(),"");
- device_lock->lock();
- String s=devices[p_device].description;
- device_lock->unlock();
- return s;
-}
-
-void EditorExportPlatformBB10::_device_poll_thread(void *ud) {
-
- EditorExportPlatformBB10 *ea=(EditorExportPlatformBB10 *)ud;
-
- while(!ea->quit_request) {
-
- String bb_deploy=EditorSettings::get_singleton()->get("export/blackberry/host_tools");
- bb_deploy=bb_deploy.plus_file("blackberry-deploy");
- bool windows = OS::get_singleton()->get_name()=="Windows";
- if (windows)
- bb_deploy+=".bat";
-
- if (FileAccess::exists(bb_deploy)) {
-
- Vector<Device> devices;
-
-
- for (int i=0;i<MAX_DEVICES;i++) {
-
- String host = EditorSettings::get_singleton()->get("export/blackberry/device_"+itos(i+1)+"/host");
- if (host==String())
- continue;
- String pass = EditorSettings::get_singleton()->get("export/blackberry/device_"+itos(i+1)+"/password");
- if (pass==String())
- continue;
-
- List<String> args;
- args.push_back("-listDeviceInfo");
- args.push_back(host);
- args.push_back("-password");
- args.push_back(pass);
-
-
- int ec;
- String dp;
-
- Error err = OS::get_singleton()->execute(bb_deploy,args,true,NULL,&dp,&ec);
-
- if (err==OK && ec==0) {
-
- Device dev;
- dev.index=i;
- String descr;
- Vector<String> ls=dp.split("\n");
-
- for(int i=0;i<ls.size();i++) {
-
- String l = ls[i].strip_edges();
- if (l.begins_with("modelfullname::")) {
- dev.name=l.get_slice("::",1);
- descr+="Model: "+dev.name+"\n";
- }
- if (l.begins_with("modelnumber::")) {
- String s = l.get_slice("::",1);
- dev.name+=" ("+s+")";
- descr+="Model Number: "+s+"\n";
- }
- if (l.begins_with("scmbundle::"))
- descr+="OS Version: "+l.get_slice("::",1)+"\n";
- if (l.begins_with("[n]debug_token_expiration::"))
- descr+="Debug Token Expires:: "+l.get_slice("::",1)+"\n";
-
- }
-
- dev.description=descr;
- devices.push_back(dev);
- }
-
- }
-
- bool changed=false;
-
-
- ea->device_lock->lock();
-
- if (ea->devices.size()!=devices.size()) {
- changed=true;
- } else {
-
- for(int i=0;i<ea->devices.size();i++) {
-
- if (ea->devices[i].index!=devices[i].index) {
- changed=true;
- break;
- }
- }
- }
-
- if (changed) {
-
- ea->devices=devices;
- ea->devices_changed=true;
- }
-
- ea->device_lock->unlock();
- }
-
-
- uint64_t wait = 3000000;
- uint64_t time = OS::get_singleton()->get_ticks_usec();
- while(OS::get_singleton()->get_ticks_usec() - time < wait ) {
- OS::get_singleton()->delay_usec(1000);
- if (ea->quit_request)
- break;
- }
- }
-
-}
-
-Error EditorExportPlatformBB10::run(int p_device, int p_flags) {
-
- ERR_FAIL_INDEX_V(p_device,devices.size(),ERR_INVALID_PARAMETER);
-
- String bb_deploy=EditorSettings::get_singleton()->get("export/blackberry/host_tools");
- bb_deploy=bb_deploy.plus_file("blackberry-deploy");
- if (OS::get_singleton()->get_name()=="Windows")
- bb_deploy+=".bat";
-
- if (!FileAccess::exists(bb_deploy)) {
- EditorNode::add_io_error("Blackberry Deploy not found:\n"+bb_deploy);
- return ERR_FILE_NOT_FOUND;
- }
-
-
- device_lock->lock();
-
-
- EditorProgress ep("run","Running on "+devices[p_device].name,3);
-
- //export_temp
- ep.step("Exporting APK",0);
-
- String export_to=EditorSettings::get_singleton()->get_settings_path().plus_file("/tmp/tmpexport.bar");
- Error err = export_project(export_to,true,p_flags);
- if (err) {
- device_lock->unlock();
- return err;
- }
-#if 0
- ep.step("Uninstalling..",1);
-
- print_line("Uninstalling previous version: "+devices[p_device].name);
- List<String> args;
- args.push_back("-s");
- args.push_back(devices[p_device].id);
- args.push_back("uninstall");
- args.push_back(package);
- int rv;
- err = OS::get_singleton()->execute(adb,args,true,NULL,NULL,&rv);
-
- if (err || rv!=0) {
- EditorNode::add_io_error("Could not install to device.");
- device_lock->unlock();
- return ERR_CANT_CREATE;
- }
-
- print_line("Installing into device (please wait..): "+devices[p_device].name);
-
-#endif
- ep.step("Installing to Device (please wait..)..",2);
-
- List<String> args;
- args.clear();
- args.push_back("-installApp");
- args.push_back("-launchApp");
- args.push_back("-device");
- String host = EditorSettings::get_singleton()->get("export/blackberry/device_"+itos(p_device+1)+"/host");
- String pass = EditorSettings::get_singleton()->get("export/blackberry/device_"+itos(p_device+1)+"/password");
- args.push_back(host);
- args.push_back("-password");
- args.push_back(pass);
- args.push_back(export_to);
-
- int rv;
- err = OS::get_singleton()->execute(bb_deploy,args,true,NULL,NULL,&rv);
- if (err || rv!=0) {
- EditorNode::add_io_error("Could not install to device.");
- device_lock->unlock();
- return ERR_CANT_CREATE;
- }
-
- device_lock->unlock();
- return OK;
-
-
-}
-
-
-EditorExportPlatformBB10::EditorExportPlatformBB10() {
-
- version_code=1;
- version_name="1.0";
- package="com.godot.noname";
- category="core.games";
- name="";
- author_name="Cert. Name";
- author_id="Cert. ID";
- description="Game made with Godot Engine";
-
- device_lock = Mutex::create();
- quit_request=false;
-
- device_thread=Thread::create(_device_poll_thread,this);
- devices_changed=true;
-
- Image img( _bb10_logo );
- logo = Ref<ImageTexture>( memnew( ImageTexture ));
- logo->create_from_image(img);
-}
-
-bool EditorExportPlatformBB10::can_export(String *r_error) const {
-
- bool valid=true;
- String bb_deploy=EditorSettings::get_singleton()->get("export/blackberry/host_tools");
- String err;
-
- if (!FileAccess::exists(bb_deploy.plus_file("blackberry-deploy"))) {
-
- valid=false;
- err+="Blackberry host tools not configured in editor settings.\n";
- }
-
- if (!exists_export_template("bb10.zip")) {
- valid=false;
- err+="No export template found.\nDownload and install export templates.\n";
- }
-
- String debug_token=EditorSettings::get_singleton()->get("export/blackberry/debug_token");
-
- if (!FileAccess::exists(debug_token)) {
- valid=false;
- err+="No debug token set, will not be able to test on device.\n";
- }
-
-
- if (custom_package!="" && !FileAccess::exists(custom_package)) {
- valid=false;
- err+="Custom release package not found.\n";
- }
-
- if (r_error)
- *r_error=err;
-
- return valid;
-}
-
-
-EditorExportPlatformBB10::~EditorExportPlatformBB10() {
-
- quit_request=true;
- Thread::wait_to_finish(device_thread);
- memdelete(device_lock);
- memdelete(device_thread);
-}
-
-#endif
-void register_bb10_exporter() {
-#if 0
- EDITOR_DEF("export/blackberry/host_tools","");
- EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::STRING,"export/blackberry/host_tools",PROPERTY_HINT_GLOBAL_DIR));
- EDITOR_DEF("export/blackberry/debug_token","");
- EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::STRING,"export/blackberry/debug_token",PROPERTY_HINT_GLOBAL_FILE,"bar"));
- EDITOR_DEF("export/blackberry/device_1/host","");
- EDITOR_DEF("export/blackberry/device_1/password","");
- EDITOR_DEF("export/blackberry/device_2/host","");
- EDITOR_DEF("export/blackberry/device_2/password","");
- EDITOR_DEF("export/blackberry/device_3/host","");
- EDITOR_DEF("export/blackberry/device_3/password","");
- EDITOR_DEF("export/blackberry/device_4/host","");
- EDITOR_DEF("export/blackberry/device_4/password","");
- EDITOR_DEF("export/blackberry/device_5/host","");
- EDITOR_DEF("export/blackberry/device_5/password","");
-
- Ref<EditorExportPlatformBB10> exporter = Ref<EditorExportPlatformBB10>( memnew(EditorExportPlatformBB10) );
- EditorImportExport::get_singleton()->add_export_platform(exporter);
-
-#endif
-}
diff --git a/platform/bb10/godot_bb10.cpp b/platform/bb10/godot_bb10.cpp
deleted file mode 100644
index e1826450a6..0000000000
--- a/platform/bb10/godot_bb10.cpp
+++ /dev/null
@@ -1,47 +0,0 @@
-/*************************************************************************/
-/* godot_bb10.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* http://www.godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
-/* */
-/* 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 "main/main.h"
-#include "os_bb10.h"
-
-#include <unistd.h>
-
-int main(int argc, char *argv[]) {
-
- OSBB10 os;
-
- Error err = Main::setup(argv[0], argc - 1, &argv[1]);
- if (err != OK)
- return 255;
-
- if (Main::start())
- os.run(); // it is actually the OS that decides how to run
- Main::cleanup();
-
- return os.get_exit_code();
-}
diff --git a/platform/bb10/logo.png b/platform/bb10/logo.png
deleted file mode 100644
index abf0d2cc69..0000000000
--- a/platform/bb10/logo.png
+++ /dev/null
Binary files differ
diff --git a/platform/bb10/os_bb10.cpp b/platform/bb10/os_bb10.cpp
deleted file mode 100644
index 80e846d3cd..0000000000
--- a/platform/bb10/os_bb10.cpp
+++ /dev/null
@@ -1,613 +0,0 @@
-/*************************************************************************/
-/* os_bb10.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* http://www.godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
-/* */
-/* 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 "os_bb10.h"
-
-#include "bbutil.h"
-#include "core/global_config.h"
-#include "core/os/dir_access.h"
-#include "core/os/keyboard.h"
-#include "drivers/gles2/rasterizer_gles2.h"
-#include "main/main.h"
-#include "servers/visual/visual_server_raster.h"
-
-#include <assert.h>
-#include <bps/accelerometer.h>
-#include <bps/audiodevice.h>
-#include <bps/bps.h>
-#include <bps/navigator.h>
-#include <bps/orientation.h>
-#include <bps/screen.h>
-#include <bps/virtualkeyboard.h>
-#include <stdbool.h>
-#include <stdlib.h>
-
-#ifdef BB10_SCORELOOP_ENABLED
-#include "modules/scoreloop/scoreloop_bb10.h"
-#endif
-
-static char launch_dir[512];
-char *launch_dir_ptr;
-
-int OSBB10::get_video_driver_count() const {
-
- return 1;
-}
-const char *OSBB10::get_video_driver_name(int p_driver) const {
-
- return "GLES2";
-}
-
-OS::VideoMode OSBB10::get_default_video_mode() const {
-
- return OS::VideoMode();
-}
-
-int OSBB10::get_audio_driver_count() const {
-
- return 1;
-}
-const char *OSBB10::get_audio_driver_name(int p_driver) const {
-
- return "BB10";
-}
-
-void OSBB10::initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver) {
-
- data_dir = getenv("HOME");
-
- //Create a screen context that will be used to create an EGL surface to to receive libscreen events
- screen_create_context(&screen_cxt, 0);
-
- //Initialize BPS library
- bps_initialize();
-
- //Use utility code to initialize EGL for 2D rendering with GL ES 1.1
- enum RENDERING_API api = GL_ES_2;
-#ifdef BB10_LGLES_OVERRIDE
- api = GL_ES_1;
-#endif
- if (EXIT_SUCCESS != bbutil_init(screen_cxt, api)) {
- bbutil_terminate();
- screen_destroy_context(screen_cxt);
- return;
- };
-
- EGLint surface_width, surface_height;
-
- eglQuerySurface(egl_disp, egl_surf, EGL_WIDTH, &surface_width);
- eglQuerySurface(egl_disp, egl_surf, EGL_HEIGHT, &surface_height);
- printf("screen size: %ix%i\n", surface_width, surface_height);
- VideoMode mode;
- mode.width = surface_width;
- mode.height = surface_height;
- mode.fullscreen = true;
- mode.resizable = false;
- set_video_mode(mode);
-
- //Signal BPS library that navigator and screen events will be requested
- screen_request_events(screen_cxt);
- navigator_request_events(0);
- virtualkeyboard_request_events(0);
- audiodevice_request_events(0);
-
-#ifdef DEBUG_ENABLED
- bps_set_verbosity(3);
-#endif
-
- accel_supported = accelerometer_is_supported();
- if (accel_supported)
- accelerometer_set_update_frequency(FREQ_40_HZ);
- pitch = 0;
- roll = 0;
-
-#ifdef BB10_LGLES_OVERRIDE
- rasterizer = memnew(RasterizerGLES1(false));
-#else
- rasterizer = memnew(RasterizerGLES2(false, false));
-#endif
-
- visual_server = memnew(VisualServerRaster(rasterizer));
- visual_server->init();
- visual_server->cursor_set_visible(false, 0);
-
- audio_driver = memnew(AudioDriverBB10);
- audio_driver->set_singleton();
- audio_driver->init(NULL);
-
- physics_server = memnew(PhysicsServerSW);
- physics_server->init();
- physics_2d_server = memnew(Physics2DServerSW);
- physics_2d_server->init();
-
- input = memnew(InputDefault);
-
- power_manager = memnew(PowerBB10);
-
-#ifdef PAYMENT_SERVICE_ENABLED
- payment_service = memnew(PaymentService);
- Globals::get_singleton()->add_singleton(Globals::Singleton("InAppStore", payment_service));
-#endif
-}
-
-void OSBB10::set_main_loop(MainLoop *p_main_loop) {
-
- input->set_main_loop(p_main_loop);
- main_loop = p_main_loop;
-}
-
-void OSBB10::delete_main_loop() {
-
- memdelete(main_loop);
- main_loop = NULL;
-}
-
-void OSBB10::finalize() {
-
- if (main_loop)
- memdelete(main_loop);
- main_loop = NULL;
-
- /*
- if (debugger_connection_console) {
- memdelete(debugger_connection_console);
- }
- */
-
- visual_server->finish();
- memdelete(visual_server);
- memdelete(rasterizer);
-
- physics_server->finish();
- memdelete(physics_server);
-
- physics_2d_server->finish();
- memdelete(physics_2d_server);
-
-#ifdef PAYMENT_SERVICE_ENABLED
- memdelete(payment_service);
-#endif
-
- memdelete(input);
-
- bbutil_terminate();
- screen_destroy_context(screen_cxt);
-
- bps_shutdown();
-}
-
-void OSBB10::set_mouse_show(bool p_show) {
-
- //android has no mouse...
-}
-
-void OSBB10::set_mouse_grab(bool p_grab) {
-
- //it really has no mouse...!
-}
-
-bool OSBB10::is_mouse_grab_enabled() const {
-
- //*sigh* technology has evolved so much since i was a kid..
- return false;
-}
-Point2 OSBB10::get_mouse_pos() const {
-
- return Point2();
-}
-int OSBB10::get_mouse_button_state() const {
-
- return 0;
-}
-void OSBB10::set_window_title(const String &p_title) {
-}
-
-//interesting byt not yet
-//void set_clipboard(const String& p_text);
-//String get_clipboard() const;
-
-void OSBB10::set_video_mode(const VideoMode &p_video_mode, int p_screen) {
-
- default_videomode = p_video_mode;
-}
-
-OS::VideoMode OSBB10::get_video_mode(int p_screen) const {
-
- return default_videomode;
-}
-void OSBB10::get_fullscreen_mode_list(List<VideoMode> *p_list, int p_screen) const {
-
- p_list->push_back(default_videomode);
-}
-
-String OSBB10::get_name() {
-
- return "BlackBerry 10";
-}
-
-MainLoop *OSBB10::get_main_loop() const {
-
- return main_loop;
-}
-
-bool OSBB10::can_draw() const {
-
- return !minimized;
-}
-
-void OSBB10::set_cursor_shape(CursorShape p_shape) {
-
- //android really really really has no mouse.. how amazing..
-}
-
-void OSBB10::handle_screen_event(bps_event_t *event) {
-
- screen_event_t screen_event = screen_event_get_event(event);
-
- int screen_val;
- screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_TYPE, &screen_val);
-
- int pos[2];
-
- switch (screen_val) {
- case SCREEN_EVENT_MTOUCH_TOUCH:
- case SCREEN_EVENT_MTOUCH_RELEASE: {
-
- screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_POSITION, pos);
-
- InputEvent ievent;
- ievent.type = InputEvent::SCREEN_TOUCH;
- ievent.ID = ++last_id;
- ievent.device = 0;
- ievent.screen_touch.pressed = (screen_val == SCREEN_EVENT_MTOUCH_TOUCH);
- ievent.screen_touch.x = pos[0];
- ievent.screen_touch.y = pos[1];
- Point2 mpos(ievent.screen_touch.x, ievent.screen_touch.y);
-
- screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_TOUCH_ID, &pos[0]);
- ievent.screen_touch.index = pos[0];
-
- last_touch_x[pos[0]] = ievent.screen_touch.x;
- last_touch_y[pos[0]] = ievent.screen_touch.y;
-
- input->parse_input_event(ievent);
-
- if (ievent.screen_touch.index == 0) {
-
- InputEvent ievent;
- ievent.type = InputEvent::MOUSE_BUTTON;
- ievent.ID = ++last_id;
- ievent.device = 0;
- ievent.mouse_button.pressed = (screen_val == SCREEN_EVENT_MTOUCH_TOUCH);
- ievent.mouse_button.button_index = BUTTON_LEFT;
- ievent.mouse_button.doubleclick = 0;
- ievent.mouse_button.x = ievent.mouse_button.global_x = mpos.x;
- ievent.mouse_button.y = ievent.mouse_button.global_y = mpos.y;
- input->parse_input_event(ievent);
- };
-
- } break;
- case SCREEN_EVENT_MTOUCH_MOVE: {
-
- screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_POSITION, pos);
-
- InputEvent ievent;
- ievent.type = InputEvent::SCREEN_DRAG;
- ievent.ID = ++last_id;
- ievent.device = 0;
- ievent.screen_drag.x = pos[0];
- ievent.screen_drag.y = pos[1];
-
- /*
- screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_SOURCE_POSITION, pos);
- ievent.screen_drag.relative_x = ievent.screen_drag.x - pos[0];
- ievent.screen_drag.relative_y = ievent.screen_drag.y - pos[1];
- */
-
- screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_TOUCH_ID, &pos[0]);
- ievent.screen_drag.index = pos[0];
-
- ievent.screen_drag.relative_x = ievent.screen_drag.x - last_touch_x[ievent.screen_drag.index];
- ievent.screen_drag.relative_y = ievent.screen_drag.y - last_touch_y[ievent.screen_drag.index];
-
- last_touch_x[ievent.screen_drag.index] = ievent.screen_drag.x;
- last_touch_y[ievent.screen_drag.index] = ievent.screen_drag.y;
-
- Point2 mpos(ievent.screen_drag.x, ievent.screen_drag.y);
- Point2 mrel(ievent.screen_drag.relative_x, ievent.screen_drag.relative_y);
-
- input->parse_input_event(ievent);
-
- if (ievent.screen_touch.index == 0) {
-
- InputEvent ievent;
- ievent.type = InputEvent::MOUSE_MOTION;
- ievent.ID = ++last_id;
- ievent.device = 0;
- ievent.mouse_motion.x = ievent.mouse_motion.global_x = mpos.x;
- ievent.mouse_motion.y = ievent.mouse_motion.global_y = mpos.y;
- input->set_mouse_pos(Point2(ievent.mouse_motion.x, ievent.mouse_motion.y));
- ievent.mouse_motion.speed_x = input->get_last_mouse_speed().x;
- ievent.mouse_motion.speed_y = input->get_last_mouse_speed().y;
- ievent.mouse_motion.relative_x = mrel.x;
- ievent.mouse_motion.relative_y = mrel.y;
- ievent.mouse_motion.button_mask = 1; // pressed
-
- input->parse_input_event(ievent);
- };
- } break;
-
- case SCREEN_EVENT_KEYBOARD: {
-
- InputEvent ievent;
- ievent.type = InputEvent::KEY;
- ievent.ID = ++last_id;
- ievent.device = 0;
- int val = 0;
- screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_KEY_SCAN, &val);
- ievent.key.scancode = val;
- screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_KEY_SYM, &val);
- ievent.key.unicode = val;
- if (val == 61448) {
- ievent.key.scancode = KEY_BACKSPACE;
- ievent.key.unicode = KEY_BACKSPACE;
- };
- if (val == 61453) {
- ievent.key.scancode = KEY_ENTER;
- ievent.key.unicode = KEY_ENTER;
- };
-
- int flags;
- screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_KEY_FLAGS, &flags);
- ievent.key.pressed = flags & 1; // bit 1 is pressed apparently
-
- int mod;
- screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_KEY_MODIFIERS, &mod);
-
- input->parse_input_event(ievent);
- } break;
-
- default:
- break;
- }
-};
-
-void OSBB10::handle_accelerometer() {
-
- if (!accel_supported)
- return;
-
- if (!fullscreen)
- return;
-
- double force_x, force_y, force_z;
- accelerometer_read_forces(&force_x, &force_y, &force_z);
- Vector3 accel = Vector3(force_x, flip_accelerometer ? force_y : -force_y, force_z);
- input->set_accelerometer(accel);
- // rotate 90 degrees
- //input->set_accelerometer(Vector3(force_y, flip_accelerometer?force_x:(-force_x), force_z));
-};
-
-void OSBB10::_resize(bps_event_t *event) {
-
- int angle = navigator_event_get_orientation_angle(event);
- bbutil_rotate_screen_surface(angle);
-
- EGLint surface_width, surface_height;
- eglQuerySurface(egl_disp, egl_surf, EGL_WIDTH, &surface_width);
- eglQuerySurface(egl_disp, egl_surf, EGL_HEIGHT, &surface_height);
-
- VideoMode mode;
- mode.width = surface_width;
- mode.height = surface_height;
- mode.fullscreen = true;
- mode.resizable = false;
- set_video_mode(mode);
-};
-
-void OSBB10::process_events() {
-
- handle_accelerometer();
-
- bps_event_t *event = NULL;
-
- do {
- int rc = bps_get_event(&event, 0);
- assert(rc == BPS_SUCCESS);
-
- if (!event) break;
-
-#ifdef BB10_SCORELOOP_ENABLED
- ScoreloopBB10 *sc = Globals::get_singleton()->get_singleton_object("Scoreloop")->cast_to<ScoreloopBB10>();
- if (sc->handle_event(event))
- continue;
-#endif
-
-#ifdef PAYMENT_SERVICE_ENABLED
- if (payment_service->handle_event(event))
- continue;
-#endif
-
- int domain = bps_event_get_domain(event);
- if (domain == screen_get_domain()) {
-
- handle_screen_event(event);
-
- } else if (domain == navigator_get_domain()) {
-
- if (NAVIGATOR_EXIT == bps_event_get_code(event)) {
- if (main_loop)
- main_loop->notification(MainLoop::NOTIFICATION_WM_QUIT_REQUEST);
- bps_event_destroy(event);
- exit(0);
- return;
- /*
- } else if (bps_event_get_code(event) == NAVIGATOR_ORIENTATION_CHECK) {
-
- int angle = navigator_event_get_orientation_angle(event);
- navigator_orientation_check_response(event, false);
-
- } else if (bps_event_get_code(event) == NAVIGATOR_ORIENTATION) {
-
- _resize(event);
- */
- } else if (bps_event_get_code(event) == NAVIGATOR_WINDOW_STATE) {
-
- int state = navigator_event_get_window_state(event);
- bool was_fullscreen = fullscreen;
- minimized = state == NAVIGATOR_WINDOW_INVISIBLE;
- fullscreen = state == NAVIGATOR_WINDOW_FULLSCREEN;
- set_low_processor_usage_mode(!fullscreen);
- if (fullscreen != was_fullscreen) {
- if (fullscreen) {
- audio_server->set_fx_global_volume_scale(fullscreen_mixer_volume);
- audio_server->set_stream_global_volume_scale(fullscreen_stream_volume);
- } else {
- fullscreen_mixer_volume = audio_server->get_fx_global_volume_scale();
- fullscreen_stream_volume = audio_server->get_stream_global_volume_scale();
- audio_server->set_fx_global_volume_scale(0);
- audio_server->set_stream_global_volume_scale(0);
- };
- };
- };
- } else if (domain == audiodevice_get_domain()) {
-
- const char *audiodevice_path = audiodevice_event_get_path(event);
- printf("************* got audiodevice event, path %s\n", audiodevice_path);
- audio_driver->finish();
- audio_driver->init(audiodevice_path);
- audio_driver->start();
- };
-
- //bps_event_destroy(event);
- } while (event);
-};
-
-bool OSBB10::has_virtual_keyboard() const {
-
- return true;
-};
-
-void OSBB10::show_virtual_keyboard(const String &p_existing_text, const Rect2 &p_screen_rect) {
-
- virtualkeyboard_show();
-};
-
-void OSBB10::hide_virtual_keyboard() {
-
- virtualkeyboard_hide();
-};
-
-void OSBB10::run() {
-
- if (!main_loop)
- return;
-
- main_loop->init();
-
- int flip = bbutil_is_flipped();
- int rot = bbutil_get_rotation();
- flip_accelerometer = rot == 90;
- printf("**************** rot is %i, flip %i\n", rot, (int)flip_accelerometer);
- /*
- orientation_direction_t orientation;
- int angle;
- orientation_get(&orientation, &angle);
- printf("******************** orientation %i, %i, %i\n", orientation, ORIENTATION_BOTTOM_UP, ORIENTATION_TOP_UP);
- if (orientation == ORIENTATION_BOTTOM_UP) {
- flip_accelerometer = true;
- };
- */
-
- while (true) {
-
- process_events(); // get rid of pending events
- if (Main::iteration() == true)
- break;
- bbutil_swap();
- //#ifdef DEBUG_ENABLED
- fflush(stdout);
- //#endif
- };
-
- main_loop->finish();
-};
-
-bool OSBB10::has_touchscreen_ui_hint() const {
-
- return true;
-}
-
-Error OSBB10::shell_open(String p_uri) {
-
- char *msg = NULL;
- int ret = navigator_invoke(p_uri.utf8().get_data(), &msg);
-
- return ret == BPS_SUCCESS ? OK : FAILED;
-};
-
-String OSBB10::get_data_dir() const {
-
- return data_dir;
-};
-
-Size2 OSBB10::get_window_size() const {
- return Vector2(default_videomode.width, default_videomode.height);
-}
-
-PowerState OSBB10::get_power_state() {
- return power_manager->get_power_state();
-}
-
-int OSBB10::get_power_seconds_left() {
- return power_manager->get_power_seconds_left();
-}
-
-int OSBB10::get_power_percent_left() {
- return power_manager->get_power_percent_left();
-}
-
-OSBB10::OSBB10() {
-
- main_loop = NULL;
- last_id = 1;
- minimized = false;
- fullscreen = true;
- flip_accelerometer = true;
- fullscreen_mixer_volume = 1;
- fullscreen_stream_volume = 1;
-
- printf("godot bb10!\n");
- getcwd(launch_dir, sizeof(launch_dir));
- printf("launch dir %s\n", launch_dir);
- chdir("app/native");
- launch_dir_ptr = launch_dir;
-}
-
-OSBB10::~OSBB10() {
-}
diff --git a/platform/bb10/os_bb10.h b/platform/bb10/os_bb10.h
deleted file mode 100644
index 313f9c9e6b..0000000000
--- a/platform/bb10/os_bb10.h
+++ /dev/null
@@ -1,154 +0,0 @@
-/*************************************************************************/
-/* os_bb10.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* http://www.godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
-/* */
-/* 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. */
-/*************************************************************************/
-#ifndef OS_BB10_H
-#define OS_BB10_H
-
-#include "audio_driver_bb10.h"
-#include "drivers/unix/os_unix.h"
-#include "main/input_default.h"
-#include "os/input.h"
-#include "os/main_loop.h"
-#include "payment_service.h"
-#include "power_bb10.h"
-#include "servers/audio_server.h"
-#include "servers/physics/physics_server_sw.h"
-#include "servers/physics_2d/physics_2d_server_sw.h"
-#include "servers/visual/rasterizer.h"
-
-#include <bps/event.h>
-#include <screen/screen.h>
-#include <stdint.h>
-#include <sys/platform.h>
-
-class OSBB10 : public OS_Unix {
-
- unsigned int last_id;
-
- screen_context_t screen_cxt;
- float fullscreen_mixer_volume;
- float fullscreen_stream_volume;
-
- Rasterizer *rasterizer;
- VisualServer *visual_server;
- PhysicsServer *physics_server;
- Physics2DServer *physics_2d_server;
- AudioDriverBB10 *audio_driver;
- PowerBB10 *power_manager;
-
-#ifdef PAYMENT_SERVICE_ENABLED
- PaymentService *payment_service;
-#endif
-
- VideoMode default_videomode;
- MainLoop *main_loop;
-
- void process_events();
-
- void _resize(bps_event_t *event);
- void handle_screen_event(bps_event_t *event);
- void handle_accelerometer();
-
- int last_touch_x[16];
- int last_touch_y[16];
-
- bool accel_supported;
- float pitch;
- float roll;
-
- bool minimized;
- bool fullscreen;
- bool flip_accelerometer;
- String data_dir;
-
- InputDefault *input;
-
-public:
- // functions used by main to initialize/deintialize the OS
- virtual int get_video_driver_count() const;
- virtual const char *get_video_driver_name(int p_driver) const;
-
- virtual VideoMode get_default_video_mode() const;
-
- virtual String get_data_dir() const;
-
- virtual int get_audio_driver_count() const;
- virtual const char *get_audio_driver_name(int p_driver) const;
-
- virtual void initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver);
-
- virtual void set_main_loop(MainLoop *p_main_loop);
- virtual void delete_main_loop();
-
- virtual void finalize();
-
- typedef int64_t ProcessID;
-
- static OS *get_singleton();
-
- virtual void set_mouse_show(bool p_show);
- virtual void set_mouse_grab(bool p_grab);
- virtual bool is_mouse_grab_enabled() const;
- virtual Point2 get_mouse_pos() const;
- virtual int get_mouse_button_state() const;
- virtual void set_window_title(const String &p_title);
-
- //virtual void set_clipboard(const String& p_text);
- //virtual String get_clipboard() const;
-
- virtual bool has_virtual_keyboard() const;
- virtual void show_virtual_keyboard(const String &p_existing_text, const Rect2 &p_screen_rect);
- virtual void hide_virtual_keyboard();
-
- 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;
-
- virtual Size2 get_window_size() const;
- virtual String get_name();
- virtual MainLoop *get_main_loop() const;
-
- virtual bool can_draw() const;
-
- virtual void set_cursor_shape(CursorShape p_shape);
-
- virtual bool has_touchscreen_ui_hint() const;
-
- virtual Error shell_open(String p_uri);
-
- void run();
-
- virtual PowerState get_power_state();
- virtual int get_power_seconds_left();
- virtual int get_power_percent_left();
-
- OSBB10();
- ~OSBB10();
-};
-
-#endif
diff --git a/platform/bb10/payment_service.cpp b/platform/bb10/payment_service.cpp
deleted file mode 100644
index e78326e8b1..0000000000
--- a/platform/bb10/payment_service.cpp
+++ /dev/null
@@ -1,148 +0,0 @@
-/*************************************************************************/
-/* payment_service.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* http://www.godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
-/* */
-/* 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 PAYMENT_SERVICE_ENABLED
-
-#include "payment_service.h"
-
-#include "bbutil.h"
-#include <errno.h>
-#include <string.h>
-#include <unistd.h>
-extern char *launch_dir_ptr;
-
-void PaymentService::_bind_methods() {
-
- ClassDB::bind_method(D_METHOD("request_product_info"), &PaymentService::request_product_info);
- ClassDB::bind_method(D_METHOD("purchase"), &PaymentService::purchase);
-
- ClassDB::bind_method(D_METHOD("get_pending_event_count"), &PaymentService::get_pending_event_count);
- ClassDB::bind_method(D_METHOD("pop_pending_event"), &PaymentService::pop_pending_event);
-};
-
-Error PaymentService::request_product_info(Variant p_params) {
-
- return ERR_UNAVAILABLE;
-};
-
-Error PaymentService::purchase(Variant p_params) {
-
- Dictionary params = p_params;
- ERR_FAIL_COND_V((!params.has("product_id")) && (!params.has("product_sku")), ERR_INVALID_PARAMETER);
-
- char *id = NULL;
- char *sku = NULL;
-
- CharString p_id = params.has("product_id") ? String(params["product_id"]).ascii() : CharString();
- CharString p_sku = params.has("product_sku") ? String(params["product_sku"]).ascii() : CharString();
- unsigned int request_id;
- chdir(launch_dir_ptr);
- int ret = paymentservice_purchase_request(params.has("product_sku") ? NULL : p_id.get_data(),
- params.has("product_sku") ? p_sku.get_data() : NULL,
- NULL, NULL, NULL, NULL, get_window_group_id(), &request_id);
- chdir("app/native");
-
- if (ret != BPS_SUCCESS) {
- int eret = errno;
- printf("purchase error %i, %x, %i, %x\n", ret, ret, eret, eret);
- ERR_FAIL_V((Error)eret);
- return (Error)eret;
- };
- return OK;
-};
-
-bool PaymentService::handle_event(bps_event_t *p_event) {
-
- if (bps_event_get_domain(p_event) != paymentservice_get_domain()) {
- return false;
- };
-
- Dictionary dict;
- int res = paymentservice_event_get_response_code(p_event);
- if (res == SUCCESS_RESPONSE) {
- dict["result"] = "ok";
-
- res = bps_event_get_code(p_event);
- if (res == PURCHASE_RESPONSE) {
- dict["type"] = "purchase";
- const char *pid = paymentservice_event_get_digital_good_id(p_event, 0);
- dict["product_id"] = String(pid ? pid : "");
- };
-
- } else {
- const char *desc = paymentservice_event_get_error_text(p_event);
- if (strcmp(desc, "alreadyPurchased") == 0) {
- dict["result"] = "ok";
- } else {
- dict["result"] = "error";
- dict["error_description"] = paymentservice_event_get_error_text(p_event);
- dict["error_code"] = paymentservice_event_get_error_id(p_event);
- printf("error code is %i\n", paymentservice_event_get_error_id(p_event));
- printf("error description is %s\n", paymentservice_event_get_error_text(p_event));
- };
- dict["product_id"] = "";
- };
-
- res = bps_event_get_code(p_event);
- if (res == PURCHASE_RESPONSE) {
- dict["type"] = "purchase";
- };
-
- printf("********** adding event with result %ls\n", String(dict["result"]).c_str());
- pending_events.push_back(dict);
-
- return true;
-};
-
-int PaymentService::get_pending_event_count() {
- return pending_events.size();
-};
-
-Variant PaymentService::pop_pending_event() {
-
- Variant front = pending_events.front()->get();
- pending_events.pop_front();
-
- return front;
-};
-
-PaymentService::PaymentService() {
-
- paymentservice_request_events(0);
-#ifdef DEBUG_ENABLED
- paymentservice_set_connection_mode(true);
-#else
- paymentservice_set_connection_mode(false);
-#endif
-};
-
-PaymentService::~PaymentService(){
-
-};
-
-#endif
diff --git a/platform/bb10/payment_service.h b/platform/bb10/payment_service.h
deleted file mode 100644
index d5b4cc3d60..0000000000
--- a/platform/bb10/payment_service.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*************************************************************************/
-/* payment_service.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* http://www.godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
-/* */
-/* 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 PAYMENT_SERVICE_ENABLED
-
-#ifndef PAYMENT_SERVICE_H
-#define PAYMENT_SERVICE_H
-
-#include <bps/bps.h>
-#include <bps/event.h>
-#include <bps/paymentservice.h>
-
-#include "core/object.h"
-
-class PaymentService : public Object {
-
- GDCLASS(PaymentService, Object);
-
- static void _bind_methods();
-
- List<Variant> pending_events;
-
-public:
- Error request_product_info(Variant p_params);
- Error purchase(Variant p_params);
-
- int get_pending_event_count();
- Variant pop_pending_event();
-
- bool handle_event(bps_event_t *p_event);
-
- PaymentService();
- ~PaymentService();
-};
-
-#endif
-
-#endif
diff --git a/platform/bb10/platform_config.h b/platform/bb10/platform_config.h
deleted file mode 100644
index cdef185ff0..0000000000
--- a/platform/bb10/platform_config.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*************************************************************************/
-/* platform_config.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* http://www.godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
-/* */
-/* 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 <alloca.h>
diff --git a/platform/haiku/audio_driver_media_kit.cpp b/platform/haiku/audio_driver_media_kit.cpp
index 0f969d25ab..93351e0799 100644
--- a/platform/haiku/audio_driver_media_kit.cpp
+++ b/platform/haiku/audio_driver_media_kit.cpp
@@ -6,6 +6,7 @@
/* http://www.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 */
@@ -30,7 +31,7 @@
#ifdef MEDIA_KIT_ENABLED
-#include "global_config.h"
+#include "project_settings.h"
int32_t *AudioDriverMediaKit::samples_in = NULL;
diff --git a/platform/haiku/audio_driver_media_kit.h b/platform/haiku/audio_driver_media_kit.h
index e9282c8471..2cceb279e8 100644
--- a/platform/haiku/audio_driver_media_kit.h
+++ b/platform/haiku/audio_driver_media_kit.h
@@ -6,6 +6,7 @@
/* http://www.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 */
diff --git a/platform/haiku/context_gl_haiku.cpp b/platform/haiku/context_gl_haiku.cpp
index f345928005..eb5e60152f 100644
--- a/platform/haiku/context_gl_haiku.cpp
+++ b/platform/haiku/context_gl_haiku.cpp
@@ -6,6 +6,7 @@
/* http://www.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 */
diff --git a/platform/haiku/context_gl_haiku.h b/platform/haiku/context_gl_haiku.h
index c0030fad41..074b4bf0d1 100644
--- a/platform/haiku/context_gl_haiku.h
+++ b/platform/haiku/context_gl_haiku.h
@@ -6,6 +6,7 @@
/* http://www.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 */
diff --git a/platform/haiku/detect.py b/platform/haiku/detect.py
index 71202a9a49..c0e003a3d2 100644
--- a/platform/haiku/detect.py
+++ b/platform/haiku/detect.py
@@ -11,57 +11,58 @@ def get_name():
def can_build():
- if (os.name != "posix"):
- return False
- if (sys.platform == "darwin"):
+ if (os.name != "posix" or sys.platform == "darwin"):
return False
return True
def get_opts():
+
return [
('debug_release', 'Add debug symbols to release version', 'no')
]
def get_flags():
+
return [
]
def configure(env):
- is64 = sys.maxsize > 2**32
-
- if (env["bits"] == "default"):
- if (is64):
- env["bits"] = "64"
- else:
- env["bits"] = "32"
-
- env.Append(CPPPATH=['#platform/haiku'])
- env["CC"] = "gcc-x86"
- env["CXX"] = "g++-x86"
+ ## Build type
if (env["target"] == "release"):
if (env["debug_release"] == "yes"):
- env.Append(CCFLAGS=['-g2'])
+ env.Prepend(CCFLAGS=['-g2'])
else:
- env.Append(CCFLAGS=['-O3', '-ffast-math'])
+ env.Prepend(CCFLAGS=['-O3', '-ffast-math'])
+
elif (env["target"] == "release_debug"):
- env.Append(CCFLAGS=['-O2', '-ffast-math', '-DDEBUG_ENABLED'])
+ env.Prepend(CCFLAGS=['-O2', '-ffast-math', '-DDEBUG_ENABLED'])
+
elif (env["target"] == "debug"):
- env.Append(CCFLAGS=['-g2', '-Wall', '-DDEBUG_ENABLED', '-DDEBUG_MEMORY_ENABLED'])
+ env.Prepend(CCFLAGS=['-g2', '-DDEBUG_ENABLED', '-DDEBUG_MEMORY_ENABLED'])
+
+ ## Architecture
+
+ is64 = sys.maxsize > 2**32
+ if (env["bits"] == "default"):
+ env["bits"] = "64" if is64 else "32"
+
+ ## Compiler configuration
+ env["CC"] = "gcc-x86"
+ env["CXX"] = "g++-x86"
+
+ ## Flags
+
+ env.Append(CPPPATH=['#platform/haiku'])
+ env.Append(CPPFLAGS=['-DUNIX_ENABLED', '-DOPENGL_ENABLED', '-DGLES2_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
- env.Append(CPPFLAGS=['-DOPENGL_ENABLED', '-DMEDIA_KIT_ENABLED'])
- env.Append(CPPFLAGS=['-DUNIX_ENABLED', '-DGLES2_ENABLED', '-DGLES_OVER_GL'])
env.Append(LIBS=['be', 'game', 'media', 'network', 'bnetapi', 'z', 'GL'])
-
- import methods
- env.Append(BUILDERS={'GLSL120': env.Builder(action=methods.build_legacygl_headers, suffix='glsl.h', src_suffix='.glsl')})
- env.Append(BUILDERS={'GLSL': env.Builder(action=methods.build_glsl_headers, suffix='glsl.h', src_suffix='.glsl')})
- env.Append(BUILDERS={'GLSL120GLES': env.Builder(action=methods.build_gles2_headers, suffix='glsl.h', src_suffix='.glsl')})
diff --git a/platform/haiku/godot_haiku.cpp b/platform/haiku/godot_haiku.cpp
index 47cfbe55d7..3a8206d9d5 100644
--- a/platform/haiku/godot_haiku.cpp
+++ b/platform/haiku/godot_haiku.cpp
@@ -6,6 +6,7 @@
/* http://www.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 */
diff --git a/platform/haiku/haiku_application.cpp b/platform/haiku/haiku_application.cpp
index f675d4216d..1f0c9fdcbf 100644
--- a/platform/haiku/haiku_application.cpp
+++ b/platform/haiku/haiku_application.cpp
@@ -6,6 +6,7 @@
/* http://www.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 */
diff --git a/platform/haiku/haiku_application.h b/platform/haiku/haiku_application.h
index 7fbce5dcbc..6e690d4ab8 100644
--- a/platform/haiku/haiku_application.h
+++ b/platform/haiku/haiku_application.h
@@ -6,6 +6,7 @@
/* http://www.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 */
diff --git a/platform/haiku/haiku_direct_window.cpp b/platform/haiku/haiku_direct_window.cpp
index 3ed7a84eb5..4a9f8c780d 100644
--- a/platform/haiku/haiku_direct_window.cpp
+++ b/platform/haiku/haiku_direct_window.cpp
@@ -6,6 +6,7 @@
/* http://www.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 */
@@ -150,36 +151,35 @@ void HaikuDirectWindow::HandleMouseButton(BMessage *message) {
}
*/
- InputEvent mouse_event;
- mouse_event.ID = ++event_id;
- mouse_event.type = InputEvent::MOUSE_BUTTON;
+ Ref<InputEvent> mouse_event;
+ mouse_event.type = Ref<InputEvent>::MOUSE_BUTTON;
mouse_event.device = 0;
mouse_event.mouse_button.mod = GetKeyModifierState(modifiers);
- mouse_event.mouse_button.button_mask = GetMouseButtonState(buttons);
- mouse_event.mouse_button.x = where.x;
- mouse_event.mouse_button.y = where.y;
+ mouse_event->get_button_mask() = GetMouseButtonState(buttons);
+ mouse_event->get_pos().x = where.x;
+ mouse_event->get_pos().y = where.y;
mouse_event.mouse_button.global_x = where.x;
mouse_event.mouse_button.global_y = where.y;
switch (button) {
default:
case B_PRIMARY_MOUSE_BUTTON:
- mouse_event.mouse_button.button_index = 1;
+ mouse_event->get_button_index() = 1;
break;
case B_SECONDARY_MOUSE_BUTTON:
- mouse_event.mouse_button.button_index = 2;
+ mouse_event->get_button_index() = 2;
break;
case B_TERTIARY_MOUSE_BUTTON:
- mouse_event.mouse_button.button_index = 3;
+ mouse_event->get_button_index() = 3;
break;
}
- mouse_event.mouse_button.pressed = (message->what == B_MOUSE_DOWN);
+ mouse_event->is_pressed() = (message->what == B_MOUSE_DOWN);
- if (message->what == B_MOUSE_DOWN && mouse_event.mouse_button.button_index == 1) {
+ if (message->what == B_MOUSE_DOWN && mouse_event->get_button_index() == 1) {
int32 clicks = message->FindInt32("clicks");
if (clicks > 1) {
@@ -207,23 +207,22 @@ void HaikuDirectWindow::HandleMouseMoved(BMessage *message) {
Point2i rel = pos - last_mouse_position;
- InputEvent motion_event;
- motion_event.ID = ++event_id;
- motion_event.type = InputEvent::MOUSE_MOTION;
+ Ref<InputEvent> motion_event;
+ motion_event.type = Ref<InputEvent>::MOUSE_MOTION;
motion_event.device = 0;
motion_event.mouse_motion.mod = GetKeyModifierState(modifiers);
- motion_event.mouse_motion.button_mask = GetMouseButtonState(buttons);
+ motion_event->get_button_mask() = GetMouseButtonState(buttons);
motion_event.mouse_motion.x = pos.x;
motion_event.mouse_motion.y = pos.y;
- input->set_mouse_pos(pos);
+ input->set_mouse_position(pos);
motion_event.mouse_motion.global_x = pos.x;
motion_event.mouse_motion.global_y = pos.y;
motion_event.mouse_motion.speed_x = input->get_last_mouse_speed().x;
motion_event.mouse_motion.speed_y = input->get_last_mouse_speed().y;
- motion_event.mouse_motion.relative_x = rel.x;
- motion_event.mouse_motion.relative_y = rel.y;
+ motion_event->get_relative().x = rel.x;
+ motion_event->get_relative().y = rel.y;
last_mouse_position = pos;
@@ -236,24 +235,22 @@ void HaikuDirectWindow::HandleMouseWheelChanged(BMessage *message) {
return;
}
- InputEvent mouse_event;
- mouse_event.ID = ++event_id;
- mouse_event.type = InputEvent::MOUSE_BUTTON;
+ Ref<InputEvent> mouse_event;
+ mouse_event.type = Ref<InputEvent>::MOUSE_BUTTON;
mouse_event.device = 0;
- mouse_event.mouse_button.button_index = wheel_delta_y < 0 ? 4 : 5;
+ mouse_event->get_button_index() = wheel_delta_y < 0 ? 4 : 5;
mouse_event.mouse_button.mod = GetKeyModifierState(last_key_modifier_state);
- mouse_event.mouse_button.button_mask = last_button_mask;
- mouse_event.mouse_button.x = last_mouse_position.x;
- mouse_event.mouse_button.y = last_mouse_position.y;
+ mouse_event->get_button_mask() = last_button_mask;
+ mouse_event->get_pos().x = last_mouse_position.x;
+ mouse_event->get_pos().y = last_mouse_position.y;
mouse_event.mouse_button.global_x = last_mouse_position.x;
mouse_event.mouse_button.global_y = last_mouse_position.y;
- mouse_event.mouse_button.pressed = true;
+ mouse_event->is_pressed() = true;
input->parse_input_event(mouse_event);
- mouse_event.ID = ++event_id;
- mouse_event.mouse_button.pressed = false;
+ mouse_event->is_pressed() = false;
input->parse_input_event(mouse_event);
}
@@ -274,14 +271,13 @@ void HaikuDirectWindow::HandleKeyboardEvent(BMessage *message) {
return;
}
- InputEvent event;
- event.ID = ++event_id;
- event.type = InputEvent::KEY;
+ Ref<InputEvent> event;
+ event.type = Ref<InputEvent>::KEY;
event.device = 0;
event.key.mod = GetKeyModifierState(modifiers);
- event.key.pressed = (message->what == B_KEY_DOWN);
- event.key.scancode = KeyMappingHaiku::get_keysym(raw_char, key);
- event.key.echo = message->HasInt32("be:key_repeat");
+ event->is_pressed() = (message->what == B_KEY_DOWN);
+ event->get_scancode() = KeyMappingHaiku::get_keysym(raw_char, key);
+ event->is_echo() = message->HasInt32("be:key_repeat");
event.key.unicode = 0;
const char *bytes = NULL;
@@ -290,9 +286,9 @@ void HaikuDirectWindow::HandleKeyboardEvent(BMessage *message) {
}
//make it consistent across platforms.
- if (event.key.scancode == KEY_BACKTAB) {
- event.key.scancode = KEY_TAB;
- event.key.mod.shift = true;
+ if (event->get_scancode() == KEY_BACKTAB) {
+ event->get_scancode() = KEY_TAB;
+ event->get_shift() = true;
}
input->parse_input_event(event);
@@ -312,14 +308,13 @@ void HaikuDirectWindow::HandleKeyboardModifierEvent(BMessage *message) {
int32 key = old_modifiers ^ modifiers;
- InputEvent event;
- event.ID = ++event_id;
- event.type = InputEvent::KEY;
+ Ref<InputEvent> event;
+ event.type = Ref<InputEvent>::KEY;
event.device = 0;
event.key.mod = GetKeyModifierState(modifiers);
- event.key.pressed = ((modifiers & key) != 0);
- event.key.scancode = KeyMappingHaiku::get_modifier_keysym(key);
- event.key.echo = false;
+ event->is_pressed() = ((modifiers & key) != 0);
+ event->get_scancode() = KeyMappingHaiku::get_modifier_keysym(key);
+ event->is_echo() = false;
event.key.unicode = 0;
input->parse_input_event(event);
diff --git a/platform/haiku/haiku_direct_window.h b/platform/haiku/haiku_direct_window.h
index 7fcea7a6f6..3671c3c9cb 100644
--- a/platform/haiku/haiku_direct_window.h
+++ b/platform/haiku/haiku_direct_window.h
@@ -6,6 +6,7 @@
/* http://www.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 */
@@ -43,7 +44,6 @@
class HaikuDirectWindow : public BDirectWindow {
private:
- unsigned int event_id;
Point2i last_mouse_position;
bool last_mouse_pos_valid;
uint32 last_buttons_state;
diff --git a/platform/haiku/haiku_gl_view.cpp b/platform/haiku/haiku_gl_view.cpp
index ded15e12a7..dd568f281e 100644
--- a/platform/haiku/haiku_gl_view.cpp
+++ b/platform/haiku/haiku_gl_view.cpp
@@ -6,6 +6,7 @@
/* http://www.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 */
diff --git a/platform/haiku/haiku_gl_view.h b/platform/haiku/haiku_gl_view.h
index f06bc64794..14e2889d6c 100644
--- a/platform/haiku/haiku_gl_view.h
+++ b/platform/haiku/haiku_gl_view.h
@@ -6,6 +6,7 @@
/* http://www.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 */
diff --git a/platform/haiku/key_mapping_haiku.cpp b/platform/haiku/key_mapping_haiku.cpp
index 1bc3467914..3db31fa3e4 100644
--- a/platform/haiku/key_mapping_haiku.cpp
+++ b/platform/haiku/key_mapping_haiku.cpp
@@ -6,6 +6,7 @@
/* http://www.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 */
@@ -82,7 +83,7 @@ static _HaikuTranslatePair _fn_to_keycode[] = {
static _HaikuTranslatePair _hb_to_keycode[] = {
{ KEY_BACKSPACE, B_BACKSPACE },
{ KEY_TAB, B_TAB },
- { KEY_RETURN, B_RETURN },
+ { KEY_ENTER, B_RETURN },
{ KEY_CAPSLOCK, B_CAPS_LOCK },
{ KEY_ESCAPE, B_ESCAPE },
{ KEY_SPACE, B_SPACE },
diff --git a/platform/haiku/key_mapping_haiku.h b/platform/haiku/key_mapping_haiku.h
index 0f2e2e64bd..8d09203737 100644
--- a/platform/haiku/key_mapping_haiku.h
+++ b/platform/haiku/key_mapping_haiku.h
@@ -6,6 +6,7 @@
/* http://www.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 */
diff --git a/platform/haiku/os_haiku.cpp b/platform/haiku/os_haiku.cpp
index 0853fac393..e897d4c385 100644
--- a/platform/haiku/os_haiku.cpp
+++ b/platform/haiku/os_haiku.cpp
@@ -6,6 +6,7 @@
/* http://www.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 */
@@ -206,7 +207,7 @@ void OS_Haiku::swap_buffers() {
context_gl->swap_buffers();
}
-Point2 OS_Haiku::get_mouse_pos() const {
+Point2 OS_Haiku::get_mouse_position() const {
return window->GetLastMousePosition();
}
@@ -330,3 +331,8 @@ void OS_Haiku::get_fullscreen_mode_list(List<VideoMode> *p_list, int p_screen) c
String OS_Haiku::get_executable_path() const {
return OS::get_executable_path();
}
+
+bool OS_Haiku::_check_internal_feature_support(const String &p_feature) {
+
+ return p_feature == "pc" || p_feature == "s3tc";
+}
diff --git a/platform/haiku/os_haiku.h b/platform/haiku/os_haiku.h
index 827814c7e9..256c9eecf7 100644
--- a/platform/haiku/os_haiku.h
+++ b/platform/haiku/os_haiku.h
@@ -6,6 +6,7 @@
/* http://www.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 */
@@ -88,7 +89,7 @@ public:
virtual void make_rendering_thread();
virtual void swap_buffers();
- virtual Point2 get_mouse_pos() const;
+ virtual Point2 get_mouse_position() const;
virtual int get_mouse_button_state() const;
virtual void set_cursor_shape(CursorShape p_shape);
@@ -119,6 +120,8 @@ public:
virtual PowerState get_power_state();
virtual int get_power_seconds_left();
virtual int get_power_percent_left();
+
+ virtual bool _check_internal_feature_support(const String &p_feature);
};
#endif
diff --git a/platform/haiku/platform_config.h b/platform/haiku/platform_config.h
index a3aa918ba8..e59b9bac80 100644
--- a/platform/haiku/platform_config.h
+++ b/platform/haiku/platform_config.h
@@ -6,6 +6,7 @@
/* http://www.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 */
diff --git a/platform/haiku/power_haiku.cpp b/platform/haiku/power_haiku.cpp
index d70aad9d5f..b0d01df982 100644
--- a/platform/haiku/power_haiku.cpp
+++ b/platform/haiku/power_haiku.cpp
@@ -6,6 +6,7 @@
/* http://www.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 */
diff --git a/platform/haiku/power_haiku.h b/platform/haiku/power_haiku.h
index 8e7b050cd6..711ad86a02 100644
--- a/platform/haiku/power_haiku.h
+++ b/platform/haiku/power_haiku.h
@@ -6,6 +6,7 @@
/* http://www.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 */
diff --git a/platform/iphone/SCsub b/platform/iphone/SCsub
index 5d3267cff3..998d0a3f0d 100644
--- a/platform/iphone/SCsub
+++ b/platform/iphone/SCsub
@@ -5,7 +5,6 @@ Import('env')
iphone_lib = [
'os_iphone.cpp',
- #'rasterizer_iphone.cpp',
'audio_driver_iphone.cpp',
'sem_iphone.cpp',
'gl_view.mm',
@@ -18,17 +17,8 @@ iphone_lib = [
'ios.mm',
]
-# env.Depends('#core/math/vector3.h', 'vector3_psp.h')
-
-#iphone_lib = env.Library('iphone', iphone_lib)
-
env_ios = env.Clone()
-
-if env['ios_gles22_override'] == "yes":
- env_ios.Append(CPPFLAGS=['-DGLES2_OVERRIDE'])
-
-
obj = env_ios.Object('godot_iphone.cpp')
prog = None
diff --git a/platform/iphone/app_delegate.h b/platform/iphone/app_delegate.h
index eaa74946ee..f357427144 100644
--- a/platform/iphone/app_delegate.h
+++ b/platform/iphone/app_delegate.h
@@ -6,6 +6,7 @@
/* http://www.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 */
diff --git a/platform/iphone/app_delegate.mm b/platform/iphone/app_delegate.mm
index e82649692c..362cfd1478 100644
--- a/platform/iphone/app_delegate.mm
+++ b/platform/iphone/app_delegate.mm
@@ -6,6 +6,7 @@
/* http://www.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 */
@@ -27,11 +28,12 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#import "app_delegate.h"
-#import "gl_view.h"
-#include "os_iphone.h"
-#include "core/global_config.h"
+#include "audio_driver_iphone.h"
+#include "core/project_settings.h"
+#import "gl_view.h"
#include "main/main.h"
+#include "os_iphone.h"
#ifdef MODULE_FACEBOOKSCORER_IOS_ENABLED
#include "modules/FacebookScorer_ios/FacebookScorer.h"
@@ -44,24 +46,26 @@
#endif
#ifdef MODULE_PARSE_ENABLED
-#import <Parse/Parse.h>
#import "FBSDKCoreKit/FBSDKCoreKit.h"
+#import <Parse/Parse.h>
#endif
-#define kFilteringFactor 0.1
-#define kRenderingFrequency 60
-#define kAccelerometerFrequency 100.0 // Hz
+#import "GameController/GameController.h"
+
+#define kFilteringFactor 0.1
+#define kRenderingFrequency 60
+#define kAccelerometerFrequency 100.0 // Hz
Error _shell_open(String);
void _set_keep_screen_on(bool p_enabled);
Error _shell_open(String p_uri) {
- NSString* url = [[NSString alloc] initWithUTF8String:p_uri.utf8().get_data()];
+ NSString *url = [[NSString alloc] initWithUTF8String:p_uri.utf8().get_data()];
- if (![[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:url]])
- return ERR_CANT_OPEN;
+ if (![[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:url]])
+ return ERR_CANT_OPEN;
- printf("opening url %ls\n", p_uri.c_str());
+ printf("opening url %ls\n", p_uri.c_str());
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:url]];
[url release];
return OK;
@@ -76,325 +80,664 @@ void _set_keep_screen_on(bool p_enabled) {
@synthesize window;
extern int gargc;
-extern char** gargv;
-extern int iphone_main(int, int, int, char**);
+extern char **gargv;
+extern int iphone_main(int, int, int, char **);
extern void iphone_finish();
CMMotionManager *motionManager;
-bool motionInitialised;
+bool motionInitialised;
-static ViewController* mainViewController = nil;
-+ (ViewController*) getViewController
-{
+static ViewController *mainViewController = nil;
++ (ViewController *)getViewController {
return mainViewController;
}
-static int frame_count = 0;
-- (void)drawView:(GLView*)view; {
+NSMutableDictionary *ios_joysticks = nil;
+
+- (GCControllerPlayerIndex)getFreePlayerIndex {
+ bool have_player_1 = false;
+ bool have_player_2 = false;
+ bool have_player_3 = false;
+ bool have_player_4 = false;
+
+ if (ios_joysticks == nil) {
+ NSArray *keys = [ios_joysticks allKeys];
+ for (NSNumber *key in keys) {
+ GCController *controller = [ios_joysticks objectForKey:key];
+ if (controller.playerIndex == GCControllerPlayerIndex1) {
+ have_player_1 = true;
+ } else if (controller.playerIndex == GCControllerPlayerIndex2) {
+ have_player_2 = true;
+ } else if (controller.playerIndex == GCControllerPlayerIndex3) {
+ have_player_3 = true;
+ } else if (controller.playerIndex == GCControllerPlayerIndex4) {
+ have_player_4 = true;
+ };
+ };
+ };
- switch (frame_count) {
+ if (!have_player_1) {
+ return GCControllerPlayerIndex1;
+ } else if (!have_player_2) {
+ return GCControllerPlayerIndex2;
+ } else if (!have_player_3) {
+ return GCControllerPlayerIndex3;
+ } else if (!have_player_4) {
+ return GCControllerPlayerIndex4;
+ } else {
+ return GCControllerPlayerIndexUnset;
+ };
+};
- case 0: {
- int backingWidth;
- int backingHeight;
- glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &backingWidth);
- glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &backingHeight);
+- (void)controllerWasConnected:(NSNotification *)notification {
+ // create our dictionary if we don't have one yet
+ if (ios_joysticks == nil) {
+ ios_joysticks = [[NSMutableDictionary alloc] init];
+ };
+ // get our controller
+ GCController *controller = (GCController *)notification.object;
+ if (controller == nil) {
+ printf("Couldn't retrieve new controller\n");
+ } else if ([[ios_joysticks allKeysForObject:controller] count] != 0) {
+ printf("Controller is already registered\n");
+ } else {
+ // get a new id for our controller
+ int joy_id = OSIPhone::get_singleton()->get_unused_joy_id();
+ if (joy_id != -1) {
+ // assign our player index
+ if (controller.playerIndex == GCControllerPlayerIndexUnset) {
+ controller.playerIndex = [self getFreePlayerIndex];
+ };
- OS::VideoMode vm;
- vm.fullscreen = true;
- vm.width = backingWidth;
- vm.height = backingHeight;
- vm.resizable = false;
- OS::get_singleton()->set_video_mode(vm);
+ // tell Godot about our new controller
+ OSIPhone::get_singleton()->joy_connection_changed(
+ joy_id, true, [controller.vendorName UTF8String]);
- if (!OS::get_singleton()) {
- exit(0);
+ // add it to our dictionary, this will retain our controllers
+ [ios_joysticks setObject:controller
+ forKey:[NSNumber numberWithInt:joy_id]];
+
+ // set our input handler
+ [self setControllerInputHandler:controller];
+ } else {
+ printf("Couldn't retrieve new joy id\n");
};
- ++frame_count;
-
- NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
- NSString *documentsDirectory = [paths objectAtIndex:0];
- //NSString *documentsDirectory = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
- OSIPhone::get_singleton()->set_data_dir(String::utf8([documentsDirectory UTF8String]));
-
- NSString *locale_code = [[[NSLocale preferredLanguages] objectAtIndex:0] substringToIndex:2];
- OSIPhone::get_singleton()->set_locale(String::utf8([locale_code UTF8String]));
-
- NSString* uuid;
- if ([[UIDevice currentDevice]respondsToSelector:@selector(identifierForVendor)]) {
- uuid = [UIDevice currentDevice].identifierForVendor.UUIDString;
- }else{
-
- // before iOS 6, so just generate an identifier and store it
- uuid = [[NSUserDefaults standardUserDefaults] objectForKey:@"identiferForVendor"];
- if( !uuid ) {
- CFUUIDRef cfuuid = CFUUIDCreate(NULL);
- uuid = (__bridge_transfer NSString*)CFUUIDCreateString(NULL, cfuuid);
- CFRelease(cfuuid);
- [[NSUserDefaults standardUserDefaults] setObject:uuid forKey:@"identifierForVendor"];
- }
- }
+ };
+};
- OSIPhone::get_singleton()->set_unique_ID(String::utf8([uuid UTF8String]));
+- (void)controllerWasDisconnected:(NSNotification *)notification {
+ if (ios_joysticks != nil) {
+ // find our joystick, there should be only one in our dictionary
+ GCController *controller = (GCController *)notification.object;
+ NSArray *keys = [ios_joysticks allKeysForObject:controller];
+ for (NSNumber *key in keys) {
+ // tell Godot this joystick is no longer there
+ int joy_id = [key intValue];
+ OSIPhone::get_singleton()->joy_connection_changed(joy_id, false, "");
+
+ // and remove it from our dictionary
+ [ios_joysticks removeObjectForKey:key];
+ };
+ };
+};
- }; break;
-/*
- case 1: {
- ++frame_count;
- } break;
-*/
- case 1: {
+- (int)getJoyIdForController:(GCController *)controller {
+ if (ios_joysticks != nil) {
+ // find our joystick, there should be only one in our dictionary
+ NSArray *keys = [ios_joysticks allKeysForObject:controller];
+ for (NSNumber *key in keys) {
+ int joy_id = [key intValue];
+ return joy_id;
+ };
+ };
- Main::setup2();
- ++frame_count;
+ return -1;
+};
- // this might be necessary before here
- NSDictionary* dict = [[NSBundle mainBundle] infoDictionary];
- for (NSString* key in dict) {
- NSObject* value = [dict objectForKey:key];
- String ukey = String::utf8([key UTF8String]);
+- (void)setControllerInputHandler:(GCController *)controller {
+ // Hook in the callback handler for the correct gamepad profile.
+ // This is a bit of a weird design choice on Apples part.
+ // You need to select the most capable gamepad profile for the
+ // gamepad attached.
+ if (controller.extendedGamepad != nil) {
+ // The extended gamepad profile has all the input you could possibly find on
+ // a gamepad but will only be active if your gamepad actually has all of
+ // these...
+ controller.extendedGamepad.valueChangedHandler = ^(
+ GCExtendedGamepad *gamepad, GCControllerElement *element) {
+ int joy_id = [self getJoyIdForController:controller];
+
+ if (element == gamepad.buttonA) {
+ OSIPhone::get_singleton()->joy_button(joy_id, JOY_BUTTON_0,
+ gamepad.buttonA.isPressed);
+ } else if (element == gamepad.buttonB) {
+ OSIPhone::get_singleton()->joy_button(joy_id, JOY_BUTTON_1,
+ gamepad.buttonB.isPressed);
+ } else if (element == gamepad.buttonX) {
+ OSIPhone::get_singleton()->joy_button(joy_id, JOY_BUTTON_2,
+ gamepad.buttonX.isPressed);
+ } else if (element == gamepad.buttonY) {
+ OSIPhone::get_singleton()->joy_button(joy_id, JOY_BUTTON_3,
+ gamepad.buttonY.isPressed);
+ } else if (element == gamepad.leftShoulder) {
+ OSIPhone::get_singleton()->joy_button(joy_id, JOY_L,
+ gamepad.leftShoulder.isPressed);
+ } else if (element == gamepad.rightShoulder) {
+ OSIPhone::get_singleton()->joy_button(joy_id, JOY_R,
+ gamepad.rightShoulder.isPressed);
+ } else if (element == gamepad.leftTrigger) {
+ OSIPhone::get_singleton()->joy_button(joy_id, JOY_L2,
+ gamepad.leftTrigger.isPressed);
+ } else if (element == gamepad.rightTrigger) {
+ OSIPhone::get_singleton()->joy_button(joy_id, JOY_R2,
+ gamepad.rightTrigger.isPressed);
+ } else if (element == gamepad.dpad) {
+ OSIPhone::get_singleton()->joy_button(joy_id, JOY_DPAD_UP,
+ gamepad.dpad.up.isPressed);
+ OSIPhone::get_singleton()->joy_button(joy_id, JOY_DPAD_DOWN,
+ gamepad.dpad.down.isPressed);
+ OSIPhone::get_singleton()->joy_button(joy_id, JOY_DPAD_LEFT,
+ gamepad.dpad.left.isPressed);
+ OSIPhone::get_singleton()->joy_button(joy_id, JOY_DPAD_RIGHT,
+ gamepad.dpad.right.isPressed);
+ };
- // we need a NSObject to Variant conversor
+ InputDefault::JoyAxis jx;
+ jx.min = -1;
+ if (element == gamepad.leftThumbstick) {
+ jx.value = gamepad.leftThumbstick.xAxis.value;
+ OSIPhone::get_singleton()->joy_axis(joy_id, JOY_ANALOG_LX, jx);
+ jx.value = -gamepad.leftThumbstick.yAxis.value;
+ OSIPhone::get_singleton()->joy_axis(joy_id, JOY_ANALOG_LY, jx);
+ } else if (element == gamepad.rightThumbstick) {
+ jx.value = gamepad.rightThumbstick.xAxis.value;
+ OSIPhone::get_singleton()->joy_axis(joy_id, JOY_ANALOG_RX, jx);
+ jx.value = -gamepad.rightThumbstick.yAxis.value;
+ OSIPhone::get_singleton()->joy_axis(joy_id, JOY_ANALOG_RY, jx);
+ } else if (element == gamepad.leftTrigger) {
+ jx.value = gamepad.leftTrigger.value;
+ OSIPhone::get_singleton()->joy_axis(joy_id, JOY_ANALOG_L2, jx);
+ } else if (element == gamepad.rightTrigger) {
+ jx.value = gamepad.rightTrigger.value;
+ OSIPhone::get_singleton()->joy_axis(joy_id, JOY_ANALOG_R2, jx);
+ };
+ };
+ } else if (controller.gamepad != nil) {
+ // gamepad is the standard profile with 4 buttons, shoulder buttons and a
+ // D-pad
+ controller.gamepad.valueChangedHandler = ^(GCGamepad *gamepad,
+ GCControllerElement *element) {
+ int joy_id = [self getJoyIdForController:controller];
+
+ if (element == gamepad.buttonA) {
+ OSIPhone::get_singleton()->joy_button(joy_id, JOY_BUTTON_0,
+ gamepad.buttonA.isPressed);
+ } else if (element == gamepad.buttonB) {
+ OSIPhone::get_singleton()->joy_button(joy_id, JOY_BUTTON_1,
+ gamepad.buttonB.isPressed);
+ } else if (element == gamepad.buttonX) {
+ OSIPhone::get_singleton()->joy_button(joy_id, JOY_BUTTON_2,
+ gamepad.buttonX.isPressed);
+ } else if (element == gamepad.buttonY) {
+ OSIPhone::get_singleton()->joy_button(joy_id, JOY_BUTTON_3,
+ gamepad.buttonY.isPressed);
+ } else if (element == gamepad.leftShoulder) {
+ OSIPhone::get_singleton()->joy_button(joy_id, JOY_L,
+ gamepad.leftShoulder.isPressed);
+ } else if (element == gamepad.rightShoulder) {
+ OSIPhone::get_singleton()->joy_button(joy_id, JOY_R,
+ gamepad.rightShoulder.isPressed);
+ } else if (element == gamepad.dpad) {
+ OSIPhone::get_singleton()->joy_button(joy_id, JOY_DPAD_UP,
+ gamepad.dpad.up.isPressed);
+ OSIPhone::get_singleton()->joy_button(joy_id, JOY_DPAD_DOWN,
+ gamepad.dpad.down.isPressed);
+ OSIPhone::get_singleton()->joy_button(joy_id, JOY_DPAD_LEFT,
+ gamepad.dpad.left.isPressed);
+ OSIPhone::get_singleton()->joy_button(joy_id, JOY_DPAD_RIGHT,
+ gamepad.dpad.right.isPressed);
+ };
+ };
+#ifdef ADD_MICRO_GAMEPAD // disabling this for now, only available on iOS 9+,
+ // while we are setting that as the minimum, seems our
+ // build environment doesn't like it
+ } else if (controller.microGamepad != nil) {
+ // micro gamepads were added in OS 9 and feature just 2 buttons and a d-pad
+ controller.microGamepad.valueChangedHandler =
+ ^(GCMicroGamepad *gamepad, GCControllerElement *element) {
+ int joy_id = [self getJoyIdForController:controller];
+
+ if (element == gamepad.buttonA) {
+ OSIPhone::get_singleton()->joy_button(joy_id, JOY_BUTTON_0,
+ gamepad.buttonA.isPressed);
+ } else if (element == gamepad.buttonX) {
+ OSIPhone::get_singleton()->joy_button(joy_id, JOY_BUTTON_2,
+ gamepad.buttonX.isPressed);
+ } else if (element == gamepad.dpad) {
+ OSIPhone::get_singleton()->joy_button(joy_id, JOY_DPAD_UP,
+ gamepad.dpad.up.isPressed);
+ OSIPhone::get_singleton()->joy_button(joy_id, JOY_DPAD_DOWN,
+ gamepad.dpad.down.isPressed);
+ OSIPhone::get_singleton()->joy_button(joy_id, JOY_DPAD_LEFT,
+ gamepad.dpad.left.isPressed);
+ OSIPhone::get_singleton()->joy_button(joy_id, JOY_DPAD_RIGHT,
+ gamepad.dpad.right.isPressed);
+ };
+ };
+#endif
+ };
- if ([value isKindOfClass:[NSString class]]) {
- NSString* str = (NSString*)value;
- String uval = String::utf8([str UTF8String]);
+ ///@TODO need to add support for controller.motion which gives us access to
+ /// the orientation of the device (if supported)
- GlobalConfig::get_singleton()->set("Info.plist/"+ukey, uval);
+ ///@TODO need to add support for controllerPausedHandler which should be a
+ /// toggle
+};
- } else if ([value isKindOfClass:[NSNumber class]]) {
+- (void)initGameControllers {
+ // get told when controllers connect, this will be called right away for
+ // already connected controllers
+ [[NSNotificationCenter defaultCenter]
+ addObserver:self
+ selector:@selector(controllerWasConnected:)
+ name:GCControllerDidConnectNotification
+ object:nil];
+
+ // get told when controllers disconnect
+ [[NSNotificationCenter defaultCenter]
+ addObserver:self
+ selector:@selector(controllerWasDisconnected:)
+ name:GCControllerDidDisconnectNotification
+ object:nil];
+};
- NSNumber* n = (NSNumber*)value;
- double dval = [n doubleValue];
+- (void)deinitGameControllers {
+ [[NSNotificationCenter defaultCenter]
+ removeObserver:self
+ name:GCControllerDidConnectNotification
+ object:nil];
+ [[NSNotificationCenter defaultCenter]
+ removeObserver:self
+ name:GCControllerDidDisconnectNotification
+ object:nil];
+
+ if (ios_joysticks != nil) {
+ [ios_joysticks dealloc];
+ ios_joysticks = nil;
+ };
+};
- GlobalConfig::get_singleton()->set("Info.plist/"+ukey, dval);
+static int frame_count = 0;
+- (void)drawView:(GLView *)view;
+{
+
+ switch (frame_count) {
+ case 0: {
+ int backingWidth;
+ int backingHeight;
+ glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES,
+ GL_RENDERBUFFER_WIDTH_OES, &backingWidth);
+ glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES,
+ GL_RENDERBUFFER_HEIGHT_OES, &backingHeight);
+
+ OS::VideoMode vm;
+ vm.fullscreen = true;
+ vm.width = backingWidth;
+ vm.height = backingHeight;
+ vm.resizable = false;
+ OS::get_singleton()->set_video_mode(vm);
+
+ if (!OS::get_singleton()) {
+ exit(0);
};
- // do stuff
- }
+ ++frame_count;
+
+ NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
+ NSUserDomainMask, YES);
+ NSString *documentsDirectory = [paths objectAtIndex:0];
+ // NSString *documentsDirectory = [[[NSFileManager defaultManager]
+ // URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask]
+ // lastObject];
+ OSIPhone::get_singleton()->set_data_dir(
+ String::utf8([documentsDirectory UTF8String]));
+
+ NSString *locale_code = [[NSLocale currentLocale] localeIdentifier];
+ OSIPhone::get_singleton()->set_locale(
+ String::utf8([locale_code UTF8String]));
+
+ NSString *uuid;
+ if ([[UIDevice currentDevice]
+ respondsToSelector:@selector(identifierForVendor)]) {
+ uuid = [UIDevice currentDevice].identifierForVendor.UUIDString;
+ } else {
+ // before iOS 6, so just generate an identifier and store it
+ uuid = [[NSUserDefaults standardUserDefaults]
+ objectForKey:@"identiferForVendor"];
+ if (!uuid) {
+ CFUUIDRef cfuuid = CFUUIDCreate(NULL);
+ uuid = (__bridge_transfer NSString *)CFUUIDCreateString(NULL, cfuuid);
+ CFRelease(cfuuid);
+ [[NSUserDefaults standardUserDefaults]
+ setObject:uuid
+ forKey:@"identifierForVendor"];
+ }
+ }
- } break;
-/*
- case 3: {
- ++frame_count;
- } break;
+ OSIPhone::get_singleton()->set_unique_id(String::utf8([uuid UTF8String]));
+
+ }; break;
+ /*
+ case 1: {
+ ++frame_count;
+ }; break;
*/
- case 2: {
-
- Main::start();
- ++frame_count;
-
- }; break; // no fallthrough
-
- default: {
- if (OSIPhone::get_singleton()) {
-// OSIPhone::get_singleton()->update_accelerometer(accel[0], accel[1], accel[2]);
- if (motionInitialised) {
- // Just using polling approach for now, we can set this up so it sends data to us in intervals, might be better.
- // See Apple reference pages for more details:
- // https://developer.apple.com/reference/coremotion/cmmotionmanager?language=objc
-
- // Apple splits our accelerometer date into a gravity and user movement component. We add them back together
- CMAcceleration gravity = motionManager.deviceMotion.gravity;
- CMAcceleration acceleration = motionManager.deviceMotion.userAcceleration;
-
- ///@TODO We don't seem to be getting data here, is my device broken or is this code incorrect?
- CMMagneticField magnetic = motionManager.deviceMotion.magneticField.field;
-
- ///@TODO we can access rotationRate as a CMRotationRate variable (processed date) or CMGyroData (raw data), have to see what works best
- CMRotationRate rotation = motionManager.deviceMotion.rotationRate;
-
- // Adjust for screen orientation.
- // [[UIDevice currentDevice] orientation] changes even if we've fixed our orientation which is not
- // a good thing when you're trying to get your user to move the screen in all directions and want consistent output
-
- ///@TODO Using [[UIApplication sharedApplication] statusBarOrientation] is a bit of a hack. Godot obviously knows the orientation so maybe we
- // can use that instead? (note that left and right seem swapped)
-
- switch ([[UIApplication sharedApplication] statusBarOrientation]) {
- case UIDeviceOrientationLandscapeLeft: {
- OSIPhone::get_singleton()->update_gravity(-gravity.y, gravity.x, gravity.z);
- OSIPhone::get_singleton()->update_accelerometer(-(acceleration.y + gravity.y), (acceleration.x + gravity.x), acceleration.z + gravity.z);
- OSIPhone::get_singleton()->update_magnetometer(-magnetic.y, magnetic.x, magnetic.z);
- OSIPhone::get_singleton()->update_gyroscope(-rotation.y, rotation.x, rotation.z);
- }; break;
- case UIDeviceOrientationLandscapeRight: {
- OSIPhone::get_singleton()->update_gravity(gravity.y, -gravity.x, gravity.z);
- OSIPhone::get_singleton()->update_accelerometer((acceleration.y + gravity.y), -(acceleration.x + gravity.x), acceleration.z + gravity.z);
- OSIPhone::get_singleton()->update_magnetometer(magnetic.y, -magnetic.x, magnetic.z);
- OSIPhone::get_singleton()->update_gyroscope(rotation.y, -rotation.x, rotation.z);
- }; break;
- case UIDeviceOrientationPortraitUpsideDown: {
- OSIPhone::get_singleton()->update_gravity(-gravity.x, gravity.y, gravity.z);
- OSIPhone::get_singleton()->update_accelerometer(-(acceleration.x + gravity.x), (acceleration.y + gravity.y), acceleration.z + gravity.z);
- OSIPhone::get_singleton()->update_magnetometer(-magnetic.x, magnetic.y, magnetic.z);
- OSIPhone::get_singleton()->update_gyroscope(-rotation.x, rotation.y, rotation.z);
- }; break;
- default: { // assume portrait
- OSIPhone::get_singleton()->update_gravity(gravity.x, gravity.y, gravity.z);
- OSIPhone::get_singleton()->update_accelerometer(acceleration.x + gravity.x, acceleration.y + gravity.y, acceleration.z + gravity.z);
- OSIPhone::get_singleton()->update_magnetometer(magnetic.x, magnetic.y, magnetic.z);
- OSIPhone::get_singleton()->update_gyroscope(rotation.x, rotation.y, rotation.z);
- }; break;
+ case 1: {
+
+ Main::setup2();
+ ++frame_count;
+
+ // this might be necessary before here
+ NSDictionary *dict = [[NSBundle mainBundle] infoDictionary];
+ for (NSString *key in dict) {
+ NSObject *value = [dict objectForKey:key];
+ String ukey = String::utf8([key UTF8String]);
+
+ // we need a NSObject to Variant conversor
+
+ if ([value isKindOfClass:[NSString class]]) {
+ NSString *str = (NSString *)value;
+ String uval = String::utf8([str UTF8String]);
+
+ ProjectSettings::get_singleton()->set("Info.plist/" + ukey, uval);
+
+ } else if ([value isKindOfClass:[NSNumber class]]) {
+
+ NSNumber *n = (NSNumber *)value;
+ double dval = [n doubleValue];
+
+ ProjectSettings::get_singleton()->set("Info.plist/" + ukey, dval);
};
+ // do stuff
}
- bool quit_request = OSIPhone::get_singleton()->iterate();
- };
-
- };
+ }; break;
+ /*
+ case 3: {
+ ++frame_count;
+ }; break;
+*/
+ case 2: {
+
+ Main::start();
+ ++frame_count;
+
+ }; break; // no fallthrough
+
+ default: {
+ if (OSIPhone::get_singleton()) {
+ // OSIPhone::get_singleton()->update_accelerometer(accel[0], accel[1],
+ // accel[2]);
+ if (motionInitialised) {
+ // Just using polling approach for now, we can set this up so it sends
+ // data to us in intervals, might be better. See Apple reference pages
+ // for more details:
+ // https://developer.apple.com/reference/coremotion/cmmotionmanager?language=objc
+
+ // Apple splits our accelerometer date into a gravity and user movement
+ // component. We add them back together
+ CMAcceleration gravity = motionManager.deviceMotion.gravity;
+ CMAcceleration acceleration =
+ motionManager.deviceMotion.userAcceleration;
+
+ ///@TODO We don't seem to be getting data here, is my device broken or
+ /// is this code incorrect?
+ CMMagneticField magnetic =
+ motionManager.deviceMotion.magneticField.field;
+
+ ///@TODO we can access rotationRate as a CMRotationRate variable
+ ///(processed date) or CMGyroData (raw data), have to see what works
+ /// best
+ CMRotationRate rotation = motionManager.deviceMotion.rotationRate;
+
+ // Adjust for screen orientation.
+ // [[UIDevice currentDevice] orientation] changes even if we've fixed
+ // our orientation which is not a good thing when you're trying to get
+ // your user to move the screen in all directions and want consistent
+ // output
+
+ ///@TODO Using [[UIApplication sharedApplication] statusBarOrientation]
+ /// is a bit of a hack. Godot obviously knows the orientation so maybe
+ /// we
+ // can use that instead? (note that left and right seem swapped)
+
+ switch ([[UIApplication sharedApplication] statusBarOrientation]) {
+ case UIDeviceOrientationLandscapeLeft: {
+ OSIPhone::get_singleton()->update_gravity(-gravity.y, gravity.x,
+ gravity.z);
+ OSIPhone::get_singleton()->update_accelerometer(
+ -(acceleration.y + gravity.y), (acceleration.x + gravity.x),
+ acceleration.z + gravity.z);
+ OSIPhone::get_singleton()->update_magnetometer(
+ -magnetic.y, magnetic.x, magnetic.z);
+ OSIPhone::get_singleton()->update_gyroscope(-rotation.y, rotation.x,
+ rotation.z);
+ }; break;
+ case UIDeviceOrientationLandscapeRight: {
+ OSIPhone::get_singleton()->update_gravity(gravity.y, -gravity.x,
+ gravity.z);
+ OSIPhone::get_singleton()->update_accelerometer(
+ (acceleration.y + gravity.y), -(acceleration.x + gravity.x),
+ acceleration.z + gravity.z);
+ OSIPhone::get_singleton()->update_magnetometer(
+ magnetic.y, -magnetic.x, magnetic.z);
+ OSIPhone::get_singleton()->update_gyroscope(rotation.y, -rotation.x,
+ rotation.z);
+ }; break;
+ case UIDeviceOrientationPortraitUpsideDown: {
+ OSIPhone::get_singleton()->update_gravity(-gravity.x, gravity.y,
+ gravity.z);
+ OSIPhone::get_singleton()->update_accelerometer(
+ -(acceleration.x + gravity.x), (acceleration.y + gravity.y),
+ acceleration.z + gravity.z);
+ OSIPhone::get_singleton()->update_magnetometer(
+ -magnetic.x, magnetic.y, magnetic.z);
+ OSIPhone::get_singleton()->update_gyroscope(-rotation.x, rotation.y,
+ rotation.z);
+ }; break;
+ default: { // assume portrait
+ OSIPhone::get_singleton()->update_gravity(gravity.x, gravity.y,
+ gravity.z);
+ OSIPhone::get_singleton()->update_accelerometer(
+ acceleration.x + gravity.x, acceleration.y + gravity.y,
+ acceleration.z + gravity.z);
+ OSIPhone::get_singleton()->update_magnetometer(magnetic.x, magnetic.y,
+ magnetic.z);
+ OSIPhone::get_singleton()->update_gyroscope(rotation.x, rotation.y,
+ rotation.z);
+ }; break;
+ };
+ }
+
+ bool quit_request = OSIPhone::get_singleton()->iterate();
+ };
+ }; break;
};
};
- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application {
printf("****************** did receive memory warning!\n");
- OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_OS_MEMORY_WARNING);
+ OS::get_singleton()->get_main_loop()->notification(
+ MainLoop::NOTIFICATION_OS_MEMORY_WARNING);
};
-- (void)applicationDidFinishLaunching:(UIApplication*)application {
+- (void)applicationDidFinishLaunching:(UIApplication *)application {
printf("**************** app delegate init\n");
CGRect rect = [[UIScreen mainScreen] bounds];
[application setStatusBarHidden:YES withAnimation:UIStatusBarAnimationNone];
// disable idle timer
- //application.idleTimerDisabled = YES;
+ // application.idleTimerDisabled = YES;
- //Create a full-screen window
+ // Create a full-screen window
window = [[UIWindow alloc] initWithFrame:rect];
- //window.autoresizesSubviews = YES;
- //[window setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleWidth];
+ // window.autoresizesSubviews = YES;
+ //[window setAutoresizingMask:UIViewAutoresizingFlexibleWidth |
+ // UIViewAutoresizingFlexibleWidth];
- //Create the OpenGL ES view and add it to the window
+ // Create the OpenGL ES view and add it to the window
GLView *glView = [[GLView alloc] initWithFrame:rect];
printf("glview is %p\n", glView);
//[window addSubview:glView];
glView.delegate = self;
- //glView.autoresizesSubviews = YES;
- //[glView setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleWidth];
+ // glView.autoresizesSubviews = YES;
+ //[glView setAutoresizingMask:UIViewAutoresizingFlexibleWidth |
+ // UIViewAutoresizingFlexibleWidth];
int backingWidth;
int backingHeight;
- glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &backingWidth);
- glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &backingHeight);
-
- iphone_main(backingWidth, backingHeight, gargc, gargv);
+ glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES,
+ GL_RENDERBUFFER_WIDTH_OES, &backingWidth);
+ glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES,
+ GL_RENDERBUFFER_HEIGHT_OES, &backingHeight);
+
+ int err = iphone_main(backingWidth, backingHeight, gargc, gargv);
+ 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;
+ };
view_controller = [[ViewController alloc] init];
view_controller.view = glView;
window.rootViewController = view_controller;
- _set_keep_screen_on(bool(GLOBAL_DEF("display/keep_screen_on",true)) ? YES : NO);
- glView.useCADisplayLink = bool(GLOBAL_DEF("display.iOS/use_cadisplaylink",true)) ? YES : NO;
+ _set_keep_screen_on(bool(GLOBAL_DEF("display/window/keep_screen_on", true)) ? YES : NO);
+ glView.useCADisplayLink =
+ bool(GLOBAL_DEF("display.iOS/use_cadisplaylink", true)) ? YES : NO;
printf("cadisaplylink: %d", glView.useCADisplayLink);
glView.animationInterval = 1.0 / kRenderingFrequency;
[glView startAnimation];
- //Show the window
+ // Show the window
[window makeKeyAndVisible];
- //Configure and start accelerometer
+ // Configure and start accelerometer
if (!motionInitialised) {
motionManager = [[CMMotionManager alloc] init];
if (motionManager.deviceMotionAvailable) {
- motionManager.deviceMotionUpdateInterval = 1.0/70.0;
- [motionManager startDeviceMotionUpdatesUsingReferenceFrame:CMAttitudeReferenceFrameXMagneticNorthZVertical];
+ motionManager.deviceMotionUpdateInterval = 1.0 / 70.0;
+ [motionManager startDeviceMotionUpdatesUsingReferenceFrame:
+ CMAttitudeReferenceFrameXMagneticNorthZVertical];
motionInitialised = YES;
};
};
- //OSIPhone::screen_width = rect.size.width - rect.origin.x;
- //OSIPhone::screen_height = rect.size.height - rect.origin.y;
+ [self initGameControllers];
+
+ // OSIPhone::screen_width = rect.size.width - rect.origin.x;
+ // OSIPhone::screen_height = rect.size.height - rect.origin.y;
mainViewController = view_controller;
#ifdef MODULE_GAME_ANALYTICS_ENABLED
- printf("********************* didFinishLaunchingWithOptions\n");
- if(!GlobalConfig::get_singleton()->has("mobileapptracker/advertiser_id"))
- {
- return;
- }
- if(!GlobalConfig::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]];
+ printf("********************* didFinishLaunchingWithOptions\n");
+ if (!ProjectSettings::get_singleton()->has("mobileapptracker/advertiser_id")) {
+ return;
+ }
+ if (!ProjectSettings::get_singleton()->has("mobileapptracker/conversion_key")) {
+ return;
+ }
-#endif
+ 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
};
-- (void)applicationWillTerminate:(UIApplication*)application {
+- (void)applicationWillTerminate:(UIApplication *)application {
printf("********************* will terminate\n");
+ [self deinitGameControllers];
+
if (motionInitialised) {
///@TODO is this the right place to clean this up?
[motionManager stopDeviceMotionUpdates];
[motionManager release];
motionManager = nil;
- motionInitialised = NO;
+ motionInitialised = NO;
};
iphone_finish();
};
-- (void)applicationDidEnterBackground:(UIApplication *)application
-{
+- (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())
- OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_WM_FOCUS_OUT);
+ OS::get_singleton()->get_main_loop()->notification(
+ MainLoop::NOTIFICATION_WM_FOCUS_OUT);
+
[view_controller.view stopAnimation];
if (OS::get_singleton()->native_video_is_playing()) {
OSIPhone::get_singleton()->native_video_focus_out();
};
}
-- (void)applicationWillEnterForeground:(UIApplication *)application
-{
+- (void)applicationWillEnterForeground:(UIApplication *)application {
printf("********************* did enter foreground\n");
- //OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_WM_FOCUS_IN);
+ // OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_WM_FOCUS_IN);
[view_controller.view startAnimation];
}
-- (void) applicationWillResignActive:(UIApplication *)application
-{
+- (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
+ // 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
-{
+- (void)applicationDidBecomeActive:(UIApplication *)application {
printf("********************* did become active\n");
#ifdef MODULE_GAME_ANALYTICS_ENABLED
- printf("********************* mobile app tracker found\n");
+ 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);
- [view_controller.view startAnimation]; // FIXME: resume seems to be recommended elsewhere
+ OS::get_singleton()->get_main_loop()->notification(
+ MainLoop::NOTIFICATION_WM_FOCUS_IN);
+
+ [view_controller.view
+ startAnimation]; // FIXME: resume seems to be recommended elsewhere
if (OSIPhone::get_singleton()->native_video_is_playing()) {
OSIPhone::get_singleton()->native_video_unpause();
};
+
+ // Fixed audio can not resume if it is interrupted cause by an incoming phone call
+ if (AudioDriverIphone::get_singleton() != NULL)
+ AudioDriverIphone::get_singleton()->start();
}
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url {
@@ -406,16 +749,19 @@ static int frame_count = 0;
}
// For 4.2+ support
-- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
+- (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];
+ return
+ [[FBSDKApplicationDelegate sharedInstance] application:application
+ openURL:url
+ sourceApplication:sourceApplication
+ annotation:annotation];
#endif
-
#ifdef MODULE_FACEBOOKSCORER_IOS_ENABLED
return [[[FacebookScorer sharedInstance] facebook] handleOpenURL:url];
#else
@@ -423,21 +769,25 @@ static int frame_count = 0;
#endif
}
-- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
+- (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];
+ // 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 {
+- (void)application:(UIApplication *)application
+ didReceiveRemoteNotification:(NSDictionary *)userInfo {
#ifdef MODULE_PARSE_ENABLED
[PFPush handlePush:userInfo];
- NSDictionary *aps = [userInfo objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
+ NSDictionary *aps =
+ [userInfo objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSLog(@"Push Notification Payload (app active) %@", aps);
@@ -449,8 +799,7 @@ static int frame_count = 0;
#endif
}
-- (void)dealloc
-{
+- (void)dealloc {
[window release];
[super dealloc];
}
diff --git a/platform/iphone/audio_driver_iphone.cpp b/platform/iphone/audio_driver_iphone.cpp
index eff91fa40f..57b6388016 100644
--- a/platform/iphone/audio_driver_iphone.cpp
+++ b/platform/iphone/audio_driver_iphone.cpp
@@ -6,6 +6,7 @@
/* http://www.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 */
@@ -147,6 +148,11 @@ OSStatus AudioDriverIphone::output_callback(void *inRefCon,
void AudioDriverIphone::start() {
active = true;
+ // Resume audio
+ // iOS audio-thread stoped if it is interrupted cause by an incoming phone call
+ // Use AudioOutputUnitStart to re-create audio-thread
+ OSStatus result = AudioOutputUnitStart(audio_unit);
+ ERR_FAIL_COND(result != noErr);
};
int AudioDriverIphone::get_mix_rate() const {
diff --git a/platform/iphone/audio_driver_iphone.h b/platform/iphone/audio_driver_iphone.h
index 8a0d92e070..c620e9068c 100644
--- a/platform/iphone/audio_driver_iphone.h
+++ b/platform/iphone/audio_driver_iphone.h
@@ -6,6 +6,7 @@
/* http://www.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 */
diff --git a/platform/iphone/detect.py b/platform/iphone/detect.py
index fa6082a5a7..1d802ff288 100644
--- a/platform/iphone/detect.py
+++ b/platform/iphone/detect.py
@@ -1,4 +1,5 @@
import os
+import string
import sys
@@ -12,8 +13,6 @@ def get_name():
def can_build():
- import sys
- import os
if sys.platform == 'darwin' or os.environ.has_key("OSXCROSS_IOS"):
return True
@@ -23,14 +22,13 @@ def can_build():
def get_opts():
return [
- ('IPHONEPLATFORM', 'name of the iphone platform', 'iPhoneOS'),
- ('IPHONEPATH', 'the path to iphone toolchain', '/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain'),
- ('IPHONESDK', 'path to the iphone SDK', '/Applications/Xcode.app/Contents/Developer/Platforms/${IPHONEPLATFORM}.platform/Developer/SDKs/${IPHONEPLATFORM}.sdk/'),
+ ('IPHONEPLATFORM', 'Name of the iPhone platform', 'iPhoneOS'),
+ ('IPHONEPATH', 'Path to iPhone toolchain', '/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain'),
+ ('IPHONESDK', 'Path to the iPhone SDK', '/Applications/Xcode.app/Contents/Developer/Platforms/${IPHONEPLATFORM}.platform/Developer/SDKs/${IPHONEPLATFORM}.sdk/'),
('game_center', 'Support for game center', 'yes'),
('store_kit', 'Support for in-app store', 'yes'),
('icloud', 'Support for iCloud', 'yes'),
- ('ios_gles22_override', 'Force GLES2.0 on iOS', 'yes'),
- ('ios_exceptions', 'Use exceptions when compiling on playbook', 'yes'),
+ ('ios_exceptions', 'Enable exceptions', 'no'),
('ios_triple', 'Triple for ios toolchain', ''),
('ios_sim', 'Build simulator binary', 'no'),
]
@@ -45,7 +43,32 @@ def get_flags():
def configure(env):
- env.Append(CPPPATH=['#platform/iphone'])
+ ## Build type
+
+ if (env["target"].startswith("release")):
+ env.Append(CPPFLAGS=['-DNDEBUG', '-DNS_BLOCK_ASSERTIONS=1'])
+ env.Append(CPPFLAGS=['-O2', '-flto', '-ftree-vectorize', '-fomit-frame-pointer', '-ffast-math', '-funsafe-math-optimizations'])
+ env.Append(LINKFLAGS=['-O2', '-flto'])
+
+ if env["target"] == "release_debug":
+ env.Append(CPPFLAGS=['-DDEBUG_ENABLED'])
+
+ elif (env["target"] == "debug"):
+ env.Append(CPPFLAGS=['-D_DEBUG', '-DDEBUG=1', '-gdwarf-2', '-O0', '-DDEBUG_ENABLED', '-DDEBUG_MEMORY_ENABLED'])
+
+ ## Architecture
+
+ if (env["ios_sim"] == "yes" or env["arch"] == "x86"): # i386, simulator
+ env["arch"] = "x86"
+ env["bits"] = "32"
+ elif (env["arch"] == "arm" or env["arch"] == "arm32" or env["arch"] == "armv7" or env["bits"] == "32"): # arm
+ env["arch"] = "arm"
+ env["bits"] = "32"
+ else: # armv64
+ env["arch"] = "arm64"
+ env["bits"] = "64"
+
+ ## Compiler configuration
env['ENV']['PATH'] = env['IPHONEPATH'] + "/Developer/usr/bin/:" + env['ENV']['PATH']
@@ -53,85 +76,61 @@ def configure(env):
env['CXX'] = '$IPHONEPATH/usr/bin/${ios_triple}clang++'
env['AR'] = '$IPHONEPATH/usr/bin/${ios_triple}ar'
env['RANLIB'] = '$IPHONEPATH/usr/bin/${ios_triple}ranlib'
+ env['S_compiler'] = '$IPHONEPATH/Developer/usr/bin/gcc'
- import string
- if (env["ios_sim"] == "yes" or env["arch"] == "x86"): # i386, simulator
- env["arch"] = "x86"
- env["bits"] = "32"
- env['CCFLAGS'] = string.split('-arch i386 -fobjc-abi-version=2 -fobjc-legacy-dispatch -fmessage-length=0 -fpascal-strings -fasm-blocks -Wall -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\\\"')
- elif (env["arch"] == "arm64"): # arm64
- env["bits"] = "64"
- env['CCFLAGS'] = string.split('-fno-objc-arc -arch arm64 -fmessage-length=0 -fno-strict-aliasing -fdiagnostics-print-source-range-info -fdiagnostics-show-category=id -fdiagnostics-parseable-fixits -Wno-trigraphs -fpascal-strings -Wmissing-prototypes -Wreturn-type -Wparentheses -Wswitch -Wno-unused-parameter -Wunused-variable -Wunused-value -Wno-shorten-64-to-32 -fvisibility=hidden -Wno-sign-conversion -MMD -MT dependencies -miphoneos-version-min=7.0 -isysroot $IPHONESDK')
+ ## Compile flags
+
+ if (env["arch"] == "x86"):
+ env['IPHONEPLATFORM'] = 'iPhoneSimulator'
+ env['ENV']['MACOSX_DEPLOYMENT_TARGET'] = '10.6'
+ env.Append(CCFLAGS=string.split('-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\\\"'))
+ elif (env["arch"] == "arm"):
+ env.Append(CCFLAGS=string.split('-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'))
+ elif (env["arch"] == "arm64"):
+ env.Append(CCFLAGS=string.split('-fno-objc-arc -arch arm64 -fmessage-length=0 -fno-strict-aliasing -fdiagnostics-print-source-range-info -fdiagnostics-show-category=id -fdiagnostics-parseable-fixits -fpascal-strings -fblocks -fvisibility=hidden -MMD -MT dependencies -miphoneos-version-min=9.0 -isysroot $IPHONESDK'))
env.Append(CPPFLAGS=['-DNEED_LONG_INT'])
env.Append(CPPFLAGS=['-DLIBYUV_DISABLE_NEON'])
- else: # armv7
- env["arch"] = "arm"
- env["bits"] = "32"
- env['CCFLAGS'] = string.split('-fno-objc-arc -arch armv7 -fmessage-length=0 -fno-strict-aliasing -fdiagnostics-print-source-range-info -fdiagnostics-show-category=id -fdiagnostics-parseable-fixits -Wno-trigraphs -fpascal-strings -Wmissing-prototypes -Wreturn-type -Wparentheses -Wswitch -Wno-unused-parameter -Wunused-variable -Wunused-value -Wno-shorten-64-to-32 -isysroot $IPHONESDK -fvisibility=hidden -Wno-sign-conversion -mthumb "-DIBOutlet=__attribute__((iboutlet))" "-DIBOutletCollection(ClassName)=__attribute__((iboutletcollection(ClassName)))" "-DIBAction=void)__attribute__((ibaction)" -miphoneos-version-min=7.0 -MMD -MT dependencies -isysroot $IPHONESDK')
+
+ if env['ios_exceptions'] == 'yes':
+ env.Append(CPPFLAGS=['-fexceptions'])
+ else:
+ env.Append(CPPFLAGS=['-fno-exceptions'])
+
+ ## Link flags
if (env["arch"] == "x86"):
- env['IPHONEPLATFORM'] = 'iPhoneSimulator'
env.Append(LINKFLAGS=['-arch', 'i386', '-mios-simulator-version-min=4.3',
'-isysroot', '$IPHONESDK',
- #'-mmacosx-version-min=10.6',
'-Xlinker',
'-objc_abi_version',
'-Xlinker', '2',
- '-framework', 'AudioToolbox',
- '-framework', 'AVFoundation',
- '-framework', 'CoreAudio',
- '-framework', 'CoreGraphics',
- '-framework', 'CoreMedia',
- '-framework', 'CoreMotion',
- '-framework', 'Foundation',
- '-framework', 'Security',
- '-framework', 'UIKit',
- '-framework', 'MediaPlayer',
- '-framework', 'OpenGLES',
- '-framework', 'QuartzCore',
- '-framework', 'SystemConfiguration',
'-F$IPHONESDK',
])
- elif (env["arch"] == "arm64"):
- env.Append(LINKFLAGS=['-arch', 'arm64', '-Wl,-dead_strip', '-miphoneos-version-min=7.0',
- '-isysroot', '$IPHONESDK',
- #'-stdlib=libc++',
- '-framework', 'Foundation',
- '-framework', 'UIKit',
- '-framework', 'CoreGraphics',
- '-framework', 'OpenGLES',
- '-framework', 'QuartzCore',
- '-framework', 'CoreAudio',
- '-framework', 'AudioToolbox',
- '-framework', 'SystemConfiguration',
- '-framework', 'Security',
- #'-framework', 'AdSupport',
- '-framework', 'MediaPlayer',
- '-framework', 'AVFoundation',
- '-framework', 'CoreMedia',
- '-framework', 'CoreMotion',
- ])
- else:
- env.Append(LINKFLAGS=['-arch', 'armv7', '-Wl,-dead_strip', '-miphoneos-version-min=7.0',
- '-isysroot', '$IPHONESDK',
- '-framework', 'Foundation',
- '-framework', 'UIKit',
- '-framework', 'CoreGraphics',
- '-framework', 'OpenGLES',
- '-framework', 'QuartzCore',
- '-framework', 'CoreAudio',
- '-framework', 'AudioToolbox',
- '-framework', 'SystemConfiguration',
- '-framework', 'Security',
- #'-framework', 'AdSupport',
- '-framework', 'MediaPlayer',
- '-framework', 'AVFoundation',
- '-framework', 'CoreMedia',
- '-framework', 'CoreMotion',
- ])
-
+ elif (env["arch"] == "arm"):
+ env.Append(LINKFLAGS=['-arch', 'armv7', '-Wl,-dead_strip', '-miphoneos-version-min=9.0'])
+ if (env["arch"] == "arm64"):
+ env.Append(LINKFLAGS=['-arch', 'arm64', '-Wl,-dead_strip', '-miphoneos-version-min=9.0'])
+
+ env.Append(LINKFLAGS=['-isysroot', '$IPHONESDK',
+ '-framework', 'AudioToolbox',
+ '-framework', 'AVFoundation',
+ '-framework', 'CoreAudio',
+ '-framework', 'CoreGraphics',
+ '-framework', 'CoreMedia',
+ '-framework', 'CoreMotion',
+ '-framework', 'Foundation',
+ '-framework', 'GameController',
+ '-framework', 'MediaPlayer',
+ '-framework', 'OpenGLES',
+ '-framework', 'QuartzCore',
+ '-framework', 'Security',
+ '-framework', 'SystemConfiguration',
+ '-framework', 'UIKit',
+ ])
+
+ # Feature options
if env['game_center'] == 'yes':
- env.Append(CPPFLAGS=['-fblocks', '-DGAME_CENTER_ENABLED'])
+ env.Append(CPPFLAGS=['-DGAME_CENTER_ENABLED'])
env.Append(LINKFLAGS=['-framework', 'GameKit'])
if env['store_kit'] == 'yes':
@@ -141,51 +140,20 @@ def configure(env):
if env['icloud'] == 'yes':
env.Append(CPPFLAGS=['-DICLOUD_ENABLED'])
- env.Append(CPPPATH=['$IPHONESDK/usr/include', '$IPHONESDK/System/Library/Frameworks/OpenGLES.framework/Headers', '$IPHONESDK/System/Library/Frameworks/AudioUnit.framework/Headers'])
-
- if (env["target"] == "release"):
-
- env.Append(CCFLAGS=['-O3', '-DNS_BLOCK_ASSERTIONS=1', '-Wall', '-gdwarf-2']) # removed -ffast-math
- env.Append(LINKFLAGS=['-O3'])
-
- elif env["target"] == "release_debug":
- env.Append(CCFLAGS=['-Os', '-DNS_BLOCK_ASSERTIONS=1', '-Wall', '-DDEBUG_ENABLED'])
- env.Append(LINKFLAGS=['-Os'])
- env.Append(CPPFLAGS=['-DDEBUG_MEMORY_ENABLED'])
-
- elif (env["target"] == "debug"):
-
- env.Append(CCFLAGS=['-D_DEBUG', '-DDEBUG=1', '-gdwarf-2', '-Wall', '-O0', '-DDEBUG_ENABLED'])
- env.Append(CPPFLAGS=['-DDEBUG_MEMORY_ENABLED'])
+ env.Append(CPPPATH=['$IPHONESDK/usr/include',
+ '$IPHONESDK/System/Library/Frameworks/OpenGLES.framework/Headers',
+ '$IPHONESDK/System/Library/Frameworks/AudioUnit.framework/Headers',
+ ])
- elif (env["target"] == "profile"):
-
- env.Append(CCFLAGS=['-g', '-pg', '-Os'])
- env.Append(LINKFLAGS=['-pg'])
-
- if (env["ios_sim"] == "yes"): # TODO: Check if needed?
- env['ENV']['MACOSX_DEPLOYMENT_TARGET'] = '10.6'
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'])
# TODO: Move that to opus module's config
if("module_opus_enabled" in env and env["module_opus_enabled"] != "no"):
env.opus_fixed_point = "yes"
- if env["arch"] == "x86":
- pass
- elif(env["arch"] == "arm64"):
- env.Append(CFLAGS=["-DOPUS_ARM64_OPT"])
- else:
+ if (env["arch"] == "arm"):
env.Append(CFLAGS=["-DOPUS_ARM_OPT"])
-
- if env['ios_exceptions'] == 'yes':
- env.Append(CPPFLAGS=['-fexceptions'])
- else:
- env.Append(CPPFLAGS=['-fno-exceptions'])
- # env['neon_enabled']=True
- env['S_compiler'] = '$IPHONEPATH/Developer/usr/bin/gcc'
-
- import methods
- env.Append(BUILDERS={'GLSL120': env.Builder(action=methods.build_legacygl_headers, suffix='glsl.h', src_suffix='.glsl')})
- env.Append(BUILDERS={'GLSL': env.Builder(action=methods.build_glsl_headers, suffix='glsl.h', src_suffix='.glsl')})
- env.Append(BUILDERS={'GLSL120GLES': env.Builder(action=methods.build_gles2_headers, suffix='glsl.h', src_suffix='.glsl')})
+ elif (env["arch"] == "arm64"):
+ env.Append(CFLAGS=["-DOPUS_ARM64_OPT"])
diff --git a/platform/iphone/export/export.cpp b/platform/iphone/export/export.cpp
new file mode 100644
index 0000000000..6ae2a0692d
--- /dev/null
+++ b/platform/iphone/export/export.cpp
@@ -0,0 +1,366 @@
+/*************************************************************************/
+/* export.cpp */
+/*************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* http://www.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 "export.h"
+#include "editor/editor_export.h"
+#include "editor/editor_node.h"
+#include "editor/editor_settings.h"
+#include "io/marshalls.h"
+#include "io/resource_saver.h"
+#include "io/zip_io.h"
+#include "os/file_access.h"
+#include "os/os.h"
+#include "platform/osx/logo.gen.h"
+#include "project_settings.h"
+#include "string.h"
+#include "version.h"
+
+#include <sys/stat.h>
+
+class EditorExportPlatformIOS : public EditorExportPlatform {
+
+ GDCLASS(EditorExportPlatformIOS, EditorExportPlatform);
+
+ int version_code;
+
+ Ref<ImageTexture> logo;
+
+ void _fix_config_file(const Ref<EditorExportPreset> &p_preset, Vector<uint8_t> &pfile, const String &p_name, const String &p_binary);
+
+protected:
+ virtual void get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features);
+ virtual void get_export_options(List<ExportOption> *r_options);
+
+public:
+ virtual String get_name() const { return "iOS"; }
+ virtual String get_os_name() const { return "iOS"; }
+ virtual Ref<Texture> get_logo() const { return logo; }
+
+ virtual String get_binary_extension() const { return "xcodeproj"; }
+ 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;
+
+ virtual void get_platform_features(List<String> *r_features) {
+
+ r_features->push_back("mobile");
+ r_features->push_back("iOS");
+ }
+
+ EditorExportPlatformIOS();
+ ~EditorExportPlatformIOS();
+};
+
+void EditorExportPlatformIOS::get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) {
+
+ if (p_preset->get("texture_format/s3tc")) {
+ r_features->push_back("s3tc");
+ }
+ if (p_preset->get("texture_format/etc")) {
+ r_features->push_back("etc");
+ }
+ if (p_preset->get("texture_format/etc2")) {
+ r_features->push_back("etc2");
+ }
+}
+
+void EditorExportPlatformIOS::get_export_options(List<ExportOption> *r_options) {
+
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_package/debug", PROPERTY_HINT_GLOBAL_FILE, "zip"), ""));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_package/release", PROPERTY_HINT_GLOBAL_FILE, "zip"), ""));
+
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/name"), ""));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/info"), "Made with Godot Engine"));
+ // r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/icon", PROPERTY_HINT_FILE, "png"), ""));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/identifier"), "org.godotengine.iosgame"));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/signature"), "godotiosgame"));
+ 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::BOOL, "texture_format/s3tc"), false));
+ 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 */
+}
+
+void EditorExportPlatformIOS::_fix_config_file(const Ref<EditorExportPreset> &p_preset, Vector<uint8_t> &pfile, const String &p_name, const String &p_binary) {
+
+ String str;
+ String strnew;
+ str.parse_utf8((const char *)pfile.ptr(), pfile.size());
+ 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";
+ } else if (lines[i].find("$name") != -1) {
+ strnew += lines[i].replace("$name", p_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) {
+ strnew += lines[i].replace("$identifier", p_preset->get("application/identifier")) + "\n";
+ } else if (lines[i].find("$short_version") != -1) {
+ strnew += lines[i].replace("$short_version", p_preset->get("application/short_version")) + "\n";
+ } else if (lines[i].find("$version") != -1) {
+ strnew += lines[i].replace("$version", p_preset->get("application/version")) + "\n";
+ } else if (lines[i].find("$signature") != -1) {
+ strnew += lines[i].replace("$signature", p_preset->get("application/signature")) + "\n";
+ } else if (lines[i].find("$copyright") != -1) {
+ strnew += lines[i].replace("$copyright", p_preset->get("application/copyright")) + "\n";
+ } else {
+ strnew += lines[i] + "\n";
+ }
+ }
+
+ // !BAS! I'm assuming the 9 in the original code was a typo. I've added -1 or else it seems to also be adding our terminating zero...
+ // should apply the same fix in our OSX export.
+ CharString cs = strnew.utf8();
+ pfile.resize(cs.size() - 1);
+ for (int i = 0; i < cs.size() - 1; i++) {
+ pfile[i] = cs[i];
+ }
+}
+
+Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags) {
+ String src_pkg_name;
+ String dest_dir = p_path.get_base_dir() + "/";
+ String binary_name = p_path.get_file().get_basename();
+
+ EditorProgress ep("export", "Exporting for iOS", 3);
+
+ if (p_debug)
+ src_pkg_name = p_preset->get("custom_package/debug");
+ else
+ src_pkg_name = p_preset->get("custom_package/release");
+
+ if (src_pkg_name == "") {
+ String err;
+ src_pkg_name = find_export_template("iphone.zip", &err);
+ if (src_pkg_name == "") {
+ EditorNode::add_io_error(err);
+ return ERR_FILE_NOT_FOUND;
+ }
+ }
+
+ FileAccess *src_f = NULL;
+ zlib_filefunc_def io = zipio_create_io_from_file(&src_f);
+
+ ep.step("Creating app", 0);
+
+ unzFile src_pkg_zip = unzOpen2(src_pkg_name.utf8().get_data(), &io);
+ if (!src_pkg_zip) {
+
+ EditorNode::add_io_error("Could not find template app to export:\n" + src_pkg_name);
+ return ERR_FILE_NOT_FOUND;
+ }
+
+ ERR_FAIL_COND_V(!src_pkg_zip, ERR_CANT_OPEN);
+ int ret = unzGoToFirstFile(src_pkg_zip);
+
+ 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");
+
+ print_line("binary: " + binary_to_use);
+ String pkg_name;
+ if (p_preset->get("application/name") != "")
+ pkg_name = p_preset->get("application/name"); // app_name
+ else if (String(ProjectSettings::get_singleton()->get("application/config/name")) != "")
+ pkg_name = String(ProjectSettings::get_singleton()->get("application/config/name"));
+ 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;
+ int total_size = 0;
+
+ while (ret == UNZ_OK) {
+ bool is_execute = false;
+
+ //get filename
+ unz_file_info info;
+ char fname[16384];
+ ret = unzGetCurrentFileInfo(src_pkg_zip, &info, fname, 16384, NULL, 0, NULL, 0);
+
+ String file = fname;
+
+ print_line("READ: " + file);
+ Vector<uint8_t> data;
+ data.resize(info.uncompressed_size);
+
+ //read
+ unzOpenCurrentFile(src_pkg_zip);
+ unzReadCurrentFile(src_pkg_zip, data.ptr(), data.size());
+ unzCloseCurrentFile(src_pkg_zip);
+
+ //write
+
+ file = file.replace_first("iphone/", "");
+
+ if (file == "godot_ios.xcodeproj/project.pbxproj") {
+ print_line("parse pbxproj");
+ _fix_config_file(p_preset, data, pkg_name, binary_name);
+ } else if (file == "godot_ios/godot_ios-Info.plist") {
+ print_line("parse plist");
+ _fix_config_file(p_preset, data, pkg_name, binary_name);
+ } else if (file.begins_with("godot.iphone")) {
+ if (file != binary_to_use) {
+ ret = unzGoToNextFile(src_pkg_zip);
+ continue; //ignore!
+ }
+ found_binary = true;
+ is_execute = true;
+ file = "godot_ios.iphone";
+ }
+
+ ///@TODO need to parse logo files
+
+ if (data.size() > 0) {
+ file = file.replace("godot_ios", binary_name);
+
+ print_line("ADDING: " + file + " size: " + itos(data.size()));
+ total_size += data.size();
+
+ /* write it into our folder structure */
+ file = dest_dir + file;
+
+ /* make sure this folder exists */
+ String dir_name = file.get_base_dir();
+ if (!tmp_app_path->dir_exists(dir_name)) {
+ print_line("Creating " + dir_name);
+ Error dir_err = tmp_app_path->make_dir_recursive(dir_name);
+ if (dir_err) {
+ ERR_PRINTS("Can't create '" + dir_name + "'.");
+ unzClose(src_pkg_zip);
+ return ERR_CANT_CREATE;
+ }
+ }
+
+ /* write the file */
+ FileAccess *f = FileAccess::open(file, FileAccess::WRITE);
+ if (!f) {
+ ERR_PRINTS("Can't write '" + file + "'.");
+ unzClose(src_pkg_zip);
+ return ERR_CANT_CREATE;
+ };
+ f->store_buffer(data.ptr(), data.size());
+ f->close();
+ memdelete(f);
+
+#ifdef OSX_ENABLED
+ if (is_execute) {
+ // we need execute rights on this file
+ chmod(file.utf8().get_data(), 0755);
+ }
+#endif
+ }
+
+ ret = unzGoToNextFile(src_pkg_zip);
+ }
+
+ /* 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.");
+ unzClose(src_pkg_zip);
+ return ERR_FILE_NOT_FOUND;
+ }
+
+ ep.step("Making PKG", 1);
+
+ String pack_path = dest_dir + binary_name + ".pck";
+ Error err = save_pack(p_preset, pack_path);
+
+ if (err) {
+ return err;
+ }
+
+#ifdef OSX_ENABLED
+ /* and open up xcode with our new project.... */
+ List<String> args;
+ args.push_back(p_path);
+ err = OS::get_singleton()->execute("/usr/bin/open", args, false);
+ ERR_FAIL_COND_V(err, err);
+
+#endif
+
+ return OK;
+}
+
+bool EditorExportPlatformIOS::can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const {
+
+ bool valid = true;
+ String err;
+
+ if (!exists_export_template("iphone.zip", &err)) {
+ valid = false;
+ }
+
+ if (p_preset->get("custom_package/debug") != "" && !FileAccess::exists(p_preset->get("custom_package/debug"))) {
+ valid = false;
+ err += "Custom debug package not found.\n";
+ }
+
+ if (p_preset->get("custom_package/release") != "" && !FileAccess::exists(p_preset->get("custom_package/release"))) {
+ valid = false;
+ err += "Custom release package not found.\n";
+ }
+
+ if (!err.empty())
+ r_error = err;
+
+ 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));
+ logo.instance();
+ logo->create_from_image(img);
+}
+
+EditorExportPlatformIOS::~EditorExportPlatformIOS() {
+}
+
+void register_iphone_exporter() {
+
+ Ref<EditorExportPlatformIOS> platform;
+ platform.instance();
+
+ EditorExport::get_singleton()->add_export_platform(platform);
+}
diff --git a/platform/bb10/export/export.h b/platform/iphone/export/export.h
index d8407c4152..6e9324aed7 100644
--- a/platform/bb10/export/export.h
+++ b/platform/iphone/export/export.h
@@ -6,6 +6,7 @@
/* http://www.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 */
@@ -26,4 +27,4 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-void register_bb10_exporter();
+void register_iphone_exporter();
diff --git a/platform/iphone/game_center.h b/platform/iphone/game_center.h
index a732a97a4c..cda6f78a1f 100644
--- a/platform/iphone/game_center.h
+++ b/platform/iphone/game_center.h
@@ -6,6 +6,7 @@
/* http://www.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 */
diff --git a/platform/iphone/game_center.mm b/platform/iphone/game_center.mm
index 4cfa64ae4b..f9bc70b7c4 100644
--- a/platform/iphone/game_center.mm
+++ b/platform/iphone/game_center.mm
@@ -6,6 +6,7 @@
/* http://www.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 */
@@ -45,24 +46,23 @@ extern "C" {
#import "app_delegate.h"
};
-GameCenter* GameCenter::instance = NULL;
+GameCenter *GameCenter::instance = NULL;
void GameCenter::_bind_methods() {
- ClassDB::bind_method(D_METHOD("connect"),&GameCenter::connect);
- ClassDB::bind_method(D_METHOD("is_connected"),&GameCenter::is_connected);
-
- ClassDB::bind_method(D_METHOD("post_score"),&GameCenter::post_score);
- ClassDB::bind_method(D_METHOD("award_achievement"),&GameCenter::award_achievement);
- ClassDB::bind_method(D_METHOD("reset_achievements"),&GameCenter::reset_achievements);
- ClassDB::bind_method(D_METHOD("request_achievements"),&GameCenter::request_achievements);
- ClassDB::bind_method(D_METHOD("request_achievement_descriptions"),&GameCenter::request_achievement_descriptions);
- ClassDB::bind_method(D_METHOD("show_game_center"),&GameCenter::show_game_center);
-
- ClassDB::bind_method(D_METHOD("get_pending_event_count"),&GameCenter::get_pending_event_count);
- ClassDB::bind_method(D_METHOD("pop_pending_event"),&GameCenter::pop_pending_event);
+ ClassDB::bind_method(D_METHOD("connect"), &GameCenter::connect);
+ ClassDB::bind_method(D_METHOD("is_connected"), &GameCenter::is_connected);
+
+ ClassDB::bind_method(D_METHOD("post_score"), &GameCenter::post_score);
+ ClassDB::bind_method(D_METHOD("award_achievement"), &GameCenter::award_achievement);
+ ClassDB::bind_method(D_METHOD("reset_achievements"), &GameCenter::reset_achievements);
+ ClassDB::bind_method(D_METHOD("request_achievements"), &GameCenter::request_achievements);
+ ClassDB::bind_method(D_METHOD("request_achievement_descriptions"), &GameCenter::request_achievement_descriptions);
+ ClassDB::bind_method(D_METHOD("show_game_center"), &GameCenter::show_game_center);
+
+ ClassDB::bind_method(D_METHOD("get_pending_event_count"), &GameCenter::get_pending_event_count);
+ ClassDB::bind_method(D_METHOD("pop_pending_event"), &GameCenter::pop_pending_event);
};
-
Error GameCenter::connect() {
//if this class isn't available, game center isn't implemented
@@ -71,33 +71,34 @@ Error GameCenter::connect() {
return ERR_UNAVAILABLE;
}
- GKLocalPlayer* player = [GKLocalPlayer localPlayer];
+ GKLocalPlayer *player = [GKLocalPlayer localPlayer];
ERR_FAIL_COND_V(![player respondsToSelector:@selector(authenticateHandler)], ERR_UNAVAILABLE);
- ViewController *root_controller=(ViewController *)((AppDelegate *)[[UIApplication sharedApplication] delegate]).window.rootViewController;
+ ViewController *root_controller = (ViewController *)((AppDelegate *)[[UIApplication sharedApplication] delegate]).window.rootViewController;
ERR_FAIL_COND_V(!root_controller, FAILED);
- //this handler is called serveral times. first when the view needs to be shown, then again after the view is cancelled or the user logs in. or if the user's already logged in, it's called just once to confirm they're authenticated. This is why no result needs to be specified in the presentViewController phase. in this case, more calls to this function will follow.
+ // This handler is called several times. First when the view needs to be shown, then again
+ // after the view is cancelled or the user logs in. Or if the user's already logged in, it's
+ // called just once to confirm they're authenticated. This is why no result needs to be specified
+ // in the presentViewController phase. In this case, more calls to this function will follow.
player.authenticateHandler = (^(UIViewController *controller, NSError *error) {
- if (controller) {
- [root_controller presentViewController:controller animated:YES completion:nil];
- }
- else {
- Dictionary ret;
- ret["type"] = "authentication";
- if (player.isAuthenticated) {
- ret["result"] = "ok";
- GameCenter::get_singleton()->connected = true;
- } else {
- ret["result"] = "error";
- ret["error_code"] = error.code;
- ret["error_description"] = [error.localizedDescription UTF8String];
- GameCenter::get_singleton()->connected = false;
- };
-
- pending_events.push_back(ret);
- };
-
+ if (controller) {
+ [root_controller presentViewController:controller animated:YES completion:nil];
+ } else {
+ Dictionary ret;
+ ret["type"] = "authentication";
+ if (player.isAuthenticated) {
+ ret["result"] = "ok";
+ GameCenter::get_singleton()->connected = true;
+ } else {
+ ret["result"] = "error";
+ ret["error_code"] = error.code;
+ ret["error_description"] = [error.localizedDescription UTF8String];
+ GameCenter::get_singleton()->connected = false;
+ };
+
+ pending_events.push_back(ret);
+ };
});
return OK;
@@ -114,26 +115,27 @@ Error GameCenter::post_score(Variant p_score) {
float score = params["score"];
String category = params["category"];
- NSString* cat_str = [[[NSString alloc] initWithUTF8String:category.utf8().get_data()] autorelease];
- GKScore* reporter = [[[GKScore alloc] initWithCategory:cat_str] autorelease];
+ NSString *cat_str = [[[NSString alloc] initWithUTF8String:category.utf8().get_data()] autorelease];
+ GKScore *reporter = [[[GKScore alloc] initWithCategory:cat_str] autorelease];
reporter.value = score;
ERR_FAIL_COND_V([GKScore respondsToSelector:@selector(reportScores)], ERR_UNAVAILABLE);
- [GKScore reportScores:@[reporter] withCompletionHandler:^(NSError* error) {
+ [GKScore reportScores:@[ reporter ]
+ withCompletionHandler:^(NSError *error) {
- Dictionary ret;
- ret["type"] = "post_score";
- if (error == nil) {
- ret["result"] = "ok";
- } else {
- ret["result"] = "error";
- ret["error_code"] = error.code;
- ret["error_description"] = [error.localizedDescription UTF8String];
- };
+ Dictionary ret;
+ ret["type"] = "post_score";
+ if (error == nil) {
+ ret["result"] = "ok";
+ } else {
+ ret["result"] = "error";
+ ret["error_code"] = error.code;
+ ret["error_description"] = [error.localizedDescription UTF8String];
+ };
- pending_events.push_back(ret);
- }];
+ pending_events.push_back(ret);
+ }];
return OK;
};
@@ -145,8 +147,8 @@ Error GameCenter::award_achievement(Variant p_params) {
String name = params["name"];
float progress = params["progress"];
- NSString* name_str = [[[NSString alloc] initWithUTF8String:name.utf8().get_data()] autorelease];
- GKAchievement* achievement = [[[GKAchievement alloc] initWithIdentifier: name_str] autorelease];
+ NSString *name_str = [[[NSString alloc] initWithUTF8String:name.utf8().get_data()] autorelease];
+ GKAchievement *achievement = [[[GKAchievement alloc] initWithIdentifier:name_str] autorelease];
ERR_FAIL_COND_V(!achievement, FAILED);
ERR_FAIL_COND_V([GKAchievement respondsToSelector:@selector(reportAchievements)], ERR_UNAVAILABLE);
@@ -157,19 +159,20 @@ Error GameCenter::award_achievement(Variant p_params) {
achievement.showsCompletionBanner = params["show_completion_banner"] ? YES : NO;
}
- [GKAchievement reportAchievements:@[achievement] withCompletionHandler:^(NSError *error) {
+ [GKAchievement reportAchievements:@[ achievement ]
+ withCompletionHandler:^(NSError *error) {
- Dictionary ret;
- ret["type"] = "award_achievement";
- if (error == nil) {
- ret["result"] = "ok";
- } else {
- ret["result"] = "error";
- ret["error_code"] = error.code;
- };
+ Dictionary ret;
+ ret["type"] = "award_achievement";
+ if (error == nil) {
+ ret["result"] = "ok";
+ } else {
+ ret["result"] = "error";
+ ret["error_code"] = error.code;
+ };
- pending_events.push_back(ret);
- }];
+ pending_events.push_back(ret);
+ }];
return OK;
};
@@ -190,11 +193,11 @@ void GameCenter::request_achievement_descriptions() {
Array hidden;
Array replayable;
- for (int i=0; i<[descriptions count]; i++) {
+ for (int i = 0; i < [descriptions count]; i++) {
- GKAchievementDescription* description = [descriptions objectAtIndex:i];
+ GKAchievementDescription *description = [descriptions objectAtIndex:i];
- const char* str = [description.identifier UTF8String];
+ const char *str = [description.identifier UTF8String];
names.push_back(String::utf8(str != NULL ? str : ""));
str = [description.title UTF8String];
@@ -230,7 +233,6 @@ void GameCenter::request_achievement_descriptions() {
}];
};
-
void GameCenter::request_achievements() {
[GKAchievement loadAchievementsWithCompletionHandler:^(NSArray *achievements, NSError *error) {
@@ -242,10 +244,10 @@ void GameCenter::request_achievements() {
PoolStringArray names;
PoolRealArray percentages;
- for (int i=0; i<[achievements count]; i++) {
+ for (int i = 0; i < [achievements count]; i++) {
- GKAchievement* achievement = [achievements objectAtIndex:i];
- const char* str = [achievement.identifier UTF8String];
+ GKAchievement *achievement = [achievements objectAtIndex:i];
+ const char *str = [achievement.identifier UTF8String];
names.push_back(String::utf8(str != NULL ? str : ""));
percentages.push_back(achievement.percentComplete);
@@ -265,8 +267,7 @@ void GameCenter::request_achievements() {
void GameCenter::reset_achievements() {
- [GKAchievement resetAchievementsWithCompletionHandler:^(NSError *error)
- {
+ [GKAchievement resetAchievementsWithCompletionHandler:^(NSError *error) {
Dictionary ret;
ret["type"] = "reset_achievements";
if (error == nil) {
@@ -291,17 +292,13 @@ Error GameCenter::show_game_center(Variant p_params) {
String view_name = params["view"];
if (view_name == "default") {
view_state = GKGameCenterViewControllerStateDefault;
- }
- else if (view_name == "leaderboards") {
+ } else if (view_name == "leaderboards") {
view_state = GKGameCenterViewControllerStateLeaderboards;
- }
- else if (view_name == "achievements") {
+ } else if (view_name == "achievements") {
view_state = GKGameCenterViewControllerStateAchievements;
- }
- else if (view_name == "challenges") {
+ } else if (view_name == "challenges") {
view_state = GKGameCenterViewControllerStateChallenges;
- }
- else {
+ } else {
return ERR_INVALID_PARAMETER;
}
}
@@ -309,7 +306,7 @@ Error GameCenter::show_game_center(Variant p_params) {
GKGameCenterViewController *controller = [[GKGameCenterViewController alloc] init];
ERR_FAIL_COND_V(!controller, FAILED);
- ViewController *root_controller=(ViewController *)((AppDelegate *)[[UIApplication sharedApplication] delegate]).window.rootViewController;
+ ViewController *root_controller = (ViewController *)((AppDelegate *)[[UIApplication sharedApplication] delegate]).window.rootViewController;
ERR_FAIL_COND_V(!root_controller, FAILED);
controller.gameCenterDelegate = root_controller;
@@ -318,12 +315,12 @@ Error GameCenter::show_game_center(Variant p_params) {
controller.leaderboardIdentifier = nil;
if (params.has("leaderboard_name")) {
String name = params["leaderboard_name"];
- NSString* name_str = [[[NSString alloc] initWithUTF8String:name.utf8().get_data()] autorelease];
+ NSString *name_str = [[[NSString alloc] initWithUTF8String:name.utf8().get_data()] autorelease];
controller.leaderboardIdentifier = name_str;
}
}
- [root_controller presentViewController: controller animated: YES completion:nil];
+ [root_controller presentViewController:controller animated:YES completion:nil];
return OK;
};
@@ -331,7 +328,7 @@ Error GameCenter::show_game_center(Variant p_params) {
void GameCenter::game_center_closed() {
Dictionary ret;
- ret["type"] = "show_game_center";
+ ret["type"] = "show_game_center";
ret["result"] = "ok";
pending_events.push_back(ret);
}
@@ -349,7 +346,7 @@ Variant GameCenter::pop_pending_event() {
return front;
};
-GameCenter* GameCenter::get_singleton() {
+GameCenter *GameCenter::get_singleton() {
return instance;
};
@@ -359,9 +356,6 @@ GameCenter::GameCenter() {
connected = false;
};
-
-GameCenter::~GameCenter() {
-
-};
+GameCenter::~GameCenter(){};
#endif
diff --git a/platform/iphone/gl_view.h b/platform/iphone/gl_view.h
index 555e34a895..14e9a66a4a 100644
--- a/platform/iphone/gl_view.h
+++ b/platform/iphone/gl_view.h
@@ -6,6 +6,7 @@
/* http://www.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 */
diff --git a/platform/iphone/gl_view.mm b/platform/iphone/gl_view.mm
index 6850b6be38..f2778e8165 100755..100644
--- a/platform/iphone/gl_view.mm
+++ b/platform/iphone/gl_view.mm
@@ -6,6 +6,7 @@
/* http://www.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 */
@@ -26,15 +27,15 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+#import "gl_view.h"
-#import <QuartzCore/QuartzCore.h>
-#import <OpenGLES/EAGLDrawable.h>
-#include "os_iphone.h"
#include "core/os/keyboard.h"
-#include "core/global_config.h"
+#include "core/project_settings.h"
+#include "os_iphone.h"
#include "servers/audio_server.h"
-#import "gl_view.h"
+#import <OpenGLES/EAGLDrawable.h>
+#import <QuartzCore/QuartzCore.h>
/*
@interface GLView (private)
@@ -47,7 +48,7 @@
int gl_view_base_fb;
static String keyboard_text;
-static GLView* _instance = NULL;
+static GLView *_instance = NULL;
static bool video_found_error = false;
static bool video_playing = false;
@@ -76,23 +77,24 @@ void _hide_keyboard() {
};
bool _play_video(String p_path, float p_volume, String p_audio_track, String p_subtitle_track) {
- p_path = GlobalConfig::get_singleton()->globalize_path(p_path);
+ p_path = ProjectSettings::get_singleton()->globalize_path(p_path);
- NSString* file_path = [[[NSString alloc] initWithUTF8String:p_path.utf8().get_data()] autorelease];
+ NSString *file_path = [[[NSString alloc] initWithUTF8String:p_path.utf8().get_data()] autorelease];
_instance.avAsset = [AVAsset assetWithURL:[NSURL fileURLWithPath:file_path]];
- _instance.avPlayerItem =[[AVPlayerItem alloc]initWithAsset:_instance.avAsset];
+ _instance.avPlayerItem = [[AVPlayerItem alloc] initWithAsset:_instance.avAsset];
[_instance.avPlayerItem addObserver:_instance forKeyPath:@"status" options:0 context:nil];
- _instance.avPlayer = [[AVPlayer alloc]initWithPlayerItem:_instance.avPlayerItem];
- _instance.avPlayerLayer =[AVPlayerLayer playerLayerWithPlayer:_instance.avPlayer];
+ _instance.avPlayer = [[AVPlayer alloc] initWithPlayerItem:_instance.avPlayerItem];
+ _instance.avPlayerLayer = [AVPlayerLayer playerLayerWithPlayer:_instance.avPlayer];
[_instance.avPlayer addObserver:_instance forKeyPath:@"status" options:0 context:nil];
- [[NSNotificationCenter defaultCenter] addObserver:_instance
- selector:@selector(playerItemDidReachEnd:)
- name:AVPlayerItemDidPlayToEndTimeNotification
- object:[_instance.avPlayer currentItem]];
+ [[NSNotificationCenter defaultCenter]
+ addObserver:_instance
+ selector:@selector(playerItemDidReachEnd:)
+ name:AVPlayerItemDidPlayToEndTimeNotification
+ object:[_instance.avPlayer currentItem]];
[_instance.avPlayer addObserver:_instance forKeyPath:@"rate" options:NSKeyValueObservingOptionNew context:0];
@@ -100,16 +102,14 @@ bool _play_video(String p_path, float p_volume, String p_audio_track, String p_s
[_instance.layer addSublayer:_instance.avPlayerLayer];
[_instance.avPlayer play];
- AVMediaSelectionGroup *audioGroup = [_instance.avAsset mediaSelectionGroupForMediaCharacteristic: AVMediaCharacteristicAudible];
+ AVMediaSelectionGroup *audioGroup = [_instance.avAsset mediaSelectionGroupForMediaCharacteristic:AVMediaCharacteristicAudible];
NSMutableArray *allAudioParams = [NSMutableArray array];
- for (id track in audioGroup.options)
- {
- NSString* language = [[track locale] localeIdentifier];
+ for (id track in audioGroup.options) {
+ NSString *language = [[track locale] localeIdentifier];
NSLog(@"subtitle lang: %@", language);
- if ([language isEqualToString:[NSString stringWithUTF8String:p_audio_track.utf8()]])
- {
+ if ([language isEqualToString:[NSString stringWithUTF8String:p_audio_track.utf8()]]) {
AVMutableAudioMixInputParameters *audioInputParams = [AVMutableAudioMixInputParameters audioMixInputParameters];
[audioInputParams setVolume:p_volume atTime:kCMTimeZero];
[audioInputParams setTrackID:[track trackID]];
@@ -118,26 +118,24 @@ bool _play_video(String p_path, float p_volume, String p_audio_track, String p_s
AVMutableAudioMix *audioMix = [AVMutableAudioMix audioMix];
[audioMix setInputParameters:allAudioParams];
- [_instance.avPlayer.currentItem selectMediaOption:track inMediaSelectionGroup: audioGroup];
+ [_instance.avPlayer.currentItem selectMediaOption:track inMediaSelectionGroup:audioGroup];
[_instance.avPlayer.currentItem setAudioMix:audioMix];
- break;
- }
+ break;
+ }
}
- AVMediaSelectionGroup *subtitlesGroup = [_instance.avAsset mediaSelectionGroupForMediaCharacteristic: AVMediaCharacteristicLegible];
+ AVMediaSelectionGroup *subtitlesGroup = [_instance.avAsset mediaSelectionGroupForMediaCharacteristic:AVMediaCharacteristicLegible];
NSArray *useableTracks = [AVMediaSelectionGroup mediaSelectionOptionsFromArray:subtitlesGroup.options withoutMediaCharacteristics:[NSArray arrayWithObject:AVMediaCharacteristicContainsOnlyForcedSubtitles]];
- for (id track in useableTracks)
- {
- NSString* language = [[track locale] localeIdentifier];
+ for (id track in useableTracks) {
+ NSString *language = [[track locale] localeIdentifier];
NSLog(@"subtitle lang: %@", language);
- if ([language isEqualToString:[NSString stringWithUTF8String:p_subtitle_track.utf8()]])
- {
- [_instance.avPlayer.currentItem selectMediaOption:track inMediaSelectionGroup: subtitlesGroup];
- break;
- }
+ if ([language isEqualToString:[NSString stringWithUTF8String:p_subtitle_track.utf8()]]) {
+ [_instance.avPlayer.currentItem selectMediaOption:track inMediaSelectionGroup:subtitlesGroup];
+ break;
+ }
}
video_playing = true;
@@ -181,19 +179,19 @@ void _stop_video() {
@synthesize animationInterval;
static const int max_touches = 8;
-static UITouch* touches[max_touches];
+static UITouch *touches[max_touches];
static void init_touches() {
- for (int i=0; i<max_touches; i++) {
+ for (int i = 0; i < max_touches; i++) {
touches[i] = NULL;
};
};
-static int get_touch_id(UITouch* p_touch) {
+static int get_touch_id(UITouch *p_touch) {
int first = -1;
- for (int i=0; i<max_touches; i++) {
+ for (int i = 0; i < max_touches; i++) {
if (first == -1 && touches[i] == NULL) {
first = i;
continue;
@@ -210,10 +208,10 @@ static int get_touch_id(UITouch* p_touch) {
return -1;
};
-static int remove_touch(UITouch* p_touch) {
+static int remove_touch(UITouch *p_touch) {
int remaining = 0;
- for (int i=0; i<max_touches; i++) {
+ for (int i = 0; i < max_touches; i++) {
if (touches[i] == NULL)
continue;
@@ -225,9 +223,9 @@ static int remove_touch(UITouch* p_touch) {
return remaining;
};
-static int get_first_id(UITouch* p_touch) {
+static int get_first_id(UITouch *p_touch) {
- for (int i=0; i<max_touches; i++) {
+ for (int i = 0; i < max_touches; i++) {
if (touches[i] != NULL)
return i;
@@ -237,7 +235,7 @@ static int get_first_id(UITouch* p_touch) {
static void clear_touches() {
- for (int i=0; i<max_touches; i++) {
+ for (int i = 0; i < max_touches; i++) {
touches[i] = NULL;
};
@@ -245,39 +243,36 @@ static void clear_touches() {
// Implement this to override the default layer class (which is [CALayer class]).
// We do this so that our view will be backed by a layer that is capable of OpenGL ES rendering.
-+ (Class) layerClass
-{
++ (Class)layerClass {
return [CAEAGLLayer class];
}
//The GL view is stored in the nib file. When it's unarchived it's sent -initWithCoder:
-- (id)initWithCoder:(NSCoder*)coder
-{
+- (id)initWithCoder:(NSCoder *)coder {
active = FALSE;
- if((self = [super initWithCoder:coder]))
- {
+ if ((self = [super initWithCoder:coder])) {
self = [self initGLES];
}
return self;
}
--(id)initGLES
-{
+- (id)initGLES {
// Get our backing layer
- CAEAGLLayer *eaglLayer = (CAEAGLLayer*) self.layer;
+ CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer;
// Configure it so that it is opaque, does not retain the contents of the backbuffer when displayed, and uses RGBA8888 color.
eaglLayer.opaque = YES;
- eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys:
- [NSNumber numberWithBool:FALSE], kEAGLDrawablePropertyRetainedBacking,
- kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat,
- nil];
+ eaglLayer.drawableProperties = [NSDictionary
+ dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:FALSE],
+ kEAGLDrawablePropertyRetainedBacking,
+ kEAGLColorFormatRGBA8,
+ kEAGLDrawablePropertyColorFormat,
+ nil];
// Create our EAGLContext, and if successful make it current and create our framebuffer.
context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES3];
- if(!context || ![EAGLContext setCurrentContext:context] || ![self createFramebuffer])
- {
+ if (!context || ![EAGLContext setCurrentContext:context] || ![self createFramebuffer]) {
[self release];
return nil;
}
@@ -287,14 +282,12 @@ static void clear_touches() {
return self;
}
--(id<GLViewDelegate>)delegate
-{
+- (id<GLViewDelegate>)delegate {
return delegate;
}
// Update the delegate, and if it needs a -setupView: call, set our internal flag so that it will be called.
--(void)setDelegate:(id<GLViewDelegate>)d
-{
+- (void)setDelegate:(id<GLViewDelegate>)d {
delegate = d;
delegateSetup = ![delegate respondsToSelector:@selector(setupView:)];
}
@@ -305,21 +298,18 @@ static void clear_touches() {
// This is the perfect opportunity to also update the framebuffer so that it is
// the same size as our display area.
--(void)layoutSubviews
-{
+- (void)layoutSubviews {
//printf("HERE\n");
[EAGLContext setCurrentContext:context];
[self destroyFramebuffer];
[self createFramebuffer];
[self drawView];
[self drawView];
-
}
-- (BOOL)createFramebuffer
-{
+- (BOOL)createFramebuffer {
// Generate IDs for a framebuffer object and a color renderbuffer
- UIScreen* mainscr = [UIScreen mainScreen];
+ UIScreen *mainscr = [UIScreen mainScreen];
printf("******** screen size %i, %i\n", (int)mainscr.currentMode.size.width, (int)mainscr.currentMode.size.height);
float minPointSize = MIN(mainscr.bounds.size.width, mainscr.bounds.size.height);
float minScreenSize = MIN(mainscr.currentMode.size.width, mainscr.currentMode.size.height);
@@ -344,8 +334,7 @@ static void clear_touches() {
glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_DEPTH_COMPONENT16_OES, backingWidth, backingHeight);
glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES, GL_RENDERBUFFER_OES, depthRenderbuffer);
- if(glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) != GL_FRAMEBUFFER_COMPLETE_OES)
- {
+ if (glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) != GL_FRAMEBUFFER_COMPLETE_OES) {
NSLog(@"failed to make complete framebuffer object %x", glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES));
return NO;
}
@@ -365,22 +354,19 @@ static void clear_touches() {
}
// Clean up any buffers we have allocated.
-- (void)destroyFramebuffer
-{
+- (void)destroyFramebuffer {
glDeleteFramebuffersOES(1, &viewFramebuffer);
viewFramebuffer = 0;
glDeleteRenderbuffersOES(1, &viewRenderbuffer);
viewRenderbuffer = 0;
- if(depthRenderbuffer)
- {
+ if (depthRenderbuffer) {
glDeleteRenderbuffersOES(1, &depthRenderbuffer);
depthRenderbuffer = 0;
}
}
-- (void)startAnimation
-{
+- (void)startAnimation {
if (active)
return;
active = TRUE;
@@ -389,26 +375,23 @@ static void clear_touches() {
// Approximate frame rate
// assumes device refreshes at 60 fps
- int frameInterval = (int) floor(animationInterval * 60.0f);
+ int frameInterval = (int)floor(animationInterval * 60.0f);
displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(drawView)];
[displayLink setFrameInterval:frameInterval];
// Setup DisplayLink in main thread
[displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
- }
- else {
+ } else {
animationTimer = [NSTimer scheduledTimerWithTimeInterval:animationInterval target:self selector:@selector(drawView) userInfo:nil repeats:YES];
}
- if (video_playing)
- {
+ if (video_playing) {
_unpause_video();
}
}
-- (void)stopAnimation
-{
+- (void)stopAnimation {
if (!active)
return;
active = FALSE;
@@ -417,41 +400,38 @@ static void clear_touches() {
if (useCADisplayLink) {
[displayLink invalidate];
displayLink = nil;
- }
- else {
+ } else {
[animationTimer invalidate];
animationTimer = nil;
}
clear_touches();
- if (video_playing)
- {
+ if (video_playing) {
// save position
}
}
-- (void)setAnimationInterval:(NSTimeInterval)interval
-{
+- (void)setAnimationInterval:(NSTimeInterval)interval {
animationInterval = interval;
- if ( (useCADisplayLink && displayLink) || ( !useCADisplayLink && animationTimer ) ) {
+ if ((useCADisplayLink && displayLink) || (!useCADisplayLink && animationTimer)) {
[self stopAnimation];
[self startAnimation];
}
}
// Updates the OpenGL view when the timer fires
-- (void)drawView
-{
+- (void)drawView {
if (useCADisplayLink) {
// Pause the CADisplayLink to avoid recursion
- [displayLink setPaused: YES];
+ [displayLink setPaused:YES];
// Process all input events
- while(CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, TRUE) == kCFRunLoopRunHandledSource);
+ while (CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, TRUE) == kCFRunLoopRunHandledSource)
+ ;
// We are good to go, resume the CADisplayLink
- [displayLink setPaused: NO];
+ [displayLink setPaused:NO];
}
if (!active) {
@@ -463,8 +443,7 @@ static void clear_touches() {
[EAGLContext setCurrentContext:context];
// If our drawing delegate needs to have the view setup, then call -setupView: and flag that it won't need to be called again.
- if(!delegateSetup)
- {
+ if (!delegateSetup) {
[delegate setupView:self];
delegateSetup = YES;
}
@@ -478,19 +457,18 @@ static void clear_touches() {
#ifdef DEBUG_ENABLED
GLenum err = glGetError();
- if(err)
+ if (err)
NSLog(@"%x error", err);
#endif
}
-- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
-{
- NSArray* tlist = [[event allTouches] allObjects];
- for (unsigned int i=0; i< [tlist count]; i++) {
+- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
+ NSArray *tlist = [[event allTouches] allObjects];
+ for (unsigned int i = 0; i < [tlist count]; i++) {
- if ( [touches containsObject:[tlist objectAtIndex:i]] ) {
+ if ([touches containsObject:[tlist objectAtIndex:i]]) {
- UITouch* touch = [tlist objectAtIndex:i];
+ UITouch *touch = [tlist objectAtIndex:i];
if (touch.phase != UITouchPhaseBegan)
continue;
int tid = get_touch_id(touch);
@@ -501,15 +479,14 @@ static void clear_touches() {
};
}
-- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
-{
+- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
- NSArray* tlist = [[event allTouches] allObjects];
- for (unsigned int i=0; i< [tlist count]; i++) {
+ NSArray *tlist = [[event allTouches] allObjects];
+ for (unsigned int i = 0; i < [tlist count]; i++) {
- if ( [touches containsObject:[tlist objectAtIndex:i]] ) {
+ if ([touches containsObject:[tlist objectAtIndex:i]]) {
- UITouch* touch = [tlist objectAtIndex:i];
+ UITouch *touch = [tlist objectAtIndex:i];
if (touch.phase != UITouchPhaseMoved)
continue;
int tid = get_touch_id(touch);
@@ -520,17 +497,15 @@ static void clear_touches() {
OSIPhone::get_singleton()->mouse_move(tid, prev_point.x * self.contentScaleFactor, prev_point.y * self.contentScaleFactor, touchPoint.x * self.contentScaleFactor, touchPoint.y * self.contentScaleFactor, first == tid);
};
};
-
}
-- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
-{
- NSArray* tlist = [[event allTouches] allObjects];
- for (unsigned int i=0; i< [tlist count]; i++) {
+- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
+ NSArray *tlist = [[event allTouches] allObjects];
+ for (unsigned int i = 0; i < [tlist count]; i++) {
- if ( [touches containsObject:[tlist objectAtIndex:i]] ) {
+ if ([touches containsObject:[tlist objectAtIndex:i]]) {
- UITouch* touch = [tlist objectAtIndex:i];
+ UITouch *touch = [tlist objectAtIndex:i];
if (touch.phase != UITouchPhaseEnded)
continue;
int tid = get_touch_id(touch);
@@ -552,7 +527,6 @@ static void clear_touches() {
return YES;
};
-
- (void)open_keyboard {
//keyboard_text = p_existing;
[self becomeFirstResponder];
@@ -577,12 +551,11 @@ static void clear_touches() {
String character;
character.parse_utf8([p_text UTF8String]);
keyboard_text = keyboard_text + character;
- OSIPhone::get_singleton()->key(character[0] == 10 ? KEY_ENTER : character[0] , true);
+ OSIPhone::get_singleton()->key(character[0] == 10 ? KEY_ENTER : character[0], true);
printf("inserting text with character %i\n", character[0]);
};
-- (void)audioRouteChangeListenerCallback:(NSNotification*)notification
-{
+- (void)audioRouteChangeListenerCallback:(NSNotification *)notification {
printf("*********** route changed!\n");
NSDictionary *interuptionDict = notification.userInfo;
@@ -590,49 +563,48 @@ static void clear_touches() {
switch (routeChangeReason) {
- case AVAudioSessionRouteChangeReasonNewDeviceAvailable:
+ case AVAudioSessionRouteChangeReasonNewDeviceAvailable: {
NSLog(@"AVAudioSessionRouteChangeReasonNewDeviceAvailable");
NSLog(@"Headphone/Line plugged in");
- break;
+ }; break;
- case AVAudioSessionRouteChangeReasonOldDeviceUnavailable:
+ case AVAudioSessionRouteChangeReasonOldDeviceUnavailable: {
NSLog(@"AVAudioSessionRouteChangeReasonOldDeviceUnavailable");
NSLog(@"Headphone/Line was pulled. Resuming video play....");
if (_is_video_playing()) {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.5f * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
- [_instance.avPlayer play]; // NOTE: change this line according your current player implementation
- NSLog(@"resumed play");
+ [_instance.avPlayer play]; // NOTE: change this line according your current player implementation
+ NSLog(@"resumed play");
});
};
- break;
+ }; break;
- case AVAudioSessionRouteChangeReasonCategoryChange:
+ case AVAudioSessionRouteChangeReasonCategoryChange: {
// called at start - also when other audio wants to play
NSLog(@"AVAudioSessionRouteChangeReasonCategoryChange");
- break;
+ }; break;
}
}
-
// When created via code however, we get initWithFrame
--(id)initWithFrame:(CGRect)frame
-{
+- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
_instance = self;
printf("after init super %p\n", self);
- if(self != nil)
- {
+ if (self != nil) {
self = [self initGLES];
printf("after init gles %p\n", self);
}
init_touches();
- self. multipleTouchEnabled = YES;
+ self.multipleTouchEnabled = YES;
printf("******** adding observer for sound routing changes\n");
- [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(audioRouteChangeListenerCallback:)
- name:AVAudioSessionRouteChangeNotification
- object:nil];
+ [[NSNotificationCenter defaultCenter]
+ addObserver:self
+ selector:@selector(audioRouteChangeListenerCallback:)
+ name:AVAudioSessionRouteChangeNotification
+ object:nil];
//self.autoresizesSubviews = YES;
//[self setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleWidth];
@@ -640,21 +612,19 @@ static void clear_touches() {
return self;
}
-// -(BOOL)automaticallyForwardAppearanceAndRotationMethodsToChildViewControllers {
-// return YES;
-// }
+//- (BOOL)automaticallyForwardAppearanceAndRotationMethodsToChildViewControllers {
+// return YES;
+//}
-// - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation{
-// return YES;
-// }
+//- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation{
+// return YES;
+//}
// Stop animating and release resources when they are no longer needed.
-- (void)dealloc
-{
+- (void)dealloc {
[self stopAnimation];
- if([EAGLContext currentContext] == context)
- {
+ if ([EAGLContext currentContext] == context) {
[EAGLContext setCurrentContext:nil];
}
@@ -664,32 +634,31 @@ static void clear_touches() {
[super dealloc];
}
-- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object
- change:(NSDictionary *)change context:(void *)context {
+- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
if (object == _instance.avPlayerItem && [keyPath isEqualToString:@"status"]) {
- if (_instance.avPlayerItem.status == AVPlayerStatusFailed || _instance.avPlayer.status == AVPlayerStatusFailed) {
- _stop_video();
- video_found_error = true;
- }
+ if (_instance.avPlayerItem.status == AVPlayerStatusFailed || _instance.avPlayer.status == AVPlayerStatusFailed) {
+ _stop_video();
+ video_found_error = true;
+ }
- if(_instance.avPlayer.status == AVPlayerStatusReadyToPlay &&
- _instance.avPlayerItem.status == AVPlayerItemStatusReadyToPlay &&
- CMTIME_COMPARE_INLINE(video_current_time, ==, kCMTimeZero)) {
+ if (_instance.avPlayer.status == AVPlayerStatusReadyToPlay &&
+ _instance.avPlayerItem.status == AVPlayerItemStatusReadyToPlay &&
+ CMTIME_COMPARE_INLINE(video_current_time, ==, kCMTimeZero)) {
- //NSLog(@"time: %@", video_current_time);
+ //NSLog(@"time: %@", video_current_time);
- [_instance.avPlayer seekToTime:video_current_time];
- video_current_time = kCMTimeZero;
+ [_instance.avPlayer seekToTime:video_current_time];
+ video_current_time = kCMTimeZero;
}
- }
+ }
if (object == _instance.avPlayer && [keyPath isEqualToString:@"rate"]) {
NSLog(@"Player playback rate changed: %.5f", _instance.avPlayer.rate);
if (_is_video_playing() && _instance.avPlayer.rate == 0.0 && !_instance.avPlayer.error) {
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.5f * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
- [_instance.avPlayer play]; // NOTE: change this line according your current player implementation
- NSLog(@"resumed play");
+ [_instance.avPlayer play]; // NOTE: change this line according your current player implementation
+ NSLog(@"resumed play");
});
NSLog(@" . . . PAUSED (or just started)");
@@ -698,40 +667,40 @@ static void clear_touches() {
}
- (void)playerItemDidReachEnd:(NSNotification *)notification {
- _stop_video();
+ _stop_video();
}
/*
- (void)moviePlayBackDidFinish:(NSNotification*)notification {
- NSNumber* reason = [[notification userInfo] objectForKey:MPMoviePlayerPlaybackDidFinishReasonUserInfoKey];
- switch ([reason intValue]) {
- case MPMovieFinishReasonPlaybackEnded:
- //NSLog(@"Playback Ended");
- break;
- case MPMovieFinishReasonPlaybackError:
- //NSLog(@"Playback Error");
- video_found_error = true;
- break;
- case MPMovieFinishReasonUserExited:
- //NSLog(@"User Exited");
- video_found_error = true;
- break;
- default:
- //NSLog(@"Unsupported reason!");
- break;
- }
-
- MPMoviePlayerController *player = [notification object];
-
- [[NSNotificationCenter defaultCenter]
- removeObserver:self
- name:MPMoviePlayerPlaybackDidFinishNotification
- object:player];
-
- [_instance.moviePlayerController stop];
- [_instance.moviePlayerController.view removeFromSuperview];
+ NSNumber* reason = [[notification userInfo] objectForKey:MPMoviePlayerPlaybackDidFinishReasonUserInfoKey];
+ switch ([reason intValue]) {
+ case MPMovieFinishReasonPlaybackEnded:
+ //NSLog(@"Playback Ended");
+ break;
+ case MPMovieFinishReasonPlaybackError:
+ //NSLog(@"Playback Error");
+ video_found_error = true;
+ break;
+ case MPMovieFinishReasonUserExited:
+ //NSLog(@"User Exited");
+ video_found_error = true;
+ break;
+ default:
+ //NSLog(@"Unsupported reason!");
+ break;
+ }
+
+ MPMoviePlayerController *player = [notification object];
+
+ [[NSNotificationCenter defaultCenter]
+ removeObserver:self
+ name:MPMoviePlayerPlaybackDidFinishNotification
+ object:player];
+
+ [_instance.moviePlayerController stop];
+ [_instance.moviePlayerController.view removeFromSuperview];
//[[MPMusicPlayerController applicationMusicPlayer] setVolume: video_previous_volume];
video_playing = false;
diff --git a/platform/iphone/globals/global_defaults.cpp b/platform/iphone/globals/global_defaults.cpp
index b3067dc0c4..aa4662302d 100644
--- a/platform/iphone/globals/global_defaults.cpp
+++ b/platform/iphone/globals/global_defaults.cpp
@@ -6,6 +6,7 @@
/* http://www.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 */
@@ -27,14 +28,14 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "global_defaults.h"
-#include "global_config.h"
+#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");
- GlobalConfig::get_singleton()->set_custom_property_info("display.iOS/driver",PropertyInfo(Variant::STRING,"display.iOS/driver",PROPERTY_HINT_ENUM,"GLES1,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/globals/global_defaults.h b/platform/iphone/globals/global_defaults.h
index 1432b74425..6fe1027287 100644
--- a/platform/iphone/globals/global_defaults.h
+++ b/platform/iphone/globals/global_defaults.h
@@ -6,6 +6,7 @@
/* http://www.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 */
diff --git a/platform/iphone/godot_iphone.cpp b/platform/iphone/godot_iphone.cpp
index 626c78fdf4..4d34ebedf9 100644
--- a/platform/iphone/godot_iphone.cpp
+++ b/platform/iphone/godot_iphone.cpp
@@ -6,6 +6,7 @@
/* http://www.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 */
diff --git a/platform/iphone/icloud.h b/platform/iphone/icloud.h
index 743a9a5de3..67d12a990a 100644
--- a/platform/iphone/icloud.h
+++ b/platform/iphone/icloud.h
@@ -6,6 +6,7 @@
/* http://www.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 */
diff --git a/platform/iphone/icloud.mm b/platform/iphone/icloud.mm
index a9b23baaeb..94c3d2ef91 100644
--- a/platform/iphone/icloud.mm
+++ b/platform/iphone/icloud.mm
@@ -6,6 +6,7 @@
/* http://www.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 */
@@ -34,24 +35,25 @@
extern "C" {
#endif
-#import <Foundation/Foundation.h>
#import "app_delegate.h"
+#import <Foundation/Foundation.h>
+
#ifndef __IPHONE_9_0
};
#endif
-ICloud* ICloud::instance = NULL;
+ICloud *ICloud::instance = NULL;
void ICloud::_bind_methods() {
- ClassDB::bind_method(D_METHOD("remove_key"),&ICloud::remove_key);
- ClassDB::bind_method(D_METHOD("set_key_values"),&ICloud::set_key_values);
- ClassDB::bind_method(D_METHOD("get_key_value"),&ICloud::get_key_value);
- ClassDB::bind_method(D_METHOD("synchronize_key_values"),&ICloud::synchronize_key_values);
- ClassDB::bind_method(D_METHOD("get_all_key_values"),&ICloud::get_all_key_values);
-
- ClassDB::bind_method(D_METHOD("get_pending_event_count"),&ICloud::get_pending_event_count);
- ClassDB::bind_method(D_METHOD("pop_pending_event"),&ICloud::pop_pending_event);
+ ClassDB::bind_method(D_METHOD("remove_key"), &ICloud::remove_key);
+ ClassDB::bind_method(D_METHOD("set_key_values"), &ICloud::set_key_values);
+ ClassDB::bind_method(D_METHOD("get_key_value"), &ICloud::get_key_value);
+ ClassDB::bind_method(D_METHOD("synchronize_key_values"), &ICloud::synchronize_key_values);
+ ClassDB::bind_method(D_METHOD("get_all_key_values"), &ICloud::get_all_key_values);
+
+ ClassDB::bind_method(D_METHOD("get_pending_event_count"), &ICloud::get_pending_event_count);
+ ClassDB::bind_method(D_METHOD("pop_pending_event"), &ICloud::pop_pending_event);
};
int ICloud::get_pending_event_count() {
@@ -67,19 +69,18 @@ Variant ICloud::pop_pending_event() {
return front;
};
-ICloud* ICloud::get_singleton() {
+ICloud *ICloud::get_singleton() {
return instance;
};
//convert from apple's abstract type to godot's abstract type....
-Variant nsobject_to_variant(NSObject* object) {
+Variant nsobject_to_variant(NSObject *object) {
if ([object isKindOfClass:[NSString class]]) {
- const char* str = [(NSString*)object UTF8String];
+ const char *str = [(NSString *)object UTF8String];
return String::utf8(str != NULL ? str : "");
- }
- else if ([object isKindOfClass:[NSData class]]) {
+ } else if ([object isKindOfClass:[NSData class]]) {
PoolByteArray ret;
- NSData* data = (NSData*)object;
+ NSData *data = (NSData *)object;
if ([data length] > 0) {
ret.resize([data length]);
{
@@ -88,95 +89,78 @@ Variant nsobject_to_variant(NSObject* object) {
}
}
return ret;
- }
- else if ([object isKindOfClass:[NSArray class]]) {
+ } else if ([object isKindOfClass:[NSArray class]]) {
Array result;
- NSArray* array = (NSArray*)object;
+ NSArray *array = (NSArray *)object;
for (unsigned int i = 0; i < [array count]; ++i) {
- NSObject* value = [array objectAtIndex:i];
+ NSObject *value = [array objectAtIndex:i];
result.push_back(nsobject_to_variant(value));
}
return result;
- }
- else if ([object isKindOfClass:[NSDictionary class]]) {
+ } else if ([object isKindOfClass:[NSDictionary class]]) {
Dictionary result;
- NSDictionary* dic = (NSDictionary*)object;
+ NSDictionary *dic = (NSDictionary *)object;
-
- NSArray* keys = [dic allKeys];
+ NSArray *keys = [dic allKeys];
int count = [keys count];
- for (int i=0; i < count; ++i) {
- NSObject* k = [ keys objectAtIndex:i];
- NSObject* v = [dic objectForKey:k];
+ for (int i = 0; i < count; ++i) {
+ NSObject *k = [keys objectAtIndex:i];
+ NSObject *v = [dic objectForKey:k];
result[nsobject_to_variant(k)] = nsobject_to_variant(v);
}
return result;
- }
- else if ([object isKindOfClass:[NSNumber class]]) {
+ } else if ([object isKindOfClass:[NSNumber class]]) {
//Every type except numbers can reliably identify its type. The following is comparing to the *internal* representation, which isn't guaranteed to match the type that was used to create it, and is not advised, particularly when dealing with potential platform differences (ie, 32/64 bit)
//To avoid errors, we'll cast as broadly as possible, and only return int or float.
//bool, char, int, uint, longlong -> int
//float, double -> float
- NSNumber* num = (NSNumber*)object;
- if(strcmp([num objCType], @encode(BOOL)) == 0) {
+ NSNumber *num = (NSNumber *)object;
+ if (strcmp([num objCType], @encode(BOOL)) == 0) {
return Variant((int)[num boolValue]);
- }
- else if(strcmp([num objCType], @encode(char)) == 0) {
+ } else if (strcmp([num objCType], @encode(char)) == 0) {
return Variant((int)[num charValue]);
- }
- else if(strcmp([num objCType], @encode(int)) == 0) {
+ } else if (strcmp([num objCType], @encode(int)) == 0) {
return Variant([num intValue]);
- }
- else if(strcmp([num objCType], @encode(unsigned int)) == 0) {
+ } else if (strcmp([num objCType], @encode(unsigned int)) == 0) {
return Variant((int)[num unsignedIntValue]);
- }
- else if(strcmp([num objCType], @encode(long long)) == 0) {
+ } else if (strcmp([num objCType], @encode(long long)) == 0) {
return Variant((int)[num longValue]);
- }
- else if(strcmp([num objCType], @encode(float)) == 0) {
+ } else if (strcmp([num objCType], @encode(float)) == 0) {
return Variant([num floatValue]);
- }
- else if(strcmp([num objCType], @encode(double)) == 0) {
+ } else if (strcmp([num objCType], @encode(double)) == 0) {
return Variant((float)[num doubleValue]);
}
- }
- else if ([object isKindOfClass:[NSDate class]]) {
+ } else if ([object isKindOfClass:[NSDate class]]) {
//this is a type that icloud supports...but how did you submit it in the first place?
//I guess this is a type that *might* show up, if you were, say, trying to make your game
//compatible with existing cloud data written by another engine's version of your game
WARN_PRINT("NSDate unsupported, returning null Variant")
return Variant();
- }
- else if ([object isKindOfClass:[NSNull class]] or object == nil) {
+ } else if ([object isKindOfClass:[NSNull class]] or object == nil) {
return Variant();
- }
- else {
+ } else {
WARN_PRINT("Trying to convert unknown NSObject type to Variant");
return Variant();
}
}
-NSObject* variant_to_nsobject(Variant v) {
+NSObject *variant_to_nsobject(Variant v) {
if (v.get_type() == Variant::STRING) {
return [[[NSString alloc] initWithUTF8String:((String)v).utf8().get_data()] autorelease];
- }
- else if (v.get_type() == Variant::REAL) {
+ } else if (v.get_type() == Variant::REAL) {
return [NSNumber numberWithDouble:(double)v];
- }
- else if (v.get_type() == Variant::INT) {
+ } else if (v.get_type() == Variant::INT) {
return [NSNumber numberWithLongLong:(long)(int)v];
- }
- else if (v.get_type() == Variant::BOOL) {
+ } else if (v.get_type() == Variant::BOOL) {
return [NSNumber numberWithBool:BOOL((bool)v)];
- }
- else if (v.get_type() == Variant::DICTIONARY) {
- NSMutableDictionary* result = [[[NSMutableDictionary alloc] init] autorelease];
+ } else if (v.get_type() == Variant::DICTIONARY) {
+ NSMutableDictionary *result = [[[NSMutableDictionary alloc] init] autorelease];
Dictionary dic = v;
Array keys = dic.keys();
for (unsigned int i = 0; i < keys.size(); ++i) {
- NSString* key = [[[NSString alloc] initWithUTF8String:((String)(keys[i])).utf8().get_data()] autorelease];
- NSObject* value = variant_to_nsobject(dic[keys[i]]);
+ NSString *key = [[[NSString alloc] initWithUTF8String:((String)(keys[i])).utf8().get_data()] autorelease];
+ NSObject *value = variant_to_nsobject(dic[keys[i]]);
if (key == NULL || value == NULL) {
return NULL;
@@ -185,12 +169,11 @@ NSObject* variant_to_nsobject(Variant v) {
[result setObject:value forKey:key];
}
return result;
- }
- else if (v.get_type() == Variant::ARRAY) {
- NSMutableArray* result = [[[NSMutableArray alloc] init] autorelease];
+ } else if (v.get_type() == Variant::ARRAY) {
+ NSMutableArray *result = [[[NSMutableArray alloc] init] autorelease];
Array arr = v;
for (unsigned int i = 0; i < arr.size(); ++i) {
- NSObject* value = variant_to_nsobject(arr[i]);
+ NSObject *value = variant_to_nsobject(arr[i]);
if (value == NULL) {
//trying to add something unsupported to the array. cancel the whole array
return NULL;
@@ -198,21 +181,19 @@ NSObject* variant_to_nsobject(Variant v) {
[result addObject:value];
}
return result;
- }
- else if (v.get_type() == Variant::POOL_BYTE_ARRAY) {
+ } else if (v.get_type() == Variant::POOL_BYTE_ARRAY) {
PoolByteArray arr = v;
PoolByteArray::Read r = arr.read();
- NSData* result = [NSData dataWithBytes:r.ptr() length:arr.size()];
+ NSData *result = [NSData dataWithBytes:r.ptr() length:arr.size()];
return result;
}
- WARN_PRINT(String("Could not add unsupported type to iCloud: '" + Variant::get_type_name(v.get_type())+"'").utf8().get_data());
+ WARN_PRINT(String("Could not add unsupported type to iCloud: '" + Variant::get_type_name(v.get_type()) + "'").utf8().get_data());
return NULL;
}
-
Error ICloud::remove_key(Variant p_param) {
String param = p_param;
- NSString* key = [[[NSString alloc] initWithUTF8String:param.utf8().get_data()] autorelease];
+ NSString *key = [[[NSString alloc] initWithUTF8String:param.utf8().get_data()] autorelease];
NSUbiquitousKeyValueStore *store = [NSUbiquitousKeyValueStore defaultStore];
@@ -235,13 +216,13 @@ Variant ICloud::set_key_values(Variant p_params) {
String variant_key = keys[i];
Variant variant_value = params[variant_key];
- NSString* key = [[[NSString alloc] initWithUTF8String:variant_key.utf8().get_data()] autorelease];
+ NSString *key = [[[NSString alloc] initWithUTF8String:variant_key.utf8().get_data()] autorelease];
if (key == NULL) {
error_keys.push_back(variant_key);
continue;
}
- NSObject* value = variant_to_nsobject(variant_value);
+ NSObject *value = variant_to_nsobject(variant_value);
if (value == NULL) {
error_keys.push_back(variant_key);
@@ -258,7 +239,7 @@ Variant ICloud::set_key_values(Variant p_params) {
Variant ICloud::get_key_value(Variant p_param) {
String param = p_param;
- NSString* key = [[[NSString alloc] initWithUTF8String:param.utf8().get_data()] autorelease];
+ NSString *key = [[[NSString alloc] initWithUTF8String:param.utf8().get_data()] autorelease];
NSUbiquitousKeyValueStore *store = [NSUbiquitousKeyValueStore defaultStore];
if (![[store dictionaryRepresentation] objectForKey:key]) {
@@ -273,16 +254,16 @@ Variant ICloud::get_key_value(Variant p_param) {
Variant ICloud::get_all_key_values() {
Dictionary result;
- NSUbiquitousKeyValueStore* store = [NSUbiquitousKeyValueStore defaultStore];
- NSDictionary* store_dictionary = [store dictionaryRepresentation];
+ NSUbiquitousKeyValueStore *store = [NSUbiquitousKeyValueStore defaultStore];
+ NSDictionary *store_dictionary = [store dictionaryRepresentation];
- NSArray* keys = [store_dictionary allKeys];
+ NSArray *keys = [store_dictionary allKeys];
int count = [keys count];
- for (int i=0; i < count; ++i) {
- NSString* k = [ keys objectAtIndex:i];
- NSObject* v = [store_dictionary objectForKey:k];
+ for (int i = 0; i < count; ++i) {
+ NSString *k = [keys objectAtIndex:i];
+ NSObject *v = [store_dictionary objectForKey:k];
- const char* str = [k UTF8String];
+ const char *str = [k UTF8String];
if (str != NULL) {
result[String::utf8(str)] = nsobject_to_variant(v);
}
@@ -296,8 +277,7 @@ Error ICloud::synchronize_key_values() {
BOOL result = [store synchronize];
if (result == YES) {
return OK;
- }
- else {
+ } else {
return FAILED;
}
}
@@ -306,14 +286,14 @@ Error ICloud::initial_sync() {
//you sometimes have to write something to the store to get it to download new data. go apple!
NSUbiquitousKeyValueStore *store = [NSUbiquitousKeyValueStore defaultStore];
if ([store boolForKey:@"isb"])
- {
- [store setBool:NO forKey:@"isb"];
- }
- else
- {
- [store setBool:YES forKey:@"isb"];
- }
- return synchronize();
+ {
+ [store setBool:NO forKey:@"isb"];
+ }
+ else
+ {
+ [store setBool:YES forKey:@"isb"];
+ }
+ return synchronize();
}
*/
ICloud::ICloud() {
@@ -321,65 +301,56 @@ ICloud::ICloud() {
instance = this;
//connected = false;
- [
- //[NSNotificationCenter defaultCenter] addObserverForName: @"notify"
- [NSNotificationCenter defaultCenter] addObserverForName: NSUbiquitousKeyValueStoreDidChangeExternallyNotification
- object: [NSUbiquitousKeyValueStore defaultStore]
- queue: nil
- usingBlock: ^ (NSNotification * notification) {
- NSDictionary* userInfo = [notification userInfo];
- NSInteger change = [[userInfo objectForKey:NSUbiquitousKeyValueStoreChangeReasonKey] integerValue];
-
- Dictionary ret;
- ret["type"] = "key_value_changed";
-
- //PoolStringArray result_keys;
- //Array result_values;
- Dictionary keyValues;
- String reason = "";
-
- if (change == NSUbiquitousKeyValueStoreServerChange) {
- reason = "server";
- }
- else if (change == NSUbiquitousKeyValueStoreInitialSyncChange) {
- reason = "initial_sync";
- }
- else if (change == NSUbiquitousKeyValueStoreQuotaViolationChange) {
- reason = "quota_violation";
- }
- else if (change == NSUbiquitousKeyValueStoreAccountChange) {
- reason = "account";
- }
-
- ret["reason"] = reason;
-
-
- NSUbiquitousKeyValueStore *store = [NSUbiquitousKeyValueStore defaultStore];
-
- NSArray * keys = [userInfo objectForKey:NSUbiquitousKeyValueStoreChangedKeysKey];
- for (NSString* key in keys) {
- const char* str = [key UTF8String];
- if (str == NULL) {
- continue;
- }
-
- NSObject* object = [store objectForKey:key];
-
- //figure out what kind of object it is
- Variant value = nsobject_to_variant(object);
-
- keyValues[String::utf8(str)] = value;
- }
-
- ret["changed_values"] = keyValues;
- pending_events.push_back(ret);
- }
- ];
+ [[NSNotificationCenter defaultCenter]
+ addObserverForName:NSUbiquitousKeyValueStoreDidChangeExternallyNotification
+ object:[NSUbiquitousKeyValueStore defaultStore]
+ queue:nil
+ usingBlock:^(NSNotification *notification) {
+ NSDictionary *userInfo = [notification userInfo];
+ NSInteger change = [[userInfo objectForKey:NSUbiquitousKeyValueStoreChangeReasonKey] integerValue];
+
+ Dictionary ret;
+ ret["type"] = "key_value_changed";
+
+ //PoolStringArray result_keys;
+ //Array result_values;
+ Dictionary keyValues;
+ String reason = "";
+
+ if (change == NSUbiquitousKeyValueStoreServerChange) {
+ reason = "server";
+ } else if (change == NSUbiquitousKeyValueStoreInitialSyncChange) {
+ reason = "initial_sync";
+ } else if (change == NSUbiquitousKeyValueStoreQuotaViolationChange) {
+ reason = "quota_violation";
+ } else if (change == NSUbiquitousKeyValueStoreAccountChange) {
+ reason = "account";
+ }
+
+ ret["reason"] = reason;
+
+ NSUbiquitousKeyValueStore *store = [NSUbiquitousKeyValueStore defaultStore];
+
+ NSArray *keys = [userInfo objectForKey:NSUbiquitousKeyValueStoreChangedKeysKey];
+ for (NSString *key in keys) {
+ const char *str = [key UTF8String];
+ if (str == NULL) {
+ continue;
+ }
+
+ NSObject *object = [store objectForKey:key];
+
+ //figure out what kind of object it is
+ Variant value = nsobject_to_variant(object);
+
+ keyValues[String::utf8(str)] = value;
+ }
+
+ ret["changed_values"] = keyValues;
+ pending_events.push_back(ret);
+ }];
}
-
-ICloud::~ICloud() {
-
-};
+ICloud::~ICloud(){};
#endif
diff --git a/platform/iphone/in_app_store.h b/platform/iphone/in_app_store.h
index b2ed6f70e4..153c46bd7b 100644
--- a/platform/iphone/in_app_store.h
+++ b/platform/iphone/in_app_store.h
@@ -6,6 +6,7 @@
/* http://www.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 */
diff --git a/platform/iphone/in_app_store.mm b/platform/iphone/in_app_store.mm
index b63d7b42ab..710df0f757 100644
--- a/platform/iphone/in_app_store.mm
+++ b/platform/iphone/in_app_store.mm
@@ -6,6 +6,7 @@
/* http://www.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 */
@@ -28,30 +29,29 @@
/*************************************************************************/
#ifdef STOREKIT_ENABLED
+#include "in_app_store.h"
+
#ifdef MODULE_FUSEBOXX_ENABLED
#import "modules/fuseboxx/ios/FuseSDK.h"
#endif
-#include "in_app_store.h"
-
extern "C" {
-#import <StoreKit/StoreKit.h>
#import <Foundation/Foundation.h>
+#import <StoreKit/StoreKit.h>
};
bool auto_finish_transactions = true;
-NSMutableDictionary* pending_transactions = [NSMutableDictionary dictionary];
+NSMutableDictionary *pending_transactions = [NSMutableDictionary dictionary];
@interface SKProduct (LocalizedPrice)
-@property (nonatomic, readonly) NSString *localizedPrice;
+@property(nonatomic, readonly) NSString *localizedPrice;
@end
//----------------------------------//
// SKProduct extension
//----------------------------------//
@implementation SKProduct (LocalizedPrice)
-- (NSString *)localizedPrice
-{
+- (NSString *)localizedPrice {
NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init];
[numberFormatter setFormatterBehavior:NSNumberFormatterBehavior10_4];
[numberFormatter setNumberStyle:NSNumberFormatterCurrencyStyle];
@@ -62,30 +62,28 @@ NSMutableDictionary* pending_transactions = [NSMutableDictionary dictionary];
}
@end
-
-InAppStore* InAppStore::instance = NULL;
+InAppStore *InAppStore::instance = NULL;
void InAppStore::_bind_methods() {
- ClassDB::bind_method(D_METHOD("request_product_info"),&InAppStore::request_product_info);
- ClassDB::bind_method(D_METHOD("purchase"),&InAppStore::purchase);
+ ClassDB::bind_method(D_METHOD("request_product_info"), &InAppStore::request_product_info);
+ ClassDB::bind_method(D_METHOD("purchase"), &InAppStore::purchase);
- ClassDB::bind_method(D_METHOD("get_pending_event_count"),&InAppStore::get_pending_event_count);
- ClassDB::bind_method(D_METHOD("pop_pending_event"),&InAppStore::pop_pending_event);
- ClassDB::bind_method(D_METHOD("finish_transaction"),&InAppStore::finish_transaction);
- ClassDB::bind_method(D_METHOD("set_auto_finish_transaction"),&InAppStore::set_auto_finish_transaction);
+ ClassDB::bind_method(D_METHOD("get_pending_event_count"), &InAppStore::get_pending_event_count);
+ ClassDB::bind_method(D_METHOD("pop_pending_event"), &InAppStore::pop_pending_event);
+ ClassDB::bind_method(D_METHOD("finish_transaction"), &InAppStore::finish_transaction);
+ ClassDB::bind_method(D_METHOD("set_auto_finish_transaction"), &InAppStore::set_auto_finish_transaction);
};
-@interface ProductsDelegate : NSObject<SKProductsRequestDelegate> {
-
+@interface ProductsDelegate : NSObject <SKProductsRequestDelegate> {
};
@end
@implementation ProductsDelegate
-- (void)productsRequest:(SKProductsRequest*)request didReceiveResponse:(SKProductsResponse*)response {
+- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response {
- NSArray* products = response.products;
+ NSArray *products = response.products;
Dictionary ret;
ret["type"] = "product_info";
ret["result"] = "ok";
@@ -95,11 +93,11 @@ void InAppStore::_bind_methods() {
PoolStringArray ids;
PoolStringArray localized_prices;
- for (int i=0; i<[products count]; i++) {
+ for (int i = 0; i < [products count]; i++) {
- SKProduct* product = [products objectAtIndex:i];
+ SKProduct *product = [products objectAtIndex:i];
- const char* str = [product.localizedTitle UTF8String];
+ const char *str = [product.localizedTitle UTF8String];
titles.push_back(String::utf8(str != NULL ? str : ""));
str = [product.localizedDescription UTF8String];
@@ -116,7 +114,7 @@ void InAppStore::_bind_methods() {
PoolStringArray invalid_ids;
- for (NSString* ipid in response.invalidProductIdentifiers) {
+ for (NSString *ipid in response.invalidProductIdentifiers) {
invalid_ids.push_back(String::utf8([ipid UTF8String]));
};
@@ -137,15 +135,15 @@ Error InAppStore::request_product_info(Variant p_params) {
PoolStringArray pids = params["product_ids"];
printf("************ request product info! %i\n", pids.size());
- NSMutableArray* array = [[[NSMutableArray alloc] initWithCapacity:pids.size()] autorelease];
- for (int i=0; i<pids.size(); i++) {
+ NSMutableArray *array = [[[NSMutableArray alloc] initWithCapacity:pids.size()] autorelease];
+ for (int i = 0; i < pids.size(); i++) {
printf("******** adding %ls to product list\n", pids[i].c_str());
- NSString* pid = [[[NSString alloc] initWithUTF8String:pids[i].utf8().get_data()] autorelease];
+ NSString *pid = [[[NSString alloc] initWithUTF8String:pids[i].utf8().get_data()] autorelease];
[array addObject:pid];
};
- NSSet* products = [[[NSSet alloc] initWithArray:array] autorelease];
- SKProductsRequest* request = [[SKProductsRequest alloc] initWithProductIdentifiers:products];
+ NSSet *products = [[[NSSet alloc] initWithArray:array] autorelease];
+ SKProductsRequest *request = [[SKProductsRequest alloc] initWithProductIdentifiers:products];
ProductsDelegate *delegate = [[ProductsDelegate alloc] init];
@@ -155,131 +153,123 @@ Error InAppStore::request_product_info(Variant p_params) {
return OK;
};
-@interface TransObserver : NSObject<SKPaymentTransactionObserver> {
-
+@interface TransObserver : NSObject <SKPaymentTransactionObserver> {
};
@end
@implementation TransObserver
-- (void)paymentQueue:(SKPaymentQueue*)queue updatedTransactions:(NSArray*) transactions {
+- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions {
- printf("transactions updated!\n");
- for (SKPaymentTransaction* transaction in transactions) {
+ printf("transactions updated!\n");
+ for (SKPaymentTransaction *transaction in transactions) {
switch (transaction.transactionState) {
+ case SKPaymentTransactionStatePurchased: {
+ printf("status purchased!\n");
+ String pid = String::utf8([transaction.payment.productIdentifier UTF8String]);
+ String transactionId = String::utf8([transaction.transactionIdentifier UTF8String]);
+ InAppStore::get_singleton()->_record_purchase(pid);
+ Dictionary ret;
+ ret["type"] = "purchase";
+ ret["result"] = "ok";
+ ret["product_id"] = pid;
+ ret["transaction_id"] = transactionId;
+
+ NSData *receipt = nil;
+ int sdk_version = 6;
+
+ if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0) {
+
+ NSURL *receiptFileURL = nil;
+ NSBundle *bundle = [NSBundle mainBundle];
+ if ([bundle respondsToSelector:@selector(appStoreReceiptURL)]) {
+
+ // Get the transaction receipt file path location in the app bundle.
+ receiptFileURL = [bundle appStoreReceiptURL];
+
+ // Read in the contents of the transaction file.
+ receipt = [NSData dataWithContentsOfURL:receiptFileURL];
+ sdk_version = 7;
+
+ } else {
+ // Fall back to deprecated transaction receipt,
+ // which is still available in iOS 7.
+
+ // Use SKPaymentTransaction's transactionReceipt.
+ receipt = transaction.transactionReceipt;
+ }
+
+ } else {
+ receipt = transaction.transactionReceipt;
+ }
+
+ NSString *receipt_to_send = nil;
+ if (receipt != nil) {
+ receipt_to_send = [receipt description];
+ }
+ Dictionary receipt_ret;
+ receipt_ret["receipt"] = String::utf8(receipt_to_send != nil ? [receipt_to_send UTF8String] : "");
+ receipt_ret["sdk"] = sdk_version;
+ ret["receipt"] = receipt_ret;
+
+ InAppStore::get_singleton()->_post_event(ret);
+
+ if (auto_finish_transactions) {
+ [[SKPaymentQueue defaultQueue] finishTransaction:transaction];
+ } else {
+ [pending_transactions setObject:transaction forKey:transaction.payment.productIdentifier];
+ }
- case SKPaymentTransactionStatePurchased: {
- printf("status purchased!\n");
- String pid = String::utf8([transaction.payment.productIdentifier UTF8String]);
- String transactionId = String::utf8([transaction.transactionIdentifier UTF8String]);
- InAppStore::get_singleton()->_record_purchase(pid);
- Dictionary ret;
- ret["type"] = "purchase";
- ret["result"] = "ok";
- ret["product_id"] = pid;
- ret["transaction_id"] = transactionId;
-
- NSData* receipt = nil;
- int sdk_version = 6;
-
- if([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0){
-
- NSURL *receiptFileURL = nil;
- NSBundle *bundle = [NSBundle mainBundle];
- if ([bundle respondsToSelector:@selector(appStoreReceiptURL)]) {
-
- // Get the transaction receipt file path location in the app bundle.
- receiptFileURL = [bundle appStoreReceiptURL];
-
- // Read in the contents of the transaction file.
- receipt = [NSData dataWithContentsOfURL:receiptFileURL];
- sdk_version = 7;
-
- } else {
- // Fall back to deprecated transaction receipt,
- // which is still available in iOS 7.
-
- // Use SKPaymentTransaction's transactionReceipt.
- receipt = transaction.transactionReceipt;
- }
-
- }else{
- receipt = transaction.transactionReceipt;
- }
-
- NSString* receipt_to_send = nil;
- if (receipt != nil)
- {
- receipt_to_send = [receipt description];
- }
- Dictionary receipt_ret;
- receipt_ret["receipt"] = String::utf8(receipt_to_send != nil ? [receipt_to_send UTF8String] : "");
- receipt_ret["sdk"] = sdk_version;
- ret["receipt"] = receipt_ret;
-
- InAppStore::get_singleton()->_post_event(ret);
-
- if (auto_finish_transactions){
- [[SKPaymentQueue defaultQueue] finishTransaction:transaction];
- }
- else{
- [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");
- String pid = String::utf8([transaction.payment.productIdentifier UTF8String]);
- Dictionary ret;
- ret["type"] = "purchase";
- ret["result"] = "error";
- ret["product_id"] = pid;
- InAppStore::get_singleton()->_post_event(ret);
- [[SKPaymentQueue defaultQueue] finishTransaction:transaction];
- } break;
- case SKPaymentTransactionStateRestored: {
- printf("status transaction restored!\n");
- String pid = String::utf8([transaction.originalTransaction.payment.productIdentifier UTF8String]);
- InAppStore::get_singleton()->_record_purchase(pid);
- [[SKPaymentQueue defaultQueue] finishTransaction:transaction];
- } break;
-
- default:
- printf("status default %i!\n", (int)transaction.transactionState);
-
- break;
+#ifdef MODULE_FUSEBOXX_ENABLED
+ printf("Registering transaction on Fuseboxx!\n");
+ [FuseSDK registerInAppPurchase:transaction];
+#endif
+ }; break;
+ case SKPaymentTransactionStateFailed: {
+ printf("status transaction failed!\n");
+ String pid = String::utf8([transaction.payment.productIdentifier UTF8String]);
+ Dictionary ret;
+ ret["type"] = "purchase";
+ ret["result"] = "error";
+ ret["product_id"] = pid;
+ InAppStore::get_singleton()->_post_event(ret);
+ [[SKPaymentQueue defaultQueue] finishTransaction:transaction];
+ } break;
+ case SKPaymentTransactionStateRestored: {
+ printf("status transaction restored!\n");
+ String pid = String::utf8([transaction.originalTransaction.payment.productIdentifier UTF8String]);
+ InAppStore::get_singleton()->_record_purchase(pid);
+ [[SKPaymentQueue defaultQueue] finishTransaction:transaction];
+ } break;
+ default: {
+ printf("status default %i!\n", (int)transaction.transactionState);
+ }; break;
};
};
};
@end
-
Error InAppStore::purchase(Variant p_params) {
ERR_FAIL_COND_V(![SKPaymentQueue canMakePayments], ERR_UNAVAILABLE);
if (![SKPaymentQueue canMakePayments])
return ERR_UNAVAILABLE;
- printf("purchasing!\n");
+ printf("purchasing!\n");
Dictionary params = p_params;
ERR_FAIL_COND_V(!params.has("product_id"), ERR_INVALID_PARAMETER);
NSString *pid = [[[NSString alloc] initWithUTF8String:String(params["product_id"]).utf8().get_data()] autorelease];
SKPayment *payment = [SKPayment paymentWithProductIdentifier:pid];
- SKPaymentQueue* defq = [SKPaymentQueue defaultQueue];
+ SKPaymentQueue *defq = [SKPaymentQueue defaultQueue];
[defq addPayment:payment];
- printf("purchase sent!\n");
+ printf("purchase sent!\n");
return OK;
};
-
int InAppStore::get_pending_event_count() {
return pending_events.size();
};
@@ -299,13 +289,13 @@ void InAppStore::_post_event(Variant p_event) {
void InAppStore::_record_purchase(String product_id) {
- String skey = "purchased/"+product_id;
- NSString* key = [[[NSString alloc] initWithUTF8String:skey.utf8().get_data()] autorelease];
+ String skey = "purchased/" + product_id;
+ NSString *key = [[[NSString alloc] initWithUTF8String:skey.utf8().get_data()] autorelease];
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:key];
[[NSUserDefaults standardUserDefaults] synchronize];
};
-InAppStore* InAppStore::get_singleton() {
+InAppStore *InAppStore::get_singleton() {
return instance;
};
@@ -315,27 +305,24 @@ InAppStore::InAppStore() {
instance = this;
auto_finish_transactions = false;
- TransObserver* observer = [[TransObserver alloc] init];
+ TransObserver *observer = [[TransObserver alloc] init];
[[SKPaymentQueue defaultQueue] addTransactionObserver:observer];
- //pending_transactions = [NSMutableDictionary dictionary];
+ //pending_transactions = [NSMutableDictionary dictionary];
};
-void InAppStore::finish_transaction(String product_id){
- NSString* prod_id = [NSString stringWithCString:product_id.utf8().get_data() encoding:NSUTF8StringEncoding];
+void InAppStore::finish_transaction(String product_id) {
+ NSString *prod_id = [NSString stringWithCString:product_id.utf8().get_data() encoding:NSUTF8StringEncoding];
- if ([pending_transactions objectForKey:prod_id]){
+ if ([pending_transactions objectForKey:prod_id]) {
[[SKPaymentQueue defaultQueue] finishTransaction:[pending_transactions objectForKey:prod_id]];
- [pending_transactions removeObjectForKey:prod_id];
+ [pending_transactions removeObjectForKey:prod_id];
}
};
-void InAppStore::set_auto_finish_transaction(bool b){
- auto_finish_transactions = b;
+void InAppStore::set_auto_finish_transaction(bool b) {
+ auto_finish_transactions = b;
}
-InAppStore::~InAppStore() {
-
-};
-
+InAppStore::~InAppStore(){};
#endif
diff --git a/platform/iphone/ios.h b/platform/iphone/ios.h
index e5baf8f4d2..2572d626d2 100644
--- a/platform/iphone/ios.h
+++ b/platform/iphone/ios.h
@@ -6,6 +6,7 @@
/* http://www.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 */
@@ -38,6 +39,8 @@ class iOS : public Object {
static void _bind_methods();
public:
+ static void alert(const char *p_alert, const char *p_title);
+
String get_rate_url(int p_app_id) const;
iOS();
diff --git a/platform/iphone/ios.mm b/platform/iphone/ios.mm
index 4aca85dafc..6c95903241 100644
--- a/platform/iphone/ios.mm
+++ b/platform/iphone/ios.mm
@@ -6,6 +6,7 @@
/* http://www.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 */
@@ -32,9 +33,14 @@
void iOS::_bind_methods() {
- ClassDB::bind_method(D_METHOD("get_rate_url","app_id"),&iOS::get_rate_url);
+ ClassDB::bind_method(D_METHOD("get_rate_url", "app_id"), &iOS::get_rate_url);
};
+void iOS::alert(const char *p_alert, const char *p_title) {
+ UIAlertView *alert = [[[UIAlertView alloc] initWithTitle:[NSString stringWithUTF8String:p_title] message:[NSString stringWithUTF8String:p_alert] delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil, nil] autorelease];
+ [alert show];
+}
+
String iOS::get_rate_url(int p_app_id) const {
String templ = "itms-apps://ax.itunes.apple.com/WebObjects/MZStore.woa/wa/viewContentsUserReviews?type=Purple+Software&id=APP_ID";
String templ_iOS7 = "itms-apps://itunes.apple.com/app/idAPP_ID";
@@ -43,14 +49,11 @@ String iOS::get_rate_url(int p_app_id) const {
//ios7 before
String ret = templ;
- // iOS 7 needs a different templateReviewURL @see https://github.com/arashpayan/appirater/issues/131
- if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0 && [[[UIDevice currentDevice] systemVersion] floatValue] < 7.1)
- {
+ if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0 && [[[UIDevice currentDevice] systemVersion] floatValue] < 7.1) {
+ // iOS 7 needs a different templateReviewURL @see https://github.com/arashpayan/appirater/issues/131
ret = templ_iOS7;
- }
- // iOS 8 needs a different templateReviewURL also @see https://github.com/arashpayan/appirater/issues/182
- else if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0)
- {
+ } else if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0) {
+ // iOS 8 needs a different templateReviewURL also @see https://github.com/arashpayan/appirater/issues/182
ret = templ_iOS8;
}
@@ -61,4 +64,4 @@ String iOS::get_rate_url(int p_app_id) const {
return ret;
};
-iOS::iOS() {};
+iOS::iOS(){};
diff --git a/platform/iphone/main.m b/platform/iphone/main.m
index 02a45737c5..6757cc8146 100644
--- a/platform/iphone/main.m
+++ b/platform/iphone/main.m
@@ -6,6 +6,7 @@
/* http://www.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 */
@@ -26,25 +27,24 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#import <UIKit/UIKit.h>
#import "app_delegate.h"
+
+#import <UIKit/UIKit.h>
#include <stdio.h>
int gargc;
-char** gargv;
+char **gargv;
-int main(int argc, char *argv[])
-{
+int main(int argc, char *argv[]) {
printf("*********** main.m\n");
gargc = argc;
gargv = argv;
NSAutoreleasePool *pool = [NSAutoreleasePool new];
- AppDelegate* app = [AppDelegate alloc];
+ AppDelegate *app = [AppDelegate alloc];
printf("running app main\n");
UIApplicationMain(argc, argv, nil, @"AppDelegate");
printf("main done, pool release\n");
[pool release];
return 0;
}
-
diff --git a/platform/iphone/os_iphone.cpp b/platform/iphone/os_iphone.cpp
index 752690762e..df497349ae 100644
--- a/platform/iphone/os_iphone.cpp
+++ b/platform/iphone/os_iphone.cpp
@@ -6,6 +6,7 @@
/* http://www.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 */
@@ -37,10 +38,10 @@
#include "audio_driver_iphone.h"
#include "main/main.h"
-#include "core/global_config.h"
#include "core/io/file_access_pack.h"
#include "core/os/dir_access.h"
#include "core/os/file_access.h"
+#include "core/project_settings.h"
#include "sem_iphone.h"
@@ -82,12 +83,12 @@ void OSIPhone::set_data_dir(String p_dir) {
memdelete(da);
};
-void OSIPhone::set_unique_ID(String p_ID) {
+void OSIPhone::set_unique_id(String p_ID) {
unique_ID = p_ID;
};
-String OSIPhone::get_unique_ID() const {
+String OSIPhone::get_unique_id() const {
return unique_ID;
};
@@ -108,7 +109,6 @@ void OSIPhone::initialize(const VideoMode &p_desired, int p_video_driver, int p_
RasterizerGLES3::register_config();
RasterizerGLES3::make_current();
- RasterizerStorageGLES3::system_fbo = gl_view_base_fb;
visual_server = memnew(VisualServerRaster());
/*
@@ -119,7 +119,10 @@ 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;
audio_driver = memnew(AudioDriverIphone);
audio_driver->set_singleton();
@@ -137,28 +140,28 @@ void OSIPhone::initialize(const VideoMode &p_desired, int p_video_driver, int p_
/*
#ifdef IOS_SCORELOOP_ENABLED
scoreloop = memnew(ScoreloopIOS);
- GlobalConfig::get_singleton()->add_singleton(GlobalConfig::Singleton("Scoreloop", scoreloop));
+ ProjectSettings::get_singleton()->add_singleton(ProjectSettings::Singleton("Scoreloop", scoreloop));
scoreloop->connect();
#endif
*/
#ifdef GAME_CENTER_ENABLED
game_center = memnew(GameCenter);
- GlobalConfig::get_singleton()->add_singleton(GlobalConfig::Singleton("GameCenter", game_center));
+ ProjectSettings::get_singleton()->add_singleton(ProjectSettings::Singleton("GameCenter", game_center));
game_center->connect();
#endif
#ifdef STOREKIT_ENABLED
store_kit = memnew(InAppStore);
- GlobalConfig::get_singleton()->add_singleton(GlobalConfig::Singleton("InAppStore", store_kit));
+ ProjectSettings::get_singleton()->add_singleton(ProjectSettings::Singleton("InAppStore", store_kit));
#endif
#ifdef ICLOUD_ENABLED
icloud = memnew(ICloud);
- GlobalConfig::get_singleton()->add_singleton(GlobalConfig::Singleton("ICloud", icloud));
+ ProjectSettings::get_singleton()->add_singleton(ProjectSettings::Singleton("ICloud", icloud));
//icloud->connect();
#endif
- GlobalConfig::get_singleton()->add_singleton(GlobalConfig::Singleton("iOS", memnew(iOS)));
+ ProjectSettings::get_singleton()->add_singleton(ProjectSettings::Singleton("iOS", memnew(iOS)));
};
MainLoop *OSIPhone::get_main_loop() const {
@@ -194,26 +197,24 @@ bool OSIPhone::iterate() {
void OSIPhone::key(uint32_t p_key, bool p_pressed) {
- InputEvent ev;
- ev.type = InputEvent::KEY;
- ev.ID = ++last_event_id;
- ev.key.echo = false;
- ev.key.pressed = p_pressed;
- ev.key.scancode = p_key;
- ev.key.unicode = p_key;
+ Ref<InputEventKey> ev;
+ ev.instance();
+ ev->set_echo(false);
+ ev->set_pressed(p_pressed);
+ ev->set_scancode(p_key);
+ ev->set_unicode(p_key);
queue_event(ev);
};
void OSIPhone::mouse_button(int p_idx, int p_x, int p_y, bool p_pressed, bool p_doubleclick, bool p_use_as_mouse) {
if (!GLOBAL_DEF("debug/disable_touch", false)) {
- InputEvent ev;
- ev.type = InputEvent::SCREEN_TOUCH;
- ev.ID = ++last_event_id;
- ev.screen_touch.index = p_idx;
- ev.screen_touch.pressed = p_pressed;
- ev.screen_touch.x = p_x;
- ev.screen_touch.y = p_y;
+ Ref<InputEventScreenTouch> ev;
+ ev.instance();
+
+ ev->set_index(p_idx);
+ ev->set_pressed(p_pressed);
+ ev->set_position(Vector2(p_x, p_y));
queue_event(ev);
};
@@ -221,24 +222,18 @@ void OSIPhone::mouse_button(int p_idx, int p_x, int p_y, bool p_pressed, bool p_
if (p_use_as_mouse) {
- InputEvent ev;
- ev.type = InputEvent::MOUSE_BUTTON;
- ev.device = 0;
- ev.mouse_button.pointer_index = p_idx;
- ev.ID = ++last_event_id;
+ Ref<InputEventMouseButton> ev;
+ ev.instance();
- // swaped it for tilted screen
- //ev.mouse_button.x = ev.mouse_button.global_x = video_mode.height - p_y;
- //ev.mouse_button.y = ev.mouse_button.global_y = p_x;
- ev.mouse_button.x = ev.mouse_button.global_x = p_x;
- ev.mouse_button.y = ev.mouse_button.global_y = p_y;
+ ev->set_position(Vector2(p_x, p_y));
+ ev->set_global_position(Vector2(p_x, p_y));
//mouse_list.pressed[p_idx] = p_pressed;
- input->set_mouse_pos(Point2(ev.mouse_motion.x, ev.mouse_motion.y));
- ev.mouse_button.button_index = BUTTON_LEFT;
- ev.mouse_button.doubleclick = p_doubleclick;
- ev.mouse_button.pressed = p_pressed;
+ input->set_mouse_position(ev->get_position());
+ ev->set_button_index(BUTTON_LEFT);
+ ev->set_doubleclick(p_doubleclick);
+ ev->set_pressed(p_pressed);
queue_event(ev);
};
@@ -248,48 +243,31 @@ void OSIPhone::mouse_move(int p_idx, int p_prev_x, int p_prev_y, int p_x, int p_
if (!GLOBAL_DEF("debug/disable_touch", false)) {
- InputEvent ev;
- ev.type = InputEvent::SCREEN_DRAG;
- ev.ID = ++last_event_id;
- ev.screen_drag.index = p_idx;
- ev.screen_drag.x = p_x;
- ev.screen_drag.y = p_y;
- ev.screen_drag.relative_x = p_x - p_prev_x;
- ev.screen_drag.relative_y = p_y - p_prev_y;
+ Ref<InputEventScreenDrag> ev;
+ ev.instance();
+ ev->set_index(p_idx);
+ ev->set_position(Vector2(p_x, p_y));
+ ev->set_relative(Vector2(p_x - p_prev_x, p_y - p_prev_y));
queue_event(ev);
};
if (p_use_as_mouse) {
- InputEvent ev;
- ev.type = InputEvent::MOUSE_MOTION;
- ev.device = 0;
- ev.mouse_motion.pointer_index = p_idx;
- ev.ID = ++last_event_id;
+ Ref<InputEventMouseMotion> ev;
+ ev.instance();
- if (true) { // vertical
+ ev->set_position(Vector2(p_x, p_y));
+ ev->set_global_position(Vector2(p_x, p_y));
+ ev->set_relative(Vector2(p_x - p_prev_x, p_y - p_prev_y));
- ev.mouse_motion.x = ev.mouse_button.global_x = p_x;
- ev.mouse_motion.y = ev.mouse_button.global_y = p_y;
- ev.mouse_motion.relative_x = ev.mouse_motion.x - p_prev_x;
- ev.mouse_motion.relative_y = ev.mouse_motion.y - p_prev_y;
-
- } else { // horizontal?
- ev.mouse_motion.x = ev.mouse_button.global_x = video_mode.height - p_y;
- ev.mouse_motion.y = ev.mouse_button.global_y = p_x;
- ev.mouse_motion.relative_x = ev.mouse_motion.x - (video_mode.height - p_prev_x);
- ev.mouse_motion.relative_y = ev.mouse_motion.y - p_prev_x;
- };
-
- input->set_mouse_pos(Point2(ev.mouse_motion.x, ev.mouse_motion.y));
- ev.mouse_motion.speed_x = input->get_last_mouse_speed().x;
- ev.mouse_motion.speed_y = input->get_last_mouse_speed().y;
- ev.mouse_motion.button_mask = 1; // pressed
+ input->set_mouse_position(ev->get_position());
+ ev->set_speed(input->get_last_mouse_speed());
+ ev->set_button_mask(BUTTON_LEFT); // pressed
queue_event(ev);
};
};
-void OSIPhone::queue_event(const InputEvent &p_event) {
+void OSIPhone::queue_event(const Ref<InputEvent> &p_event) {
ERR_FAIL_INDEX(event_count, MAX_EVENTS);
@@ -327,7 +305,6 @@ void OSIPhone::update_accelerometer(float p_x, float p_y, float p_z) {
ev.device = 0;
ev.joy_motion.axis = JOY_ANALOG_0;
ev.joy_motion.axis_value = (p_x / (float)ACCEL_RANGE);
- ev.ID = ++last_event_id;
last_accel.x = p_x;
queue_event(ev);
};
@@ -338,7 +315,6 @@ void OSIPhone::update_accelerometer(float p_x, float p_y, float p_z) {
ev.device = 0;
ev.joy_motion.axis = JOY_ANALOG_1;
ev.joy_motion.axis_value = (p_y / (float)ACCEL_RANGE);
- ev.ID = ++last_event_id;
last_accel.y = p_y;
queue_event(ev);
};
@@ -349,7 +325,6 @@ void OSIPhone::update_accelerometer(float p_x, float p_y, float p_z) {
ev.device = 0;
ev.joy_motion.axis = JOY_ANALOG_2;
ev.joy_motion.axis_value = ( (1.0 - p_z) / (float)ACCEL_RANGE);
- ev.ID = ++last_event_id;
last_accel.z = p_z;
queue_event(ev);
};
@@ -364,6 +339,22 @@ void OSIPhone::update_gyroscope(float p_x, float p_y, float p_z) {
input->set_gyroscope(Vector3(p_x, p_y, p_z));
};
+int OSIPhone::get_unused_joy_id() {
+ return input->get_unused_joy_id();
+};
+
+void OSIPhone::joy_connection_changed(int p_idx, bool p_connected, String p_name) {
+ input->joy_connection_changed(p_idx, p_connected, p_name);
+};
+
+void OSIPhone::joy_button(int p_device, int p_button, bool p_pressed) {
+ input->joy_button(p_device, p_button, p_pressed);
+};
+
+void OSIPhone::joy_axis(int p_device, int p_axis, const InputDefault::JoyAxis &p_value) {
+ input->joy_axis(p_device, p_axis, p_value);
+};
+
void OSIPhone::delete_main_loop() {
if (main_loop) {
@@ -400,7 +391,7 @@ bool OSIPhone::is_mouse_grab_enabled() const {
return true;
};
-Point2 OSIPhone::get_mouse_pos() const {
+Point2 OSIPhone::get_mouse_position() const {
return Point2();
};
@@ -412,6 +403,13 @@ int OSIPhone::get_mouse_button_state() const {
void OSIPhone::set_window_title(const String &p_title){};
+void OSIPhone::alert(const String &p_alert, const String &p_title) {
+
+ const CharString utf8_alert = p_alert.utf8();
+ const CharString utf8_title = p_title.utf8();
+ iOS::alert(utf8_alert.get_data(), utf8_title.get_data());
+}
+
void OSIPhone::set_video_mode(const VideoMode &p_video_mode, int p_screen) {
video_mode = p_video_mode;
@@ -436,7 +434,8 @@ bool OSIPhone::can_draw() const {
int OSIPhone::set_base_framebuffer(int p_fb) {
- RasterizerStorageGLES3::system_fbo = gl_view_base_fb;
+ // gl_view_base_fb has not been updated yet
+ RasterizerStorageGLES3::system_fbo = p_fb;
return 0;
};
@@ -519,7 +518,7 @@ Error OSIPhone::native_video_play(String p_path, float p_volume, String p_audio_
print("Unable to play %S using the native player as it resides in a .pck file\n", p_path.c_str());
return ERR_INVALID_PARAMETER;
} else {
- p_path = p_path.replace("res:/", GlobalConfig::get_singleton()->get_resource_path());
+ 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());
@@ -554,6 +553,11 @@ void OSIPhone::native_video_stop() {
_stop_video();
}
+bool OSIPhone::_check_internal_feature_support(const String &p_feature) {
+
+ return p_feature == "mobile" || p_feature == "etc" || p_feature == "pvrtc" || p_feature == "etc2";
+}
+
OSIPhone::OSIPhone(int width, int height) {
main_loop = NULL;
@@ -566,7 +570,6 @@ OSIPhone::OSIPhone(int width, int height) {
vm.resizable = false;
set_video_mode(vm);
event_count = 0;
- last_event_id = 0;
};
OSIPhone::~OSIPhone() {
diff --git a/platform/iphone/os_iphone.h b/platform/iphone/os_iphone.h
index 36261a62c2..cf2766bb33 100644
--- a/platform/iphone/os_iphone.h
+++ b/platform/iphone/os_iphone.h
@@ -6,6 +6,7 @@
/* http://www.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 */
@@ -117,10 +118,9 @@ private:
Vector3 last_accel;
- InputEvent event_queue[MAX_EVENTS];
+ Ref<InputEvent> event_queue[MAX_EVENTS];
int event_count;
- int last_event_id;
- void queue_event(const InputEvent &p_event);
+ void queue_event(const Ref<InputEvent> &p_event);
String data_dir;
String unique_ID;
@@ -145,15 +145,22 @@ public:
void update_magnetometer(float p_x, float p_y, float p_z);
void update_gyroscope(float p_x, float p_y, float p_z);
+ int get_unused_joy_id();
+ void joy_connection_changed(int p_idx, bool p_connected, String p_name);
+ void joy_button(int p_device, int p_button, bool p_pressed);
+ void joy_axis(int p_device, int p_axis, const InputDefault::JoyAxis &p_value);
+
static OSIPhone *get_singleton();
virtual void set_mouse_show(bool p_show);
virtual void set_mouse_grab(bool p_grab);
virtual bool is_mouse_grab_enabled() const;
- virtual Point2 get_mouse_pos() const;
+ virtual Point2 get_mouse_position() const;
virtual int get_mouse_button_state() const;
virtual void set_window_title(const String &p_title);
+ virtual void alert(const String &p_alert, const String &p_title = "ALERT!");
+
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;
@@ -183,8 +190,8 @@ public:
void set_locale(String p_locale);
String get_locale() const;
- void set_unique_ID(String p_ID);
- String get_unique_ID() const;
+ void set_unique_id(String p_ID);
+ String get_unique_id() const;
virtual Error native_video_play(String p_path, float p_volume, String p_audio_track, String p_subtitle_track);
virtual bool native_video_is_playing() const;
@@ -193,6 +200,7 @@ public:
virtual void native_video_focus_out();
virtual void native_video_stop();
+ virtual bool _check_internal_feature_support(const String &p_feature);
OSIPhone(int width, int height);
~OSIPhone();
};
diff --git a/platform/iphone/platform_config.h b/platform/iphone/platform_config.h
index 64e9388910..7e4b533254 100644
--- a/platform/iphone/platform_config.h
+++ b/platform/iphone/platform_config.h
@@ -6,6 +6,7 @@
/* http://www.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 */
diff --git a/platform/iphone/platform_refcount.h b/platform/iphone/platform_refcount.h
index 6cfdc49369..c02e709ea1 100644
--- a/platform/iphone/platform_refcount.h
+++ b/platform/iphone/platform_refcount.h
@@ -6,6 +6,7 @@
/* http://www.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 */
diff --git a/platform/iphone/power_iphone.cpp b/platform/iphone/power_iphone.cpp
index 7b1f9246f4..5192f8e593 100644
--- a/platform/iphone/power_iphone.cpp
+++ b/platform/iphone/power_iphone.cpp
@@ -6,6 +6,7 @@
/* http://www.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 */
diff --git a/platform/iphone/power_iphone.h b/platform/iphone/power_iphone.h
index 8890c33e74..174ee6c63b 100644
--- a/platform/iphone/power_iphone.h
+++ b/platform/iphone/power_iphone.h
@@ -6,6 +6,7 @@
/* http://www.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 */
diff --git a/platform/iphone/rasterizer_iphone.cpp b/platform/iphone/rasterizer_iphone.cpp
deleted file mode 100644
index 14288e4ba0..0000000000
--- a/platform/iphone/rasterizer_iphone.cpp
+++ /dev/null
@@ -1,2584 +0,0 @@
-/*************************************************************************/
-/* rasterizer_iphone.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* http://www.godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
-/* */
-/* 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 IPHONE_ENABLED
-
-#include "rasterizer_iphone.h"
-#include "global_config.h"
-#include "os/os.h"
-#include <stdio.h>
-
-_FORCE_INLINE_ static void _gl_load_transform(const Transform &tr) {
-
- GLfloat matrix[16] = { /* build a 16x16 matrix */
- tr.basis.elements[0][0],
- tr.basis.elements[1][0],
- tr.basis.elements[2][0],
- 0,
- tr.basis.elements[0][1],
- tr.basis.elements[1][1],
- tr.basis.elements[2][1],
- 0,
- tr.basis.elements[0][2],
- tr.basis.elements[1][2],
- tr.basis.elements[2][2],
- 0,
- tr.origin.x,
- tr.origin.y,
- tr.origin.z,
- 1
- };
-
- glLoadMatrixf(matrix);
-};
-
-_FORCE_INLINE_ static void _gl_mult_transform(const Transform &tr) {
-
- GLfloat matrix[16] = { /* build a 16x16 matrix */
- tr.basis.elements[0][0],
- tr.basis.elements[1][0],
- tr.basis.elements[2][0],
- 0,
- tr.basis.elements[0][1],
- tr.basis.elements[1][1],
- tr.basis.elements[2][1],
- 0,
- tr.basis.elements[0][2],
- tr.basis.elements[1][2],
- tr.basis.elements[2][2],
- 0,
- tr.origin.x,
- tr.origin.y,
- tr.origin.z,
- 1
- };
-
- glMultMatrixf(matrix);
-};
-
-static const GLenum prim_type[] = { GL_POINTS, GL_LINES, GL_TRIANGLES, GL_TRIANGLE_FAN };
-
-static void _draw_primitive(int p_points, const float *p_vertices, const float *p_normals, const float *p_colors, const float *p_uvs, const Plane *p_tangents = NULL, int p_instanced = 1) {
-
- ERR_FAIL_COND(!p_vertices);
- ERR_FAIL_COND(p_points < 1 || p_points > 4);
-
- GLenum type = prim_type[p_points - 1];
-
- if (!p_colors) {
- glColor4f(1, 1, 1, 1);
- };
-
- glEnableClientState(GL_VERTEX_ARRAY);
- glVertexPointer(3, GL_FLOAT, 0, (GLvoid *)p_vertices);
-
- if (p_normals) {
-
- glEnableClientState(GL_NORMAL_ARRAY);
- glNormalPointer(GL_FLOAT, 0, (GLvoid *)p_normals);
- };
-
- if (p_colors) {
- glEnableClientState(GL_COLOR_ARRAY);
- glColorPointer(4, GL_FLOAT, 0, p_colors);
- };
-
- if (p_uvs) {
-
- glClientActiveTexture(GL_TEXTURE0);
- glEnableClientState(GL_TEXTURE_COORD_ARRAY);
- glTexCoordPointer(2, GL_FLOAT, 0, p_uvs);
- };
-
- glDrawArrays(type, 0, p_points);
-
- glDisableClientState(GL_VERTEX_ARRAY);
- glDisableClientState(GL_NORMAL_ARRAY);
- glDisableClientState(GL_COLOR_ARRAY);
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
-};
-
-/* TEXTURE API */
-
-static Image _get_gl_image_and_format(const Image &p_image, Image::Format p_format, uint32_t p_flags, GLenum &r_gl_format, int &r_gl_components, bool &r_has_alpha_cache) {
-
- r_has_alpha_cache = false;
- Image image = p_image;
-
- switch (p_format) {
-
- case Image::FORMAT_L8: {
- r_gl_components = 1;
- r_gl_format = GL_LUMINANCE;
-
- } break;
- case Image::FORMAT_INTENSITY: {
-
- image.convert(Image::FORMAT_RGBA8);
- r_gl_components = 4;
- r_gl_format = GL_RGBA;
- r_has_alpha_cache = true;
- } break;
- case Image::FORMAT_LA8: {
-
- image.convert(Image::FORMAT_RGBA8);
- r_gl_components = 4;
- r_gl_format = GL_RGBA;
- r_has_alpha_cache = true;
- } break;
-
- case Image::FORMAT_INDEXED: {
-
- image.convert(Image::FORMAT_RGB8);
- r_gl_components = 3;
- r_gl_format = GL_RGB;
-
- } break;
-
- case Image::FORMAT_INDEXED_ALPHA: {
-
- image.convert(Image::FORMAT_RGBA8);
- r_gl_components = 4;
- r_gl_format = GL_RGB;
- r_has_alpha_cache = true;
-
- } break;
- case Image::FORMAT_RGB8: {
-
- r_gl_components = 3;
- r_gl_format = GL_RGB;
- } break;
- case Image::FORMAT_RGBA8: {
-
- r_gl_components = 4;
- r_gl_format = GL_RGBA;
- r_has_alpha_cache = true;
- } break;
- default: {
-
- ERR_FAIL_V(Image());
- }
- }
-
- return image;
-}
-
-RID RasterizerIPhone::texture_create() {
-
- Texture *texture = memnew(Texture);
- ERR_FAIL_COND_V(!texture, RID());
- glGenTextures(1, &texture->tex_id);
- texture->active = false;
-
- return texture_owner.make_rid(texture);
-}
-
-void RasterizerIPhone::texture_allocate(RID p_texture, int p_width, int p_height, Image::Format p_format, uint32_t p_flags) {
-
- bool has_alpha_cache;
- int components;
- GLenum format;
-
- Texture *texture = texture_owner.get(p_texture);
- ERR_FAIL_COND(!texture);
- texture->width = p_width;
- texture->height = p_height;
- texture->format = p_format;
- texture->flags = p_flags;
- //texture->target = (p_flags & VS::TEXTURE_FLAG_CUBEMAP) ? GL_TEXTURE_CUBE_MAP : GL_TEXTURE_2D;
- texture->target = GL_TEXTURE_2D;
-
- _get_gl_image_and_format(Image(), texture->format, texture->flags, format, components, has_alpha_cache);
-
- texture->gl_components_cache = components;
- texture->gl_format_cache = format;
- texture->format_has_alpha = has_alpha_cache;
- texture->has_alpha = false; //by default it doesn't have alpha unless something with alpha is blitteds
-
- glBindTexture(texture->target, texture->tex_id);
-
- if (texture->flags & VS::TEXTURE_FLAG_MIPMAPS) {
- glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE);
- }
-
- if (texture->target == GL_TEXTURE_2D) {
- glTexImage2D(texture->target, 0, format, texture->width, texture->height, 0, format, GL_UNSIGNED_BYTE, NULL);
- }
-
- /*
- else {
- //cubemappor
- for (int i=0;i<6;i++)
- glTexImage2D(_cube_side_enum[i], 0, format, texture->width, texture->height, 0, format, GL_UNSIGNED_BYTE,NULL);
- }
- */
-
- glTexParameteri(texture->target, GL_TEXTURE_MIN_FILTER, GL_LINEAR); // Linear Filtering
-
- if (texture->flags & VS::TEXTURE_FLAG_FILTER) {
-
- glTexParameteri(texture->target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // Linear Filtering
- if (texture->flags & VS::TEXTURE_FLAG_MIPMAPS) {
- //glTexParameteri(texture->target,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_LINEAR);
- };
- }
-
- if (texture->flags & VS::TEXTURE_FLAG_REPEAT /* && texture->target != GL_TEXTURE_CUBE_MAP*/) {
-
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
- } else {
-
- //glTexParameterf( texture->target, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE );
- glTexParameterf(texture->target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameterf(texture->target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- }
-
- texture->active = true;
-}
-
-void RasterizerIPhone::texture_blit_rect(RID p_texture, int p_x, int p_y, const Image &p_image, VS::CubeMapSide p_cube_side) {
-
- Texture *texture = texture_owner.get(p_texture);
-
- ERR_FAIL_COND(!texture);
- ERR_FAIL_COND(!texture->active);
- ERR_FAIL_COND(texture->format != p_image.get_format());
-
- int components;
- GLenum format;
- bool alpha;
-
- Image img = _get_gl_image_and_format(p_image, p_image.get_format(), texture->flags, format, components, alpha);
-
- if (img.detect_alpha())
- texture->has_alpha = true;
-
- GLenum blit_target = GL_TEXTURE_2D; //(texture->target == GL_TEXTURE_CUBE_MAP)?_cube_side_enum[p_cube_side]:GL_TEXTURE_2D;
-
- PoolVector<uint8_t>::Read read = img.get_data().read();
-
- glBindTexture(texture->target, texture->tex_id);
- glTexSubImage2D(blit_target, 0, p_x, p_y, img.get_width(), img.get_height(), format, GL_UNSIGNED_BYTE, read.ptr());
-
- //glGenerateMipmap( texture->target );
-}
-
-Image RasterizerIPhone::texture_get_rect(RID p_texture, int p_x, int p_y, int p_width, int p_height, VS::CubeMapSide p_cube_side) const {
-
- return Image();
-}
-void RasterizerIPhone::texture_set_flags(RID p_texture, uint32_t p_flags) {
-
- Texture *texture = texture_owner.get(p_texture);
- ERR_FAIL_COND(!texture);
-
- glBindTexture(texture->target, texture->tex_id);
- uint32_t cube = texture->flags & VS::TEXTURE_FLAG_CUBEMAP;
- texture->flags = p_flags | cube; // can't remove a cube from being a cube
-
- if (texture->flags & VS::TEXTURE_FLAG_REPEAT /*&& texture->target != GL_TEXTURE_CUBE_MAP*/) {
-
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
- glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
- } else {
- //glTexParameterf( texture->target, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE );
- glTexParameterf(texture->target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameterf(texture->target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
- }
-
- if (texture->flags & VS::TEXTURE_FLAG_FILTER) {
-
- glTexParameteri(texture->target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // Linear Filtering
- if (texture->flags & VS::TEXTURE_FLAG_MIPMAPS)
- glTexParameteri(texture->target, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
-
- } else {
-
- glTexParameteri(texture->target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); // nearest
- }
-}
-uint32_t RasterizerIPhone::texture_get_flags(RID p_texture) const {
-
- Texture *texture = texture_owner.get(p_texture);
-
- ERR_FAIL_COND_V(!texture, 0);
-
- return texture->flags;
-}
-Image::Format RasterizerIPhone::texture_get_format(RID p_texture) const {
-
- Texture *texture = texture_owner.get(p_texture);
-
- ERR_FAIL_COND_V(!texture, Image::FORMAT_L8);
-
- return texture->format;
-}
-uint32_t RasterizerIPhone::texture_get_width(RID p_texture) const {
-
- Texture *texture = texture_owner.get(p_texture);
-
- ERR_FAIL_COND_V(!texture, 0);
-
- return texture->width;
-}
-uint32_t RasterizerIPhone::texture_get_height(RID p_texture) const {
-
- Texture *texture = texture_owner.get(p_texture);
-
- ERR_FAIL_COND_V(!texture, 0);
-
- return texture->height;
-}
-
-bool RasterizerIPhone::texture_has_alpha(RID p_texture) const {
-
- Texture *texture = texture_owner.get(p_texture);
-
- ERR_FAIL_COND_V(!texture, 0);
-
- return texture->has_alpha;
-}
-
-/* SHADER API */
-
-RID RasterizerIPhone::shader_create() {
-
- return RID();
-}
-
-void RasterizerIPhone::shader_node_add(RID p_shader, VS::ShaderNodeType p_type, int p_id) {
-}
-void RasterizerIPhone::shader_node_remove(RID p_shader, int p_id) {
-}
-void RasterizerIPhone::shader_node_change_type(RID p_shader, int p_id, VS::ShaderNodeType p_type) {
-}
-void RasterizerIPhone::shader_node_set_param(RID p_shader, int p_id, const Variant &p_value) {
-}
-
-void RasterizerIPhone::shader_get_node_list(RID p_shader, List<int> *p_node_list) const {
-}
-VS::ShaderNodeType RasterizerIPhone::shader_node_get_type(RID p_shader, int p_id) const {
-
- return VS::NODE_ADD;
-}
-Variant RasterizerIPhone::shader_node_get_param(RID p_shader, int p_id) const {
-
- return Variant();
-}
-
-void RasterizerIPhone::shader_connect(RID p_shader, int p_src_id, int p_src_slot, int p_dst_id, int p_dst_slot) {
-}
-bool RasterizerIPhone::shader_is_connected(RID p_shader, int p_src_id, int p_src_slot, int p_dst_id, int p_dst_slot) const {
-
- return false;
-}
-
-void RasterizerIPhone::shader_disconnect(RID p_shader, int p_src_id, int p_src_slot, int p_dst_id, int p_dst_slot) {
-}
-
-void RasterizerIPhone::shader_get_connections(RID p_shader, List<VS::ShaderConnection> *p_connections) const {
-}
-
-void RasterizerIPhone::shader_clear(RID p_shader) {
-}
-
-/* COMMON MATERIAL API */
-
-void RasterizerIPhone::material_set_param(RID p_material, const StringName &p_param, const Variant &p_value) {
-}
-Variant RasterizerIPhone::material_get_param(RID p_material, const StringName &p_param) const {
-
- return Variant();
-}
-void RasterizerIPhone::material_get_param_list(RID p_material, List<String> *p_param_list) const {
-}
-
-void RasterizerIPhone::material_set_flag(RID p_material, VS::MaterialFlag p_flag, bool p_enabled) {
-}
-bool RasterizerIPhone::material_get_flag(RID p_material, VS::MaterialFlag p_flag) const {
-
- return false;
-}
-
-void RasterizerIPhone::material_set_blend_mode(RID p_material, VS::MaterialBlendMode p_mode) {
-}
-VS::MaterialBlendMode RasterizerIPhone::material_get_blend_mode(RID p_material) const {
-
- return VS::MATERIAL_BLEND_MODE_ADD;
-}
-
-void RasterizerIPhone::material_set_line_width(RID p_material, float p_line_width) {
-}
-float RasterizerIPhone::material_get_line_width(RID p_material) const {
-
- return 0;
-}
-
-/* FIXED MATERIAL */
-
-RID RasterizerIPhone::material_create() {
-
- return material_owner.make_rid(memnew(Material));
-}
-
-void RasterizerIPhone::fixed_material_set_parameter(RID p_material, VS::FixedSpatialMaterialParam p_parameter, const Variant &p_value) {
-
- Material *m = material_owner.get(p_material);
- ERR_FAIL_COND(!m);
- ERR_FAIL_INDEX(p_parameter, VisualServer::FIXED_MATERIAL_PARAM_MAX);
-
- m->parameters[p_parameter] = p_value;
-}
-Variant RasterizerIPhone::fixed_material_get_parameter(RID p_material, VS::FixedSpatialMaterialParam p_parameter) const {
-
- Material *m = material_owner.get(p_material);
- ERR_FAIL_COND_V(!m, Variant());
- ERR_FAIL_INDEX_V(p_parameter, VisualServer::FIXED_MATERIAL_PARAM_MAX, Variant());
-
- return m->parameters[p_parameter];
-}
-
-void RasterizerIPhone::fixed_material_set_texture(RID p_material, VS::FixedSpatialMaterialParam p_parameter, RID p_texture) {
-
- Material *m = material_owner.get(p_material);
- ERR_FAIL_COND(!m);
- ERR_FAIL_INDEX(p_parameter, VisualServer::FIXED_MATERIAL_PARAM_MAX);
-
- m->textures[p_parameter] = p_texture;
-}
-RID RasterizerIPhone::fixed_material_get_texture(RID p_material, VS::FixedSpatialMaterialParam p_parameter) const {
-
- Material *m = material_owner.get(p_material);
- ERR_FAIL_COND_V(!m, RID());
- ERR_FAIL_INDEX_V(p_parameter, VisualServer::FIXED_MATERIAL_PARAM_MAX, Variant());
-
- return m->textures[p_parameter];
-}
-
-void RasterizerIPhone::fixed_material_set_detail_blend_mode(RID p_material, VS::MaterialBlendMode p_mode) {
-
- Material *m = material_owner.get(p_material);
- ERR_FAIL_COND(!m);
-
- m->detail_blend_mode = p_mode;
-}
-VS::MaterialBlendMode RasterizerIPhone::fixed_material_get_detail_blend_mode(RID p_material) const {
-
- Material *m = material_owner.get(p_material);
- ERR_FAIL_COND_V(!m, VS::MATERIAL_BLEND_MODE_MIX);
-
- return m->detail_blend_mode;
-}
-
-void RasterizerIPhone::fixed_material_set_texcoord_mode(RID p_material, VS::FixedSpatialMaterialParam p_parameter, VS::FixedSpatialMaterialTexCoordMode p_mode) {
-
- Material *m = material_owner.get(p_material);
- ERR_FAIL_COND(!m);
- ERR_FAIL_INDEX(p_parameter, VisualServer::FIXED_MATERIAL_PARAM_MAX);
-
- m->texcoord_mode[p_parameter] = p_mode;
-}
-VS::FixedSpatialMaterialTexCoordMode RasterizerIPhone::fixed_material_get_texcoord_mode(RID p_material, VS::FixedSpatialMaterialParam p_parameter) const {
-
- Material *m = material_owner.get(p_material);
- ERR_FAIL_COND_V(!m, VS::FIXED_MATERIAL_TEXCOORD_TEXGEN);
- ERR_FAIL_INDEX_V(p_parameter, VisualServer::FIXED_MATERIAL_PARAM_MAX, VS::FIXED_MATERIAL_TEXCOORD_UV);
-
- return m->texcoord_mode[p_parameter]; // for now
-}
-
-void RasterizerIPhone::fixed_material_set_texgen_mode(RID p_material, VS::FixedSpatialMaterialTexGenMode p_mode) {
-
- Material *m = material_owner.get(p_material);
- ERR_FAIL_COND(!m);
-
- m->texgen_mode = p_mode;
-};
-
-VS::FixedSpatialMaterialTexGenMode RasterizerIPhone::fixed_material_get_texgen_mode(RID p_material) const {
-
- Material *m = material_owner.get(p_material);
- ERR_FAIL_COND_V(!m, VS::FIXED_MATERIAL_TEXGEN_SPHERE);
-
- return m->texgen_mode;
-};
-
-void RasterizerIPhone::fixed_material_set_uv_transform(RID p_material, const Transform &p_transform) {
-
- Material *m = material_owner.get(p_material);
- ERR_FAIL_COND(!m);
-
- m->uv_transform = p_transform;
-}
-Transform RasterizerIPhone::fixed_material_get_uv_transform(RID p_material) const {
-
- Material *m = material_owner.get(p_material);
- ERR_FAIL_COND_V(!m, Transform());
-
- return m->uv_transform;
-}
-
-/* SHADER MATERIAL */
-
-RID RasterizerIPhone::shader_material_create() const {
-
- return RID();
-}
-
-void RasterizerIPhone::shader_material_set_vertex_shader(RID p_material, RID p_shader, bool p_owned) {
-}
-RID RasterizerIPhone::shader_material_get_vertex_shader(RID p_material) const {
-
- return RID();
-}
-
-void RasterizerIPhone::shader_material_set_fragment_shader(RID p_material, RID p_shader, bool p_owned) {
-}
-RID RasterizerIPhone::shader_material_get_fragment_shader(RID p_material) const {
-
- return RID();
-}
-
-/* MESH API */
-
-RID RasterizerIPhone::mesh_create() {
-
- return mesh_owner.make_rid(memnew(Mesh));
-}
-
-void RasterizerIPhone::mesh_add_surface(RID p_mesh, VS::PrimitiveType p_primitive, uint32_t p_format, int p_array_len, int p_index_array_len) {
-
- Mesh *mesh = mesh_owner.get(p_mesh);
- ERR_FAIL_COND(!mesh);
-
- ERR_FAIL_COND((p_format & VS::ARRAY_FORMAT_VERTEX) == 0); // mandatory
- ERR_FAIL_COND(p_array_len <= 0);
- ERR_FAIL_COND(p_index_array_len == 0);
- ERR_FAIL_INDEX(p_primitive, VS::PRIMITIVE_MAX);
-
- Surface *surface = memnew(Surface);
- ERR_FAIL_COND(!surface);
-
- int total_elem_size = 0;
-
- bool use_VBO = true; //glGenBuffersARB!=NULL; // TODO detect if it's in there
- if (p_format & VS::ARRAY_FORMAT_WEIGHTS) {
-
- use_VBO = false;
- }
-
- for (int i = 0; i < VS::ARRAY_MAX; i++) {
-
- Surface::ArrayData &ad = surface->array[i];
- ad.size = 0;
- ad.configured = false;
- ad.ofs = 0;
- int elem_size = 0;
- int elem_count = 0;
-
- if (!(p_format & (1 << i))) // no array
- continue;
-
- switch (i) {
-
- case VS::ARRAY_VERTEX:
- case VS::ARRAY_NORMAL: {
-
- elem_size = 3 * sizeof(GLfloat); // vertex
- elem_count = 3;
- } break;
- case VS::ARRAY_TANGENT: {
- elem_size = 4 * sizeof(GLfloat); // vertex
- elem_count = 4;
-
- } break;
- case VS::ARRAY_COLOR: {
-
- elem_size = 4; /* RGBA */
- elem_count = 4;
- } break;
- case VS::ARRAY_TEX_UV: {
- elem_size = 2 * sizeof(GLfloat);
- elem_count = 2;
-
- } break;
- case VS::ARRAY_WEIGHTS:
- case VS::ARRAY_BONES: {
-
- elem_size = VS::ARRAY_WEIGHTS_SIZE * sizeof(GLfloat);
- elem_count = VS::ARRAY_WEIGHTS_SIZE;
-
- } break;
- case VS::ARRAY_INDEX: {
-
- if (p_index_array_len <= 0) {
- ERR_PRINT("p_index_array_len==NO_INDEX_ARRAY");
- break;
- }
- /* determine wether using 8 or 16 bits indices */
- if (p_index_array_len > (1 << 8)) {
-
- elem_size = 2;
- } else {
- elem_size = 1;
- }
-
- if (use_VBO) {
-
- glGenBuffers(1, &surface->index_id);
- ERR_FAIL_COND(surface->index_id == 0);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, surface->index_id);
- glBufferData(GL_ELEMENT_ARRAY_BUFFER, p_index_array_len * elem_size, NULL, GL_STATIC_DRAW);
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); //unbind
- } else {
- surface->index_array_local = (uint8_t *)memalloc(p_index_array_len * elem_size);
- };
-
- surface->index_array_len = p_index_array_len; // only way it can exist
- ad.ofs = 0;
- ad.size = elem_size;
- ad.configured = false;
- ad.components = 1;
-
- continue;
- } break;
- default: {
- ERR_FAIL();
- }
- }
-
- ad.ofs = total_elem_size;
- ad.size = elem_size;
- ad.components = elem_count;
- total_elem_size += elem_size;
- ad.configured = false;
- }
-
- surface->stride = total_elem_size;
- surface->array_len = p_array_len;
- surface->format = p_format;
- surface->primitive = p_primitive;
-
- /* bind the bigass buffers */
- if (use_VBO) {
-
- glGenBuffers(1, &surface->vertex_id);
- ERR_FAIL_COND(surface->vertex_id == 0);
- glBindBuffer(GL_ARRAY_BUFFER, surface->vertex_id);
- glBufferData(GL_ARRAY_BUFFER, surface->array_len * surface->stride, NULL, GL_STATIC_DRAW);
- glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind
- } else {
- surface->array_local = (uint8_t *)memalloc(surface->array_len * surface->stride);
- };
-
- mesh->surfaces.push_back(surface);
-}
-
-Error RasterizerIPhone::mesh_surface_set_array(RID p_mesh, int p_surface, VS::ArrayType p_type, const Variant &p_array) {
-
- ERR_FAIL_INDEX_V(p_type, VS::ARRAY_MAX, ERR_INVALID_PARAMETER);
-
- Mesh *mesh = mesh_owner.get(p_mesh);
- ERR_FAIL_COND_V(!mesh, ERR_INVALID_PARAMETER);
- ERR_FAIL_INDEX_V(p_surface, mesh->surfaces.size(), ERR_INVALID_PARAMETER);
- Surface *surface = mesh->surfaces[p_surface];
- ERR_FAIL_COND_V(!surface, ERR_INVALID_PARAMETER);
-
- ERR_FAIL_COND_V(surface->array[p_type].size == 0, ERR_INVALID_PARAMETER);
-
- Surface::ArrayData &a = surface->array[p_type];
-
- switch (p_type) {
-
- case VS::ARRAY_INDEX: {
- ERR_FAIL_COND_V(surface->index_array_len <= 0, ERR_INVALID_DATA);
- ERR_FAIL_COND_V(p_array.get_type() != Variant::INT_ARRAY, ERR_INVALID_PARAMETER);
-
- PoolVector<int> indices = p_array;
- ERR_FAIL_COND_V(indices.size() == 0, ERR_INVALID_PARAMETER);
- ERR_FAIL_COND_V(indices.size() != surface->index_array_len, ERR_INVALID_PARAMETER);
-
- /* determine wether using 16 or 32 bits indices */
-
- if (surface->index_array_local == 0) {
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, surface->index_id);
- };
-
- PoolVector<int>::Read read = indices.read();
- const int *src = read.ptr();
-
- for (int i = 0; i < surface->index_array_len; i++) {
-
- if (surface->index_array_local) {
-
- if (a.size <= (1 << 8)) {
- uint8_t v = src[i];
-
- copymem(&surface->array_local[i * a.size], &v, a.size);
- } else {
- uint16_t v = src[i];
-
- copymem(&surface->array_local[i * a.size], &v, a.size);
- }
-
- } else {
- if (a.size <= (1 << 8)) {
- uint8_t v = src[i];
-
- glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, i * a.size, a.size, &v);
- } else {
- uint16_t v = src[i];
-
- glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, i * a.size, a.size, &v);
- }
- };
- }
- if (surface->index_array_local == 0) {
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
- };
- a.configured = true;
- return OK;
- } break;
- case VS::ARRAY_VERTEX:
- case VS::ARRAY_NORMAL: {
-
- ERR_FAIL_COND_V(p_array.get_type() != Variant::VECTOR3_ARRAY, ERR_INVALID_PARAMETER);
-
- PoolVector<Vector3> array = p_array;
- ERR_FAIL_COND_V(array.size() != surface->array_len, ERR_INVALID_PARAMETER);
-
- if (surface->array_local == 0) {
- glBindBuffer(GL_ARRAY_BUFFER, surface->vertex_id);
- };
-
- PoolVector<Vector3>::Read read = array.read();
- const Vector3 *src = read.ptr();
-
- // setting vertices means regenerating the AABB
- if (p_type == VS::ARRAY_VERTEX)
- surface->aabb = AABB();
-
- for (int i = 0; i < surface->array_len; i++) {
-
- GLfloat vector[3] = { src[i].x, src[i].y, src[i].z };
-
- if (surface->array_local == 0) {
- glBufferSubData(GL_ARRAY_BUFFER, a.ofs + i * surface->stride, a.size, vector);
- } else {
- copymem(&surface->array_local[a.ofs + i * surface->stride], vector, a.size);
- }
-
- if (p_type == VS::ARRAY_VERTEX) {
-
- if (i == 0) {
-
- surface->aabb = AABB(src[i], Vector3());
- } else {
-
- surface->aabb.expand_to(src[i]);
- }
- }
- }
-
- if (surface->array_local == 0) {
- glBindBuffer(GL_ARRAY_BUFFER, 0);
- };
-
- } break;
- case VS::ARRAY_TANGENT: {
-
- ERR_FAIL_COND_V(p_array.get_type() != Variant::REAL_ARRAY, ERR_INVALID_PARAMETER);
-
- PoolVector<real_t> array = p_array;
-
- ERR_FAIL_COND_V(array.size() != surface->array_len * 4, ERR_INVALID_PARAMETER);
-
- if (surface->array_local == 0) {
- glBindBuffer(GL_ARRAY_BUFFER, surface->vertex_id);
- };
-
- PoolVector<real_t>::Read read = array.read();
- const real_t *src = read.ptr();
-
- for (int i = 0; i < surface->array_len; i++) {
-
- GLfloat xyzw[4] = {
- src[i * 4 + 0],
- src[i * 4 + 1],
- src[i * 4 + 2],
- src[i * 4 + 3]
- };
-
- if (surface->array_local == 0) {
-
- glBufferSubData(GL_ARRAY_BUFFER, a.ofs + i * surface->stride, a.size, xyzw);
- } else {
-
- copymem(&surface->array_local[a.ofs + i * surface->stride], xyzw, a.size);
- };
- }
-
- if (surface->array_local == 0) {
- glBindBuffer(GL_ARRAY_BUFFER, 0);
- };
- } break;
- case VS::ARRAY_COLOR: {
-
- ERR_FAIL_COND_V(p_array.get_type() != Variant::COLOR_ARRAY, ERR_INVALID_PARAMETER);
-
- PoolVector<Color> array = p_array;
-
- ERR_FAIL_COND_V(array.size() != surface->array_len, ERR_INVALID_PARAMETER);
-
- if (surface->array_local == 0)
- glBindBuffer(GL_ARRAY_BUFFER, surface->vertex_id);
-
- PoolVector<Color>::Read read = array.read();
- const Color *src = read.ptr();
- surface->has_alpha_cache = false;
-
- for (int i = 0; i < surface->array_len; i++) {
-
- if (src[i].a < 0.98) // tolerate alpha a bit, for crappy exporters
- surface->has_alpha_cache = true;
- uint8_t colors[4] = { src[i].r * 255.0, src[i].g * 255.0, src[i].b * 255.0, src[i].a * 255.0 };
- // I'm not sure if this is correct, endianness-wise, i should re-check the GL spec
-
- if (surface->array_local == 0)
- glBufferSubData(GL_ARRAY_BUFFER, a.ofs + i * surface->stride, a.size, colors);
- else
- copymem(&surface->array_local[a.ofs + i * surface->stride], colors, a.size);
- }
-
- if (surface->array_local == 0)
- glBindBuffer(GL_ARRAY_BUFFER, 0);
-
- } break;
- case VS::ARRAY_TEX_UV: {
-
- ERR_FAIL_COND_V(p_array.get_type() != Variant::VECTOR3_ARRAY, ERR_INVALID_PARAMETER);
-
- PoolVector<Vector3> array = p_array;
-
- ERR_FAIL_COND_V(array.size() != surface->array_len, ERR_INVALID_PARAMETER);
-
- if (surface->array_local == 0)
- glBindBuffer(GL_ARRAY_BUFFER, surface->vertex_id);
-
- PoolVector<Vector3>::Read read = array.read();
-
- const Vector3 *src = read.ptr();
-
- for (int i = 0; i < surface->array_len; i++) {
-
- GLfloat uv[2] = { src[i].x, src[i].y };
-
- if (surface->array_local == 0)
- glBufferSubData(GL_ARRAY_BUFFER, a.ofs + i * surface->stride, a.size, uv);
- else
- copymem(&surface->array_local[a.ofs + i * surface->stride], uv, a.size);
- }
-
- if (surface->array_local == 0)
- glBindBuffer(GL_ARRAY_BUFFER, 0);
-
- } break;
- case VS::ARRAY_BONES:
- case VS::ARRAY_WEIGHTS: {
-
- ERR_FAIL_COND_V(p_array.get_type() != Variant::REAL_ARRAY, ERR_INVALID_PARAMETER);
-
- PoolVector<real_t> array = p_array;
-
- ERR_FAIL_COND_V(array.size() != surface->array_len * VS::ARRAY_WEIGHTS_SIZE, ERR_INVALID_PARAMETER);
-
- if (surface->array_local == 0)
- glBindBuffer(GL_ARRAY_BUFFER, surface->vertex_id);
-
- PoolVector<real_t>::Read read = array.read();
-
- const real_t *src = read.ptr();
-
- for (int i = 0; i < surface->array_len; i++) {
-
- GLfloat data[VS::ARRAY_WEIGHTS_SIZE];
- for (int j = 0; j < VS::ARRAY_WEIGHTS_SIZE; j++)
- data[j] = src[i * VS::ARRAY_WEIGHTS_SIZE + j];
-
- if (surface->array_local == 0)
- glBufferSubData(GL_ARRAY_BUFFER, a.ofs + i * surface->stride, a.size, data);
- else
- copymem(&surface->array_local[a.ofs + i * surface->stride], data, a.size);
- }
-
- if (surface->array_local == 0)
- glBindBuffer(GL_ARRAY_BUFFER, 0);
- } break;
- default: { ERR_FAIL_V(ERR_INVALID_PARAMETER); }
- }
-
- a.configured = true;
-
- return OK;
-}
-Variant RasterizerIPhone::mesh_surface_get_array(RID p_mesh, int p_surface, VS::ArrayType p_type) const {
-
- return Variant();
-}
-
-void RasterizerIPhone::mesh_surface_set_material(RID p_mesh, int p_surface, RID p_material, bool p_owned) {
-
- Mesh *mesh = mesh_owner.get(p_mesh);
- ERR_FAIL_COND(!mesh);
- ERR_FAIL_INDEX(p_surface, mesh->surfaces.size());
- Surface *surface = mesh->surfaces[p_surface];
- ERR_FAIL_COND(!surface);
-
- if (surface->material_owned && surface->material.is_valid())
- free(surface->material);
-
- surface->material_owned = p_owned;
-
- surface->material = p_material;
-}
-
-RID RasterizerIPhone::mesh_surface_get_material(RID p_mesh, int p_surface) const {
-
- Mesh *mesh = mesh_owner.get(p_mesh);
- ERR_FAIL_COND_V(!mesh, RID());
- ERR_FAIL_INDEX_V(p_surface, mesh->surfaces.size(), RID());
- Surface *surface = mesh->surfaces[p_surface];
- ERR_FAIL_COND_V(!surface, RID());
-
- return surface->material;
-}
-
-int RasterizerIPhone::mesh_surface_get_array_len(RID p_mesh, int p_surface) const {
-
- Mesh *mesh = mesh_owner.get(p_mesh);
- ERR_FAIL_COND_V(!mesh, -1);
- ERR_FAIL_INDEX_V(p_surface, mesh->surfaces.size(), -1);
- Surface *surface = mesh->surfaces[p_surface];
- ERR_FAIL_COND_V(!surface, -1);
-
- return surface->array_len;
-}
-int RasterizerIPhone::mesh_surface_get_array_index_len(RID p_mesh, int p_surface) const {
-
- Mesh *mesh = mesh_owner.get(p_mesh);
- ERR_FAIL_COND_V(!mesh, -1);
- ERR_FAIL_INDEX_V(p_surface, mesh->surfaces.size(), -1);
- Surface *surface = mesh->surfaces[p_surface];
- ERR_FAIL_COND_V(!surface, -1);
-
- return surface->index_array_len;
-}
-uint32_t RasterizerIPhone::mesh_surface_get_format(RID p_mesh, int p_surface) const {
-
- Mesh *mesh = mesh_owner.get(p_mesh);
- ERR_FAIL_COND_V(!mesh, 0);
- ERR_FAIL_INDEX_V(p_surface, mesh->surfaces.size(), 0);
- Surface *surface = mesh->surfaces[p_surface];
- ERR_FAIL_COND_V(!surface, 0);
-
- return surface->format;
-}
-VS::PrimitiveType RasterizerIPhone::mesh_surface_get_primitive_type(RID p_mesh, int p_surface) const {
-
- Mesh *mesh = mesh_owner.get(p_mesh);
- ERR_FAIL_COND_V(!mesh, VS::PRIMITIVE_POINTS);
- ERR_FAIL_INDEX_V(p_surface, mesh->surfaces.size(), VS::PRIMITIVE_POINTS);
- Surface *surface = mesh->surfaces[p_surface];
- ERR_FAIL_COND_V(!surface, VS::PRIMITIVE_POINTS);
-
- return surface->primitive;
-}
-
-void RasterizerIPhone::mesh_erase_surface(RID p_mesh, int p_index) {
-
- Mesh *mesh = mesh_owner.get(p_mesh);
- ERR_FAIL_COND(!mesh);
- ERR_FAIL_INDEX(p_index, mesh->surfaces.size());
- Surface *surface = mesh->surfaces[p_index];
- ERR_FAIL_COND(!surface);
-
- memdelete(mesh->surfaces[p_index]);
- mesh->surfaces.remove(p_index);
-}
-int RasterizerIPhone::mesh_get_surface_count(RID p_mesh) const {
-
- Mesh *mesh = mesh_owner.get(p_mesh);
- ERR_FAIL_COND_V(!mesh, -1);
-
- return mesh->surfaces.size();
-}
-
-AABB RasterizerIPhone::mesh_get_aabb(RID p_mesh) const {
-
- Mesh *mesh = mesh_owner.get(p_mesh);
- ERR_FAIL_COND_V(!mesh, AABB());
-
- AABB aabb;
-
- for (int i = 0; i < mesh->surfaces.size(); i++) {
-
- if (i == 0)
- aabb = mesh->surfaces[i]->aabb;
- else
- aabb.merge_with(mesh->surfaces[i]->aabb);
- }
-
- return aabb;
-}
-
-/* MULTIMESH API */
-
-RID RasterizerIPhone::multimesh_create() {
-
- return RID();
-}
-
-void RasterizerIPhone::multimesh_set_instance_count(RID p_multimesh, int p_count) {
-}
-int RasterizerIPhone::multimesh_get_instance_count(RID p_multimesh) const {
-
- return 0;
-}
-
-void RasterizerIPhone::multimesh_set_mesh(RID p_multimesh, RID p_mesh) {
-}
-void RasterizerIPhone::multimesh_set_aabb(RID p_multimesh, const AABB &p_aabb) {
-}
-void RasterizerIPhone::multimesh_instance_set_transform(RID p_multimesh, int p_index, const Transform &p_transform) {
-}
-void RasterizerIPhone::multimesh_instance_set_color(RID p_multimesh, int p_index, const Color &p_color) {
-}
-
-RID RasterizerIPhone::multimesh_get_mesh(RID p_multimesh) const {
-
- return RID();
-}
-AABB RasterizerIPhone::multimesh_get_aabb(RID p_multimesh) const {
-
- return AABB();
-}
-
-Transform RasterizerIPhone::multimesh_instance_get_transform(RID p_multimesh, int p_index) const {
-
- return Transform();
-}
-Color RasterizerIPhone::multimesh_instance_get_color(RID p_multimesh, int p_index) const {
-
- return Color();
-}
-
-/* POLY API */
-
-RID RasterizerIPhone::poly_create() {
-
- return RID();
-}
-void RasterizerIPhone::poly_set_material(RID p_poly, RID p_material, bool p_owned) {
-}
-void RasterizerIPhone::poly_add_primitive(RID p_poly, const Vector<Vector3> &p_points, const Vector<Vector3> &p_normals, const Vector<Color> &p_colors, const Vector<Vector3> &p_uvs) {
-}
-void RasterizerIPhone::poly_clear(RID p_poly) {
-}
-
-AABB RasterizerIPhone::poly_get_aabb(RID p_poly) const {
-
- return AABB();
-}
-
-/* PARTICLES API */
-
-RID RasterizerIPhone::particles_create() {
-
- return RID();
-}
-
-void RasterizerIPhone::particles_set_amount(RID p_particles, int p_amount) {
-}
-int RasterizerIPhone::particles_get_amount(RID p_particles) const {
-
- return 0;
-}
-
-void RasterizerIPhone::particles_set_emitting(RID p_particles, bool p_emitting) {
-}
-
-bool RasterizerIPhone::particles_is_emitting(RID p_particles) const {
-
- return false;
-}
-
-void RasterizerIPhone::particles_set_visibility_aabb(RID p_particles, const AABB &p_visibility) {
-}
-AABB RasterizerIPhone::particles_get_visibility_aabb(RID p_particles) const {
-
- return AABB();
-}
-
-void RasterizerIPhone::particles_set_emission_half_extents(RID p_particles, const Vector3 &p_half_extents) {
-}
-Vector3 RasterizerIPhone::particles_get_emission_half_extents(RID p_particles) const {
-
- return Vector3();
-}
-
-void RasterizerIPhone::particles_set_gravity_normal(RID p_particles, const Vector3 &p_normal) {
-}
-Vector3 RasterizerIPhone::particles_get_gravity_normal(RID p_particles) const {
-
- return Vector3();
-}
-
-void RasterizerIPhone::particles_set_variable(RID p_particles, VS::ParticleVariable p_variable, float p_value) {
-}
-float RasterizerIPhone::particles_get_variable(RID p_particles, VS::ParticleVariable p_variable) const {
-
- return 0;
-}
-
-void RasterizerIPhone::particles_set_randomness(RID p_particles, VS::ParticleVariable p_variable, float p_randomness) {
-}
-float RasterizerIPhone::particles_get_randomness(RID p_particles, VS::ParticleVariable p_variable) const {
-
- return 0;
-}
-
-void RasterizerIPhone::particles_set_color_phase_pos(RID p_particles, int p_phase, float p_pos) {
-}
-float RasterizerIPhone::particles_get_color_phase_pos(RID p_particles, int p_phase) const {
-
- return 0;
-}
-
-void RasterizerIPhone::particles_set_color_phases(RID p_particles, int p_phases) {
-}
-int RasterizerIPhone::particles_get_color_phases(RID p_particles) const {
-
- return 0;
-}
-
-void RasterizerIPhone::particles_set_color_phase_color(RID p_particles, int p_phase, const Color &p_color) {
-}
-Color RasterizerIPhone::particles_get_color_phase_color(RID p_particles, int p_phase) const {
-
- return Color();
-}
-
-void RasterizerIPhone::particles_set_attractors(RID p_particles, int p_attractors) {
-}
-int RasterizerIPhone::particles_get_attractors(RID p_particles) const {
-
- return 0;
-}
-
-void RasterizerIPhone::particles_set_attractor_pos(RID p_particles, int p_attractor, const Vector3 &p_pos) {
-}
-Vector3 RasterizerIPhone::particles_get_attractor_pos(RID p_particles, int p_attractor) const {
-
- return Vector3();
-}
-
-void RasterizerIPhone::particles_set_attractor_strength(RID p_particles, int p_attractor, float p_force) {
-}
-float RasterizerIPhone::particles_get_attractor_strength(RID p_particles, int p_attractor) const {
-
- return 0;
-}
-
-void RasterizerIPhone::particles_set_material(RID p_particles, RID p_material, bool p_owned) {
-}
-
-RID RasterizerIPhone::particles_get_material(RID p_particles) const {
-
- return RID();
-}
-
-AABB RasterizerIPhone::particles_get_aabb(RID p_particles) const {
-
- return AABB();
-}
-/* BEAM API */
-
-RID RasterizerIPhone::beam_create() {
-
- return RID();
-}
-
-void RasterizerIPhone::beam_set_point_count(RID p_beam, int p_count) {
-}
-int RasterizerIPhone::beam_get_point_count(RID p_beam) const {
-
- return 0;
-}
-void RasterizerIPhone::beam_clear(RID p_beam) {
-}
-
-void RasterizerIPhone::beam_set_point(RID p_beam, int p_point, Vector3 &p_pos) {
-}
-Vector3 RasterizerIPhone::beam_get_point(RID p_beam, int p_point) const {
-
- return Vector3();
-}
-
-void RasterizerIPhone::beam_set_primitive(RID p_beam, VS::BeamPrimitive p_primitive) {
-}
-
-VS::BeamPrimitive RasterizerIPhone::beam_get_primitive(RID p_beam) const {
-
- return VS::BEAM_CUBIC;
-}
-
-void RasterizerIPhone::beam_set_material(RID p_beam, RID p_material) {
-}
-RID RasterizerIPhone::beam_get_material(RID p_beam) const {
-
- return RID();
-}
-
-AABB RasterizerIPhone::beam_get_aabb(RID p_particles) const {
-
- return AABB();
-}
-/* SKELETON API */
-
-RID RasterizerIPhone::skeleton_create() {
-
- Skeleton *skeleton = memnew(Skeleton);
- ERR_FAIL_COND_V(!skeleton, RID());
- return skeleton_owner.make_rid(skeleton);
-}
-void RasterizerIPhone::skeleton_resize(RID p_skeleton, int p_bones) {
-
- Skeleton *skeleton = skeleton_owner.get(p_skeleton);
- ERR_FAIL_COND(!skeleton);
- if (p_bones == skeleton->bones.size()) {
- return;
- };
- ERR_FAIL_COND(p_bones < 0 || p_bones > 256);
-
- skeleton->bones.resize(p_bones);
-}
-int RasterizerIPhone::skeleton_get_bone_count(RID p_skeleton) const {
-
- Skeleton *skeleton = skeleton_owner.get(p_skeleton);
- ERR_FAIL_COND_V(!skeleton, -1);
- return skeleton->bones.size();
-}
-void RasterizerIPhone::skeleton_bone_set_transform(RID p_skeleton, int p_bone, const Transform &p_transform) {
-
- Skeleton *skeleton = skeleton_owner.get(p_skeleton);
- ERR_FAIL_COND(!skeleton);
- ERR_FAIL_INDEX(p_bone, skeleton->bones.size());
-
- skeleton->bones[p_bone] = p_transform;
-}
-Transform RasterizerIPhone::skeleton_bone_get_transform(RID p_skeleton, int p_bone) {
-
- Skeleton *skeleton = skeleton_owner.get(p_skeleton);
- ERR_FAIL_COND_V(!skeleton, Transform());
- ERR_FAIL_INDEX_V(p_bone, skeleton->bones.size(), Transform());
-
- // something
- return skeleton->bones[p_bone];
-}
-
-/* LIGHT API */
-
-RID RasterizerIPhone::light_create(VS::LightType p_type) {
-
- Light *light = memnew(Light);
- light->type = p_type;
- return light_owner.make_rid(light);
-}
-
-VS::LightType RasterizerIPhone::light_get_type(RID p_light) const {
-
- Light *light = light_owner.get(p_light);
- ERR_FAIL_COND_V(!light, VS::LIGHT_OMNI);
- return light->type;
-}
-
-void RasterizerIPhone::light_set_color(RID p_light, VS::LightColor p_type, const Color &p_color) {
-
- Light *light = light_owner.get(p_light);
- ERR_FAIL_COND(!light);
- ERR_FAIL_INDEX(p_type, 3);
- light->colors[p_type] = p_color;
-}
-Color RasterizerIPhone::light_get_color(RID p_light, VS::LightColor p_type) const {
-
- Light *light = light_owner.get(p_light);
- ERR_FAIL_COND_V(!light, Color());
- ERR_FAIL_INDEX_V(p_type, 3, Color());
- return light->colors[p_type];
-}
-
-void RasterizerIPhone::light_set_shadow(RID p_light, bool p_enabled) {
-
- Light *light = light_owner.get(p_light);
- ERR_FAIL_COND(!light);
- light->shadow_enabled = p_enabled;
-}
-
-bool RasterizerIPhone::light_has_shadow(RID p_light) const {
-
- Light *light = light_owner.get(p_light);
- ERR_FAIL_COND_V(!light, false);
- return light->shadow_enabled;
-}
-
-void RasterizerIPhone::light_set_volumetric(RID p_light, bool p_enabled) {
-
- Light *light = light_owner.get(p_light);
- ERR_FAIL_COND(!light);
- light->volumetric_enabled = p_enabled;
-}
-bool RasterizerIPhone::light_is_volumetric(RID p_light) const {
-
- Light *light = light_owner.get(p_light);
- ERR_FAIL_COND_V(!light, false);
- return light->volumetric_enabled;
-}
-
-void RasterizerIPhone::light_set_projector(RID p_light, RID p_texture) {
-
- Light *light = light_owner.get(p_light);
- ERR_FAIL_COND(!light);
- light->projector = p_texture;
-}
-RID RasterizerIPhone::light_get_projector(RID p_light) const {
-
- Light *light = light_owner.get(p_light);
- ERR_FAIL_COND_V(!light, RID());
- return light->projector;
-}
-
-void RasterizerIPhone::light_set_var(RID p_light, VS::LightParam p_var, float p_value) {
-
- Light *light = light_owner.get(p_light);
- ERR_FAIL_COND(!light);
- ERR_FAIL_INDEX(p_var, VS::LIGHT_PARAM_MAX);
-
- light->vars[p_var] = p_value;
-}
-float RasterizerIPhone::light_get_var(RID p_light, VS::LightParam p_var) const {
-
- Light *light = light_owner.get(p_light);
- ERR_FAIL_COND_V(!light, 0);
-
- ERR_FAIL_INDEX_V(p_var, VS::LIGHT_PARAM_MAX, 0);
-
- return light->vars[p_var];
-}
-
-AABB RasterizerIPhone::light_get_aabb(RID p_light) const {
-
- Light *light = light_owner.get(p_light);
- ERR_FAIL_COND_V(!light, AABB());
-
- switch (light->type) {
-
- case VS::LIGHT_SPOT: {
-
- float len = light->vars[VS::LIGHT_PARAM_RADIUS];
- float size = Math::tan(Math::deg2rad(light->vars[VS::LIGHT_PARAM_SPOT_ANGLE])) * len;
- return AABB(Vector3(-size, -size, -len), Vector3(size * 2, size * 2, len));
- } break;
- case VS::LIGHT_OMNI: {
-
- float r = light->vars[VS::LIGHT_PARAM_RADIUS];
- return AABB(-Vector3(r, r, r), Vector3(r, r, r) * 2);
- } break;
- case VS::LIGHT_DIRECTIONAL: {
-
- return AABB();
- } break;
- default: {}
- }
-
- ERR_FAIL_V(AABB());
-}
-
-RID RasterizerIPhone::light_instance_create(RID p_light) {
-
- Light *light = light_owner.get(p_light);
- ERR_FAIL_COND_V(!light, RID());
-
- LightInstance *light_instance = memnew(LightInstance);
-
- light_instance->light = p_light;
- light_instance->base = light;
- light_instance->last_pass = 0;
-
- return light_instance_owner.make_rid(light_instance);
-}
-void RasterizerIPhone::light_instance_set_transform(RID p_light_instance, const Transform &p_transform) {
-
- LightInstance *lighti = light_instance_owner.get(p_light_instance);
- ERR_FAIL_COND(!lighti);
- lighti->transform = p_transform;
-}
-
-void RasterizerIPhone::light_instance_set_active_hint(RID p_light_instance) {
-
- LightInstance *lighti = light_instance_owner.get(p_light_instance);
- ERR_FAIL_COND(!lighti);
- lighti->last_pass = frame;
-}
-bool RasterizerIPhone::light_instance_has_shadow(RID p_light_instance) const {
-
- return false;
-}
-bool RasterizerIPhone::light_instance_assign_shadow(RID p_light_instance) {
-
- return false;
-}
-Rasterizer::ShadowType RasterizerIPhone::light_instance_get_shadow_type(RID p_light_instance) const {
-
- return Rasterizer::SHADOW_CUBE;
-}
-int RasterizerIPhone::light_instance_get_shadow_passes(RID p_light_instance) const {
-
- return 0;
-}
-void RasterizerIPhone::light_instance_set_pssm_split_info(RID p_light_instance, int p_split, float p_near, float p_far, const CameraMatrix &p_camera, const Transform &p_transform) {
-}
-
-/* PARTICLES INSTANCE */
-
-RID RasterizerIPhone::particles_instance_create(RID p_particles) {
-
- return RID();
-}
-void RasterizerIPhone::particles_instance_set_transform(RID p_particles_instance, const Transform &p_transform) {
-}
-
-/* RENDER API */
-/* all calls (inside begin/end shadow) are always warranted to be in the following order: */
-
-static GLfloat rtri; // Angle For The Triangle ( NEW )
-static GLfloat rquad; // Angle For The Quad ( NEW )
-
-void RasterizerIPhone::begin_frame() {
-
- window_size = Size2(OS::get_singleton()->get_video_mode().width, OS::get_singleton()->get_video_mode().height);
-
- double time = (OS::get_singleton()->get_ticks_usec() / 1000); // get msec
- time /= 1000.0; // make secs
- time_delta = time - last_time;
- last_time = time;
- frame++;
- glClearColor(0, 0, 1, 1);
- glClear(GL_COLOR_BUFFER_BIT);
-
-/* nehe ?*/
-
-#if 0
- glViewport(0,0,window_size.width,window_size.height); // Reset The Current Viewport
-
- glMatrixMode(GL_PROJECTION); // Select The Projection Matrix
- glLoadIdentity(); // Reset The Projection Matrix
-
- // Calculate The Aspect Ratio Of The Window
- gluPerspective(45.0f,(GLfloat)window_size.width/(GLfloat)window_size.height,0.1f,100.0f);
-
- glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix
- glLoadIdentity(); // Reset The Modelview Matrix
-
-
-
- glShadeModel(GL_SMOOTH); // Enable Smooth Shading
- glClearColor(0.0f, 0.0f, 0.0f, 0.5f); // Black Background
- glClearDepth(1.0f); // Depth Buffer Setup
- glEnable(GL_DEPTH_TEST); // Enables Depth Testing
- glDepthFunc(GL_LEQUAL); // The Type Of Depth Testing To Do
- glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Really Nice Perspective Calculations
-
- glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear Screen And Depth Buffer
- glLoadIdentity(); // Reset The Current Modelview Matrix
- glTranslatef(-1.5f,0.0f,-6.0f); // Move Left 1.5 Units And Into The Screen 6.0
- glRotatef(rtri,0.0f,1.0f,0.0f); // Rotate The Triangle On The Y axis ( NEW )
- glBegin(GL_TRIANGLES); // Start Drawing A Triangle
- glColor3f(1.0f,0.0f,0.0f); // Red
- glVertex3f( 0.0f, 1.0f, 0.0f); // Top Of Triangle (Front)
- glColor3f(0.0f,1.0f,0.0f); // Green
- glVertex3f(-1.0f,-1.0f, 1.0f); // Left Of Triangle (Front)
- glColor3f(0.0f,0.0f,1.0f); // Blue
- glVertex3f( 1.0f,-1.0f, 1.0f); // Right Of Triangle (Front)
- glColor3f(1.0f,0.0f,0.0f); // Red
- glVertex3f( 0.0f, 1.0f, 0.0f); // Top Of Triangle (Right)
- glColor3f(0.0f,0.0f,1.0f); // Blue
- glVertex3f( 1.0f,-1.0f, 1.0f); // Left Of Triangle (Right)
- glColor3f(0.0f,1.0f,0.0f); // Green
- glVertex3f( 1.0f,-1.0f, -1.0f); // Right Of Triangle (Right)
- glColor3f(1.0f,0.0f,0.0f); // Red
- glVertex3f( 0.0f, 1.0f, 0.0f); // Top Of Triangle (Back)
- glColor3f(0.0f,1.0f,0.0f); // Green
- glVertex3f( 1.0f,-1.0f, -1.0f); // Left Of Triangle (Back)
- glColor3f(0.0f,0.0f,1.0f); // Blue
- glVertex3f(-1.0f,-1.0f, -1.0f); // Right Of Triangle (Back)
- glColor3f(1.0f,0.0f,0.0f); // Red
- glVertex3f( 0.0f, 1.0f, 0.0f); // Top Of Triangle (Left)
- glColor3f(0.0f,0.0f,1.0f); // Blue
- glVertex3f(-1.0f,-1.0f,-1.0f); // Left Of Triangle (Left)
- glColor3f(0.0f,1.0f,0.0f); // Green
- glVertex3f(-1.0f,-1.0f, 1.0f); // Right Of Triangle (Left)
- glEnd(); // Done Drawing The Pyramid
-
- glLoadIdentity(); // Reset The Current Modelview Matrix
- glTranslatef(1.5f,0.0f,-7.0f); // Move Right 1.5 Units And Into The Screen 7.0
- glRotatef(rquad,1.0f,1.0f,1.0f); // Rotate The Quad On The X axis ( NEW )
- glBegin(GL_QUADS); // Draw A Quad
- glColor3f(0.0f,1.0f,0.0f); // Set The Color To Green
- glVertex3f( 1.0f, 1.0f,-1.0f); // Top Right Of The Quad (Top)
- glVertex3f(-1.0f, 1.0f,-1.0f); // Top Left Of The Quad (Top)
- glVertex3f(-1.0f, 1.0f, 1.0f); // Bottom Left Of The Quad (Top)
- glVertex3f( 1.0f, 1.0f, 1.0f); // Bottom Right Of The Quad (Top)
- glColor3f(1.0f,0.5f,0.0f); // Set The Color To Orange
- glVertex3f( 1.0f,-1.0f, 1.0f); // Top Right Of The Quad (Bottom)
- glVertex3f(-1.0f,-1.0f, 1.0f); // Top Left Of The Quad (Bottom)
- glVertex3f(-1.0f,-1.0f,-1.0f); // Bottom Left Of The Quad (Bottom)
- glVertex3f( 1.0f,-1.0f,-1.0f); // Bottom Right Of The Quad (Bottom)
- glColor3f(1.0f,0.0f,0.0f); // Set The Color To Red
- glVertex3f( 1.0f, 1.0f, 1.0f); // Top Right Of The Quad (Front)
- glVertex3f(-1.0f, 1.0f, 1.0f); // Top Left Of The Quad (Front)
- glVertex3f(-1.0f,-1.0f, 1.0f); // Bottom Left Of The Quad (Front)
- glVertex3f( 1.0f,-1.0f, 1.0f); // Bottom Right Of The Quad (Front)
- glColor3f(1.0f,1.0f,0.0f); // Set The Color To Yellow
- glVertex3f( 1.0f,-1.0f,-1.0f); // Top Right Of The Quad (Back)
- glVertex3f(-1.0f,-1.0f,-1.0f); // Top Left Of The Quad (Back)
- glVertex3f(-1.0f, 1.0f,-1.0f); // Bottom Left Of The Quad (Back)
- glVertex3f( 1.0f, 1.0f,-1.0f); // Bottom Right Of The Quad (Back)
- glColor3f(0.0f,0.0f,1.0f); // Set The Color To Blue
- glVertex3f(-1.0f, 1.0f, 1.0f); // Top Right Of The Quad (Left)
- glVertex3f(-1.0f, 1.0f,-1.0f); // Top Left Of The Quad (Left)
- glVertex3f(-1.0f,-1.0f,-1.0f); // Bottom Left Of The Quad (Left)
- glVertex3f(-1.0f,-1.0f, 1.0f); // Bottom Right Of The Quad (Left)
- glColor3f(1.0f,0.0f,1.0f); // Set The Color To Violet
- glVertex3f( 1.0f, 1.0f,-1.0f); // Top Right Of The Quad (Right)
- glVertex3f( 1.0f, 1.0f, 1.0f); // Top Left Of The Quad (Right)
- glVertex3f( 1.0f,-1.0f, 1.0f); // Bottom Left Of The Quad (Right)
- glVertex3f( 1.0f,-1.0f,-1.0f); // Bottom Right Of The Quad (Right)
- glEnd(); // Done Drawing The Quad
-
- rtri+=0.2f; // Increase The Rotation Variable For The Triangle ( NEW )
- rquad-=0.15f; // Decrease The Rotation Variable For The Quad ( NEW )
-
-#endif
-}
-
-void RasterizerIPhone::set_viewport(const VS::ViewportRect &p_viewport) {
-
- viewport = p_viewport;
- canvas_transform = Transform();
- canvas_transform.translate(-(viewport.width / 2.0f), -(viewport.height / 2.0f), 0.0f);
- canvas_transform.scale(Vector3(2.0f / viewport.width, -2.0f / viewport.height, 1.0f));
-
- glViewport(viewport.x, window_size.height - (viewport.height + viewport.y), viewport.width, viewport.height);
-}
-
-void RasterizerIPhone::begin_scene(RID p_fx, VS::ScenarioDebugMode p_debug) {
-
- opaque_render_list.clear();
- alpha_render_list.clear();
- light_instance_count = 0;
- scene_fx = p_fx.is_valid() ? fx_owner.get(p_fx) : NULL;
-};
-
-void RasterizerIPhone::begin_shadow_map(RID p_light_instance, int p_shadow_pass) {
-}
-
-void RasterizerIPhone::set_camera(const Transform &p_world, const CameraMatrix &p_projection) {
-
- camera_transform = p_world;
- camera_transform_inverse = camera_transform.inverse();
- camera_projection = p_projection;
- camera_plane = Plane(camera_transform.origin, camera_transform.basis.get_axis(2));
- camera_z_near = camera_projection.get_z_near();
- camera_z_far = camera_projection.get_z_far();
- camera_projection.get_viewport_size(camera_vp_size.x, camera_vp_size.y);
-}
-
-void RasterizerIPhone::add_light(RID p_light_instance) {
-
-#define LIGHT_FADE_TRESHOLD 0.05
-
- ERR_FAIL_COND(light_instance_count >= MAX_LIGHTS);
-
- LightInstance *li = light_instance_owner.get(p_light_instance);
- ERR_FAIL_COND(!li);
-
- /* make light hash */
-
- // actually, not really a hash, but helps to sort the lights
- // and avoid recompiling redudant shader versions
-
- li->hash_aux = li->base->type;
-
- if (li->base->shadow_enabled)
- li->hash_aux |= (1 << 3);
-
- if (li->base->projector.is_valid())
- li->hash_aux |= (1 << 4);
-
- if (li->base->shadow_enabled && li->base->volumetric_enabled)
- li->hash_aux |= (1 << 5);
-
- switch (li->base->type) {
-
- case VisualServer::LIGHT_DIRECTIONAL: {
-
- Vector3 dir = li->transform.basis.get_axis(2);
- li->light_vector.x = dir.x;
- li->light_vector.y = dir.y;
- li->light_vector.z = dir.z;
-
- } break;
- case VisualServer::LIGHT_OMNI: {
-
- float radius = li->base->vars[VisualServer::LIGHT_PARAM_RADIUS];
- if (radius == 0)
- radius = 0.0001;
- li->linear_att = (1 / LIGHT_FADE_TRESHOLD) / radius;
- li->light_vector.x = li->transform.origin.x;
- li->light_vector.y = li->transform.origin.y;
- li->light_vector.z = li->transform.origin.z;
-
- } break;
- case VisualServer::LIGHT_SPOT: {
-
- float radius = li->base->vars[VisualServer::LIGHT_PARAM_RADIUS];
- if (radius == 0)
- radius = 0.0001;
- li->linear_att = (1 / LIGHT_FADE_TRESHOLD) / radius;
- li->light_vector.x = li->transform.origin.x;
- li->light_vector.y = li->transform.origin.y;
- li->light_vector.z = li->transform.origin.z;
- Vector3 dir = -li->transform.basis.get_axis(2);
- li->spot_vector.x = dir.x;
- li->spot_vector.y = dir.y;
- li->spot_vector.z = dir.z;
-
- } break;
- }
-
- light_instances[light_instance_count++] = li;
-}
-
-void RasterizerIPhone::_add_geometry(const Geometry *p_geometry, const Transform &p_world, uint32_t p_vertex_format, const RID *p_light_instances, int p_light_count, const ParamOverrideMap *p_material_overrides, const Skeleton *p_skeleton, GeometryOwner *p_owner) {
-
- Material *m = NULL;
-
- if (p_geometry->material.is_valid())
- m = material_owner.get(p_geometry->material);
-
- if (!m) {
- m = material_owner.get(default_material);
- }
-
- ERR_FAIL_COND(!m);
-
- LightInstance *lights[RenderList::MAX_LIGHTS];
- int light_count = 0;
-
- RenderList *render_list = &opaque_render_list;
- if (p_geometry->has_alpha || m->detail_blend_mode != VS::MATERIAL_BLEND_MODE_MIX) {
- render_list = &alpha_render_list;
- };
-
- if (!m->flags[VS::MATERIAL_FLAG_UNSHADED]) {
-
- light_count = p_light_count;
- for (int i = 0; i < light_count; i++) {
- lights[i] = light_instance_owner.get(p_light_instances[i]);
- }
- }
-
- render_list->add_element(p_geometry, m, p_world, lights, light_count, p_material_overrides, p_skeleton, camera_plane.distance(p_world.origin), p_owner);
-}
-
-void RasterizerIPhone::add_mesh(RID p_mesh, const Transform *p_world, const RID *p_light_instances, int p_light_count, const ParamOverrideMap *p_material_overrides, RID p_skeleton) {
-
- Mesh *mesh = mesh_owner.get(p_mesh);
-
- int ssize = mesh->surfaces.size();
-
- for (int i = 0; i < ssize; i++) {
-
- Surface *s = mesh->surfaces[i];
- Skeleton *sk = p_skeleton.is_valid() ? skeleton_owner.get(p_skeleton) : NULL;
-
- _add_geometry(s, *p_world, s->format, p_light_instances, p_light_count, p_material_overrides, sk, NULL);
- }
-
- mesh->last_pass = frame;
-}
-
-void RasterizerIPhone::add_multimesh(RID p_multimesh, const Transform *p_world, const RID *p_light_instances, int p_light_count, const ParamOverrideMap *p_material_overrides) {
-}
-
-void RasterizerIPhone::add_poly(RID p_poly, const Transform *p_world, const RID *p_light_instances, int p_light_count, const ParamOverrideMap *p_material_overrides) {
-
- Poly *p = poly_owner.get(p_poly);
- if (!p->primitives.empty()) {
- const Poly::Primitive *pp = &p->primitives[0];
-
- uint32_t format = VisualServer::ARRAY_FORMAT_VERTEX;
-
- if (!pp->normals.empty())
- format |= VisualServer::ARRAY_FORMAT_NORMAL;
- if (!pp->colors.empty())
- format |= VisualServer::ARRAY_FORMAT_COLOR;
- if (!pp->uvs.empty())
- format |= VisualServer::ARRAY_TEX_UV;
-
- _add_geometry(p, *p_world, format, p_light_instances, p_light_count, p_material_overrides, NULL, NULL);
- }
-}
-
-void RasterizerIPhone::add_beam(RID p_beam, const Transform *p_world, const RID *p_light_instances, int p_light_count, const ParamOverrideMap *p_material_overrides) {
-}
-
-void RasterizerIPhone::add_particles(RID p_particle_instance, const RID *p_light_instances, int p_light_count, const ParamOverrideMap *p_material_overrides) {
-}
-
-void RasterizerIPhone::_setup_material(const Geometry *p_geometry, const Material *p_material) {
-
- if (p_material->flags[VS::MATERIAL_FLAG_DOUBLE_SIDED])
- glDisable(GL_CULL_FACE);
- else {
- glEnable(GL_CULL_FACE);
- glCullFace((p_material->flags[VS::MATERIAL_FLAG_INVERT_FACES]) ? GL_FRONT : GL_BACK);
- }
-
- glEnable(GL_COLOR_MATERIAL); /* unused, unless color array */
- //glColorMaterial( GL_FRONT_AND_BACK, GL_DIFFUSE );
- glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
-
- ///ambient @TODO offer global ambient group option
- float ambient_rgba[4] = {
- 1,
- 1,
- 1,
- 1.0
- };
- glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, ambient_rgba);
-
- ///diffuse
- const Color &diffuse_color = p_material->parameters[VS::FIXED_MATERIAL_PARAM_DIFFUSE];
- float diffuse_rgba[4] = {
- (float)diffuse_color.r,
- (float)diffuse_color.g,
- (float)diffuse_color.b,
- (float)diffuse_color.a
- };
-
- glColor4f(diffuse_rgba[0], diffuse_rgba[1], diffuse_rgba[2], diffuse_rgba[3]);
-
- glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diffuse_rgba);
-
- //specular
-
- const Color &specular_color = p_material->parameters[VS::FIXED_MATERIAL_PARAM_SPECULAR];
- float specular_rgba[4] = {
- (float)specular_color.r,
- (float)specular_color.g,
- (float)specular_color.b,
- 1.0
- };
-
- glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specular_rgba);
-
- const Color &emission_color = p_material->parameters[VS::FIXED_MATERIAL_PARAM_EMISSION];
- float emission_rgba[4] = {
- (float)emission_color.r,
- (float)emission_color.g,
- (float)emission_color.b,
- 1.0
- };
-
- glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, emission_rgba);
-
- glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, p_material->parameters[VS::FIXED_MATERIAL_PARAM_SPECULAR_EXP]);
-
- if (p_material->flags[VS::MATERIAL_FLAG_UNSHADED]) {
- glDisable(GL_LIGHTING);
- } else {
- glEnable(GL_LIGHTING);
- glDisable(GL_LIGHTING);
- }
-
- //depth test?
- /*
- if (p_material->flags[VS::MATERIAL_FLAG_WIREFRAME])
- glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
- else
- glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
- */
- if (p_material->textures[VS::FIXED_MATERIAL_PARAM_DIFFUSE]) {
-
- Texture *texture = texture_owner.get(p_material->textures[VS::FIXED_MATERIAL_PARAM_DIFFUSE]);
- ERR_FAIL_COND(!texture);
- glActiveTexture(GL_TEXTURE0);
- glEnable(GL_TEXTURE_2D);
- glBindTexture(GL_TEXTURE_2D, texture->tex_id);
- };
-};
-
-void RasterizerIPhone::_setup_light(LightInstance *p_instance, int p_idx) {
-
- Light *ld = p_instance->base;
-
- int glid = GL_LIGHT0 + p_idx;
- glLightfv(glid, GL_AMBIENT, ld->colors[VS::LIGHT_COLOR_AMBIENT].components);
- glLightfv(glid, GL_DIFFUSE, ld->colors[VS::LIGHT_COLOR_DIFFUSE].components);
- glLightfv(glid, GL_SPECULAR, ld->colors[VS::LIGHT_COLOR_SPECULAR].components);
-
- switch (ld->type) {
-
- case VS::LIGHT_DIRECTIONAL: {
- /* This doesn't have attenuation */
-
- glMatrixMode(GL_MODELVIEW);
- glPushMatrix();
- glLoadIdentity();
- Vector3 v(0.0, 0.0, -1.0); // directional lights point up by default
- v = p_instance->transform.get_basis().xform(v);
- v = camera_transform_inverse.get_basis().xform(v);
- v.normalize(); // this sucks, so it will be optimized at some point
- v = -v;
- float lightpos[4] = { v.x, v.y, v.z, 0.0 };
-
- glLightfv(glid, GL_POSITION, lightpos); //at modelview
-
- glPopMatrix();
-
- } break;
- case VS::LIGHT_OMNI: {
-
- glLightf(glid, GL_SPOT_CUTOFF, 180.0);
- glLightf(glid, GL_CONSTANT_ATTENUATION, ld->vars[VS::LIGHT_PARAM_ATTENUATION]);
- glLightf(glid, GL_LINEAR_ATTENUATION, ld->vars[VS::LIGHT_PARAM_RADIUS]);
- glLightf(glid, GL_QUADRATIC_ATTENUATION, ld->vars[VS::LIGHT_PARAM_ENERGY]); // wut?
-
- glMatrixMode(GL_MODELVIEW);
- glPushMatrix();
- glLoadIdentity();
- Vector3 pos = p_instance->transform.get_origin();
- pos = camera_transform_inverse.xform(pos);
- float lightpos[4] = { pos.x, pos.y, pos.z, 1.0 };
- glLightfv(glid, GL_POSITION, lightpos); //at modelview
-
- glPopMatrix();
-
- } break;
- case VS::LIGHT_SPOT: {
-
- glLightf(glid, GL_SPOT_CUTOFF, ld->vars[VS::LIGHT_PARAM_SPOT_ANGLE]);
- glLightf(glid, GL_SPOT_EXPONENT, ld->vars[VS::LIGHT_PARAM_SPOT_ATTENUATION]);
- glLightf(glid, GL_CONSTANT_ATTENUATION, ld->vars[VS::LIGHT_PARAM_ATTENUATION]);
- glLightf(glid, GL_LINEAR_ATTENUATION, ld->vars[VS::LIGHT_PARAM_RADIUS]);
- glLightf(glid, GL_QUADRATIC_ATTENUATION, ld->vars[VS::LIGHT_PARAM_ENERGY]); // wut?
-
- glMatrixMode(GL_MODELVIEW);
- glPushMatrix();
- glLoadIdentity();
-
- Vector3 v(0.0, 0.0, -1.0); // directional lights point up by default
- v = p_instance->transform.get_basis().xform(v);
- v = camera_transform_inverse.get_basis().xform(v);
- v.normalize(); // this sucks, so it will be optimized at some point
- float lightdir[4] = { v.x, v.y, v.z, 1.0 };
- glLightfv(glid, GL_SPOT_DIRECTION, lightdir); //at modelview
-
- v = p_instance->transform.get_origin();
- v = camera_transform_inverse.xform(v);
- float lightpos[4] = { v.x, v.y, v.z, 1.0 };
- glLightfv(glid, GL_POSITION, lightpos); //at modelview
-
- glPopMatrix();
-
- } break;
- default: break;
- }
-};
-
-void RasterizerIPhone::_setup_lights(LightInstance **p_lights, int p_light_count) {
-
- for (int i = 0; i < MAX_LIGHTS; i++) {
-
- if (i < p_light_count) {
- glEnable(GL_LIGHT0 + i);
- _setup_light(p_lights[i], i);
- } else {
- glDisable(GL_LIGHT0 + i);
- }
- }
-}
-
-static const int gl_client_states[] = {
-
- GL_VERTEX_ARRAY,
- GL_NORMAL_ARRAY,
- -1, // ARRAY_TANGENT
- GL_COLOR_ARRAY,
- GL_TEXTURE_COORD_ARRAY, // ARRAY_TEX_UV
- GL_TEXTURE_COORD_ARRAY, // ARRAY_TEX_UV2
- -1, // ARRAY_BONES
- -1, // ARRAY_WEIGHTS
- -1, // ARRAY_INDEX
-};
-
-void RasterizerIPhone::_setup_geometry(const Geometry *p_geometry, const Material *p_material) {
-
- switch (p_geometry->type) {
-
- case Geometry::GEOMETRY_SURFACE: {
-
- Surface *surf = (Surface *)p_geometry;
- uint8_t *base = 0;
- bool use_VBO = (surf->array_local == 0);
-
- if (!use_VBO) {
-
- base = surf->array_local;
- glBindBuffer(GL_ARRAY_BUFFER, 0);
-
- } else {
-
- glBindBuffer(GL_ARRAY_BUFFER, surf->vertex_id);
- };
-
- const Surface::ArrayData *a = surf->array;
- for (int i = 0; i < VS::ARRAY_MAX; i++) {
-
- const Surface::ArrayData &ad = surf->array[i];
- if (ad.size == 0) {
- if (gl_client_states[i] != -1) {
- glDisableClientState(gl_client_states[i]);
- };
- continue; // this one is disabled.
- }
- ERR_CONTINUE(!ad.configured);
-
- if (gl_client_states[i] != -1) {
- glEnableClientState(gl_client_states[i]);
- };
-
- switch (i) {
-
- case VS::ARRAY_VERTEX:
- if (!use_VBO)
- glVertexPointer(3, GL_FLOAT, surf->stride, (GLvoid *)&base[a->ofs]);
- else if (surf->array[VS::ARRAY_BONES].size)
- glVertexPointer(3, GL_FLOAT, 0, skinned_buffer);
- else
- glVertexPointer(3, GL_FLOAT, surf->stride, (GLvoid *)a->ofs);
- break;
-
- case VS::ARRAY_NORMAL:
- if (use_VBO)
- glNormalPointer(GL_FLOAT, surf->stride, (GLvoid *)a->ofs);
- else
- glNormalPointer(GL_FLOAT, surf->stride, (GLvoid *)&base[a->ofs]);
- break;
- case VS::ARRAY_TANGENT:
- break;
- case VS::ARRAY_COLOR:
- if (use_VBO)
- glColorPointer(4, GL_UNSIGNED_BYTE, surf->stride, (GLvoid *)a->ofs);
- else
- glColorPointer(4, GL_UNSIGNED_BYTE, surf->stride, (GLvoid *)&base[a->ofs]);
- break;
- case VS::ARRAY_TEX_UV:
- case VS::ARRAY_TEX_UV2:
- if (use_VBO)
- glTexCoordPointer(2, GL_FLOAT, surf->stride, (GLvoid *)a->ofs);
- else
- glTexCoordPointer(2, GL_FLOAT, surf->stride, &base[a->ofs]);
- break;
- case VS::ARRAY_BONES:
- case VS::ARRAY_WEIGHTS:
- case VS::ARRAY_INDEX:
- break;
- };
- }
-
- // process skeleton here
-
- } break;
-
- default: break;
- };
-};
-
-static const GLenum gl_primitive[] = {
- GL_POINTS,
- GL_LINES,
- GL_LINE_STRIP,
- GL_LINE_LOOP,
- GL_TRIANGLES,
- GL_TRIANGLE_STRIP,
- GL_TRIANGLE_FAN
-};
-
-void RasterizerIPhone::_render(const Geometry *p_geometry, const Material *p_material, const Skeleton *p_skeleton) {
-
- switch (p_geometry->type) {
-
- case Geometry::GEOMETRY_SURFACE: {
-
- Surface *s = (Surface *)p_geometry;
-
- if (s->index_array_len > 0) {
-
- if (s->index_array_local) {
-
- glDrawElements(gl_primitive[s->primitive], s->index_array_len, (s->index_array_len > (1 << 8)) ? GL_UNSIGNED_SHORT : GL_UNSIGNED_BYTE, s->index_array_local);
-
- } else {
-
- glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, s->index_id);
- glDrawElements(gl_primitive[s->primitive], s->index_array_len, (s->index_array_len > (1 << 8)) ? GL_UNSIGNED_SHORT : GL_UNSIGNED_BYTE, 0);
- }
-
- } else {
-
- glDrawArrays(gl_primitive[s->primitive], 0, s->array_len);
- };
- } break;
-
- default: break;
- };
-};
-
-void RasterizerIPhone::_render_list_forward(RenderList *p_render_list) {
-
- const Material *prev_material = NULL;
- uint64_t prev_light_hash = 0;
- const Skeleton *prev_skeleton = NULL;
- const Geometry *prev_geometry = NULL;
- const ParamOverrideMap *prev_overrides = NULL; // make it different than NULL
-
- Geometry::Type prev_geometry_type = Geometry::GEOMETRY_INVALID;
-
- glMatrixMode(GL_PROJECTION);
- glLoadMatrixf(&camera_projection.matrix[0][0]);
-
- for (int i = 0; i < p_render_list->element_count; i++) {
-
- RenderList::Element *e = p_render_list->elements[i];
- const Material *material = e->material;
- uint64_t light_hash = e->light_hash;
- const Skeleton *skeleton = e->skeleton;
- const Geometry *geometry = e->geometry;
- const ParamOverrideMap *material_overrides = e->material_overrides;
-
- if (material != prev_material || geometry->type != prev_geometry_type) {
- _setup_material(e->geometry, material);
- //_setup_material_overrides(e->material,NULL,material_overrides);
- //_setup_material_skeleton(material,skeleton);
- } else {
-
- if (material_overrides != prev_overrides) {
-
- //_setup_material_overrides(e->material,prev_overrides,material_overrides);
- }
-
- if (prev_skeleton != skeleton) {
- //_setup_material_skeleton(material,skeleton);
- };
- }
-
- if (geometry != prev_geometry || geometry->type != prev_geometry_type) {
-
- _setup_geometry(geometry, material);
- };
-
- if (i == 0 || light_hash != prev_light_hash)
- _setup_lights(e->lights, e->light_count);
-
- glMatrixMode(GL_MODELVIEW);
- _gl_load_transform(camera_transform_inverse);
- _gl_mult_transform(e->transform);
-
- _render(geometry, material, skeleton);
-
- prev_material = material;
- prev_skeleton = skeleton;
- prev_geometry = geometry;
- prev_light_hash = e->light_hash;
- prev_geometry_type = geometry->type;
- prev_overrides = material_overrides;
- }
-};
-
-void RasterizerIPhone::end_scene() {
-
- glEnable(GL_BLEND);
- glDepthMask(GL_FALSE);
-
- opaque_render_list.sort_mat_light();
- _render_list_forward(&opaque_render_list);
-
- glDisable(GL_BLEND);
- glDepthMask(GL_TRUE);
-
- alpha_render_list.sort_z();
- _render_list_forward(&alpha_render_list);
-}
-void RasterizerIPhone::end_shadow_map() {
-}
-
-void RasterizerIPhone::end_frame() {
-
- //ContextGL::get_singleton()->swap_buffers();
-}
-
-/* CANVAS API */
-
-void RasterizerIPhone::canvas_begin() {
-
- glDisable(GL_CULL_FACE);
- glDisable(GL_DEPTH_TEST);
- glEnable(GL_BLEND);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glLineWidth(1.0);
- glDisable(GL_LIGHTING);
-
- glMatrixMode(GL_PROJECTION);
- glLoadIdentity();
-}
-void RasterizerIPhone::canvas_set_transparency(float p_transparency) {
-}
-
-void RasterizerIPhone::canvas_set_rect(const Rect2 &p_rect, bool p_clip) {
-
- glMatrixMode(GL_MODELVIEW);
- glLoadIdentity();
- glScalef(2.0 / window_size.x, -2.0 / window_size.y, 0);
- glTranslatef((-(window_size.x / 2.0)) + p_rect.pos.x, (-(window_size.y / 2.0)) + p_rect.pos.y, 0);
-
- if (p_clip) {
-
- glEnable(GL_SCISSOR_TEST);
- glScissor(viewport.x + p_rect.pos.x, viewport.y + (viewport.height - (p_rect.pos.y + p_rect.size.height)),
- p_rect.size.width, p_rect.size.height);
- } else {
-
- glDisable(GL_SCISSOR_TEST);
- }
-}
-void RasterizerIPhone::canvas_draw_line(const Point2 &p_from, const Point2 &p_to, const Color &p_color, float p_width) {
-
- glColor4f(1, 1, 1, 1);
-
- float verts[6] = {
- p_from.x, p_from.y, 0,
- p_to.x, p_to.y, 0
- };
-
- float colors[] = {
- p_color.r, p_color.g, p_color.b, p_color.a,
- p_color.r, p_color.g, p_color.b, p_color.a,
- };
- glLineWidth(p_width);
- _draw_primitive(2, verts, 0, colors, 0);
-}
-
-static void _draw_textured_quad(const Rect2 &p_rect, const Rect2 &p_src_region, const Size2 &p_tex_size) {
-
- float texcoords[] = {
- p_src_region.pos.x / p_tex_size.width,
- p_src_region.pos.y / p_tex_size.height,
-
- (p_src_region.pos.x + p_src_region.size.width) / p_tex_size.width,
- p_src_region.pos.y / p_tex_size.height,
-
- (p_src_region.pos.x + p_src_region.size.width) / p_tex_size.width,
- (p_src_region.pos.y + p_src_region.size.height) / p_tex_size.height,
-
- p_src_region.pos.x / p_tex_size.width,
- (p_src_region.pos.y + p_src_region.size.height) / p_tex_size.height,
- };
-
- float coords[] = {
- p_rect.pos.x, p_rect.pos.y, 0,
- p_rect.pos.x + p_rect.size.width, p_rect.pos.y, 0,
- p_rect.pos.x + p_rect.size.width, p_rect.pos.y + p_rect.size.height, 0,
- p_rect.pos.x, p_rect.pos.y + p_rect.size.height, 0
- };
-
- _draw_primitive(4, coords, 0, 0, texcoords);
-}
-
-static void _draw_quad(const Rect2 &p_rect) {
-
- float coords[] = {
- p_rect.pos.x, p_rect.pos.y, 0,
- p_rect.pos.x + p_rect.size.width, p_rect.pos.y, 0,
- p_rect.pos.x + p_rect.size.width, p_rect.pos.y + p_rect.size.height, 0,
- p_rect.pos.x, p_rect.pos.y + p_rect.size.height, 0
- };
-
- _draw_primitive(4, coords, 0, 0, 0);
-}
-
-void RasterizerIPhone::canvas_draw_rect(const Rect2 &p_rect, bool p_region, const Rect2 &p_source, bool p_tile, RID p_texture, const Color &p_modulate) {
-
- glColor4f(p_modulate.r, p_modulate.g, p_modulate.b, p_modulate.a);
-
- if (p_texture.is_valid()) {
-
- glEnable(GL_TEXTURE_2D);
- Texture *texture = texture_owner.get(p_texture);
- ERR_FAIL_COND(!texture);
- glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D, texture->tex_id);
-
- if (!p_region) {
-
- Rect2 region = Rect2(0, 0, texture->width, texture->height);
- _draw_textured_quad(p_rect, region, region.size);
-
- } else {
-
- _draw_textured_quad(p_rect, p_source, Size2(texture->width, texture->height));
- }
- } else {
-
- _draw_quad(p_rect);
- }
-}
-void RasterizerIPhone::canvas_draw_style_box(const Rect2 &p_rect, const Rect2 &p_src_region, RID p_texture, const float *p_margin, bool p_draw_center) {
-
- glColor4f(1, 1, 1, 1);
-
- Texture *texture = texture_owner.get(p_texture);
- ERR_FAIL_COND(!texture);
-
- glEnable(GL_TEXTURE_2D);
- glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D, texture->tex_id);
-
- Rect2 region = p_src_region;
- if (region.size.width <= 0)
- region.size.width = texture->width;
- if (region.size.height <= 0)
- region.size.height = texture->height;
- /* CORNERS */
- _draw_textured_quad( // top left
- Rect2(p_rect.pos, Size2(p_margin[MARGIN_LEFT], p_margin[MARGIN_TOP])),
- Rect2(region.pos, Size2(p_margin[MARGIN_LEFT], p_margin[MARGIN_TOP])),
- Size2(texture->width, texture->height));
-
- _draw_textured_quad( // top right
- Rect2(Point2(p_rect.pos.x + p_rect.size.width - p_margin[MARGIN_RIGHT], p_rect.pos.y), Size2(p_margin[MARGIN_RIGHT], p_margin[MARGIN_TOP])),
- Rect2(Point2(region.pos.x + region.size.width - p_margin[MARGIN_RIGHT], region.pos.y), Size2(p_margin[MARGIN_RIGHT], p_margin[MARGIN_TOP])),
- Size2(texture->width, texture->height));
-
- _draw_textured_quad( // bottom left
- Rect2(Point2(p_rect.pos.x, p_rect.pos.y + p_rect.size.height - p_margin[MARGIN_BOTTOM]), Size2(p_margin[MARGIN_LEFT], p_margin[MARGIN_BOTTOM])),
- Rect2(Point2(region.pos.x, region.pos.y + region.size.height - p_margin[MARGIN_BOTTOM]), Size2(p_margin[MARGIN_LEFT], p_margin[MARGIN_BOTTOM])),
- Size2(texture->width, texture->height));
-
- _draw_textured_quad( // bottom right
- Rect2(Point2(p_rect.pos.x + p_rect.size.width - p_margin[MARGIN_RIGHT], p_rect.pos.y + p_rect.size.height - p_margin[MARGIN_BOTTOM]), Size2(p_margin[MARGIN_RIGHT], p_margin[MARGIN_BOTTOM])),
- Rect2(Point2(region.pos.x + region.size.width - p_margin[MARGIN_RIGHT], region.pos.y + region.size.height - p_margin[MARGIN_BOTTOM]), Size2(p_margin[MARGIN_RIGHT], p_margin[MARGIN_BOTTOM])),
- Size2(texture->width, texture->height));
-
- Rect2 rect_center(p_rect.pos + Point2(p_margin[MARGIN_LEFT], p_margin[MARGIN_TOP]), Size2(p_rect.size.width - p_margin[MARGIN_LEFT] - p_margin[MARGIN_RIGHT], p_rect.size.height - p_margin[MARGIN_TOP] - p_margin[MARGIN_BOTTOM]));
-
- Rect2 src_center(Point2(region.pos.x + p_margin[MARGIN_LEFT], region.pos.y + p_margin[MARGIN_TOP]), Size2(region.size.width - p_margin[MARGIN_LEFT] - p_margin[MARGIN_RIGHT], region.size.height - p_margin[MARGIN_TOP] - p_margin[MARGIN_BOTTOM]));
-
- _draw_textured_quad( // top
- Rect2(Point2(rect_center.pos.x, p_rect.pos.y), Size2(rect_center.size.width, p_margin[MARGIN_TOP])),
- Rect2(Point2(src_center.pos.x, region.pos.y), Size2(src_center.size.width, p_margin[MARGIN_TOP])),
- Size2(texture->width, texture->height));
-
- _draw_textured_quad( // bottom
- Rect2(Point2(rect_center.pos.x, rect_center.pos.y + rect_center.size.height), Size2(rect_center.size.width, p_margin[MARGIN_BOTTOM])),
- Rect2(Point2(src_center.pos.x, src_center.pos.y + src_center.size.height), Size2(src_center.size.width, p_margin[MARGIN_BOTTOM])),
- Size2(texture->width, texture->height));
-
- _draw_textured_quad( // left
- Rect2(Point2(p_rect.pos.x, rect_center.pos.y), Size2(p_margin[MARGIN_LEFT], rect_center.size.height)),
- Rect2(Point2(region.pos.x, region.pos.y + p_margin[MARGIN_TOP]), Size2(p_margin[MARGIN_LEFT], src_center.size.height)),
- Size2(texture->width, texture->height));
-
- _draw_textured_quad( // right
- Rect2(Point2(rect_center.pos.x + rect_center.size.width, rect_center.pos.y), Size2(p_margin[MARGIN_RIGHT], rect_center.size.height)),
- Rect2(Point2(src_center.pos.x + src_center.size.width, region.pos.y + p_margin[MARGIN_TOP]), Size2(p_margin[MARGIN_RIGHT], src_center.size.height)),
- Size2(texture->width, texture->height));
-
- if (p_draw_center) {
-
- _draw_textured_quad(
- rect_center,
- src_center,
- Size2(texture->width, texture->height));
- }
-}
-void RasterizerIPhone::canvas_draw_primitive(const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, RID p_texture) {
-
- ERR_FAIL_COND(p_points.size() < 1);
- float verts[12];
- float uvs[8];
- float colors[16];
-
- glColor4f(1, 1, 1, 1);
-
- int idx = 0;
- for (int i = 0; i < p_points.size(); i++) {
-
- verts[idx++] = p_points[i].x;
- verts[idx++] = p_points[i].y;
- verts[idx++] = 0;
- }
-
- idx = 0;
- for (int i = 0; i < p_uvs.size(); i++) {
-
- uvs[idx++] = p_uvs[i].x;
- uvs[idx++] = p_uvs[i].y;
- }
-
- idx = 0;
- for (int i = 0; i < p_colors.size(); i++) {
-
- colors[idx++] = p_colors[i].r;
- colors[idx++] = p_colors[i].g;
- colors[idx++] = p_colors[i].b;
- colors[idx++] = p_colors[i].a;
- };
-
- if (p_texture.is_valid()) {
- glEnable(GL_TEXTURE_2D);
- Texture *texture = texture_owner.get(p_texture);
- if (texture) {
- glActiveTexture(GL_TEXTURE0);
- glBindTexture(GL_TEXTURE_2D, texture->tex_id);
- }
- }
-
- _draw_primitive(p_points.size(), &verts[0], NULL, p_colors.size() ? &colors[0] : NULL, p_uvs.size() ? uvs : NULL);
-}
-
-/* FX */
-
-RID RasterizerIPhone::fx_create() {
-
- return RID();
-}
-void RasterizerIPhone::fx_get_effects(RID p_fx, List<String> *p_effects) const {
-}
-void RasterizerIPhone::fx_set_active(RID p_fx, const String &p_effect, bool p_active) {
-}
-bool RasterizerIPhone::fx_is_active(RID p_fx, const String &p_effect) const {
-
- return false;
-}
-void RasterizerIPhone::fx_get_effect_params(RID p_fx, const String &p_effect, List<PropertyInfo> *p_params) const {
-}
-Variant RasterizerIPhone::fx_get_effect_param(RID p_fx, const String &p_effect, const String &p_param) const {
-
- return Variant();
-}
-void RasterizerIPhone::fx_set_effect_param(RID p_fx, const String &p_effect, const String &p_param, const Variant &p_pvalue) {
-}
-
-/*MISC*/
-
-bool RasterizerIPhone::is_texture(const RID &p_rid) const {
-
- return texture_owner.owns(p_rid);
-}
-bool RasterizerIPhone::is_material(const RID &p_rid) const {
-
- return material_owner.owns(p_rid);
-}
-bool RasterizerIPhone::is_mesh(const RID &p_rid) const {
-
- return mesh_owner.owns(p_rid);
-}
-bool RasterizerIPhone::is_multimesh(const RID &p_rid) const {
-
- return false;
-}
-bool RasterizerIPhone::is_poly(const RID &p_rid) const {
-
- return poly_owner.owns(p_rid);
-}
-bool RasterizerIPhone::is_particles(const RID &p_beam) const {
-
- return false;
-}
-
-bool RasterizerIPhone::is_beam(const RID &p_beam) const {
-
- return false;
-}
-
-bool RasterizerIPhone::is_light(const RID &p_rid) const {
-
- return light_owner.owns(p_rid);
-}
-bool RasterizerIPhone::is_light_instance(const RID &p_rid) const {
-
- return light_instance_owner.owns(p_rid);
-}
-bool RasterizerIPhone::is_particles_instance(const RID &p_rid) const {
-
- return false;
-}
-bool RasterizerIPhone::is_skeleton(const RID &p_rid) const {
-
- return skeleton_owner.owns(p_rid);
-}
-bool RasterizerIPhone::is_fx(const RID &p_rid) const {
-
- return fx_owner.owns(p_rid);
-}
-bool RasterizerIPhone::is_shader(const RID &p_rid) const {
-
- return false;
-}
-
-void RasterizerIPhone::free(const RID &p_rid) const {
-
- if (texture_owner.owns(p_rid)) {
-
- // delete the texture
- Texture *texture = texture_owner.get(p_rid);
-
- glDeleteTextures(1, &texture->tex_id);
-
- texture_owner.free(p_rid);
- memdelete(texture);
-
- } else if (material_owner.owns(p_rid)) {
-
- Material *material = material_owner.get(p_rid);
- ERR_FAIL_COND(!material);
-
- material_owner.free(p_rid);
- memdelete(material);
-
- } else if (mesh_owner.owns(p_rid)) {
-
- Mesh *mesh = mesh_owner.get(p_rid);
- ERR_FAIL_COND(!mesh);
- for (int i = 0; i < mesh->surfaces.size(); i++) {
-
- Surface *surface = mesh->surfaces[i];
- if (surface->array_local != 0) {
- memfree(surface->array_local);
- };
- if (surface->index_array_local != 0) {
- memfree(surface->index_array_local);
- };
-
- if (surface->vertex_id)
- glDeleteBuffers(1, &surface->vertex_id);
- if (surface->index_id)
- glDeleteBuffers(1, &surface->index_id);
-
- memdelete(surface);
- };
-
- mesh->surfaces.clear();
-
- mesh_owner.free(p_rid);
- memdelete(mesh);
-
- } else if (skeleton_owner.owns(p_rid)) {
-
- Skeleton *skeleton = skeleton_owner.get(p_rid);
- ERR_FAIL_COND(!skeleton)
-
- skeleton_owner.free(p_rid);
- memdelete(skeleton);
-
- } else if (light_owner.owns(p_rid)) {
-
- Light *light = light_owner.get(p_rid);
- ERR_FAIL_COND(!light)
-
- light_owner.free(p_rid);
- memdelete(light);
-
- } else if (light_instance_owner.owns(p_rid)) {
-
- LightInstance *light_instance = light_instance_owner.get(p_rid);
- ERR_FAIL_COND(!light_instance);
-
- light_instance_owner.free(p_rid);
- memdelete(light_instance);
-
- } else if (fx_owner.owns(p_rid)) {
-
- FX *fx = fx_owner.get(p_rid);
- ERR_FAIL_COND(!fx);
-
- fx_owner.free(p_rid);
- memdelete(fx);
- };
-}
-
-void RasterizerIPhone::init() {
-
- glEnable(GL_DEPTH_TEST);
- glDepthFunc(GL_LEQUAL);
- glFrontFace(GL_CW);
-
- glEnable(GL_TEXTURE_2D);
-}
-
-void RasterizerIPhone::finish() {
-}
-
-int RasterizerIPhone::get_render_info(VS::RenderInfo p_info) {
-
- return false;
-}
-
-RasterizerIPhone::RasterizerIPhone() {
-
- frame = 0;
-};
-
-RasterizerIPhone::~RasterizerIPhone(){
-
-};
-
-#endif
diff --git a/platform/iphone/rasterizer_iphone.h b/platform/iphone/rasterizer_iphone.h
deleted file mode 100644
index 02cb985dc8..0000000000
--- a/platform/iphone/rasterizer_iphone.h
+++ /dev/null
@@ -1,880 +0,0 @@
-/*************************************************************************/
-/* rasterizer_iphone.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* http://www.godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
-/* */
-/* 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 IPHONE_ENABLED
-
-#ifndef RASTERIZER_IPHONE_H
-#define RASTERIZER_IPHONE_H
-
-#include "servers/visual/rasterizer.h"
-
-#include "camera_matrix.h"
-#include "image.h"
-#include "list.h"
-#include "map.h"
-#include "rid.h"
-#include "servers/visual_server.h"
-#include "sort.h"
-#include <ES1/gl.h>
-
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-class RasterizerIPhone : public Rasterizer {
-
- enum {
- SKINNED_BUFFER_SIZE = 1024 * 128, // 10k vertices
- MAX_LIGHTS = 8,
- };
-
- uint8_t skinned_buffer[SKINNED_BUFFER_SIZE];
-
- struct Texture {
-
- uint32_t flags;
- int width, height;
- Image::Format format;
-
- GLenum target;
- GLenum gl_format_cache;
- int gl_components_cache;
- bool has_alpha;
- bool format_has_alpha;
-
- bool active;
- GLuint tex_id;
- bool mipmap_dirty;
-
- Texture() {
-
- flags = width = height = 0;
- tex_id = 0;
- format = Image::FORMAT_L8;
- gl_components_cache = 0;
- format_has_alpha = false;
- has_alpha = false;
- active = false;
- mipmap_dirty = true;
- }
-
- ~Texture() {
-
- if (tex_id != 0) {
-
- glDeleteTextures(1, &tex_id);
- }
- }
- };
-
- mutable RID_Owner<Texture> texture_owner;
-
- struct Material {
-
- bool flags[VS::MATERIAL_FLAG_MAX];
- Variant parameters[VisualServer::FIXED_MATERIAL_PARAM_MAX];
- RID textures[VisualServer::FIXED_MATERIAL_PARAM_MAX];
-
- Transform uv_transform;
- VS::FixedSpatialMaterialTexCoordMode texcoord_mode[VisualServer::FIXED_MATERIAL_PARAM_MAX];
-
- VS::MaterialBlendMode detail_blend_mode;
-
- VS::FixedSpatialMaterialTexGenMode texgen_mode;
-
- Material() {
-
- flags[VS::MATERIAL_FLAG_VISIBLE] = true;
- flags[VS::MATERIAL_FLAG_DOUBLE_SIDED] = false;
- flags[VS::MATERIAL_FLAG_INVERT_FACES] = false;
- flags[VS::MATERIAL_FLAG_UNSHADED] = false;
- flags[VS::MATERIAL_FLAG_WIREFRAME] = false;
-
- parameters[VS::FIXED_MATERIAL_PARAM_DIFFUSE] = Color(0.8, 0.8, 0.8);
- parameters[VS::FIXED_MATERIAL_PARAM_SPECULAR_EXP] = 12;
-
- for (int i = 0; i < VisualServer::FIXED_MATERIAL_PARAM_MAX; i++) {
- texcoord_mode[i] = VS::FIXED_MATERIAL_TEXCOORD_UV;
- };
- detail_blend_mode = VS::MATERIAL_BLEND_MODE_MIX;
- texgen_mode = VS::FIXED_MATERIAL_TEXGEN_SPHERE;
- }
- };
- mutable RID_Owner<Material> material_owner;
-
- struct Geometry {
-
- enum Type {
- GEOMETRY_INVALID,
- GEOMETRY_SURFACE,
- GEOMETRY_POLY,
- GEOMETRY_PARTICLES,
- GEOMETRY_BEAM,
- GEOMETRY_DETAILER,
- };
-
- Type type;
- RID material;
- bool has_alpha;
- bool material_owned;
-
- Vector3 scale;
- Vector3 uv_scale;
-
- Geometry()
- : scale(1, 1, 1) {
- has_alpha = false;
- material_owned = false;
- }
- virtual ~Geometry(){};
- };
-
- struct GeometryOwner {
-
- virtual ~GeometryOwner() {}
- };
-
- struct Surface : public Geometry {
-
- struct ArrayData {
-
- uint32_t ofs, size;
- bool configured;
- int components;
- ArrayData() {
- ofs = 0;
- size = 0;
- configured = false;
- }
- };
-
- ArrayData array[VS::ARRAY_MAX];
- // support for vertex array objects
- GLuint array_object_id;
- // support for vertex buffer object
- GLuint vertex_id; // 0 means, unconfigured
- GLuint index_id; // 0 means, unconfigured
- // no support for the above, array in localmem.
- uint8_t *array_local;
- uint8_t *index_array_local;
-
- AABB aabb;
-
- int array_len;
- int index_array_len;
-
- VS::PrimitiveType primitive;
-
- uint32_t format;
-
- int stride;
-
- bool active;
-
- Point2 uv_min;
- Point2 uv_max;
-
- bool has_alpha_cache;
-
- Surface() {
-
- array_len = 0;
- type = GEOMETRY_SURFACE;
- primitive = VS::PRIMITIVE_POINTS;
- index_array_len = VS::NO_INDEX_ARRAY;
- format = 0;
- stride = 0;
-
- array_local = index_array_local = 0;
- vertex_id = index_id = 0;
-
- active = false;
- }
-
- ~Surface() {
- }
- };
-
- struct Mesh {
-
- bool active;
- Vector<Surface *> surfaces;
-
- mutable uint64_t last_pass;
- Mesh() {
- last_pass = 0;
- active = false;
- }
- };
- mutable RID_Owner<Mesh> mesh_owner;
-
- struct Poly : public Geometry {
-
- struct Primitive {
-
- Vector<Vector3> vertices;
- Vector<Vector3> normals;
- Vector<Vector3> uvs;
- Vector<Color> colors;
- };
-
- AABB aabb;
- List<Primitive> primitives;
- Poly() {
-
- type = GEOMETRY_POLY;
- }
- };
-
- mutable RID_Owner<Poly> poly_owner;
-
- struct Skeleton {
-
- Vector<Transform> bones;
- };
-
- mutable RID_Owner<Skeleton> skeleton_owner;
-
- struct Light {
-
- VS::LightType type;
- float vars[VS::LIGHT_PARAM_MAX];
- Color colors[3];
- bool shadow_enabled;
- RID projector;
- bool volumetric_enabled;
- Color volumetric_color;
-
- Light() {
-
- vars[VS::LIGHT_PARAM_SPOT_ATTENUATION] = 1;
- vars[VS::LIGHT_PARAM_SPOT_ANGLE] = 45;
- vars[VS::LIGHT_PARAM_ATTENUATION] = 1.0;
- vars[VS::LIGHT_PARAM_ENERGY] = 1.0;
- vars[VS::LIGHT_PARAM_RADIUS] = 1.0;
- colors[VS::LIGHT_COLOR_AMBIENT] = Color(0, 0, 0);
- colors[VS::LIGHT_COLOR_DIFFUSE] = Color(1, 1, 1);
- colors[VS::LIGHT_COLOR_SPECULAR] = Color(1, 1, 1);
- shadow_enabled = false;
- volumetric_enabled = false;
- }
- };
-
- struct ShadowBuffer;
-
- struct LightInstance {
-
- struct SplitInfo {
-
- CameraMatrix camera;
- Transform transform;
- float near;
- float far;
- };
-
- RID light;
- Light *base;
- uint64_t last_pass;
- Transform transform;
-
- CameraMatrix projection;
- Vector<SplitInfo> splits;
-
- Vector3 light_vector;
- Vector3 spot_vector;
- float linear_att;
-
- uint64_t hash_aux;
- };
- mutable RID_Owner<Light> light_owner;
- mutable RID_Owner<LightInstance> light_instance_owner;
-
- LightInstance *light_instances[MAX_LIGHTS];
- int light_instance_count;
-
- struct RenderList {
-
- enum {
- MAX_ELEMENTS = 4096,
- MAX_LIGHTS = 4
- };
-
- struct Element {
-
- float depth;
- const Skeleton *skeleton;
- Transform transform;
- LightInstance *lights[MAX_LIGHTS];
- int light_count;
- const Geometry *geometry;
- const Material *material;
- uint64_t light_hash;
- GeometryOwner *owner;
- const ParamOverrideMap *material_overrides;
- };
-
- Element _elements[MAX_ELEMENTS];
- Element *elements[MAX_ELEMENTS];
- int element_count;
-
- void clear() {
-
- element_count = 0;
- }
-
- struct SortZ {
-
- _FORCE_INLINE_ bool operator()(const Element *A, const Element *B) const {
-
- return A->depth > B->depth;
- }
- };
-
- void sort_z() {
-
- SortArray<Element *, SortZ> sorter;
- sorter.sort(elements, element_count);
- }
-
- struct SortSkel {
-
- _FORCE_INLINE_ bool operator()(const Element *A, const Element *B) const {
-
- if (A->geometry < B->geometry)
- return true;
- else if (A->geometry > B->geometry)
- return false;
- else
- return (!A->skeleton && B->skeleton);
- }
- };
-
- void sort_skel() {
-
- SortArray<Element *, SortSkel> sorter;
- sorter.sort(elements, element_count);
- }
-
- struct SortMat {
-
- _FORCE_INLINE_ bool operator()(const Element *A, const Element *B) const {
-
- if (A->geometry == B->geometry) {
-
- if (A->material == B->material) {
-
- return (A->material_overrides < B->material_overrides);
- } else {
-
- return (A->material < B->material);
- }
- } else {
-
- return (A->geometry < B->geometry);
- }
- }
- };
-
- void sort_mat() {
-
- SortArray<Element *, SortMat> sorter;
- sorter.sort(elements, element_count);
- }
-
- struct SortMatLight {
-
- _FORCE_INLINE_ bool operator()(const Element *A, const Element *B) const {
-
- if (A->geometry == B->geometry) {
-
- if (A->material == B->material) {
-
- if (A->light_hash == B->light_hash)
- return (A->material_overrides < B->material_overrides);
- else
- return A->light_hash < B->light_hash;
- } else {
-
- return (A->material < B->material);
- }
- } else {
-
- return (A->geometry < B->geometry);
- }
- }
- };
-
- void sort_mat_light() {
-
- SortArray<Element *, SortMatLight> sorter;
- sorter.sort(elements, element_count);
- }
-
- struct LISort {
-
- _FORCE_INLINE_ bool operator()(const LightInstance *A, const LightInstance *B) const {
-
- return (A->hash_aux < B->hash_aux);
- }
- };
-
- _FORCE_INLINE_ void add_element(const Geometry *p_geometry, const Material *p_material, const Transform &p_transform, LightInstance **p_light_instances, int p_light_count, const ParamOverrideMap *p_material_overrides, const Skeleton *p_skeleton, float p_depth, GeometryOwner *p_owner = NULL) {
-
- ERR_FAIL_COND(element_count >= MAX_ELEMENTS);
- Element *e = elements[element_count++];
-
- e->geometry = p_geometry;
- e->material = p_material;
- e->transform = p_transform;
- e->skeleton = p_skeleton;
- e->light_hash = 0;
- e->light_count = p_light_count;
- e->owner = p_owner;
- e->material_overrides = p_material_overrides;
-
- if (e->light_count > 0) {
-
- SortArray<LightInstance *, LISort> light_sort;
- light_sort.sort(p_light_instances, p_light_count);
- //@TODO OPTIOMIZE
-
- for (int i = 0; i < p_light_count; i++) {
-
- e->lights[i] = p_light_instances[i];
-
- if (i == 0)
- e->light_hash = hash_djb2_one_64(make_uint64_t(e->lights[i]));
- else
- e->light_hash = hash_djb2_one_64(make_uint64_t(e->lights[i]), e->light_hash);
- }
- }
- }
-
- RenderList() {
-
- for (int i = 0; i < MAX_ELEMENTS; i++)
- elements[i] = &_elements[i]; // assign elements
- }
- };
-
- RenderList opaque_render_list;
- RenderList alpha_render_list;
-
- RID default_material;
-
- struct FX {
-
- bool bgcolor_active;
- Color bgcolor;
-
- bool skybox_active;
- RID skybox_cubemap;
-
- bool antialias_active;
- float antialias_tolerance;
-
- bool glow_active;
- int glow_passes;
- float glow_attenuation;
- float glow_bloom;
-
- bool ssao_active;
- float ssao_attenuation;
- float ssao_radius;
- float ssao_max_distance;
- float ssao_range_max;
- float ssao_range_min;
- bool ssao_only;
-
- bool fog_active;
- float fog_distance;
- float fog_attenuation;
- Color fog_color_near;
- Color fog_color_far;
- bool fog_bg;
-
- bool toon_active;
- float toon_treshold;
- float toon_soft;
-
- bool edge_active;
- Color edge_color;
- float edge_size;
-
- FX();
- };
- mutable RID_Owner<FX> fx_owner;
-
- FX *scene_fx;
- CameraMatrix camera_projection;
- Transform camera_transform;
- Transform camera_transform_inverse;
- float camera_z_near;
- float camera_z_far;
- Size2 camera_vp_size;
-
- Plane camera_plane;
-
- void _add_geometry(const Geometry *p_geometry, const Transform &p_world, uint32_t p_vertex_format, const RID *p_light_instances, int p_light_count, const ParamOverrideMap *p_material_overrides, const Skeleton *p_skeleton, GeometryOwner *p_owner);
- void _render_list_forward(RenderList *p_render_list);
-
- void _setup_light(LightInstance *p_instance, int p_idx);
- void _setup_lights(LightInstance **p_lights, int p_light_count);
- void _setup_material(const Geometry *p_geometry, const Material *p_material);
-
- void _setup_geometry(const Geometry *p_geometry, const Material *p_material);
- void _render(const Geometry *p_geometry, const Material *p_material, const Skeleton *p_skeleton);
-
- /*********/
- /* FRAME */
- /*********/
-
- Size2 window_size;
- VS::ViewportRect viewport;
- Transform canvas_transform;
- double last_time;
- double time_delta;
- uint64_t frame;
-
-public:
- /* TEXTURE API */
-
- virtual RID texture_create();
- virtual void texture_allocate(RID p_texture, int p_width, int p_height, Image::Format p_format, uint32_t p_flags = VS::TEXTURE_FLAGS_DEFAULT);
- virtual void texture_blit_rect(RID p_texture, int p_x, int p_y, const Image &p_image, VS::CubeMapSide p_cube_side = VS::CUBEMAP_LEFT);
- virtual Image texture_get_rect(RID p_texture, int p_x, int p_y, int p_width, int p_height, VS::CubeMapSide p_cube_side = VS::CUBEMAP_LEFT) const;
- virtual void texture_set_flags(RID p_texture, uint32_t p_flags);
- virtual uint32_t texture_get_flags(RID p_texture) const;
- virtual Image::Format texture_get_format(RID p_texture) const;
- virtual uint32_t texture_get_width(RID p_texture) const;
- virtual uint32_t texture_get_height(RID p_texture) const;
- virtual bool texture_has_alpha(RID p_texture) const;
-
- /* SHADER API */
-
- virtual RID shader_create();
-
- virtual void shader_node_add(RID p_shader, VS::ShaderNodeType p_type, int p_id);
- virtual void shader_node_remove(RID p_shader, int p_id);
- virtual void shader_node_change_type(RID p_shader, int p_id, VS::ShaderNodeType p_type);
- virtual void shader_node_set_param(RID p_shader, int p_id, const Variant &p_value);
-
- virtual void shader_get_node_list(RID p_shader, List<int> *p_node_list) const;
- virtual VS::ShaderNodeType shader_node_get_type(RID p_shader, int p_id) const;
- virtual Variant shader_node_get_param(RID p_shader, int p_id) const;
-
- virtual void shader_connect(RID p_shader, int p_src_id, int p_src_slot, int p_dst_id, int p_dst_slot);
- virtual bool shader_is_connected(RID p_shader, int p_src_id, int p_src_slot, int p_dst_id, int p_dst_slot) const;
- virtual void shader_disconnect(RID p_shader, int p_src_id, int p_src_slot, int p_dst_id, int p_dst_slot);
-
- virtual void shader_get_connections(RID p_shader, List<VS::ShaderConnection> *p_connections) const;
-
- virtual void shader_clear(RID p_shader);
-
- /* COMMON MATERIAL API */
-
- virtual void material_set_param(RID p_material, const StringName &p_param, const Variant &p_value);
- virtual Variant material_get_param(RID p_material, const StringName &p_param) const;
- virtual void material_get_param_list(RID p_material, List<String> *p_param_list) const;
-
- virtual void material_set_flag(RID p_material, VS::MaterialFlag p_flag, bool p_enabled);
- virtual bool material_get_flag(RID p_material, VS::MaterialFlag p_flag) const;
-
- virtual void material_set_blend_mode(RID p_material, VS::MaterialBlendMode p_mode);
- virtual VS::MaterialBlendMode material_get_blend_mode(RID p_material) const;
-
- virtual void material_set_line_width(RID p_material, float p_line_width);
- virtual float material_get_line_width(RID p_material) const;
-
- /* FIXED MATERIAL */
-
- virtual RID material_create();
-
- virtual void fixed_material_set_parameter(RID p_material, VS::FixedSpatialMaterialParam p_parameter, const Variant &p_value);
- virtual Variant fixed_material_get_parameter(RID p_material, VS::FixedSpatialMaterialParam p_parameter) const;
-
- virtual void fixed_material_set_texture(RID p_material, VS::FixedSpatialMaterialParam p_parameter, RID p_texture);
- virtual RID fixed_material_get_texture(RID p_material, VS::FixedSpatialMaterialParam p_parameter) const;
-
- virtual void fixed_material_set_detail_blend_mode(RID p_material, VS::MaterialBlendMode p_mode);
- virtual VS::MaterialBlendMode fixed_material_get_detail_blend_mode(RID p_material) const;
-
- virtual void fixed_material_set_texgen_mode(RID p_material, VS::FixedSpatialMaterialTexGenMode p_mode);
- virtual VS::FixedSpatialMaterialTexGenMode fixed_material_get_texgen_mode(RID p_material) const;
-
- virtual void fixed_material_set_texcoord_mode(RID p_material, VS::FixedSpatialMaterialParam p_parameter, VS::FixedSpatialMaterialTexCoordMode p_mode);
- virtual VS::FixedSpatialMaterialTexCoordMode fixed_material_get_texcoord_mode(RID p_material, VS::FixedSpatialMaterialParam p_parameter) const;
-
- virtual void fixed_material_set_uv_transform(RID p_material, const Transform &p_transform);
- virtual Transform fixed_material_get_uv_transform(RID p_material) const;
-
- /* SHADER MATERIAL */
-
- virtual RID shader_material_create() const;
-
- virtual void shader_material_set_vertex_shader(RID p_material, RID p_shader, bool p_owned = false);
- virtual RID shader_material_get_vertex_shader(RID p_material) const;
-
- virtual void shader_material_set_fragment_shader(RID p_material, RID p_shader, bool p_owned = false);
- virtual RID shader_material_get_fragment_shader(RID p_material) const;
-
- /* MESH API */
-
- virtual RID mesh_create();
-
- virtual void mesh_add_surface(RID p_mesh, VS::PrimitiveType p_primitive, uint32_t p_format, int p_array_len, int p_index_array_len = VS::NO_INDEX_ARRAY);
-
- virtual Error mesh_surface_set_array(RID p_mesh, int p_surface, VS::ArrayType p_type, const Variant &p_array);
- virtual Variant mesh_surface_get_array(RID p_mesh, int p_surface, VS::ArrayType p_type) const;
-
- virtual void mesh_surface_set_material(RID p_mesh, int p_surface, RID p_material, bool p_owned = false);
- virtual RID mesh_surface_get_material(RID p_mesh, int p_surface) const;
-
- virtual int mesh_surface_get_array_len(RID p_mesh, int p_surface) const;
- virtual int mesh_surface_get_array_index_len(RID p_mesh, int p_surface) const;
- virtual uint32_t mesh_surface_get_format(RID p_mesh, int p_surface) const;
- virtual VS::PrimitiveType mesh_surface_get_primitive_type(RID p_mesh, int p_surface) const;
-
- virtual void mesh_erase_surface(RID p_mesh, int p_index);
- virtual int mesh_get_surface_count(RID p_mesh) const;
-
- virtual AABB mesh_get_aabb(RID p_mesh) const;
-
- /* MULTIMESH API */
-
- virtual RID multimesh_create();
-
- virtual void multimesh_set_instance_count(RID p_multimesh, int p_count);
- virtual int multimesh_get_instance_count(RID p_multimesh) const;
-
- virtual void multimesh_set_mesh(RID p_multimesh, RID p_mesh);
- virtual void multimesh_set_aabb(RID p_multimesh, const AABB &p_aabb);
- virtual void multimesh_instance_set_transform(RID p_multimesh, int p_index, const Transform &p_transform);
- virtual void multimesh_instance_set_color(RID p_multimesh, int p_index, const Color &p_color);
-
- virtual RID multimesh_get_mesh(RID p_multimesh) const;
- virtual AABB multimesh_get_aabb(RID p_multimesh) const;
-
- virtual Transform multimesh_instance_get_transform(RID p_multimesh, int p_index) const;
- virtual Color multimesh_instance_get_color(RID p_multimesh, int p_index) const;
-
- /* POLY API */
-
- virtual RID poly_create();
- virtual void poly_set_material(RID p_poly, RID p_material, bool p_owned = false);
- virtual void poly_add_primitive(RID p_poly, const Vector<Vector3> &p_points, const Vector<Vector3> &p_normals, const Vector<Color> &p_colors, const Vector<Vector3> &p_uvs);
- virtual void poly_clear(RID p_poly);
-
- virtual AABB poly_get_aabb(RID p_poly) const;
-
- /* PARTICLES API */
-
- virtual RID particles_create();
-
- virtual void particles_set_amount(RID p_particles, int p_amount);
- virtual int particles_get_amount(RID p_particles) const;
-
- virtual void particles_set_emitting(RID p_particles, bool p_emitting);
- virtual bool particles_is_emitting(RID p_particles) const;
-
- virtual void particles_set_visibility_aabb(RID p_particles, const AABB &p_visibility);
- virtual AABB particles_get_visibility_aabb(RID p_particles) const;
-
- virtual void particles_set_emission_half_extents(RID p_particles, const Vector3 &p_half_extents);
- virtual Vector3 particles_get_emission_half_extents(RID p_particles) const;
-
- virtual void particles_set_gravity_normal(RID p_particles, const Vector3 &p_normal);
- virtual Vector3 particles_get_gravity_normal(RID p_particles) const;
-
- virtual void particles_set_variable(RID p_particles, VS::ParticleVariable p_variable, float p_value);
- virtual float particles_get_variable(RID p_particles, VS::ParticleVariable p_variable) const;
-
- virtual void particles_set_randomness(RID p_particles, VS::ParticleVariable p_variable, float p_randomness);
- virtual float particles_get_randomness(RID p_particles, VS::ParticleVariable p_variable) const;
-
- virtual void particles_set_color_phase_pos(RID p_particles, int p_phase, float p_pos);
- virtual float particles_get_color_phase_pos(RID p_particles, int p_phase) const;
-
- virtual void particles_set_color_phases(RID p_particles, int p_phases);
- virtual int particles_get_color_phases(RID p_particles) const;
-
- virtual void particles_set_color_phase_color(RID p_particles, int p_phase, const Color &p_color);
- virtual Color particles_get_color_phase_color(RID p_particles, int p_phase) const;
-
- virtual void particles_set_attractors(RID p_particles, int p_attractors);
- virtual int particles_get_attractors(RID p_particles) const;
-
- virtual void particles_set_attractor_pos(RID p_particles, int p_attractor, const Vector3 &p_pos);
- virtual Vector3 particles_get_attractor_pos(RID p_particles, int p_attractor) const;
-
- virtual void particles_set_attractor_strength(RID p_particles, int p_attractor, float p_force);
- virtual float particles_get_attractor_strength(RID p_particles, int p_attractor) const;
-
- virtual void particles_set_material(RID p_particles, RID p_material, bool p_owned = false);
- virtual RID particles_get_material(RID p_particles) const;
-
- virtual AABB particles_get_aabb(RID p_particles) const;
- /* BEAM API */
-
- virtual RID beam_create();
-
- virtual void beam_set_point_count(RID p_beam, int p_count);
- virtual int beam_get_point_count(RID p_beam) const;
- virtual void beam_clear(RID p_beam);
-
- virtual void beam_set_point(RID p_beam, int p_point, Vector3 &p_pos);
- virtual Vector3 beam_get_point(RID p_beam, int p_point) const;
-
- virtual void beam_set_primitive(RID p_beam, VS::BeamPrimitive p_primitive);
- virtual VS::BeamPrimitive beam_get_primitive(RID p_beam) const;
-
- virtual void beam_set_material(RID p_beam, RID p_material);
- virtual RID beam_get_material(RID p_beam) const;
-
- virtual AABB beam_get_aabb(RID p_particles) const;
- /* SKELETON API */
-
- virtual RID skeleton_create();
- virtual void skeleton_resize(RID p_skeleton, int p_bones);
- virtual int skeleton_get_bone_count(RID p_skeleton) const;
- virtual void skeleton_bone_set_transform(RID p_skeleton, int p_bone, const Transform &p_transform);
- virtual Transform skeleton_bone_get_transform(RID p_skeleton, int p_bone);
-
- /* LIGHT API */
-
- virtual RID light_create(VS::LightType p_type);
- virtual VS::LightType light_get_type(RID p_light) const;
-
- virtual void light_set_color(RID p_light, VS::LightColor p_type, const Color &p_color);
- virtual Color light_get_color(RID p_light, VS::LightColor p_type) const;
-
- virtual void light_set_shadow(RID p_light, bool p_enabled);
- virtual bool light_has_shadow(RID p_light) const;
-
- virtual void light_set_volumetric(RID p_light, bool p_enabled);
- virtual bool light_is_volumetric(RID p_light) const;
-
- virtual void light_set_projector(RID p_light, RID p_texture);
- virtual RID light_get_projector(RID p_light) const;
-
- virtual void light_set_var(RID p_light, VS::LightParam p_var, float p_value);
- virtual float light_get_var(RID p_light, VS::LightParam p_var) const;
-
- virtual AABB light_get_aabb(RID p_poly) const;
-
- virtual RID light_instance_create(RID p_light);
- virtual void light_instance_set_transform(RID p_light_instance, const Transform &p_transform);
-
- virtual void light_instance_set_active_hint(RID p_light_instance);
- virtual bool light_instance_has_shadow(RID p_light_instance) const;
- virtual bool light_instance_assign_shadow(RID p_light_instance);
- virtual ShadowType light_instance_get_shadow_type(RID p_light_instance) const;
- virtual int light_instance_get_shadow_passes(RID p_light_instance) const;
- virtual void light_instance_set_pssm_split_info(RID p_light_instance, int p_split, float p_near, float p_far, const CameraMatrix &p_camera, const Transform &p_transform);
-
- /* PARTICLES INSTANCE */
-
- virtual RID particles_instance_create(RID p_particles);
- virtual void particles_instance_set_transform(RID p_particles_instance, const Transform &p_transform);
-
- /* RENDER API */
- /* all calls (inside begin/end shadow) are always warranted to be in the following order: */
-
- virtual void begin_frame();
-
- virtual void set_viewport(const VS::ViewportRect &p_viewport);
-
- virtual void begin_scene(RID p_fx = RID(), VS::ScenarioDebugMode p_debug = VS::SCENARIO_DEBUG_DISABLED);
- virtual void begin_shadow_map(RID p_light_instance, int p_shadow_pass);
-
- virtual void set_camera(const Transform &p_world, const CameraMatrix &p_projection);
-
- virtual void add_light(RID p_light_instance); ///< all "add_light" calls happen before add_geometry calls
-
- typedef Map<StringName, Variant> ParamOverrideMap;
-
- virtual void add_mesh(RID p_mesh, const Transform *p_world, const RID *p_light_instances, int p_light_count, const ParamOverrideMap *p_material_overrides = NULL, RID p_skeleton = RID());
- virtual void add_multimesh(RID p_multimesh, const Transform *p_world, const RID *p_light_instances, int p_light_count, const ParamOverrideMap *p_material_overrides = NULL);
- virtual void add_poly(RID p_poly, const Transform *p_world, const RID *p_light_instances, int p_light_count, const ParamOverrideMap *p_material_overrides = NULL);
- virtual void add_beam(RID p_beam, const Transform *p_world, const RID *p_light_instances, int p_light_count, const ParamOverrideMap *p_material_overrides = NULL);
- virtual void add_particles(RID p_particle_instance, const RID *p_light_instances, int p_light_count, const ParamOverrideMap *p_material_overrides = NULL);
-
- virtual void end_scene();
- virtual void end_shadow_map();
-
- virtual void end_frame();
-
- /* CANVAS API */
-
- virtual void canvas_begin();
- virtual void canvas_set_transparency(float p_transparency);
- virtual void canvas_set_rect(const Rect2 &p_rect, bool p_clip);
- virtual void canvas_draw_line(const Point2 &p_from, const Point2 &p_to, const Color &p_color, float p_width);
- virtual void canvas_draw_rect(const Rect2 &p_rect, bool p_region, const Rect2 &p_source, bool p_tile, RID p_texture, const Color &p_modulate);
- virtual void canvas_draw_style_box(const Rect2 &p_rect, RID p_texture, const float *p_margins, bool p_draw_center = true);
- virtual void canvas_draw_primitive(const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, RID p_texture);
-
- /* FX */
-
- virtual RID fx_create();
- virtual void fx_get_effects(RID p_fx, List<String> *p_effects) const;
- virtual void fx_set_active(RID p_fx, const String &p_effect, bool p_active);
- virtual bool fx_is_active(RID p_fx, const String &p_effect) const;
- virtual void fx_get_effect_params(RID p_fx, const String &p_effect, List<PropertyInfo> *p_params) const;
- virtual Variant fx_get_effect_param(RID p_fx, const String &p_effect, const String &p_param) const;
- virtual void fx_set_effect_param(RID p_fx, const String &p_effect, const String &p_param, const Variant &p_pvalue);
-
- /*MISC*/
-
- virtual bool is_texture(const RID &p_rid) const;
- virtual bool is_material(const RID &p_rid) const;
- virtual bool is_mesh(const RID &p_rid) const;
- virtual bool is_multimesh(const RID &p_rid) const;
- virtual bool is_poly(const RID &p_rid) const;
- virtual bool is_particles(const RID &p_beam) const;
- virtual bool is_beam(const RID &p_beam) const;
-
- virtual bool is_light(const RID &p_rid) const;
- virtual bool is_light_instance(const RID &p_rid) const;
- virtual bool is_particles_instance(const RID &p_rid) const;
- virtual bool is_skeleton(const RID &p_rid) const;
- virtual bool is_fx(const RID &p_rid) const;
- virtual bool is_shader(const RID &p_rid) const;
-
- virtual void free(const RID &p_rid) const;
-
- virtual void init();
- virtual void finish();
-
- virtual int get_render_info(VS::RenderInfo p_info);
-
- RasterizerIPhone();
- virtual ~RasterizerIPhone();
-};
-
-#endif
-#endif
diff --git a/platform/iphone/sem_iphone.cpp b/platform/iphone/sem_iphone.cpp
index e74c696607..4614b201a4 100644
--- a/platform/iphone/sem_iphone.cpp
+++ b/platform/iphone/sem_iphone.cpp
@@ -6,6 +6,7 @@
/* http://www.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 */
diff --git a/platform/iphone/sem_iphone.h b/platform/iphone/sem_iphone.h
index 8a87ab47ca..90db0fb74d 100644
--- a/platform/iphone/sem_iphone.h
+++ b/platform/iphone/sem_iphone.h
@@ -6,6 +6,7 @@
/* http://www.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 */
diff --git a/platform/iphone/view_controller.h b/platform/iphone/view_controller.h
index ca05818040..57ed576c25 100644
--- a/platform/iphone/view_controller.h
+++ b/platform/iphone/view_controller.h
@@ -6,6 +6,7 @@
/* http://www.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 */
diff --git a/platform/iphone/view_controller.mm b/platform/iphone/view_controller.mm
index 8b3dc7c984..574598e1d3 100644
--- a/platform/iphone/view_controller.mm
+++ b/platform/iphone/view_controller.mm
@@ -6,6 +6,7 @@
/* http://www.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 */
@@ -32,44 +33,43 @@
extern "C" {
-int add_path(int, char**);
-int add_cmdline(int, char**);
+int add_path(int, char **);
+int add_cmdline(int, char **);
-int add_path(int p_argc, char** p_args) {
+int add_path(int p_argc, char **p_args) {
- NSString* str = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"godot_path"];
+ NSString *str = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"godot_path"];
if (!str)
return p_argc;
p_args[p_argc++] = "-path";
[str retain]; // memory leak lol (maybe make it static here and delete it in ViewController destructor? @todo
- p_args[p_argc++] = (char*)[str cString];
+ p_args[p_argc++] = (char *)[str cString];
p_args[p_argc] = NULL;
return p_argc;
};
-int add_cmdline(int p_argc, char** p_args) {
+int add_cmdline(int p_argc, char **p_args) {
- NSArray* arr = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"godot_cmdline"];
+ NSArray *arr = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"godot_cmdline"];
if (!arr)
return p_argc;
- for (int i=0; i < [arr count]; i++) {
+ for (int i = 0; i < [arr count]; i++) {
- NSString* str = [arr objectAtIndex:i];
+ NSString *str = [arr objectAtIndex:i];
if (!str)
continue;
[str retain]; // @todo delete these at some point
- p_args[p_argc++] = (char*)[str cString];
+ p_args[p_argc++] = (char *)[str cString];
};
p_args[p_argc] = NULL;
return p_argc;
};
-
-};
+}; // extern "C"
@interface ViewController ()
@@ -84,59 +84,58 @@ int add_cmdline(int p_argc, char** p_args) {
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)p_orientation {
- if (/*OSIPhone::get_singleton() == NULL*/TRUE) {
+ if (/*OSIPhone::get_singleton() == NULL*/ TRUE) {
printf("checking on info.plist\n");
- NSArray* arr = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"UISupportedInterfaceOrientations"];
- switch(p_orientation) {
+ NSArray *arr = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"UISupportedInterfaceOrientations"];
+ switch (p_orientation) {
- case UIInterfaceOrientationLandscapeLeft:
- return [arr indexOfObject:@"UIInterfaceOrientationLandscapeLeft"] != NSNotFound ? YES : NO;
+ case UIInterfaceOrientationLandscapeLeft:
+ return [arr indexOfObject:@"UIInterfaceOrientationLandscapeLeft"] != NSNotFound ? YES : NO;
- case UIInterfaceOrientationLandscapeRight:
- return [arr indexOfObject:@"UIInterfaceOrientationLandscapeRight"] != NSNotFound ? YES : NO;
+ case UIInterfaceOrientationLandscapeRight:
+ return [arr indexOfObject:@"UIInterfaceOrientationLandscapeRight"] != NSNotFound ? YES : NO;
- case UIInterfaceOrientationPortrait:
- return [arr indexOfObject:@"UIInterfaceOrientationPortrait"] != NSNotFound ? YES : NO;
+ case UIInterfaceOrientationPortrait:
+ return [arr indexOfObject:@"UIInterfaceOrientationPortrait"] != NSNotFound ? YES : NO;
- case UIInterfaceOrientationPortraitUpsideDown:
- return [arr indexOfObject:@"UIInterfaceOrientationPortraitUpsideDown"] != NSNotFound ? YES : NO;
+ case UIInterfaceOrientationPortraitUpsideDown:
+ return [arr indexOfObject:@"UIInterfaceOrientationPortraitUpsideDown"] != NSNotFound ? YES : NO;
- default:
- return NO;
+ default:
+ return NO;
}
};
uint8_t supported = OSIPhone::get_singleton()->get_orientations();
- switch(p_orientation) {
+ switch (p_orientation) {
- case UIInterfaceOrientationLandscapeLeft:
- return supported & (1<<OSIPhone::LandscapeLeft) ? YES : NO;
+ case UIInterfaceOrientationLandscapeLeft:
+ return supported & (1 << OSIPhone::LandscapeLeft) ? YES : NO;
- case UIInterfaceOrientationLandscapeRight:
- return supported & (1<<OSIPhone::LandscapeRight) ? YES : NO;
+ case UIInterfaceOrientationLandscapeRight:
+ return supported & (1 << OSIPhone::LandscapeRight) ? YES : NO;
- case UIInterfaceOrientationPortrait:
- return supported & (1<<OSIPhone::PortraitDown) ? YES : NO;
+ case UIInterfaceOrientationPortrait:
+ return supported & (1 << OSIPhone::PortraitDown) ? YES : NO;
- case UIInterfaceOrientationPortraitUpsideDown:
- return supported & (1<<OSIPhone::PortraitUp) ? YES : NO;
+ case UIInterfaceOrientationPortraitUpsideDown:
+ return supported & (1 << OSIPhone::PortraitUp) ? YES : NO;
- default:
- return NO;
+ default:
+ return NO;
}
};
-- (BOOL)prefersStatusBarHidden
-{
+- (BOOL)prefersStatusBarHidden {
return YES;
}
#ifdef GAME_CENTER_ENABLED
-- (void) gameCenterViewControllerDidFinish:(GKGameCenterViewController*) gameCenterViewController {
- //[gameCenterViewController dismissViewControllerAnimated:YES completion:^{GameCenter::get_singleton()->game_center_closed();}];//version for signaling when overlay is completely gone
- GameCenter::get_singleton()->game_center_closed();
- [gameCenterViewController dismissViewControllerAnimated:YES completion:nil];
+- (void)gameCenterViewControllerDidFinish:(GKGameCenterViewController *)gameCenterViewController {
+ //[gameCenterViewController dismissViewControllerAnimated:YES completion:^{GameCenter::get_singleton()->game_center_closed();}];//version for signaling when overlay is completely gone
+ GameCenter::get_singleton()->game_center_closed();
+ [gameCenterViewController dismissViewControllerAnimated:YES completion:nil];
}
#endif
diff --git a/platform/javascript/SCsub b/platform/javascript/SCsub
index 02ff2090f9..b804863ee1 100644
--- a/platform/javascript/SCsub
+++ b/platform/javascript/SCsub
@@ -19,29 +19,34 @@ javascript_objects = []
for x in javascript_files:
javascript_objects.append(env_javascript.Object(x))
-env.Append(LINKFLAGS=["-s", "EXPORTED_FUNCTIONS=\"['_main','_audio_server_mix_function','_main_after_fs_sync']\""])
+env.Append(LINKFLAGS=["-s", "EXPORTED_FUNCTIONS=\"['_main','_audio_server_mix_function','_main_after_fs_sync','_send_notification']\""])
env.Append(LINKFLAGS=["--shell-file", '"platform/javascript/godot_shell.html"'])
-html_file = env.Program('#bin/godot', javascript_objects, PROGSUFFIX=env["PROGSUFFIX"] + ".html")[0]
+# output file name without file extension
+basename = "godot" + env["PROGSUFFIX"]
+target_dir = env.Dir("#bin")
+js_file = target_dir.File(basename + ".js")
+implicit_targets = [js_file]
+
+zip_dir = target_dir.Dir('.javascript_zip')
+zip_files = env.InstallAs([zip_dir.File("godot.js"), zip_dir.File("godotfs.js")], [js_file, "#misc/dist/html_fs/godotfs.js"])
+
+if env['wasm'] == 'yes':
+ wasm_file = target_dir.File(basename+'.wasm')
+ implicit_targets.append(wasm_file)
+ zip_files.append(InstallAs(zip_dir.File('godot.wasm'), wasm_file))
+else:
+ asmjs_files = [target_dir.File(basename+'.asm.js'), target_dir.File(basename+'.html.mem')]
+ zip_files.append(InstallAs([zip_dir.File('godot.asm.js'), zip_dir.File('godot.mem')], asmjs_files))
+ implicit_targets.extend(asmjs_files)
+
+# HTML file must be the first target in the list
+html_file = env.Program(["#bin/godot"] + implicit_targets, javascript_objects, PROGSUFFIX=env["PROGSUFFIX"]+".html")[0]
Depends(html_file, "godot_shell.html")
-basename = "godot" + env["PROGSUFFIX"] # output file name without file extension
# Emscripten hardcodes file names, so replace common base name with
# placeholder while leaving extension; also change `.html.mem` to just `.mem`
fixup_html = env.Substfile(html_file, SUBST_DICT=[(basename, '$$GODOT_BASE'), ('.html.mem', '.mem')], SUBSTFILESUFFIX='.fixup.html')
-zip_dir = env.Dir('#bin/.javascript_zip')
-zip_files = []
-js_file = env.SideEffect(html_file.File(basename+'.js'), html_file)
-zip_files.append(env.InstallAs(
- [zip_dir.File('godot.html'), zip_dir.File('godot.js'), zip_dir.File('godotfs.js')],
- [fixup_html, js_file, '#misc/dist/html_fs/godotfs.js']))
-
-if env['wasm'] == 'yes':
- wasm_file = env.SideEffect(html_file.File(basename+'.wasm'), html_file)
- zip_files.append(env.InstallAs(zip_dir.File('godot.wasm'), wasm_file))
-else:
- asmjs_files = env.SideEffect([html_file.File(basename+'.asm.js'), html_file.File(basename+'.html.mem')], html_file)
- zip_files.append(env.InstallAs([zip_dir.File('godot.asm.js'), zip_dir.File('godot.mem')], asmjs_files))
-
-Zip('#bin/godot', zip_files, ZIPSUFFIX=env['PROGSUFFIX']+env['ZIPSUFFIX'], ZIPROOT=zip_dir)
+zip_files.append(InstallAs(zip_dir.File('godot.html'), fixup_html))
+Zip('#bin/godot', zip_files, ZIPSUFFIX=env['PROGSUFFIX']+env['ZIPSUFFIX'], ZIPROOT=zip_dir, ZIPCOMSTR="Archving $SOURCES as $TARGET")
diff --git a/platform/javascript/audio_driver_javascript.cpp b/platform/javascript/audio_driver_javascript.cpp
index 80bc7047ae..3e37ec293e 100644
--- a/platform/javascript/audio_driver_javascript.cpp
+++ b/platform/javascript/audio_driver_javascript.cpp
@@ -6,6 +6,7 @@
/* http://www.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 */
diff --git a/platform/javascript/audio_driver_javascript.h b/platform/javascript/audio_driver_javascript.h
index ca5dba7e5c..7ccaff0f43 100644
--- a/platform/javascript/audio_driver_javascript.h
+++ b/platform/javascript/audio_driver_javascript.h
@@ -6,6 +6,7 @@
/* http://www.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 */
diff --git a/platform/javascript/audio_server_javascript.cpp b/platform/javascript/audio_server_javascript.cpp
index 7dfd562402..f9b7890e12 100644
--- a/platform/javascript/audio_server_javascript.cpp
+++ b/platform/javascript/audio_server_javascript.cpp
@@ -6,6 +6,7 @@
/* http://www.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 */
diff --git a/platform/javascript/audio_server_javascript.h b/platform/javascript/audio_server_javascript.h
index 2f48e7e79e..58c240f793 100644
--- a/platform/javascript/audio_server_javascript.h
+++ b/platform/javascript/audio_server_javascript.h
@@ -6,6 +6,7 @@
/* http://www.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 */
diff --git a/platform/javascript/detect.py b/platform/javascript/detect.py
index f82eae9ff2..68c8d1eea5 100644
--- a/platform/javascript/detect.py
+++ b/platform/javascript/detect.py
@@ -1,6 +1,6 @@
import os
-import sys
import string
+import sys
def is_active():
@@ -12,7 +12,8 @@ def get_name():
def can_build():
- return os.environ.has_key("EMSCRIPTEN_ROOT")
+
+ return (os.environ.has_key("EMSCRIPTEN_ROOT"))
def get_opts():
@@ -27,12 +28,12 @@ def get_flags():
return [
('tools', 'no'),
- ('module_etc1_enabled', 'no'),
('module_theora_enabled', 'no'),
]
def create(env):
+
# remove Windows' .exe suffix
return env.Clone(tools=['textfile', 'zip'], PROGSUFFIX='')
@@ -45,10 +46,26 @@ def escape_target_backslashes(target, source, env, for_signature):
def configure(env):
- env['ENV'] = os.environ
- env.Append(CPPPATH=['#platform/javascript'])
+ ## Build type
+ if (env["target"] == "release"):
+ env.Append(CCFLAGS=['-O3'])
+ env.Append(LINKFLAGS=['-O3'])
+
+ elif (env["target"] == "release_debug"):
+ env.Append(CCFLAGS=['-O2', '-DDEBUG_ENABLED'])
+ env.Append(LINKFLAGS=['-O2', '-s', 'ASSERTIONS=1'])
+ # retain function names at the cost of file size, for backtraces and profiling
+ env.Append(LINKFLAGS=['--profiling-funcs'])
+
+ elif (env["target"] == "debug"):
+ env.Append(CCFLAGS=['-O1', '-D_DEBUG', '-g', '-DDEBUG_ENABLED'])
+ env.Append(LINKFLAGS=['-O1', '-g'])
+
+ ## Compiler configuration
+
+ env['ENV'] = os.environ
env.PrependENVPath('PATH', os.environ['EMSCRIPTEN_ROOT'])
env['CC'] = 'emcc'
env['CXX'] = 'em++'
@@ -57,6 +74,7 @@ def configure(env):
# Emscripten's ar has issues with duplicate file names, so use cc
env['AR'] = 'emcc'
env['ARFLAGS'] = '-o'
+
if (os.name == 'nt'):
# use TempFileMunge on Windows since some commands get too long for
# cmd.exe even with spawn_fix
@@ -68,26 +86,20 @@ def configure(env):
env['OBJSUFFIX'] = '.bc'
env['LIBSUFFIX'] = '.bc'
- if (env["target"] == "release"):
- env.Append(CCFLAGS=['-O3'])
- env.Append(LINKFLAGS=['-O3'])
- elif (env["target"] == "release_debug"):
- env.Append(CCFLAGS=['-O2', '-DDEBUG_ENABLED'])
- env.Append(LINKFLAGS=['-O2'])
- # retain function names at the cost of file size, for backtraces and profiling
- env.Append(LINKFLAGS=['--profiling-funcs'])
- elif (env["target"] == "debug"):
- env.Append(CCFLAGS=['-O1', '-D_DEBUG', '-Wall', '-g', '-DDEBUG_ENABLED'])
- env.Append(LINKFLAGS=['-O1', '-g'])
+ ## Compile flags
- # TODO: Move that to opus module's config
- if("module_opus_enabled" in env and env["module_opus_enabled"] != "no"):
- env.opus_fixed_point = "yes"
+ env.Append(CPPPATH=['#platform/javascript'])
+ env.Append(CPPFLAGS=['-DJAVASCRIPT_ENABLED', '-DUNIX_ENABLED', '-DPTHREAD_NO_RENAME', '-DTYPED_METHOD_BIND', '-DNO_THREADS'])
+ env.Append(CPPFLAGS=['-DGLES3_ENABLED'])
# These flags help keep the file size down
env.Append(CPPFLAGS=["-fno-exceptions", '-DNO_SAFE_CAST', '-fno-rtti'])
- env.Append(CPPFLAGS=['-DJAVASCRIPT_ENABLED', '-DUNIX_ENABLED', '-DPTHREAD_NO_RENAME', '-DTYPED_METHOD_BIND', '-DNO_THREADS'])
- env.Append(CPPFLAGS=['-DGLES3_ENABLED'])
+
+ if env['javascript_eval'] == 'yes':
+ env.Append(CPPFLAGS=['-DJAVASCRIPT_EVAL_ENABLED'])
+
+ ## Link flags
+
env.Append(LINKFLAGS=['-s', 'USE_WEBGL2=1'])
if (env['wasm'] == 'yes'):
@@ -101,8 +113,6 @@ def configure(env):
env.Append(LINKFLAGS=['-s', 'ASM_JS=1'])
env.Append(LINKFLAGS=['--separate-asm'])
- if env['javascript_eval'] == 'yes':
- env.Append(CPPFLAGS=['-DJAVASCRIPT_EVAL_ENABLED'])
-
-
- import methods
+ # TODO: Move that to opus module's config
+ if("module_opus_enabled" in env and env["module_opus_enabled"] != "no"):
+ env.opus_fixed_point = "yes"
diff --git a/platform/javascript/dom_keys.h b/platform/javascript/dom_keys.h
index 53a2705577..4b8b764c45 100644
--- a/platform/javascript/dom_keys.h
+++ b/platform/javascript/dom_keys.h
@@ -6,6 +6,7 @@
/* http://www.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 */
@@ -248,7 +249,7 @@ int dom2godot_scancode(int dom_keycode) {
case DOM_VK_RETURN:
case DOM_VK_ENTER: // unused according to MDN
- return KEY_RETURN;
+ return KEY_ENTER;
case DOM_VK_SHIFT: return KEY_SHIFT;
case DOM_VK_CONTROL: return KEY_CONTROL;
diff --git a/platform/javascript/export/export.cpp b/platform/javascript/export/export.cpp
index 4fdb6f39c8..b436d52363 100644
--- a/platform/javascript/export/export.cpp
+++ b/platform/javascript/export/export.cpp
@@ -6,6 +6,7 @@
/* http://www.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 */
@@ -26,399 +27,354 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "export.h"
-#include "editor/editor_export.h"
#include "editor/editor_node.h"
-#include "editor/editor_settings.h"
-#include "global_config.h"
-#include "io/marshalls.h"
+#include "editor_export.h"
#include "io/zip_io.h"
-#include "os/file_access.h"
-#include "os/os.h"
-#include "platform/javascript/logo.h"
-#include "string.h"
-#include "version.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"
-#if 0
class EditorExportPlatformJavaScript : public EditorExportPlatform {
- GDCLASS( EditorExportPlatformJavaScript,EditorExportPlatform );
+ GDCLASS(EditorExportPlatformJavaScript, EditorExportPlatform)
+
+ Ref<ImageTexture> logo;
+ Ref<ImageTexture> run_icon;
+ bool runnable_when_last_polled;
- String custom_release_package;
- String custom_debug_package;
+ 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);
- enum PackMode {
- PACK_SINGLE_FILE,
- PACK_MULTIPLE_FILES
+public:
+ enum Target {
+ TARGET_WEBASSEMBLY,
+ TARGET_ASMJS
};
- void _fix_html(Vector<uint8_t>& p_html, const String& p_name, bool p_debug);
+ virtual void get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features);
- PackMode pack_mode;
+ 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;
- bool show_run;
+ virtual String get_name() const;
+ virtual String get_os_name() const;
+ virtual Ref<Texture> get_logo() const;
- int max_memory;
- int version_code;
+ virtual bool can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const;
+ virtual String get_binary_extension() const;
+ virtual Error export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags = 0);
- String html_title;
- String html_head_include;
- String html_font_family;
- String html_style_include;
- bool html_controls_enabled;
+ virtual bool poll_devices();
+ virtual int get_device_count() const;
+ virtual String get_device_name(int p_device) const { return TTR("Run in Browser"); }
+ virtual String get_device_info(int p_device) const { return TTR("Run exported HTML in the system's default browser."); }
+ virtual Error run(const Ref<EditorExportPreset> &p_preset, int p_device, int p_debug_flags);
+ virtual Ref<Texture> get_run_icon() const;
- Ref<ImageTexture> logo;
+ virtual void get_platform_features(List<String> *r_features) {
-protected:
+ r_features->push_back("web");
+ r_features->push_back("JavaScript");
+ }
- bool _set(const StringName& p_name, const Variant& p_value);
- bool _get(const StringName& p_name,Variant &r_ret) const;
- void _get_property_list( List<PropertyInfo> *p_list) const;
+ EditorExportPlatformJavaScript();
+};
-public:
+void EditorExportPlatformJavaScript::_fix_html(Vector<uint8_t> &p_html, const Ref<EditorExportPreset> &p_preset, const String &p_name, bool p_debug) {
- virtual String get_name() const { return "HTML5"; }
- virtual ImageCompression get_image_compression() const { return IMAGE_COMPRESSION_BC; }
- virtual Ref<Texture> get_logo() const { return logo; }
+ String str_template = String::utf8(reinterpret_cast<const char *>(p_html.ptr()), p_html.size());
+ 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);
- virtual bool poll_devices() { return show_run?true:false;}
- virtual int get_device_count() const { return show_run?1:0; };
- virtual String get_device_name(int p_device) const { return "Run in Browser"; }
- virtual String get_device_info(int p_device) const { return "Run exported HTML in the system's default browser."; }
- virtual Error run(int p_device,int p_flags=0);
+ for (int i = 0; i < lines.size(); i++) {
- virtual bool requires_password(bool p_debug) const { return false; }
- virtual String get_binary_extension() const { return "html"; }
- virtual Error export_project(const String& p_path,bool p_debug,int p_flags=0);
+ String current_line = lines[i];
+ current_line = current_line.replace("$GODOT_TMEM", itos(memory_mb * 1024 * 1024));
+ current_line = current_line.replace("$GODOT_BASE", 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");
+ str_export += current_line + "\n";
+ }
- virtual bool can_export(String *r_error=NULL) const;
+ CharString cs = str_export.utf8();
+ p_html.resize(cs.length());
+ for (int i = 0; i < cs.length(); i++) {
+ p_html[i] = cs[i];
+ }
+}
- EditorExportPlatformJavaScript();
- ~EditorExportPlatformJavaScript();
-};
+void EditorExportPlatformJavaScript::_fix_fsloader_js(Vector<uint8_t> &p_js, const String &p_pack_name, uint64_t p_pack_size) {
-bool EditorExportPlatformJavaScript::_set(const StringName& p_name, const Variant& p_value) {
-
- String n=p_name;
-
- if (n=="custom_package/debug")
- custom_debug_package=p_value;
- else if (n=="custom_package/release")
- custom_release_package=p_value;
- else if (n=="browser/enable_run")
- show_run=p_value;
- else if (n=="options/memory_size")
- max_memory=p_value;
- else if (n=="html/title")
- html_title=p_value;
- else if (n=="html/head_include")
- html_head_include=p_value;
- else if (n=="html/font_family")
- html_font_family=p_value;
- else if (n=="html/style_include")
- html_style_include=p_value;
- else if (n=="html/controls_enabled")
- html_controls_enabled=p_value;
- else
- return false;
+ String str_template = String::utf8(reinterpret_cast<const char *>(p_js.ptr()), p_js.size());
+ String str_export;
+ Vector<String> lines = str_template.split("\n");
+ for (int i = 0; i < lines.size(); i++) {
+ if (lines[i].find("$GODOT_PACK_NAME") != -1) {
+ str_export += lines[i].replace("$GODOT_PACK_NAME", p_pack_name);
+ } else if (lines[i].find("$GODOT_PACK_SIZE") != -1) {
+ str_export += lines[i].replace("$GODOT_PACK_SIZE", itos(p_pack_size));
+ } else {
+ str_export += lines[i] + "\n";
+ }
+ }
- return true;
+ CharString cs = str_export.utf8();
+ p_js.resize(cs.length());
+ for (int i = 0; i < cs.length(); i++) {
+ p_js[i] = cs[i];
+ }
}
-bool EditorExportPlatformJavaScript::_get(const StringName& p_name,Variant &r_ret) const{
-
- String n=p_name;
-
- if (n=="custom_package/debug")
- r_ret=custom_debug_package;
- else if (n=="custom_package/release")
- r_ret=custom_release_package;
- else if (n=="browser/enable_run")
- r_ret=show_run;
- else if (n=="options/memory_size")
- r_ret=max_memory;
- else if (n=="html/title")
- r_ret=html_title;
- else if (n=="html/head_include")
- r_ret=html_head_include;
- else if (n=="html/font_family")
- r_ret=html_font_family;
- else if (n=="html/style_include")
- r_ret=html_style_include;
- else if (n=="html/controls_enabled")
- r_ret=html_controls_enabled;
- else
- return false;
+void EditorExportPlatformJavaScript::get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) {
- return true;
+ if (p_preset->get("texture_format/s3tc")) {
+ r_features->push_back("s3tc");
+ }
+ if (p_preset->get("texture_format/etc")) {
+ r_features->push_back("etc");
+ }
+ if (p_preset->get("texture_format/etc2")) {
+ r_features->push_back("etc2");
+ }
}
-void EditorExportPlatformJavaScript::_get_property_list( List<PropertyInfo> *p_list) const{
- p_list->push_back( PropertyInfo( Variant::STRING, "custom_package/debug", PROPERTY_HINT_GLOBAL_FILE,"zip"));
- p_list->push_back( PropertyInfo( Variant::STRING, "custom_package/release", PROPERTY_HINT_GLOBAL_FILE,"zip"));
- p_list->push_back( PropertyInfo( Variant::INT, "options/memory_size",PROPERTY_HINT_ENUM,"32mb,64mb,128mb,256mb,512mb,1024mb"));
- p_list->push_back( PropertyInfo( Variant::BOOL, "browser/enable_run"));
- p_list->push_back( PropertyInfo( Variant::STRING, "html/title"));
- p_list->push_back( PropertyInfo( Variant::STRING, "html/head_include",PROPERTY_HINT_MULTILINE_TEXT));
- p_list->push_back( PropertyInfo( Variant::STRING, "html/font_family"));
- p_list->push_back( PropertyInfo( Variant::STRING, "html/style_include",PROPERTY_HINT_MULTILINE_TEXT));
- p_list->push_back( PropertyInfo( Variant::BOOL, "html/controls_enabled"));
+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/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"), ""));
+}
- //p_list->push_back( PropertyInfo( Variant::INT, "resources/pack_mode", PROPERTY_HINT_ENUM,"Copy,Single Exec.,Pack (.pck),Bundles (Optical)"));
+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 {
-void EditorExportPlatformJavaScript::_fix_html(Vector<uint8_t>& p_html, const String& p_name, bool p_debug) {
+ return "HTML5";
+}
+String EditorExportPlatformJavaScript::get_os_name() const {
- String str;
- String strnew;
- str.parse_utf8((const char*)p_html.ptr(),p_html.size());
- Vector<String> lines=str.split("\n");
- for(int i=0;i<lines.size();i++) {
+ return "JavaScript";
+}
- String current_line = lines[i];
- current_line = current_line.replace("$GODOT_TMEM",itos((1<<(max_memory+5))*1024*1024));
- current_line = current_line.replace("$GODOT_BASE",p_name);
- current_line = current_line.replace("$GODOT_CANVAS_WIDTH",GlobalConfig::get_singleton()->get("display/window/width"));
- current_line = current_line.replace("$GODOT_CANVAS_HEIGHT",GlobalConfig::get_singleton()->get("display/window/height"));
- current_line = current_line.replace("$GODOT_HEAD_TITLE",!html_title.empty()?html_title:(String) GlobalConfig::get_singleton()->get("application/name"));
- current_line = current_line.replace("$GODOT_HEAD_INCLUDE",html_head_include);
- current_line = current_line.replace("$GODOT_STYLE_FONT_FAMILY",html_font_family);
- current_line = current_line.replace("$GODOT_STYLE_INCLUDE",html_style_include);
- current_line = current_line.replace("$GODOT_CONTROLS_ENABLED",html_controls_enabled?"true":"false");
- current_line = current_line.replace("$GODOT_DEBUG_ENABLED",p_debug?"true":"false");
- strnew += current_line+"\n";
- }
+Ref<Texture> EditorExportPlatformJavaScript::get_logo() const {
- CharString cs = strnew.utf8();
- p_html.resize(cs.length());
- for(int i=9;i<cs.length();i++) {
- p_html[i]=cs[i];
- }
+ return logo;
}
-static void _fix_files(Vector<uint8_t>& html,uint64_t p_data_size) {
+bool EditorExportPlatformJavaScript::can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const {
+ r_missing_templates = false;
- String str;
- String strnew;
- str.parse_utf8((const char*)html.ptr(),html.size());
- Vector<String> lines=str.split("\n");
- for(int i=0;i<lines.size();i++) {
- if (lines[i].find("$DPLEN")!=-1) {
- strnew+=lines[i].replace("$DPLEN",itos(p_data_size));
- } else {
- strnew+=lines[i]+"\n";
- }
- }
-
- CharString cs = strnew.utf8();
- html.resize(cs.length());
- for(int i=9;i<cs.length();i++) {
- html[i]=cs[i];
+ 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;
}
+ return !r_missing_templates;
}
-struct JSExportData {
-
- EditorProgress *ep;
- FileAccess *f;
-
-};
-
+String EditorExportPlatformJavaScript::get_binary_extension() const {
+ return "html";
+}
-Error EditorExportPlatformJavaScript::export_project(const String& p_path, bool p_debug, int p_flags) {
+Error EditorExportPlatformJavaScript::export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags) {
+ String custom_debug = p_preset->get("custom_template/debug");
+ String custom_release = p_preset->get("custom_template/release");
- String src_template;
+ String template_path = p_debug ? custom_debug : custom_release;
- EditorProgress ep("export","Exporting for javascript",104);
+ template_path = template_path.strip_edges();
- if (p_debug)
- src_template=custom_debug_package;
- else
- src_template=custom_release_package;
+ if (template_path == String()) {
- if (src_template=="") {
- String err;
- if (p_debug) {
- src_template=find_export_template("javascript_debug.zip", &err);
+ 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 {
- src_template=find_export_template("javascript_release.zip", &err);
- }
- if (src_template=="") {
- EditorNode::add_io_error(err);
- return ERR_FILE_NOT_FOUND;
+ if (p_debug)
+ template_path = find_export_template(EXPORT_TEMPLATE_ASMJS_DEBUG);
+ else
+ template_path = find_export_template(EXPORT_TEMPLATE_ASMJS_RELEASE);
}
}
- FileAccess *src_f=NULL;
- zlib_filefunc_def io = zipio_create_io_from_file(&src_f);
-
- ep.step("Exporting to HTML5",0);
+ if (template_path != String() && !FileAccess::exists(template_path)) {
+ EditorNode::get_singleton()->show_warning(TTR("Template file not found:\n") + template_path);
+ return ERR_FILE_NOT_FOUND;
+ }
- ep.step("Finding Files..",1);
+ String pck_path = p_path.get_basename() + ".pck";
+ Error error = save_pack(p_preset, pck_path);
+ if (error != OK) {
+ EditorNode::get_singleton()->show_warning(TTR("Could not write file:\n") + pck_path);
+ return error;
+ }
- FileAccess *f=FileAccess::open(p_path.get_base_dir()+"/data.pck",FileAccess::WRITE);
+ FileAccess *f = FileAccess::open(pck_path, FileAccess::READ);
if (!f) {
- EditorNode::add_io_error("Could not create file for writing:\n"+p_path.get_basename()+"_files.js");
- return ERR_FILE_CANT_WRITE;
+ EditorNode::get_singleton()->show_warning(TTR("Could not read file:\n") + pck_path);
+ return ERR_FILE_CANT_READ;
}
- Error err = save_pack(f);
- size_t len = f->get_len();
+ size_t pack_size = f->get_len();
memdelete(f);
- if (err)
- return err;
+ FileAccess *src_f = NULL;
+ zlib_filefunc_def io = zipio_create_io_from_file(&src_f);
+ unzFile pkg = unzOpen2(template_path.utf8().get_data(), &io);
- unzFile pkg = unzOpen2(src_template.utf8().get_data(), &io);
if (!pkg) {
- EditorNode::add_io_error("Could not find template HTML5 to export:\n"+src_template);
+ EditorNode::get_singleton()->show_warning(TTR("Could not open template for export:\n") + template_path);
return ERR_FILE_NOT_FOUND;
}
- ERR_FAIL_COND_V(!pkg, ERR_CANT_OPEN);
int ret = unzGoToFirstFile(pkg);
-
-
- while(ret==UNZ_OK) {
+ while (ret == UNZ_OK) {
//get filename
unz_file_info info;
char fname[16384];
- ret = unzGetCurrentFileInfo(pkg,&info,fname,16384,NULL,0,NULL,0);
+ ret = unzGetCurrentFileInfo(pkg, &info, fname, 16384, NULL, 0, NULL, 0);
- String file=fname;
+ String file = fname;
Vector<uint8_t> data;
data.resize(info.uncompressed_size);
//read
unzOpenCurrentFile(pkg);
- unzReadCurrentFile(pkg,data.ptr(),data.size());
+ unzReadCurrentFile(pkg, data.ptr(), data.size());
unzCloseCurrentFile(pkg);
//write
- if (file=="godot.html") {
+ if (file == "godot.html") {
- _fix_html(data,p_path.get_file().get_basename(), p_debug);
- file=p_path.get_file();
- }
- if (file=="godotfs.js") {
-
- _fix_files(data,len);
- file=p_path.get_file().get_basename()+"fs.js";
- }
- if (file=="godot.js") {
+ _fix_html(data, p_preset, p_path.get_file().get_basename(), p_debug);
+ file = p_path.get_file();
+ } else if (file == "godotfs.js") {
- file=p_path.get_file().get_basename()+".js";
- }
+ _fix_fsloader_js(data, pck_path.get_file(), pack_size);
+ file = p_path.get_file().get_basename() + "fs.js";
+ } else if (file == "godot.js") {
- if (file=="godot.asm.js") {
+ file = p_path.get_file().get_basename() + ".js";
+ } else if (file == "godot.wasm") {
- file=p_path.get_file().get_basename()+".asm.js";
- }
+ file = p_path.get_file().get_basename() + ".wasm";
+ } else if (file == "godot.asm.js") {
- if (file=="godot.mem") {
+ file = p_path.get_file().get_basename() + ".asm.js";
+ } else if (file == "godot.mem") {
- file=p_path.get_file().get_basename()+".mem";
- }
-
- if (file=="godot.wasm") {
-
- file=p_path.get_file().get_basename()+".wasm";
+ file = p_path.get_file().get_basename() + ".mem";
}
String dst = p_path.get_base_dir().plus_file(file);
- FileAccess *f=FileAccess::open(dst,FileAccess::WRITE);
+ FileAccess *f = FileAccess::open(dst, FileAccess::WRITE);
if (!f) {
- EditorNode::add_io_error("Could not create file for writing:\n"+dst);
+ EditorNode::get_singleton()->show_warning(TTR("Could not write file:\n") + dst);
unzClose(pkg);
return ERR_FILE_CANT_WRITE;
}
- f->store_buffer(data.ptr(),data.size());
+ f->store_buffer(data.ptr(), data.size());
memdelete(f);
-
ret = unzGoToNextFile(pkg);
}
-
-
return OK;
-
}
+bool EditorExportPlatformJavaScript::poll_devices() {
-Error EditorExportPlatformJavaScript::run(int p_device, int p_flags) {
+ Ref<EditorExportPreset> preset;
- String path = EditorSettings::get_singleton()->get_settings_path()+"/tmp/tmp_export.html";
- Error err = export_project(path,true,p_flags);
- if (err)
- return err;
+ for (int i = 0; i < EditorExport::get_singleton()->get_export_preset_count(); i++) {
- OS::get_singleton()->shell_open(path);
+ Ref<EditorExportPreset> ep = EditorExport::get_singleton()->get_export_preset(i);
+ if (ep->is_runnable() && ep->get_platform() == this) {
+ preset = ep;
+ break;
+ }
+ }
- return OK;
+ bool prev = runnable_when_last_polled;
+ runnable_when_last_polled = preset.is_valid();
+ return runnable_when_last_polled != prev;
}
+int EditorExportPlatformJavaScript::get_device_count() const {
-EditorExportPlatformJavaScript::EditorExportPlatformJavaScript() {
-
- show_run=false;
- Image img( _javascript_logo );
- logo = Ref<ImageTexture>( memnew( ImageTexture ));
- logo->create_from_image(img);
- max_memory=3;
- html_title="";
- html_font_family="'Droid Sans',arial,sans-serif";
- html_controls_enabled=true;
- pack_mode=PACK_SINGLE_FILE;
+ return runnable_when_last_polled;
}
-bool EditorExportPlatformJavaScript::can_export(String *r_error) const {
-
-
- bool valid=true;
- String err;
+Error EditorExportPlatformJavaScript::run(const Ref<EditorExportPreset> &p_preset, int p_device, int p_debug_flags) {
- if (!exists_export_template("javascript_debug.zip") || !exists_export_template("javascript_release.zip")) {
- valid=false;
- err+="No export templates found.\nDownload and install export templates.\n";
- }
-
- if (custom_debug_package!="" && !FileAccess::exists(custom_debug_package)) {
- valid=false;
- err+="Custom debug package not found.\n";
- }
-
- if (custom_release_package!="" && !FileAccess::exists(custom_release_package)) {
- valid=false;
- err+="Custom release package not found.\n";
+ String path = EditorSettings::get_singleton()->get_settings_path() + "/tmp/tmp_export.html";
+ Error err = export_project(p_preset, true, path, p_debug_flags);
+ if (err) {
+ return err;
}
+ OS::get_singleton()->shell_open(path);
+ return OK;
+}
- if (r_error)
- *r_error=err;
+Ref<Texture> EditorExportPlatformJavaScript::get_run_icon() const {
- return valid;
+ return run_icon;
}
+EditorExportPlatformJavaScript::EditorExportPlatformJavaScript() {
+
+ Ref<Image> img = memnew(Image(_javascript_logo));
+ logo.instance();
+ logo->create_from_image(img);
-EditorExportPlatformJavaScript::~EditorExportPlatformJavaScript() {
+ img = Ref<Image>(memnew(Image(_javascript_run_icon)));
+ run_icon.instance();
+ run_icon->create_from_image(img);
+ runnable_when_last_polled = false;
}
-#endif
void register_javascript_exporter() {
- //Ref<EditorExportPlatformJavaScript> exporter = Ref<EditorExportPlatformJavaScript>( memnew(EditorExportPlatformJavaScript) );
- //EditorImportExport::get_singleton()->add_export_platform(exporter);
+ Ref<EditorExportPlatformJavaScript> platform;
+ platform.instance();
+ EditorExport::get_singleton()->add_export_platform(platform);
}
diff --git a/platform/javascript/export/export.h b/platform/javascript/export/export.h
index 59c0a67e6d..910c4119f7 100644
--- a/platform/javascript/export/export.h
+++ b/platform/javascript/export/export.h
@@ -6,6 +6,7 @@
/* http://www.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 */
diff --git a/platform/javascript/godot_shell.html b/platform/javascript/godot_shell.html
index 65f3b4a340..ee7399a129 100644
--- a/platform/javascript/godot_shell.html
+++ b/platform/javascript/godot_shell.html
@@ -2,8 +2,7 @@
<html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang="">
<head>
<meta charset="utf-8" />
- <title>$GODOT_HEAD_TITLE</title>
-$GODOT_HEAD_INCLUDE
+ <title></title>
<style type="text/css">
body {
margin: 0;
@@ -11,7 +10,7 @@ $GODOT_HEAD_INCLUDE
padding: 0;
text-align: center;
background-color: #222226;
- font-family: $GODOT_STYLE_FONT_FAMILY;
+ font-family: 'Droid Sans', Arial, sans-serif;
}
@@ -27,7 +26,7 @@ $GODOT_HEAD_INCLUDE
}
button.godot {
- font-family: $GODOT_STYLE_FONT_FAMILY; /* override user agent style */
+ font-family: 'Droid Sans', Arial, sans-serif; /* override user agent style */
padding: 1px 5px;
background-color: #37353f;
background-image: linear-gradient(to bottom, #413e49, #3a3842);
@@ -84,6 +83,10 @@ $GODOT_HEAD_INCLUDE
color: white;
}
+ #canvas:focus {
+ outline: none;
+ }
+
/* Status display
* ============== */
@@ -109,53 +112,12 @@ $GODOT_HEAD_INCLUDE
}
- /* On-hover controls
- * ================= */
-
- #controls {
- visibility: hidden;
- opacity: 0.0;
- transition: opacity 500ms ease-in-out 200ms;
- position: absolute;
- right: 16px;
- top: 16px;
- padding: 3px 5px;
- font-size: small;
- -moz-user-select: none;
- -webkit-user-select: none;
- -ms-user-select: none;
- }
-
- :hover > #controls {
- opacity: 1.0;
- transition: opacity 60ms ease-in-out;
- }
-
- #controls > button,
- #controls > label {
- vertical-align: middle;
- margin-left: 2px;
- margin-right: 2px;
- }
-
- #controls > label > input {
- vertical-align: middle;
- }
-
- #controls > label > input[type="checkbox"] {
- /* override user agent style */
- margin-left: 0;
- }
-
- #output-toggle { display: none; }
-
-
/* Debug output
* ============ */
#output-panel {
display: none;
- max-width: $GODOT_CANVAS_WIDTHpx;
+ max-width: 700px;
font-size: small;
margin: 6px auto 0;
padding: 0 4px 4px;
@@ -184,32 +146,18 @@ $GODOT_HEAD_INCLUDE
font-size: small;
font-family: "Lucida Console", Monaco, monospace;
}
-
-
-/* Export style include
- * ==================== */
-
-$GODOT_STYLE_INCLUDE
-
</style>
+$GODOT_HEAD_INCLUDE
</head>
<body>
<div id="container">
- <canvas id="canvas" width="$GODOT_CANVAS_WIDTH" height="$GODOT_CANVAS_HEIGHT" onclick="canvas.ownerDocument.defaultView.focus();" oncontextmenu="event.preventDefault();">
+ <canvas id="canvas" width="640" height="480" tabindex="0" oncontextmenu="event.preventDefault();">
HTML5 canvas appears to be unsupported in the current browser.<br />
Please try updating or use a different browser.
</canvas>
<div id="status-container">
<span id="status" class="godot" onclick="this.style.visibility='hidden';">Downloading page...</span>
</div>
- <div id="controls" class="godot">
- <label id="output-toggle"><input type="checkbox" checked="checked" autocomplete="off" onchange="Presentation.setOutputVisible(this.checked);" />Display Output</label>
- <!-- hidden until implemented
- <label><input class="postRun-enable" type="checkbox" disabled="disabled" autocomplete="off" />lock cursor</label>
- <label><input class="postRun-enable" type="checkbox" disabled="disabled" autocomplete="off" onchange="Presentation.setCanvasMaximized(this.checked);" />maximize</label>
- -->
- <button id="fullscreen" class="godot postRun-enable" type="button" disabled="disabled" autocomplete="off" onclick="Presentation.requestFullscreen();">Fullscreen</button>
- </div>
</div>
<div id="output-panel" class="godot">
<div id="output-header">
@@ -226,33 +174,9 @@ $GODOT_STYLE_INCLUDE
var canvasElement = document.getElementById("canvas");
var presentation = {
- postRun: [
- function() {
- var elements = document.getElementsByClassName("postRun-enable");
- Array.prototype.slice.call(elements).forEach(function(element) {
- element.disabled = false;
- });
- }
- ],
- requestFullscreen: function requestFullscreen() {
- if (typeof Module !== "undefined" && Module.requestFullscreen) {
- Module.requestFullscreen(false, false);
- }
- },
- /*
- requestPointerlock: function requestPointerlock() {
- if (typeof Module !== "undefined" && Module.requestPointerlock) {
- Module.requestPointerlock(false, false);
- }
- },
- setCanvasMaximized: function setCanvasMaximized(enabled) {
- if (typeof Module !== "undefined" && Module.setCanvasMaximized) {
- Module.setCanvasMaximized(enabled);
- }
- },
- */
+ postRun: [],
setStatusVisible: function setStatusVisible(visible) {
- statusElement.style.visibility = (visible?"visible":"hidden");
+ statusElement.style.visibility = (visible ? "visible" : "hidden");
},
setStatus: function setStatus(text) {
if (text.length === 0) {
@@ -288,18 +212,13 @@ $GODOT_STYLE_INCLUDE
window.onerror = function(event) { presentation.setStatus("Failure during start-up\nSee JavaScript console") };
- if ($GODOT_CONTROLS_ENABLED) { // controls enabled
- document.getElementById("controls").style.visibility="visible";
- }
-
if ($GODOT_DEBUG_ENABLED) { // debugging enabled
var outputRoot = document.getElementById("output-panel");
var outputElement = document.getElementById("output-scroll");
- var outputToggle = document.getElementById("output-toggle");
const maxOutputMessages = 400;
presentation.setOutputVisible = function setOutputVisible(visible) {
- outputRoot.style.display = (visible?"block":"none");
+ outputRoot.style.display = (visible ? "block" : "none");
};
presentation.clearOutput = function clearOutput() {
while (outputElement.firstChild) {
@@ -308,7 +227,6 @@ $GODOT_STYLE_INCLUDE
};
presentation.setOutputVisible(true);
- outputToggle.style.display = "inline";
presentation.print = function print(text) {
if (arguments.length > 1) {
@@ -347,56 +265,59 @@ $GODOT_STYLE_INCLUDE
})();
// Emscripten interface
- var Module = {
- TOTAL_MEMORY: $GODOT_TMEM,
- postRun: (function() {
- if (typeof Presentation !== "undefined" && Presentation.postRun instanceof Array) {
- return Presentation.postRun;
- }
- })(),
- print: function print(text) {
- if (arguments.length > 1) {
- text = Array.prototype.slice.call(arguments).join(" ");
- }
- console.log(text);
- if (typeof Presentation !== "undefined" && typeof Presentation.print === "function") {
- Presentation.print(text);
- }
- },
- printErr: function printErr(text) {
- if (arguments.length > 1) {
- text = Array.prototype.slice.call(arguments).join(" ");
- }
- console.error(text);
- if (typeof Presentation !== "undefined" && typeof Presentation.print === "function") {
- Presentation.print("**ERROR**:", text)
- }
- },
- canvas: (function() {
- var canvas = document.getElementById("canvas");
- // As a default initial behavior, pop up an alert when WebGL context is lost. To make your
- // application robust, you may want to override this behavior before shipping!
- // See http://www.khronos.org/registry/webgl/specs/latest/1.0/#5.15.2
- canvas.addEventListener("webglcontextlost", function(e) { alert("WebGL context lost. Plase reload the page."); e.preventDefault(); }, false);
- return canvas;
-
- })(),
- setStatus: function setStatus(text) {
- var m = text.match(/([^(]+)\((\d+(\.\d+)?)\/(\d+)\)/);
- var now = Date.now();
- if (m) {
- if (now - Date.now() < 30) // if this is a progress update, skip it if too soon
- return;
- text = m[1];
- }
- if (typeof Presentation !== "undefined" && typeof Presentation.setStatus == "function") {
- Presentation.setStatus(text);
+ var Module = (function() {
+ const BASE_NAME = '$GODOT_BASE';
+ var module = {
+ thisProgram: BASE_NAME,
+ wasmBinaryFile: BASE_NAME + '.wasm',
+ TOTAL_MEMORY: $GODOT_TMEM,
+ print: function print(text) {
+ if (arguments.length > 1) {
+ text = Array.prototype.slice.call(arguments).join(" ");
+ }
+ console.log(text);
+ if (typeof Presentation !== "undefined" && typeof Presentation.print === "function") {
+ Presentation.print(text);
+ }
+ },
+ printErr: function printErr(text) {
+ if (arguments.length > 1) {
+ text = Array.prototype.slice.call(arguments).join(" ");
+ }
+ console.error(text);
+ if (typeof Presentation !== "undefined" && typeof Presentation.print === "function") {
+ Presentation.print("**ERROR**:", text)
+ }
+ },
+ canvas: document.getElementById("canvas"),
+ setStatus: function setStatus(text) {
+ var m = text.match(/([^(]+)\((\d+(\.\d+)?)\/(\d+)\)/);
+ var now = Date.now();
+ if (m) {
+ if (now - Date.now() < 30) // if this is a progress update, skip it if too soon
+ return;
+ text = m[1];
+ }
+ if (typeof Presentation !== "undefined" && typeof Presentation.setStatus == "function") {
+ Presentation.setStatus(text);
+ }
}
+ };
+
+ // As a default initial behavior, pop up an alert when WebGL context is lost. To make your
+ // application robust, you may want to override this behavior before shipping!
+ // See http://www.khronos.org/registry/webgl/specs/latest/1.0/#5.15.2
+ module.canvas.addEventListener("webglcontextlost", function(e) { alert("WebGL context lost. Plase reload the page."); e.preventDefault(); }, false);
+
+ if (typeof Presentation !== "undefined" && Presentation.postRun instanceof Array) {
+ module.postRun = Presentation.postRun;
}
- };
+
+ return module;
+ })();
if (!Presentation.isWebGL2Available()) {
- Presentation.setStatus("WebGL2 appears to be unsupported in the current browser.\nPlease try updating or use a different browser.");
+ Presentation.setStatus("WebGL 2 appears to be unsupported.\nPlease update browser and drivers.");
Presentation.preventLoading = true;
} else {
Presentation.setStatus("Downloading...");
diff --git a/platform/javascript/javascript_eval.cpp b/platform/javascript/javascript_eval.cpp
index 897c2276bb..c9312e8d30 100644
--- a/platform/javascript/javascript_eval.cpp
+++ b/platform/javascript/javascript_eval.cpp
@@ -6,6 +6,7 @@
/* http://www.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 */
diff --git a/platform/javascript/javascript_eval.h b/platform/javascript/javascript_eval.h
index 0050b855d8..4a732cec76 100644
--- a/platform/javascript/javascript_eval.h
+++ b/platform/javascript/javascript_eval.h
@@ -6,6 +6,7 @@
/* http://www.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 */
diff --git a/platform/javascript/javascript_main.cpp b/platform/javascript/javascript_main.cpp
index 00e531baa1..6b1d574496 100644
--- a/platform/javascript/javascript_main.cpp
+++ b/platform/javascript/javascript_main.cpp
@@ -6,6 +6,7 @@
/* http://www.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 */
@@ -30,171 +31,50 @@
#include "io/resource_loader.h"
#include "main/main.h"
#include "os_javascript.h"
-#include <GL/glut.h>
-#include <string.h>
OS_JavaScript *os = NULL;
-static void _gfx_init(void *ud, bool gl2, int w, int h, bool fs) {
+static void main_loop() {
- glutInitWindowSize(w, h);
- glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
- glutCreateWindow("godot");
+ os->main_loop_iterate();
}
-static uint32_t _mouse_button_mask = 0;
+extern "C" void main_after_fs_sync() {
-static void _glut_mouse_button(int button, int state, int x, int y) {
-
- InputEvent ev;
- ev.type = InputEvent::MOUSE_BUTTON;
- switch (button) {
- case GLUT_LEFT_BUTTON: ev.mouse_button.button_index = BUTTON_LEFT; break;
- case GLUT_MIDDLE_BUTTON: ev.mouse_button.button_index = BUTTON_MIDDLE; break;
- case GLUT_RIGHT_BUTTON: ev.mouse_button.button_index = BUTTON_RIGHT; break;
- case 3: ev.mouse_button.button_index = BUTTON_WHEEL_UP; break;
- case 4: ev.mouse_button.button_index = BUTTON_WHEEL_DOWN; break;
- }
-
- ev.mouse_button.pressed = state == GLUT_DOWN;
- ev.mouse_button.x = x;
- ev.mouse_button.y = y;
- ev.mouse_button.global_x = x;
- ev.mouse_button.global_y = y;
-
- if (ev.mouse_button.button_index < 4) {
- if (ev.mouse_button.pressed) {
- _mouse_button_mask |= 1 << (ev.mouse_button.button_index - 1);
- } else {
- _mouse_button_mask &= ~(1 << (ev.mouse_button.button_index - 1));
- }
- }
- ev.mouse_button.button_mask = _mouse_button_mask;
-
- uint32_t m = glutGetModifiers();
- ev.mouse_button.mod.alt = (m & GLUT_ACTIVE_ALT) != 0;
- ev.mouse_button.mod.shift = (m & GLUT_ACTIVE_SHIFT) != 0;
- ev.mouse_button.mod.control = (m & GLUT_ACTIVE_CTRL) != 0;
-
- os->push_input(ev);
-
- if (ev.mouse_button.button_index == BUTTON_WHEEL_UP || ev.mouse_button.button_index == BUTTON_WHEEL_DOWN) {
- // GLUT doesn't send release events for mouse wheel, so send manually
- ev.mouse_button.pressed = false;
- os->push_input(ev);
- }
-}
-
-static int _glut_prev_x = 0;
-static int _glut_prev_y = 0;
-
-static void _glut_mouse_motion(int x, int y) {
-
- InputEvent ev;
- ev.type = InputEvent::MOUSE_MOTION;
- ev.mouse_motion.button_mask = _mouse_button_mask;
- ev.mouse_motion.x = x;
- ev.mouse_motion.y = y;
- ev.mouse_motion.global_x = x;
- ev.mouse_motion.global_y = y;
- ev.mouse_motion.relative_x = x - _glut_prev_x;
- ev.mouse_motion.relative_y = y - _glut_prev_y;
- _glut_prev_x = x;
- _glut_prev_y = y;
-
- uint32_t m = glutGetModifiers();
- ev.mouse_motion.mod.alt = (m & GLUT_ACTIVE_ALT) != 0;
- ev.mouse_motion.mod.shift = (m & GLUT_ACTIVE_SHIFT) != 0;
- ev.mouse_motion.mod.control = (m & GLUT_ACTIVE_CTRL) != 0;
-
- os->push_input(ev);
-}
-
-static void _gfx_idle() {
-
- glutPostRedisplay();
-}
-
-int start_step = 0;
-
-static void _godot_draw(void) {
-
- if (start_step == 1) {
- start_step = 2;
- Main::start();
- os->main_loop_begin();
- }
-
- if (start_step == 2) {
- os->main_loop_iterate();
- }
-
- glutSwapBuffers();
-}
-
-extern "C" {
-
-void main_after_fs_sync() {
-
- start_step = 1;
-}
+ // Ease up compatibility
+ ResourceLoader::set_abort_on_missing_resources(false);
+ Main::start();
+ os->main_loop_begin();
+ emscripten_set_main_loop(main_loop, 0, false);
}
int main(int argc, char *argv[]) {
- /* Initialize the window */
printf("let it go dude!\n");
- glutInit(&argc, argv);
- os = new OS_JavaScript(_gfx_init, NULL, NULL);
-#if 0
- char *args[]={"-test","gui","-v",NULL};
- Error err = Main::setup("apk",3,args);
-#else
- char *args[] = { "-main_pack", "data.pck", NULL }; //pass location of main pack manually, because it wont get an executable name
- Error err = Main::setup("", 2, args);
-
-#endif
- ResourceLoader::set_abort_on_missing_resources(false); //ease up compatibility
-
- glutMouseFunc(_glut_mouse_button);
- glutMotionFunc(_glut_mouse_motion);
- glutPassiveMotionFunc(_glut_mouse_motion);
- /* Set up glut callback functions */
- glutIdleFunc(_gfx_idle);
- // glutReshapeFunc(gears_reshape);
- glutDisplayFunc(_godot_draw);
- //glutSpecialFunc(gears_special);
-
- //mount persistent file system
+ // sync from persistent state into memory and then
+ // run the 'main_after_fs_sync' function
/* clang-format off */
EM_ASM(
+ Module.noExitRuntime = true;
FS.mkdir('/userfs');
FS.mount(IDBFS, {}, '/userfs');
-
- // sync from persistent state into memory and then
- // run the 'main_after_fs_sync' function
FS.syncfs(true, function(err) {
-
if (err) {
Module.setStatus('Failed to load persistent data\nPlease allow (third-party) cookies');
Module.printErr('Failed to populate IDB file system: ' + err.message);
- Module.exit();
+ Module.noExitRuntime = false;
} else {
Module.print('Successfully populated IDB file system');
- ccall('main_after_fs_sync', 'void', []);
+ ccall('main_after_fs_sync', null);
}
});
);
/* clang-format on */
- glutMainLoop();
+ os = new OS_JavaScript(argv[0], NULL);
+ Error err = Main::setup(argv[0], argc - 1, &argv[1]);
return 0;
+ // continued async in main_after_fs_sync() from syncfs() callback
}
-
-/*
- *
- *09] <azakai|2__> reduz: yes, define TOTAL_MEMORY on Module. for example var Module = { TOTAL_MEMORY: 12345.. }; before the main
- *
- */
diff --git a/platform/javascript/os_javascript.cpp b/platform/javascript/os_javascript.cpp
index 83072c30aa..d339baf024 100644
--- a/platform/javascript/os_javascript.cpp
+++ b/platform/javascript/os_javascript.cpp
@@ -6,6 +6,7 @@
/* http://www.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 */
@@ -28,8 +29,8 @@
/*************************************************************************/
#include "os_javascript.h"
-#include "core/global_config.h"
#include "core/io/file_access_buffered_fa.h"
+#include "core/project_settings.h"
#include "dom_keys.h"
#include "drivers/gles3/rasterizer_gles3.h"
#include "drivers/unix/dir_access_unix.h"
@@ -40,6 +41,19 @@
#include <emscripten.h>
#include <stdlib.h>
+#define DOM_BUTTON_LEFT 0
+#define DOM_BUTTON_MIDDLE 1
+#define DOM_BUTTON_RIGHT 2
+
+template <typename T>
+static void dom2godot_mod(T emscripten_event_ptr, Ref<InputEventWithModifiers> godot_event) {
+
+ godot_event->set_shift(emscripten_event_ptr->shiftKey);
+ godot_event->set_alt(emscripten_event_ptr->altKey);
+ godot_event->set_control(emscripten_event_ptr->ctrlKey);
+ godot_event->set_metakey(emscripten_event_ptr->metaKey);
+}
+
int OS_JavaScript::get_video_driver_count() const {
return 1;
@@ -82,30 +96,18 @@ static EM_BOOL _browser_resize_callback(int event_type, const EmscriptenUiEvent
ERR_FAIL_COND_V(event_type != EMSCRIPTEN_EVENT_RESIZE, false);
OS_JavaScript *os = static_cast<OS_JavaScript *>(user_data);
-
- // the order in which _browser_resize_callback and
- // _fullscreen_change_callback are called is browser-dependent,
- // so try adjusting for fullscreen in both
- if (os->is_window_fullscreen() || os->is_window_maximized()) {
-
- OS::VideoMode vm = os->get_video_mode();
- vm.width = ui_event->windowInnerWidth;
- vm.height = ui_event->windowInnerHeight;
- os->set_video_mode(vm);
- emscripten_set_canvas_size(ui_event->windowInnerWidth, ui_event->windowInnerHeight);
- }
+ // The order of the fullscreen change event and the window size change
+ // event varies, even within just one browser, so defer handling
+ os->request_canvas_size_adjustment();
return false;
}
-static Size2 _windowed_size;
-
static EM_BOOL _fullscreen_change_callback(int event_type, const EmscriptenFullscreenChangeEvent *event, void *user_data) {
ERR_FAIL_COND_V(event_type != EMSCRIPTEN_EVENT_FULLSCREENCHANGE, false);
OS_JavaScript *os = static_cast<OS_JavaScript *>(user_data);
String id = String::utf8(event->id);
-
// empty id is canvas
if (id.empty() || id == "canvas") {
@@ -113,32 +115,247 @@ static EM_BOOL _fullscreen_change_callback(int event_type, const EmscriptenFulls
// this event property is the only reliable information on
// browser fullscreen state
vm.fullscreen = event->isFullscreen;
+ os->set_video_mode(vm);
+ os->request_canvas_size_adjustment();
+ }
+ return false;
+}
- if (event->isFullscreen) {
- vm.width = event->screenWidth;
- vm.height = event->screenHeight;
- os->set_video_mode(vm);
- emscripten_set_canvas_size(vm.width, vm.height);
- } else {
- os->set_video_mode(vm);
- if (!os->is_window_maximized()) {
- os->set_window_size(_windowed_size);
- }
+static InputDefault *_input;
+
+static bool is_canvas_focused() {
+
+ /* clang-format off */
+ return EM_ASM_INT_V(
+ return document.activeElement == Module.canvas;
+ );
+ /* clang-format on */
+}
+
+static void focus_canvas() {
+
+ /* clang-format off */
+ EM_ASM(
+ Module.canvas.focus();
+ );
+ /* clang-format on */
+}
+
+static bool _cursor_inside_canvas = true;
+
+static bool is_cursor_inside_canvas() {
+
+ return _cursor_inside_canvas;
+}
+
+static EM_BOOL _mousebutton_callback(int event_type, const EmscriptenMouseEvent *mouse_event, void *user_data) {
+
+ ERR_FAIL_COND_V(event_type != EMSCRIPTEN_EVENT_MOUSEDOWN && event_type != EMSCRIPTEN_EVENT_MOUSEUP, false);
+
+ Ref<InputEventMouseButton> ev;
+ ev.instance();
+ ev->set_pressed(event_type == EMSCRIPTEN_EVENT_MOUSEDOWN);
+ ev->set_position(Point2(mouse_event->canvasX, mouse_event->canvasY));
+ ev->set_global_position(ev->get_position());
+ dom2godot_mod(mouse_event, ev);
+
+ switch (mouse_event->button) {
+ case DOM_BUTTON_LEFT: ev->set_button_index(BUTTON_LEFT); break;
+ case DOM_BUTTON_MIDDLE: ev->set_button_index(BUTTON_MIDDLE); break;
+ case DOM_BUTTON_RIGHT: ev->set_button_index(BUTTON_RIGHT); break;
+ default: return false;
+ }
+
+ int mask = _input->get_mouse_button_mask();
+ if (ev->is_pressed()) {
+ // since the event is consumed, focus manually
+ if (!is_canvas_focused()) {
+ focus_canvas();
}
+ mask |= 1 << ev->get_button_index();
+ } else if (mask & (1 << ev->get_button_index())) {
+ mask &= ~(1 << ev->get_button_index());
+ } else {
+ // release event, but press was outside the canvas, so ignore
+ return false;
}
+ ev->set_button_mask(mask >> 1);
+
+ _input->parse_input_event(ev);
+ // prevent selection dragging
+ return true;
+}
+
+static EM_BOOL _mousemove_callback(int event_type, const EmscriptenMouseEvent *mouse_event, void *user_data) {
+
+ ERR_FAIL_COND_V(event_type != EMSCRIPTEN_EVENT_MOUSEMOVE, false);
+ OS_JavaScript *os = static_cast<OS_JavaScript *>(user_data);
+ int input_mask = _input->get_mouse_button_mask();
+ Point2 pos = Point2(mouse_event->canvasX, mouse_event->canvasY);
+ // outside the canvas, only read mouse movement if dragging started inside
+ // the canvas; imitating desktop app behaviour
+ if (!is_cursor_inside_canvas() && !input_mask)
+ return false;
+
+ Ref<InputEventMouseMotion> ev;
+ ev.instance();
+ dom2godot_mod(mouse_event, ev);
+ ev->set_button_mask(input_mask >> 1);
+
+ ev->set_position(pos);
+ ev->set_global_position(ev->get_position());
+
+ ev->set_relative(_input->get_mouse_position() - ev->get_position());
+ _input->set_mouse_position(ev->get_position());
+ ev->set_speed(_input->get_last_mouse_speed());
+
+ _input->parse_input_event(ev);
+ // don't suppress mouseover/leave events
return false;
}
-static InputEvent _setup_key_event(const EmscriptenKeyboardEvent *emscripten_event) {
+static EM_BOOL _wheel_callback(int event_type, const EmscriptenWheelEvent *wheel_event, void *user_data) {
+
+ ERR_FAIL_COND_V(event_type != EMSCRIPTEN_EVENT_WHEEL, false);
+ if (!is_canvas_focused()) {
+ if (is_cursor_inside_canvas()) {
+ focus_canvas();
+ } else {
+ return false;
+ }
+ }
+
+ Ref<InputEventMouseButton> ev;
+ ev.instance();
+ ev->set_button_mask(_input->get_mouse_button_mask() >> 1);
+ ev->set_position(_input->get_mouse_position());
+ ev->set_global_position(ev->get_position());
+
+ ev->set_shift(_input->is_key_pressed(KEY_SHIFT));
+ ev->set_alt(_input->is_key_pressed(KEY_ALT));
+ ev->set_control(_input->is_key_pressed(KEY_CONTROL));
+ ev->set_metakey(_input->is_key_pressed(KEY_META));
+
+ if (wheel_event->deltaY < 0)
+ ev->set_button_index(BUTTON_WHEEL_UP);
+ else if (wheel_event->deltaY > 0)
+ ev->set_button_index(BUTTON_WHEEL_DOWN);
+ else if (wheel_event->deltaX > 0)
+ ev->set_button_index(BUTTON_WHEEL_LEFT);
+ else if (wheel_event->deltaX < 0)
+ ev->set_button_index(BUTTON_WHEEL_RIGHT);
+ else
+ return false;
+
+ // Different browsers give wildly different delta values, and we can't
+ // interpret deltaMode, so use default value for wheel events' factor
+
+ ev->set_pressed(true);
+ _input->parse_input_event(ev);
+
+ ev->set_pressed(false);
+ _input->parse_input_event(ev);
+
+ return true;
+}
+
+static Point2 _prev_touches[32];
+
+static EM_BOOL _touchpress_callback(int event_type, const EmscriptenTouchEvent *touch_event, void *user_data) {
+
+ ERR_FAIL_COND_V(
+ event_type != EMSCRIPTEN_EVENT_TOUCHSTART &&
+ event_type != EMSCRIPTEN_EVENT_TOUCHEND &&
+ event_type != EMSCRIPTEN_EVENT_TOUCHCANCEL,
+ false);
+
+ Ref<InputEventScreenTouch> ev;
+ ev.instance();
+ int lowest_id_index = -1;
+ for (int i = 0; i < touch_event->numTouches; ++i) {
+
+ const EmscriptenTouchPoint &touch = touch_event->touches[i];
+ if (lowest_id_index == -1 || touch.identifier < touch_event->touches[lowest_id_index].identifier)
+ lowest_id_index = i;
+ if (!touch.isChanged)
+ continue;
+ ev->set_index(touch.identifier);
+ ev->set_position(Point2(touch.canvasX, touch.canvasY));
+ _prev_touches[i] = ev->get_position();
+ ev->set_pressed(event_type == EMSCRIPTEN_EVENT_TOUCHSTART);
+
+ _input->parse_input_event(ev);
+ }
+
+ if (touch_event->touches[lowest_id_index].isChanged) {
+
+ Ref<InputEventMouseButton> ev_mouse;
+ ev_mouse.instance();
+ ev_mouse->set_button_mask(_input->get_mouse_button_mask() >> 1);
+ dom2godot_mod(touch_event, ev_mouse);
+
+ const EmscriptenTouchPoint &first_touch = touch_event->touches[lowest_id_index];
+ ev_mouse->set_position(Point2(first_touch.canvasX, first_touch.canvasY));
+ ev_mouse->set_global_position(ev_mouse->get_position());
+
+ ev_mouse->set_button_index(BUTTON_LEFT);
+ ev_mouse->set_pressed(event_type == EMSCRIPTEN_EVENT_TOUCHSTART);
+
+ _input->parse_input_event(ev_mouse);
+ }
+ return true;
+}
+
+static EM_BOOL _touchmove_callback(int event_type, const EmscriptenTouchEvent *touch_event, void *user_data) {
+
+ ERR_FAIL_COND_V(event_type != EMSCRIPTEN_EVENT_TOUCHMOVE, false);
+
+ Ref<InputEventScreenDrag> ev;
+ ev.instance();
+ int lowest_id_index = -1;
+ for (int i = 0; i < touch_event->numTouches; ++i) {
+
+ const EmscriptenTouchPoint &touch = touch_event->touches[i];
+ if (lowest_id_index == -1 || touch.identifier < touch_event->touches[lowest_id_index].identifier)
+ lowest_id_index = i;
+ if (!touch.isChanged)
+ continue;
+ ev->set_index(touch.identifier);
+ ev->set_position(Point2(touch.canvasX, touch.canvasY));
+ Point2 &prev = _prev_touches[i];
+ ev->set_relative(ev->get_position() - prev);
+ prev = ev->get_position();
+
+ _input->parse_input_event(ev);
+ }
+
+ if (touch_event->touches[lowest_id_index].isChanged) {
+
+ Ref<InputEventMouseMotion> ev_mouse;
+ ev_mouse.instance();
+ dom2godot_mod(touch_event, ev_mouse);
+ ev_mouse->set_button_mask(_input->get_mouse_button_mask() >> 1);
+
+ const EmscriptenTouchPoint &first_touch = touch_event->touches[lowest_id_index];
+ 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());
+ _input->set_mouse_position(ev_mouse->get_position());
+ ev_mouse->set_speed(_input->get_last_mouse_speed());
+
+ _input->parse_input_event(ev_mouse);
+ }
+ return true;
+}
+
+static Ref<InputEventKey> _setup_key_event(const EmscriptenKeyboardEvent *emscripten_event) {
- InputEvent ev;
- ev.type = InputEvent::KEY;
- ev.key.echo = emscripten_event->repeat;
- ev.key.mod.alt = emscripten_event->altKey;
- ev.key.mod.shift = emscripten_event->shiftKey;
- ev.key.mod.control = emscripten_event->ctrlKey;
- ev.key.mod.meta = emscripten_event->metaKey;
- ev.key.scancode = dom2godot_scancode(emscripten_event->keyCode);
+ Ref<InputEventKey> ev;
+ ev.instance();
+ ev->set_echo(emscripten_event->repeat);
+ dom2godot_mod(emscripten_event, ev);
+ ev->set_scancode(dom2godot_scancode(emscripten_event->keyCode));
String unicode = String::utf8(emscripten_event->key);
// check if empty or multi-character (e.g. `CapsLock`)
@@ -147,26 +364,26 @@ static InputEvent _setup_key_event(const EmscriptenKeyboardEvent *emscripten_eve
unicode = String::utf8(emscripten_event->charValue);
}
if (unicode.length() == 1) {
- ev.key.unicode = unicode[0];
+ ev->set_unicode(unicode[0]);
}
return ev;
}
-static InputEvent deferred_key_event;
+static Ref<InputEventKey> deferred_key_event;
static EM_BOOL _keydown_callback(int event_type, const EmscriptenKeyboardEvent *key_event, void *user_data) {
ERR_FAIL_COND_V(event_type != EMSCRIPTEN_EVENT_KEYDOWN, false);
- InputEvent ev = _setup_key_event(key_event);
- ev.key.pressed = true;
- if (ev.key.unicode == 0 && keycode_has_unicode(ev.key.scancode)) {
+ Ref<InputEventKey> ev = _setup_key_event(key_event);
+ ev->set_pressed(true);
+ if (ev->get_unicode() == 0 && keycode_has_unicode(ev->get_scancode())) {
// defer to keypress event for legacy unicode retrieval
deferred_key_event = ev;
return false; // do not suppress keypress event
}
- static_cast<OS_JavaScript *>(user_data)->push_input(ev);
+ _input->parse_input_event(ev);
return true;
}
@@ -174,8 +391,8 @@ static EM_BOOL _keypress_callback(int event_type, const EmscriptenKeyboardEvent
ERR_FAIL_COND_V(event_type != EMSCRIPTEN_EVENT_KEYPRESS, false);
- deferred_key_event.key.unicode = key_event->charCode;
- static_cast<OS_JavaScript *>(user_data)->push_input(deferred_key_event);
+ deferred_key_event->set_unicode(key_event->charCode);
+ _input->parse_input_event(deferred_key_event);
return true;
}
@@ -183,10 +400,10 @@ static EM_BOOL _keyup_callback(int event_type, const EmscriptenKeyboardEvent *ke
ERR_FAIL_COND_V(event_type != EMSCRIPTEN_EVENT_KEYUP, false);
- InputEvent ev = _setup_key_event(key_event);
- ev.key.pressed = false;
- static_cast<OS_JavaScript *>(user_data)->push_input(ev);
- return ev.key.scancode != KEY_UNKNOWN && ev.key.scancode != 0;
+ Ref<InputEventKey> ev = _setup_key_event(key_event);
+ ev->set_pressed(false);
+ _input->parse_input_event(ev);
+ return ev->get_scancode() != KEY_UNKNOWN && ev->get_scancode() != 0;
}
static EM_BOOL joy_callback_func(int p_type, const EmscriptenGamepadEvent *p_event, void *p_user) {
@@ -197,18 +414,31 @@ static EM_BOOL joy_callback_func(int p_type, const EmscriptenGamepadEvent *p_eve
return false;
}
+extern "C" {
+void send_notification(int notif) {
+ if (notif == MainLoop::NOTIFICATION_WM_MOUSE_ENTER || notif == MainLoop::NOTIFICATION_WM_MOUSE_EXIT) {
+ _cursor_inside_canvas = notif == MainLoop::NOTIFICATION_WM_MOUSE_ENTER;
+ }
+ OS_JavaScript::get_singleton()->get_main_loop()->notification(notif);
+}
+}
+
void OS_JavaScript::initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver) {
print_line("Init OS");
- if (gfx_init_func)
- gfx_init_func(gfx_init_ud, use_gl2, p_desired.width, p_desired.height, p_desired.fullscreen);
+ EmscriptenWebGLContextAttributes attributes;
+ emscripten_webgl_init_context_attributes(&attributes);
+ attributes.alpha = false;
+ attributes.antialias = false;
+ attributes.majorVersion = 2;
+ EMSCRIPTEN_WEBGL_CONTEXT_HANDLE ctx = emscripten_webgl_create_context(NULL, &attributes);
+ ERR_FAIL_COND(emscripten_webgl_make_context_current(ctx) != EMSCRIPTEN_RESULT_SUCCESS);
- // nothing to do here, can't fulfil fullscreen request due to
- // browser security, window size is already set from HTML
video_mode = p_desired;
+ // can't fulfil fullscreen request due to browser security
video_mode.fullscreen = false;
- _windowed_size = get_window_size();
+ set_window_size(Size2(p_desired.width, p_desired.height));
// find locale, emscripten only sets "C"
char locale_ptr[16];
@@ -246,7 +476,7 @@ void OS_JavaScript::initialize(const VideoMode &p_desired, int p_video_driver, i
print_line("Init VS");
visual_server = memnew(VisualServerRaster());
- visual_server->cursor_set_visible(false, 0);
+ // visual_server->cursor_set_visible(false, 0);
print_line("Init Physicsserver");
@@ -256,25 +486,34 @@ void OS_JavaScript::initialize(const VideoMode &p_desired, int p_video_driver, i
physics_2d_server->init();
input = memnew(InputDefault);
+ _input = input;
power_manager = memnew(PowerJavascript);
#define EM_CHECK(ev) \
if (result != EMSCRIPTEN_RESULT_SUCCESS) \
ERR_PRINTS("Error while setting " #ev " callback: Code " + itos(result))
-#define SET_EM_CALLBACK(ev, cb) \
- result = emscripten_set_##ev##_callback(NULL, this, true, &cb); \
+#define SET_EM_CALLBACK(target, ev, cb) \
+ result = emscripten_set_##ev##_callback(target, this, true, &cb); \
EM_CHECK(ev)
#define SET_EM_CALLBACK_NODATA(ev, cb) \
result = emscripten_set_##ev##_callback(NULL, true, &cb); \
EM_CHECK(ev)
EMSCRIPTEN_RESULT result;
- SET_EM_CALLBACK(keydown, _keydown_callback)
- SET_EM_CALLBACK(keypress, _keypress_callback)
- SET_EM_CALLBACK(keyup, _keyup_callback)
- SET_EM_CALLBACK(resize, _browser_resize_callback)
- SET_EM_CALLBACK(fullscreenchange, _fullscreen_change_callback)
+ SET_EM_CALLBACK("#window", mousemove, _mousemove_callback)
+ SET_EM_CALLBACK("#canvas", mousedown, _mousebutton_callback)
+ SET_EM_CALLBACK("#window", mouseup, _mousebutton_callback)
+ SET_EM_CALLBACK("#window", wheel, _wheel_callback)
+ SET_EM_CALLBACK("#window", touchstart, _touchpress_callback)
+ SET_EM_CALLBACK("#window", touchmove, _touchmove_callback)
+ SET_EM_CALLBACK("#window", touchend, _touchpress_callback)
+ SET_EM_CALLBACK("#window", touchcancel, _touchpress_callback)
+ SET_EM_CALLBACK("#canvas", keydown, _keydown_callback)
+ SET_EM_CALLBACK("#canvas", keypress, _keypress_callback)
+ SET_EM_CALLBACK("#canvas", keyup, _keyup_callback)
+ SET_EM_CALLBACK(NULL, resize, _browser_resize_callback)
+ SET_EM_CALLBACK(NULL, fullscreenchange, _fullscreen_change_callback)
SET_EM_CALLBACK_NODATA(gamepadconnected, joy_callback_func)
SET_EM_CALLBACK_NODATA(gamepaddisconnected, joy_callback_func)
@@ -282,9 +521,24 @@ void OS_JavaScript::initialize(const VideoMode &p_desired, int p_video_driver, i
#undef SET_EM_CALLBACK
#undef EM_CHECK
+ /* clang-format off */
+ EM_ASM_ARGS({
+ const send_notification = Module.cwrap('send_notification', null, ['number']);
+ const notifs = arguments;
+ (['mouseover', 'mouseleave', 'focus', 'blur']).forEach(function(event, i) {
+ Module.canvas.addEventListener(event, send_notification.bind(this, notifs[i]));
+ });
+ },
+ MainLoop::NOTIFICATION_WM_MOUSE_ENTER,
+ MainLoop::NOTIFICATION_WM_MOUSE_EXIT,
+ MainLoop::NOTIFICATION_WM_FOCUS_IN,
+ MainLoop::NOTIFICATION_WM_FOCUS_OUT
+ );
+/* clang-format on */
+
#ifdef JAVASCRIPT_EVAL_ENABLED
javascript_eval = memnew(JavaScript);
- GlobalConfig::get_singleton()->add_singleton(GlobalConfig::Singleton("JavaScript", javascript_eval));
+ ProjectSettings::get_singleton()->add_singleton(ProjectSettings::Singleton("JavaScript", javascript_eval));
#endif
visual_server->init();
@@ -315,30 +569,97 @@ void OS_JavaScript::alert(const String &p_alert, const String &p_title) {
/* clang-format on */
}
-void OS_JavaScript::set_mouse_show(bool p_show) {
+static const char *godot2dom_cursor(OS::CursorShape p_shape) {
+
+ switch (p_shape) {
+ case OS::CURSOR_ARROW:
+ default:
+ return "auto";
+ case OS::CURSOR_IBEAM: return "text";
+ case OS::CURSOR_POINTING_HAND: return "pointer";
+ case OS::CURSOR_CROSS: return "crosshair";
+ case OS::CURSOR_WAIT: return "progress";
+ case OS::CURSOR_BUSY: return "wait";
+ case OS::CURSOR_DRAG: return "grab";
+ case OS::CURSOR_CAN_DROP: return "grabbing";
+ case OS::CURSOR_FORBIDDEN: return "no-drop";
+ case OS::CURSOR_VSIZE: return "ns-resize";
+ case OS::CURSOR_HSIZE: return "ew-resize";
+ case OS::CURSOR_BDIAGSIZE: return "nesw-resize";
+ case OS::CURSOR_FDIAGSIZE: return "nwse-resize";
+ case OS::CURSOR_MOVE: return "move";
+ case OS::CURSOR_VSPLIT: return "row-resize";
+ case OS::CURSOR_HSPLIT: return "col-resize";
+ case OS::CURSOR_HELP: return "help";
+ }
+}
+
+void OS_JavaScript::set_css_cursor(const char *p_cursor) {
- //javascript has no mouse...
+ /* clang-format off */
+ EM_ASM_({
+ Module.canvas.style.cursor = Module.UTF8ToString($0);
+ }, p_cursor);
+ /* clang-format on */
}
-void OS_JavaScript::set_mouse_grab(bool p_grab) {
+const char *OS_JavaScript::get_css_cursor() const {
- //it really has no mouse...!
+ char cursor[16];
+ /* clang-format off */
+ EM_ASM_INT({
+ Module.stringToUTF8(Module.canvas.style.cursor ? Module.canvas.style.cursor : 'auto', $0, 16);
+ }, cursor);
+ /* clang-format on */
+ return cursor;
}
-bool OS_JavaScript::is_mouse_grab_enabled() const {
+void OS_JavaScript::set_mouse_mode(OS::MouseMode p_mode) {
- //*sigh* technology has evolved so much since i was a kid..
- return false;
+ ERR_FAIL_INDEX(p_mode, MOUSE_MODE_CONFINED + 1);
+ ERR_EXPLAIN("MOUSE_MODE_CONFINED is not supported for the HTML5 platform");
+ ERR_FAIL_COND(p_mode == MOUSE_MODE_CONFINED);
+ if (p_mode == get_mouse_mode())
+ return;
+
+ if (p_mode == MOUSE_MODE_VISIBLE) {
+
+ set_css_cursor(godot2dom_cursor(cursor_shape));
+ emscripten_exit_pointerlock();
+
+ } else if (p_mode == MOUSE_MODE_HIDDEN) {
+
+ set_css_cursor("none");
+ emscripten_exit_pointerlock();
+
+ } else if (p_mode == MOUSE_MODE_CAPTURED) {
+
+ EMSCRIPTEN_RESULT result = emscripten_request_pointerlock("canvas", false);
+ ERR_EXPLAIN("MOUSE_MODE_CAPTURED can only be entered from within an appropriate input callback");
+ ERR_FAIL_COND(result == EMSCRIPTEN_RESULT_FAILED_NOT_DEFERRED);
+ ERR_FAIL_COND(result != EMSCRIPTEN_RESULT_SUCCESS);
+ set_css_cursor(godot2dom_cursor(cursor_shape));
+ }
+}
+
+OS::MouseMode OS_JavaScript::get_mouse_mode() const {
+
+ if (!strcmp(get_css_cursor(), "none"))
+ return MOUSE_MODE_HIDDEN;
+
+ EmscriptenPointerlockChangeEvent ev;
+ emscripten_get_pointerlock_status(&ev);
+ return ev.isActive && (strcmp(ev.id, "canvas") == 0) ? MOUSE_MODE_CAPTURED : MOUSE_MODE_VISIBLE;
}
-Point2 OS_JavaScript::get_mouse_pos() const {
+Point2 OS_JavaScript::get_mouse_position() const {
- return input->get_mouse_pos();
+ return input->get_mouse_position();
}
int OS_JavaScript::get_mouse_button_state() const {
- return last_button_mask;
+ return input->get_mouse_button_mask();
}
void OS_JavaScript::set_window_title(const String &p_title) {
@@ -376,14 +697,17 @@ Size2 OS_JavaScript::get_screen_size(int p_screen) const {
void OS_JavaScript::set_window_size(const Size2 p_size) {
- window_maximized = false;
+ windowed_size = p_size;
if (is_window_fullscreen()) {
+ window_maximized = false;
set_window_fullscreen(false);
+ } else if (is_window_maximized()) {
+ set_window_maximized(false);
+ } else {
+ video_mode.width = p_size.x;
+ video_mode.height = p_size.y;
+ emscripten_set_canvas_size(p_size.x, p_size.y);
}
- _windowed_size = p_size;
- video_mode.width = p_size.x;
- video_mode.height = p_size.y;
- emscripten_set_canvas_size(p_size.x, p_size.y);
}
Size2 OS_JavaScript::get_window_size() const {
@@ -396,20 +720,30 @@ Size2 OS_JavaScript::get_window_size() const {
void OS_JavaScript::set_window_maximized(bool p_enabled) {
window_maximized = p_enabled;
- if (p_enabled) {
-
- if (is_window_fullscreen()) {
- // _browser_resize callback will set canvas size
- set_window_fullscreen(false);
- } else {
- /* clang-format off */
- video_mode.width = EM_ASM_INT_V(return window.innerWidth);
- video_mode.height = EM_ASM_INT_V(return window.innerHeight);
- /* clang-format on */
- emscripten_set_canvas_size(video_mode.width, video_mode.height);
- }
- } else {
- set_window_size(_windowed_size);
+ if (is_window_fullscreen()) {
+ set_window_fullscreen(false);
+ return;
+ }
+ // Calling emscripten_enter_soft_fullscreen mutltiple times hides all
+ // page elements except the canvas permanently, so track state
+ if (p_enabled && !soft_fs_enabled) {
+
+ EmscriptenFullscreenStrategy strategy;
+ strategy.scaleMode = EMSCRIPTEN_FULLSCREEN_SCALE_STRETCH;
+ strategy.canvasResolutionScaleMode = EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_STDDEF;
+ strategy.filteringMode = EMSCRIPTEN_FULLSCREEN_FILTERING_DEFAULT;
+ strategy.canvasResizedCallback = NULL;
+ emscripten_enter_soft_fullscreen(NULL, &strategy);
+ soft_fs_enabled = true;
+ video_mode.width = get_window_size().width;
+ video_mode.height = get_window_size().height;
+ } else if (!p_enabled) {
+
+ emscripten_exit_soft_fullscreen();
+ soft_fs_enabled = false;
+ video_mode.width = windowed_size.width;
+ video_mode.height = windowed_size.height;
+ emscripten_set_canvas_size(video_mode.width, video_mode.height);
}
}
@@ -423,9 +757,17 @@ void OS_JavaScript::set_window_fullscreen(bool p_enable) {
// _browser_resize_callback or _fullscreen_change_callback
EMSCRIPTEN_RESULT result;
if (p_enable) {
- /* clang-format off */
- EM_ASM(Module.requestFullscreen(false, false););
- /* clang-format on */
+ if (window_maximized) {
+ // soft fs during real fs can cause issues
+ set_window_maximized(false);
+ window_maximized = true;
+ }
+ EmscriptenFullscreenStrategy strategy;
+ strategy.scaleMode = EMSCRIPTEN_FULLSCREEN_SCALE_STRETCH;
+ strategy.canvasResolutionScaleMode = EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_STDDEF;
+ strategy.filteringMode = EMSCRIPTEN_FULLSCREEN_FILTERING_DEFAULT;
+ strategy.canvasResizedCallback = NULL;
+ emscripten_request_fullscreen_strategy(NULL, false, &strategy);
} else {
result = emscripten_exit_fullscreen();
if (result != EMSCRIPTEN_RESULT_SUCCESS) {
@@ -439,6 +781,11 @@ bool OS_JavaScript::is_window_fullscreen() const {
return video_mode.fullscreen;
}
+void OS_JavaScript::request_canvas_size_adjustment() {
+
+ canvas_size_adjustment_requested = true;
+}
+
void OS_JavaScript::get_fullscreen_mode_list(List<VideoMode> *p_list, int p_screen) const {
Size2 screen = get_screen_size();
@@ -462,7 +809,11 @@ bool OS_JavaScript::can_draw() const {
void OS_JavaScript::set_cursor_shape(CursorShape p_shape) {
- //javascript really really really has no mouse.. how amazing..
+ ERR_FAIL_INDEX(p_shape, CURSOR_MAX);
+
+ cursor_shape = p_shape;
+ if (get_mouse_mode() != MOUSE_MODE_HIDDEN)
+ set_css_cursor(godot2dom_cursor(cursor_shape));
}
void OS_JavaScript::main_loop_begin() {
@@ -494,6 +845,17 @@ bool OS_JavaScript::main_loop_iterate() {
}
}
process_joypads();
+ if (canvas_size_adjustment_requested) {
+
+ if (video_mode.fullscreen || window_maximized) {
+ video_mode.width = get_window_size().width;
+ video_mode.height = get_window_size().height;
+ }
+ if (!video_mode.fullscreen) {
+ set_window_maximized(window_maximized);
+ }
+ canvas_size_adjustment_requested = false;
+ }
return Main::iteration();
}
@@ -503,222 +865,6 @@ void OS_JavaScript::main_loop_end() {
main_loop->finish();
}
-void OS_JavaScript::main_loop_focusout() {
-
- if (main_loop)
- main_loop->notification(MainLoop::NOTIFICATION_WM_FOCUS_OUT);
- //audio_driver_javascript.set_pause(true);
-}
-
-void OS_JavaScript::main_loop_focusin() {
-
- if (main_loop)
- main_loop->notification(MainLoop::NOTIFICATION_WM_FOCUS_IN);
- //audio_driver_javascript.set_pause(false);
-}
-
-void OS_JavaScript::push_input(const InputEvent &p_ev) {
-
- InputEvent ev = p_ev;
- ev.ID = last_id++;
- if (ev.type == InputEvent::MOUSE_MOTION) {
- input->set_mouse_pos(Point2(ev.mouse_motion.x, ev.mouse_motion.y));
- } else if (ev.type == InputEvent::MOUSE_BUTTON) {
- last_button_mask = ev.mouse_button.button_mask;
- }
- input->parse_input_event(p_ev);
-}
-
-void OS_JavaScript::process_touch(int p_what, int p_pointer, const Vector<TouchPos> &p_points) {
-
- //print_line("ev: "+itos(p_what)+" pnt: "+itos(p_pointer)+" pointc: "+itos(p_points.size()));
-
- switch (p_what) {
- case 0: { //gesture begin
-
- if (touch.size()) {
- //end all if exist
- InputEvent ev;
- ev.type = InputEvent::MOUSE_BUTTON;
- ev.ID = last_id++;
- ev.mouse_button.button_index = BUTTON_LEFT;
- ev.mouse_button.button_mask = BUTTON_MASK_LEFT;
- ev.mouse_button.pressed = false;
- ev.mouse_button.x = touch[0].pos.x;
- ev.mouse_button.y = touch[0].pos.y;
- ev.mouse_button.global_x = touch[0].pos.x;
- ev.mouse_button.global_y = touch[0].pos.y;
- input->parse_input_event(ev);
-
- for (int i = 0; i < touch.size(); i++) {
-
- InputEvent ev;
- ev.type = InputEvent::SCREEN_TOUCH;
- ev.ID = last_id++;
- ev.screen_touch.index = touch[i].id;
- ev.screen_touch.pressed = false;
- ev.screen_touch.x = touch[i].pos.x;
- ev.screen_touch.y = touch[i].pos.y;
- input->parse_input_event(ev);
- }
- }
-
- touch.resize(p_points.size());
- for (int i = 0; i < p_points.size(); i++) {
- touch[i].id = p_points[i].id;
- touch[i].pos = p_points[i].pos;
- }
-
- {
- //send mouse
- InputEvent ev;
- ev.type = InputEvent::MOUSE_BUTTON;
- ev.ID = last_id++;
- ev.mouse_button.button_index = BUTTON_LEFT;
- ev.mouse_button.button_mask = BUTTON_MASK_LEFT;
- ev.mouse_button.pressed = true;
- ev.mouse_button.x = touch[0].pos.x;
- ev.mouse_button.y = touch[0].pos.y;
- ev.mouse_button.global_x = touch[0].pos.x;
- ev.mouse_button.global_y = touch[0].pos.y;
- last_mouse = touch[0].pos;
- input->parse_input_event(ev);
- }
-
- //send touch
- for (int i = 0; i < touch.size(); i++) {
-
- InputEvent ev;
- ev.type = InputEvent::SCREEN_TOUCH;
- ev.ID = last_id++;
- ev.screen_touch.index = touch[i].id;
- ev.screen_touch.pressed = true;
- ev.screen_touch.x = touch[i].pos.x;
- ev.screen_touch.y = touch[i].pos.y;
- input->parse_input_event(ev);
- }
-
- } break;
- case 1: { //motion
-
- if (p_points.size()) {
- //send mouse, should look for point 0?
- InputEvent ev;
- ev.type = InputEvent::MOUSE_MOTION;
- ev.ID = last_id++;
- ev.mouse_motion.button_mask = BUTTON_MASK_LEFT;
- ev.mouse_motion.x = p_points[0].pos.x;
- ev.mouse_motion.y = p_points[0].pos.y;
- input->set_mouse_pos(Point2(ev.mouse_motion.x, ev.mouse_motion.y));
- ev.mouse_motion.speed_x = input->get_last_mouse_speed().x;
- ev.mouse_motion.speed_y = input->get_last_mouse_speed().y;
- ev.mouse_motion.relative_x = p_points[0].pos.x - last_mouse.x;
- ev.mouse_motion.relative_y = p_points[0].pos.y - last_mouse.y;
- last_mouse = p_points[0].pos;
- input->parse_input_event(ev);
- }
-
- ERR_FAIL_COND(touch.size() != p_points.size());
-
- for (int i = 0; i < touch.size(); i++) {
-
- int idx = -1;
- for (int j = 0; j < p_points.size(); j++) {
-
- if (touch[i].id == p_points[j].id) {
- idx = j;
- break;
- }
- }
-
- ERR_CONTINUE(idx == -1);
-
- if (touch[i].pos == p_points[idx].pos)
- continue; //no move unncesearily
-
- InputEvent ev;
- ev.type = InputEvent::SCREEN_DRAG;
- ev.ID = last_id++;
- ev.screen_drag.index = touch[i].id;
- ev.screen_drag.x = p_points[idx].pos.x;
- ev.screen_drag.y = p_points[idx].pos.y;
- ev.screen_drag.relative_x = p_points[idx].pos.x - touch[i].pos.x;
- ev.screen_drag.relative_y = p_points[idx].pos.y - touch[i].pos.y;
- input->parse_input_event(ev);
- touch[i].pos = p_points[idx].pos;
- }
-
- } break;
- case 2: { //release
-
- if (touch.size()) {
- //end all if exist
- InputEvent ev;
- ev.type = InputEvent::MOUSE_BUTTON;
- ev.ID = last_id++;
- ev.mouse_button.button_index = BUTTON_LEFT;
- ev.mouse_button.button_mask = BUTTON_MASK_LEFT;
- ev.mouse_button.pressed = false;
- ev.mouse_button.x = touch[0].pos.x;
- ev.mouse_button.y = touch[0].pos.y;
- ev.mouse_button.global_x = touch[0].pos.x;
- ev.mouse_button.global_y = touch[0].pos.y;
- input->parse_input_event(ev);
-
- for (int i = 0; i < touch.size(); i++) {
-
- InputEvent ev;
- ev.type = InputEvent::SCREEN_TOUCH;
- ev.ID = last_id++;
- ev.screen_touch.index = touch[i].id;
- ev.screen_touch.pressed = false;
- ev.screen_touch.x = touch[i].pos.x;
- ev.screen_touch.y = touch[i].pos.y;
- input->parse_input_event(ev);
- }
- touch.clear();
- }
-
- } break;
- case 3: { // add tuchi
-
- ERR_FAIL_INDEX(p_pointer, p_points.size());
-
- TouchPos tp = p_points[p_pointer];
- touch.push_back(tp);
-
- InputEvent ev;
- ev.type = InputEvent::SCREEN_TOUCH;
- ev.ID = last_id++;
- ev.screen_touch.index = tp.id;
- ev.screen_touch.pressed = true;
- ev.screen_touch.x = tp.pos.x;
- ev.screen_touch.y = tp.pos.y;
- input->parse_input_event(ev);
-
- } break;
- case 4: {
-
- for (int i = 0; i < touch.size(); i++) {
- if (touch[i].id == p_pointer) {
-
- InputEvent ev;
- ev.type = InputEvent::SCREEN_TOUCH;
- ev.ID = last_id++;
- ev.screen_touch.index = touch[i].id;
- ev.screen_touch.pressed = false;
- ev.screen_touch.x = touch[i].pos.x;
- ev.screen_touch.y = touch[i].pos.y;
- input->parse_input_event(ev);
- touch.remove(i);
- i--;
- }
- }
-
- } break;
- }
-}
-
void OS_JavaScript::process_accelerometer(const Vector3 &p_accelerometer) {
input->set_accelerometer(p_accelerometer);
@@ -726,7 +872,11 @@ void OS_JavaScript::process_accelerometer(const Vector3 &p_accelerometer) {
bool OS_JavaScript::has_touchscreen_ui_hint() const {
- return false; //???
+ /* clang-format off */
+ return EM_ASM_INT_V(
+ return 'ontouchstart' in window;
+ );
+ /* clang-format on */
}
void OS_JavaScript::main_loop_request_quit() {
@@ -756,12 +906,12 @@ String OS_JavaScript::get_data_dir() const {
return get_data_dir_func();
*/
return "/userfs";
- //return GlobalConfig::get_singleton()->get_singleton_object("GodotOS")->call("get_data_dir");
+ //return ProjectSettings::get_singleton()->get_singleton_object("GodotOS")->call("get_data_dir");
};
String OS_JavaScript::get_executable_path() const {
- return String();
+ return OS::get_executable_path();
}
void OS_JavaScript::_close_notification_funcs(const String &p_file, int p_flags) {
@@ -790,9 +940,9 @@ void OS_JavaScript::process_joypads() {
InputDefault::JoyAxis jx;
jx.min = 0;
jx.value = value;
- last_id = input->joy_axis(last_id, i, j, jx);
+ input->joy_axis(i, j, jx);
} else {
- last_id = input->joy_button(last_id, i, j, value);
+ input->joy_button(i, j, value);
}
}
for (int j = 0; j < num_axes; j++) {
@@ -800,7 +950,7 @@ void OS_JavaScript::process_joypads() {
InputDefault::JoyAxis jx;
jx.min = -1;
jx.value = state.axis[j];
- last_id = input->joy_axis(last_id, i, j, jx);
+ input->joy_axis(i, j, jx);
}
}
}
@@ -839,14 +989,18 @@ int OS_JavaScript::get_power_percent_left() {
return power_manager->get_power_percent_left();
}
-OS_JavaScript::OS_JavaScript(GFXInitFunc p_gfx_init_func, void *p_gfx_init_ud, GetDataDirFunc p_get_data_dir_func) {
- gfx_init_func = p_gfx_init_func;
- gfx_init_ud = p_gfx_init_ud;
- last_button_mask = 0;
+bool OS_JavaScript::_check_internal_feature_support(const String &p_feature) {
+
+ return p_feature == "web" || p_feature == "s3tc"; // TODO check for these features really being available
+}
+
+OS_JavaScript::OS_JavaScript(const char *p_execpath, GetDataDirFunc p_get_data_dir_func) {
+ set_cmdline(p_execpath, get_cmdline_args());
main_loop = NULL;
- last_id = 1;
gl_extensions = NULL;
window_maximized = false;
+ soft_fs_enabled = false;
+ canvas_size_adjustment_requested = false;
get_data_dir_func = p_get_data_dir_func;
FileAccessUnix::close_notification_func = _close_notification_funcs;
diff --git a/platform/javascript/os_javascript.h b/platform/javascript/os_javascript.h
index b16918b2da..13c500b3dc 100644
--- a/platform/javascript/os_javascript.h
+++ b/platform/javascript/os_javascript.h
@@ -6,6 +6,7 @@
/* http://www.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 */
@@ -44,25 +45,9 @@
#include <emscripten/html5.h>
-typedef void (*GFXInitFunc)(void *ud, bool gl2, int w, int h, bool fs);
typedef String (*GetDataDirFunc)();
class OS_JavaScript : public OS_Unix {
-public:
- struct TouchPos {
- int id;
- Point2 pos;
- };
-
-private:
- Vector<TouchPos> touch;
- Point2 last_mouse;
- int last_button_mask;
- unsigned int last_id;
- GFXInitFunc gfx_init_func;
- void *gfx_init_ud;
-
- bool use_gl2;
int64_t time_to_save_sync;
int64_t last_sync_time;
@@ -74,8 +59,12 @@ private:
const char *gl_extensions;
InputDefault *input;
+ Vector2 windowed_size;
bool window_maximized;
+ bool soft_fs_enabled;
+ bool canvas_size_adjustment_requested;
VideoMode video_mode;
+ CursorShape cursor_shape;
MainLoop *main_loop;
GetDataDirFunc get_data_dir_func;
@@ -90,6 +79,9 @@ private:
void process_joypads();
+ void set_css_cursor(const char *);
+ const char *get_css_cursor() const;
+
public:
// functions used by main to initialize/deintialize the OS
virtual int get_video_driver_count() const;
@@ -119,10 +111,9 @@ public:
virtual void alert(const String &p_alert, const String &p_title = "ALERT!");
- virtual void set_mouse_show(bool p_show);
- virtual void set_mouse_grab(bool p_grab);
- virtual bool is_mouse_grab_enabled() const;
- virtual Point2 get_mouse_pos() const;
+ virtual void set_mouse_mode(MouseMode p_mode);
+ virtual MouseMode get_mouse_mode() const;
+ virtual Point2 get_mouse_position() const;
virtual int get_mouse_button_state() const;
virtual void set_window_title(const String &p_title);
@@ -142,6 +133,8 @@ public:
virtual void set_window_fullscreen(bool p_enable);
virtual bool is_window_fullscreen() const;
+ void request_canvas_size_adjustment();
+
virtual String get_name();
virtual MainLoop *get_main_loop() const;
@@ -166,8 +159,7 @@ public:
virtual String get_resource_dir() const;
void process_accelerometer(const Vector3 &p_accelerometer);
- void process_touch(int p_what, int p_pointer, const Vector<TouchPos> &p_points);
- void push_input(const InputEvent &p_ev);
+ void push_input(const Ref<InputEvent> &p_ev);
virtual bool is_joy_known(int p_device);
virtual String get_joy_guid(int p_device) const;
@@ -177,7 +169,9 @@ public:
virtual int get_power_seconds_left();
virtual int get_power_percent_left();
- OS_JavaScript(GFXInitFunc p_gfx_init_func, void *p_gfx_init_ud, GetDataDirFunc p_get_data_dir_func);
+ virtual bool _check_internal_feature_support(const String &p_feature);
+
+ OS_JavaScript(const char *p_execpath, GetDataDirFunc p_get_data_dir_func);
~OS_JavaScript();
};
diff --git a/platform/javascript/platform_config.h b/platform/javascript/platform_config.h
index cdef185ff0..48bcadcc29 100644
--- a/platform/javascript/platform_config.h
+++ b/platform/javascript/platform_config.h
@@ -6,6 +6,7 @@
/* http://www.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 */
diff --git a/platform/javascript/power_javascript.cpp b/platform/javascript/power_javascript.cpp
index 24158a34fe..bd4502fc2a 100644
--- a/platform/javascript/power_javascript.cpp
+++ b/platform/javascript/power_javascript.cpp
@@ -6,6 +6,7 @@
/* http://www.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 */
diff --git a/platform/javascript/power_javascript.h b/platform/javascript/power_javascript.h
index 78a896c430..c7b853ce11 100644
--- a/platform/javascript/power_javascript.h
+++ b/platform/javascript/power_javascript.h
@@ -6,6 +6,7 @@
/* http://www.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 */
diff --git a/platform/javascript/run_icon.png b/platform/javascript/run_icon.png
new file mode 100644
index 0000000000..dedee6f479
--- /dev/null
+++ b/platform/javascript/run_icon.png
Binary files differ
diff --git a/platform/osx/SCsub b/platform/osx/SCsub
index 1427c2e00d..27117c2e8d 100644
--- a/platform/osx/SCsub
+++ b/platform/osx/SCsub
@@ -7,7 +7,6 @@ files = [
'godot_main_osx.mm',
'audio_driver_osx.cpp',
'sem_osx.cpp',
- # 'context_gl_osx.cpp',
'dir_access_osx.mm',
'joypad_osx.cpp',
'power_osx.cpp',
diff --git a/platform/osx/audio_driver_osx.cpp b/platform/osx/audio_driver_osx.cpp
index 7ef0669656..d7a91b1653 100644
--- a/platform/osx/audio_driver_osx.cpp
+++ b/platform/osx/audio_driver_osx.cpp
@@ -6,6 +6,7 @@
/* http://www.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 */
@@ -30,11 +31,15 @@
#include "audio_driver_osx.h"
-Error AudioDriverOSX::init() {
+static OSStatus outputDeviceAddressCB(AudioObjectID inObjectID, UInt32 inNumberAddresses, const AudioObjectPropertyAddress *inAddresses, void *__nullable inClientData) {
+ AudioDriverOSX *driver = (AudioDriverOSX *)inClientData;
- active = false;
- channels = 2;
+ driver->reopen();
+ return noErr;
+}
+
+Error AudioDriverOSX::initDevice() {
AudioStreamBasicDescription strdesc;
strdesc.mFormatID = kAudioFormatLinearPCM;
strdesc.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger | kLinearPCMFormatFlagIsPacked;
@@ -42,12 +47,10 @@ Error AudioDriverOSX::init() {
strdesc.mSampleRate = 44100;
strdesc.mFramesPerPacket = 1;
strdesc.mBitsPerChannel = 16;
- strdesc.mBytesPerFrame =
- strdesc.mBitsPerChannel * strdesc.mChannelsPerFrame / 8;
- strdesc.mBytesPerPacket =
- strdesc.mBytesPerFrame * strdesc.mFramesPerPacket;
+ strdesc.mBytesPerFrame = strdesc.mBitsPerChannel * strdesc.mChannelsPerFrame / 8;
+ strdesc.mBytesPerPacket = strdesc.mBytesPerFrame * strdesc.mFramesPerPacket;
- OSStatus result = noErr;
+ OSStatus result;
AURenderCallbackStruct callback;
AudioComponentDescription desc;
AudioComponent comp = NULL;
@@ -57,83 +60,130 @@ Error AudioDriverOSX::init() {
zeromem(&desc, sizeof(desc));
desc.componentType = kAudioUnitType_Output;
- desc.componentSubType = 0; /* !!! FIXME: ? */
- comp = AudioComponentFindNext(NULL, &desc);
+ desc.componentSubType = kAudioUnitSubType_HALOutput;
desc.componentManufacturer = kAudioUnitManufacturer_Apple;
+ comp = AudioComponentFindNext(NULL, &desc);
+ ERR_FAIL_COND_V(comp == NULL, FAILED);
+
result = AudioComponentInstanceNew(comp, &audio_unit);
ERR_FAIL_COND_V(result != noErr, FAILED);
- ERR_FAIL_COND_V(comp == NULL, FAILED);
- result = AudioUnitSetProperty(audio_unit,
- kAudioUnitProperty_StreamFormat,
- scope, bus, &strdesc, sizeof(strdesc));
+ result = AudioUnitSetProperty(audio_unit, kAudioUnitProperty_StreamFormat, scope, bus, &strdesc, sizeof(strdesc));
ERR_FAIL_COND_V(result != noErr, FAILED);
zeromem(&callback, sizeof(AURenderCallbackStruct));
callback.inputProc = &AudioDriverOSX::output_callback;
callback.inputProcRefCon = this;
- result = AudioUnitSetProperty(audio_unit,
- kAudioUnitProperty_SetRenderCallback,
- scope, bus, &callback, sizeof(callback));
+ result = AudioUnitSetProperty(audio_unit, kAudioUnitProperty_SetRenderCallback, scope, bus, &callback, sizeof(callback));
ERR_FAIL_COND_V(result != noErr, FAILED);
result = AudioUnitInitialize(audio_unit);
ERR_FAIL_COND_V(result != noErr, FAILED);
- result = AudioOutputUnitStart(audio_unit);
+ return OK;
+}
+
+Error AudioDriverOSX::finishDevice() {
+ OSStatus result;
+
+ if (active) {
+ result = AudioOutputUnitStop(audio_unit);
+ ERR_FAIL_COND_V(result != noErr, FAILED);
+
+ active = false;
+ }
+
+ result = AudioUnitUninitialize(audio_unit);
+ ERR_FAIL_COND_V(result != noErr, FAILED);
+
+ return OK;
+}
+
+Error AudioDriverOSX::init() {
+ OSStatus result;
+
+ mutex = Mutex::create();
+ active = false;
+ channels = 2;
+
+ outputDeviceAddress.mSelector = kAudioHardwarePropertyDefaultOutputDevice;
+ outputDeviceAddress.mScope = kAudioObjectPropertyScopeGlobal;
+ outputDeviceAddress.mElement = kAudioObjectPropertyElementMaster;
+
+ result = AudioObjectAddPropertyListener(kAudioObjectSystemObject, &outputDeviceAddress, &outputDeviceAddressCB, this);
ERR_FAIL_COND_V(result != noErr, FAILED);
const int samples = 1024;
samples_in = memnew_arr(int32_t, samples); // whatever
buffer_frames = samples / channels;
- return OK;
+ return initDevice();
};
+Error AudioDriverOSX::reopen() {
+ Error err;
+ bool restart = false;
+
+ lock();
+
+ if (active) {
+ restart = true;
+ }
+
+ err = finishDevice();
+ if (err != OK) {
+ ERR_PRINT("finishDevice failed");
+ unlock();
+ return err;
+ }
+
+ err = initDevice();
+ if (err != OK) {
+ ERR_PRINT("initDevice failed");
+ unlock();
+ return err;
+ }
+
+ if (restart) {
+ start();
+ }
+
+ unlock();
+
+ return OK;
+}
+
OSStatus AudioDriverOSX::output_callback(void *inRefCon,
AudioUnitRenderActionFlags *ioActionFlags,
const AudioTimeStamp *inTimeStamp,
UInt32 inBusNumber, UInt32 inNumberFrames,
AudioBufferList *ioData) {
- AudioBuffer *abuf;
AudioDriverOSX *ad = (AudioDriverOSX *)inRefCon;
- bool mix = true;
-
- if (!ad->active)
- mix = false;
- else if (ad->mutex) {
- mix = ad->mutex->try_lock() == OK;
- };
-
- if (!mix) {
+ if (!ad->active || !ad->try_lock()) {
for (unsigned int i = 0; i < ioData->mNumberBuffers; i++) {
- abuf = &ioData->mBuffers[i];
+ AudioBuffer *abuf = &ioData->mBuffers[i];
zeromem(abuf->mData, abuf->mDataByteSize);
};
return 0;
};
- int frames_left;
-
for (unsigned int i = 0; i < ioData->mNumberBuffers; i++) {
- abuf = &ioData->mBuffers[i];
- frames_left = inNumberFrames;
+ AudioBuffer *abuf = &ioData->mBuffers[i];
+ int frames_left = inNumberFrames;
int16_t *out = (int16_t *)abuf->mData;
while (frames_left) {
int frames = MIN(frames_left, ad->buffer_frames);
- //ad->lock();
ad->audio_server_process(frames, ad->samples_in);
- //ad->unlock();
- for (int i = 0; i < frames * ad->channels; i++) {
+ for (int j = 0; j < frames * ad->channels; j++) {
- out[i] = ad->samples_in[i] >> 16;
+ out[j] = ad->samples_in[j] >> 16;
}
frames_left -= frames;
@@ -141,14 +191,20 @@ OSStatus AudioDriverOSX::output_callback(void *inRefCon,
};
};
- if (ad->mutex)
- ad->mutex->unlock();
+ ad->unlock();
return 0;
};
void AudioDriverOSX::start() {
- active = true;
+ if (!active) {
+ OSStatus result = AudioOutputUnitStart(audio_unit);
+ if (result != noErr) {
+ ERR_PRINT("AudioOutputUnitStart failed");
+ } else {
+ active = true;
+ }
+ }
};
int AudioDriverOSX::get_mix_rate() const {
@@ -160,29 +216,47 @@ AudioDriver::SpeakerMode AudioDriverOSX::get_speaker_mode() const {
};
void AudioDriverOSX::lock() {
- if (active && mutex)
+ if (mutex)
mutex->lock();
};
+
void AudioDriverOSX::unlock() {
- if (active && mutex)
+ if (mutex)
mutex->unlock();
};
+bool AudioDriverOSX::try_lock() {
+ if (mutex)
+ return mutex->try_lock() == OK;
+ return true;
+}
+
void AudioDriverOSX::finish() {
+ OSStatus result;
- if (active)
- AudioOutputUnitStop(audio_unit);
+ finishDevice();
- memdelete_arr(samples_in);
-};
+ result = AudioObjectRemovePropertyListener(kAudioObjectSystemObject, &outputDeviceAddress, &outputDeviceAddressCB, this);
+ if (result != noErr) {
+ ERR_PRINT("AudioObjectRemovePropertyListener failed");
+ }
-AudioDriverOSX::AudioDriverOSX() {
+ if (mutex) {
+ memdelete(mutex);
+ mutex = NULL;
+ }
- mutex = Mutex::create(); //NULL;
+ if (samples_in) {
+ memdelete_arr(samples_in);
+ samples_in = NULL;
+ }
};
-AudioDriverOSX::~AudioDriverOSX(){
-
+AudioDriverOSX::AudioDriverOSX() {
+ mutex = NULL;
+ samples_in = NULL;
};
+AudioDriverOSX::~AudioDriverOSX(){};
+
#endif
diff --git a/platform/osx/audio_driver_osx.h b/platform/osx/audio_driver_osx.h
index b030570a6e..287c9d6cbf 100644
--- a/platform/osx/audio_driver_osx.h
+++ b/platform/osx/audio_driver_osx.h
@@ -6,6 +6,7 @@
/* http://www.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 */
@@ -34,10 +35,12 @@
#include "servers/audio_server.h"
#include <AudioUnit/AudioUnit.h>
+#include <CoreAudio/AudioHardware.h>
class AudioDriverOSX : public AudioDriver {
AudioComponentInstance audio_unit;
+ AudioObjectPropertyAddress outputDeviceAddress;
bool active;
Mutex *mutex;
@@ -51,6 +54,9 @@ class AudioDriverOSX : public AudioDriver {
UInt32 inBusNumber, UInt32 inNumberFrames,
AudioBufferList *ioData);
+ Error initDevice();
+ Error finishDevice();
+
public:
const char *get_name() const {
return "AudioUnit";
@@ -64,6 +70,9 @@ public:
virtual void unlock();
virtual void finish();
+ bool try_lock();
+ Error reopen();
+
AudioDriverOSX();
~AudioDriverOSX();
};
diff --git a/platform/osx/context_gl_osx.cpp b/platform/osx/context_gl_osx.cpp
deleted file mode 100644
index 0737e3d3c6..0000000000
--- a/platform/osx/context_gl_osx.cpp
+++ /dev/null
@@ -1,102 +0,0 @@
-/*************************************************************************/
-/* context_gl_osx.cpp */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* http://www.godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
-/* */
-/* 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 "context_gl_osx.h"
-
-#ifdef OSX_ENABLED
-#if defined(OPENGL_ENABLED) || defined(LEGACYGL_ENABLED)
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-#define GLX_CONTEXT_MAJOR_VERSION_ARB 0x2091
-#define GLX_CONTEXT_MINOR_VERSION_ARB 0x2092
-
-void ContextGL_OSX::release_current() {
-
- aglSetCurrentContext(context);
-}
-
-void ContextGL_OSX::make_current() {
-
- aglSetCurrentContext(NULL);
-}
-void ContextGL_OSX::swap_buffers() {
-
- aglSwapBuffers(context);
-}
-
-Error ContextGL_OSX::initialize() {
-
- if ((Ptr)kUnresolvedCFragSymbolAddress == (Ptr)aglChoosePixelFormat)
- return FAILED;
-
- GLint attributes[] = { AGL_RGBA,
- AGL_DOUBLEBUFFER,
- AGL_DEPTH_SIZE, 32,
- AGL_NO_RECOVERY,
- AGL_NONE,
- AGL_NONE };
-
- AGLPixelFormat format = NULL;
-
- format = aglChoosePixelFormat(NULL, 0, attributes);
-
- if (!format)
- return FAILED;
-
- context = aglCreateContext(format, 0);
-
- if (!context)
- return FAILED;
-
- aglDestroyPixelFormat(format);
-
- aglSetWindowRef(context, window);
-
- GLint swapInterval = 1;
- aglSetInteger(context, AGL_SWAP_INTERVAL, &swapInterval);
-
- aglSetCurrentContext(context);
-
- return OK;
-}
-
-ContextGL_OSX::ContextGL_OSX(WindowRef p_window) {
-
- window = p_window;
-}
-
-ContextGL_OSX::~ContextGL_OSX() {
-
- if (context)
- aglDestroyContext(context);
-}
-
-#endif
-#endif
diff --git a/platform/osx/context_gl_osx.h b/platform/osx/context_gl_osx.h
deleted file mode 100644
index 66da8b1ecf..0000000000
--- a/platform/osx/context_gl_osx.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*************************************************************************/
-/* context_gl_osx.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* http://www.godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
-/* */
-/* 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. */
-/*************************************************************************/
-#ifndef CONTEXT_GL_OSX_H
-#define CONTEXT_GL_OSX_H
-
-/**
- @author Juan Linietsky <reduzio@gmail.com>
-*/
-#ifdef OSX_ENABLED
-
-#if defined(OPENGL_ENABLED) || defined(LEGACYGL_ENABLED)
-
-#include "drivers/gl_context/context_gl.h"
-#include "os/os.h"
-#include <AGL/agl.h>
-#include <Carbon/Carbon.h>
-
-class ContextGL_OSX : public ContextGL {
-
- AGLContext context;
- WindowRef window;
-
-public:
- virtual void release_current();
- virtual void make_current();
- virtual void swap_buffers();
-
- virtual Error initialize();
-
- ContextGL_OSX(WindowRef window);
- ~ContextGL_OSX();
-};
-
-#endif
-
-#endif
-#endif
diff --git a/platform/osx/detect.py b/platform/osx/detect.py
index b59dfe1afb..d9891dda61 100644
--- a/platform/osx/detect.py
+++ b/platform/osx/detect.py
@@ -1,4 +1,3 @@
-
import os
import sys
@@ -22,9 +21,7 @@ def can_build():
def get_opts():
return [
- ('force_64_bits', 'Force 64 bits binary', 'no'),
('osxcross_sdk', 'OSXCross SDK version', 'darwin14'),
-
]
@@ -36,36 +33,37 @@ def get_flags():
def configure(env):
- env.Append(CPPPATH=['#platform/osx'])
-
- if (env["bits"] == "default"):
- env["bits"] = "32"
+ ## Build type
if (env["target"] == "release"):
-
- env.Append(CCFLAGS=['-O2', '-ffast-math', '-fomit-frame-pointer', '-ftree-vectorize', '-msse2'])
+ env.Prepend(CCFLAGS=['-O2', '-ffast-math', '-fomit-frame-pointer', '-ftree-vectorize', '-msse2'])
elif (env["target"] == "release_debug"):
-
- env.Append(CCFLAGS=['-O2', '-DDEBUG_ENABLED'])
+ env.Prepend(CCFLAGS=['-O2', '-DDEBUG_ENABLED'])
elif (env["target"] == "debug"):
+ env.Prepend(CCFLAGS=['-g3', '-DDEBUG_ENABLED', '-DDEBUG_MEMORY_ENABLED'])
- env.Append(CCFLAGS=['-g3', '-Wall', '-DDEBUG_ENABLED', '-DDEBUG_MEMORY_ENABLED'])
+ ## Architecture
- if (not os.environ.has_key("OSXCROSS_ROOT")):
- # regular native build
- if (env["bits"] == "64"):
- env.Append(CCFLAGS=['-arch', 'x86_64'])
- env.Append(LINKFLAGS=['-arch', 'x86_64'])
+ is64 = sys.maxsize > 2**32
+ if (env["bits"] == "default"):
+ env["bits"] = "64" if is64 else "32"
+
+ ## Compiler configuration
+
+ if (not os.environ.has_key("OSXCROSS_ROOT")): # regular native build
+ if (env["bits"] == "fat"):
+ env.Append(CCFLAGS=['-arch', 'i386', '-arch', 'x86_64'])
+ env.Append(LINKFLAGS=['-arch', 'i386', '-arch', 'x86_64'])
elif (env["bits"] == "32"):
env.Append(CCFLAGS=['-arch', 'i386'])
env.Append(LINKFLAGS=['-arch', 'i386'])
- else:
- env.Append(CCFLAGS=['-arch', 'i386', '-arch', 'x86_64'])
- env.Append(LINKFLAGS=['-arch', 'i386', '-arch', 'x86_64'])
- else:
- # osxcross build
+ else: # 64-bit, default
+ env.Append(CCFLAGS=['-arch', 'x86_64'])
+ env.Append(LINKFLAGS=['-arch', 'x86_64'])
+
+ else: # osxcross build
root = os.environ.get("OSXCROSS_ROOT", 0)
if env["bits"] == "64":
basecmd = root + "/target/bin/x86_64-apple-" + env["osxcross_sdk"] + "-"
@@ -78,26 +76,22 @@ def configure(env):
env['RANLIB'] = basecmd + "ranlib"
env['AS'] = basecmd + "as"
- env.Append(CPPFLAGS=["-DAPPLE_STYLE_KEYS"])
- env.Append(CPPFLAGS=['-DUNIX_ENABLED', '-DGLES2_ENABLED', '-DOSX_ENABLED'])
- env.Append(CPPFLAGS=["-mmacosx-version-min=10.9"])
- env.Append(LIBS=['pthread'])
- #env.Append(CPPFLAGS=['-F/Developer/SDKs/MacOSX10.4u.sdk/System/Library/Frameworks', '-isysroot', '/Developer/SDKs/MacOSX10.4u.sdk', '-mmacosx-version-min=10.4'])
- #env.Append(LINKFLAGS=['-mmacosx-version-min=10.4', '-isysroot', '/Developer/SDKs/MacOSX10.4u.sdk', '-Wl,-syslibroot,/Developer/SDKs/MacOSX10.4u.sdk'])
- env.Append(LINKFLAGS=['-framework', 'Cocoa', '-framework', 'Carbon', '-framework', 'OpenGL', '-framework', 'AGL', '-framework', 'AudioUnit', '-lz', '-framework', 'IOKit', '-framework', 'ForceFeedback'])
- env.Append(LINKFLAGS=["-mmacosx-version-min=10.9"])
-
if (env["CXX"] == "clang++"):
env.Append(CPPFLAGS=['-DTYPED_METHOD_BIND'])
env["CC"] = "clang"
env["LD"] = "clang++"
- import methods
+ ## Dependencies
+
+ if (env['builtin_libtheora'] != 'no'):
+ env["x86_libtheora_opt_gcc"] = True
- env.Append(BUILDERS={'GLSL120': env.Builder(action=methods.build_legacygl_headers, suffix='glsl.h', src_suffix='.glsl')})
- env.Append(BUILDERS={'GLSL': env.Builder(action=methods.build_glsl_headers, suffix='glsl.h', src_suffix='.glsl')})
- env.Append(BUILDERS={'GLSL120GLES': env.Builder(action=methods.build_gles2_headers, suffix='glsl.h', src_suffix='.glsl')})
- #env.Append( BUILDERS = { 'HLSL9' : env.Builder(action = methods.build_hlsl_dx9_headers, suffix = 'hlsl.h',src_suffix = '.hlsl') } )
+ ## Flags
+
+ env.Append(CPPPATH=['#platform/osx'])
+ env.Append(CPPFLAGS=['-DOSX_ENABLED', '-DUNIX_ENABLED', '-DGLES2_ENABLED', '-DAPPLE_STYLE_KEYS'])
+ env.Append(LINKFLAGS=['-framework', 'Cocoa', '-framework', 'Carbon', '-framework', 'OpenGL', '-framework', 'AGL', '-framework', 'AudioUnit', '-framework', 'CoreAudio', '-lz', '-framework', 'IOKit', '-framework', 'ForceFeedback'])
+ env.Append(LIBS=['pthread'])
- env["x86_libtheora_opt_gcc"] = True
-
+ env.Append(CPPFLAGS=['-mmacosx-version-min=10.9'])
+ env.Append(LINKFLAGS=['-mmacosx-version-min=10.9'])
diff --git a/platform/osx/dir_access_osx.h b/platform/osx/dir_access_osx.h
index 56a8e057dd..6dcff3898c 100644
--- a/platform/osx/dir_access_osx.h
+++ b/platform/osx/dir_access_osx.h
@@ -6,6 +6,7 @@
/* http://www.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 */
diff --git a/platform/osx/dir_access_osx.mm b/platform/osx/dir_access_osx.mm
index 476da2635e..37ba0e6b19 100644
--- a/platform/osx/dir_access_osx.mm
+++ b/platform/osx/dir_access_osx.mm
@@ -6,6 +6,7 @@
/* http://www.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 */
@@ -34,17 +35,14 @@
#include <Foundation/NSString.h>
-
-String DirAccessOSX::fix_unicode_name(const char* p_name) const {
+String DirAccessOSX::fix_unicode_name(const char *p_name) const {
String fname;
- NSString* nsstr = [[NSString stringWithUTF8String: p_name] precomposedStringWithCanonicalMapping];
+ NSString *nsstr = [[NSString stringWithUTF8String:p_name] precomposedStringWithCanonicalMapping];
fname.parse_utf8([nsstr UTF8String]);
return fname;
}
-
-
#endif //posix_enabled
diff --git a/platform/osx/export/export.cpp b/platform/osx/export/export.cpp
index ba4ef0300c..03f424de8d 100644
--- a/platform/osx/export/export.cpp
+++ b/platform/osx/export/export.cpp
@@ -6,6 +6,7 @@
/* http://www.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 */
@@ -26,521 +27,671 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
#include "export.h"
#include "editor/editor_export.h"
#include "editor/editor_node.h"
#include "editor/editor_settings.h"
-#include "global_config.h"
#include "io/marshalls.h"
#include "io/resource_saver.h"
#include "io/zip_io.h"
#include "os/file_access.h"
#include "os/os.h"
-#include "platform/osx/logo.h"
+#include "platform/osx/logo.gen.h"
+#include "project_settings.h"
#include "string.h"
#include "version.h"
-#if 0
+#include <sys/stat.h>
class EditorExportPlatformOSX : public EditorExportPlatform {
- GDCLASS( EditorExportPlatformOSX,EditorExportPlatform );
-
- String custom_release_package;
- String custom_debug_package;
-
- enum BitsMode {
- BITS_FAT,
- BITS_64,
- BITS_32
- };
+ GDCLASS(EditorExportPlatformOSX, EditorExportPlatform);
int version_code;
- String app_name;
- String info;
- String icon;
- String identifier;
- String short_version;
- String version;
- String signature;
- String copyright;
- BitsMode bits_mode;
- bool high_resolution;
-
Ref<ImageTexture> logo;
- void _fix_plist(Vector<uint8_t>& plist, const String &p_binary);
- void _make_icon(const Image& p_icon,Vector<uint8_t>& data);
-
+ void _fix_plist(const Ref<EditorExportPreset> &p_preset, Vector<uint8_t> &plist, const String &p_binary);
+ void _make_icon(const Ref<Image> &p_icon, Vector<uint8_t> &p_data);
+#ifdef OSX_ENABLED
+ Error _code_sign(const Ref<EditorExportPreset> &p_preset, const String &p_path);
+ Error _create_dmg(const String &p_dmg_path, const String &p_pkg_name, const String &p_app_path_name);
+#endif
protected:
-
- bool _set(const StringName& p_name, const Variant& p_value);
- bool _get(const StringName& p_name,Variant &r_ret) const;
- void _get_property_list( List<PropertyInfo> *p_list) const;
+ virtual void get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features);
+ virtual void get_export_options(List<ExportOption> *r_options);
public:
-
virtual String get_name() const { return "Mac OSX"; }
- virtual ImageCompression get_image_compression() const { return IMAGE_COMPRESSION_BC; }
+ virtual String get_os_name() const { return "OSX"; }
virtual Ref<Texture> get_logo() const { return logo; }
+#ifdef OSX_ENABLED
+ virtual String get_binary_extension() const { return "dmg"; }
+#else
+ virtual String get_binary_extension() const { return "zip"; }
+#endif
+ virtual Error export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags = 0);
- virtual bool poll_devices() { return false;}
- virtual int get_device_count() const { return 0; }
- virtual String get_device_name(int p_device) const { return String(); }
- virtual String get_device_info(int p_device) const { return String(); }
- virtual Error run(int p_device,int p_flags=0);
+ virtual bool can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const;
- virtual bool requires_password(bool p_debug) const { return false; }
- virtual String get_binary_extension() const { return "zip"; }
- virtual Error export_project(const String& p_path,bool p_debug,int p_flags=0);
+ virtual void get_platform_features(List<String> *r_features) {
- virtual bool can_export(String *r_error=NULL) const;
+ r_features->push_back("pc");
+ r_features->push_back("s3tc");
+ r_features->push_back("OSX");
+ }
EditorExportPlatformOSX();
~EditorExportPlatformOSX();
};
-bool EditorExportPlatformOSX::_set(const StringName& p_name, const Variant& p_value) {
-
- String n=p_name;
-
- if (n=="custom_package/debug")
- custom_debug_package=p_value;
- else if (n=="custom_package/release")
- custom_release_package=p_value;
- else if (n=="application/name")
- app_name=p_value;
- else if (n=="application/info")
- info=p_value;
- else if (n=="application/icon")
- icon=p_value;
- else if (n=="application/identifier")
- identifier=p_value;
- else if (n=="application/signature")
- signature=p_value;
- else if (n=="application/short_version")
- short_version=p_value;
- else if (n=="application/version")
- version=p_value;
- else if (n=="application/copyright")
- copyright=p_value;
- else if (n=="application/bits_mode")
- bits_mode=BitsMode(int(p_value));
- else if (n=="display/high_res")
- high_resolution=p_value;
- else
- return false;
-
- return true;
-}
-
-bool EditorExportPlatformOSX::_get(const StringName& p_name,Variant &r_ret) const{
-
- String n=p_name;
-
- if (n=="custom_package/debug")
- r_ret=custom_debug_package;
- else if (n=="custom_package/release")
- r_ret=custom_release_package;
- else if (n=="application/name")
- r_ret=app_name;
- else if (n=="application/info")
- r_ret=info;
- else if (n=="application/icon")
- r_ret=icon;
- else if (n=="application/identifier")
- r_ret=identifier;
- else if (n=="application/signature")
- r_ret=signature;
- else if (n=="application/short_version")
- r_ret=short_version;
- else if (n=="application/version")
- r_ret=version;
- else if (n=="application/copyright")
- r_ret=copyright;
- else if (n=="application/bits_mode")
- r_ret=bits_mode;
- else if (n=="display/high_res")
- r_ret=high_resolution;
- else
- return false;
+void EditorExportPlatformOSX::get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) {
- return true;
+ // what does this need to do?
}
-void EditorExportPlatformOSX::_get_property_list( List<PropertyInfo> *p_list) const{
-
- p_list->push_back( PropertyInfo( Variant::STRING, "custom_package/debug", PROPERTY_HINT_GLOBAL_FILE,"zip"));
- p_list->push_back( PropertyInfo( Variant::STRING, "custom_package/release", PROPERTY_HINT_GLOBAL_FILE,"zip"));
-
- p_list->push_back( PropertyInfo( Variant::STRING, "application/name") );
- p_list->push_back( PropertyInfo( Variant::STRING, "application/info") );
- p_list->push_back( PropertyInfo( Variant::STRING, "application/icon",PROPERTY_HINT_FILE,"png") );
- p_list->push_back( PropertyInfo( Variant::STRING, "application/identifier") );
- p_list->push_back( PropertyInfo( Variant::STRING, "application/signature") );
- p_list->push_back( PropertyInfo( Variant::STRING, "application/short_version") );
- p_list->push_back( PropertyInfo( Variant::STRING, "application/version") );
- p_list->push_back( PropertyInfo( Variant::STRING, "application/copyright") );
- p_list->push_back( PropertyInfo( Variant::INT, "application/bits_mode", PROPERTY_HINT_ENUM, "Fat (32 & 64 bits),64 bits,32 bits") );
- p_list->push_back( PropertyInfo( Variant::BOOL, "display/high_res") );
+void EditorExportPlatformOSX::get_export_options(List<ExportOption> *r_options) {
+
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_package/debug", PROPERTY_HINT_GLOBAL_FILE, "zip"), ""));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_package/release", PROPERTY_HINT_GLOBAL_FILE, "zip"), ""));
+
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/name"), ""));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/info"), "Made with Godot Engine"));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/icon", PROPERTY_HINT_FILE, "png"), ""));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/identifier"), "org.godotengine.macgame"));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/signature"), "godotmacgame"));
+ 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"), 0));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "display/high_res"), false));
+
+#ifdef OSX_ENABLED
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "codesign/identity"), ""));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "codesign/entitlements"), ""));
+#endif
}
-void EditorExportPlatformOSX::_make_icon(const Image& p_icon,Vector<uint8_t>& icon) {
+void EditorExportPlatformOSX::_make_icon(const Ref<Image> &p_icon, Vector<uint8_t> &p_data) {
-
- Ref<ImageTexture> it = memnew( ImageTexture );
- int size=512;
+ Ref<ImageTexture> it = memnew(ImageTexture);
+ int size = 512;
Vector<uint8_t> data;
data.resize(8);
- data[0]='i';
- data[1]='c';
- data[2]='n';
- data[3]='s';
+ data[0] = 'i';
+ data[1] = 'c';
+ data[2] = 'n';
+ data[3] = 's';
- const char *name[]={"ic09","ic08","ic07","icp6","icp5","icp4"};
- int index=0;
+ const char *name[] = { "ic09", "ic08", "ic07", "icp6", "icp5", "icp4" };
+ int index = 0;
- while(size>=16) {
+ while (size >= 16) {
- Image copy = p_icon;
- copy.convert(Image::FORMAT_RGBA8);
- copy.resize(size,size);
+ Ref<Image> copy = p_icon; // does this make sense? doesn't this just increase the reference count instead of making a copy? Do we even need a copy?
+ 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";
- ResourceSaver::save(path,it);
+ String path = EditorSettings::get_singleton()->get_settings_path() + "/tmp/icon.png";
+ ResourceSaver::save(path, it);
- FileAccess *f = FileAccess::open(path,FileAccess::READ);
+ FileAccess *f = FileAccess::open(path, FileAccess::READ);
ERR_FAIL_COND(!f);
int ofs = data.size();
uint32_t len = f->get_len();
- data.resize(data.size()+len+8);
- f->get_buffer(&data[ofs+8],len);
+ data.resize(data.size() + len + 8);
+ f->get_buffer(&data[ofs + 8], len);
memdelete(f);
- len+=8;
- len=BSWAP32(len);
- copymem(&data[ofs],name[index],4);
- encode_uint32(len,&data[ofs+4]);
+ len += 8;
+ len = BSWAP32(len);
+ copymem(&data[ofs], name[index], 4);
+ encode_uint32(len, &data[ofs + 4]);
index++;
- size/=2;
+ size /= 2;
}
uint32_t total_len = data.size();
total_len = BSWAP32(total_len);
- encode_uint32(total_len,&data[4]);
+ encode_uint32(total_len, &data[4]);
- icon=data;
+ p_data = data;
}
-
-void EditorExportPlatformOSX::_fix_plist(Vector<uint8_t>& plist,const String& p_binary) {
-
+void EditorExportPlatformOSX::_fix_plist(const Ref<EditorExportPreset> &p_preset, Vector<uint8_t> &plist, const String &p_binary) {
String str;
String strnew;
- str.parse_utf8((const char*)plist.ptr(),plist.size());
- 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";
- } else if (lines[i].find("$name")!=-1) {
- strnew+=lines[i].replace("$name",p_binary)+"\n";
- } else if (lines[i].find("$info")!=-1) {
- strnew+=lines[i].replace("$info",info)+"\n";
- } else if (lines[i].find("$identifier")!=-1) {
- strnew+=lines[i].replace("$identifier",identifier)+"\n";
- } else if (lines[i].find("$short_version")!=-1) {
- strnew+=lines[i].replace("$short_version",short_version)+"\n";
- } else if (lines[i].find("$version")!=-1) {
- strnew+=lines[i].replace("$version",version)+"\n";
- } else if (lines[i].find("$signature")!=-1) {
- strnew+=lines[i].replace("$signature",signature)+"\n";
- } else if (lines[i].find("$copyright")!=-1) {
- strnew+=lines[i].replace("$copyright",copyright)+"\n";
- } else if (lines[i].find("$highres")!=-1) {
- strnew+=lines[i].replace("$highres",high_resolution?"<true/>":"<false/>")+"\n";
+ str.parse_utf8((const char *)plist.ptr(), plist.size());
+ 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";
+ } else if (lines[i].find("$name") != -1) {
+ strnew += lines[i].replace("$name", p_binary) + "\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) {
+ strnew += lines[i].replace("$identifier", p_preset->get("application/identifier")) + "\n";
+ } else if (lines[i].find("$short_version") != -1) {
+ strnew += lines[i].replace("$short_version", p_preset->get("application/short_version")) + "\n";
+ } else if (lines[i].find("$version") != -1) {
+ strnew += lines[i].replace("$version", p_preset->get("application/version")) + "\n";
+ } else if (lines[i].find("$signature") != -1) {
+ strnew += lines[i].replace("$signature", p_preset->get("application/signature")) + "\n";
+ } else if (lines[i].find("$copyright") != -1) {
+ strnew += lines[i].replace("$copyright", p_preset->get("application/copyright")) + "\n";
+ } else if (lines[i].find("$highres") != -1) {
+ strnew += lines[i].replace("$highres", p_preset->get("display/high_res") ? "<true/>" : "<false/>") + "\n";
} else {
- strnew+=lines[i]+"\n";
+ strnew += lines[i] + "\n";
}
}
CharString cs = strnew.utf8();
- plist.resize(cs.size());
- for(int i=9;i<cs.size();i++) {
- plist[i]=cs[i];
+ plist.resize(cs.size() - 1);
+ for (int i = 0; i < cs.size() - 1; i++) {
+ plist[i] = cs[i];
}
}
-Error EditorExportPlatformOSX::export_project(const String& p_path, bool p_debug, int p_flags) {
+#ifdef OSX_ENABLED
+/**
+ If we're running the OSX version of the Godot editor we'll:
+ - export our application bundle to a temporary folder
+ - attempt to code sign it
+ - and then wrap it up in a DMG
+**/
+
+Error EditorExportPlatformOSX::_code_sign(const Ref<EditorExportPreset> &p_preset, const String &p_path) {
+ List<String> args;
+ if (p_preset->get("codesign/entitlements") != "") {
+ /* this should point to our entitlements.plist file that sandboxes our application, I don't know if this should also be placed in our app bundle */
+ args.push_back("-entitlements");
+ args.push_back(p_preset->get("codesign/entitlements"));
+ }
+ args.push_back("-s");
+ args.push_back(p_preset->get("codesign/identity"));
+ args.push_back("-v"); /* provide some more feedback */
+ args.push_back(p_path);
+ Error err = OS::get_singleton()->execute("/usr/bin/codesign", args, true);
+ ERR_FAIL_COND_V(err, err);
+
+ return OK;
+}
+
+Error EditorExportPlatformOSX::_create_dmg(const String &p_dmg_path, const String &p_pkg_name, const String &p_app_path_name) {
+ List<String> args;
+ args.push_back("create");
+ args.push_back(p_dmg_path);
+ args.push_back("-volname");
+ args.push_back(p_pkg_name);
+ args.push_back("-fs");
+ args.push_back("HFS+");
+ args.push_back("-srcfolder");
+ args.push_back(p_app_path_name);
+ Error err = OS::get_singleton()->execute("/usr/bin/hdiutil", args, true);
+ ERR_FAIL_COND_V(err, err);
- String src_pkg;
+ return OK;
+}
- EditorProgress ep("export","Exporting for OSX",104);
+Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags) {
+ String src_pkg_name;
+
+ EditorProgress ep("export", "Exporting for OSX", 3);
if (p_debug)
- src_pkg=custom_debug_package;
+ src_pkg_name = p_preset->get("custom_package/debug");
else
- src_pkg=custom_release_package;
+ src_pkg_name = p_preset->get("custom_package/release");
- if (src_pkg=="") {
+ if (src_pkg_name == "") {
String err;
- src_pkg=find_export_template("osx.zip", &err);
- if (src_pkg=="") {
+ src_pkg_name = find_export_template("osx.zip", &err);
+ if (src_pkg_name == "") {
EditorNode::add_io_error(err);
return ERR_FILE_NOT_FOUND;
}
}
-
- FileAccess *src_f=NULL;
+ FileAccess *src_f = NULL;
zlib_filefunc_def io = zipio_create_io_from_file(&src_f);
- ep.step("Creating app",0);
+ ep.step("Creating app", 0);
- unzFile pkg = unzOpen2(src_pkg.utf8().get_data(), &io);
- if (!pkg) {
+ unzFile src_pkg_zip = unzOpen2(src_pkg_name.utf8().get_data(), &io);
+ if (!src_pkg_zip) {
- EditorNode::add_io_error("Could not find template app to export:\n"+src_pkg);
+ EditorNode::add_io_error("Could not find template app to export:\n" + src_pkg_name);
return ERR_FILE_NOT_FOUND;
}
- ERR_FAIL_COND_V(!pkg, ERR_CANT_OPEN);
- int ret = unzGoToFirstFile(pkg);
+ ERR_FAIL_COND_V(!src_pkg_zip, ERR_CANT_OPEN);
+ int ret = unzGoToFirstFile(src_pkg_zip);
+
+ String binary_to_use = "godot_osx_" + 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 ? "64" : "32");
+
+ print_line("binary: " + binary_to_use);
+ String pkg_name;
+ if (p_preset->get("application/name") != "")
+ pkg_name = p_preset->get("application/name"); // app_name
+ else if (String(ProjectSettings::get_singleton()->get("application/config/name")) != "")
+ pkg_name = String(ProjectSettings::get_singleton()->get("application/config/name"));
+ else
+ pkg_name = "Unnamed";
+
+ // We're on OSX so we can export to DMG, but first we create our application bundle
+ String tmp_app_path_name = p_path.get_base_dir() + "/" + pkg_name + ".app";
+ print_line("Exporting to " + tmp_app_path_name);
+ DirAccess *tmp_app_path = DirAccess::create_for_path(tmp_app_path_name);
+ ERR_FAIL_COND_V(!tmp_app_path, ERR_CANT_CREATE)
+
+ ///@TODO We should delete the existing application bundle especially if we attempt to code sign it, but what is a safe way to do this? Maybe call system function so it moves to trash?
+ // tmp_app_path->erase_contents_recursive();
+
+ // Create our folder structure or rely on unzip?
+ print_line("Creating " + tmp_app_path_name + "/Contents/MacOS");
+ Error dir_err = tmp_app_path->make_dir_recursive(tmp_app_path_name + "/Contents/MacOS");
+ ERR_FAIL_COND_V(dir_err, ERR_CANT_CREATE)
+ print_line("Creating " + tmp_app_path_name + "/Contents/Resources");
+ dir_err = tmp_app_path->make_dir_recursive(tmp_app_path_name + "/Contents/Resources");
+ ERR_FAIL_COND_V(dir_err, ERR_CANT_CREATE)
+
+ /* Now process our template */
+ bool found_binary = false;
+ int total_size = 0;
+
+ while (ret == UNZ_OK) {
+ bool is_execute = false;
+
+ //get filename
+ unz_file_info info;
+ char fname[16384];
+ ret = unzGetCurrentFileInfo(src_pkg_zip, &info, fname, 16384, NULL, 0, NULL, 0);
+
+ String file = fname;
+
+ print_line("READ: " + file);
+ Vector<uint8_t> data;
+ data.resize(info.uncompressed_size);
+
+ //read
+ unzOpenCurrentFile(src_pkg_zip);
+ unzReadCurrentFile(src_pkg_zip, data.ptr(), data.size());
+ unzCloseCurrentFile(src_pkg_zip);
+
+ //write
+
+ file = file.replace_first("osx_template.app/", "");
+
+ if (file == "Contents/Info.plist") {
+ print_line("parse plist");
+ _fix_plist(p_preset, data, pkg_name);
+ }
+
+ if (file.begins_with("Contents/MacOS/godot_")) {
+ if (file != "Contents/MacOS/" + binary_to_use) {
+ ret = unzGoToNextFile(src_pkg_zip);
+ continue; //ignore!
+ }
+ found_binary = true;
+ is_execute = true;
+ file = "Contents/MacOS/" + pkg_name;
+ }
+
+ if (file == "Contents/Resources/icon.icns") {
+ //see if there is an icon
+ String iconpath;
+ if (p_preset->get("application/icon") != "")
+ iconpath = p_preset->get("application/icon");
+ else
+ iconpath = ProjectSettings::get_singleton()->get("application/config/icon");
+ print_line("icon? " + iconpath);
+ if (iconpath != "") {
+ Ref<Image> icon;
+ icon.instance();
+ icon->load(iconpath);
+ if (!icon->empty()) {
+ print_line("loaded?");
+ _make_icon(icon, data);
+ }
+ }
+ //bleh?
+ }
+
+ if (data.size() > 0) {
+ print_line("ADDING: " + file + " size: " + itos(data.size()));
+ total_size += data.size();
+
+ /* write it into our application bundle */
+ file = tmp_app_path_name + "/" + file;
+
+ /* write the file, need to add chmod */
+ FileAccess *f = FileAccess::open(file, FileAccess::WRITE);
+ ERR_FAIL_COND_V(!f, ERR_CANT_CREATE)
+ f->store_buffer(data.ptr(), data.size());
+ f->close();
+ memdelete(f);
+
+ if (is_execute) {
+ // we need execute rights on this file
+ chmod(file.utf8().get_data(), 0755);
+ } else {
+ // seems to already be set correctly
+ // chmod(file.utf8().get_data(), 0644);
+ }
+ }
+
+ ret = unzGoToNextFile(src_pkg_zip);
+ }
+
+ /* 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.");
+ unzClose(src_pkg_zip);
+ return ERR_FILE_NOT_FOUND;
+ }
+
+ ep.step("Making PKG", 1);
+
+ String pack_path = tmp_app_path_name + "/Contents/Resources/" + pkg_name + ".pck";
+ Error err = save_pack(p_preset, pack_path);
+ // chmod(pack_path.utf8().get_data(), 0644);
+
+ if (err) {
+ return err;
+ }
+
+ /* see if we can code sign our new package */
+ if (p_preset->get("codesign/identity") != "") {
+ ep.step("Code signing bundle", 2);
+
+ /* the order in which we code sign is important, this is a bit of a shame or we could do this in our loop that extracts the files from our ZIP */
+
+ // start with our application
+ err = _code_sign(p_preset, tmp_app_path_name + "/Contents/MacOS/" + pkg_name);
+ ERR_FAIL_COND_V(err, err);
+
+ ///@TODO we should check the contents of /Contents/Frameworks for frameworks to sign
+
+ // we should probably loop through all resources and sign them?
+ err = _code_sign(p_preset, tmp_app_path_name + "/Contents/Resources/icon.icns");
+ ERR_FAIL_COND_V(err, err);
+ err = _code_sign(p_preset, pack_path);
+ ERR_FAIL_COND_V(err, err);
+ err = _code_sign(p_preset, tmp_app_path_name + "/Contents/Info.plist");
+ ERR_FAIL_COND_V(err, err);
+ }
+
+ /* and finally create a DMG */
+ ep.step("Making DMG", 3);
+ err = _create_dmg(p_path, pkg_name, tmp_app_path_name);
+ ERR_FAIL_COND_V(err, err);
+
+ return OK;
+}
+
+#else
+
+/**
+ When exporting for OSX from any other platform we don't have access to code signing or creating DMGs so we'll wrap the bundle into a zip file.
+
+ Should probably find a nicer way to have just one export method instead of duplicating the method like this but I would the code got very
+ messy with switches inside of it.
+**/
+Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags) {
+
+ String src_pkg_name;
+
+ EditorProgress ep("export", "Exporting for OSX", 104);
+
+ if (p_debug)
+ src_pkg_name = p_preset->get("custom_package/debug");
+ else
+ src_pkg_name = p_preset->get("custom_package/release");
+
+ if (src_pkg_name == "") {
+ String err;
+ src_pkg_name = find_export_template("osx.zip", &err);
+ if (src_pkg_name == "") {
+ EditorNode::add_io_error(err);
+ return ERR_FILE_NOT_FOUND;
+ }
+ }
+
+ FileAccess *src_f = NULL;
+ zlib_filefunc_def io = zipio_create_io_from_file(&src_f);
+
+ ep.step("Creating app", 0);
- zlib_filefunc_def io2=io;
- FileAccess *dst_f=NULL;
- io2.opaque=&dst_f;
- zipFile dpkg=zipOpen2(p_path.utf8().get_data(),APPEND_STATUS_CREATE,NULL,&io2);
+ unzFile src_pkg_zip = unzOpen2(src_pkg_name.utf8().get_data(), &io);
+ if (!src_pkg_zip) {
+
+ EditorNode::add_io_error("Could not find template app to export:\n" + src_pkg_name);
+ return ERR_FILE_NOT_FOUND;
+ }
+
+ ERR_FAIL_COND_V(!src_pkg_zip, ERR_CANT_OPEN);
+ int ret = unzGoToFirstFile(src_pkg_zip);
String binary_to_use = "godot_osx_" + String(p_debug ? "debug" : "release") + ".";
- binary_to_use += String(bits_mode==BITS_FAT ? "fat" : bits_mode==BITS_64 ? "64" : "32");
+ int bits_mode = p_preset->get("application/bits_mode");
+ binary_to_use += String(bits_mode == 0 ? "fat" : bits_mode == 1 ? "64" : "32");
- print_line("binary: "+binary_to_use);
+ print_line("binary: " + binary_to_use);
String pkg_name;
- if (app_name!="")
- pkg_name=app_name;
- else if (String(GlobalConfig::get_singleton()->get("application/name"))!="")
- pkg_name=String(GlobalConfig::get_singleton()->get("application/name"));
+ if (p_preset->get("application/name") != "")
+ pkg_name = p_preset->get("application/name"); // app_name
+ else if (String(ProjectSettings::get_singleton()->get("application/config/name")) != "")
+ pkg_name = String(ProjectSettings::get_singleton()->get("application/config/name"));
else
- pkg_name="Unnamed";
+ pkg_name = "Unnamed";
+ /* Open our destination zip file */
+ zlib_filefunc_def io2 = io;
+ FileAccess *dst_f = NULL;
+ io2.opaque = &dst_f;
+ zipFile dst_pkg_zip = zipOpen2(p_path.utf8().get_data(), APPEND_STATUS_CREATE, NULL, &io2);
bool found_binary = false;
- while(ret==UNZ_OK) {
+ while (ret == UNZ_OK) {
//get filename
unz_file_info info;
char fname[16384];
- ret = unzGetCurrentFileInfo(pkg,&info,fname,16384,NULL,0,NULL,0);
+ ret = unzGetCurrentFileInfo(src_pkg_zip, &info, fname, 16384, NULL, 0, NULL, 0);
- String file=fname;
+ String file = fname;
- print_line("READ: "+file);
+ print_line("READ: " + file);
Vector<uint8_t> data;
data.resize(info.uncompressed_size);
//read
- unzOpenCurrentFile(pkg);
- unzReadCurrentFile(pkg,data.ptr(),data.size());
- unzCloseCurrentFile(pkg);
+ unzOpenCurrentFile(src_pkg_zip);
+ unzReadCurrentFile(src_pkg_zip, data.ptr(), data.size());
+ unzCloseCurrentFile(src_pkg_zip);
//write
- file = file.replace_first("osx_template.app/","");
-
+ file = file.replace_first("osx_template.app/", "");
- if (file=="Contents/Info.plist") {
+ if (file == "Contents/Info.plist") {
print_line("parse plist");
- _fix_plist(data,pkg_name);
+ _fix_plist(p_preset, data, pkg_name);
}
if (file.begins_with("Contents/MacOS/godot_")) {
- if (file!="Contents/MacOS/"+binary_to_use) {
- ret = unzGoToNextFile(pkg);
+ if (file != "Contents/MacOS/" + binary_to_use) {
+ ret = unzGoToNextFile(src_pkg_zip);
continue; //ignore!
}
found_binary = true;
- file="Contents/MacOS/"+pkg_name;
+ file = "Contents/MacOS/" + pkg_name;
}
- if (file=="Contents/Resources/icon.icns") {
+ if (file == "Contents/Resources/icon.icns") {
//see if there is an icon
- String iconpath = GlobalConfig::get_singleton()->get("application/icon");
- print_line("icon? "+iconpath);
- if (iconpath!="") {
- Image icon;
- icon.load(iconpath);
- if (!icon.empty()) {
+ String iconpath;
+ if (p_preset->get("application/icon") != "")
+ iconpath = p_preset->get("application/icon");
+ else
+ iconpath = ProjectSettings::get_singleton()->get("application/config/icon");
+ print_line("icon? " + iconpath);
+ if (iconpath != "") {
+ Ref<Image> icon;
+ icon.instance();
+ icon->load(iconpath);
+ if (!icon->empty()) {
print_line("loaded?");
- _make_icon(icon,data);
+ _make_icon(icon, data);
}
}
//bleh?
}
- file=pkg_name+".app/"+file;
+ if (data.size() > 0) {
+ print_line("ADDING: " + file + " size: " + itos(data.size()));
- if (data.size()>0) {
- print_line("ADDING: "+file+" size: "+itos(data.size()));
+ /* add it to our zip file */
+ file = pkg_name + ".app/" + file;
zip_fileinfo fi;
- fi.tmz_date.tm_hour=info.tmu_date.tm_hour;
- fi.tmz_date.tm_min=info.tmu_date.tm_min;
- fi.tmz_date.tm_sec=info.tmu_date.tm_sec;
- fi.tmz_date.tm_mon=info.tmu_date.tm_mon;
- fi.tmz_date.tm_mday=info.tmu_date.tm_mday;
- fi.tmz_date.tm_year=info.tmu_date.tm_year;
- fi.dosDate=info.dosDate;
- fi.internal_fa=info.internal_fa;
- fi.external_fa=info.external_fa;
-
- int err = zipOpenNewFileInZip(dpkg,
- file.utf8().get_data(),
- &fi,
- NULL,
- 0,
- NULL,
- 0,
- NULL,
- Z_DEFLATED,
- Z_DEFAULT_COMPRESSION);
-
- print_line("OPEN ERR: "+itos(err));
- err = zipWriteInFileInZip(dpkg,data.ptr(),data.size());
- print_line("WRITE ERR: "+itos(err));
- zipCloseFileInZip(dpkg);
+ fi.tmz_date.tm_hour = info.tmu_date.tm_hour;
+ fi.tmz_date.tm_min = info.tmu_date.tm_min;
+ fi.tmz_date.tm_sec = info.tmu_date.tm_sec;
+ fi.tmz_date.tm_mon = info.tmu_date.tm_mon;
+ fi.tmz_date.tm_mday = info.tmu_date.tm_mday;
+ fi.tmz_date.tm_year = info.tmu_date.tm_year;
+ fi.dosDate = info.dosDate;
+ fi.internal_fa = info.internal_fa;
+ fi.external_fa = info.external_fa;
+
+ int err = zipOpenNewFileInZip(dst_pkg_zip,
+ file.utf8().get_data(),
+ &fi,
+ NULL,
+ 0,
+ NULL,
+ 0,
+ NULL,
+ Z_DEFLATED,
+ Z_DEFAULT_COMPRESSION);
+
+ print_line("OPEN ERR: " + itos(err));
+ err = zipWriteInFileInZip(dst_pkg_zip, data.ptr(), data.size());
+ print_line("WRITE ERR: " + itos(err));
+ zipCloseFileInZip(dst_pkg_zip);
}
- ret = unzGoToNextFile(pkg);
+ ret = unzGoToNextFile(src_pkg_zip);
}
if (!found_binary) {
- ERR_PRINTS("Requested template binary '"+binary_to_use+"' not found. It might be missing from your template archive.");
- zipClose(dpkg,NULL);
- unzClose(pkg);
+ ERR_PRINTS("Requested template binary '" + binary_to_use + "' not found. It might be missing from your template archive.");
+ zipClose(dst_pkg_zip, NULL);
+ unzClose(src_pkg_zip);
return ERR_FILE_NOT_FOUND;
}
+ ep.step("Making PKG", 1);
- ep.step("Making PKG",1);
-
- String pack_path=EditorSettings::get_singleton()->get_settings_path()+"/tmp/data.pck";
- FileAccess *pfs = FileAccess::open(pack_path,FileAccess::WRITE);
- Error err = save_pack(pfs);
- memdelete(pfs);
+ String pack_path = EditorSettings::get_singleton()->get_settings_path() + "/tmp/" + pkg_name + ".pck";
+ Error err = save_pack(p_preset, pack_path);
if (err) {
- zipClose(dpkg,NULL);
- unzClose(pkg);
+ zipClose(dst_pkg_zip, NULL);
+ unzClose(src_pkg_zip);
return err;
-
}
{
//write datapack
- zipOpenNewFileInZip(dpkg,
- (pkg_name+".app/Contents/Resources/data.pck").utf8().get_data(),
- NULL,
- NULL,
- 0,
- NULL,
- 0,
- NULL,
- Z_DEFLATED,
- Z_DEFAULT_COMPRESSION);
-
+ zipOpenNewFileInZip(dst_pkg_zip,
+ (pkg_name + ".app/Contents/Resources/" + pkg_name + ".pck").utf8().get_data(),
+ NULL,
+ NULL,
+ 0,
+ NULL,
+ 0,
+ NULL,
+ Z_DEFLATED,
+ Z_DEFAULT_COMPRESSION);
- FileAccess *pf = FileAccess::open(pack_path,FileAccess::READ);
- ERR_FAIL_COND_V(!pf,ERR_CANT_OPEN);
+ FileAccess *pf = FileAccess::open(pack_path, FileAccess::READ);
+ ERR_FAIL_COND_V(!pf, ERR_CANT_OPEN);
const int BSIZE = 16384;
uint8_t buf[BSIZE];
- while(true) {
+ while (true) {
- int r = pf->get_buffer(buf,BSIZE);
- if (r<=0)
+ int r = pf->get_buffer(buf, BSIZE);
+ if (r <= 0)
break;
- zipWriteInFileInZip(dpkg,buf,r);
-
+ zipWriteInFileInZip(dst_pkg_zip, buf, r);
}
- zipCloseFileInZip(dpkg);
+ zipCloseFileInZip(dst_pkg_zip);
memdelete(pf);
-
}
- zipClose(dpkg,NULL);
- unzClose(pkg);
+ zipClose(dst_pkg_zip, NULL);
+ unzClose(src_pkg_zip);
return OK;
}
+#endif
+bool EditorExportPlatformOSX::can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const {
-Error EditorExportPlatformOSX::run(int p_device, int p_flags) {
-
- return OK;
-}
-
-
-EditorExportPlatformOSX::EditorExportPlatformOSX() {
-
- Image img( _osx_logo );
- logo = Ref<ImageTexture>( memnew( ImageTexture ));
- logo->create_from_image(img);
-
- info="Made with Godot Engine";
- identifier="org.godotengine.macgame";
- signature="godotmacgame";
- short_version="1.0";
- version="1.0";
- bits_mode=BITS_FAT;
- high_resolution=false;
-
-}
-
-bool EditorExportPlatformOSX::can_export(String *r_error) const {
-
-
- bool valid=true;
+ bool valid = true;
String err;
- if (!exists_export_template("osx.zip")) {
- valid=false;
- err+="No export templates found.\nDownload and install export templates.\n";
+ if (!exists_export_template("osx.zip", &err)) {
+ valid = false;
}
- if (custom_debug_package!="" && !FileAccess::exists(custom_debug_package)) {
- valid=false;
- err+="Custom debug package not found.\n";
+ if (p_preset->get("custom_package/debug") != "" && !FileAccess::exists(p_preset->get("custom_package/debug"))) {
+ valid = false;
+ err += "Custom debug package not found.\n";
}
- if (custom_release_package!="" && !FileAccess::exists(custom_release_package)) {
- valid=false;
- err+="Custom release package not found.\n";
+ if (p_preset->get("custom_package/release") != "" && !FileAccess::exists(p_preset->get("custom_package/release"))) {
+ valid = false;
+ err += "Custom release package not found.\n";
}
- if (r_error)
- *r_error=err;
+ if (!err.empty())
+ r_error = err;
return valid;
}
+EditorExportPlatformOSX::EditorExportPlatformOSX() {
-EditorExportPlatformOSX::~EditorExportPlatformOSX() {
+ Ref<Image> img = memnew(Image(_osx_logo));
+ logo.instance();
+ logo->create_from_image(img);
+}
+EditorExportPlatformOSX::~EditorExportPlatformOSX() {
}
-#endif
void register_osx_exporter() {
-#if 0
- Ref<EditorExportPlatformOSX> exporter = Ref<EditorExportPlatformOSX>( memnew(EditorExportPlatformOSX) );
- EditorImportExport::get_singleton()->add_export_platform(exporter);
-#endif
+ Ref<EditorExportPlatformOSX> platform;
+ platform.instance();
+
+ EditorExport::get_singleton()->add_export_platform(platform);
}
diff --git a/platform/osx/export/export.h b/platform/osx/export/export.h
index 98e63ff48e..50604f068f 100644
--- a/platform/osx/export/export.h
+++ b/platform/osx/export/export.h
@@ -6,6 +6,7 @@
/* http://www.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 */
diff --git a/platform/osx/godot_main_osx.mm b/platform/osx/godot_main_osx.mm
index 8eedd7f6fc..0bf678f9b7 100644
--- a/platform/osx/godot_main_osx.mm
+++ b/platform/osx/godot_main_osx.mm
@@ -6,6 +6,7 @@
/* http://www.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 */
@@ -26,68 +27,62 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "os_osx.h"
#include "main/main.h"
+#include "os_osx.h"
+
#include <string.h>
#include <unistd.h>
-//#define main godot_main
-
-int main(int argc, char** argv) {
+int main(int argc, char **argv) {
int first_arg = 1;
- const char* dbg_arg = "-NSDocumentRevisionsDebugMode";
+ const char *dbg_arg = "-NSDocumentRevisionsDebugMode";
printf("arguments\n");
- for (int i=0; i<argc; i++) {
+ for (int i = 0; i < argc; i++) {
if (strcmp(dbg_arg, argv[i]) == 0)
- first_arg = i+2;
+ first_arg = i + 2;
printf("%i: %s\n", i, argv[i]);
};
-
- if (argc>=1 && argv[0][0]=='/') {
+ if (argc >= 1 && argv[0][0] == '/') {
//potentially launched from finder
int len = strlen(argv[0]);
while (len--) {
if (argv[0][len] == '/') break;
}
- if (len>=0) {
- char *path = (char *)malloc(len+1);
+ if (len >= 0) {
+ char *path = (char *)malloc(len + 1);
memcpy(path, argv[0], len);
- path[len]=0;
+ path[len] = 0;
- char *pathinfo = (char*)malloc(strlen(path)+strlen("/../Info.plist")+1);
- //in real code you would check for errors in malloc here
+ char *pathinfo = (char *)malloc(strlen(path) + strlen("/../Info.plist") + 1);
+ //in real code you would check for errors in malloc here
strcpy(pathinfo, path);
strcat(pathinfo, "/../Info.plist");
- FILE*f=fopen(pathinfo,"rb");
+ FILE *f = fopen(pathinfo, "rb");
if (f) {
//running from app bundle, as Info.plist was found
fclose(f);
chdir(path);
chdir("../Resources"); //data.pck, or just the files are here
-
}
free(path);
free(pathinfo);
}
-
-
-
}
OS_OSX os;
-
- Error err = Main::setup(argv[0],argc-first_arg,&argv[first_arg]);
- if (err!=OK)
+ Error err = Main::setup(argv[0], argc - first_arg, &argv[first_arg]);
+ if (err != OK)
return 255;
if (Main::start())
os.run(); // it is actually the OS that decides how to run
+
Main::cleanup();
return 0;
diff --git a/platform/osx/godot_osx.h b/platform/osx/godot_osx.h
deleted file mode 100644
index b6f2b06f26..0000000000
--- a/platform/osx/godot_osx.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*************************************************************************/
-/* godot_osx.h */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* http://www.godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
-/* */
-/* 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. */
-/*************************************************************************/
-#ifndef GODOT_OSX_H
-#define GODOT_OSX_H
-
-#import <Cocoa/Cocoa.h>
-
-@interface GodotMain : NSObject
-@end
-
-#endif
diff --git a/platform/osx/godot_osx.mm b/platform/osx/godot_osx.mm
deleted file mode 100644
index 2296fb016f..0000000000
--- a/platform/osx/godot_osx.mm
+++ /dev/null
@@ -1,215 +0,0 @@
-/*************************************************************************/
-/* godot_osx.mm */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* http://www.godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */
-/* */
-/* 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 <sys/param.h> /* for MAXPATHLEN */
-#include <unistd.h>
-#include "godot_osx.h"
-
-/* For some reaon, Apple removed setAppleMenu from the headers in 10.4,
- but the method still is there and works. To avoid warnings, we declare
- it ourselves here. */
-@interface NSApplication()
-- (void)setAppleMenu:(NSMenu *)menu;
-@end
-
-static int global_argc;
-static char **global_argv;
-static BOOL gCalledAppMainline = FALSE;
-
-static NSString *getApplicationName(void)
-{
- const NSDictionary *dict;
- NSString *appName = 0;
-
- /* Determine the application name */
- dict = (const NSDictionary *)CFBundleGetInfoDictionary(CFBundleGetMainBundle());
- if (dict)
- appName = [dict objectForKey: @"CFBundleName"];
-
- if (![appName length])
- appName = [[NSProcessInfo processInfo] processName];
-
- return appName;
-}
-
-/* The main class of the application, the application's delegate */
-@implementation GodotMain
-
-static void setApplicationMenu(void)
-{
- /* warning: this code is very odd */
- NSMenu *appleMenu;
- NSMenuItem *menuItem;
- NSString *title;
- NSString *appName;
-
- appName = getApplicationName();
- appleMenu = [[NSMenu alloc] initWithTitle:@""];
-
- /* Add menu items */
- title = [@"About " stringByAppendingString:appName];
- [appleMenu addItemWithTitle:title action:@selector(orderFrontStandardAboutPanel:) keyEquivalent:@""];
-
- [appleMenu addItem:[NSMenuItem separatorItem]];
-
- title = [@"Hide " stringByAppendingString:appName];
- [appleMenu addItemWithTitle:title action:@selector(hide:) keyEquivalent:@"h"];
-
- menuItem = (NSMenuItem *)[appleMenu addItemWithTitle:@"Hide Others" action:@selector(hideOtherApplications:) keyEquivalent:@"h"];
- [menuItem setKeyEquivalentModifierMask:(NSAlternateKeyMask|NSCommandKeyMask)];
-
- [appleMenu addItemWithTitle:@"Show All" action:@selector(unhideAllApplications:) keyEquivalent:@""];
-
- [appleMenu addItem:[NSMenuItem separatorItem]];
-
- title = [@"Quit " stringByAppendingString:appName];
- [appleMenu addItemWithTitle:title action:@selector(terminate:) keyEquivalent:@"q"];
-
-
- /* Put menu into the menubar */
- menuItem = [[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""];
- [menuItem setSubmenu:appleMenu];
- [[NSApp mainMenu] addItem:menuItem];
-
- /* Tell the application object that this is now the application menu */
- [NSApp setAppleMenu:appleMenu];
-
- /* Finally give up our references to the objects */
- [appleMenu release];
- [menuItem release];
-}
-
-/* Create a window menu */
-static void setupWindowMenu(void)
-{
- NSMenu *windowMenu;
- NSMenuItem *windowMenuItem;
- NSMenuItem *menuItem;
-
- windowMenu = [[NSMenu alloc] initWithTitle:@"Window"];
-
- /* "Minimize" item */
- menuItem = [[NSMenuItem alloc] initWithTitle:@"Minimize" action:@selector(performMiniaturize:) keyEquivalent:@"m"];
- [windowMenu addItem:menuItem];
- [menuItem release];
-
- /* Put menu into the menubar */
- windowMenuItem = [[NSMenuItem alloc] initWithTitle:@"Window" action:nil keyEquivalent:@""];
- [windowMenuItem setSubmenu:windowMenu];
- [[NSApp mainMenu] addItem:windowMenuItem];
-
- /* Tell the application object that this is now the window menu */
- [NSApp setWindowsMenu:windowMenu];
-
- /* Finally give up our references to the objects */
- [windowMenu release];
- [windowMenuItem release];
-}
-
-/* Replacement for NSApplicationMain */
-static void CustomApplicationMain (int argc, char **argv)
-{
- NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- GodotMain *main;
-
- /* Ensure the application object is initialised */
- [NSApplication sharedApplication];
-
- /* Set up the menubar */
- [NSApp setMainMenu:[[NSMenu alloc] init]];
- setApplicationMenu();
- setupWindowMenu();
-
- main = [[main alloc] init];
- [NSApp setDelegate:main];
-
- /* Start the main event loop */
- [NSApp run];
-
- [main release];
- [pool release];
-}
-
-extern int godot_main(int argc, char** argv);
-
-/* Called when the internal event loop has just started running */
-- (void) applicationDidFinishLaunching: (NSNotification *) note
-{
- int status;
-
- /* Hand off to main application code */
- gCalledAppMainline = TRUE;
-
- int ret = godot_main(global_argc, global_argv);
-
- exit(ret);
-}
-@end
-
-#ifdef main
-# undef main
-#endif
-
-
-int main (int argc, char **argv)
-{
- /* Copy the arguments into a global variable */
- /* This is passed if we are launched by double-clicking */
- if ( argc >= 2 && strncmp (argv[1], "-psn", 4) == 0 ) {
- global_argv = (char **) malloc(sizeof (char *) * 2);
- global_argv[0] = argv[0];
- global_argv[1] = NULL;
- global_argc = 1;
-
- // chdir to binary's dir when launched from finder
- int len = strlen(global_argv[0]);
-
- while (len--){
- if (global_argv[0][len] == '/') break;
- }
-
- if (len>=0) {
- char *path = (char *)malloc(len+1);
- memcpy(path, global_argv[0], len);
- path[len]=0;
- printf("Path: %s\n", path);
- chdir(path);
- }
-
- } else {
- int i;
- global_argc = argc;
- global_argv = (char **) malloc(sizeof (char *) * (argc+1));
- for (i = 0; i <= argc; i++)
- global_argv[i] = argv[i];
- }
-
- CustomApplicationMain (argc, argv);
- return 0;
-}
-
diff --git a/platform/osx/joypad_osx.cpp b/platform/osx/joypad_osx.cpp
index c2b0e1f052..1a4b3a460e 100644
--- a/platform/osx/joypad_osx.cpp
+++ b/platform/osx/joypad_osx.cpp
@@ -6,6 +6,7 @@
/* http://www.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 */
@@ -458,7 +459,7 @@ static const InputDefault::JoyAxis axis_correct(int p_value, int p_min, int p_ma
return jx;
}
-uint32_t JoypadOSX::process_joypads(uint32_t p_last_id) {
+void JoypadOSX::process_joypads() {
poll_joypads();
for (int i = 0; i < device_list.size(); i++) {
@@ -467,17 +468,17 @@ uint32_t JoypadOSX::process_joypads(uint32_t p_last_id) {
for (int j = 0; j < joy.axis_elements.size(); j++) {
rec_element &elem = joy.axis_elements[j];
int value = joy.get_hid_element_state(&elem);
- p_last_id = input->joy_axis(p_last_id, joy.id, j, axis_correct(value, elem.min, elem.max));
+ input->joy_axis(joy.id, j, axis_correct(value, elem.min, elem.max));
}
for (int j = 0; j < joy.button_elements.size(); j++) {
int value = joy.get_hid_element_state(&joy.button_elements[j]);
- p_last_id = input->joy_button(p_last_id, joy.id, j, (value >= 1));
+ input->joy_button(joy.id, j, (value >= 1));
}
for (int j = 0; j < joy.hat_elements.size(); j++) {
rec_element &elem = joy.hat_elements[j];
int value = joy.get_hid_element_state(&elem);
int hat_value = process_hat_value(elem.min, elem.max, value);
- p_last_id = input->joy_hat(p_last_id, joy.id, hat_value);
+ input->joy_hat(joy.id, hat_value);
}
if (joy.ffservice) {
@@ -494,7 +495,6 @@ uint32_t JoypadOSX::process_joypads(uint32_t p_last_id) {
}
}
}
- return p_last_id;
}
void JoypadOSX::joypad_vibration_start(int p_id, float p_magnitude, float p_duration, uint64_t p_timestamp) {
diff --git a/platform/osx/joypad_osx.h b/platform/osx/joypad_osx.h
index dabd1b8aec..bfbc523cff 100644
--- a/platform/osx/joypad_osx.h
+++ b/platform/osx/joypad_osx.h
@@ -6,6 +6,7 @@
/* http://www.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 */
@@ -110,7 +111,7 @@ private:
void joypad_vibration_stop(int p_id, uint64_t p_timestamp);
public:
- uint32_t process_joypads(uint32_t p_last_id);
+ void process_joypads();
void _device_added(IOReturn p_res, IOHIDDeviceRef p_device);
void _device_removed(int p_id);
diff --git a/platform/osx/os_osx.h b/platform/osx/os_osx.h
index 2c7ad09b89..56e6802eeb 100644
--- a/platform/osx/os_osx.h
+++ b/platform/osx/os_osx.h
@@ -6,6 +6,7 @@
/* http://www.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 */
@@ -29,21 +30,21 @@
#ifndef OS_OSX_H
#define OS_OSX_H
+#include "drivers/alsa/audio_driver_alsa.h"
+#include "drivers/rtaudio/audio_driver_rtaudio.h"
#include "drivers/unix/os_unix.h"
#include "joypad_osx.h"
#include "main/input_default.h"
#include "os/input.h"
-#include "power_osx.h"
-#include "servers/visual_server.h"
-// #include "servers/visual/visual_server_wrap_mt.h"
-#include "drivers/alsa/audio_driver_alsa.h"
-#include "drivers/rtaudio/audio_driver_rtaudio.h"
#include "platform/osx/audio_driver_osx.h"
+#include "power_osx.h"
#include "servers/audio_server.h"
#include "servers/physics_2d/physics_2d_server_sw.h"
#include "servers/physics_2d/physics_2d_server_wrap_mt.h"
#include "servers/physics_server.h"
#include "servers/visual/rasterizer.h"
+#include "servers/visual/visual_server_wrap_mt.h"
+#include "servers/visual_server.h"
#include <ApplicationServices/ApplicationServices.h>
//bitch
@@ -61,7 +62,6 @@ public:
List<String> args;
MainLoop *main_loop;
- unsigned int event_id;
PhysicsServer *physics_server;
Physics2DServer *physics_2d_server;
@@ -83,7 +83,6 @@ public:
// pthread_key_t current;
bool mouse_grab;
Point2 mouse_pos;
- uint32_t last_id;
id delegate;
id window_delegate;
@@ -97,17 +96,18 @@ public:
CursorShape cursor_shape;
MouseMode mouse_mode;
+ String title;
bool minimized;
bool maximized;
bool zoomed;
- Vector<Rect2> screens;
- Vector<int> screen_dpi;
-
Size2 window_size;
- int current_screen;
Rect2 restore_rect;
+ Point2 im_position;
+ ImeCallback im_callback;
+ void *im_target;
+
power_osx *power_manager;
float _mouse_scale(float p_scale) {
@@ -117,6 +117,8 @@ public:
return 1.0;
}
+ void _update_window();
+
float display_scale;
protected:
@@ -138,6 +140,8 @@ public:
virtual String get_name();
+ virtual void print_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, ErrorType p_type = ERR_ERROR);
+
virtual void alert(const String &p_alert, const String &p_title = "ALERT!");
virtual void set_cursor_shape(CursorShape p_shape);
@@ -146,13 +150,13 @@ public:
virtual void set_mouse_grab(bool p_grab);
virtual bool is_mouse_grab_enabled() const;
virtual void warp_mouse_pos(const Point2 &p_to);
- virtual Point2 get_mouse_pos() const;
+ virtual Point2 get_mouse_position() const;
virtual int get_mouse_button_state() const;
virtual void set_window_title(const String &p_title);
virtual Size2 get_window_size() const;
- virtual void set_icon(const Image &p_icon);
+ virtual void set_icon(const Ref<Image> &p_icon);
virtual MainLoop *get_main_loop() const;
@@ -166,7 +170,7 @@ public:
virtual void swap_buffers();
Error shell_open(String p_uri);
- void push_input(const InputEvent &p_event);
+ void push_input(const Ref<InputEvent> &p_event);
String get_locale() const;
@@ -201,10 +205,17 @@ public:
virtual void request_attention();
virtual String get_joy_guid(int p_device) const;
+ virtual void set_borderless_window(int 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);
+
virtual PowerState get_power_state();
virtual int get_power_seconds_left();
virtual int get_power_percent_left();
+ virtual bool _check_internal_feature_support(const String &p_feature);
+
void run();
void set_mouse_mode(MouseMode p_mode);
diff --git a/platform/osx/os_osx.mm b/platform/osx/os_osx.mm
index 0699978caf..6d8a6eca66 100644
--- a/platform/osx/os_osx.mm
+++ b/platform/osx/os_osx.mm
@@ -6,6 +6,7 @@
/* http://www.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 */
@@ -26,94 +27,63 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#import <Cocoa/Cocoa.h>
+#include "os_osx.h"
+
+#include "dir_access_osx.h"
+#include "drivers/gles3/rasterizer_gles3.h"
+#include "main/main.h"
+#include "os/keyboard.h"
+#include "print_string.h"
+#include "sem_osx.h"
+#include "servers/physics/physics_server_sw.h"
+#include "servers/visual/visual_server_raster.h"
#include <Carbon/Carbon.h>
-#include <IOKit/IOKitLib.h>
+#import <Cocoa/Cocoa.h>
#include <IOKit/IOCFPlugIn.h>
-#include <IOKit/hid/IOHIDLib.h>
+#include <IOKit/IOKitLib.h>
#include <IOKit/hid/IOHIDKeys.h>
+#include <IOKit/hid/IOHIDLib.h>
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101200
+#include <os/log.h>
+#endif
-#include "sem_osx.h"
-#include "servers/visual/visual_server_raster.h"
-//#include "drivers/opengl/rasterizer_gl.h"
-//#include "drivers/gles2/rasterizer_gles2.h"
-#include "drivers/gles3/rasterizer_gles3.h"
-#include "os_osx.h"
+#include <fcntl.h>
+#include <libproc.h>
#include <stdio.h>
#include <stdlib.h>
-#include "print_string.h"
-#include "servers/physics/physics_server_sw.h"
-// #include "drivers/gles2/rasterizer_instance_gles2.h"
-// #include "servers/visual/visual_server_wrap_mt.h"
-#include "main/main.h"
-#include "os/keyboard.h"
-#include "dir_access_osx.h"
-
-#include <sys/types.h>
#include <sys/stat.h>
-#include <fcntl.h>
+#include <sys/types.h>
#include <unistd.h>
-#include <libproc.h>
-//uses portions of glfw
-//========================================================================
-// GLFW 3.0 - www.glfw.org
-//------------------------------------------------------------------------
-// Copyright (c) 2002-2006 Marcus Geelnard
-// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org>
-//
-// This software is provided 'as-is', without any express or implied
-// warranty. In no event will the authors be held liable for any damages
-// arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it
-// freely, subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented; you must not
-// claim that you wrote the original software. If you use this software
-// in a product, an acknowledgment in the product documentation would
-// be appreciated but is not required.
-//
-// 2. Altered source versions must be plainly marked as such, and must not
-// be misrepresented as being the original software.
-//
-// 3. This notice may not be removed or altered from any source
-// distribution.
-//
-//========================================================================
+#if MAC_OS_X_VERSION_MAX_ALLOWED < 101200
+#define NSWindowStyleMaskBorderless NSBorderlessWindowMask
+#endif
static NSRect convertRectToBacking(NSRect contentRect) {
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
- if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6)
- return [OS_OSX::singleton->window_view convertRectToBacking:contentRect];
- else
+ if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6)
+ return [OS_OSX::singleton->window_view convertRectToBacking:contentRect];
+ else
#endif /*MAC_OS_X_VERSION_MAX_ALLOWED*/
- return contentRect;
-
+ return contentRect;
}
-static InputModifierState translateFlags(NSUInteger flags)
-{
- InputModifierState mod;
-
-
- mod.shift = (flags & NSShiftKeyMask);
- mod.control = (flags & NSControlKeyMask);
- mod.alt = (flags & NSAlternateKeyMask);
- mod.meta = (flags & NSCommandKeyMask);
+static void get_key_modifier_state(unsigned int p_osx_state, Ref<InputEventWithModifiers> state) {
- return mod;
+ state->set_shift((p_osx_state & NSShiftKeyMask));
+ state->set_control((p_osx_state & NSControlKeyMask));
+ state->set_alt((p_osx_state & NSAlternateKeyMask));
+ state->set_metakey((p_osx_state & NSCommandKeyMask));
}
-static int mouse_x=0;
-static int mouse_y=0;
-static int prev_mouse_x=0;
-static int prev_mouse_y=0;
-static int button_mask=0;
-
+static int mouse_x = 0;
+static int mouse_y = 0;
+static int prev_mouse_x = 0;
+static int prev_mouse_y = 0;
+static int button_mask = 0;
+static bool mouse_down_control = false;
@interface GodotApplication : NSApplication
@end
@@ -123,12 +93,11 @@ static int button_mask=0;
// From http://cocoadev.com/index.pl?GameKeyboardHandlingAlmost
// This works around an AppKit bug, where key up events while holding
// down the command key don't get sent to the key window.
-- (void)sendEvent:(NSEvent *)event
-{
- if ([event type] == NSKeyUp && ([event modifierFlags] & NSCommandKeyMask))
- [[self keyWindow] sendEvent:event];
- else
- [super sendEvent:event];
+- (void)sendEvent:(NSEvent *)event {
+ if ([event type] == NSKeyUp && ([event modifierFlags] & NSCommandKeyMask))
+ [[self keyWindow] sendEvent:event];
+ else
+ [super sendEvent:event];
}
@end
@@ -138,45 +107,39 @@ static int button_mask=0;
@implementation GodotApplicationDelegate
-- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender
-{
+- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender {
if (OS_OSX::singleton->get_main_loop())
OS_OSX::singleton->get_main_loop()->notification(MainLoop::NOTIFICATION_WM_QUIT_REQUEST);
return NSTerminateCancel;
}
-- (void)applicationDidHide:(NSNotification *)notification
-{
+- (void)applicationDidHide:(NSNotification *)notification {
/*
_Godotwindow* window;
for (window = _Godot.windowListHead; window; window = window->next)
_GodotInputWindowVisibility(window, GL_FALSE);
- */
+*/
}
-- (void)applicationDidUnhide:(NSNotification *)notification
-{
+- (void)applicationDidUnhide:(NSNotification *)notification {
/*
_Godotwindow* window;
- for (window = _Godot.windowListHead; window; window = window->next)
- {
- if ([window_object isVisible])
- _GodotInputWindowVisibility(window, GL_TRUE);
+ for (window = _Godot.windowListHead; window; window = window->next) {
+ if ([window_object isVisible])
+ _GodotInputWindowVisibility(window, GL_TRUE);
}
- */
+*/
}
-- (void)applicationDidChangeScreenParameters:(NSNotification *) notification
-{
+- (void)applicationDidChangeScreenParameters:(NSNotification *)notification {
//_GodotInputMonitorChange();
}
@end
-@interface GodotWindowDelegate : NSObject
-{
+@interface GodotWindowDelegate : NSObject {
//_Godotwindow* window;
}
@@ -184,28 +147,68 @@ static int button_mask=0;
@implementation GodotWindowDelegate
-
-- (BOOL)windowShouldClose:(id)sender
-{
+- (BOOL)windowShouldClose:(id)sender {
//_GodotInputWindowCloseRequest(window);
if (OS_OSX::singleton->get_main_loop())
OS_OSX::singleton->get_main_loop()->notification(MainLoop::NOTIFICATION_WM_QUIT_REQUEST);
- return NO;
+
+ return NO;
}
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
+- (void)windowDidEnterFullScreen:(NSNotification *)notification {
+ OS_OSX::singleton->zoomed = true;
+}
+- (void)windowDidExitFullScreen:(NSNotification *)notification {
+ OS_OSX::singleton->zoomed = false;
+}
+#endif // MAC_OS_X_VERSION_MAX_ALLOWED
+
+- (void)windowDidChangeBackingProperties:(NSNotification *)notification {
+ if (!OS_OSX::singleton)
+ return;
+
+ NSWindow *window = (NSWindow *)[notification object];
+ CGFloat newBackingScaleFactor = [window backingScaleFactor];
+ CGFloat oldBackingScaleFactor = [[[notification userInfo] objectForKey:@"NSBackingPropertyOldScaleFactorKey"] doubleValue];
+ if (newBackingScaleFactor != oldBackingScaleFactor) {
+ //Set new display scale and window size
+ OS_OSX::singleton->display_scale = newBackingScaleFactor;
+
+ const NSRect contentRect = [OS_OSX::singleton->window_view frame];
+ const NSRect fbRect = contentRect; //convertRectToBacking(contentRect);
+
+ OS_OSX::singleton->window_size.width = fbRect.size.width * OS_OSX::singleton->display_scale;
+ OS_OSX::singleton->window_size.height = fbRect.size.height * OS_OSX::singleton->display_scale;
+
+ //Update context
+ if (OS_OSX::singleton->main_loop) {
+ [OS_OSX::singleton->context update];
+
+ //Force window resize ???
+ NSRect frame = [OS_OSX::singleton->window_object frame];
+ [OS_OSX::singleton->window_object setFrame:NSMakeRect(frame.origin.x, frame.origin.y, 1, 1) display:YES];
+ [OS_OSX::singleton->window_object setFrame:frame display:YES];
+ }
+ }
+}
-- (void)windowDidResize:(NSNotification *)notification
-{
- [OS_OSX::singleton->context update];
+- (void)windowDidResize:(NSNotification *)notification {
+ [OS_OSX::singleton->context update];
- const NSRect contentRect = [OS_OSX::singleton->window_view frame];
- const NSRect fbRect = contentRect;//convertRectToBacking(contentRect);
+ const NSRect contentRect = [OS_OSX::singleton->window_view frame];
+ const NSRect fbRect = contentRect; //convertRectToBacking(contentRect);
- OS_OSX::singleton->window_size.width=fbRect.size.width*OS_OSX::singleton->display_scale;
- OS_OSX::singleton->window_size.height=fbRect.size.height*OS_OSX::singleton->display_scale;
+ OS_OSX::singleton->window_size.width = fbRect.size.width * OS_OSX::singleton->display_scale;
+ OS_OSX::singleton->window_size.height = fbRect.size.height * OS_OSX::singleton->display_scale;
+ if (OS_OSX::singleton->main_loop) {
+ Main::force_redraw();
+ //Event retrieval blocks until resize is over. Call Main::iteration() directly.
+ Main::iteration();
+ }
/*
_GodotInputFramebufferSize(window, fbRect.size.width, fbRect.size.height);
@@ -214,11 +217,10 @@ static int button_mask=0;
if (window->cursorMode == Godot_CURSOR_DISABLED)
centerCursor(window);
- */
+*/
}
-- (void)windowDidMove:(NSNotification *)notification
-{
+- (void)windowDidMove:(NSNotification *)notification {
/*
[window->nsgl.context update];
@@ -228,35 +230,30 @@ static int button_mask=0;
if (window->cursorMode == Godot_CURSOR_DISABLED)
centerCursor(window);
- */
+*/
}
-- (void)windowDidBecomeKey:(NSNotification *)notification
-{
+- (void)windowDidBecomeKey:(NSNotification *)notification {
//_GodotInputWindowFocus(window, GL_TRUE);
//_GodotPlatformSetCursorMode(window, window->cursorMode);
if (OS_OSX::singleton->get_main_loop())
OS_OSX::singleton->get_main_loop()->notification(MainLoop::NOTIFICATION_WM_FOCUS_IN);
}
-- (void)windowDidResignKey:(NSNotification *)notification
-{
+- (void)windowDidResignKey:(NSNotification *)notification {
//_GodotInputWindowFocus(window, GL_FALSE);
//_GodotPlatformSetCursorMode(window, Godot_CURSOR_NORMAL);
if (OS_OSX::singleton->get_main_loop())
OS_OSX::singleton->get_main_loop()->notification(MainLoop::NOTIFICATION_WM_FOCUS_OUT);
}
-- (void)windowDidMiniaturize:(NSNotification*)notification
-{
+- (void)windowDidMiniaturize:(NSNotification *)notification {
OS_OSX::singleton->wm_minimized(true);
if (OS_OSX::singleton->get_main_loop())
OS_OSX::singleton->get_main_loop()->notification(MainLoop::NOTIFICATION_WM_FOCUS_OUT);
};
-- (void)windowDidDeminiaturize:(NSNotification*)notification
-{
-
+- (void)windowDidDeminiaturize:(NSNotification *)notification {
OS_OSX::singleton->wm_minimized(false);
if (OS_OSX::singleton->get_main_loop())
OS_OSX::singleton->get_main_loop()->notification(MainLoop::NOTIFICATION_WM_FOCUS_IN);
@@ -264,659 +261,634 @@ static int button_mask=0;
@end
-@interface GodotContentView : NSView
-{
- NSTrackingArea* trackingArea;
+@interface GodotContentView : NSView <NSTextInputClient> {
+ NSTrackingArea *trackingArea;
+ NSMutableAttributedString *markedText;
+ bool imeMode;
}
-
-
-
+- (void)cancelComposition;
@end
@implementation GodotContentView
-+ (void)initialize
-{
- if (self == [GodotContentView class])
- {
- /*
- if (_glfw.ns.cursor == nil)
- {
- NSImage* data = [[NSImage alloc] initWithSize:NSMakeSize(1, 1)];
- _glfw.ns.cursor = [[NSCursor alloc] initWithImage:data
- hotSpot:NSZeroPoint];
- [data release];
- }
- */
++ (void)initialize {
+ if (self == [GodotContentView class]) {
+ // nothing left to do here at the moment..
}
}
-- (id)init
-{
- self = [super init];
- trackingArea = nil;
- [self updateTrackingAreas];
- [self registerForDraggedTypes:[NSArray arrayWithObject:NSFilenamesPboardType]];
- return self;
+- (id)init {
+ self = [super init];
+ trackingArea = nil;
+ imeMode = false;
+ [self updateTrackingAreas];
+ [self registerForDraggedTypes:[NSArray arrayWithObject:NSFilenamesPboardType]];
+ markedText = [[NSMutableAttributedString alloc] init];
+ return self;
}
+- (void)dealloc {
+ [trackingArea release];
+ [markedText release];
+ [super dealloc];
+}
+
+static const NSRange kEmptyRange = { NSNotFound, 0 };
--(void)dealloc
-{
- [trackingArea release];
- [super dealloc];
+- (BOOL)hasMarkedText {
+ return (markedText.length > 0);
}
-- (NSDragOperation)draggingEntered:(id < NSDraggingInfo >)sender {
- return NSDragOperationCopy;
+- (NSRange)markedRange {
+ return (markedText.length > 0) ? NSMakeRange(0, markedText.length - 1) : kEmptyRange;
}
-- (NSDragOperation)draggingUpdated:(id<NSDraggingInfo>)sender {
- return NSDragOperationCopy;
+- (NSRange)selectedRange {
+ return kEmptyRange;
}
-- (BOOL)performDragOperation:(id<NSDraggingInfo>)sender {
+- (void)setMarkedText:(id)aString selectedRange:(NSRange)selectedRange replacementRange:(NSRange)replacementRange {
+ if ([aString isKindOfClass:[NSAttributedString class]]) {
+ [markedText initWithAttributedString:aString];
+ } else {
+ [markedText initWithString:aString];
+ }
+ if (OS_OSX::singleton->im_callback) {
+ imeMode = true;
+ String ret;
+ ret.parse_utf8([[markedText mutableString] UTF8String]);
+ OS_OSX::singleton->im_callback(OS_OSX::singleton->im_target, ret, Point2(selectedRange.location, selectedRange.length));
+ }
+}
+- (void)doCommandBySelector:(SEL)aSelector {
+ if ([self respondsToSelector:aSelector])
+ [self performSelector:aSelector];
+}
- NSPasteboard *pboard = [sender draggingPasteboard];
- NSArray *filenames = [pboard propertyListForType:NSFilenamesPboardType];
+- (void)unmarkText {
+ imeMode = false;
+ [[markedText mutableString] setString:@""];
+ if (OS_OSX::singleton->im_callback)
+ OS_OSX::singleton->im_callback(OS_OSX::singleton->im_target, "", Point2());
+}
- Vector<String> files;
- for(int i=0;i<filenames.count;i++) {
- NSString *ns = [filenames objectAtIndex:i];
- char *utfs = strdup([ns UTF8String]);
- String ret;
- ret.parse_utf8(utfs);
- free(utfs);
- files.push_back(ret);
+- (NSArray *)validAttributesForMarkedText {
+ return [NSArray array];
+}
+- (NSAttributedString *)attributedSubstringForProposedRange:(NSRange)aRange actualRange:(NSRangePointer)actualRange {
+ return nil;
+}
- }
+- (NSUInteger)characterIndexForPoint:(NSPoint)aPoint {
+ return 0;
+}
- if (files.size()) {
- OS_OSX::singleton->main_loop->drop_files(files,0);
- OS_OSX::singleton->move_window_to_foreground();
- }
+- (NSRect)firstRectForCharacterRange:(NSRange)aRange actualRange:(NSRangePointer)actualRange {
+ const NSRect contentRect = [OS_OSX::singleton->window_view frame];
+ NSRect pointInWindowRect = NSMakeRect(OS_OSX::singleton->im_position.x / OS_OSX::singleton->display_scale, contentRect.size.height - (OS_OSX::singleton->im_position.y / OS_OSX::singleton->display_scale) - 1, 0, 0);
+ NSPoint pointOnScreen = [[OS_OSX::singleton->window_view window] convertRectToScreen:pointInWindowRect].origin;
- return NO;
+ return NSMakeRect(pointOnScreen.x, pointOnScreen.y, 0, 0);
}
+- (void)cancelComposition {
+ [self unmarkText];
+ NSInputManager *currentInputManager = [NSInputManager currentInputManager];
+ [currentInputManager markedTextAbandoned:self];
+}
-- (BOOL)isOpaque
-{
- return YES;
+- (void)insertText:(id)aString {
+ [self insertText:aString replacementRange:NSMakeRange(0, 0)];
}
-- (BOOL)canBecomeKeyView
-{
- return YES;
+- (void)insertText:(id)aString replacementRange:(NSRange)replacementRange {
+ NSEvent *event = [NSApp currentEvent];
+ Ref<InputEventKey> k;
+ k.instance();
+
+ get_key_modifier_state([event modifierFlags], k);
+ k->set_pressed(true);
+ k->set_echo(false);
+ k->set_scancode(0);
+
+ NSString *characters;
+ if ([aString isKindOfClass:[NSAttributedString class]]) {
+ characters = [aString string];
+ } else {
+ characters = (NSString *)aString;
+ }
+
+ NSUInteger i, length = [characters length];
+
+ NSCharacterSet *ctrlChars = [NSCharacterSet controlCharacterSet];
+ NSCharacterSet *wsnlChars = [NSCharacterSet whitespaceAndNewlineCharacterSet];
+ if ([characters rangeOfCharacterFromSet:ctrlChars].length && [characters rangeOfCharacterFromSet:wsnlChars].length == 0) {
+ NSInputManager *currentInputManager = [NSInputManager currentInputManager];
+ [currentInputManager markedTextAbandoned:self];
+ [self cancelComposition];
+ return;
+ }
+
+ for (i = 0; i < length; i++) {
+ const unichar codepoint = [characters characterAtIndex:i];
+ if ((codepoint & 0xFF00) == 0xF700)
+ continue;
+
+ k->set_unicode(codepoint);
+ OS_OSX::singleton->push_input(k);
+ }
+ [self cancelComposition];
}
-- (BOOL)acceptsFirstResponder
-{
- return YES;
+- (NSDragOperation)draggingEntered:(id<NSDraggingInfo>)sender {
+ return NSDragOperationCopy;
}
-- (void)cursorUpdate:(NSEvent *)event
-{
- // setModeCursor(window, window->cursorMode);
+- (NSDragOperation)draggingUpdated:(id<NSDraggingInfo>)sender {
+ return NSDragOperationCopy;
+}
+
+- (BOOL)performDragOperation:(id<NSDraggingInfo>)sender {
+
+ NSPasteboard *pboard = [sender draggingPasteboard];
+ NSArray *filenames = [pboard propertyListForType:NSFilenamesPboardType];
+
+ Vector<String> files;
+ for (int i = 0; i < filenames.count; i++) {
+ NSString *ns = [filenames objectAtIndex:i];
+ char *utfs = strdup([ns UTF8String]);
+ String ret;
+ ret.parse_utf8(utfs);
+ free(utfs);
+ files.push_back(ret);
+ }
+
+ if (files.size()) {
+ OS_OSX::singleton->main_loop->drop_files(files, 0);
+ OS_OSX::singleton->move_window_to_foreground();
+ }
+
+ return NO;
}
-- (void)mouseDown:(NSEvent *)event
-{
+- (BOOL)isOpaque {
+ return YES;
+}
- //print_line("mouse down:");
- button_mask|=BUTTON_MASK_LEFT;
- InputEvent ev;
- ev.type=InputEvent::MOUSE_BUTTON;
- ev.mouse_button.button_index=BUTTON_LEFT;
- ev.mouse_button.pressed=true;
- ev.mouse_button.x=mouse_x;
- ev.mouse_button.y=mouse_y;
- ev.mouse_button.global_x=mouse_x;
- ev.mouse_button.global_y=mouse_y;
- ev.mouse_button.button_mask=button_mask;
- ev.mouse_button.doubleclick = [event clickCount]==2;
- ev.mouse_button.mod = translateFlags([event modifierFlags]);
- OS_OSX::singleton->push_input(ev);
+- (BOOL)canBecomeKeyView {
+ return YES;
+}
+- (BOOL)acceptsFirstResponder {
+ return YES;
+}
- /* _glfwInputMouseClick(window,
- GLFW_MOUSE_BUTTON_LEFT,
- GLFW_PRESS,
- translateFlags([event modifierFlags]));*/
+- (void)cursorUpdate:(NSEvent *)event {
+ //setModeCursor(window, window->cursorMode);
}
-- (void)mouseDragged:(NSEvent *)event
-{
- [self mouseMoved:event];
+static void _mouseDownEvent(NSEvent *event, int index, int mask, bool pressed) {
+ if (pressed) {
+ button_mask |= mask;
+ } else {
+ button_mask &= ~mask;
+ }
+
+ Ref<InputEventMouseButton> mb;
+ mb.instance();
+
+ get_key_modifier_state([event modifierFlags], mb);
+ mb->set_button_index(index);
+ mb->set_pressed(pressed);
+ mb->set_position(Vector2(mouse_x, mouse_y));
+ mb->set_global_position(Vector2(mouse_x, mouse_y));
+ mb->set_button_mask(button_mask);
+ if (index == BUTTON_LEFT && pressed) {
+ mb->set_doubleclick([event clickCount] == 2);
+ }
+ OS_OSX::singleton->push_input(mb);
}
-- (void)mouseUp:(NSEvent *)event
-{
+- (void)mouseDown:(NSEvent *)event {
+ if (([event modifierFlags] & NSControlKeyMask)) {
+ mouse_down_control = true;
+ _mouseDownEvent(event, BUTTON_RIGHT, BUTTON_MASK_RIGHT, true);
+ } else {
+ mouse_down_control = false;
+ _mouseDownEvent(event, BUTTON_LEFT, BUTTON_MASK_LEFT, true);
+ }
+}
- button_mask&=~BUTTON_MASK_LEFT;
- InputEvent ev;
- ev.type=InputEvent::MOUSE_BUTTON;
- ev.mouse_button.button_index=BUTTON_LEFT;
- ev.mouse_button.pressed=false;
- ev.mouse_button.x=mouse_x;
- ev.mouse_button.y=mouse_y;
- ev.mouse_button.global_x=mouse_x;
- ev.mouse_button.global_y=mouse_y;
- ev.mouse_button.button_mask=button_mask;
- ev.mouse_button.mod = translateFlags([event modifierFlags]);
- OS_OSX::singleton->push_input(ev);
+- (void)mouseDragged:(NSEvent *)event {
+ [self mouseMoved:event];
+}
- /* _glfwInputMouseClick(window,
- GLFW_MOUSE_BUTTON_LEFT,
- GLFW_RELEASE,
- translateFlags([event modifierFlags]));*/
+- (void)mouseUp:(NSEvent *)event {
+ if (mouse_down_control) {
+ _mouseDownEvent(event, BUTTON_RIGHT, BUTTON_MASK_RIGHT, false);
+ } else {
+ _mouseDownEvent(event, BUTTON_LEFT, BUTTON_MASK_LEFT, false);
+ }
}
-- (void)mouseMoved:(NSEvent *)event
-{
+- (void)mouseMoved:(NSEvent *)event {
+
+ Ref<InputEventMouseMotion> mm;
+ mm.instance();
- InputEvent ev;
- ev.type=InputEvent::MOUSE_MOTION;
- ev.mouse_motion.button_mask=button_mask;
- prev_mouse_x=mouse_x;
- prev_mouse_y=mouse_y;
+ 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]);
- ev.mouse_motion.x=mouse_x;
- ev.mouse_motion.y=mouse_y;
- ev.mouse_motion.global_x=mouse_x;
- ev.mouse_motion.global_y=mouse_y;
- ev.mouse_motion.relative_x=[event deltaX] * OS_OSX::singleton->_mouse_scale([[event window] backingScaleFactor]);
- ev.mouse_motion.relative_y=[event deltaY] * OS_OSX::singleton->_mouse_scale([[event window] backingScaleFactor]);
- ev.mouse_motion.mod = translateFlags([event modifierFlags]);
-
- OS_OSX::singleton->input->set_mouse_pos(Point2(mouse_x,mouse_y));
- OS_OSX::singleton->push_input(ev);
-
-
- /* if (window->cursorMode == GLFW_CURSOR_DISABLED)
- _glfwInputCursorMotion(window, [event deltaX], [event deltaY]);
- else
- {
- const NSRect contentRect = [window->ns.view frame];
- const NSPoint p = [event locationInWindow];
+ mm->set_position(Vector2(mouse_x, mouse_y));
+ mm->set_global_position(Vector2(mouse_x, mouse_y));
+ 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]);
+ mm->set_relative(relativeMotion);
+ get_key_modifier_state([event modifierFlags], mm);
- _glfwInputCursorMotion(window, p.x, contentRect.size.height - p.y);
- }*/
+ OS_OSX::singleton->input->set_mouse_position(Point2(mouse_x, mouse_y));
+ OS_OSX::singleton->push_input(mm);
}
-- (void)rightMouseDown:(NSEvent *)event
-{
-
- button_mask|=BUTTON_MASK_RIGHT;
- InputEvent ev;
- ev.type=InputEvent::MOUSE_BUTTON;
- ev.mouse_button.button_index=BUTTON_RIGHT;
- ev.mouse_button.pressed=true;
- ev.mouse_button.x=mouse_x;
- ev.mouse_button.y=mouse_y;
- ev.mouse_button.global_x=mouse_x;
- ev.mouse_button.global_y=mouse_y;
- ev.mouse_button.button_mask=button_mask;
- ev.mouse_button.mod = translateFlags([event modifierFlags]);
- OS_OSX::singleton->push_input(ev);
-
- /* _glfwInputMouseClick(window,
- GLFW_MOUSE_BUTTON_RIGHT,
- GLFW_PRESS,
- translateFlags([event modifierFlags]));*/
+- (void)rightMouseDown:(NSEvent *)event {
+ _mouseDownEvent(event, BUTTON_RIGHT, BUTTON_MASK_RIGHT, true);
}
-- (void)rightMouseDragged:(NSEvent *)event
-{
- [self mouseMoved:event];
+- (void)rightMouseDragged:(NSEvent *)event {
+ [self mouseMoved:event];
}
-- (void)rightMouseUp:(NSEvent *)event
-{
-
- button_mask&=~BUTTON_MASK_RIGHT;
- InputEvent ev;
- ev.type=InputEvent::MOUSE_BUTTON;
- ev.mouse_button.button_index=BUTTON_RIGHT;
- ev.mouse_button.pressed=false;
- ev.mouse_button.x=mouse_x;
- ev.mouse_button.y=mouse_y;
- ev.mouse_button.global_x=mouse_x;
- ev.mouse_button.global_y=mouse_y;
- ev.mouse_button.button_mask=button_mask;
- ev.mouse_button.mod = translateFlags([event modifierFlags]);
- OS_OSX::singleton->push_input(ev);
-
- /*_glfwInputMouseClick(window,
- GLFW_MOUSE_BUTTON_RIGHT,
- GLFW_RELEASE,
- translateFlags([event modifierFlags]));*/
+- (void)rightMouseUp:(NSEvent *)event {
+ _mouseDownEvent(event, BUTTON_RIGHT, BUTTON_MASK_RIGHT, false);
}
-- (void)otherMouseDown:(NSEvent *)event
-{
+- (void)otherMouseDown:(NSEvent *)event {
- if ((int) [event buttonNumber]!=2)
+ if ((int)[event buttonNumber] != 2)
return;
- button_mask|=BUTTON_MASK_MIDDLE;
- InputEvent ev;
- ev.type=InputEvent::MOUSE_BUTTON;
- ev.mouse_button.button_index=BUTTON_MIDDLE;
- ev.mouse_button.pressed=true;
- ev.mouse_button.x=mouse_x;
- ev.mouse_button.y=mouse_y;
- ev.mouse_button.global_x=mouse_x;
- ev.mouse_button.global_y=mouse_y;
- ev.mouse_button.button_mask=button_mask;
- ev.mouse_button.mod = translateFlags([event modifierFlags]);
- OS_OSX::singleton->push_input(ev);
-
- /*_glfwInputMouseClick(window,
- (int) [event buttonNumber],
- GLFW_PRESS,
- translateFlags([event modifierFlags]));*/
+ _mouseDownEvent(event, BUTTON_MIDDLE, BUTTON_MASK_MIDDLE, true);
}
-- (void)otherMouseDragged:(NSEvent *)event
-{
- [self mouseMoved:event];
+- (void)otherMouseDragged:(NSEvent *)event {
+ [self mouseMoved:event];
}
-- (void)otherMouseUp:(NSEvent *)event
-{
+- (void)otherMouseUp:(NSEvent *)event {
- if ((int) [event buttonNumber]!=2)
+ if ((int)[event buttonNumber] != 2)
return;
- button_mask&=~BUTTON_MASK_MIDDLE;
- InputEvent ev;
- ev.type=InputEvent::MOUSE_BUTTON;
- ev.mouse_button.button_index=BUTTON_MIDDLE;
- ev.mouse_button.pressed=false;
- ev.mouse_button.x=mouse_x;
- ev.mouse_button.y=mouse_y;
- ev.mouse_button.global_x=mouse_x;
- ev.mouse_button.global_y=mouse_y;
- ev.mouse_button.button_mask=button_mask;
- ev.mouse_button.mod = translateFlags([event modifierFlags]);
- OS_OSX::singleton->push_input(ev);
- /* _glfwInputMouseClick(window,
- (int) [event buttonNumber],
- GLFW_RELEASE,
- translateFlags([event modifierFlags]));*/
-}
-
-- (void)mouseExited:(NSEvent *)event
-{
+ _mouseDownEvent(event, BUTTON_MIDDLE, BUTTON_MASK_MIDDLE, false);
+}
+
+- (void)mouseExited:(NSEvent *)event {
if (!OS_OSX::singleton)
return;
- if (OS_OSX::singleton->main_loop && OS_OSX::singleton->mouse_mode!=OS::MOUSE_MODE_CAPTURED)
+ if (OS_OSX::singleton->main_loop && OS_OSX::singleton->mouse_mode != OS::MOUSE_MODE_CAPTURED)
OS_OSX::singleton->main_loop->notification(MainLoop::NOTIFICATION_WM_MOUSE_EXIT);
if (OS_OSX::singleton->input)
OS_OSX::singleton->input->set_mouse_in_window(false);
- // _glfwInputCursorEnter(window, GL_FALSE);
}
-- (void)mouseEntered:(NSEvent *)event
-{
- // _glfwInputCursorEnter(window, GL_TRUE);
+- (void)mouseEntered:(NSEvent *)event {
if (!OS_OSX::singleton)
return;
- if (OS_OSX::singleton->main_loop && OS_OSX::singleton->mouse_mode!=OS::MOUSE_MODE_CAPTURED)
+ if (OS_OSX::singleton->main_loop && OS_OSX::singleton->mouse_mode != OS::MOUSE_MODE_CAPTURED)
OS_OSX::singleton->main_loop->notification(MainLoop::NOTIFICATION_WM_MOUSE_ENTER);
if (OS_OSX::singleton->input)
OS_OSX::singleton->input->set_mouse_in_window(true);
-
}
-- (void)viewDidChangeBackingProperties
-{
- /* const NSRect contentRect = [window->ns.view frame];
- const NSRect fbRect = convertRectToBacking(window, contentRect);
-
- _glfwInputFramebufferSize(window, fbRect.size.width, fbRect.size.height);*/
+- (void)viewDidChangeBackingProperties {
+ // nothing left to do here
}
-- (void)updateTrackingAreas
-{
- if (trackingArea != nil)
- {
- [self removeTrackingArea:trackingArea];
- [trackingArea release];
- }
+- (void)updateTrackingAreas {
+ if (trackingArea != nil) {
+ [self removeTrackingArea:trackingArea];
+ [trackingArea release];
+ }
- NSTrackingAreaOptions options = NSTrackingMouseEnteredAndExited |
- NSTrackingActiveInKeyWindow |
- NSTrackingCursorUpdate |
- NSTrackingInVisibleRect;
+ NSTrackingAreaOptions options =
+ NSTrackingMouseEnteredAndExited |
+ NSTrackingActiveInKeyWindow |
+ NSTrackingCursorUpdate |
+ NSTrackingInVisibleRect;
- trackingArea = [[NSTrackingArea alloc] initWithRect:[self bounds]
- options:options
- owner:self
- userInfo:nil];
+ trackingArea = [[NSTrackingArea alloc]
+ initWithRect:[self bounds]
+ options:options
+ owner:self
+ userInfo:nil];
- [self addTrackingArea:trackingArea];
- [super updateTrackingAreas];
+ [self addTrackingArea:trackingArea];
+ [super updateTrackingAreas];
}
// Translates a OS X keycode to a Godot keycode
//
-static int translateKey(unsigned int key)
-{
- // Keyboard symbol translation table
- static const unsigned int table[128] =
- {
- /* 00 */ KEY_A,
- /* 01 */ KEY_S,
- /* 02 */ KEY_D,
- /* 03 */ KEY_F,
- /* 04 */ KEY_H,
- /* 05 */ KEY_G,
- /* 06 */ KEY_Z,
- /* 07 */ KEY_X,
- /* 08 */ KEY_C,
- /* 09 */ KEY_V,
- /* 0a */ KEY_UNKNOWN,
- /* 0b */ KEY_B,
- /* 0c */ KEY_Q,
- /* 0d */ KEY_W,
- /* 0e */ KEY_E,
- /* 0f */ KEY_R,
- /* 10 */ KEY_Y,
- /* 11 */ KEY_T,
- /* 12 */ KEY_1,
- /* 13 */ KEY_2,
- /* 14 */ KEY_3,
- /* 15 */ KEY_4,
- /* 16 */ KEY_6,
- /* 17 */ KEY_5,
- /* 18 */ KEY_EQUAL,
- /* 19 */ KEY_9,
- /* 1a */ KEY_7,
- /* 1b */ KEY_MINUS,
- /* 1c */ KEY_8,
- /* 1d */ KEY_0,
- /* 1e */ KEY_BRACERIGHT,
- /* 1f */ KEY_O,
- /* 20 */ KEY_U,
- /* 21 */ KEY_BRACELEFT,
- /* 22 */ KEY_I,
- /* 23 */ KEY_P,
- /* 24 */ KEY_RETURN,
- /* 25 */ KEY_L,
- /* 26 */ KEY_J,
- /* 27 */ KEY_APOSTROPHE,
- /* 28 */ KEY_K,
- /* 29 */ KEY_SEMICOLON,
- /* 2a */ KEY_BACKSLASH,
- /* 2b */ KEY_COMMA,
- /* 2c */ KEY_SLASH,
- /* 2d */ KEY_N,
- /* 2e */ KEY_M,
- /* 2f */ KEY_PERIOD,
- /* 30 */ KEY_TAB,
- /* 31 */ KEY_SPACE,
- /* 32 */ KEY_QUOTELEFT,
- /* 33 */ KEY_BACKSPACE,
- /* 34 */ KEY_UNKNOWN,
- /* 35 */ KEY_ESCAPE,
- /* 36 */ KEY_META,
- /* 37 */ KEY_META,
- /* 38 */ KEY_SHIFT,
- /* 39 */ KEY_CAPSLOCK,
- /* 3a */ KEY_ALT,
- /* 3b */ KEY_CONTROL,
- /* 3c */ KEY_SHIFT,
- /* 3d */ KEY_ALT,
- /* 3e */ KEY_CONTROL,
- /* 3f */ KEY_UNKNOWN, /* Function */
- /* 40 */ KEY_UNKNOWN,
- /* 41 */ KEY_KP_PERIOD,
- /* 42 */ KEY_UNKNOWN,
- /* 43 */ KEY_KP_MULTIPLY,
- /* 44 */ KEY_UNKNOWN,
- /* 45 */ KEY_KP_ADD,
- /* 46 */ KEY_UNKNOWN,
- /* 47 */ KEY_NUMLOCK, /* Really KeypadClear... */
- /* 48 */ KEY_UNKNOWN, /* VolumeUp */
- /* 49 */ KEY_UNKNOWN, /* VolumeDown */
- /* 4a */ KEY_UNKNOWN, /* Mute */
- /* 4b */ KEY_KP_DIVIDE,
- /* 4c */ KEY_KP_ENTER,
- /* 4d */ KEY_UNKNOWN,
- /* 4e */ KEY_KP_SUBTRACT,
- /* 4f */ KEY_UNKNOWN,
- /* 50 */ KEY_UNKNOWN,
- /* 51 */ KEY_EQUAL, //wtf equal?
- /* 52 */ KEY_KP_0,
- /* 53 */ KEY_KP_1,
- /* 54 */ KEY_KP_2,
- /* 55 */ KEY_KP_3,
- /* 56 */ KEY_KP_4,
- /* 57 */ KEY_KP_5,
- /* 58 */ KEY_KP_6,
- /* 59 */ KEY_KP_7,
- /* 5a */ KEY_UNKNOWN,
- /* 5b */ KEY_KP_8,
- /* 5c */ KEY_KP_9,
- /* 5d */ KEY_UNKNOWN,
- /* 5e */ KEY_UNKNOWN,
- /* 5f */ KEY_UNKNOWN,
- /* 60 */ KEY_F5,
- /* 61 */ KEY_F6,
- /* 62 */ KEY_F7,
- /* 63 */ KEY_F3,
- /* 64 */ KEY_F8,
- /* 65 */ KEY_F9,
- /* 66 */ KEY_UNKNOWN,
- /* 67 */ KEY_F11,
- /* 68 */ KEY_UNKNOWN,
- /* 69 */ KEY_F13,
- /* 6a */ KEY_F16,
- /* 6b */ KEY_F14,
- /* 6c */ KEY_UNKNOWN,
- /* 6d */ KEY_F10,
- /* 6e */ KEY_UNKNOWN,
- /* 6f */ KEY_F12,
- /* 70 */ KEY_UNKNOWN,
- /* 71 */ KEY_F15,
- /* 72 */ KEY_INSERT, /* Really Help... */
- /* 73 */ KEY_HOME,
- /* 74 */ KEY_PAGEUP,
- /* 75 */ KEY_DELETE,
- /* 76 */ KEY_F4,
- /* 77 */ KEY_END,
- /* 78 */ KEY_F2,
- /* 79 */ KEY_PAGEDOWN,
- /* 7a */ KEY_F1,
- /* 7b */ KEY_LEFT,
- /* 7c */ KEY_RIGHT,
- /* 7d */ KEY_DOWN,
- /* 7e */ KEY_UP,
- /* 7f */ KEY_UNKNOWN,
- };
-
- if (key >= 128)
- return KEY_UNKNOWN;
-
- return table[key];
-}
-- (void)keyDown:(NSEvent *)event
-{
- InputEvent ev;
- ev.type=InputEvent::KEY;
- ev.key.pressed=true;
- ev.key.mod=translateFlags([event modifierFlags]);
- ev.key.scancode = latin_keyboard_keycode_convert(translateKey([event keyCode]));
- ev.key.echo = [event isARepeat];
-
- NSString* characters = [event characters];
- NSUInteger i, length = [characters length];
-
-
- if (length>0 && keycode_has_unicode(ev.key.scancode)) {
-
-
- for (i = 0; i < length; i++) {
- ev.key.unicode=[characters characterAtIndex:i];
- OS_OSX::singleton->push_input(ev);
- ev.key.scancode=0;
- }
+static int translateKey(unsigned int key) {
+ // Keyboard symbol translation table
+ static const unsigned int table[128] = {
+ /* 00 */ KEY_A,
+ /* 01 */ KEY_S,
+ /* 02 */ KEY_D,
+ /* 03 */ KEY_F,
+ /* 04 */ KEY_H,
+ /* 05 */ KEY_G,
+ /* 06 */ KEY_Z,
+ /* 07 */ KEY_X,
+ /* 08 */ KEY_C,
+ /* 09 */ KEY_V,
+ /* 0a */ KEY_UNKNOWN,
+ /* 0b */ KEY_B,
+ /* 0c */ KEY_Q,
+ /* 0d */ KEY_W,
+ /* 0e */ KEY_E,
+ /* 0f */ KEY_R,
+ /* 10 */ KEY_Y,
+ /* 11 */ KEY_T,
+ /* 12 */ KEY_1,
+ /* 13 */ KEY_2,
+ /* 14 */ KEY_3,
+ /* 15 */ KEY_4,
+ /* 16 */ KEY_6,
+ /* 17 */ KEY_5,
+ /* 18 */ KEY_EQUAL,
+ /* 19 */ KEY_9,
+ /* 1a */ KEY_7,
+ /* 1b */ KEY_MINUS,
+ /* 1c */ KEY_8,
+ /* 1d */ KEY_0,
+ /* 1e */ KEY_BRACERIGHT,
+ /* 1f */ KEY_O,
+ /* 20 */ KEY_U,
+ /* 21 */ KEY_BRACELEFT,
+ /* 22 */ KEY_I,
+ /* 23 */ KEY_P,
+ /* 24 */ KEY_ENTER,
+ /* 25 */ KEY_L,
+ /* 26 */ KEY_J,
+ /* 27 */ KEY_APOSTROPHE,
+ /* 28 */ KEY_K,
+ /* 29 */ KEY_SEMICOLON,
+ /* 2a */ KEY_BACKSLASH,
+ /* 2b */ KEY_COMMA,
+ /* 2c */ KEY_SLASH,
+ /* 2d */ KEY_N,
+ /* 2e */ KEY_M,
+ /* 2f */ KEY_PERIOD,
+ /* 30 */ KEY_TAB,
+ /* 31 */ KEY_SPACE,
+ /* 32 */ KEY_QUOTELEFT,
+ /* 33 */ KEY_BACKSPACE,
+ /* 34 */ KEY_UNKNOWN,
+ /* 35 */ KEY_ESCAPE,
+ /* 36 */ KEY_META,
+ /* 37 */ KEY_META,
+ /* 38 */ KEY_SHIFT,
+ /* 39 */ KEY_CAPSLOCK,
+ /* 3a */ KEY_ALT,
+ /* 3b */ KEY_CONTROL,
+ /* 3c */ KEY_SHIFT,
+ /* 3d */ KEY_ALT,
+ /* 3e */ KEY_CONTROL,
+ /* 3f */ KEY_UNKNOWN, /* Function */
+ /* 40 */ KEY_UNKNOWN,
+ /* 41 */ KEY_KP_PERIOD,
+ /* 42 */ KEY_UNKNOWN,
+ /* 43 */ KEY_KP_MULTIPLY,
+ /* 44 */ KEY_UNKNOWN,
+ /* 45 */ KEY_KP_ADD,
+ /* 46 */ KEY_UNKNOWN,
+ /* 47 */ KEY_NUMLOCK, /* Really KeypadClear... */
+ /* 48 */ KEY_UNKNOWN, /* VolumeUp */
+ /* 49 */ KEY_UNKNOWN, /* VolumeDown */
+ /* 4a */ KEY_UNKNOWN, /* Mute */
+ /* 4b */ KEY_KP_DIVIDE,
+ /* 4c */ KEY_KP_ENTER,
+ /* 4d */ KEY_UNKNOWN,
+ /* 4e */ KEY_KP_SUBTRACT,
+ /* 4f */ KEY_UNKNOWN,
+ /* 50 */ KEY_UNKNOWN,
+ /* 51 */ KEY_EQUAL, //wtf equal?
+ /* 52 */ KEY_KP_0,
+ /* 53 */ KEY_KP_1,
+ /* 54 */ KEY_KP_2,
+ /* 55 */ KEY_KP_3,
+ /* 56 */ KEY_KP_4,
+ /* 57 */ KEY_KP_5,
+ /* 58 */ KEY_KP_6,
+ /* 59 */ KEY_KP_7,
+ /* 5a */ KEY_UNKNOWN,
+ /* 5b */ KEY_KP_8,
+ /* 5c */ KEY_KP_9,
+ /* 5d */ KEY_UNKNOWN,
+ /* 5e */ KEY_UNKNOWN,
+ /* 5f */ KEY_UNKNOWN,
+ /* 60 */ KEY_F5,
+ /* 61 */ KEY_F6,
+ /* 62 */ KEY_F7,
+ /* 63 */ KEY_F3,
+ /* 64 */ KEY_F8,
+ /* 65 */ KEY_F9,
+ /* 66 */ KEY_UNKNOWN,
+ /* 67 */ KEY_F11,
+ /* 68 */ KEY_UNKNOWN,
+ /* 69 */ KEY_F13,
+ /* 6a */ KEY_F16,
+ /* 6b */ KEY_F14,
+ /* 6c */ KEY_UNKNOWN,
+ /* 6d */ KEY_F10,
+ /* 6e */ KEY_UNKNOWN,
+ /* 6f */ KEY_F12,
+ /* 70 */ KEY_UNKNOWN,
+ /* 71 */ KEY_F15,
+ /* 72 */ KEY_INSERT, /* Really Help... */
+ /* 73 */ KEY_HOME,
+ /* 74 */ KEY_PAGEUP,
+ /* 75 */ KEY_DELETE,
+ /* 76 */ KEY_F4,
+ /* 77 */ KEY_END,
+ /* 78 */ KEY_F2,
+ /* 79 */ KEY_PAGEDOWN,
+ /* 7a */ KEY_F1,
+ /* 7b */ KEY_LEFT,
+ /* 7c */ KEY_RIGHT,
+ /* 7d */ KEY_DOWN,
+ /* 7e */ KEY_UP,
+ /* 7f */ KEY_UNKNOWN,
+ };
- } else {
- OS_OSX::singleton->push_input(ev);
- }
+ if (key >= 128)
+ return KEY_UNKNOWN;
+
+ return table[key];
+}
+
+- (void)keyDown:(NSEvent *)event {
+
+ Ref<InputEventKey> k;
+ k.instance();
+
+ get_key_modifier_state([event modifierFlags], k);
+ k->set_pressed(true);
+ k->set_scancode(latin_keyboard_keycode_convert(translateKey([event keyCode])));
+ k->set_echo([event isARepeat]);
+
+ NSString *characters = [event characters];
+ NSUInteger i, length = [characters length];
+
+ //disable raw input in IME mode
+ if (!imeMode)
+ OS_OSX::singleton->push_input(k);
+
+ if ((OS_OSX::singleton->im_position.x != 0) && (OS_OSX::singleton->im_position.y != 0))
+ [self interpretKeyEvents:[NSArray arrayWithObject:event]];
}
-- (void)flagsChanged:(NSEvent *)event
-{
- InputEvent ev;
+- (void)flagsChanged:(NSEvent *)event {
+ Ref<InputEventKey> k;
+ k.instance();
+
int key = [event keyCode];
int mod = [event modifierFlags];
- ev.type=InputEvent::KEY;
-
if (key == 0x36 || key == 0x37) {
if (mod & NSCommandKeyMask) {
- mod&= ~NSCommandKeyMask;
- ev.key.pressed = true;
+ mod &= ~NSCommandKeyMask;
+ k->set_pressed(true);
} else {
- ev.key.pressed = false;
+ k->set_pressed(false);
}
} else if (key == 0x38 || key == 0x3c) {
if (mod & NSShiftKeyMask) {
- mod&= ~NSShiftKeyMask;
- ev.key.pressed = true;
+ mod &= ~NSShiftKeyMask;
+ k->set_pressed(true);
} else {
- ev.key.pressed = false;
+ k->set_pressed(false);
}
} else if (key == 0x3a || key == 0x3d) {
if (mod & NSAlternateKeyMask) {
- mod&= ~NSAlternateKeyMask;
- ev.key.pressed = true;
+ mod &= ~NSAlternateKeyMask;
+ k->set_pressed(true);
} else {
- ev.key.pressed = false;
+ k->set_pressed(false);
}
} else if (key == 0x3b || key == 0x3e) {
if (mod & NSControlKeyMask) {
- mod&= ~NSControlKeyMask;
- ev.key.pressed = true;
+ mod &= ~NSControlKeyMask;
+ k->set_pressed(true);
} else {
- ev.key.pressed = false;
+ k->set_pressed(false);
}
} else {
return;
}
- ev.key.mod=translateFlags(mod);
- ev.key.scancode = latin_keyboard_keycode_convert(translateKey(key));
+ get_key_modifier_state(mod, k);
+ k->set_scancode(latin_keyboard_keycode_convert(translateKey(key)));
- OS_OSX::singleton->push_input(ev);
+ OS_OSX::singleton->push_input(k);
}
-- (void)keyUp:(NSEvent *)event
-{
+- (void)keyUp:(NSEvent *)event {
- InputEvent ev;
- ev.type=InputEvent::KEY;
- ev.key.pressed=false;
- ev.key.mod=translateFlags([event modifierFlags]);
- ev.key.scancode = latin_keyboard_keycode_convert(translateKey([event keyCode]));
- OS_OSX::singleton->push_input(ev);
+ Ref<InputEventKey> k;
+ k.instance();
+ get_key_modifier_state([event modifierFlags], k);
+ k->set_pressed(false);
+ k->set_scancode(latin_keyboard_keycode_convert(translateKey([event keyCode])));
- /* const int key = translateKey([event keyCode]);
- const int mods = translateFlags([event modifierFlags]);
- _glfwInputKey(window, key, [event keyCode], GLFW_RELEASE, mods);*/
+ OS_OSX::singleton->push_input(k);
}
-- (void)scrollWheel:(NSEvent *)event
-{
+inline void sendScrollEvent(int button, double factor, int modifierFlags) {
- double deltaX, deltaY;
+ Ref<InputEventMouseButton> sc;
+ sc.instance();
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
- if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6)
- {
- deltaX = [event scrollingDeltaX];
- deltaY = [event scrollingDeltaY];
-
- if ([event hasPreciseScrollingDeltas])
- {
- deltaX *= 0.1;
- deltaY *= 0.1;
- }
- }
- else
-#endif /*MAC_OS_X_VERSION_MAX_ALLOWED*/
- {
- deltaX = [event deltaX];
- deltaY = [event deltaY];
- }
+ get_key_modifier_state(modifierFlags, sc);
+ sc->set_button_index(button);
+ sc->set_factor(factor);
+ sc->set_pressed(true);
+ Vector2 mouse_pos = Vector2(mouse_x, mouse_y);
+ sc->set_position(mouse_pos);
+ sc->set_global_position(mouse_pos);
+ sc->set_button_mask(button_mask);
+ OS_OSX::singleton->push_input(sc);
+ sc->set_pressed(false);
+ OS_OSX::singleton->push_input(sc);
+}
+- (void)scrollWheel:(NSEvent *)event {
+ double deltaX, deltaY;
- if (fabs(deltaY)) {
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
+ if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6) {
+ deltaX = [event scrollingDeltaX];
+ deltaY = [event scrollingDeltaY];
- InputEvent ev;
- ev.type=InputEvent::MOUSE_BUTTON;
- ev.mouse_button.button_index=deltaY >0 ? BUTTON_WHEEL_UP : BUTTON_WHEEL_DOWN;
- ev.mouse_button.pressed=true;
- ev.mouse_button.x=mouse_x;
- ev.mouse_button.y=mouse_y;
- ev.mouse_button.global_x=mouse_x;
- ev.mouse_button.global_y=mouse_y;
- ev.mouse_button.button_mask=button_mask;
- OS_OSX::singleton->push_input(ev);
- ev.mouse_button.pressed=false;
- OS_OSX::singleton->push_input(ev);
+ if ([event hasPreciseScrollingDeltas]) {
+ deltaX *= 0.03;
+ deltaY *= 0.03;
+ }
+ } else
+#endif // MAC_OS_X_VERSION_MAX_ALLOWED
+ {
+ deltaX = [event deltaX];
+ deltaY = [event deltaY];
}
-
if (fabs(deltaX)) {
-
- InputEvent ev;
- ev.type=InputEvent::MOUSE_BUTTON;
- ev.mouse_button.button_index=deltaX < 0 ? BUTTON_WHEEL_RIGHT : BUTTON_WHEEL_LEFT;
- ev.mouse_button.pressed=true;
- ev.mouse_button.x=mouse_x;
- ev.mouse_button.y=mouse_y;
- ev.mouse_button.global_x=mouse_x;
- ev.mouse_button.global_y=mouse_y;
- ev.mouse_button.button_mask=button_mask;
- OS_OSX::singleton->push_input(ev);
- ev.mouse_button.pressed=false;
- OS_OSX::singleton->push_input(ev);
+ 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]);
}
}
@end
-@interface GodotWindow : NSWindow {}
+@interface GodotWindow : NSWindow {
+}
@end
@implementation GodotWindow
-
-- (BOOL)canBecomeKeyWindow
-{
- // Required for NSBorderlessWindowMask windows
- return YES;
+- (BOOL)canBecomeKeyWindow {
+ // Required for NSBorderlessWindowMask windows
+ return YES;
}
@end
+void OS_OSX::set_ime_intermediate_text_callback(ImeCallback p_callback, void *p_inp) {
+ im_callback = p_callback;
+ im_target = p_inp;
+ if (!im_callback) {
+ [window_view cancelComposition];
+ }
+}
-int OS_OSX::get_video_driver_count() const {
+void OS_OSX::set_ime_position(const Point2 &p_pos) {
+ im_position = p_pos;
+}
+int OS_OSX::get_video_driver_count() const {
return 1;
}
-const char * OS_OSX::get_video_driver_name(int p_driver) const {
+
+const char *OS_OSX::get_video_driver_name(int p_driver) const {
return "GLES2";
}
@@ -924,14 +896,13 @@ const char * OS_OSX::get_video_driver_name(int p_driver) const {
OS::VideoMode OS_OSX::get_default_video_mode() const {
VideoMode vm;
- vm.width=1024;
- vm.height=600;
- vm.fullscreen=false;
- vm.resizable=true;
+ vm.width = 1024;
+ vm.height = 600;
+ vm.fullscreen = false;
+ vm.resizable = true;
return vm;
}
-
void OS_OSX::initialize_core() {
OS_Unix::initialize_core();
@@ -941,7 +912,6 @@ void OS_OSX::initialize_core() {
DirAccess::make_default<DirAccessOSX>(DirAccess::ACCESS_FILESYSTEM);
SemaphoreOSX::make_default();
-
}
static bool keyboard_layout_dirty = true;
@@ -949,7 +919,7 @@ static void keyboardLayoutChanged(CFNotificationCenterRef center, void *observer
keyboard_layout_dirty = true;
}
-void OS_OSX::initialize(const VideoMode& p_desired,int p_video_driver,int p_audio_driver) {
+void OS_OSX::initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver) {
/*** OSX INITIALIZATION ***/
/*** OSX INITIALIZATION ***/
@@ -959,43 +929,48 @@ void OS_OSX::initialize(const VideoMode& p_desired,int p_video_driver,int p_audi
// Register to be notified on keyboard layout changes
CFNotificationCenterAddObserver(CFNotificationCenterGetDistributedCenter(),
- NULL, keyboardLayoutChanged,
- kTISNotifySelectedKeyboardInputSourceChanged, NULL,
- CFNotificationSuspensionBehaviorDeliverImmediately);
+ NULL, keyboardLayoutChanged,
+ kTISNotifySelectedKeyboardInputSourceChanged, NULL,
+ CFNotificationSuspensionBehaviorDeliverImmediately);
if (is_hidpi_allowed() && [[NSScreen mainScreen] respondsToSelector:@selector(backingScaleFactor)]) {
- for (NSScreen *screen in [NSScreen screens]) {
- float s = [screen backingScaleFactor];
- if (s > display_scale) {
- display_scale=s;
- }
- }
+ for (NSScreen *screen in [NSScreen screens]) {
+ float s = [screen backingScaleFactor];
+ if (s > display_scale) {
+ display_scale = s;
+ }
+ }
}
window_delegate = [[GodotWindowDelegate alloc] init];
- // Don't use accumulation buffer support; it's not accelerated
- // Aux buffers probably aren't accelerated either
+ // Don't use accumulation buffer support; it's not accelerated
+ // Aux buffers probably aren't accelerated either
- unsigned int styleMask = NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | (p_desired.resizable?NSResizableWindowMask:0);
+ unsigned int styleMask;
+ if (p_desired.borderless_window) {
+ styleMask = NSWindowStyleMaskBorderless;
+ } else {
+ styleMask = NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | (p_desired.resizable ? NSResizableWindowMask : 0);
+ }
window_object = [[GodotWindow alloc]
- initWithContentRect:NSMakeRect(0, 0, p_desired.width/display_scale, p_desired.height/display_scale)
- styleMask:styleMask
- backing:NSBackingStoreBuffered
- defer:NO];
+ initWithContentRect:NSMakeRect(0, 0, p_desired.width, p_desired.height)
+ styleMask:styleMask
+ backing:NSBackingStoreBuffered
+ defer:NO];
- ERR_FAIL_COND( window_object==nil );
+ ERR_FAIL_COND(window_object == nil);
window_view = [[GodotContentView alloc] init];
- window_size.width = p_desired.width;
- window_size.height = p_desired.height;
+ window_size.width = p_desired.width * display_scale;
+ window_size.height = p_desired.height * display_scale;
- if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6 && display_scale>1) {
- [window_view setWantsBestResolutionOpenGLSurface:YES];
- //if (current_videomode.resizable)
+ if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6 && display_scale > 1) {
+ [window_view setWantsBestResolutionOpenGLSurface:YES];
+ //if (current_videomode.resizable)
[window_object setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary];
}
@@ -1013,11 +988,15 @@ void OS_OSX::initialize(const VideoMode& p_desired,int p_video_driver,int p_audi
// 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; }
-#define ADD_ATTR2(x, y) { ADD_ATTR(x); ADD_ATTR(y); }
+#define ADD_ATTR(x) \
+ { attributes[attributeCount++] = x; }
+#define ADD_ATTR2(x, y) \
+ { \
+ ADD_ATTR(x); \
+ ADD_ATTR(y); \
+ }
// Arbitrary array size here
NSOpenGLPixelFormatAttribute attributes[40];
@@ -1030,21 +1009,26 @@ void OS_OSX::initialize(const VideoMode& p_desired,int p_video_driver,int p_audi
ADD_ATTR2(NSOpenGLPFAColorSize, colorBits);
- /* if (fbconfig->alphaBits > 0)
- ADD_ATTR2(NSOpenGLPFAAlphaSize, fbconfig->alphaBits);*/
+ /*
+ if (fbconfig->alphaBits > 0)
+ ADD_ATTR2(NSOpenGLPFAAlphaSize, fbconfig->alphaBits);
+*/
ADD_ATTR2(NSOpenGLPFADepthSize, 24);
ADD_ATTR2(NSOpenGLPFAStencilSize, 8);
- /*if (fbconfig->stereo)
- ADD_ATTR(NSOpenGLPFAStereo);*/
+ /*
+ if (fbconfig->stereo)
+ ADD_ATTR(NSOpenGLPFAStereo);
+*/
- /* if (fbconfig->samples > 0)
- {
- ADD_ATTR2(NSOpenGLPFASampleBuffers, 1);
- ADD_ATTR2(NSOpenGLPFASamples, fbconfig->samples);
- }*/
+ /*
+ if (fbconfig->samples > 0) {
+ ADD_ATTR2(NSOpenGLPFASampleBuffers, 1);
+ ADD_ATTR2(NSOpenGLPFASamples, fbconfig->samples);
+ }
+*/
// NOTE: All NSOpenGLPixelFormats on the relevant cards support sRGB
// frambuffer, so there's no need (and no way) to request it
@@ -1055,14 +1039,11 @@ void OS_OSX::initialize(const VideoMode& p_desired,int p_video_driver,int p_audi
#undef ADD_ATTR2
pixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:attributes];
- ERR_FAIL_COND( pixelFormat == nil);
-
+ ERR_FAIL_COND(pixelFormat == nil);
- context = [[NSOpenGLContext alloc] initWithFormat:pixelFormat
- shareContext:nil];
-
- ERR_FAIL_COND(context==nil);
+ context = [[NSOpenGLContext alloc] initWithFormat:pixelFormat shareContext:nil];
+ ERR_FAIL_COND(context == nil);
[context setView:window_view];
@@ -1070,6 +1051,8 @@ void OS_OSX::initialize(const VideoMode& p_desired,int p_video_driver,int p_audi
[NSApp activateIgnoringOtherApps:YES];
+ _update_window();
+
[window_object makeKeyAndOrderFront:nil];
if (p_desired.fullscreen)
@@ -1079,79 +1062,49 @@ void OS_OSX::initialize(const VideoMode& p_desired,int p_video_driver,int p_audi
/*** END OSX INITIALIZATION ***/
/*** END OSX INITIALIZATION ***/
- bool use_gl2=p_video_driver!=1;
-
-
+ bool use_gl2 = p_video_driver != 1;
AudioDriverManager::add_driver(&audio_driver_osx);
- // only opengl support here...
+ // only opengl support here...
RasterizerGLES3::register_config();
RasterizerGLES3::make_current();
//rasterizer = instance_RasterizerGLES2();
//visual_server = memnew( VisualServerRaster(rasterizer) );
- visual_server = memnew( VisualServerRaster );
- // FIXME: Reimplement threaded rendering? Or remove?
- /*
- if (get_render_thread_mode()!=RENDER_THREAD_UNSAFE) {
- visual_server =memnew(VisualServerWrapMT(visual_server,get_render_thread_mode()==RENDER_SEPARATE_THREAD));
+ 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);
+ // visual_server->cursor_set_visible(false, 0);
AudioDriverManager::get_driver(p_audio_driver)->set_singleton();
- if (AudioDriverManager::get_driver(p_audio_driver)->init()!=OK) {
+ if (AudioDriverManager::get_driver(p_audio_driver)->init() != OK) {
ERR_PRINT("Initializing audio failed.");
}
//
- physics_server = memnew( PhysicsServerSW );
+ physics_server = memnew(PhysicsServerSW);
physics_server->init();
//physics_2d_server = memnew( Physics2DServerSW );
physics_2d_server = Physics2DServerWrapMT::init_server<Physics2DServerSW>();
physics_2d_server->init();
- input = memnew( InputDefault );
- joypad_osx = memnew( JoypadOSX );
+ input = memnew(InputDefault);
+ joypad_osx = memnew(JoypadOSX);
- power_manager = memnew( power_osx );
+ power_manager = memnew(power_osx);
_ensure_data_dir();
- NSArray *screenArray = [NSScreen screens];
- printf("nscreen count %i\n", (int)[screenArray count]);
- for (int i=0; i<[screenArray count]; i++) {
-
- float displayScale = 1.0;
-
- if (display_scale>1.0 && [[screenArray objectAtIndex: i] respondsToSelector:@selector(backingScaleFactor)]) {
- displayScale = [[screenArray objectAtIndex: i] backingScaleFactor];
- }
-
- NSRect nsrect = [[screenArray objectAtIndex: i] visibleFrame];
- Rect2 rect = Rect2(nsrect.origin.x, nsrect.origin.y, nsrect.size.width, nsrect.size.height);
- rect.pos*=displayScale;
- rect.size*=displayScale;
- screens.push_back(rect);
-
- NSDictionary *description = [[screenArray objectAtIndex: i] deviceDescription];
- NSSize displayPixelSize = [[description objectForKey:NSDeviceSize] sizeValue];
- CGSize displayPhysicalSize = CGDisplayScreenSize(
- [[description objectForKey:@"NSScreenNumber"] unsignedIntValue]);
-
- //printf("width: %i pwidth %i rect width %i\n",int(displayPixelSize.width*displayScale),int(displayPhysicalSize.width*displayScale),int(nsrect.size.width));
- int dpi = (displayPixelSize.width * 25.4f / displayPhysicalSize.width)*displayScale;
-
- screen_dpi.push_back(dpi);
-
- };
restore_rect = Rect2(get_window_position(), get_window_size());
}
+
void OS_OSX::finalize() {
CFNotificationCenterRemoveObserver(CFNotificationCenterGetDistributedCenter(), NULL, kTISNotifySelectedKeyboardInputSourceChanged, NULL);
@@ -1169,17 +1122,12 @@ void OS_OSX::finalize() {
physics_2d_server->finish();
memdelete(physics_2d_server);
-
- screens.clear();
-
-
}
-void OS_OSX::set_main_loop( MainLoop * p_main_loop ) {
+void OS_OSX::set_main_loop(MainLoop *p_main_loop) {
- main_loop=p_main_loop;
+ main_loop = p_main_loop;
input->set_main_loop(p_main_loop);
-
}
void OS_OSX::delete_main_loop() {
@@ -1187,16 +1135,54 @@ void OS_OSX::delete_main_loop() {
if (!main_loop)
return;
memdelete(main_loop);
- main_loop=NULL;
+ main_loop = NULL;
}
-
String OS_OSX::get_name() {
return "OSX";
}
-void OS_OSX::alert(const String& p_alert, const String& p_title) {
+void OS_OSX::print_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, ErrorType p_type) {
+
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 101200
+ if (!_print_error_enabled)
+ return;
+
+ const char *err_details;
+ if (p_rationale && p_rationale[0])
+ err_details = p_rationale;
+ else
+ err_details = p_code;
+
+ switch (p_type) {
+ case ERR_ERROR:
+ os_log_error(OS_LOG_DEFAULT, "ERROR: %{public}s: %{public}s\nAt: %{public}s:%i.", p_function, err_details, p_file, p_line);
+ print("\E[1;31mERROR: %s: \E[0m\E[1m%s\n", p_function, err_details);
+ print("\E[0;31m At: %s:%i.\E[0m\n", p_file, p_line);
+ break;
+ case ERR_WARNING:
+ os_log_info(OS_LOG_DEFAULT, "WARNING: %{public}s: %{public}s\nAt: %{public}s:%i.", p_function, err_details, p_file, p_line);
+ print("\E[1;33mWARNING: %s: \E[0m\E[1m%s\n", p_function, err_details);
+ print("\E[0;33m At: %s:%i.\E[0m\n", p_file, p_line);
+ break;
+ case ERR_SCRIPT:
+ os_log_error(OS_LOG_DEFAULT, "SCRIPT ERROR: %{public}s: %{public}s\nAt: %{public}s:%i.", p_function, err_details, p_file, p_line);
+ print("\E[1;35mSCRIPT ERROR: %s: \E[0m\E[1m%s\n", p_function, err_details);
+ print("\E[0;35m At: %s:%i.\E[0m\n", p_file, p_line);
+ break;
+ case ERR_SHADER:
+ os_log_error(OS_LOG_DEFAULT, "SHADER ERROR: %{public}s: %{public}s\nAt: %{public}s:%i.", p_function, err_details, p_file, p_line);
+ print("\E[1;36mSHADER ERROR: %s: \E[0m\E[1m%s\n", p_function, err_details);
+ print("\E[0;36m At: %s:%i.\E[0m\n", p_file, p_line);
+ break;
+ }
+#else
+ OS_Unix::print_error(p_function, p_file, p_line, p_code, p_rationale, p_type);
+#endif
+}
+
+void OS_OSX::alert(const String &p_alert, const String &p_title) {
// Set OS X-compliant variables
NSAlert *window = [[NSAlert alloc] init];
NSString *ns_title = [NSString stringWithUTF8String:p_title.utf8().get_data()];
@@ -1214,10 +1200,10 @@ void OS_OSX::alert(const String& p_alert, const String& p_title) {
void OS_OSX::set_cursor_shape(CursorShape p_shape) {
- if (cursor_shape==p_shape)
+ if (cursor_shape == p_shape)
return;
- switch(p_shape) {
+ switch (p_shape) {
case CURSOR_ARROW: [[NSCursor arrowCursor] set]; break;
case CURSOR_IBEAM: [[NSCursor IBeamCursor] set]; break;
case CURSOR_POINTING_HAND: [[NSCursor pointingHandCursor] set]; break;
@@ -1238,101 +1224,97 @@ void OS_OSX::set_cursor_shape(CursorShape p_shape) {
default: {};
}
- cursor_shape=p_shape;
+ cursor_shape = p_shape;
}
void OS_OSX::set_mouse_show(bool p_show) {
-
}
-void OS_OSX::set_mouse_grab(bool p_grab) {
+void OS_OSX::set_mouse_grab(bool p_grab) {
}
+
bool OS_OSX::is_mouse_grab_enabled() const {
return mouse_grab;
}
-void OS_OSX::warp_mouse_pos(const Point2& p_to) {
-
- //copied from windows impl with osx native calls
- if (mouse_mode == MOUSE_MODE_CAPTURED){
- mouse_x = p_to.x;
- mouse_y = p_to.y;
- }
- else{ //set OS position
+void OS_OSX::warp_mouse_pos(const Point2 &p_to) {
- /* this code has not been tested, please be a kind soul and fix it if it fails! */
+ //copied from windows impl with osx native calls
+ if (mouse_mode == MOUSE_MODE_CAPTURED) {
+ mouse_x = p_to.x;
+ mouse_y = p_to.y;
+ } else { //set OS position
- //local point in window coords
- NSPoint localPoint = { p_to.x, p_to.y };
+ //local point in window coords
+ const NSRect contentRect = [window_view frame];
+ NSRect pointInWindowRect = NSMakeRect(p_to.x / display_scale, contentRect.size.height - (p_to.y / display_scale) - 1, 0, 0);
+ NSPoint pointOnScreen = [[window_view window] convertRectToScreen:pointInWindowRect].origin;
- NSPoint pointInWindow = [window_view convertPoint:localPoint toView:nil];
- NSRect pointInWindowRect;
- pointInWindowRect.origin = pointInWindow;
- NSPoint pointOnScreen = [[window_view window] convertRectToScreen:pointInWindowRect].origin;
+ //point in scren coords
+ CGPoint lMouseWarpPos = { pointOnScreen.x, CGDisplayBounds(CGMainDisplayID()).size.height - pointOnScreen.y };
- //point in scren coords
- CGPoint lMouseWarpPos = { pointOnScreen.x, pointOnScreen.y};
-
- //do the warping
- CGEventSourceRef lEventRef = CGEventSourceCreate(kCGEventSourceStateCombinedSessionState);
- CGEventSourceSetLocalEventsSuppressionInterval(lEventRef, 0.0);
- CGAssociateMouseAndMouseCursorPosition(false);
- CGWarpMouseCursorPosition(lMouseWarpPos);
- CGAssociateMouseAndMouseCursorPosition(true);
- }
+ //do the warping
+ CGEventSourceRef lEventRef = CGEventSourceCreate(kCGEventSourceStateCombinedSessionState);
+ CGEventSourceSetLocalEventsSuppressionInterval(lEventRef, 0.0);
+ CGAssociateMouseAndMouseCursorPosition(false);
+ CGWarpMouseCursorPosition(lMouseWarpPos);
+ CGAssociateMouseAndMouseCursorPosition(true);
+ }
}
-Point2 OS_OSX::get_mouse_pos() const {
+Point2 OS_OSX::get_mouse_position() const {
- return Vector2(mouse_x,mouse_y);
+ return Vector2(mouse_x, mouse_y);
}
+
int OS_OSX::get_mouse_button_state() const {
return button_mask;
}
-void OS_OSX::set_window_title(const String& p_title) {
- [window_object setTitle:[NSString stringWithUTF8String:p_title.utf8().get_data()]];
+void OS_OSX::set_window_title(const String &p_title) {
+ title = p_title;
+ [window_object setTitle:[NSString stringWithUTF8String:p_title.utf8().get_data()]];
}
-void OS_OSX::set_icon(const Image& p_icon) {
-
- Image img=p_icon;
- img.convert(Image::FORMAT_RGBA8);
- NSBitmapImageRep *imgrep= [[[NSBitmapImageRep alloc] initWithBitmapDataPlanes: NULL
- pixelsWide: p_icon.get_width()
- pixelsHigh: p_icon.get_height()
- bitsPerSample: 8
- samplesPerPixel: 4
- hasAlpha: YES
- isPlanar: NO
- colorSpaceName: NSDeviceRGBColorSpace
- bytesPerRow: p_icon.get_width()*4
- bitsPerPixel: 32] autorelease];
- ERR_FAIL_COND(imgrep==nil);
+void OS_OSX::set_icon(const Ref<Image> &p_icon) {
+
+ Ref<Image> img = p_icon;
+ img = img->duplicate();
+ img->convert(Image::FORMAT_RGBA8);
+ NSBitmapImageRep *imgrep = [[[NSBitmapImageRep alloc]
+ initWithBitmapDataPlanes:NULL
+ pixelsWide:img->get_width()
+ pixelsHigh:img->get_height()
+ bitsPerSample:8
+ samplesPerPixel:4
+ hasAlpha:YES
+ isPlanar:NO
+ colorSpaceName:NSDeviceRGBColorSpace
+ bytesPerRow:img->get_width() * 4
+ bitsPerPixel:32] autorelease];
+ ERR_FAIL_COND(imgrep == nil);
uint8_t *pixels = [imgrep bitmapData];
- int len = img.get_width()*img.get_height();
- PoolVector<uint8_t> data = img.get_data();
+ int len = img->get_width() * img->get_height();
+ PoolVector<uint8_t> data = img->get_data();
PoolVector<uint8_t>::Read r = data.read();
/* Premultiply the alpha channel */
- for (int i = 0; i<len ; i++) {
- uint8_t alpha = r[i*4+3];
- pixels[i*4+0] = (uint8_t)(((uint16_t)r[i*4+0] * alpha) / 255);
- pixels[i*4+1] = (uint8_t)(((uint16_t)r[i*4+1] * alpha) / 255);
- pixels[i*4+2] = (uint8_t)(((uint16_t)r[i*4+2] * alpha) / 255);
- pixels[i*4+3] = alpha;
-
+ for (int i = 0; i < len; i++) {
+ uint8_t alpha = r[i * 4 + 3];
+ pixels[i * 4 + 0] = (uint8_t)(((uint16_t)r[i * 4 + 0] * alpha) / 255);
+ pixels[i * 4 + 1] = (uint8_t)(((uint16_t)r[i * 4 + 1] * alpha) / 255);
+ pixels[i * 4 + 2] = (uint8_t)(((uint16_t)r[i * 4 + 2] * alpha) / 255);
+ pixels[i * 4 + 3] = alpha;
}
- NSImage *nsimg = [[[NSImage alloc] initWithSize: NSMakeSize(img.get_width(),img.get_height())] autorelease];
+ NSImage *nsimg = [[[NSImage alloc] initWithSize:NSMakeSize(img->get_width(), img->get_height())] autorelease];
ERR_FAIL_COND(nsimg == nil);
- [nsimg addRepresentation: imgrep];
+ [nsimg addRepresentation:imgrep];
[NSApp setApplicationIconImage:nsimg];
-
}
MainLoop *OS_OSX::get_main_loop() const {
@@ -1345,27 +1327,26 @@ bool OS_OSX::can_draw() const {
return true;
}
-void OS_OSX::set_clipboard(const String& p_text) {
+void OS_OSX::set_clipboard(const String &p_text) {
- NSArray* types = [NSArray arrayWithObjects:NSStringPboardType, nil];
+ NSArray *types = [NSArray arrayWithObjects:NSStringPboardType, nil];
- NSPasteboard* pasteboard = [NSPasteboard generalPasteboard];
+ NSPasteboard *pasteboard = [NSPasteboard generalPasteboard];
[pasteboard declareTypes:types owner:nil];
[pasteboard setString:[NSString stringWithUTF8String:p_text.utf8().get_data()]
- forType:NSStringPboardType];
+ forType:NSStringPboardType];
}
+
String OS_OSX::get_clipboard() const {
- NSPasteboard* pasteboard = [NSPasteboard generalPasteboard];
+ NSPasteboard *pasteboard = [NSPasteboard generalPasteboard];
- if (![[pasteboard types] containsObject:NSStringPboardType])
- {
+ if (![[pasteboard types] containsObject:NSStringPboardType]) {
return "";
}
- NSString* object = [pasteboard stringForType:NSStringPboardType];
- if (!object)
- {
+ NSString *object = [pasteboard stringForType:NSStringPboardType];
+ if (!object) {
return "";
}
@@ -1380,12 +1361,11 @@ String OS_OSX::get_clipboard() const {
void OS_OSX::release_rendering_thread() {
[NSOpenGLContext clearCurrentContext];
-
}
+
void OS_OSX::make_rendering_thread() {
[context makeCurrentContext];
-
}
Error OS_OSX::shell_open(String p_uri) {
@@ -1395,14 +1375,13 @@ Error OS_OSX::shell_open(String p_uri) {
}
String OS_OSX::get_locale() const {
- NSString* preferredLang = [[NSLocale preferredLanguages] objectAtIndex:0];
- return [preferredLang UTF8String];
+ NSString *locale_code = [[NSLocale currentLocale] localeIdentifier];
+ return [locale_code UTF8String];
}
void OS_OSX::swap_buffers() {
[context flushBuffer];
-
}
void OS_OSX::wm_minimized(bool p_minimized) {
@@ -1410,92 +1389,163 @@ void OS_OSX::wm_minimized(bool p_minimized) {
minimized = p_minimized;
};
-void OS_OSX::set_video_mode(const VideoMode& p_video_mode,int p_screen) {
-
+void OS_OSX::set_video_mode(const VideoMode &p_video_mode, int p_screen) {
}
OS::VideoMode OS_OSX::get_video_mode(int p_screen) const {
VideoMode vm;
- vm.width=window_size.width;
- vm.height=window_size.height;
+ vm.width = window_size.width;
+ vm.height = window_size.height;
return vm;
}
-void OS_OSX::get_fullscreen_mode_list(List<VideoMode> *p_list,int p_screen) const {
+void OS_OSX::get_fullscreen_mode_list(List<VideoMode> *p_list, int p_screen) const {
}
-
int OS_OSX::get_screen_count() const {
-
- return screens.size();
+ NSArray *screenArray = [NSScreen screens];
+ return [screenArray count];
};
int OS_OSX::get_current_screen() const {
-
- return current_screen;
+ Vector2 wpos = get_window_position();
+
+ int count = get_screen_count();
+ for (int i = 0; i < count; i++) {
+ Point2 pos = get_screen_position(i);
+ Size2 size = get_screen_size(i);
+ if ((wpos.x >= pos.x && wpos.x < pos.x + size.width) && (wpos.y >= pos.y && wpos.y < pos.y + size.height))
+ return i;
+ }
+ return 0;
};
void OS_OSX::set_current_screen(int p_screen) {
-
- current_screen = p_screen;
+ Vector2 wpos = get_window_position() - get_screen_position(get_current_screen());
+ set_window_position(wpos + get_screen_position(p_screen));
};
Point2 OS_OSX::get_screen_position(int p_screen) const {
+ NSArray *screenArray = [NSScreen screens];
+ if (p_screen < [screenArray count]) {
+ float displayScale = 1.0;
- ERR_FAIL_INDEX_V(p_screen, screens.size(), Point2());
- return screens[p_screen].pos;
-};
+ if (display_scale > 1.0 && [[screenArray objectAtIndex:p_screen] respondsToSelector:@selector(backingScaleFactor)]) {
+ displayScale = [[screenArray objectAtIndex:p_screen] backingScaleFactor];
+ }
+
+ NSRect nsrect = [[screenArray objectAtIndex:p_screen] frame];
+ return Point2(nsrect.origin.x, nsrect.origin.y) * displayScale;
+ }
+
+ return Point2();
+}
int OS_OSX::get_screen_dpi(int p_screen) const {
+ NSArray *screenArray = [NSScreen screens];
+ if (p_screen < [screenArray count]) {
+ float displayScale = 1.0;
+
+ if (display_scale > 1.0 && [[screenArray objectAtIndex:p_screen] respondsToSelector:@selector(backingScaleFactor)]) {
+ displayScale = [[screenArray objectAtIndex:p_screen] backingScaleFactor];
+ }
+
+ NSDictionary *description = [[screenArray objectAtIndex:p_screen] deviceDescription];
+ NSSize displayPixelSize = [[description objectForKey:NSDeviceSize] sizeValue];
+ CGSize displayPhysicalSize = CGDisplayScreenSize(
+ [[description objectForKey:@"NSScreenNumber"] unsignedIntValue]);
- ERR_FAIL_INDEX_V(p_screen, screens.size(), 72);
- return screen_dpi[p_screen];
+ return (displayPixelSize.width * 25.4f / displayPhysicalSize.width) * displayScale;
+ }
+
+ return 72;
}
Size2 OS_OSX::get_screen_size(int p_screen) const {
+ NSArray *screenArray = [NSScreen screens];
+ if (p_screen < [screenArray count]) {
+ float displayScale = 1.0;
- ERR_FAIL_INDEX_V(p_screen, screens.size(), Point2());
- return screens[p_screen].size;
-};
+ if (display_scale > 1.0 && [[screenArray objectAtIndex:p_screen] respondsToSelector:@selector(backingScaleFactor)]) {
+ displayScale = [[screenArray objectAtIndex:p_screen] backingScaleFactor];
+ }
+
+ // Note: Use frame to get the whole screen size
+ NSRect nsrect = [[screenArray objectAtIndex:p_screen] frame];
+ return Size2(nsrect.size.width, nsrect.size.height) * displayScale;
+ }
+
+ return Size2();
+}
+
+void OS_OSX::_update_window() {
+ bool borderless_full = false;
+
+ if (get_borderless_window()) {
+ NSRect frameRect = [window_object frame];
+ NSRect screenRect = [[window_object screen] frame];
+
+ // Check if our window covers up the screen
+ if (frameRect.origin.x <= screenRect.origin.x && frameRect.origin.y <= frameRect.origin.y &&
+ frameRect.size.width >= screenRect.size.width && frameRect.size.height >= screenRect.size.height) {
+ borderless_full = true;
+ }
+ }
+
+ if (borderless_full) {
+ // If the window covers up the screen set the level to above the main menu and hide on deactivate
+ [window_object setLevel:NSMainMenuWindowLevel + 1];
+ [window_object setHidesOnDeactivate:YES];
+ } else {
+ // Reset these when our window is not a borderless window that covers up the screen
+ [window_object setLevel:NSNormalWindowLevel];
+ [window_object setHidesOnDeactivate:NO];
+ }
+}
Point2 OS_OSX::get_window_position() const {
Size2 wp([window_object frame].origin.x, [window_object frame].origin.y);
- wp*=display_scale;
+ wp *= display_scale;
return wp;
};
+void OS_OSX::set_window_position(const Point2 &p_position) {
-void OS_OSX::set_window_position(const Point2& p_position) {
-
- Point2 size=p_position;
- size/=display_scale;
+ Point2 size = p_position;
+ size /= display_scale;
[window_object setFrame:NSMakeRect(size.x, size.y, [window_object frame].size.width, [window_object frame].size.height) display:YES];
+
+ _update_window();
};
Size2 OS_OSX::get_window_size() const {
return window_size;
-
};
void OS_OSX::set_window_size(const Size2 p_size) {
- Size2 size=p_size;
+ Size2 size = p_size;
- // NSRect used by setFrame includes the title bar, so add it to our size.y
- CGFloat menuBarHeight = [[[NSApplication sharedApplication] mainMenu] menuBarHeight];
- if (menuBarHeight != 0.f) {
- size.y+= menuBarHeight;
+ if (get_borderless_window() == false) {
+ // NSRect used by setFrame includes the title bar, so add it to our size.y
+ CGFloat menuBarHeight = [[[NSApplication sharedApplication] mainMenu] menuBarHeight];
+ if (menuBarHeight != 0.f) {
+ size.y += menuBarHeight;
#if MAC_OS_X_VERSION_MAX_ALLOWED <= 101104
- } else {
- size.y+= [[NSStatusBar systemStatusBar] thickness];
+ } else {
+ size.y += [[NSStatusBar systemStatusBar] thickness];
#endif
+ }
}
+
NSRect frame = [window_object frame];
[window_object setFrame:NSMakeRect(frame.origin.x, frame.origin.y, size.x, size.y) display:YES];
+
+ _update_window();
};
void OS_OSX::set_window_fullscreen(bool p_enabled) {
@@ -1513,7 +1563,7 @@ void OS_OSX::set_window_fullscreen(bool p_enabled) {
bool OS_OSX::is_window_fullscreen() const {
#if MAC_OS_X_VERSION_MAX_ALLOWED < 1070
- if ( [window_object respondsToSelector:@selector(isZoomed)] )
+ if ([window_object respondsToSelector:@selector(isZoomed)])
return [window_object isZoomed];
#endif /*MAC_OS_X_VERSION_MAX_ALLOWED*/
@@ -1523,9 +1573,9 @@ bool OS_OSX::is_window_fullscreen() const {
void OS_OSX::set_window_resizable(bool p_enabled) {
if (p_enabled)
- [window_object setStyleMask:[window_object styleMask] | NSResizableWindowMask ];
+ [window_object setStyleMask:[window_object styleMask] | NSResizableWindowMask];
else
- [window_object setStyleMask:[window_object styleMask] & ~NSResizableWindowMask ];
+ [window_object setStyleMask:[window_object styleMask] & ~NSResizableWindowMask];
};
bool OS_OSX::is_window_resizable() const {
@@ -1543,21 +1593,20 @@ void OS_OSX::set_window_minimized(bool p_enabled) {
bool OS_OSX::is_window_minimized() const {
- if ( [window_object respondsToSelector:@selector(isMiniaturized)])
+ if ([window_object respondsToSelector:@selector(isMiniaturized)])
return [window_object isMiniaturized];
return minimized;
};
-
void OS_OSX::set_window_maximized(bool p_enabled) {
if (p_enabled) {
restore_rect = Rect2(get_window_position(), get_window_size());
- [window_object setFrame:[[[NSScreen screens] objectAtIndex:current_screen] visibleFrame] display:YES];
+ [window_object setFrame:[[[NSScreen screens] objectAtIndex:get_current_screen()] visibleFrame] display:YES];
} else {
set_window_size(restore_rect.size);
- set_window_position(restore_rect.pos);
+ set_window_position(restore_rect.position);
};
maximized = p_enabled;
};
@@ -1568,7 +1617,6 @@ bool OS_OSX::is_window_maximized() const {
return maximized;
};
-
void OS_OSX::move_window_to_foreground() {
[window_object orderFrontRegardless];
@@ -1579,6 +1627,35 @@ void OS_OSX::request_attention() {
[NSApp requestUserAttention:NSCriticalRequest];
}
+void OS_OSX::set_borderless_window(int p_borderless) {
+
+ // OrderOut prevents a lose focus bug with the window
+ [window_object orderOut:nil];
+
+ if (p_borderless) {
+ [window_object setStyleMask:NSWindowStyleMaskBorderless];
+ } else {
+ [window_object setStyleMask:NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | NSResizableWindowMask];
+
+ // Force update of the window styles
+ NSRect frameRect = [window_object frame];
+ [window_object setFrame:NSMakeRect(frameRect.origin.x, frameRect.origin.y, frameRect.size.width + 1, frameRect.size.height) display:NO];
+ [window_object setFrame:frameRect display:NO];
+
+ // Restore the window title
+ [window_object setTitle:[NSString stringWithUTF8String:title.utf8().get_data()]];
+ }
+
+ _update_window();
+
+ [window_object makeKeyAndOrderFront:nil];
+}
+
+bool OS_OSX::get_borderless_window() {
+
+ return [window_object styleMask] == NSWindowStyleMaskBorderless;
+}
+
String OS_OSX::get_executable_path() const {
int ret;
@@ -1586,8 +1663,8 @@ String OS_OSX::get_executable_path() const {
char pathbuf[PROC_PIDPATHINFO_MAXSIZE];
pid = getpid();
- ret = proc_pidpath (pid, pathbuf, sizeof(pathbuf));
- if ( ret <= 0 ) {
+ ret = proc_pidpath(pid, pathbuf, sizeof(pathbuf));
+ if (ret <= 0) {
return OS::get_executable_path();
} else {
String path;
@@ -1595,7 +1672,6 @@ String OS_OSX::get_executable_path() const {
return path;
}
-
}
// Returns string representation of keys, if they are printable.
@@ -1615,22 +1691,22 @@ static NSString *createStringForKeys(const CGKeyCode *keyCode, int length) {
OSStatus err;
CFMutableStringRef output = CFStringCreateMutable(NULL, 0);
- for (int i=0; i<length; ++i) {
+ for (int i = 0; i < length; ++i) {
UInt32 keysDown = 0;
UniChar chars[4];
UniCharCount realLength;
err = UCKeyTranslate(keyboardLayout,
- keyCode[i],
- kUCKeyActionDisplay,
- 0,
- LMGetKbdType(),
- kUCKeyTranslateNoDeadKeysBit,
- &keysDown,
- sizeof(chars) / sizeof(chars[0]),
- &realLength,
- chars);
+ keyCode[i],
+ kUCKeyActionDisplay,
+ 0,
+ LMGetKbdType(),
+ kUCKeyTranslateNoDeadKeysBit,
+ &keysDown,
+ sizeof(chars) / sizeof(chars[0]),
+ &realLength,
+ chars);
if (err != noErr) {
CFRelease(output);
@@ -1644,6 +1720,7 @@ static NSString *createStringForKeys(const CGKeyCode *keyCode, int length) {
return (NSString *)output;
}
+
OS::LatinKeyboardVariant OS_OSX::get_latin_keyboard_variant() const {
static LatinKeyboardVariant layout = LATIN_KEYBOARD_QWERTY;
@@ -1652,7 +1729,7 @@ OS::LatinKeyboardVariant OS_OSX::get_latin_keyboard_variant() const {
layout = LATIN_KEYBOARD_QWERTY;
- CGKeyCode keys[] = {kVK_ANSI_Q, kVK_ANSI_W, kVK_ANSI_E, kVK_ANSI_R, kVK_ANSI_T, kVK_ANSI_Y};
+ CGKeyCode keys[] = { kVK_ANSI_Q, kVK_ANSI_W, kVK_ANSI_E, kVK_ANSI_R, kVK_ANSI_T, kVK_ANSI_Y };
NSString *test = createStringForKeys(keys, 6);
if ([test isEqualToString:@"qwertz"]) {
@@ -1679,10 +1756,12 @@ OS::LatinKeyboardVariant OS_OSX::get_latin_keyboard_variant() const {
void OS_OSX::process_events() {
while (true) {
- NSEvent* event = [NSApp nextEventMatchingMask:NSAnyEventMask
- untilDate:[NSDate distantPast]
- inMode:NSDefaultRunLoopMode
- dequeue:YES];
+ NSEvent *event = [NSApp
+ nextEventMatchingMask:NSAnyEventMask
+ untilDate:[NSDate distantPast]
+ inMode:NSDefaultRunLoopMode
+ dequeue:YES];
+
if (event == nil)
break;
@@ -1693,13 +1772,9 @@ void OS_OSX::process_events() {
autoreleasePool = [[NSAutoreleasePool alloc] init];
}
+void OS_OSX::push_input(const Ref<InputEvent> &p_event) {
-
-void OS_OSX::push_input(const InputEvent& p_event) {
-
- InputEvent ev=p_event;
- ev.ID=last_id++;
- //print_line("EV: "+String(ev));
+ Ref<InputEvent> ev = p_event;
input->parse_input_event(ev);
}
@@ -1725,8 +1800,8 @@ void OS_OSX::run() {
while (!force_quit) {
process_events(); // get rid of pending events
- last_id = joypad_osx->process_joypads(last_id);
- if (Main::iteration()==true)
+ joypad_osx->process_joypads();
+ if (Main::iteration() == true)
break;
};
@@ -1735,32 +1810,31 @@ void OS_OSX::run() {
void OS_OSX::set_mouse_mode(MouseMode p_mode) {
- if (p_mode==mouse_mode)
- return;
+ if (p_mode == mouse_mode)
+ return;
- if (p_mode==MOUSE_MODE_CAPTURED) {
- // Apple Docs state that the display parameter is not used.
- // "This parameter is not used. By default, you may pass kCGDirectMainDisplay."
- // https://developer.apple.com/library/mac/documentation/graphicsimaging/reference/Quartz_Services_Ref/Reference/reference.html
- CGDisplayHideCursor(kCGDirectMainDisplay);
- CGAssociateMouseAndMouseCursorPosition(false);
- } else if (p_mode==MOUSE_MODE_HIDDEN) {
- CGDisplayHideCursor(kCGDirectMainDisplay);
- CGAssociateMouseAndMouseCursorPosition(true);
- } else {
- CGDisplayShowCursor(kCGDirectMainDisplay);
- CGAssociateMouseAndMouseCursorPosition(true);
- }
+ if (p_mode == MOUSE_MODE_CAPTURED) {
+ // Apple Docs state that the display parameter is not used.
+ // "This parameter is not used. By default, you may pass kCGDirectMainDisplay."
+ // https://developer.apple.com/library/mac/documentation/graphicsimaging/reference/Quartz_Services_Ref/Reference/reference.html
+ CGDisplayHideCursor(kCGDirectMainDisplay);
+ CGAssociateMouseAndMouseCursorPosition(false);
+ } else if (p_mode == MOUSE_MODE_HIDDEN) {
+ CGDisplayHideCursor(kCGDirectMainDisplay);
+ CGAssociateMouseAndMouseCursorPosition(true);
+ } else {
+ CGDisplayShowCursor(kCGDirectMainDisplay);
+ CGAssociateMouseAndMouseCursorPosition(true);
+ }
- mouse_mode=p_mode;
+ mouse_mode = p_mode;
}
OS::MouseMode OS_OSX::get_mouse_mode() const {
- return mouse_mode;
+ return mouse_mode;
}
-
String OS_OSX::get_joy_guid(int p_device) const {
return input->get_joy_guid_remapped(p_device);
}
@@ -1777,13 +1851,16 @@ int OS_OSX::get_power_percent_left() {
return power_manager->get_power_percent_left();
}
-OS_OSX* OS_OSX::singleton=NULL;
+OS_OSX *OS_OSX::singleton = NULL;
OS_OSX::OS_OSX() {
-
- mouse_mode=OS::MOUSE_MODE_VISIBLE;
- main_loop=NULL;
- singleton=this;
+
+ mouse_mode = OS::MOUSE_MODE_VISIBLE;
+ main_loop = NULL;
+ singleton = this;
+ im_position = Point2();
+ im_callback = NULL;
+ im_target = NULL;
autoreleasePool = [[NSAutoreleasePool alloc] init];
eventSource = CGEventSourceCreate(kCGEventSourceStateHIDSystemState);
@@ -1791,13 +1868,12 @@ OS_OSX::OS_OSX() {
CGEventSourceSetLocalEventsSuppressionInterval(eventSource, 0.0);
-
- /*if (pthread_key_create(&_Godot.nsgl.current, NULL) != 0)
- {
- _GodotInputError(Godot_PLATFORM_ERROR,
- "NSGL: Failed to create context TLS");
- return GL_FALSE;
- }*/
+ /*
+ if (pthread_key_create(&_Godot.nsgl.current, NULL) != 0) {
+ _GodotInputError(Godot_PLATFORM_ERROR, "NSGL: Failed to create context TLS");
+ return GL_FALSE;
+ }
+*/
framework = CFBundleGetBundleWithIdentifier(CFSTR("com.apple.opengl"));
ERR_FAIL_COND(!framework);
@@ -1808,12 +1884,52 @@ OS_OSX::OS_OSX() {
// In case we are unbundled, make us a proper UI application
[NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
- #if 0
// Menu bar setup must go between sharedApplication above and
// finishLaunching below, in order to properly emulate the behavior
// of NSApplicationMain
- createMenuBar();
- #endif
+ NSMenuItem *menu_item;
+ NSString *title;
+
+ NSString *nsappname = [[[NSBundle mainBundle] performSelector:@selector(localizedInfoDictionary)] objectForKey:@"CFBundleName"];
+ if (nsappname == nil)
+ nsappname = [[NSProcessInfo processInfo] processName];
+
+ // Setup Apple menu
+ NSMenu *apple_menu = [[NSMenu alloc] initWithTitle:@""];
+ title = [NSString stringWithFormat:NSLocalizedString(@"About %@", nil), nsappname];
+ [apple_menu addItemWithTitle:title action:@selector(orderFrontStandardAboutPanel:) keyEquivalent:@""];
+
+ [apple_menu addItem:[NSMenuItem separatorItem]];
+
+ NSMenu *services = [[NSMenu alloc] initWithTitle:@""];
+ menu_item = [apple_menu addItemWithTitle:NSLocalizedString(@"Services", nil) action:nil keyEquivalent:@""];
+ [apple_menu setSubmenu:services forItem:menu_item];
+ [NSApp setServicesMenu:services];
+ [services release];
+
+ [apple_menu addItem:[NSMenuItem separatorItem]];
+
+ title = [NSString stringWithFormat:NSLocalizedString(@"Hide %@", nil), nsappname];
+ [apple_menu addItemWithTitle:title action:@selector(hide:) keyEquivalent:@"h"];
+
+ menu_item = [apple_menu addItemWithTitle:NSLocalizedString(@"Hide Others", nil) action:@selector(hideOtherApplications:) keyEquivalent:@"h"];
+ [menu_item setKeyEquivalentModifierMask:(NSAlternateKeyMask | NSCommandKeyMask)];
+
+ [apple_menu addItemWithTitle:NSLocalizedString(@"Show all", nil) action:@selector(unhideAllApplications:) keyEquivalent:@""];
+
+ [apple_menu addItem:[NSMenuItem separatorItem]];
+
+ title = [NSString stringWithFormat:NSLocalizedString(@"Quit %@", nil), nsappname];
+ [apple_menu addItemWithTitle:title action:@selector(terminate:) keyEquivalent:@"q"];
+
+ // Setup menu bar
+ NSMenu *main_menu = [[NSMenu alloc] initWithTitle:@""];
+ menu_item = [main_menu addItemWithTitle:@"" action:nil keyEquivalent:@""];
+ [main_menu setSubmenu:apple_menu forItem:menu_item];
+ [NSApp setMainMenu:main_menu];
+
+ [main_menu release];
+ [apple_menu release];
[NSApp finishLaunching];
@@ -1821,15 +1937,15 @@ OS_OSX::OS_OSX() {
ERR_FAIL_COND(!delegate);
[NSApp setDelegate:delegate];
-
- last_id=1;
- cursor_shape=CURSOR_ARROW;
-
- current_screen = 0;
+ cursor_shape = CURSOR_ARROW;
maximized = false;
minimized = false;
- window_size=Vector2(1024,600);
+ window_size = Vector2(1024, 600);
zoomed = false;
- display_scale=1.0;
+ display_scale = 1.0;
+}
+
+bool OS_OSX::_check_internal_feature_support(const String &p_feature) {
+ return p_feature == "pc" || p_feature == "s3tc";
}
diff --git a/platform/osx/platform_config.h b/platform/osx/platform_config.h
index 834d0141a3..487077e651 100644
--- a/platform/osx/platform_config.h
+++ b/platform/osx/platform_config.h
@@ -6,6 +6,7 @@
/* http://www.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 */
diff --git a/platform/osx/power_osx.cpp b/platform/osx/power_osx.cpp
index de9bcaf6fc..2ef1a65ff1 100644
--- a/platform/osx/power_osx.cpp
+++ b/platform/osx/power_osx.cpp
@@ -6,6 +6,7 @@
/* http://www.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 */
@@ -26,6 +27,32 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+
+/*
+Adapted from corresponding SDL 2.0 code.
+*/
+
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
#include "power_osx.h"
#include <CoreFoundation/CoreFoundation.h>
diff --git a/platform/osx/power_osx.h b/platform/osx/power_osx.h
index c638dc675a..6d984ec466 100644
--- a/platform/osx/power_osx.h
+++ b/platform/osx/power_osx.h
@@ -6,6 +6,7 @@
/* http://www.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 */
diff --git a/platform/osx/sem_osx.cpp b/platform/osx/sem_osx.cpp
index 069e3a5153..b1eeccfec5 100644
--- a/platform/osx/sem_osx.cpp
+++ b/platform/osx/sem_osx.cpp
@@ -6,6 +6,7 @@
/* http://www.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 */
diff --git a/platform/osx/sem_osx.h b/platform/osx/sem_osx.h
index a30f3fcc98..3025318c4b 100644
--- a/platform/osx/sem_osx.h
+++ b/platform/osx/sem_osx.h
@@ -6,6 +6,7 @@
/* http://www.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 */
diff --git a/platform/server/detect.py b/platform/server/detect.py
index 8bc85f342d..2bb4b59e94 100644
--- a/platform/server/detect.py
+++ b/platform/server/detect.py
@@ -1,4 +1,3 @@
-
import os
import sys
@@ -13,17 +12,16 @@ def get_name():
def can_build():
- if (os.name != "posix"):
+ if (os.name != "posix" or sys.platform == "darwin"):
return False
- return True # enabled
+ return True
def get_opts():
return [
- ('use_llvm', 'Use llvm compiler', 'no'),
- ('force_32_bits', 'Force 32 bits binary', 'no')
+ ('use_llvm', 'Use the LLVM compiler', 'no'),
]
@@ -35,46 +33,59 @@ def get_flags():
def configure(env):
- env.Append(CPPPATH=['#platform/server'])
- if (env["use_llvm"] == "yes"):
- env["CC"] = "clang"
- env["CXX"] = "clang++"
- env["LD"] = "clang++"
-
- is64 = sys.maxsize > 2**32
-
- if (env["bits"] == "default"):
- if (is64):
- env["bits"] = "64"
- else:
- env["bits"] = "32"
-
- # if (env["tools"]=="no"):
- # #no tools suffix
- # env['OBJSUFFIX'] = ".nt"+env['OBJSUFFIX']
- # env['LIBSUFFIX'] = ".nt"+env['LIBSUFFIX']
+ ## Build type
if (env["target"] == "release"):
-
env.Append(CCFLAGS=['-O2', '-ffast-math', '-fomit-frame-pointer'])
elif (env["target"] == "release_debug"):
-
env.Append(CCFLAGS=['-O2', '-ffast-math', '-DDEBUG_ENABLED'])
elif (env["target"] == "debug"):
+ env.Append(CCFLAGS=['-g2', '-DDEBUG_ENABLED', '-DDEBUG_MEMORY_ENABLED'])
+
+ ## Architecture
- env.Append(CCFLAGS=['-g2', '-Wall', '-DDEBUG_ENABLED', '-DDEBUG_MEMORY_ENABLED'])
+ is64 = sys.maxsize > 2**32
+ if (env["bits"] == "default"):
+ env["bits"] = "64" if is64 else "32"
+
+ ## Compiler configuration
+
+ if (env["use_llvm"] == "yes"):
+ if ('clang++' not in env['CXX']):
+ env["CC"] = "clang"
+ env["CXX"] = "clang++"
+ env["LD"] = "clang++"
+ env.Append(CPPFLAGS=['-DTYPED_METHOD_BIND'])
+ env.extra_suffix = ".llvm" + env.extra_suffix
+ ## Dependencies
- # Shared libraries, when requested
+ # FIXME: Check for existence of the libs before parsing their flags with pkg-config
if (env['builtin_openssl'] == 'no'):
+ # Currently not compatible with OpenSSL 1.1.0+
+ # https://github.com/godotengine/godot/issues/8624
+ import subprocess
+ openssl_version = subprocess.check_output(['pkg-config', 'openssl', '--modversion']).strip('\n')
+ if (openssl_version >= "1.1.0"):
+ print("Error: Found system-installed OpenSSL %s, currently only supporting version 1.0.x." % openssl_version)
+ print("Aborting.. You can compile with 'builtin_openssl=yes' to use the bundled version.\n")
+ sys.exit(255)
+
env.ParseConfig('pkg-config openssl --cflags --libs')
if (env['builtin_libwebp'] == 'no'):
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'] == 'yes' or env['builtin_libpng'] == 'yes' or env['builtin_zlib'] == 'yes'):
+ env['builtin_freetype'] = 'yes'
+ env['builtin_libpng'] = 'yes'
+ env['builtin_zlib'] = 'yes'
+
if (env['builtin_freetype'] == 'no'):
env.ParseConfig('pkg-config freetype2 --cflags --libs')
@@ -109,11 +120,12 @@ def configure(env):
if (env['builtin_libogg'] == 'no'):
env.ParseConfig('pkg-config ogg --cflags --libs')
+ ## Flags
- env.Append(CPPFLAGS=['-DSERVER_ENABLED', '-DUNIX_ENABLED'])
- env.Append(LIBS=['pthread', 'z']) # TODO detect linux/BSD!
+ # Linkflags below this line should typically stay the last ones
+ if (env['builtin_zlib'] == 'no'):
+ env.ParseConfig('pkg-config zlib --cflags --libs')
- if (env["CXX"] == "clang++"):
- env.Append(CPPFLAGS=['-DTYPED_METHOD_BIND'])
- env["CC"] = "clang"
- env["LD"] = "clang++"
+ env.Append(CPPPATH=['#platform/server'])
+ env.Append(CPPFLAGS=['-DSERVER_ENABLED', '-DUNIX_ENABLED'])
+ env.Append(LIBS=['pthread'])
diff --git a/platform/server/godot_server.cpp b/platform/server/godot_server.cpp
index d06ade4a57..ed0100ac93 100644
--- a/platform/server/godot_server.cpp
+++ b/platform/server/godot_server.cpp
@@ -6,6 +6,7 @@
/* http://www.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 */
diff --git a/platform/server/os_server.cpp b/platform/server/os_server.cpp
index f44d976bd6..89af785d29 100644
--- a/platform/server/os_server.cpp
+++ b/platform/server/os_server.cpp
@@ -6,6 +6,7 @@
/* http://www.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 */
@@ -142,7 +143,7 @@ int OS_Server::get_mouse_button_state() const {
return 0;
}
-Point2 OS_Server::get_mouse_pos() const {
+Point2 OS_Server::get_mouse_position() const {
return Point2();
}
diff --git a/platform/server/os_server.h b/platform/server/os_server.h
index 7484d70e06..7c29b1e232 100644
--- a/platform/server/os_server.h
+++ b/platform/server/os_server.h
@@ -6,6 +6,7 @@
/* http://www.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 */
@@ -87,7 +88,7 @@ public:
virtual void set_mouse_show(bool p_show);
virtual void set_mouse_grab(bool p_grab);
virtual bool is_mouse_grab_enabled() const;
- virtual Point2 get_mouse_pos() const;
+ virtual Point2 get_mouse_position() const;
virtual int get_mouse_button_state() const;
virtual void set_window_title(const String &p_title);
diff --git a/platform/server/platform_config.h b/platform/server/platform_config.h
index cdef185ff0..48bcadcc29 100644
--- a/platform/server/platform_config.h
+++ b/platform/server/platform_config.h
@@ -6,6 +6,7 @@
/* http://www.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 */
diff --git a/platform/uwp/SCsub b/platform/uwp/SCsub
index 0167ea9e02..7ee5aa2ac3 100644
--- a/platform/uwp/SCsub
+++ b/platform/uwp/SCsub
@@ -9,6 +9,7 @@ files = [
'#platform/windows/stream_peer_winsock.cpp',
'#platform/windows/key_mapping_win.cpp',
'joypad_uwp.cpp',
+ 'power_uwp.cpp',
'gl_context_egl.cpp',
'app.cpp',
'os_uwp.cpp',
diff --git a/platform/uwp/app.cpp b/platform/uwp/app.cpp
index 35b25b1de5..c773c0b746 100644
--- a/platform/uwp/app.cpp
+++ b/platform/uwp/app.cpp
@@ -6,6 +6,7 @@
/* http://www.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 */
@@ -258,45 +259,48 @@ void App::pointer_event(Windows::UI::Core::CoreWindow ^ sender, Windows::UI::Cor
int but = _get_button(point);
if (_is_touch(point)) {
- InputEvent event;
- event.type = InputEvent::SCREEN_TOUCH;
- event.device = 0;
- event.screen_touch.pressed = p_pressed;
- event.screen_touch.x = pos.X;
- event.screen_touch.y = pos.Y;
- event.screen_touch.index = _get_finger(point->PointerId);
+ Ref<InputEventScreenTouch> screen_touch;
+ screen_touch.instance();
+ screen_touch->set_device(0);
+ screen_touch->set_pressed(p_pressed);
+ screen_touch->set_position(Vector2(pos.X, pos.Y));
+ screen_touch->set_index(_get_finger(point->PointerId));
- last_touch_x[event.screen_touch.index] = pos.X;
- last_touch_y[event.screen_touch.index] = pos.Y;
+ last_touch_x[screen_touch->get_index()] = pos.X;
+ last_touch_y[screen_touch->get_index()] = pos.Y;
- os->input_event(event);
+ os->input_event(screen_touch);
if (number_of_contacts > 1)
return;
}; // fallthrought of sorts
- InputEvent event;
- event.type = InputEvent::MOUSE_BUTTON;
- event.device = 0;
- event.mouse_button.pressed = p_pressed;
- event.mouse_button.button_index = but;
- event.mouse_button.x = pos.X;
- event.mouse_button.y = pos.Y;
- event.mouse_button.global_x = pos.X;
- event.mouse_button.global_y = pos.Y;
+ Ref<InputEventMouseButton> mouse_button;
+ mouse_button.instance();
+ mouse_button->set_device(0);
+ mouse_button->set_pressed(p_pressed);
+ mouse_button->set_button_index(but);
+ mouse_button->set_position(Vector2(pos.X, pos.Y));
+ mouse_button->set_global_position(Vector2(pos.X, pos.Y));
if (p_is_wheel) {
if (point->Properties->MouseWheelDelta > 0) {
- event.mouse_button.button_index = point->Properties->IsHorizontalMouseWheel ? BUTTON_WHEEL_RIGHT : BUTTON_WHEEL_UP;
+ mouse_button->set_button_index(point->Properties->IsHorizontalMouseWheel ? BUTTON_WHEEL_RIGHT : BUTTON_WHEEL_UP);
} else if (point->Properties->MouseWheelDelta < 0) {
- event.mouse_button.button_index = point->Properties->IsHorizontalMouseWheel ? BUTTON_WHEEL_LEFT : BUTTON_WHEEL_DOWN;
+ mouse_button->set_button_index(point->Properties->IsHorizontalMouseWheel ? BUTTON_WHEEL_LEFT : BUTTON_WHEEL_DOWN);
}
}
last_touch_x[31] = pos.X;
last_touch_y[31] = pos.Y;
- os->input_event(event);
+ os->input_event(mouse_button);
+
+ if (p_is_wheel) {
+ // Send release for mouse wheel
+ mouse_button->set_pressed(false);
+ os->input_event(mouse_button);
+ }
};
void App::OnPointerPressed(Windows::UI::Core::CoreWindow ^ sender, Windows::UI::Core::PointerEventArgs ^ args) {
@@ -348,16 +352,14 @@ void App::OnPointerMoved(Windows::UI::Core::CoreWindow ^ sender, Windows::UI::Co
if (point->IsInContact && _is_touch(point)) {
- InputEvent event;
- event.type = InputEvent::SCREEN_DRAG;
- event.device = 0;
- event.screen_drag.x = pos.X;
- event.screen_drag.y = pos.Y;
- event.screen_drag.index = _get_finger(point->PointerId);
- event.screen_drag.relative_x = event.screen_drag.x - last_touch_x[event.screen_drag.index];
- event.screen_drag.relative_y = event.screen_drag.y - last_touch_y[event.screen_drag.index];
+ Ref<InputEventScreenDrag> screen_drag;
+ screen_drag.instance();
+ screen_drag->set_device(0);
+ screen_drag->set_position(Vector2(pos.X, pos.Y));
+ screen_drag->set_index(_get_finger(point->PointerId));
+ screen_drag->set_relative(Vector2(screen_drag->get_position().x - last_touch_x[screen_drag->get_index()], screen_drag->get_position().y - last_touch_y[screen_drag->get_index()]));
- os->input_event(event);
+ os->input_event(screen_drag);
if (number_of_contacts > 1)
return;
@@ -367,19 +369,16 @@ void App::OnPointerMoved(Windows::UI::Core::CoreWindow ^ sender, Windows::UI::Co
if (os->get_mouse_mode() == OS::MouseMode::MOUSE_MODE_CAPTURED)
return;
- InputEvent event;
- event.type = InputEvent::MOUSE_MOTION;
- event.device = 0;
- event.mouse_motion.x = pos.X;
- event.mouse_motion.y = pos.Y;
- event.mouse_motion.global_x = pos.X;
- event.mouse_motion.global_y = pos.Y;
- event.mouse_motion.relative_x = pos.X - last_touch_x[31];
- event.mouse_motion.relative_y = pos.Y - last_touch_y[31];
+ Ref<InputEventMouseMotion> mouse_motion;
+ mouse_motion.instance();
+ mouse_motion->set_device(0);
+ mouse_motion->set_position(Vector2(pos.X, pos.Y));
+ mouse_motion->set_global_position(Vector2(pos.X, pos.Y));
+ mouse_motion->set_relative(Vector2(pos.X - last_touch_x[31], pos.Y - last_touch_y[31]));
last_mouse_pos = pos;
- os->input_event(event);
+ os->input_event(mouse_motion);
}
void App::OnMouseMoved(MouseDevice ^ mouse_device, MouseEventArgs ^ args) {
@@ -392,32 +391,25 @@ void App::OnMouseMoved(MouseDevice ^ mouse_device, MouseEventArgs ^ args) {
pos.X = last_mouse_pos.X + args->MouseDelta.X;
pos.Y = last_mouse_pos.Y + args->MouseDelta.Y;
- InputEvent event;
- event.type = InputEvent::MOUSE_MOTION;
- event.device = 0;
- event.mouse_motion.x = pos.X;
- event.mouse_motion.y = pos.Y;
- event.mouse_motion.global_x = pos.X;
- event.mouse_motion.global_y = pos.Y;
- event.mouse_motion.relative_x = args->MouseDelta.X;
- event.mouse_motion.relative_y = args->MouseDelta.Y;
+ Ref<InputEventMouseMotion> mouse_motion;
+ mouse_motion.instance();
+ mouse_motion->set_device(0);
+ mouse_motion->set_position(Vector2(pos.X, pos.Y));
+ mouse_motion->set_global_position(Vector2(pos.X, pos.Y));
+ mouse_motion->set_relative(Vector2(args->MouseDelta.X, args->MouseDelta.Y));
last_mouse_pos = pos;
- os->input_event(event);
+ os->input_event(mouse_motion);
}
void App::key_event(Windows::UI::Core::CoreWindow ^ sender, bool p_pressed, Windows::UI::Core::KeyEventArgs ^ key_args, Windows::UI::Core::CharacterReceivedEventArgs ^ char_args) {
OSUWP::KeyEvent ke;
- InputModifierState mod;
- mod.meta = false;
- mod.command = false;
- mod.control = sender->GetAsyncKeyState(VirtualKey::Control) == CoreVirtualKeyStates::Down;
- mod.alt = sender->GetAsyncKeyState(VirtualKey::Menu) == CoreVirtualKeyStates::Down;
- mod.shift = sender->GetAsyncKeyState(VirtualKey::Shift) == CoreVirtualKeyStates::Down;
- ke.mod_state = mod;
+ ke.control = sender->GetAsyncKeyState(VirtualKey::Control) == CoreVirtualKeyStates::Down;
+ ke.alt = sender->GetAsyncKeyState(VirtualKey::Menu) == CoreVirtualKeyStates::Down;
+ ke.shift = sender->GetAsyncKeyState(VirtualKey::Shift) == CoreVirtualKeyStates::Down;
ke.pressed = p_pressed;
diff --git a/platform/uwp/app.h b/platform/uwp/app.h
index fd6fc950a7..9cbe7669c9 100644
--- a/platform/uwp/app.h
+++ b/platform/uwp/app.h
@@ -6,6 +6,7 @@
/* http://www.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 */
@@ -106,7 +107,7 @@ namespace GodotUWP
int last_touch_y[32];
int number_of_contacts;
Windows::Foundation::Point last_mouse_pos;
- }
+ };
}
/* clang-format on */
diff --git a/platform/uwp/detect.py b/platform/uwp/detect.py
index f1e0716241..64dac93f1f 100644
--- a/platform/uwp/detect.py
+++ b/platform/uwp/detect.py
@@ -1,8 +1,7 @@
+import methods
import os
-
-import sys
import string
-import methods
+import sys
def is_active():
@@ -26,7 +25,9 @@ def can_build():
def get_opts():
- return []
+
+ return [
+ ]
def get_flags():
@@ -39,15 +40,37 @@ def get_flags():
def configure(env):
- if(env["bits"] != "default"):
- print "Error: bits argument is disabled for MSVC"
- print ("Bits argument is not supported for MSVC compilation. Architecture depends on the Native/Cross Compile Tools Prompt/Developer Console (or Visual Studio settings)"
- + " that is being used to run SCons. As a consequence, bits argument is disabled. Run scons again without bits argument (example: scons p=uwp) and SCons will attempt to detect what MSVC compiler"
- + " will be executed and inform you.")
+ if (env["bits"] != "default"):
+ print("Error: bits argument is disabled for MSVC")
+ print("""
+ Bits argument is not supported for MSVC compilation. Architecture depends on the Native/Cross Compile Tools Prompt/Developer Console
+ (or Visual Studio settings) that is being used to run SCons. As a consequence, bits argument is disabled. Run scons again without bits
+ argument (example: scons p=uwp) and SCons will attempt to detect what MSVC compiler will be executed and inform you.
+ """)
sys.exit()
- arch = ""
+ ## Build type
+
+ if (env["target"] == "release"):
+ env.Append(CPPFLAGS=['/O2', '/GL'])
+ env.Append(CPPFLAGS=['/MD'])
+ env.Append(LINKFLAGS=['/SUBSYSTEM:WINDOWS', '/LTCG'])
+
+ elif (env["target"] == "release_debug"):
+ env.Append(CCFLAGS=['/O2', '/Zi', '/DDEBUG_ENABLED'])
+ env.Append(CPPFLAGS=['/MD'])
+ env.Append(LINKFLAGS=['/SUBSYSTEM:CONSOLE'])
+
+ elif (env["target"] == "debug"):
+ env.Append(CCFLAGS=['/Zi', '/DDEBUG_ENABLED', '/DDEBUG_MEMORY_ENABLED'])
+ env.Append(CPPFLAGS=['/MDd'])
+ env.Append(LINKFLAGS=['/SUBSYSTEM:CONSOLE'])
+ env.Append(LINKFLAGS=['/DEBUG'])
+
+ ## Compiler configuration
+
env['ENV'] = os.environ
+ vc_base_path = os.environ['VCTOOLSINSTALLDIR'] if "VCTOOLSINSTALLDIR" in os.environ else os.environ['VCINSTALLDIR']
# ANGLE
angle_root = os.getenv("ANGLE_SRC_PATH")
@@ -58,31 +81,33 @@ def configure(env):
if os.path.isfile(str(os.getenv("ANGLE_SRC_PATH")) + "/winrt/10/src/angle.sln"):
env["build_angle"] = True
+ ## Architecture
+
+ arch = ""
if os.getenv('Platform') == "ARM":
- print "Compiled program architecture will be an ARM executable. (forcing bits=32)."
+ print("Compiled program architecture will be an ARM executable. (forcing bits=32).")
arch = "arm"
env["bits"] = "32"
env.Append(LINKFLAGS=['/MACHINE:ARM'])
- env.Append(LIBPATH=[os.environ['VCINSTALLDIR'] + 'lib/store/arm'])
+ env.Append(LIBPATH=[vc_base_path + 'lib/store/arm'])
angle_build_cmd += "ARM"
env.Append(LIBPATH=[angle_root + '/winrt/10/src/Release_ARM/lib'])
else:
-
compiler_version_str = methods.detect_visual_c_compiler_version(env['ENV'])
if(compiler_version_str == "amd64" or compiler_version_str == "x86_amd64"):
env["bits"] = "64"
- print "Compiled program architecture will be a x64 executable (forcing bits=64)."
+ print("Compiled program architecture will be a x64 executable (forcing bits=64).")
elif (compiler_version_str == "x86" or compiler_version_str == "amd64_x86"):
env["bits"] = "32"
- print "Compiled program architecture will be a x86 executable. (forcing bits=32)."
+ print("Compiled program architecture will be a x86 executable. (forcing bits=32).")
else:
- print "Failed to detect MSVC compiler architecture version... Defaulting to 32bit executable settings (forcing bits=32). Compilation attempt will continue, but SCons can not detect for what architecture this build is compiled for. You should check your settings/compilation setup."
+ print("Failed to detect MSVC compiler architecture version... Defaulting to 32bit executable settings (forcing bits=32). Compilation attempt will continue, but SCons can not detect for what architecture this build is compiled for. You should check your settings/compilation setup.")
env["bits"] = "32"
if (env["bits"] == "32"):
@@ -90,9 +115,8 @@ def configure(env):
angle_build_cmd += "Win32"
- env.Append(CPPFLAGS=['/DPNG_ABORT=abort'])
env.Append(LINKFLAGS=['/MACHINE:X86'])
- env.Append(LIBPATH=[os.environ['VCINSTALLDIR'] + 'lib/store'])
+ env.Append(LIBPATH=[vc_base_path + 'lib/store'])
env.Append(LIBPATH=[angle_root + '/winrt/10/src/Release_Win32/lib'])
else:
@@ -104,49 +128,30 @@ def configure(env):
env.Append(LIBPATH=[os.environ['VCINSTALLDIR'] + 'lib/store/amd64'])
env.Append(LIBPATH=[angle_root + '/winrt/10/src/Release_x64/lib'])
- env.Append(CPPPATH=['#platform/uwp', '#drivers/windows'])
- env.Append(LINKFLAGS=['/MANIFEST:NO', '/NXCOMPAT', '/DYNAMICBASE', '/WINMD', '/APPCONTAINER', '/ERRORREPORT:PROMPT', '/NOLOGO', '/TLBID:1', '/NODEFAULTLIB:"kernel32.lib"', '/NODEFAULTLIB:"ole32.lib"'])
- env.Append(CPPFLAGS=['/D', '__WRL_NO_DEFAULT_LIB__', '/D', 'WIN32'])
- env.Append(CPPFLAGS=['/FU', os.environ['VCINSTALLDIR'] + 'lib/store/references/platform.winmd'])
- env.Append(CPPFLAGS=['/AI', os.environ['VCINSTALLDIR'] + 'lib/store/references'])
-
- env.Append(LIBPATH=[os.environ['VCINSTALLDIR'] + 'lib/store/references'])
-
- if (env["target"] == "release"):
-
- env.Append(CPPFLAGS=['/O2', '/GL'])
- env.Append(CPPFLAGS=['/MD'])
- env.Append(LINKFLAGS=['/SUBSYSTEM:WINDOWS', '/LTCG'])
+ env["PROGSUFFIX"] = "." + arch + env["PROGSUFFIX"]
+ env["OBJSUFFIX"] = "." + arch + env["OBJSUFFIX"]
+ env["LIBSUFFIX"] = "." + arch + env["LIBSUFFIX"]
- elif (env["target"] == "release_debug"):
+ ## Compile flags
- env.Append(CCFLAGS=['/O2', '/Zi', '/DDEBUG_ENABLED'])
- env.Append(CPPFLAGS=['/MD'])
- env.Append(LINKFLAGS=['/SUBSYSTEM:CONSOLE'])
+ 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'])
+ winver = "0x0602" # Windows 8 is the minimum target for UWP build
+ env.Append(CCFLAGS=['/DWINVER=%s' % winver, '/D_WIN32_WINNT=%s' % winver])
- elif (env["target"] == "debug"):
+ env.Append(CPPFLAGS=['/D', '__WRL_NO_DEFAULT_LIB__', '/D', 'WIN32', '/DPNG_ABORT=abort'])
- env.Append(CCFLAGS=['/Zi', '/DDEBUG_ENABLED', '/DDEBUG_MEMORY_ENABLED'])
- env.Append(CPPFLAGS=['/MDd'])
- env.Append(LINKFLAGS=['/SUBSYSTEM:CONSOLE'])
- env.Append(LINKFLAGS=['/DEBUG'])
+ env.Append(CPPFLAGS=['/AI', vc_base_path + 'lib/store/references'])
+ env.Append(CPPFLAGS=['/AI', vc_base_path + 'lib/x86/store/references'])
env.Append(CCFLAGS=string.split('/FS /MP /GS /wd"4453" /wd"28204" /wd"4291" /Zc:wchar_t /Gm- /fp:precise /D "_UNICODE" /D "UNICODE" /D "WINAPI_FAMILY=WINAPI_FAMILY_APP" /errorReport:prompt /WX- /Zc:forScope /Gd /EHsc /nologo'))
env.Append(CXXFLAGS=string.split('/ZW /FS'))
- env.Append(CCFLAGS=['/AI', os.environ['VCINSTALLDIR'] + '\\vcpackages', '/AI', os.environ['WINDOWSSDKDIR'] + '\\References\\CommonConfiguration\\Neutral'])
-
- env["PROGSUFFIX"] = "." + arch + env["PROGSUFFIX"]
- env["OBJSUFFIX"] = "." + arch + env["OBJSUFFIX"]
- env["LIBSUFFIX"] = "." + arch + env["LIBSUFFIX"]
+ env.Append(CCFLAGS=['/AI', vc_base_path + '\\vcpackages', '/AI', os.environ['WINDOWSSDKDIR'] + '\\References\\CommonConfiguration\\Neutral'])
- env.Append(CCFLAGS=['/DUWP_ENABLED'])
- env.Append(CCFLAGS=['/DWINDOWS_ENABLED'])
- env.Append(CCFLAGS=['/DTYPED_METHOD_BIND'])
-
- env.Append(CCFLAGS=['/DGLES2_ENABLED', '/DGL_GLEXT_PROTOTYPES', '/DEGL_EGLEXT_PROTOTYPES', '/DANGLE_ENABLED'])
+ ## Link flags
- winver = "0x0602" # Windows 8 is the minimum target for UWP build
- env.Append(CCFLAGS=['/DWINVER=%s' % winver, '/D_WIN32_WINNT=%s' % winver])
+ env.Append(LINKFLAGS=['/MANIFEST:NO', '/NXCOMPAT', '/DYNAMICBASE', '/WINMD', '/APPCONTAINER', '/ERRORREPORT:PROMPT', '/NOLOGO', '/TLBID:1', '/NODEFAULTLIB:"kernel32.lib"', '/NODEFAULTLIB:"ole32.lib"'])
LIBS = [
'WindowsApp',
@@ -163,8 +168,3 @@ def configure(env):
env['BUILDERS']['Program'] = methods.precious_program
env.Append(BUILDERS={'ANGLE': env.Builder(action=angle_build_cmd)})
-
- env.Append(BUILDERS={'GLSL120': env.Builder(action=methods.build_legacygl_headers, suffix='glsl.h', src_suffix='.glsl')})
- env.Append(BUILDERS={'GLSL': env.Builder(action=methods.build_glsl_headers, suffix='glsl.h', src_suffix='.glsl')})
- env.Append(BUILDERS={'HLSL9': env.Builder(action=methods.build_hlsl_dx9_headers, suffix='hlsl.h', src_suffix='.hlsl')})
- env.Append(BUILDERS={'GLSL120GLES': env.Builder(action=methods.build_gles2_headers, suffix='glsl.h', src_suffix='.glsl')})
diff --git a/platform/uwp/export/export.cpp b/platform/uwp/export/export.cpp
index bef19d80ae..39717196aa 100644
--- a/platform/uwp/export/export.cpp
+++ b/platform/uwp/export/export.cpp
@@ -6,6 +6,7 @@
/* http://www.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 */
@@ -27,65 +28,27 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-/*************************************************************************
- * The code for signing the package was ported from fb-util-for-appx
- * available at https://github.com/facebook/fb-util-for-appx
- * and distributed also under the following license:
-
-BSD License
-
-For fb-util-for-appx software
-
-Copyright (c) 2016, Facebook, Inc. All rights reserved.
-
-Redistribution and use in source and binary forms, with or without modification,
-are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice, this
- list of conditions and the following disclaimer.
-
- * Redistributions in binary form must reproduce the above copyright notice,
- this list of conditions and the following disclaimer in the documentation
- and/or other materials provided with the distribution.
-
- * Neither the name Facebook nor the names of its contributors may be used to
- endorse or promote products derived from this software without specific
- prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
-ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
-ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-*************************************************************************/
-
-#if 0
#include "export.h"
#include "bind/core_bind.h"
-#include "editor/editor_import_export.h"
+#include "editor/editor_export.h"
#include "editor/editor_node.h"
-#include "global_config.h"
-#include "io/base64.h"
#include "io/marshalls.h"
-#include "io/sha256.h"
-#include "io/unzip.h"
-#include "io/zip.h"
#include "io/zip_io.h"
#include "object.h"
#include "os/file_access.h"
-#include "platform/uwp/logo.h"
+#include "platform/uwp/logo.gen.h"
+#include "project_settings.h"
#include "version.h"
+#include "thirdparty/minizip/unzip.h"
+#include "thirdparty/minizip/zip.h"
+#include "thirdparty/misc/base64.h"
+#include "thirdparty/misc/sha256.h"
+
#include <zlib.h>
// Capabilities
-static const char* uwp_capabilities[] = {
+static const char *uwp_capabilities[] = {
"allJoyn",
"codeGeneration",
"internetClient",
@@ -93,7 +56,7 @@ static const char* uwp_capabilities[] = {
"privateNetworkClientServer",
NULL
};
-static const char* uwp_uap_capabilities[] = {
+static const char *uwp_uap_capabilities[] = {
"appointments",
"blockedChatMessages",
"chat",
@@ -110,7 +73,7 @@ static const char* uwp_uap_capabilities[] = {
"voipCall",
NULL
};
-static const char* uwp_device_capabilites[] = {
+static const char *uwp_device_capabilites[] = {
"bluetooth",
"location",
"microphone",
@@ -119,166 +82,6 @@ static const char* uwp_device_capabilites[] = {
NULL
};
-#ifdef OPENSSL_ENABLED
-#include <openssl/asn1.h>
-#include <openssl/asn1t.h>
-#include <openssl/bio.h>
-#include <openssl/err.h>
-#include <openssl/ossl_typ.h>
-#include <openssl/pkcs12.h>
-#include <openssl/pkcs7.h>
-#include <openssl/x509.h>
-
-namespace asn1 {
- // https://msdn.microsoft.com/en-us/gg463180.aspx
-
- struct SPCStatementType {
- ASN1_OBJECT *type;
- };
- DECLARE_ASN1_FUNCTIONS(SPCStatementType)
-
- struct SPCSpOpusInfo {
- ASN1_TYPE *programName;
- ASN1_TYPE *moreInfo;
- };
- DECLARE_ASN1_FUNCTIONS(SPCSpOpusInfo)
-
- struct DigestInfo {
- X509_ALGOR *digestAlgorithm;
- ASN1_OCTET_STRING *digest;
- };
- DECLARE_ASN1_FUNCTIONS(DigestInfo)
-
- struct SPCAttributeTypeAndOptionalValue {
- ASN1_OBJECT *type;
- ASN1_TYPE *value; // SPCInfoValue
- };
- DECLARE_ASN1_FUNCTIONS(SPCAttributeTypeAndOptionalValue)
-
- // Undocumented.
- struct SPCInfoValue {
- ASN1_INTEGER *i1;
- ASN1_OCTET_STRING *s1;
- ASN1_INTEGER *i2;
- ASN1_INTEGER *i3;
- ASN1_INTEGER *i4;
- ASN1_INTEGER *i5;
- ASN1_INTEGER *i6;
- };
- DECLARE_ASN1_FUNCTIONS(SPCInfoValue)
-
- struct SPCIndirectDataContent {
- SPCAttributeTypeAndOptionalValue *data;
- DigestInfo *messageDigest;
- };
- DECLARE_ASN1_FUNCTIONS(SPCIndirectDataContent)
-
- IMPLEMENT_ASN1_FUNCTIONS(SPCIndirectDataContent)
- ASN1_SEQUENCE(SPCIndirectDataContent) = {
- ASN1_SIMPLE(SPCIndirectDataContent, data,
- SPCAttributeTypeAndOptionalValue),
- ASN1_SIMPLE(SPCIndirectDataContent, messageDigest, DigestInfo),
- } ASN1_SEQUENCE_END(SPCIndirectDataContent)
-
- IMPLEMENT_ASN1_FUNCTIONS(SPCAttributeTypeAndOptionalValue)
- ASN1_SEQUENCE(SPCAttributeTypeAndOptionalValue) = {
- ASN1_SIMPLE(SPCAttributeTypeAndOptionalValue, type,
- ASN1_OBJECT),
- ASN1_OPT(SPCAttributeTypeAndOptionalValue, value, ASN1_ANY),
- } ASN1_SEQUENCE_END(SPCAttributeTypeAndOptionalValue)
-
- IMPLEMENT_ASN1_FUNCTIONS(SPCInfoValue)
- ASN1_SEQUENCE(SPCInfoValue) = {
- ASN1_SIMPLE(SPCInfoValue, i1, ASN1_INTEGER),
- ASN1_SIMPLE(SPCInfoValue, s1, ASN1_OCTET_STRING),
- ASN1_SIMPLE(SPCInfoValue, i2, ASN1_INTEGER),
- ASN1_SIMPLE(SPCInfoValue, i3, ASN1_INTEGER),
- ASN1_SIMPLE(SPCInfoValue, i4, ASN1_INTEGER),
- ASN1_SIMPLE(SPCInfoValue, i5, ASN1_INTEGER),
- ASN1_SIMPLE(SPCInfoValue, i6, ASN1_INTEGER),
- } ASN1_SEQUENCE_END(SPCInfoValue)
-
- IMPLEMENT_ASN1_FUNCTIONS(DigestInfo)
- ASN1_SEQUENCE(DigestInfo) = {
- ASN1_SIMPLE(DigestInfo, digestAlgorithm, X509_ALGOR),
- ASN1_SIMPLE(DigestInfo, digest, ASN1_OCTET_STRING),
- } ASN1_SEQUENCE_END(DigestInfo)
-
- ASN1_SEQUENCE(SPCSpOpusInfo) = {
- ASN1_OPT(SPCSpOpusInfo, programName, ASN1_ANY),
- ASN1_OPT(SPCSpOpusInfo, moreInfo, ASN1_ANY),
- } ASN1_SEQUENCE_END(SPCSpOpusInfo)
- IMPLEMENT_ASN1_FUNCTIONS(SPCSpOpusInfo)
-
- ASN1_SEQUENCE(SPCStatementType) = {
- ASN1_SIMPLE(SPCStatementType, type, ASN1_OBJECT),
- } ASN1_SEQUENCE_END(SPCStatementType)
- IMPLEMENT_ASN1_FUNCTIONS(SPCStatementType)
-}
-
-class EncodedASN1 {
-
- uint8_t* i_data;
- size_t i_size;
-
- EncodedASN1(uint8_t** p_data, size_t p_size) {
-
- i_data = *p_data;
- i_size = p_size;
- }
-
-public:
-
- template <typename T, int(*TEncode)(T *, uint8_t **)>
- static EncodedASN1 FromItem(T *item) {
- uint8_t *dataRaw = NULL;
- int size = TEncode(item, &dataRaw);
-
- return EncodedASN1(&dataRaw, size);
- }
-
- const uint8_t *data() const {
- return i_data;
- }
-
- size_t size() const {
- return i_size;
- }
-
- // Assumes the encoded ASN.1 represents a SEQUENCE and puts it into
- // an ASN1_STRING.
- //
- // The returned object holds a copy of this object's data.
- ASN1_STRING* ToSequenceString() {
- ASN1_STRING* string = ASN1_STRING_new();
- if (!string) {
- return NULL;
- }
- if (!ASN1_STRING_set(string, i_data, i_size)) {
- return NULL;
- }
- return string;
- }
-
- // Assumes the encoded ASN.1 represents a SEQUENCE and puts it into
- // an ASN1_TYPE.
- //
- // The returned object holds a copy of this object's data.
- ASN1_TYPE* ToSequenceType() {
- ASN1_STRING* string = ToSequenceString();
- ASN1_TYPE* type = ASN1_TYPE_new();
- if (!type) {
- return NULL;
- }
- type->type = V_ASN1_SEQUENCE;
- type->value.sequence = string;
- return type;
- }
-
-};
-
-#endif // OPENSSL_ENABLED
-
class AppxPackager {
enum {
@@ -334,34 +137,33 @@ 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(uint8_t *p_block_data, size_t p_block_len);
void make_block_map();
void make_content_types();
-
- _FORCE_INLINE_ unsigned int buf_put_int16(uint16_t p_val, uint8_t * p_buf) {
+ _FORCE_INLINE_ unsigned int buf_put_int16(uint16_t p_val, uint8_t *p_buf) {
for (int i = 0; i < 2; i++) {
*p_buf++ = (p_val >> (i * 8)) & 0xFF;
}
return 2;
}
- _FORCE_INLINE_ unsigned int buf_put_int32(uint32_t p_val, uint8_t * p_buf) {
+ _FORCE_INLINE_ unsigned int buf_put_int32(uint32_t p_val, uint8_t *p_buf) {
for (int i = 0; i < 4; i++) {
*p_buf++ = (p_val >> (i * 8)) & 0xFF;
}
return 4;
}
- _FORCE_INLINE_ unsigned int buf_put_int64(uint64_t p_val, uint8_t * p_buf) {
+ _FORCE_INLINE_ unsigned int buf_put_int64(uint64_t p_val, uint8_t *p_buf) {
for (int i = 0; i < 8; i++) {
*p_buf++ = (p_val >> (i * 8)) & 0xFF;
}
return 8;
}
- _FORCE_INLINE_ unsigned int buf_put_string(String p_val, uint8_t * p_buf) {
+ _FORCE_INLINE_ unsigned int buf_put_string(String p_val, uint8_t *p_buf) {
for (int i = 0; i < p_val.length(); i++) {
*p_buf++ = p_val.utf8().get(i);
}
@@ -369,173 +171,24 @@ class AppxPackager {
}
Vector<uint8_t> make_file_header(FileMeta p_file_meta);
- void store_central_dir_header(const FileMeta p_file, bool p_do_hash = true);
+ void store_central_dir_header(const FileMeta &p_file, bool p_do_hash = true);
Vector<uint8_t> make_end_of_central_record();
String content_type(String p_extension);
-#ifdef OPENSSL_ENABLED
-
- // Signing methods and structs:
-
- String certificate_path;
- String certificate_pass;
- bool sign_package;
-
- struct CertFile {
-
- EVP_PKEY* private_key;
- X509* certificate;
- };
-
- SHA256_CTX axpc_context; // SHA256 context for ZIP file entries
- SHA256_CTX axcd_context; // SHA256 context for ZIP directory entries
-
- struct AppxDigests {
-
- uint8_t axpc[SHA256_DIGEST_LENGTH]; // ZIP file entries
- uint8_t axcd[SHA256_DIGEST_LENGTH]; // ZIP directory entry
- uint8_t axct[SHA256_DIGEST_LENGTH]; // Content types XML
- uint8_t axbm[SHA256_DIGEST_LENGTH]; // Block map XML
- uint8_t axci[SHA256_DIGEST_LENGTH]; // Code Integrity file (optional)
- };
-
- CertFile cert_file;
- AppxDigests digests;
-
- void MakeSPCInfoValue(asn1::SPCInfoValue &info);
- Error MakeIndirectDataContent(asn1::SPCIndirectDataContent &idc);
- Error add_attributes(PKCS7_SIGNER_INFO *signerInfo);
- void make_digests();
- void write_digest(Vector<uint8_t> &p_out_buffer);
-
- Error openssl_error(unsigned long p_err);
- Error read_cert_file(const String &p_path, const String &p_password, CertFile* p_out_cf);
- Error sign(const CertFile &p_cert, const AppxDigests &digests, PKCS7* p_out_signature);
-
-#endif // OPENSSL_ENABLED
-
public:
-
- enum SignOption {
-
- SIGN,
- DONT_SIGN,
- };
-
void set_progress_task(String p_task) { progress_task = p_task; }
- void init(FileAccess* p_fa, SignOption p_sign, String &p_certificate_path, String &p_certificate_password);
- void 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 = false);
+ void init(FileAccess *p_fa);
+ void 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 = false);
void finish();
AppxPackager();
~AppxPackager();
};
-class EditorExportPlatformUWP : public EditorExportPlatform {
-
- GDCLASS(EditorExportPlatformUWP, EditorExportPlatform);
-
- Ref<ImageTexture> logo;
-
- enum Platform {
- ARM,
- X86,
- X64
- } arch;
-
- bool is_debug;
-
- String custom_release_package;
- String custom_debug_package;
-
- String cmdline;
-
- String display_name;
- String short_name;
- String unique_name;
- String description;
- String publisher;
- String publisher_display_name;
-
- String product_guid;
- String publisher_guid;
-
- int version_major;
- int version_minor;
- int version_build;
- int version_revision;
-
- bool orientation_landscape;
- bool orientation_portrait;
- bool orientation_landscape_flipped;
- bool orientation_portrait_flipped;
-
- String background_color;
- Ref<ImageTexture> store_logo;
- Ref<ImageTexture> square44;
- Ref<ImageTexture> square71;
- Ref<ImageTexture> square150;
- Ref<ImageTexture> square310;
- Ref<ImageTexture> wide310;
- Ref<ImageTexture> splash;
-
- bool name_on_square150;
- bool name_on_square310;
- bool name_on_wide;
-
- Set<String> capabilities;
- Set<String> uap_capabilities;
- Set<String> device_capabilities;
-
- bool sign_package;
- String certificate_path;
- String certificate_pass;
-
- _FORCE_INLINE_ bool array_has(const char** p_array, const char* p_value) const {
- while (*p_array) {
- if (String(*p_array) == String(p_value)) return true;
- p_array++;
- }
- return false;
- }
-
- bool _valid_resource_name(const String &p_name) const;
- bool _valid_guid(const String &p_guid) const;
- bool _valid_bgcolor(const String &p_color) const;
- bool _valid_image(const Ref<ImageTexture> p_image, int p_width, int p_height) const;
-
- Vector<uint8_t> _fix_manifest(const Vector<uint8_t> &p_template, bool p_give_internet) const;
- Vector<uint8_t> _get_image_data(const String &p_path);
-
- static Error save_appx_file(void *p_userdata, const String& p_path, const Vector<uint8_t>& p_data, int p_file, int p_total);
- static bool _should_compress_asset(const String& p_path, const Vector<uint8_t>& p_data);
-
-protected:
-
- bool _set(const StringName& p_name, const Variant& p_value);
- bool _get(const StringName& p_name, Variant &r_ret) const;
- void _get_property_list(List<PropertyInfo> *p_list) const;
-
-public:
-
- virtual String get_name() const { return "Windows Universal"; }
- virtual ImageCompression get_image_compression() const { return IMAGE_COMPRESSION_ETC1; }
- virtual Ref<Texture> get_logo() const { return logo; }
-
- virtual bool can_export(String *r_error = NULL) const;
- virtual String get_binary_extension() const { return "appx"; }
-
- virtual Error export_project(const String& p_path, bool p_debug, int p_flags = 0);
-
- EditorExportPlatformUWP();
- ~EditorExportPlatformUWP();
-};
-
-
///////////////////////////////////////////////////////////////////////////
-String AppxPackager::hash_block(uint8_t * p_block_data, size_t p_block_len) {
+String AppxPackager::hash_block(uint8_t *p_block_data, size_t p_block_len) {
char hash[32];
char base64[45];
@@ -543,7 +196,7 @@ String AppxPackager::hash_block(uint8_t * p_block_data, size_t p_block_len) {
sha256_context ctx;
sha256_init(&ctx);
sha256_hash(&ctx, p_block_data, p_block_len);
- sha256_done(&ctx, (uint8_t*)hash);
+ sha256_done(&ctx, (uint8_t *)hash);
base64_encode(base64, hash, 32);
base64[44] = '\0';
@@ -553,7 +206,7 @@ String AppxPackager::hash_block(uint8_t * p_block_data, size_t p_block_len) {
void AppxPackager::make_block_map() {
- FileAccess* tmp_file = FileAccess::open(tmp_blockmap_file_path, FileAccess::WRITE);
+ FileAccess *tmp_file = FileAccess::open(tmp_blockmap_file_path, FileAccess::WRITE);
tmp_file->store_string("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>");
tmp_file->store_string("<BlockMap xmlns=\"http://schemas.microsoft.com/appx/2010/blockmap\" HashMethod=\"http://www.w3.org/2001/04/xmlenc#sha256\">");
@@ -563,15 +216,11 @@ void AppxPackager::make_block_map() {
FileMeta file = file_metadata[i];
tmp_file->store_string(
- "<File Name=\"" + file.name.replace("/", "\\")
- + "\" Size=\"" + itos(file.uncompressed_size)
- + "\" LfhSize=\"" + itos(file.lfh_size) + "\">");
-
+ "<File Name=\"" + file.name.replace("/", "\\") + "\" Size=\"" + itos(file.uncompressed_size) + "\" LfhSize=\"" + itos(file.lfh_size) + "\">");
for (int j = 0; j < file.hashes.size(); j++) {
- tmp_file->store_string("<Block Hash=\""
- + file.hashes[j].base64_hash + "\" ");
+ tmp_file->store_string("<Block Hash=\"" + file.hashes[j].base64_hash + "\" ");
if (file.compressed)
tmp_file->store_string("Size=\"" + itos(file.hashes[j].compressed_size) + "\" ");
tmp_file->store_string("/>");
@@ -603,12 +252,12 @@ String AppxPackager::content_type(String p_extension) {
void AppxPackager::make_content_types() {
- FileAccess* tmp_file = FileAccess::open(tmp_content_types_file_path, FileAccess::WRITE);
+ FileAccess *tmp_file = FileAccess::open(tmp_content_types_file_path, FileAccess::WRITE);
tmp_file->store_string("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
tmp_file->store_string("<Types xmlns=\"http://schemas.openxmlformats.org/package/2006/content-types\">");
- Map<String, String> types;
+ Map<String, String> types;
for (int i = 0; i < file_metadata.size(); i++) {
@@ -680,13 +329,12 @@ Vector<uint8_t> AppxPackager::make_file_header(FileMeta p_file_meta) {
return buf;
}
-void AppxPackager::store_central_dir_header(const FileMeta p_file, bool p_do_hash) {
+void AppxPackager::store_central_dir_header(const FileMeta &p_file, bool p_do_hash) {
Vector<uint8_t> &buf = central_dir_data;
int offs = buf.size();
buf.resize(buf.size() + BASE_CENTRAL_DIR_SIZE + p_file.name.length());
-
// Write magic
offs += buf_put_int32(CENTRAL_DIR_MAGIC, &buf[offs]);
@@ -730,12 +378,6 @@ void AppxPackager::store_central_dir_header(const FileMeta p_file, bool p_do_has
// File name
offs += buf_put_string(p_file.name, &buf[offs]);
-#ifdef OPENSSL_ENABLED
- // Calculate the hash for signing
- if (p_do_hash)
- SHA256_Update(&axcd_context, buf.ptr(), buf.size());
-#endif // OPENSSL_ENABLED
-
// Done!
}
@@ -809,23 +451,16 @@ Vector<uint8_t> AppxPackager::make_end_of_central_record() {
return buf;
}
-void AppxPackager::init(FileAccess * p_fa, SignOption p_sign, String &p_certificate_path, String &p_certificate_password) {
+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";
-#ifdef OPENSSL_ENABLED
- certificate_path = p_certificate_path;
- certificate_pass = p_certificate_password;
- sign_package = p_sign == SIGN;
- SHA256_Init(&axpc_context);
- SHA256_Init(&axcd_context);
-#endif // OPENSSL_ENABLED
}
-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) {
+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) {
if (p_file_no >= 1 && p_total_files >= 1) {
EditorNode::progress_task_step(progress_task, "File: " + p_file_name, (p_file_no * 100) / p_total_files);
@@ -844,7 +479,7 @@ void AppxPackager::add_file(String p_file_name, const uint8_t * p_buffer, size_t
// Data for compression
z_stream strm;
- FileAccess* strm_f = NULL;
+ FileAccess *strm_f = NULL;
Vector<uint8_t> strm_in;
strm_in.resize(BLOCK_SIZE);
Vector<uint8_t> strm_out;
@@ -890,11 +525,6 @@ void AppxPackager::add_file(String p_file_name, const uint8_t * p_buffer, size_t
file_buffer.resize(file_buffer.size() + bh.compressed_size);
for (int i = 0; i < bh.compressed_size; i++)
file_buffer[start + i] = strm_out[i];
-#ifdef OPENSSL_ENABLED
- if (do_hash)
- SHA256_Update(&axpc_context, strm_out.ptr(), strm.total_out - total_out_before);
-#endif // OPENSSL_ENABLED
-
} else {
bh.compressed_size = block_size;
//package->store_buffer(strm_in.ptr(), block_size);
@@ -902,10 +532,6 @@ void AppxPackager::add_file(String p_file_name, const uint8_t * p_buffer, size_t
file_buffer.resize(file_buffer.size() + block_size);
for (int i = 0; i < bh.compressed_size; i++)
file_buffer[start + i] = strm_in[i];
-#ifdef OPENSSL_ENABLED
- if (do_hash)
- SHA256_Update(&axpc_context, strm_in.ptr(), block_size);
-#endif // OPENSSL_ENABLED
}
meta.hashes.push_back(bh);
@@ -929,10 +555,6 @@ void AppxPackager::add_file(String p_file_name, const uint8_t * p_buffer, size_t
file_buffer.resize(file_buffer.size() + (strm.total_out - total_out_before));
for (int i = 0; i < (strm.total_out - total_out_before); i++)
file_buffer[start + i] = strm_out[i];
-#ifdef OPENSSL_ENABLED
- if (do_hash)
- SHA256_Update(&axpc_context, strm_out.ptr(), strm.total_out - total_out_before);
-#endif // OPENSSL_ENABLED
deflateEnd(&strm);
meta.compressed_size = strm.total_out;
@@ -951,14 +573,6 @@ void AppxPackager::add_file(String p_file_name, const uint8_t * p_buffer, size_t
Vector<uint8_t> file_header = make_file_header(meta);
meta.lfh_size = file_header.size();
-#ifdef OPENSSL_ENABLED
- // Hash the data for signing
- if (do_hash) {
- SHA256_Update(&axpc_context, file_header.ptr(), file_header.size());
- SHA256_Update(&axpc_context, file_buffer.ptr(), file_buffer.size());
- }
-#endif // OPENSSL_ENABLED
-
// Store the header and file;
package->store_buffer(file_header.ptr(), file_header.size());
package->store_buffer(file_buffer.ptr(), file_buffer.size());
@@ -972,22 +586,12 @@ void AppxPackager::finish() {
EditorNode::progress_task_step("export", "Creating block map...", 4);
make_block_map();
- FileAccess* blockmap_file = FileAccess::open(tmp_blockmap_file_path, FileAccess::READ);
+ FileAccess *blockmap_file = FileAccess::open(tmp_blockmap_file_path, FileAccess::READ);
Vector<uint8_t> blockmap_buffer;
blockmap_buffer.resize(blockmap_file->get_len());
blockmap_file->get_buffer(blockmap_buffer.ptr(), blockmap_buffer.size());
-#ifdef OPENSSL_ENABLED
- // Hash the file for signing
- if (sign_package) {
- SHA256_CTX axbm_context;
- SHA256_Init(&axbm_context);
- SHA256_Update(&axbm_context, blockmap_buffer.ptr(), blockmap_buffer.size());
- SHA256_Final(digests.axbm, &axbm_context);
- }
-#endif // OPENSSL_ENABLED
-
add_file("AppxBlockMap.xml", blockmap_buffer.ptr(), blockmap_buffer.size(), -1, -1, true);
blockmap_file->close();
@@ -998,22 +602,12 @@ void AppxPackager::finish() {
EditorNode::progress_task_step("export", "Setting content types...", 5);
make_content_types();
- FileAccess* types_file = FileAccess::open(tmp_content_types_file_path, FileAccess::READ);
+ FileAccess *types_file = FileAccess::open(tmp_content_types_file_path, FileAccess::READ);
Vector<uint8_t> types_buffer;
types_buffer.resize(types_file->get_len());
types_file->get_buffer(types_buffer.ptr(), types_buffer.size());
-#ifdef OPENSSL_ENABLED
- if (sign_package) {
- // Hash the file for signing
- SHA256_CTX axct_context;
- SHA256_Init(&axct_context);
- SHA256_Update(&axct_context, types_buffer.ptr(), types_buffer.size());
- SHA256_Final(digests.axct, &axct_context);
- }
-#endif // OPENSSL_ENABLED
-
add_file("[Content_Types].xml", types_buffer.ptr(), types_buffer.size(), -1, -1, true);
types_file->close();
@@ -1025,76 +619,6 @@ void AppxPackager::finish() {
store_central_dir_header(file_metadata[i]);
}
-#ifdef OPENSSL_ENABLED
- // Create the signature file
- if (sign_package) {
-
- Error err = read_cert_file(certificate_path, certificate_pass, &cert_file);
-
- if (err != OK) {
- EditorNode::add_io_error(TTR("Couldn't read the certificate file. Are the path and password both correct?"));
- package->close();
- memdelete(package);
- package = NULL;
- return;
- }
-
-
- // Make a temp end of the zip for hashing
- central_dir_offset = package->get_pos();
- end_of_central_dir_offset = central_dir_offset + central_dir_data.size();
- Vector<uint8_t> zip_end_dir = make_end_of_central_record();
-
- // Hash the end directory
- SHA256_Update(&axcd_context, zip_end_dir.ptr(), zip_end_dir.size());
-
- // Finish the hashes
- make_digests();
-
- PKCS7* signature = PKCS7_new();
- if (!signature) {
- EditorNode::add_io_error(TTR("Error creating the signature object."));
- package->close();
- memdelete(package);
- package = NULL;
- return;
- }
-
- err = sign(cert_file, digests, signature);
-
- if (err != OK) {
- EditorNode::add_io_error(TTR("Error creating the package signature."));
- package->close();
- memdelete(package);
- package = NULL;
- return;
- }
-
- // Read the signature as bytes
- BIO* bio_out = BIO_new(BIO_s_mem());
- i2d_PKCS7_bio(bio_out, signature);
-
- BIO_flush(bio_out);
-
- uint8_t* bio_ptr;
- size_t bio_size = BIO_get_mem_data(bio_out, &bio_ptr);
-
- // Create the signature buffer with magic number
- Vector<uint8_t> signature_file;
- signature_file.resize(4 + bio_size);
- buf_put_int32(P7X_SIGNATURE, signature_file.ptr());
- for (int i = 0; i < bio_size; i++)
- signature_file[i + 4] = bio_ptr[i];
-
- // Add the signature to the package
- add_file("AppxSignature.p7x", signature_file.ptr(), signature_file.size(), -1, -1, true);
-
- // Add central directory entry
- store_central_dir_header(file_metadata[file_metadata.size() - 1], false);
- }
-#endif // OPENSSL_ENABLED
-
-
// Write central directory
EditorNode::progress_task_step("export", "Finishing package...", 6);
central_dir_offset = package->get_pos();
@@ -1110,1284 +634,759 @@ void AppxPackager::finish() {
package = NULL;
}
-#ifdef OPENSSL_ENABLED
-// https://support.microsoft.com/en-us/kb/287547
-const char SPC_INDIRECT_DATA_OBJID[] = "1.3.6.1.4.1.311.2.1.4";
-const char SPC_STATEMENT_TYPE_OBJID[] = "1.3.6.1.4.1.311.2.1.11";
-const char SPC_SP_OPUS_INFO_OBJID[] = "1.3.6.1.4.1.311.2.1.12";
-const char SPC_SIPINFO_OBJID[] = "1.3.6.1.4.1.311.2.1.30";
-#endif // OPENSSL_ENABLED
-
AppxPackager::AppxPackager() {}
AppxPackager::~AppxPackager() {}
-
////////////////////////////////////////////////////////////////////
-#ifdef OPENSSL_ENABLED
-Error AppxPackager::openssl_error(unsigned long p_err) {
-
- ERR_load_crypto_strings();
+class EditorExportUWP : public EditorExportPlatform {
- char buffer[256];
- ERR_error_string_n(p_err, buffer, sizeof(buffer));
+ GDCLASS(EditorExportUWP, EditorExportPlatform);
- String err(buffer);
-
- ERR_EXPLAIN(err);
- ERR_FAIL_V(FAILED);
-}
-
-void AppxPackager::MakeSPCInfoValue(asn1::SPCInfoValue &info) {
+ Ref<ImageTexture> logo;
- // I have no idea what these numbers mean.
- static uint8_t s1Magic[] = {
- 0x4B, 0xDF, 0xC5, 0x0A, 0x07, 0xCE, 0xE2, 0x4D,
- 0xB7, 0x6E, 0x23, 0xC8, 0x39, 0xA0, 0x9F, 0xD1,
+ enum Platform {
+ ARM,
+ X86,
+ X64
};
- ASN1_INTEGER_set(info.i1, 0x01010000);
- ASN1_OCTET_STRING_set(info.s1, s1Magic, sizeof(s1Magic));
- ASN1_INTEGER_set(info.i2, 0x00000000);
- ASN1_INTEGER_set(info.i3, 0x00000000);
- ASN1_INTEGER_set(info.i4, 0x00000000);
- ASN1_INTEGER_set(info.i5, 0x00000000);
- ASN1_INTEGER_set(info.i6, 0x00000000);
-}
-
-Error AppxPackager::MakeIndirectDataContent(asn1::SPCIndirectDataContent &idc) {
- using namespace asn1;
+ bool _valid_resource_name(const String &p_name) const {
- ASN1_TYPE* algorithmParameter = ASN1_TYPE_new();
- if (!algorithmParameter) {
- return openssl_error(ERR_peek_last_error());
- }
- algorithmParameter->type = V_ASN1_NULL;
-
- SPCInfoValue* infoValue = SPCInfoValue_new();
- if (!infoValue) {
- return openssl_error(ERR_peek_last_error());
- }
- MakeSPCInfoValue(*infoValue);
+ if (p_name.empty()) return false;
+ if (p_name.ends_with(".")) return false;
- ASN1_TYPE* value =
- EncodedASN1::FromItem<asn1::SPCInfoValue,
- asn1::i2d_SPCInfoValue>(infoValue)
- .ToSequenceType();
+ static const char *invalid_names[] = {
+ "CON", "PRN", "AUX", "NUL", "COM1", "COM2", "COM3", "COM4", "COM5", "COM6", "COM7",
+ "COM8", "COM9", "LPT1", "LPT2", "LPT3", "LPT4", "LPT5", "LPT6", "LPT7", "LPT8", "LPT9",
+ NULL
+ };
- {
- Vector<uint8_t> digest;
- write_digest(digest);
- if (!ASN1_OCTET_STRING_set(idc.messageDigest->digest,
- digest.ptr(), digest.size())) {
-
- return openssl_error(ERR_peek_last_error());
+ const char **t = invalid_names;
+ while (*t) {
+ if (p_name == *t) return false;
+ t++;
}
- }
-
- idc.data->type = OBJ_txt2obj(SPC_SIPINFO_OBJID, 1);
- idc.data->value = value;
- idc.messageDigest->digestAlgorithm->algorithm = OBJ_nid2obj(NID_sha256);
- idc.messageDigest->digestAlgorithm->parameter = algorithmParameter;
-
- return OK;
-}
-
-Error AppxPackager::add_attributes(PKCS7_SIGNER_INFO * p_signer_info) {
-
- // Add opus attribute
- asn1::SPCSpOpusInfo* opus = asn1::SPCSpOpusInfo_new();
- if (!opus) return openssl_error(ERR_peek_last_error());
-
- ASN1_STRING* opus_value =
- EncodedASN1::FromItem<asn1::SPCSpOpusInfo,
- asn1::i2d_SPCSpOpusInfo>(opus)
- .ToSequenceString();
-
- if (!PKCS7_add_signed_attribute(
- p_signer_info,
- OBJ_txt2nid(SPC_SP_OPUS_INFO_OBJID),
- V_ASN1_SEQUENCE,
- opus_value
- )) {
-
- asn1::SPCSpOpusInfo_free(opus);
-
- ASN1_STRING_free(opus_value);
- return openssl_error(ERR_peek_last_error());
- }
-
- // Add content type attribute
- if (!PKCS7_add_signed_attribute(
- p_signer_info,
- NID_pkcs9_contentType,
- V_ASN1_OBJECT,
- OBJ_txt2obj(SPC_INDIRECT_DATA_OBJID, 1)
- )) {
-
- asn1::SPCSpOpusInfo_free(opus);
- ASN1_STRING_free(opus_value);
- return openssl_error(ERR_peek_last_error());
- }
-
- // Add statement type attribute
- asn1::SPCStatementType* statement_type = asn1::SPCStatementType_new();
- if (!statement_type) return openssl_error(ERR_peek_last_error());
-
- statement_type->type = OBJ_nid2obj(NID_ms_code_ind);
- ASN1_STRING* statement_type_value =
- EncodedASN1::FromItem<asn1::SPCStatementType,
- asn1::i2d_SPCStatementType>(statement_type)
- .ToSequenceString();
-
- if (!PKCS7_add_signed_attribute(
- p_signer_info,
- OBJ_txt2nid(SPC_STATEMENT_TYPE_OBJID),
- V_ASN1_SEQUENCE,
- statement_type_value
- )) {
-
- ASN1_STRING_free(opus_value);
- asn1::SPCStatementType_free(statement_type);
- ASN1_STRING_free(statement_type_value);
-
- return openssl_error(ERR_peek_last_error());
- }
-
- return OK;
-
-}
-
-void AppxPackager::make_digests() {
-
- // AXPC
- SHA256_Final(digests.axpc, &axpc_context);
-
- // AXCD
- SHA256_Final(digests.axcd, &axcd_context);
-
- // AXCI
- for (int i = 0; i < SHA256_DIGEST_LENGTH; i++)
- digests.axci[i] = 0;
-
-}
-
-void AppxPackager::write_digest(Vector<uint8_t>& p_out_buffer) {
-
- // Size of digests plus 6 32-bit magic numbers
- p_out_buffer.resize((SHA256_DIGEST_LENGTH * 5) + (6 * 4));
-
- int offs = 0;
-
- // APPX
- uint32_t sig = 0x58505041;
- offs += buf_put_int32(sig, &p_out_buffer[offs]);
-
- // AXPC
- uint32_t axpc_sig = 0x43505841;
- offs += buf_put_int32(axpc_sig, &p_out_buffer[offs]);
- for (int i = 0; i < SHA256_DIGEST_LENGTH; i++) {
- p_out_buffer[offs++] = digests.axpc[i];
- }
-
- // AXCD
- uint32_t axcd_sig = 0x44435841;
- offs += buf_put_int32(axcd_sig, &p_out_buffer[offs]);
- for (int i = 0; i < SHA256_DIGEST_LENGTH; i++) {
- p_out_buffer[offs++] = digests.axcd[i];
- }
-
- // AXCT
- uint32_t axct_sig = 0x54435841;
- offs += buf_put_int32(axct_sig, &p_out_buffer[offs]);
- for (int i = 0; i < SHA256_DIGEST_LENGTH; i++) {
- p_out_buffer[offs++] = digests.axct[i];
- }
-
- // AXBM
- uint32_t axbm_sig = 0x4D425841;
- offs += buf_put_int32(axbm_sig, &p_out_buffer[offs]);
- for (int i = 0; i < SHA256_DIGEST_LENGTH; i++) {
- p_out_buffer[offs++] = digests.axbm[i];
- }
-
- // AXCI
- uint32_t axci_sig = 0x49435841;
- offs += buf_put_int32(axci_sig, &p_out_buffer[offs]);
- for (int i = 0; i < SHA256_DIGEST_LENGTH; i++) {
- p_out_buffer[offs++] = digests.axci[i];
- }
-
- // Done!
-}
-
-Error AppxPackager::read_cert_file(const String & p_path, const String &p_password, CertFile* p_out_cf) {
-
- ERR_FAIL_COND_V(!p_out_cf, ERR_INVALID_PARAMETER);
-
- BIO* bio = BIO_new_file(p_path.utf8().get_data(), "rb");
- if (!bio) {
- return openssl_error(ERR_peek_last_error());
- }
-
- PKCS12* data = d2i_PKCS12_bio(bio, NULL);
- if (!data) {
- BIO_free(bio);
- return openssl_error(ERR_peek_last_error());
- }
-
- /* Fails to link with GCC, need to solve when implement signing
- if (!PKCS12_parse(data, p_password.utf8().get_data(), &p_out_cf->private_key, &p_out_cf->certificate, NULL)) {
- PKCS12_free(data);
- BIO_free(bio);
- return openssl_error(ERR_peek_last_error());
- }*/
-
- if (!p_out_cf->private_key) {
- PKCS12_free(data);
- BIO_free(bio);
- return openssl_error(ERR_peek_last_error());
- }
-
- if (!p_out_cf->certificate) {
- PKCS12_free(data);
- BIO_free(bio);
- return openssl_error(ERR_peek_last_error());
- }
-
- PKCS12_free(data);
- BIO_free(bio);
-
- return OK;
-}
-
-Error AppxPackager::sign(const CertFile & p_cert, const AppxDigests & digests, PKCS7 * p_out_signature) {
-
- OpenSSL_add_all_algorithms();
- // Register object IDs
- OBJ_create_and_add_object(SPC_INDIRECT_DATA_OBJID, NULL, NULL);
- OBJ_create_and_add_object(SPC_SIPINFO_OBJID, NULL, NULL);
- OBJ_create_and_add_object(SPC_SP_OPUS_INFO_OBJID, NULL, NULL);
- OBJ_create_and_add_object(SPC_STATEMENT_TYPE_OBJID, NULL, NULL);
-
- if (!PKCS7_set_type(p_out_signature, NID_pkcs7_signed)) {
-
- return openssl_error(ERR_peek_last_error());
- }
-
- PKCS7_SIGNER_INFO *signer_info = PKCS7_add_signature(p_out_signature, p_cert.certificate, p_cert.private_key, EVP_sha256());
- if (!signer_info) return openssl_error(ERR_peek_last_error());
-
- add_attributes(signer_info);
-
- if (!PKCS7_content_new(p_out_signature, NID_pkcs7_data)) {
+ return true;
+ }
+
+ bool _valid_guid(const String &p_guid) const {
+
+ Vector<String> parts = p_guid.split("-");
+
+ if (parts.size() != 5) return false;
+ if (parts[0].length() != 8) return false;
+ for (int i = 1; i < 4; i++)
+ if (parts[i].length() != 4) return false;
+ if (parts[4].length() != 12) return false;
+
+ return true;
+ }
+
+ bool _valid_bgcolor(const String &p_color) const {
+
+ if (p_color.empty()) return true;
+ if (p_color.begins_with("#") && p_color.is_valid_html_color()) return true;
+
+ // Colors from https://msdn.microsoft.com/en-us/library/windows/apps/dn934817.aspx
+ static const char *valid_colors[] = {
+ "aliceBlue", "antiqueWhite", "aqua", "aquamarine", "azure", "beige",
+ "bisque", "black", "blanchedAlmond", "blue", "blueViolet", "brown",
+ "burlyWood", "cadetBlue", "chartreuse", "chocolate", "coral", "cornflowerBlue",
+ "cornsilk", "crimson", "cyan", "darkBlue", "darkCyan", "darkGoldenrod",
+ "darkGray", "darkGreen", "darkKhaki", "darkMagenta", "darkOliveGreen", "darkOrange",
+ "darkOrchid", "darkRed", "darkSalmon", "darkSeaGreen", "darkSlateBlue", "darkSlateGray",
+ "darkTurquoise", "darkViolet", "deepPink", "deepSkyBlue", "dimGray", "dodgerBlue",
+ "firebrick", "floralWhite", "forestGreen", "fuchsia", "gainsboro", "ghostWhite",
+ "gold", "goldenrod", "gray", "green", "greenYellow", "honeydew",
+ "hotPink", "indianRed", "indigo", "ivory", "khaki", "lavender",
+ "lavenderBlush", "lawnGreen", "lemonChiffon", "lightBlue", "lightCoral", "lightCyan",
+ "lightGoldenrodYellow", "lightGreen", "lightGray", "lightPink", "lightSalmon", "lightSeaGreen",
+ "lightSkyBlue", "lightSlateGray", "lightSteelBlue", "lightYellow", "lime", "limeGreen",
+ "linen", "magenta", "maroon", "mediumAquamarine", "mediumBlue", "mediumOrchid",
+ "mediumPurple", "mediumSeaGreen", "mediumSlateBlue", "mediumSpringGreen", "mediumTurquoise", "mediumVioletRed",
+ "midnightBlue", "mintCream", "mistyRose", "moccasin", "navajoWhite", "navy",
+ "oldLace", "olive", "oliveDrab", "orange", "orangeRed", "orchid",
+ "paleGoldenrod", "paleGreen", "paleTurquoise", "paleVioletRed", "papayaWhip", "peachPuff",
+ "peru", "pink", "plum", "powderBlue", "purple", "red",
+ "rosyBrown", "royalBlue", "saddleBrown", "salmon", "sandyBrown", "seaGreen",
+ "seaShell", "sienna", "silver", "skyBlue", "slateBlue", "slateGray",
+ "snow", "springGreen", "steelBlue", "tan", "teal", "thistle",
+ "tomato", "transparent", "turquoise", "violet", "wheat", "white",
+ "whiteSmoke", "yellow", "yellowGreen",
+ NULL
+ };
+
+ const char **color = valid_colors;
+
+ while (*color) {
+ if (p_color == *color) return true;
+ color++;
+ }
- return openssl_error(ERR_peek_last_error());
+ return false;
}
- if (!PKCS7_add_certificate(p_out_signature, p_cert.certificate)) {
+ bool _valid_image(const StreamTexture *p_image, int p_width, int p_height) const {
- return openssl_error(ERR_peek_last_error());
- }
+ if (!p_image) {
+ return false;
+ }
- asn1::SPCIndirectDataContent* idc = asn1::SPCIndirectDataContent_new();
+ // TODO: Add resource creation or image rescaling to enable other scales:
+ // 1.25, 1.5, 2.0
+ real_t scales[] = { 1.0 };
+ bool valid_w = false;
+ bool valid_h = false;
- MakeIndirectDataContent(*idc);
- EncodedASN1 idc_encoded =
- EncodedASN1::FromItem<asn1::SPCIndirectDataContent, asn1::i2d_SPCIndirectDataContent>(idc);
+ for (int i = 0; i < 1; i++) {
- BIO* signed_data = PKCS7_dataInit(p_out_signature, NULL);
+ int w = ceil(p_width * scales[i]);
+ int h = ceil(p_height * scales[i]);
- if (idc_encoded.size() < 2) {
+ if (w == p_image->get_width())
+ valid_w = true;
+ if (h == p_image->get_height())
+ valid_h = true;
+ }
- ERR_EXPLAIN("Invalid encoded size");
- ERR_FAIL_V(FAILED);
+ return valid_w && valid_h;
}
- if ((idc_encoded.data()[1] & 0x80) == 0x00) {
+ Vector<uint8_t> _fix_manifest(const Ref<EditorExportPreset> &p_preset, const Vector<uint8_t> &p_template, bool p_give_internet) const {
- ERR_EXPLAIN("Invalid encoded data");
- ERR_FAIL_V(FAILED);
- }
+ String result = String::utf8((const char *)p_template.ptr(), p_template.size());
- size_t skip = 4;
+ result = result.replace("$godot_version$", VERSION_FULL_NAME);
- if (BIO_write(signed_data, idc_encoded.data() + skip, idc_encoded.size() - skip)
- != idc_encoded.size() - skip) {
+ result = result.replace("$identity_name$", p_preset->get("package/unique_name"));
+ result = result.replace("$publisher$", p_preset->get("package/publisher"));
- return openssl_error(ERR_peek_last_error());
- }
- if (BIO_flush(signed_data) != 1) {
+ result = result.replace("$product_guid$", p_preset->get("identity/product_guid"));
+ result = result.replace("$publisher_guid$", p_preset->get("identity/publisher_guid"));
- return openssl_error(ERR_peek_last_error());
- }
+ String version = itos(p_preset->get("version/major")) + "." + itos(p_preset->get("version/minor")) + "." + itos(p_preset->get("version/build")) + "." + itos(p_preset->get("version/revision"));
+ result = result.replace("$version_string$", version);
- if (!PKCS7_dataFinal(p_out_signature, signed_data)) {
+ Platform arch = (Platform)(int)p_preset->get("architecture/target");
+ String architecture = arch == ARM ? "ARM" : arch == X86 ? "x86" : "x64";
+ result = result.replace("$architecture$", architecture);
- return openssl_error(ERR_peek_last_error());
- }
+ result = result.replace("$display_name$", String(p_preset->get("package/display_name")).empty() ? (String)ProjectSettings::get_singleton()->get("application/config/name") : String(p_preset->get("package/display_name")));
- PKCS7* content = PKCS7_new();
- if (!content) {
+ result = result.replace("$publisher_display_name$", p_preset->get("package/publisher_display_name"));
+ result = result.replace("$app_description$", p_preset->get("package/description"));
+ result = result.replace("$bg_color$", p_preset->get("images/background_color"));
+ result = result.replace("$short_name$", p_preset->get("package/short_name"));
- return openssl_error(ERR_peek_last_error());
- }
+ String name_on_tiles = "";
+ if ((bool)p_preset->get("tiles/show_name_on_square150x150")) {
+ name_on_tiles += " <uap:ShowOn Tile=\"square150x150Logo\" />\n";
+ }
+ if ((bool)p_preset->get("tiles/show_name_on_wide310x150")) {
+ name_on_tiles += " <uap:ShowOn Tile=\"wide310x150Logo\" />\n";
+ }
+ if ((bool)p_preset->get("tiles/show_name_on_square310x310")) {
+ name_on_tiles += " <uap:ShowOn Tile=\"square310x310Logo\" />\n";
+ }
- content->type = OBJ_txt2obj(SPC_INDIRECT_DATA_OBJID, 1);
+ String show_name_on_tiles = "";
+ if (!name_on_tiles.empty()) {
+ show_name_on_tiles = "<uap:ShowNameOnTiles>\n" + name_on_tiles + " </uap:ShowNameOnTiles>";
+ }
- ASN1_TYPE* idc_sequence = idc_encoded.ToSequenceType();
- content->d.other = idc_sequence;
+ result = result.replace("$name_on_tiles$", name_on_tiles);
- if (!PKCS7_set_content(p_out_signature, content)) {
+ String rotations = "";
+ if ((bool)p_preset->get("orientation/landscape")) {
+ rotations += " <uap:Rotation Preference=\"landscape\" />\n";
+ }
+ if ((bool)p_preset->get("orientation/portrait")) {
+ rotations += " <uap:Rotation Preference=\"portrait\" />\n";
+ }
+ if ((bool)p_preset->get("orientation/landscape_flipped")) {
+ rotations += " <uap:Rotation Preference=\"landscapeFlipped\" />\n";
+ }
+ if ((bool)p_preset->get("orientation/portrait_flipped")) {
+ rotations += " <uap:Rotation Preference=\"portraitFlipped\" />\n";
+ }
- return openssl_error(ERR_peek_last_error());
- }
+ String rotation_preference = "";
+ if (!rotations.empty()) {
+ rotation_preference = "<uap:InitialRotationPreference>\n" + rotations + " </uap:InitialRotationPreference>";
+ }
- return OK;
-}
+ result = result.replace("$rotation_preference$", rotation_preference);
-#endif // OPENSSL_ENABLED
+ String capabilities_elements = "";
+ const char **basic = uwp_capabilities;
+ while (*basic) {
+ if ((bool)p_preset->get("capabilities/" + String(*basic))) {
+ capabilities_elements += " <Capability Name=\"" + String(*basic) + "\" />\n";
+ }
+ basic++;
+ }
+ const char **uap = uwp_uap_capabilities;
+ while (*uap) {
+ if ((bool)p_preset->get("capabilities/" + String(*uap))) {
+ capabilities_elements += " <uap:Capability Name=\"" + String(*uap) + "\" />\n";
+ }
+ uap++;
+ }
+ const char **device = uwp_device_capabilites;
+ while (*device) {
+ if ((bool)p_preset->get("capabilities/" + String(*device))) {
+ capabilities_elements += " <DeviceCapability Name=\"" + String(*device) + "\" />\n";
+ }
+ device++;
+ }
-////////////////////////////////////////////////////////////////////
+ if (!((bool)p_preset->get("capabilities/internetClient")) && p_give_internet) {
+ capabilities_elements += " <Capability Name=\"internetClient\" />\n";
+ }
+ String capabilities_string = "<Capabilities />";
+ if (!capabilities_elements.empty()) {
+ capabilities_string = "<Capabilities>\n" + capabilities_elements + " </Capabilities>";
+ }
-bool EditorExportPlatformUWP::_valid_resource_name(const String &p_name) const {
+ result = result.replace("$capabilities_place$", capabilities_string);
- if (p_name.empty()) return false;
- if (p_name.ends_with(".")) return false;
+ Vector<uint8_t> r_ret;
+ r_ret.resize(result.length());
- static const char* invalid_names[] = {
- "CON","PRN","AUX","NUL","COM1","COM2","COM3","COM4","COM5","COM6","COM7",
- "COM8","COM9","LPT1","LPT2","LPT3","LPT4","LPT5","LPT6","LPT7","LPT8","LPT9",
- NULL
- };
+ for (int i = 0; i < result.length(); i++)
+ r_ret[i] = result.utf8().get(i);
- const char** t = invalid_names;
- while (*t) {
- if (p_name == *t) return false;
- t++;
+ return r_ret;
}
- return true;
-}
+ Vector<uint8_t> _get_image_data(const Ref<EditorExportPreset> &p_preset, const String &p_path) {
-bool EditorExportPlatformUWP::_valid_guid(const String & p_guid) const {
+ Vector<uint8_t> data;
+ StreamTexture *image;
+
+ if (p_path.find("StoreLogo") != -1) {
+ image = p_preset->get("images/store_logo").is_zero() ? NULL : ((Object *)p_preset->get("images/store_logo"))->cast_to<StreamTexture>();
+ } else if (p_path.find("Square44x44Logo") != -1) {
+ image = p_preset->get("images/square44x44_logo").is_zero() ? NULL : ((Object *)p_preset->get("images/square44x44_logo"))->cast_to<StreamTexture>();
+ } else if (p_path.find("Square71x71Logo") != -1) {
+ image = p_preset->get("images/square71x71_logo").is_zero() ? NULL : ((Object *)p_preset->get("images/square71x71_logo"))->cast_to<StreamTexture>();
+ } else if (p_path.find("Square150x150Logo") != -1) {
+ image = p_preset->get("images/square150x150_logo").is_zero() ? NULL : ((Object *)p_preset->get("images/square150x150_logo"))->cast_to<StreamTexture>();
+ } else if (p_path.find("Square310x310Logo") != -1) {
+ image = p_preset->get("images/square310x310_logo").is_zero() ? NULL : ((Object *)p_preset->get("images/square310x310_logo"))->cast_to<StreamTexture>();
+ } else if (p_path.find("Wide310x150Logo") != -1) {
+ image = p_preset->get("images/wide310x150_logo").is_zero() ? NULL : ((Object *)p_preset->get("images/wide310x150_logo"))->cast_to<StreamTexture>();
+ } else if (p_path.find("SplashScreen") != -1) {
+ image = p_preset->get("images/splash_screen").is_zero() ? NULL : ((Object *)p_preset->get("images/splash_screen"))->cast_to<StreamTexture>();
+ }
- Vector<String> parts = p_guid.split("-");
+ if (!image) return data;
- if (parts.size() != 5) return false;
- if (parts[0].length() != 8) return false;
- for (int i = 1; i < 4; i++)
- if (parts[i].length() != 4) return false;
- if (parts[4].length() != 12) return false;
+ String tmp_path = EditorSettings::get_singleton()->get_settings_path().plus_file("tmp/uwp_tmp_logo.png");
- return true;
-}
+ Error err = image->get_data()->save_png(tmp_path);
-bool EditorExportPlatformUWP::_valid_bgcolor(const String & p_color) const {
-
- if (p_color.empty()) return true;
- if (p_color.begins_with("#") && p_color.is_valid_html_color()) return true;
-
- // Colors from https://msdn.microsoft.com/en-us/library/windows/apps/dn934817.aspx
- static const char* valid_colors[] = {
- "aliceBlue","antiqueWhite","aqua","aquamarine","azure","beige",
- "bisque","black","blanchedAlmond","blue","blueViolet","brown",
- "burlyWood","cadetBlue","chartreuse","chocolate","coral","cornflowerBlue",
- "cornsilk","crimson","cyan","darkBlue","darkCyan","darkGoldenrod",
- "darkGray","darkGreen","darkKhaki","darkMagenta","darkOliveGreen","darkOrange",
- "darkOrchid","darkRed","darkSalmon","darkSeaGreen","darkSlateBlue","darkSlateGray",
- "darkTurquoise","darkViolet","deepPink","deepSkyBlue","dimGray","dodgerBlue",
- "firebrick","floralWhite","forestGreen","fuchsia","gainsboro","ghostWhite",
- "gold","goldenrod","gray","green","greenYellow","honeydew",
- "hotPink","indianRed","indigo","ivory","khaki","lavender",
- "lavenderBlush","lawnGreen","lemonChiffon","lightBlue","lightCoral","lightCyan",
- "lightGoldenrodYellow","lightGreen","lightGray","lightPink","lightSalmon","lightSeaGreen",
- "lightSkyBlue","lightSlateGray","lightSteelBlue","lightYellow","lime","limeGreen",
- "linen","magenta","maroon","mediumAquamarine","mediumBlue","mediumOrchid",
- "mediumPurple","mediumSeaGreen","mediumSlateBlue","mediumSpringGreen","mediumTurquoise","mediumVioletRed",
- "midnightBlue","mintCream","mistyRose","moccasin","navajoWhite","navy",
- "oldLace","olive","oliveDrab","orange","orangeRed","orchid",
- "paleGoldenrod","paleGreen","paleTurquoise","paleVioletRed","papayaWhip","peachPuff",
- "peru","pink","plum","powderBlue","purple","red",
- "rosyBrown","royalBlue","saddleBrown","salmon","sandyBrown","seaGreen",
- "seaShell","sienna","silver","skyBlue","slateBlue","slateGray",
- "snow","springGreen","steelBlue","tan","teal","thistle",
- "tomato","transparent","turquoise","violet","wheat","white",
- "whiteSmoke","yellow","yellowGreen",
- NULL
- };
+ if (err != OK) {
- const char** color = valid_colors;
+ String err_string = "Couldn't save temp logo file.";
- while(*color) {
- if (p_color == *color) return true;
- color++;
- }
+ EditorNode::add_io_error(err_string);
+ ERR_EXPLAIN(err_string);
+ ERR_FAIL_V(data);
+ }
- return false;
-}
+ FileAccess *f = FileAccess::open(tmp_path, FileAccess::READ, &err);
-bool EditorExportPlatformUWP::_valid_image(const Ref<ImageTexture> p_image, int p_width, int p_height) const {
+ if (err != OK) {
- if (!p_image.is_valid()) return false;
+ String err_string = "Couldn't open temp logo file.";
- // TODO: Add resource creation or image rescaling to enable other scales:
- // 1.25, 1.5, 2.0
- real_t scales[] = { 1.0 };
- bool valid_w = false;
- bool valid_h = false;
+ EditorNode::add_io_error(err_string);
+ ERR_EXPLAIN(err_string);
+ ERR_FAIL_V(data);
+ }
- for (int i = 0; i < 1; i++) {
+ data.resize(f->get_len());
+ f->get_buffer(data.ptr(), data.size());
- int w = ceil(p_width * scales[i]);
- int h = ceil(p_height * scales[i]);
+ f->close();
+ memdelete(f);
- if (w == p_image->get_width())
- valid_w = true;
- if (h == p_image->get_height())
- valid_h = true;
- }
+ // Delete temp file
+ DirAccess *dir = DirAccess::open(tmp_path.get_base_dir(), &err);
- return valid_w && valid_h;
-}
+ if (err != OK) {
-Vector<uint8_t> EditorExportPlatformUWP::_fix_manifest(const Vector<uint8_t> &p_template, bool p_give_internet) const {
+ String err_string = "Couldn't open temp path to remove temp logo file.";
- String result = String::utf8((const char*)p_template.ptr(), p_template.size());
+ EditorNode::add_io_error(err_string);
+ ERR_EXPLAIN(err_string);
+ ERR_FAIL_V(data);
+ }
- result = result.replace("$godot_version$", VERSION_FULL_NAME);
+ err = dir->remove(tmp_path);
- result = result.replace("$identity_name$", unique_name);
- result = result.replace("$publisher$", publisher);
+ memdelete(dir);
- result = result.replace("$product_guid$", product_guid);
- result = result.replace("$publisher_guid$", publisher_guid);
+ if (err != OK) {
- String version = itos(version_major) + "." + itos(version_minor) + "." + itos(version_build) + "." + itos(version_revision);
- result = result.replace("$version_string$", version);
+ String err_string = "Couldn't remove temp logo file.";
- String architecture = arch == ARM ? "ARM" : arch == X86 ? "x86" : "x64";
- result = result.replace("$architecture$", architecture);
+ EditorNode::add_io_error(err_string);
+ ERR_EXPLAIN(err_string);
+ ERR_FAIL_V(data);
+ }
- result = result.replace("$display_name$", display_name.empty() ? (String)GlobalConfig::get_singleton()->get("application/name") : display_name);
- result = result.replace("$publisher_display_name$", publisher_display_name);
- result = result.replace("$app_description$", description);
- result = result.replace("$bg_color$", background_color);
- result = result.replace("$short_name$", short_name);
+ return data;
+ }
+
+ static bool _should_compress_asset(const String &p_path, const Vector<uint8_t> &p_data) {
+
+ /* TODO: This was copied verbatim from Android export. It should be
+ * refactored to the parent class and also be used for .zip export.
+ */
+
+ /*
+ * By not compressing files with little or not benefit in doing so,
+ * a performance gain is expected at runtime. Moreover, if the APK is
+ * zip-aligned, assets stored as they are can be efficiently read by
+ * Android by memory-mapping them.
+ */
+
+ // -- Unconditional uncompress to mimic AAPT plus some other
+
+ static const char *unconditional_compress_ext[] = {
+ // From https://github.com/android/platform_frameworks_base/blob/master/tools/aapt/Package.cpp
+ // These formats are already compressed, or don't compress well:
+ ".jpg", ".jpeg", ".png", ".gif",
+ ".wav", ".mp2", ".mp3", ".ogg", ".aac",
+ ".mpg", ".mpeg", ".mid", ".midi", ".smf", ".jet",
+ ".rtttl", ".imy", ".xmf", ".mp4", ".m4a",
+ ".m4v", ".3gp", ".3gpp", ".3g2", ".3gpp2",
+ ".amr", ".awb", ".wma", ".wmv",
+ // Godot-specific:
+ ".webp", // Same reasoning as .png
+ ".cfb", // Don't let small config files slow-down startup
+ ".scn", // Binary scenes are usually already compressed
+ ".stex", // Streamable textures are usually already compressed
+ // Trailer for easier processing
+ NULL
+ };
+
+ for (const char **ext = unconditional_compress_ext; *ext; ++ext) {
+ if (p_path.to_lower().ends_with(String(*ext))) {
+ return false;
+ }
+ }
- String name_on_tiles = "";
- if (name_on_square150) {
- name_on_tiles += " <uap:ShowOn Tile=\"square150x150Logo\" />\n";
- }
- if (name_on_wide) {
- name_on_tiles += " <uap:ShowOn Tile=\"wide310x150Logo\" />\n";
- }
- if (name_on_square310) {
- name_on_tiles += " <uap:ShowOn Tile=\"square310x310Logo\" />\n";
- }
+ // -- Compressed resource?
- String show_name_on_tiles = "";
- if (!name_on_tiles.empty()) {
- show_name_on_tiles = "<uap:ShowNameOnTiles>\n" + name_on_tiles + " </uap:ShowNameOnTiles>";
- }
+ if (p_data.size() >= 4 && p_data[0] == 'R' && p_data[1] == 'S' && p_data[2] == 'C' && p_data[3] == 'C') {
+ // Already compressed
+ return false;
+ }
- result = result.replace("$name_on_tiles$", name_on_tiles);
+ // --- TODO: Decide on texture resources according to their image compression setting
- String rotations = "";
- if (orientation_landscape) {
- rotations += " <uap:Rotation Preference=\"landscape\" />\n";
- }
- if (orientation_portrait) {
- rotations += " <uap:Rotation Preference=\"portrait\" />\n";
- }
- if (orientation_landscape_flipped) {
- rotations += " <uap:Rotation Preference=\"landscapeFlipped\" />\n";
- }
- if (orientation_portrait_flipped) {
- rotations += " <uap:Rotation Preference=\"portraitFlipped\" />\n";
+ return true;
}
- String rotation_preference = "";
- if (!rotations.empty()) {
- rotation_preference = "<uap:InitialRotationPreference>\n" + rotations + " </uap:InitialRotationPreference>";
- }
+ static Error save_appx_file(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total) {
- result = result.replace("$rotation_preference$", rotation_preference);
+ AppxPackager *packager = (AppxPackager *)p_userdata;
+ String dst_path = p_path.replace_first("res://", "game/");
- String capabilities_elements = "";
- const char **basic = uwp_capabilities;
- while (*basic) {
- if (capabilities.has(*basic)) {
- capabilities_elements += " <Capability Name=\"" + String(*basic) + "\" />\n";
- }
- basic++;
- }
- const char **uap = uwp_uap_capabilities;
- while (*uap) {
- if (uap_capabilities.has(*uap)) {
- capabilities_elements += " <uap:Capability Name=\"" + String(*uap) + "\" />\n";
- }
- uap++;
- }
- const char **device = uwp_device_capabilites;
- while (*device) {
- if (uap_capabilities.has(*device)) {
- capabilities_elements += " <DeviceCapability Name=\"" + String(*device) + "\" />\n";
- }
- device++;
- }
+ packager->add_file(dst_path, p_data.ptr(), p_data.size(), p_file, p_total, _should_compress_asset(p_path, p_data));
- if (!capabilities.has("internetClient") && p_give_internet) {
- capabilities_elements += " <Capability Name=\"internetClient\" />\n";
+ return OK;
}
- String capabilities_string = "<Capabilities />";
- if (!capabilities_elements.empty()) {
- capabilities_string = "<Capabilities>\n" + capabilities_elements + " </Capabilities>";
+public:
+ virtual String get_name() const {
+ return "Windows Universal";
}
-
- result = result.replace("$capabilities_place$", capabilities_string);
-
- Vector<uint8_t> r_ret;
- r_ret.resize(result.length());
-
- for (int i = 0; i < result.length(); i++)
- r_ret[i] = result.utf8().get(i);
-
- return r_ret;
-}
-
-Vector<uint8_t> EditorExportPlatformUWP::_get_image_data(const String & p_path) {
-
- Vector<uint8_t> data;
- Ref<ImageTexture> ref;
-
- if (p_path.find("StoreLogo") != -1) {
- ref = store_logo;
- } else if (p_path.find("Square44x44Logo") != -1) {
- ref = square44;
- } else if (p_path.find("Square71x71Logo") != -1) {
- ref = square71;
- } else if (p_path.find("Square150x150Logo") != -1) {
- ref = square150;
- } else if (p_path.find("Square310x310Logo") != -1) {
- ref = square310;
- } else if (p_path.find("Wide310x150Logo") != -1) {
- ref = wide310;
- } else if (p_path.find("SplashScreen") != -1) {
- ref = splash;
+ virtual String get_os_name() const {
+ return "UWP";
}
- if (!ref.is_valid()) return data;
-
-
- String tmp_path = EditorSettings::get_singleton()->get_settings_path().plus_file("tmp/uwp_tmp_logo.png");
-
- Error err = ref->get_data().save_png(tmp_path);
-
- if (err != OK) {
-
- String err_string = "Couldn't save temp logo file.";
-
- EditorNode::add_io_error(err_string);
- ERR_EXPLAIN(err_string);
- ERR_FAIL_V(data);
+ virtual String get_binary_extension() const {
+ return "appx";
}
- FileAccess* f = FileAccess::open(tmp_path, FileAccess::READ, &err);
-
- if (err != OK) {
-
- String err_string = "Couldn't open temp logo file.";
-
- EditorNode::add_io_error(err_string);
- ERR_EXPLAIN(err_string);
- ERR_FAIL_V(data);
+ virtual Ref<Texture> get_logo() const {
+ return logo;
}
- data.resize(f->get_len());
- f->get_buffer(data.ptr(), data.size());
-
- f->close();
- memdelete(f);
-
- // Delete temp file
- DirAccess* dir = DirAccess::open(tmp_path.get_base_dir(), &err);
-
- if (err != OK) {
-
- String err_string = "Couldn't open temp path to remove temp logo file.";
-
- EditorNode::add_io_error(err_string);
- ERR_EXPLAIN(err_string);
- ERR_FAIL_V(data);
+ virtual void get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) {
+ r_features->push_back("s3tc");
+ r_features->push_back("etc");
}
- err = dir->remove(tmp_path);
-
- memdelete(dir);
+ virtual void get_export_options(List<ExportOption> *r_options) {
+ r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "architecture/target", PROPERTY_HINT_ENUM, "ARM,x86,x64"), 1));
- if (err != OK) {
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "command_line/extra_args"), ""));
- String err_string = "Couldn't remove temp logo file.";
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "package/display_name"), ""));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "package/short_name"), "Godot"));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "package/unique_name"), "Godot.Engine"));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "package/description"), "Godot Engine"));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "package/publisher"), "CN=GodotEngine"));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "package/publisher_display_name"), "Godot Engine"));
- EditorNode::add_io_error(err_string);
- ERR_EXPLAIN(err_string);
- ERR_FAIL_V(data);
- }
-
- return data;
-}
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "identity/product_guid"), "00000000-0000-0000-0000-000000000000"));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "identity/publisher_guid"), "00000000-0000-0000-0000-000000000000"));
-Error EditorExportPlatformUWP::save_appx_file(void * p_userdata, const String & p_path, const Vector<uint8_t>& p_data, int p_file, int p_total) {
+ r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "version/major"), 1));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "version/minor"), 0));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "version/build"), 0));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "version/revision"), 0));
- AppxPackager *packager = (AppxPackager*)p_userdata;
- String dst_path = p_path.replace_first("res://", "game/");
+ r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "orientation/landscape"), true));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "orientation/portrait"), true));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "orientation/landscape_flipped"), true));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "orientation/portrait_flipped"), true));
- packager->add_file(dst_path, p_data.ptr(), p_data.size(), p_file, p_total, _should_compress_asset(p_path, p_data));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "images/background_color"), "transparent"));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::OBJECT, "images/store_logo", PROPERTY_HINT_RESOURCE_TYPE, "StreamTexture"), Variant()));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::OBJECT, "images/square44x44_logo", PROPERTY_HINT_RESOURCE_TYPE, "StreamTexture"), Variant()));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::OBJECT, "images/square71x71_logo", PROPERTY_HINT_RESOURCE_TYPE, "StreamTexture"), Variant()));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::OBJECT, "images/square150x150_logo", PROPERTY_HINT_RESOURCE_TYPE, "StreamTexture"), Variant()));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::OBJECT, "images/square310x310_logo", PROPERTY_HINT_RESOURCE_TYPE, "StreamTexture"), Variant()));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::OBJECT, "images/wide310x150_logo", PROPERTY_HINT_RESOURCE_TYPE, "StreamTexture"), Variant()));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::OBJECT, "images/splash_screen", PROPERTY_HINT_RESOURCE_TYPE, "StreamTexture"), Variant()));
- return OK;
-}
+ r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "tiles/show_name_on_square150x150"), false));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "tiles/show_name_on_wide310x150"), false));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "tiles/show_name_on_square310x310"), false));
-bool EditorExportPlatformUWP::_should_compress_asset(const String & p_path, const Vector<uint8_t>& p_data) {
-
- /* TODO: This was copied verbatim from Android export. It should be
- * refactored to the parent class and also be used for .zip export.
- */
-
- /*
- * By not compressing files with little or not benefit in doing so,
- * a performance gain is expected at runtime. Moreover, if the APK is
- * zip-aligned, assets stored as they are can be efficiently read by
- * Android by memory-mapping them.
- */
-
- // -- Unconditional uncompress to mimic AAPT plus some other
-
- static const char* unconditional_compress_ext[] = {
- // From https://github.com/android/platform_frameworks_base/blob/master/tools/aapt/Package.cpp
- // These formats are already compressed, or don't compress well:
- ".jpg", ".jpeg", ".png", ".gif",
- ".wav", ".mp2", ".mp3", ".ogg", ".aac",
- ".mpg", ".mpeg", ".mid", ".midi", ".smf", ".jet",
- ".rtttl", ".imy", ".xmf", ".mp4", ".m4a",
- ".m4v", ".3gp", ".3gpp", ".3g2", ".3gpp2",
- ".amr", ".awb", ".wma", ".wmv",
- // Godot-specific:
- ".webp", // Same reasoning as .png
- ".cfb", // Don't let small config files slow-down startup
- // Trailer for easier processing
- NULL
- };
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_template/debug", PROPERTY_HINT_GLOBAL_FILE, "zip"), ""));
+ r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_template/release", PROPERTY_HINT_GLOBAL_FILE, "zip"), ""));
- for (const char** ext = unconditional_compress_ext; *ext; ++ext) {
- if (p_path.to_lower().ends_with(String(*ext))) {
- return false;
+ // Capabilites
+ const char **basic = uwp_capabilities;
+ while (*basic) {
+ r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "capabilities/" + String(*basic).camelcase_to_underscore(false)), false));
+ basic++;
}
- }
- // -- Compressed resource?
+ const char **uap = uwp_uap_capabilities;
+ while (*uap) {
+ r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "capabilities/" + String(*uap).camelcase_to_underscore(false)), false));
+ uap++;
+ }
- if (p_data.size() >= 4 && p_data[0] == 'R' && p_data[1] == 'S' && p_data[2] == 'C' && p_data[3] == 'C') {
- // Already compressed
- return false;
+ const char **device = uwp_device_capabilites;
+ while (*device) {
+ r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "capabilities/" + String(*device).camelcase_to_underscore(false)), false));
+ device++;
+ }
}
- // --- TODO: Decide on texture resources according to their image compression setting
-
- return true;
-}
-
-bool EditorExportPlatformUWP::_set(const StringName& p_name, const Variant& p_value) {
-
- String n = p_name;
-
- if (n == "architecture/target")
- arch = (Platform)((int)p_value);
- else if (n == "custom_package/debug")
- custom_debug_package = p_value;
- else if (n == "custom_package/release")
- custom_release_package = p_value;
- else if (n == "command_line/extra_args")
- cmdline = p_value;
- else if (n == "package/display_name")
- display_name = p_value;
- else if (n == "package/short_name")
- short_name = p_value;
- else if (n == "package/unique_name")
- unique_name = p_value;
- else if (n == "package/description")
- description = p_value;
- else if (n == "package/publisher")
- publisher = p_value;
- else if (n == "package/publisher_display_name")
- publisher_display_name = p_value;
- else if (n == "identity/product_guid")
- product_guid = p_value;
- else if (n == "identity/publisher_guid")
- publisher_guid = p_value;
- else if (n == "version/major")
- version_major = p_value;
- else if (n == "version/minor")
- version_minor = p_value;
- else if (n == "version/build")
- version_build = p_value;
- else if (n == "version/revision")
- version_revision = p_value;
- else if (n == "orientation/landscape")
- orientation_landscape = p_value;
- else if (n == "orientation/portrait")
- orientation_portrait = p_value;
- else if (n == "orientation/landscape_flipped")
- orientation_landscape_flipped = p_value;
- else if (n == "orientation/portrait_flipped")
- orientation_portrait_flipped = p_value;
- else if (n == "images/background_color")
- background_color = p_value;
- else if (n == "images/store_logo")
- store_logo = p_value;
- else if (n == "images/square44x44_logo")
- square44 = p_value;
- else if (n == "images/square71x71_logo")
- square71 = p_value;
- else if (n == "images/square150x150_logo")
- square150 = p_value;
- else if (n == "images/square310x310_logo")
- square310 = p_value;
- else if (n == "images/wide310x150_logo")
- wide310 = p_value;
- else if (n == "images/splash_screen")
- splash = p_value;
- else if (n == "tiles/show_name_on_square150x150")
- name_on_square150 = p_value;
- else if (n == "tiles/show_name_on_wide310x150")
- name_on_wide = p_value;
- else if (n == "tiles/show_name_on_square310x310")
- name_on_square310 = p_value;
-
-#if 0 // Signing disabled
- else if (n == "signing/sign")
- sign_package = p_value;
- else if (n == "signing/certificate_file")
- certificate_path = p_value;
- else if (n == "signing/certificate_password")
- certificate_pass = p_value;
-#endif
- else if (n.begins_with("capabilities/")) {
-
- String what = n.get_slice("/", 1).replace("_", "");
- bool enable = p_value;
-
- if (array_has(uwp_capabilities, what.utf8().get_data())) {
-
- if (enable)
- capabilities.insert(what);
- else
- capabilities.erase(what);
-
- } else if (array_has(uwp_uap_capabilities, what.utf8().get_data())) {
-
- if (enable)
- uap_capabilities.insert(what);
- else
- uap_capabilities.erase(what);
-
- } else if (array_has(uwp_device_capabilites, what.utf8().get_data())) {
-
- if (enable)
- device_capabilities.insert(what);
- else
- device_capabilities.erase(what);
+ virtual bool can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const {
+ String err;
+ bool valid = true;
+ Platform arch = (Platform)(int)(p_preset->get("architecture/target"));
+
+ String custom_debug_binary = p_preset->get("custom_template/debug");
+ String custom_release_binary = p_preset->get("custom_template/release");
+
+ String platform_infix;
+
+ switch (arch) {
+ case EditorExportUWP::ARM: {
+ platform_infix = "arm";
+ } break;
+ case EditorExportUWP::X86: {
+ platform_infix = "x86";
+ } break;
+ case EditorExportUWP::X64: {
+ platform_infix = "x64";
+ } break;
}
- } else return false;
-
- return true;
-}
-bool EditorExportPlatformUWP::_get(const StringName& p_name, Variant &r_ret) const {
-
- String n = p_name;
-
- if (n == "architecture/target")
- r_ret = (int)arch;
- else if (n == "custom_package/debug")
- r_ret = custom_debug_package;
- else if (n == "custom_package/release")
- r_ret = custom_release_package;
- else if (n == "command_line/extra_args")
- r_ret = cmdline;
- else if (n == "package/display_name")
- r_ret = display_name;
- else if (n == "package/short_name")
- r_ret = short_name;
- else if (n == "package/unique_name")
- r_ret = unique_name;
- else if (n == "package/description")
- r_ret = description;
- else if (n == "package/publisher")
- r_ret = publisher;
- else if (n == "package/publisher_display_name")
- r_ret = publisher_display_name;
- else if (n == "identity/product_guid")
- r_ret = product_guid;
- else if (n == "identity/publisher_guid")
- r_ret = publisher_guid;
- else if (n == "version/major")
- r_ret = version_major;
- else if (n == "version/minor")
- r_ret = version_minor;
- else if (n == "version/build")
- r_ret = version_build;
- else if (n == "version/revision")
- r_ret = version_revision;
- else if (n == "orientation/landscape")
- r_ret = orientation_landscape;
- else if (n == "orientation/portrait")
- r_ret = orientation_portrait;
- else if (n == "orientation/landscape_flipped")
- r_ret = orientation_landscape_flipped;
- else if (n == "orientation/portrait_flipped")
- r_ret = orientation_portrait_flipped;
- else if (n == "images/background_color")
- r_ret = background_color;
- else if (n == "images/store_logo")
- r_ret = store_logo;
- else if (n == "images/square44x44_logo")
- r_ret = square44;
- else if (n == "images/square71x71_logo")
- r_ret = square71;
- else if (n == "images/square150x150_logo")
- r_ret = square150;
- else if (n == "images/square310x310_logo")
- r_ret = square310;
- else if (n == "images/wide310x150_logo")
- r_ret = wide310;
- else if (n == "images/splash_screen")
- r_ret = splash;
- else if (n == "tiles/show_name_on_square150x150")
- r_ret = name_on_square150;
- else if (n == "tiles/show_name_on_wide310x150")
- r_ret = name_on_wide;
- else if (n == "tiles/show_name_on_square310x310")
- r_ret = name_on_square310;
-
-#if 0 // Signing disabled
- else if (n == "signing/sign")
- r_ret = sign_package;
- else if (n == "signing/certificate_file")
- r_ret = certificate_path;
- else if (n == "signing/certificate_password")
- r_ret = certificate_pass;
-#endif
- else if (n.begins_with("capabilities/")) {
-
- String what = n.get_slice("/", 1).replace("_", "");
-
- if (array_has(uwp_capabilities, what.utf8().get_data())) {
-
- r_ret = capabilities.has(what);
-
- } else if (array_has(uwp_uap_capabilities, what.utf8().get_data())) {
-
- r_ret = uap_capabilities.has(what);
-
- } else if (array_has(uwp_device_capabilites, what.utf8().get_data())) {
-
- r_ret = device_capabilities.has(what);
+ if (!exists_export_template("uwp_" + platform_infix + "_debug.zip", &err) || !exists_export_template("uwp_" + platform_infix + "_debug.zip", &err)) {
+ valid = false;
+ r_missing_templates = true;
}
- } else return false;
-
- return true;
-}
-
-void EditorExportPlatformUWP::_get_property_list(List<PropertyInfo>* p_list) const {
-
- p_list->push_back(PropertyInfo(Variant::STRING, "custom_package/debug", PROPERTY_HINT_GLOBAL_FILE, "appx"));
- p_list->push_back(PropertyInfo(Variant::STRING, "custom_package/release", PROPERTY_HINT_GLOBAL_FILE, "appx"));
-
- p_list->push_back(PropertyInfo(Variant::INT, "architecture/target", PROPERTY_HINT_ENUM, "ARM,x86,x64"));
-
- p_list->push_back(PropertyInfo(Variant::STRING, "command_line/extra_args"));
-
- p_list->push_back(PropertyInfo(Variant::STRING, "package/display_name"));
- p_list->push_back(PropertyInfo(Variant::STRING, "package/short_name"));
- p_list->push_back(PropertyInfo(Variant::STRING, "package/unique_name"));
- p_list->push_back(PropertyInfo(Variant::STRING, "package/description"));
- p_list->push_back(PropertyInfo(Variant::STRING, "package/publisher"));
- p_list->push_back(PropertyInfo(Variant::STRING, "package/publisher_display_name"));
-
- p_list->push_back(PropertyInfo(Variant::STRING, "identity/product_guid"));
- p_list->push_back(PropertyInfo(Variant::STRING, "identity/publisher_guid"));
-
- p_list->push_back(PropertyInfo(Variant::INT, "version/major"));
- p_list->push_back(PropertyInfo(Variant::INT, "version/minor"));
- p_list->push_back(PropertyInfo(Variant::INT, "version/build"));
- p_list->push_back(PropertyInfo(Variant::INT, "version/revision"));
-
- p_list->push_back(PropertyInfo(Variant::BOOL, "orientation/landscape"));
- p_list->push_back(PropertyInfo(Variant::BOOL, "orientation/portrait"));
- p_list->push_back(PropertyInfo(Variant::BOOL, "orientation/landscape_flipped"));
- p_list->push_back(PropertyInfo(Variant::BOOL, "orientation/portrait_flipped"));
-
- p_list->push_back(PropertyInfo(Variant::STRING, "images/background_color"));
- p_list->push_back(PropertyInfo(Variant::OBJECT, "images/store_logo", PROPERTY_HINT_RESOURCE_TYPE, "ImageTexture"));
- p_list->push_back(PropertyInfo(Variant::OBJECT, "images/square44x44_logo", PROPERTY_HINT_RESOURCE_TYPE, "ImageTexture"));
- p_list->push_back(PropertyInfo(Variant::OBJECT, "images/square71x71_logo", PROPERTY_HINT_RESOURCE_TYPE, "ImageTexture"));
- p_list->push_back(PropertyInfo(Variant::OBJECT, "images/square150x150_logo", PROPERTY_HINT_RESOURCE_TYPE, "ImageTexture"));
- p_list->push_back(PropertyInfo(Variant::OBJECT, "images/square310x310_logo", PROPERTY_HINT_RESOURCE_TYPE, "ImageTexture"));
- p_list->push_back(PropertyInfo(Variant::OBJECT, "images/wide310x150_logo", PROPERTY_HINT_RESOURCE_TYPE, "ImageTexture"));
- p_list->push_back(PropertyInfo(Variant::OBJECT, "images/splash_screen", PROPERTY_HINT_RESOURCE_TYPE, "ImageTexture"));
-
- p_list->push_back(PropertyInfo(Variant::BOOL, "tiles/show_name_on_square150x150"));
- p_list->push_back(PropertyInfo(Variant::BOOL, "tiles/show_name_on_wide310x150"));
- p_list->push_back(PropertyInfo(Variant::BOOL, "tiles/show_name_on_square310x310"));
-
-#if 0 // Signing does not work :( disabling for now
- p_list->push_back(PropertyInfo(Variant::BOOL, "signing/sign"));
- p_list->push_back(PropertyInfo(Variant::STRING, "signing/certificate_file", PROPERTY_HINT_GLOBAL_FILE, "pfx"));
- p_list->push_back(PropertyInfo(Variant::STRING, "signing/certificate_password"));
-#endif
-
- // Capabilites
- const char **basic = uwp_capabilities;
- while (*basic) {
- p_list->push_back(PropertyInfo(Variant::BOOL, "capabilities/" + String(*basic).camelcase_to_underscore(false)));
- basic++;
- }
-
- const char **uap = uwp_uap_capabilities;
- while (*uap) {
- p_list->push_back(PropertyInfo(Variant::BOOL, "capabilities/" + String(*uap).camelcase_to_underscore(false)));
- uap++;
- }
- const char **device = uwp_device_capabilites;
- while (*device) {
- p_list->push_back(PropertyInfo(Variant::BOOL, "capabilities/" + String(*device).camelcase_to_underscore(false)));
- device++;
- }
+ if (!valid && custom_debug_binary == "" && custom_release_binary == "") {
+ if (!err.empty()) {
+ r_error = err;
+ }
+ return valid;
+ }
-}
+ bool dvalid = true;
+ bool rvalid = true;
-bool EditorExportPlatformUWP::can_export(String * r_error) const {
+ if (!FileAccess::exists(custom_debug_binary)) {
+ dvalid = false;
+ err = "\nCustom debug binary not found.";
+ }
- String err;
- bool valid = true;
+ if (!FileAccess::exists(custom_release_binary)) {
+ rvalid = false;
+ err += "\nCustom release binary not found.";
+ }
- if (!exists_export_template("uwp_x86_debug.zip") || !exists_export_template("uwp_x86_release.zip")
- || !exists_export_template("uwp_arm_debug.zip") || !exists_export_template("uwp_arm_release.zip")
- || !exists_export_template("uwp_x64_debug.zip") || !exists_export_template("uwp_x64_release.zip")) {
- valid = false;
- err += TTR("No export templates found.\nDownload and install export templates.") + "\n";
- }
+ if (dvalid || rvalid)
+ valid = true;
- if (custom_debug_package != "" && !FileAccess::exists(custom_debug_package)) {
- valid = false;
- err += TTR("Custom debug package not found.") + "\n";
- }
+ if (!valid) {
+ r_error = err;
+ return valid;
+ }
- if (custom_release_package != "" && !FileAccess::exists(custom_release_package)) {
- valid = false;
- err += TTR("Custom release package not found.") + "\n";
- }
+ if (!_valid_resource_name(p_preset->get("package/unique_name"))) {
+ valid = false;
+ err += "\nInvalid unique name.";
+ }
- if (!_valid_resource_name(unique_name)) {
- valid = false;
- err += TTR("Invalid unique name.") + "\n";
- }
+ if (!_valid_guid(p_preset->get("identity/product_guid"))) {
+ valid = false;
+ err += "\nInvalid product GUID.";
+ }
- if (!_valid_guid(product_guid)) {
- valid = false;
- err += TTR("Invalid product GUID.") + "\n";
- }
+ if (!_valid_guid(p_preset->get("identity/publisher_guid"))) {
+ valid = false;
+ err += "\nInvalid publisher GUID.";
+ }
- if (!_valid_guid(publisher_guid)) {
- valid = false;
- err += TTR("Invalid publisher GUID.") + "\n";
- }
+ if (!_valid_bgcolor(p_preset->get("images/background_color"))) {
+ valid = false;
+ err += "\nInvalid background color.";
+ }
- if (!_valid_bgcolor(background_color)) {
- valid = false;
- err += TTR("Invalid background color.") + "\n";
- }
+ if (!p_preset->get("images/store_logo").is_zero() && !_valid_image(((Object *)p_preset->get("images/store_logo"))->cast_to<StreamTexture>(), 50, 50)) {
+ valid = false;
+ err += "\nInvalid Store Logo image dimensions (should be 50x50).";
+ }
- if (store_logo.is_valid() && !_valid_image(store_logo, 50, 50)) {
- valid = false;
- err += TTR("Invalid Store Logo image dimensions (should be 50x50).") + "\n";
- }
+ if (!p_preset->get("images/square44x44_logo").is_zero() && !_valid_image(((Object *)p_preset->get("images/square44x44_logo"))->cast_to<StreamTexture>(), 44, 44)) {
+ valid = false;
+ err += "\nInvalid square 44x44 logo image dimensions (should be 44x44).";
+ }
- if (square44.is_valid() && !_valid_image(square44, 44, 44)) {
- valid = false;
- err += TTR("Invalid square 44x44 logo image dimensions (should be 44x44).") + "\n";
- }
+ if (!p_preset->get("images/square71x71_logo").is_zero() && !_valid_image(((Object *)p_preset->get("images/square71x71_logo"))->cast_to<StreamTexture>(), 71, 71)) {
+ valid = false;
+ err += "\nInvalid square 71x71 logo image dimensions (should be 71x71).";
+ }
- if (square71.is_valid() && !_valid_image(square71, 71, 71)) {
- valid = false;
- err += TTR("Invalid square 71x71 logo image dimensions (should be 71x71).") + "\n";
- }
+ if (!p_preset->get("images/square150x150_logo").is_zero() && !_valid_image(((Object *)p_preset->get("images/square150x150_logo"))->cast_to<StreamTexture>(), 150, 0)) {
+ valid = false;
+ err += "\nInvalid square 150x150 logo image dimensions (should be 150x150).";
+ }
- if (square150.is_valid() && !_valid_image(square150, 150, 150)) {
- valid = false;
- err += TTR("Invalid square 150x150 logo image dimensions (should be 150x150).") + "\n";
- }
+ if (!p_preset->get("images/square310x310_logo").is_zero() && !_valid_image(((Object *)p_preset->get("images/square310x310_logo"))->cast_to<StreamTexture>(), 310, 310)) {
+ valid = false;
+ err += "\nInvalid square 310x310 logo image dimensions (should be 310x310).";
+ }
- if (square310.is_valid() && !_valid_image(square310, 310, 310)) {
- valid = false;
- err += TTR("Invalid square 310x310 logo image dimensions (should be 310x310).") + "\n";
- }
+ if (!p_preset->get("images/wide310x150_logo").is_zero() && !_valid_image(((Object *)p_preset->get("images/wide310x150_logo"))->cast_to<StreamTexture>(), 310, 150)) {
+ valid = false;
+ err += "\nInvalid wide 310x150 logo image dimensions (should be 310x150).";
+ }
- if (wide310.is_valid() && !_valid_image(wide310, 310, 150)) {
- valid = false;
- err += TTR("Invalid wide 310x150 logo image dimensions (should be 310x150).") + "\n";
- }
+ if (!p_preset->get("images/splash_screen").is_zero() && !_valid_image(((Object *)p_preset->get("images/splash_screen"))->cast_to<StreamTexture>(), 620, 300)) {
+ valid = false;
+ err += "\nInvalid splash screen image dimensions (should be 620x300).";
+ }
- if (splash.is_valid() && !_valid_image(splash, 620, 300)) {
- valid = false;
- err += TTR("Invalid splash screen image dimensions (should be 620x300).") + "\n";
+ r_error = err;
+ return valid;
}
- if (r_error)
- *r_error = err;
+ virtual Error export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags = 0) {
- return valid;
-}
+ String src_appx;
-Error EditorExportPlatformUWP::export_project(const String & p_path, bool p_debug, int p_flags) {
+ EditorProgress ep("export", "Exporting for Windows Universal", 7);
- String src_appx;
+ if (p_debug)
+ src_appx = p_preset->get("custom_template/debug");
+ else
+ src_appx = p_preset->get("custom_template/release");
- EditorProgress ep("export", "Exporting for Windows Universal", 7);
+ src_appx = src_appx.strip_edges();
- if (is_debug)
- src_appx = custom_debug_package;
- else
- src_appx = custom_release_package;
+ Platform arch = (Platform)(int)p_preset->get("architecture/target");
- if (src_appx == "") {
- String err;
- if (p_debug) {
+ if (src_appx == "") {
+ String err, infix;
switch (arch) {
- case X86: {
- src_appx = find_export_template("uwp_x86_debug.zip", &err);
- break;
- }
- case X64: {
- src_appx = find_export_template("uwp_x64_debug.zip", &err);
- break;
- }
case ARM: {
- src_appx = find_export_template("uwp_arm_debug.zip", &err);
- break;
- }
- }
- } else {
- switch (arch) {
+ infix = "_arm_";
+ } break;
case X86: {
- src_appx = find_export_template("uwp_x86_release.zip", &err);
- break;
- }
+ infix = "_x86_";
+ } break;
case X64: {
- src_appx = find_export_template("uwp_x64_release.zip", &err);
- break;
- }
- case ARM: {
- src_appx = find_export_template("uwp_arm_release.zip", &err);
- break;
- }
+ infix = "_x64_";
+ } break;
+ }
+ if (p_debug) {
+ src_appx = find_export_template("uwp" + infix + "debug.zip", &err);
+ } else {
+ src_appx = find_export_template("uwp" + infix + "release.zip", &err);
+ }
+ if (src_appx == "") {
+ EditorNode::add_io_error(err);
+ return ERR_FILE_NOT_FOUND;
}
}
- if (src_appx == "") {
- EditorNode::add_io_error(err);
- return ERR_FILE_NOT_FOUND;
- }
- }
- Error err = OK;
+ Error err = OK;
- FileAccess *fa_pack = FileAccess::open(p_path, FileAccess::WRITE, &err);
- ERR_FAIL_COND_V(err != OK, ERR_CANT_CREATE);
+ FileAccess *fa_pack = FileAccess::open(p_path, FileAccess::WRITE, &err);
+ ERR_FAIL_COND_V(err != OK, ERR_CANT_CREATE);
- AppxPackager packager;
- packager.init(fa_pack, sign_package ? AppxPackager::SIGN : AppxPackager::DONT_SIGN, certificate_path, certificate_pass);
+ AppxPackager packager;
+ packager.init(fa_pack);
- FileAccess *src_f = NULL;
- zlib_filefunc_def io = zipio_create_io_from_file(&src_f);
+ FileAccess *src_f = NULL;
+ zlib_filefunc_def io = zipio_create_io_from_file(&src_f);
- ep.step("Creating package...", 0);
+ ep.step("Creating package...", 0);
- unzFile pkg = unzOpen2(src_appx.utf8().get_data(), &io);
+ unzFile pkg = unzOpen2(src_appx.utf8().get_data(), &io);
- if (!pkg) {
+ if (!pkg) {
- EditorNode::add_io_error("Could not find template appx to export:\n" + src_appx);
- return ERR_FILE_NOT_FOUND;
- }
-
- int ret = unzGoToFirstFile(pkg);
-
- ep.step("Copying template files...", 1);
-
- EditorNode::progress_add_task("template_files", "Template files", 100);
- packager.set_progress_task("template_files");
-
- int template_files_amount = 9;
- int template_file_no = 1;
-
- while (ret == UNZ_OK) {
-
- // get file name
- unz_file_info info;
- char fname[16834];
- ret = unzGetCurrentFileInfo(pkg, &info, fname, 16834, NULL, 0, NULL, 0);
-
- String path = fname;
-
- if (path.ends_with("/")) {
- // Ignore directories
- ret = unzGoToNextFile(pkg);
- continue;
+ EditorNode::add_io_error("Could not find template appx to export:\n" + src_appx);
+ return ERR_FILE_NOT_FOUND;
}
- Vector<uint8_t> data;
- bool do_read = true;
-
- if (path.begins_with("Assets/")) {
+ int ret = unzGoToFirstFile(pkg);
- path = path.replace(".scale-100", "");
+ ep.step("Copying template files...", 1);
- data = _get_image_data(path);
- if (data.size() > 0) do_read = false;
- }
+ EditorNode::progress_add_task("template_files", "Template files", 100);
+ packager.set_progress_task("template_files");
- //read
- if (do_read) {
- data.resize(info.uncompressed_size);
- unzOpenCurrentFile(pkg);
- unzReadCurrentFile(pkg, data.ptr(), data.size());
- unzCloseCurrentFile(pkg);
- }
+ int template_files_amount = 9;
+ int template_file_no = 1;
- if (path == "AppxManifest.xml") {
+ while (ret == UNZ_OK) {
- data = _fix_manifest(data, p_flags&(EXPORT_DUMB_CLIENT | EXPORT_REMOTE_DEBUG));
- }
+ // get file name
+ unz_file_info info;
+ char fname[16834];
+ ret = unzGetCurrentFileInfo(pkg, &info, fname, 16834, NULL, 0, NULL, 0);
- print_line("ADDING: " + path);
+ String path = fname;
- packager.add_file(path, data.ptr(), data.size(), template_file_no++, template_files_amount, _should_compress_asset(path, data));
+ if (path.ends_with("/")) {
+ // Ignore directories
+ ret = unzGoToNextFile(pkg);
+ continue;
+ }
- ret = unzGoToNextFile(pkg);
- }
+ Vector<uint8_t> data;
+ bool do_read = true;
- EditorNode::progress_end_task("template_files");
+ if (path.begins_with("Assets/")) {
- ep.step("Creating command line...", 2);
+ path = path.replace(".scale-100", "");
- Vector<String> cl = cmdline.strip_edges().split(" ");
- for (int i = 0;i<cl.size();i++) {
- if (cl[i].strip_edges().length() == 0) {
- cl.remove(i);
- i--;
- }
- }
-
- if (!(p_flags & EXPORT_DUMB_CLIENT)) {
- cl.push_back("-path");
- cl.push_back("game");
- }
+ data = _get_image_data(p_preset, path);
+ if (data.size() > 0) do_read = false;
+ }
- gen_export_flags(cl, p_flags);
+ //read
+ if (do_read) {
+ data.resize(info.uncompressed_size);
+ unzOpenCurrentFile(pkg);
+ unzReadCurrentFile(pkg, data.ptr(), data.size());
+ unzCloseCurrentFile(pkg);
+ }
- // Command line file
- Vector<uint8_t> clf;
+ if (path == "AppxManifest.xml") {
- // Argc
- clf.resize(4);
- encode_uint32(cl.size(), clf.ptr());
+ data = _fix_manifest(p_preset, data, p_flags & (DEBUG_FLAG_DUMB_CLIENT | DEBUG_FLAG_REMOTE_DEBUG));
+ }
- for (int i = 0; i < cl.size(); i++) {
+ print_line("ADDING: " + path);
- 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]);
- }
+ packager.add_file(path, data.ptr(), data.size(), template_file_no++, template_files_amount, _should_compress_asset(path, data));
- packager.add_file("__cl__.cl", clf.ptr(), clf.size(), -1, -1, false);
+ ret = unzGoToNextFile(pkg);
+ }
- ep.step("Adding project files...", 3);
+ EditorNode::progress_end_task("template_files");
- EditorNode::progress_add_task("project_files", "Project Files", 100);
- packager.set_progress_task("project_files");
+ ep.step("Creating command line...", 2);
- err = export_project_files(save_appx_file, &packager, false);
+ Vector<String> cl = ((String)p_preset->get("command_line/extra_args")).strip_edges().split(" ");
+ for (int i = 0; i < cl.size(); i++) {
+ if (cl[i].strip_edges().length() == 0) {
+ cl.remove(i);
+ i--;
+ }
+ }
- EditorNode::progress_end_task("project_files");
+ if (!(p_flags & DEBUG_FLAG_DUMB_CLIENT)) {
+ cl.push_back("-path");
+ cl.push_back("game");
+ }
- ep.step("Closing package...", 7);
+ gen_export_flags(cl, p_flags);
- unzClose(pkg);
+ // Command line file
+ Vector<uint8_t> clf;
- packager.finish();
+ // Argc
+ clf.resize(4);
+ encode_uint32(cl.size(), clf.ptr());
- return OK;
-}
+ for (int i = 0; i < cl.size(); i++) {
-EditorExportPlatformUWP::EditorExportPlatformUWP() {
+ 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]);
+ }
- Image img(_uwp_logo);
- logo = Ref<ImageTexture>(memnew(ImageTexture));
- logo->create_from_image(img);
+ packager.add_file("__cl__.cl", clf.ptr(), clf.size(), -1, -1, false);
- is_debug = true;
+ ep.step("Adding project files...", 3);
- custom_release_package = "";
- custom_debug_package = "";
+ EditorNode::progress_add_task("project_files", "Project Files", 100);
+ packager.set_progress_task("project_files");
- arch = X86;
+ err = export_project_files(p_preset, save_appx_file, &packager);
- display_name = "";
- short_name = "Godot";
- unique_name = "Godot.Engine";
- description = "Godot Engine";
- publisher = "CN=GodotEngine";
- publisher_display_name = "Godot Engine";
+ EditorNode::progress_end_task("project_files");
- product_guid = "00000000-0000-0000-0000-000000000000";
- publisher_guid = "00000000-0000-0000-0000-000000000000";
+ ep.step("Closing package...", 7);
- version_major = 1;
- version_minor = 0;
- version_build = 0;
- version_revision = 0;
+ unzClose(pkg);
- orientation_landscape = true;
- orientation_portrait = true;
- orientation_landscape_flipped = true;
- orientation_portrait_flipped = true;
+ packager.finish();
- background_color = "transparent";
+ return OK;
+ }
- name_on_square150 = false;
- name_on_square310 = false;
- name_on_wide = false;
+ virtual void get_platform_features(List<String> *r_features) {
- sign_package = false;
- certificate_path = "";
- certificate_pass = "";
-}
+ r_features->push_back("pc");
+ r_features->push_back("UWP");
+ }
-EditorExportPlatformUWP::~EditorExportPlatformUWP() {}
+ EditorExportUWP() {
+ Ref<Image> img = memnew(Image(_uwp_logo));
+ logo.instance();
+ logo->create_from_image(img);
+ }
+};
-#endif
void register_uwp_exporter() {
-#if 0
- Ref<EditorExportPlatformUWP> exporter = Ref<EditorExportPlatformUWP>(memnew(EditorExportPlatformUWP));
- EditorImportExport::get_singleton()->add_export_platform(exporter);
-#endif
+ Ref<EditorExportUWP> exporter = Ref<EditorExportUWP>(memnew(EditorExportUWP));
+ EditorExport::get_singleton()->add_export_platform(exporter);
}
diff --git a/platform/uwp/export/export.h b/platform/uwp/export/export.h
index 2d6e02bb10..81bd848241 100644
--- a/platform/uwp/export/export.h
+++ b/platform/uwp/export/export.h
@@ -6,6 +6,7 @@
/* http://www.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 */
diff --git a/platform/uwp/gl_context_egl.cpp b/platform/uwp/gl_context_egl.cpp
index 6c9efc26b4..57c4c5d572 100644
--- a/platform/uwp/gl_context_egl.cpp
+++ b/platform/uwp/gl_context_egl.cpp
@@ -6,6 +6,7 @@
/* http://www.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 */
@@ -96,7 +97,7 @@ Error ContextEGL::initialize() {
EGLContext context = EGL_NO_CONTEXT;
EGLSurface surface = EGL_NO_SURFACE;
EGLConfig config = nullptr;
- EGLint contextAttribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE, EGL_NONE };
+ EGLint contextAttribs[] = { EGL_CONTEXT_CLIENT_VERSION, 3, EGL_NONE, EGL_NONE };
try {
diff --git a/platform/uwp/gl_context_egl.h b/platform/uwp/gl_context_egl.h
index c397c1206b..908b8dceec 100644
--- a/platform/uwp/gl_context_egl.h
+++ b/platform/uwp/gl_context_egl.h
@@ -6,6 +6,7 @@
/* http://www.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 */
diff --git a/platform/uwp/joypad_uwp.cpp b/platform/uwp/joypad_uwp.cpp
index dd57ed94ae..f3d4eb99c8 100644
--- a/platform/uwp/joypad_uwp.cpp
+++ b/platform/uwp/joypad_uwp.cpp
@@ -6,6 +6,7 @@
/* http://www.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 */
@@ -28,6 +29,7 @@
/*************************************************************************/
#include "joypad_uwp.h"
+#include "core/os/os.h"
using namespace Windows::Gaming::Input;
using namespace Windows::Foundation;
@@ -40,38 +42,53 @@ void JoypadUWP::register_events() {
ref new EventHandler<Gamepad ^>(this, &JoypadUWP::OnGamepadRemoved);
}
-uint32_t JoypadUWP::process_controllers(uint32_t p_last_id) {
+void JoypadUWP::process_controllers() {
for (int i = 0; i < MAX_CONTROLLERS; i++) {
- if (!controllers[i].connected) break;
+ ControllerDevice &joy = controllers[i];
- switch (controllers[i].type) {
+ if (!joy.connected) break;
+
+ switch (joy.type) {
case ControllerType::GAMEPAD_CONTROLLER: {
- GamepadReading reading = ((Gamepad ^)controllers[i].controller_reference)->GetCurrentReading();
+ GamepadReading reading = ((Gamepad ^) joy.controller_reference)->GetCurrentReading();
int button_mask = (int)GamepadButtons::Menu;
for (int j = 0; j < 14; j++) {
- p_last_id = input->joy_button(p_last_id, controllers[i].id, j, (int)reading.Buttons & button_mask);
+ input->joy_button(joy.id, j, (int)reading.Buttons & button_mask);
button_mask *= 2;
}
- p_last_id = input->joy_axis(p_last_id, controllers[i].id, JOY_AXIS_0, axis_correct(reading.LeftThumbstickX));
- p_last_id = input->joy_axis(p_last_id, controllers[i].id, JOY_AXIS_1, axis_correct(reading.LeftThumbstickY, true));
- p_last_id = input->joy_axis(p_last_id, controllers[i].id, JOY_AXIS_2, axis_correct(reading.RightThumbstickX));
- p_last_id = input->joy_axis(p_last_id, controllers[i].id, JOY_AXIS_3, axis_correct(reading.RightThumbstickY, true));
- p_last_id = input->joy_axis(p_last_id, controllers[i].id, JOY_AXIS_4, axis_correct(reading.LeftTrigger, false, true));
- p_last_id = input->joy_axis(p_last_id, controllers[i].id, JOY_AXIS_5, axis_correct(reading.RightTrigger, false, true));
+ input->joy_axis(joy.id, JOY_AXIS_0, axis_correct(reading.LeftThumbstickX));
+ input->joy_axis(joy.id, JOY_AXIS_1, axis_correct(reading.LeftThumbstickY, true));
+ input->joy_axis(joy.id, JOY_AXIS_2, axis_correct(reading.RightThumbstickX));
+ input->joy_axis(joy.id, JOY_AXIS_3, axis_correct(reading.RightThumbstickY, true));
+ input->joy_axis(joy.id, JOY_AXIS_4, axis_correct(reading.LeftTrigger, false, true));
+ input->joy_axis(joy.id, JOY_AXIS_5, axis_correct(reading.RightTrigger, false, true));
+
+ uint64_t timestamp = input->get_joy_vibration_timestamp(joy.id);
+ if (timestamp > joy.ff_timestamp) {
+ Vector2 strength = input->get_joy_vibration_strength(joy.id);
+ float duration = input->get_joy_vibration_duration(joy.id);
+ if (strength.x == 0 && strength.y == 0) {
+ joypad_vibration_stop(i, timestamp);
+ } else {
+ joypad_vibration_start(i, strength.x, strength.y, duration, timestamp);
+ }
+ } else if (joy.vibrating && joy.ff_end_timestamp != 0) {
+ uint64_t current_time = OS::get_singleton()->get_ticks_usec();
+ if (current_time >= joy.ff_end_timestamp)
+ joypad_vibration_stop(i, current_time);
+ }
break;
}
}
}
-
- return p_last_id;
}
JoypadUWP::JoypadUWP() {
@@ -123,15 +140,7 @@ void JoypadUWP::OnGamepadRemoved(Platform::Object ^ sender, Windows::Gaming::Inp
ERR_FAIL_COND(idx == -1);
- for (int i = idx + 1; i < MAX_CONTROLLERS - 1; i++) {
-
- if (!controllers[i].connected) {
- break;
- }
-
- controllers[i - 1] = controllers[i];
- }
- controllers[MAX_CONTROLLERS - 1] = ControllerDevice();
+ controllers[idx] = ControllerDevice();
input->joy_connection_changed(idx, false, "Xbox Controller");
}
@@ -145,3 +154,30 @@ InputDefault::JoyAxis JoypadUWP::axis_correct(double p_val, bool p_negate, bool
return jx;
}
+
+void JoypadUWP::joypad_vibration_start(int p_device, float p_weak_magnitude, float p_strong_magnitude, float p_duration, uint64_t p_timestamp) {
+ ControllerDevice &joy = controllers[p_device];
+ if (joy.connected) {
+ GamepadVibration vibration;
+ vibration.LeftMotor = p_strong_magnitude;
+ vibration.RightMotor = p_weak_magnitude;
+ ((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);
+ joy.vibrating = true;
+ }
+}
+
+void JoypadUWP::joypad_vibration_stop(int p_device, uint64_t p_timestamp) {
+ ControllerDevice &joy = controllers[p_device];
+ if (joy.connected) {
+ GamepadVibration vibration;
+ vibration.LeftMotor = 0.0;
+ vibration.RightMotor = 0.0;
+ ((Gamepad ^) joy.controller_reference)->Vibration = vibration;
+
+ joy.ff_timestamp = p_timestamp;
+ joy.vibrating = false;
+ }
+}
diff --git a/platform/uwp/joypad_uwp.h b/platform/uwp/joypad_uwp.h
index e5a961e70e..c55e1e7ab7 100644
--- a/platform/uwp/joypad_uwp.h
+++ b/platform/uwp/joypad_uwp.h
@@ -6,6 +6,7 @@
/* http://www.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 */
@@ -37,7 +38,7 @@ ref class JoypadUWP sealed {
/* clang-format off */
internal:
void register_events();
- uint32_t process_controllers(uint32_t p_last_id);
+ void process_controllers();
/* clang-format on */
JoypadUWP();
@@ -61,11 +62,17 @@ private:
int id;
bool connected;
ControllerType type;
+ float ff_timestamp;
+ float ff_end_timestamp;
+ bool vibrating;
ControllerDevice() {
id = -1;
connected = false;
type = ControllerType::GAMEPAD_CONTROLLER;
+ ff_timestamp = 0.0f;
+ ff_end_timestamp = 0.0f;
+ vibrating = false;
}
};
@@ -77,6 +84,8 @@ private:
void OnGamepadRemoved(Platform::Object ^ sender, Windows::Gaming::Input::Gamepad ^ value);
InputDefault::JoyAxis axis_correct(double p_val, bool p_negate = false, bool p_trigger = false) const;
+ void joypad_vibration_start(int p_device, float p_weak_magnitude, float p_strong_magnitude, float p_duration, uint64_t p_timestamp);
+ void joypad_vibration_stop(int p_device, uint64_t p_timestamp);
};
#endif
diff --git a/platform/uwp/os_uwp.cpp b/platform/uwp/os_uwp.cpp
index 19ed2b57a3..fabb227bf5 100644
--- a/platform/uwp/os_uwp.cpp
+++ b/platform/uwp/os_uwp.cpp
@@ -6,6 +6,7 @@
/* http://www.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 */
@@ -27,24 +28,22 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "os_uwp.h"
-#include "drivers/gles2/rasterizer_gles2.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/rw_lock_windows.h"
#include "drivers/windows/semaphore_windows.h"
-#include "main/main.h"
-#include "os/memory_pool_dynamic_static.h"
-#include "servers/audio_server.h"
-#include "servers/visual/visual_server_raster.h"
-#include "thread_uwp.h"
-//#include "servers/visual/visual_server_wrap_mt.h"
-#include "drivers/unix/ip_unix.h"
-#include "global_config.h"
#include "io/marshalls.h"
-#include "os/memory_pool_dynamic_prealloc.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 "project_settings.h"
+#include "servers/audio_server.h"
+#include "servers/visual/visual_server_raster.h"
+#include "thread_uwp.h"
#include <ppltasks.h>
#include <wrl.h>
@@ -148,9 +147,6 @@ const char *OSUWP::get_audio_driver_name(int p_driver) const {
return AudioDriverManager::get_driver(p_driver)->get_name();
}
-static MemoryPoolStatic *mempool_static = NULL;
-static MemoryPoolDynamic *mempool_dynamic = NULL;
-
void OSUWP::initialize_core() {
last_button_state = 0;
@@ -160,32 +156,19 @@ void OSUWP::initialize_core() {
ThreadUWP::make_default();
SemaphoreWindows::make_default();
MutexWindows::make_default();
+ RWLockWindows::make_default();
FileAccess::make_default<FileAccessWindows>(FileAccess::ACCESS_RESOURCES);
FileAccess::make_default<FileAccessWindows>(FileAccess::ACCESS_USERDATA);
FileAccess::make_default<FileAccessWindows>(FileAccess::ACCESS_FILESYSTEM);
- //FileAccessBufferedFA<FileAccessWindows>::make_default();
DirAccess::make_default<DirAccessWindows>(DirAccess::ACCESS_RESOURCES);
DirAccess::make_default<DirAccessWindows>(DirAccess::ACCESS_USERDATA);
DirAccess::make_default<DirAccessWindows>(DirAccess::ACCESS_FILESYSTEM);
- //TCPServerWinsock::make_default();
- //StreamPeerWinsock::make_default();
-
TCPServerWinsock::make_default();
StreamPeerWinsock::make_default();
PacketPeerUDPWinsock::make_default();
- mempool_static = new MemoryPoolStaticMalloc;
-#if 1
- mempool_dynamic = memnew(MemoryPoolDynamicStatic);
-#else
-#define DYNPOOL_SIZE 4 * 1024 * 1024
- void *buffer = malloc(DYNPOOL_SIZE);
- mempool_dynamic = memnew(MemoryPoolDynamicPrealloc(buffer, DYNPOOL_SIZE));
-
-#endif
-
// We need to know how often the clock is updated
if (!QueryPerformanceFrequency((LARGE_INTEGER *)&ticks_per_second))
ticks_per_second = 1000;
@@ -258,13 +241,18 @@ void OSUWP::initialize(const VideoMode &p_desired, int p_video_driver, int p_aud
set_video_mode(vm);
gl_context->make_current();
- rasterizer = memnew(RasterizerGLES2);
- visual_server = memnew(VisualServerRaster(rasterizer));
+ RasterizerGLES3::register_config();
+ RasterizerGLES3::make_current();
+
+ visual_server = memnew(VisualServerRaster);
+ // FIXME: Reimplement threaded rendering? Or remove?
+ /*
if (get_render_thread_mode() != RENDER_THREAD_UNSAFE) {
visual_server = memnew(VisualServerWrapMT(visual_server, get_render_thread_mode() == RENDER_SEPARATE_THREAD));
}
+ */
//
physics_server = memnew(PhysicsServerSW);
@@ -287,7 +275,7 @@ void OSUWP::initialize(const VideoMode &p_desired, int p_video_driver, int p_aud
ERR_PRINT("Initializing audio failed.");
}
- power_manager = memnew(PowerWinRT);
+ power_manager = memnew(PowerUWP);
managed_object->update_clipboard();
@@ -322,7 +310,7 @@ void OSUWP::initialize(const VideoMode &p_desired, int p_video_driver, int p_aud
if (is_keep_screen_on())
display_request->RequestActive();
- set_keep_screen_on(GLOBAL_DEF("display/keep_screen_on", true));
+ set_keep_screen_on(GLOBAL_DEF("display/window/keep_screen_on", true));
}
void OSUWP::set_clipboard(const String &p_text) {
@@ -342,19 +330,9 @@ String OSUWP::get_clipboard() const {
return "";
};
-void OSUWP::input_event(InputEvent &p_event) {
-
- p_event.ID = ++last_id;
+void OSUWP::input_event(const Ref<InputEvent> &p_event) {
input->parse_input_event(p_event);
-
- if (p_event.type == InputEvent::MOUSE_BUTTON && p_event.mouse_button.pressed && p_event.mouse_button.button_index > 3) {
-
- //send release for mouse wheel
- p_event.mouse_button.pressed = false;
- p_event.ID = ++last_id;
- input->parse_input_event(p_event);
- }
};
void OSUWP::delete_main_loop() {
@@ -383,14 +361,6 @@ void OSUWP::finalize() {
if (gl_context)
memdelete(gl_context);
#endif
- if (rasterizer)
- memdelete(rasterizer);
-
- /*
- if (debugger_connection_console) {
- memdelete(debugger_connection_console);
- }
- */
memdelete(input);
@@ -402,11 +372,8 @@ void OSUWP::finalize() {
joypad = nullptr;
}
-void OSUWP::finalize_core() {
- if (mempool_dynamic)
- memdelete(mempool_dynamic);
- delete mempool_static;
+void OSUWP::finalize_core() {
}
void OSUWP::vprint(const char *p_format, va_list p_list, bool p_stderr) {
@@ -534,7 +501,7 @@ OSUWP::MouseMode OSUWP::get_mouse_mode() const {
return mouse_mode;
}
-Point2 OSUWP::get_mouse_pos() const {
+Point2 OSUWP::get_mouse_position() const {
return Point2(old_x, old_y);
}
@@ -680,7 +647,7 @@ uint64_t OSUWP::get_ticks_usec() const {
void OSUWP::process_events() {
- last_id = joypad->process_controllers(last_id);
+ joypad->process_controllers();
process_key_events();
}
@@ -689,16 +656,18 @@ void OSUWP::process_key_events() {
for (int i = 0; i < key_event_pos; i++) {
KeyEvent &kev = key_event_buffer[i];
- InputEvent iev;
-
- iev.type = InputEvent::KEY;
- iev.key.mod = kev.mod_state;
- iev.key.echo = kev.echo;
- iev.key.scancode = kev.scancode;
- iev.key.unicode = kev.unicode;
- iev.key.pressed = kev.pressed;
- input_event(iev);
+ Ref<InputEventKey> key_event;
+ key_event.instance();
+ key_event->set_alt(kev.alt);
+ key_event->set_shift(kev.shift);
+ key_event->set_control(kev.control);
+ key_event->set_echo(kev.echo);
+ key_event->set_scancode(kev.scancode);
+ key_event->set_unicode(kev.unicode);
+ key_event->set_pressed(kev.pressed);
+
+ input_event(key_event);
}
key_event_pos = 0;
}
@@ -772,7 +741,7 @@ String OSUWP::get_executable_path() const {
return "";
}
-void OSUWP::set_icon(const Image &p_icon) {
+void OSUWP::set_icon(const Ref<Image> &p_icon) {
}
bool OSUWP::has_environment(const String &p_var) const {
@@ -882,15 +851,19 @@ String OSUWP::get_data_dir() const {
return String(data_folder->Path->Data()).replace("\\", "/");
}
-PowerState OSWinrt::get_power_state() {
+bool OSUWP::_check_internal_feature_support(const String &p_feature) {
+ return p_feature == "pc" || p_feature == "s3tc";
+}
+
+PowerState OSUWP::get_power_state() {
return power_manager->get_power_state();
}
-int OSWinrt::get_power_seconds_left() {
+int OSUWP::get_power_seconds_left() {
return power_manager->get_power_seconds_left();
}
-int OSWinrt::get_power_percent_left() {
+int OSUWP::get_power_percent_left() {
return power_manager->get_power_percent_left();
}
@@ -907,7 +880,6 @@ OSUWP::OSUWP() {
pressrc = 0;
old_invalid = true;
- last_id = 0;
mouse_mode = MOUSE_MODE_VISIBLE;
#ifdef STDOUT_FILE
stdo = fopen("stdout.txt", "wb");
diff --git a/platform/uwp/os_uwp.h b/platform/uwp/os_uwp.h
index ebbb8af39c..dfa21a0934 100644
--- a/platform/uwp/os_uwp.h
+++ b/platform/uwp/os_uwp.h
@@ -6,6 +6,7 @@
/* http://www.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 */
@@ -37,7 +38,7 @@
#include "main/input_default.h"
#include "os/input.h"
#include "os/os.h"
-#include "power_winrt.h"
+#include "power_uwp.h"
#include "servers/audio_server.h"
#include "servers/physics/physics_server_sw.h"
#include "servers/physics_2d/physics_2d_server_sw.h"
@@ -62,7 +63,7 @@ public:
CHAR_EVENT_MESSAGE
};
- InputModifierState mod_state;
+ bool alt, shift, control;
MessageType type;
bool pressed;
unsigned int scancode;
@@ -92,9 +93,7 @@ private:
bool outside;
int old_x, old_y;
Point2i center;
- unsigned int last_id;
VisualServer *visual_server;
- Rasterizer *rasterizer;
PhysicsServer *physics_server;
Physics2DServer *physics_2d_server;
int pressrc;
@@ -107,7 +106,7 @@ private:
AudioDriverXAudio2 audio_driver;
- PowerWinRT *power_manager;
+ PowerUWP *power_manager;
MouseMode mouse_mode;
bool alt_mem;
@@ -190,7 +189,7 @@ public:
void set_mouse_mode(MouseMode p_mode);
MouseMode get_mouse_mode() const;
- virtual Point2 get_mouse_pos() const;
+ virtual Point2 get_mouse_position() const;
virtual int get_mouse_button_state() const;
virtual void set_window_title(const String &p_title);
@@ -228,7 +227,7 @@ public:
virtual String get_clipboard() const;
void set_cursor_shape(CursorShape p_shape);
- void set_icon(const Image &p_icon);
+ void set_icon(const Ref<Image> &p_icon);
virtual String get_executable_path() const;
@@ -237,6 +236,8 @@ public:
virtual void move_window_to_foreground();
virtual String get_data_dir() const;
+ virtual bool _check_internal_feature_support(const String &p_feature);
+
void set_gl_context(ContextEGL *p_context);
void screen_size_changed();
@@ -256,7 +257,7 @@ public:
virtual bool get_swap_ok_cancel() { return true; }
- void input_event(InputEvent &p_event);
+ void input_event(const Ref<InputEvent> &p_event);
virtual PowerState get_power_state();
virtual int get_power_seconds_left();
diff --git a/platform/uwp/platform_config.h b/platform/uwp/platform_config.h
index 7939e1c9ee..77d2c9cadb 100644
--- a/platform/uwp/platform_config.h
+++ b/platform/uwp/platform_config.h
@@ -6,6 +6,7 @@
/* http://www.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 */
diff --git a/platform/bb10/power_bb10.cpp b/platform/uwp/power_uwp.cpp
index 29c1fe370d..ece07f84ad 100644
--- a/platform/bb10/power_bb10.cpp
+++ b/platform/uwp/power_uwp.cpp
@@ -1,11 +1,12 @@
/*************************************************************************/
-/* power_bb10.cpp */
+/* power_uwp.cpp */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* http://www.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 */
@@ -27,16 +28,26 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "power_bb10.h"
+#include "power_uwp.h"
-#include "core/error_macros.h"
+PowerUWP::PowerUWP()
+ : nsecs_left(-1), percent_left(-1), power_state(POWERSTATE_UNKNOWN) {
+}
-bool PowerBB10::UpdatePowerInfo() {
+PowerUWP::~PowerUWP() {
+}
+bool PowerUWP::UpdatePowerInfo() {
+ // TODO, WinRT: Battery info is available on at least one WinRT platform (Windows Phone 8). Implement UpdatePowerInfo as appropriate. */
+ /* Notes from SDL:
+ - the Win32 function, GetSystemPowerStatus, is not available for use on WinRT
+ - Windows Phone 8 has a 'Battery' class, which is documented as available for C++
+ - More info on WP8's Battery class can be found at http://msdn.microsoft.com/library/windowsphone/develop/jj207231
+ */
return false;
}
-PowerState PowerBB10::get_power_state() {
+PowerState PowerUWP::get_power_state() {
if (UpdatePowerInfo()) {
return power_state;
} else {
@@ -45,7 +56,7 @@ PowerState PowerBB10::get_power_state() {
}
}
-int PowerBB10::get_power_seconds_left() {
+int PowerUWP::get_power_seconds_left() {
if (UpdatePowerInfo()) {
return nsecs_left;
} else {
@@ -54,7 +65,7 @@ int PowerBB10::get_power_seconds_left() {
}
}
-int PowerBB10::get_power_percent_left() {
+int PowerUWP::get_power_percent_left() {
if (UpdatePowerInfo()) {
return percent_left;
} else {
@@ -62,10 +73,3 @@ int PowerBB10::get_power_percent_left() {
return -1;
}
}
-
-PowerBB10::PowerBB10()
- : nsecs_left(-1), percent_left(-1), power_state(POWERSTATE_UNKNOWN) {
-}
-
-PowerBB10::~PowerBB10() {
-}
diff --git a/platform/bb10/power_bb10.h b/platform/uwp/power_uwp.h
index 6c13f6e997..c23d712980 100644
--- a/platform/bb10/power_bb10.h
+++ b/platform/uwp/power_uwp.h
@@ -1,11 +1,12 @@
/*************************************************************************/
-/* power_bb10.h */
+/* power_uwp.h */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* http://www.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 */
@@ -27,10 +28,15 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef PLATFORM_BB10_POWER_BB10_H_
-#define PLATFORM_BB10_POWER_BB10_H_
+#ifndef PLATFORM_UWP_POWER_UWP_H_
+#define PLATFORM_UWP_POWER_UWP_H_
+
+#include "os/dir_access.h"
+#include "os/file_access.h"
+#include "os/power.h"
+
+class PowerUWP {
-class PowerBB10 {
private:
int nsecs_left;
int percent_left;
@@ -39,12 +45,12 @@ private:
bool UpdatePowerInfo();
public:
- PowerBB10();
- virtual ~PowerBB10();
+ PowerUWP();
+ virtual ~PowerUWP();
PowerState get_power_state();
int get_power_seconds_left();
int get_power_percent_left();
};
-#endif /* PLATFORM_BB10_POWER_BB10_H_ */
+#endif /* PLATFORM_UWP_POWER_UWP_H_ */
diff --git a/platform/uwp/thread_uwp.cpp b/platform/uwp/thread_uwp.cpp
index ff079be375..0549a8ed47 100644
--- a/platform/uwp/thread_uwp.cpp
+++ b/platform/uwp/thread_uwp.cpp
@@ -6,6 +6,7 @@
/* http://www.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 */
@@ -40,7 +41,7 @@ Thread *ThreadUWP::create_func_uwp(ThreadCreateCallback p_callback, void *p_user
return thread;
};
-Thread::ID ThreadUWP::get_thread_ID_func_uwp() {
+Thread::ID ThreadUWP::get_thread_id_func_uwp() {
return std::hash<std::thread::id>()(std::this_thread::get_id());
};
@@ -51,14 +52,14 @@ void ThreadUWP::wait_to_finish_func_uwp(Thread *p_thread) {
tp->thread.join();
};
-Thread::ID ThreadUWP::get_ID() const {
+Thread::ID ThreadUWP::get_id() const {
return std::hash<std::thread::id>()(thread.get_id());
};
void ThreadUWP::make_default() {
create_func = create_func_uwp;
- get_thread_ID_func = get_thread_ID_func_uwp;
+ get_thread_id_func = get_thread_id_func_uwp;
wait_to_finish_func = wait_to_finish_func_uwp;
};
diff --git a/platform/uwp/thread_uwp.h b/platform/uwp/thread_uwp.h
index b4e67c8b5c..b8cccfb7c3 100644
--- a/platform/uwp/thread_uwp.h
+++ b/platform/uwp/thread_uwp.h
@@ -6,6 +6,7 @@
/* http://www.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 */
@@ -40,13 +41,13 @@ class ThreadUWP : public Thread {
std::thread thread;
static Thread *create_func_uwp(ThreadCreateCallback p_callback, void *, const Settings &);
- static ID get_thread_ID_func_uwp();
+ static ID get_thread_id_func_uwp();
static void wait_to_finish_func_uwp(Thread *p_thread);
ThreadUWP();
public:
- virtual ID get_ID() const;
+ virtual ID get_id() const;
static void make_default();
diff --git a/platform/windows/context_gl_win.cpp b/platform/windows/context_gl_win.cpp
index 449ac264a6..f8aed0ccab 100644
--- a/platform/windows/context_gl_win.cpp
+++ b/platform/windows/context_gl_win.cpp
@@ -6,6 +6,7 @@
/* http://www.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 */
diff --git a/platform/windows/context_gl_win.h b/platform/windows/context_gl_win.h
index 383197ba7f..b3cab7806d 100644
--- a/platform/windows/context_gl_win.h
+++ b/platform/windows/context_gl_win.h
@@ -6,6 +6,7 @@
/* http://www.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 */
diff --git a/platform/windows/ctxgl_procaddr.cpp b/platform/windows/ctxgl_procaddr.cpp
index 79c6f219f3..e01c3fc252 100644
--- a/platform/windows/ctxgl_procaddr.cpp
+++ b/platform/windows/ctxgl_procaddr.cpp
@@ -6,6 +6,7 @@
/* http://www.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 */
diff --git a/platform/windows/ctxgl_procaddr.h b/platform/windows/ctxgl_procaddr.h
index da17fbcbbe..ecef01aadf 100644
--- a/platform/windows/ctxgl_procaddr.h
+++ b/platform/windows/ctxgl_procaddr.h
@@ -6,6 +6,7 @@
/* http://www.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 */
diff --git a/platform/windows/detect.py b/platform/windows/detect.py
index a3e410ec64..4d93b3f244 100644
--- a/platform/windows/detect.py
+++ b/platform/windows/detect.py
@@ -1,104 +1,7 @@
-#
-# tested on | Windows native | Linux cross-compilation
-# ----------------------------+-------------------+---------------------------
-# Visual C++ Build Tools 2015 | WORKS | n/a
-# MSVS C++ 2010 Express | WORKS | n/a
-# Mingw-w64 | WORKS | WORKS
-# Mingw-w32 | WORKS | WORKS
-# MinGW | WORKS | untested
-#
-#####
-# Note about Visual C++ Build Tools :
-#
-# - Visual C++ Build Tools is the standalone MSVC compiler :
-# http://landinghub.visualstudio.com/visual-cpp-build-tools
-#
-#####
-# Notes about MSVS C++ :
-#
-# - MSVC2010-Express compiles to 32bits only.
-#
-#####
-# Notes about Mingw-w64 and Mingw-w32 under Windows :
-#
-# - both can be installed using the official installer :
-# http://mingw-w64.sourceforge.net/download.php#mingw-builds
-#
-# - if you want to compile both 32bits and 64bits, don't forget to
-# run the installer twice to install them both.
-#
-# - install them into a path that does not contain spaces
-# ( example : "C:/Mingw-w32", "C:/Mingw-w64" )
-#
-# - if you want to compile faster using the "-j" option, don't forget
-# to install the appropriate version of the Pywin32 python extension
-# available from : http://sourceforge.net/projects/pywin32/files/
-#
-# - before running scons, you must add into the environment path
-# the path to the "/bin" directory of the Mingw version you want
-# to use :
-#
-# set PATH=C:/Mingw-w32/bin;%PATH%
-#
-# - then, scons should be able to detect gcc.
-# - Mingw-w32 only compiles 32bits.
-# - Mingw-w64 only compiles 64bits.
-#
-# - it is possible to add them both at the same time into the PATH env,
-# if you also define the MINGW32_PREFIX and MINGW64_PREFIX environment
-# variables.
-# For instance, you could store that set of commands into a .bat script
-# that you would run just before scons :
-#
-# set PATH=C:\mingw-w32\bin;%PATH%
-# set PATH=C:\mingw-w64\bin;%PATH%
-# set MINGW32_PREFIX=C:\mingw-w32\bin\
-# set MINGW64_PREFIX=C:\mingw-w64\bin\
-#
-#####
-# Notes about Mingw, Mingw-w64 and Mingw-w32 under Linux :
-#
-# - default toolchain prefixes are :
-# "i586-mingw32msvc-" for MinGW
-# "i686-w64-mingw32-" for Mingw-w32
-# "x86_64-w64-mingw32-" for Mingw-w64
-#
-# - if both MinGW and Mingw-w32 are installed on your system
-# Mingw-w32 should take the priority over MinGW.
-#
-# - it is possible to manually override prefixes by defining
-# the MINGW32_PREFIX and MINGW64_PREFIX environment variables.
-#
-#####
-# Notes about Mingw under Windows :
-#
-# - this is the MinGW version from http://mingw.org/
-# - install it into a path that does not contain spaces
-# ( example : "C:/MinGW" )
-# - several DirectX headers might be missing. You can copy them into
-# the C:/MinGW/include" directory from this page :
-# https://code.google.com/p/mingw-lib/source/browse/trunk/working/avcodec_to_widget_5/directx_include/
-# - before running scons, add the path to the "/bin" directory :
-# set PATH=C:/MinGW/bin;%PATH%
-# - scons should be able to detect gcc.
-#
-
-#####
-# TODO :
-#
-# - finish to cleanup this script to remove all the remains of previous hacks and workarounds
-# - make it work with the Windows7 SDK that is supposed to enable 64bits compilation for MSVC2010-Express
-# - confirm it works well with other Visual Studio versions.
-# - update the wiki about the pywin32 extension required for the "-j" option under Windows.
-# - update the wiki to document MINGW32_PREFIX and MINGW64_PREFIX
-#
-
+import methods
import os
-
import sys
-import methods
-
def is_active():
return True
@@ -115,7 +18,7 @@ def can_build():
if (os.getenv("VCINSTALLDIR")):
return True
else:
- print("\nMSVC not detected, attempting Mingw.")
+ print("\nMSVC not detected, attempting MinGW.")
mingw32 = ""
mingw64 = ""
if (os.getenv("MINGW32_PREFIX")):
@@ -126,7 +29,7 @@ def can_build():
test = "gcc --version > NUL 2>&1"
if os.system(test) != 0 and os.system(mingw32 + test) != 0 and os.system(mingw64 + test) != 0:
print("- could not detect gcc.")
- print("Please, make sure a path to a Mingw /bin directory is accessible into the environment PATH.\n")
+ print("Please, make sure a path to a MinGW /bin directory is accessible into the environment PATH.\n")
return False
else:
print("- gcc detected.")
@@ -145,7 +48,7 @@ def can_build():
if (os.getenv("MINGW64_PREFIX")):
mingw64 = os.getenv("MINGW64_PREFIX")
- test = "gcc --version &>/dev/null"
+ test = "gcc --version > /dev/null 2>&1"
if (os.system(mingw + test) == 0 or os.system(mingw64 + test) == 0 or os.system(mingw32 + test) == 0):
return True
@@ -162,7 +65,7 @@ def get_opts():
mingw32 = "i686-w64-mingw32-"
mingw64 = "x86_64-w64-mingw32-"
- if os.system(mingw32 + "gcc --version &>/dev/null") != 0:
+ if os.system(mingw32 + "gcc --version > /dev/null 2>&1") != 0:
mingw32 = mingw
if (os.getenv("MINGW32_PREFIX")):
@@ -172,8 +75,8 @@ def get_opts():
mingw64 = os.getenv("MINGW64_PREFIX")
return [
- ('mingw_prefix', 'Mingw Prefix', mingw32),
- ('mingw_prefix_64', 'Mingw Prefix 64 bits', mingw64),
+ ('mingw_prefix', 'MinGW Prefix', mingw32),
+ ('mingw_prefix_64', 'MinGW Prefix 64 bits', mingw64),
]
@@ -211,55 +114,86 @@ def configure(env):
# Targeted Windows version: Vista (and later)
winver = "0x0600" # Windows Vista is the minimum target for windows builds
- env['is_mingw'] = False
- if (os.name == "nt" and os.getenv("VCINSTALLDIR")):
- # build using visual studio
+ if (os.name == "nt" and os.getenv("VCINSTALLDIR")): # MSVC
+
env['ENV']['TMP'] = os.environ['TMP']
- env.Append(CPPPATH=['#platform/windows/include'])
- env.Append(LIBPATH=['#platform/windows/lib'])
- env.Append(CCFLAGS=['/DWINVER=%s' % winver, '/D_WIN32_WINNT=%s' % winver])
- if (env["target"] == "release"):
+ ## Build type
+ if (env["target"] == "release"):
env.Append(CCFLAGS=['/O2'])
env.Append(LINKFLAGS=['/SUBSYSTEM:WINDOWS'])
env.Append(LINKFLAGS=['/ENTRY:mainCRTStartup'])
elif (env["target"] == "release_debug"):
-
env.Append(CCFLAGS=['/O2', '/DDEBUG_ENABLED'])
env.Append(LINKFLAGS=['/SUBSYSTEM:CONSOLE'])
- elif (env["target"] == "debug_release"):
+ elif (env["target"] == "debug_release"):
env.Append(CCFLAGS=['/Z7', '/Od'])
env.Append(LINKFLAGS=['/DEBUG'])
env.Append(LINKFLAGS=['/SUBSYSTEM:WINDOWS'])
env.Append(LINKFLAGS=['/ENTRY:mainCRTStartup'])
elif (env["target"] == "debug"):
-
env.Append(CCFLAGS=['/Z7', '/DDEBUG_ENABLED', '/DDEBUG_MEMORY_ENABLED', '/DD3D_DEBUG_INFO', '/Od'])
env.Append(LINKFLAGS=['/SUBSYSTEM:CONSOLE'])
env.Append(LINKFLAGS=['/DEBUG'])
+ ## Architecture
+
+ # Note: this detection/override code from here onward should be here instead of in SConstruct because it's platform and compiler specific (MSVC/Windows)
+ if (env["bits"] != "default"):
+ print("Error: bits argument is disabled for MSVC")
+ print("""
+ Bits argument is not supported for MSVC compilation. Architecture depends on the Native/Cross Compile Tools Prompt/Developer Console
+ (or Visual Studio settings) that is being used to run SCons. As a consequence, bits argument is disabled. Run scons again without bits
+ argument (example: scons p=windows) and SCons will attempt to detect what MSVC compiler will be executed and inform you.
+ """)
+ sys.exit()
+
+ # Forcing bits argument because MSVC does not have a flag to set this through SCons... it's different compilers (cl.exe's) called from the proper command prompt
+ # that decide the architecture that is build for. Scons can only detect the os.getenviron (because vsvarsall.bat sets a lot of stuff for cl.exe to work with)
+ env["bits"] = "32"
+ env["x86_libtheora_opt_vc"] = True
+
+ ## Compiler configuration
+
+ env['ENV'] = os.environ
+ # This detection function needs the tools env (that is env['ENV'], not SCons's env), and that is why it's this far bellow in the code
+ compiler_version_str = methods.detect_visual_c_compiler_version(env['ENV'])
+
+ print("Detected MSVC compiler: " + compiler_version_str)
+ # If building for 64bit architecture, disable assembly optimisations for 32 bit builds (theora as of writting)... vc compiler for 64bit can not compile _asm
+ if(compiler_version_str == "amd64" or compiler_version_str == "x86_amd64"):
+ env["bits"] = "64"
+ env["x86_libtheora_opt_vc"] = False
+ print("Compiled program architecture will be a 64 bit executable (forcing bits=64).")
+ elif (compiler_version_str == "x86" or compiler_version_str == "amd64_x86"):
+ print("Compiled program architecture will be a 32 bit executable. (forcing bits=32).")
+ else:
+ print("Failed to detect MSVC compiler architecture version... Defaulting to 32bit executable settings (forcing bits=32). Compilation attempt will continue, but SCons can not detect for what architecture this build is compiled for. You should check your settings/compilation setup.")
+
+ ## Compile flags
+
env.Append(CCFLAGS=['/MT', '/Gd', '/GR', '/nologo'])
env.Append(CXXFLAGS=['/TP'])
env.Append(CPPFLAGS=['/DMSVC', '/GR', ])
env.Append(CCFLAGS=['/I' + os.getenv("WindowsSdkDir") + "/Include"])
+
env.Append(CCFLAGS=['/DWINDOWS_ENABLED'])
+ env.Append(CCFLAGS=['/DOPENGL_ENABLED'])
env.Append(CCFLAGS=['/DRTAUDIO_ENABLED'])
- env.Append(CCFLAGS=['/DWIN32'])
env.Append(CCFLAGS=['/DTYPED_METHOD_BIND'])
+ env.Append(CCFLAGS=['/DWIN32'])
+ env.Append(CCFLAGS=['/DWINVER=%s' % winver, '/D_WIN32_WINNT=%s' % winver])
+ if env["bits"] == "64":
+ env.Append(CCFLAGS=['/D_WIN64'])
- env.Append(CCFLAGS=['/DOPENGL_ENABLED'])
LIBS = ['winmm', 'opengl32', 'dsound', 'kernel32', 'ole32', 'oleaut32', 'user32', 'gdi32', 'IPHLPAPI', 'Shlwapi', 'wsock32', 'Ws2_32', 'shell32', 'advapi32', 'dinput8', 'dxguid']
env.Append(LINKFLAGS=[p + env["LIBSUFFIX"] for p in LIBS])
env.Append(LIBPATH=[os.getenv("WindowsSdkDir") + "/Lib"])
- if (os.getenv("DXSDK_DIR")):
- DIRECTX_PATH = os.getenv("DXSDK_DIR")
- else:
- DIRECTX_PATH = "C:/Program Files/Microsoft DirectX SDK (March 2009)"
if (os.getenv("VCINSTALLDIR")):
VC_PATH = os.getenv("VCINSTALLDIR")
@@ -268,51 +202,37 @@ def configure(env):
env.Append(CCFLAGS=["/I" + p for p in os.getenv("INCLUDE").split(";")])
env.Append(LIBPATH=[p for p in os.getenv("LIB").split(";")])
- env.Append(CCFLAGS=["/I" + DIRECTX_PATH + "/Include"])
- env.Append(LIBPATH=[DIRECTX_PATH + "/Lib/x86"])
- env['ENV'] = os.environ
-
- # This detection function needs the tools env (that is env['ENV'], not SCons's env), and that is why it's this far bellow in the code
- compiler_version_str = methods.detect_visual_c_compiler_version(env['ENV'])
-
- # Note: this detection/override code from here onward should be here instead of in SConstruct because it's platform and compiler specific (MSVC/Windows)
- if(env["bits"] != "default"):
- print "Error: bits argument is disabled for MSVC"
- print ("Bits argument is not supported for MSVC compilation. Architecture depends on the Native/Cross Compile Tools Prompt/Developer Console (or Visual Studio settings)"
- + " that is being used to run SCons. As a consequence, bits argument is disabled. Run scons again without bits argument (example: scons p=windows) and SCons will attempt to detect what MSVC compiler"
- + " will be executed and inform you.")
- sys.exit()
-
- # Forcing bits argument because MSVC does not have a flag to set this through SCons... it's different compilers (cl.exe's) called from the proper command prompt
- # that decide the architecture that is build for. Scons can only detect the os.getenviron (because vsvarsall.bat sets a lot of stuff for cl.exe to work with)
- env["bits"] = "32"
- env["x86_libtheora_opt_vc"] = True
-
- print "Detected MSVC compiler: " + compiler_version_str
- # If building for 64bit architecture, disable assembly optimisations for 32 bit builds (theora as of writting)... vc compiler for 64bit can not compile _asm
- if(compiler_version_str == "amd64" or compiler_version_str == "x86_amd64"):
- env["bits"] = "64"
- env["x86_libtheora_opt_vc"] = False
- print "Compiled program architecture will be a 64 bit executable (forcing bits=64)."
- elif (compiler_version_str == "x86" or compiler_version_str == "amd64_x86"):
- print "Compiled program architecture will be a 32 bit executable. (forcing bits=32)."
- else:
- print "Failed to detect MSVC compiler architecture version... Defaulting to 32bit executable settings (forcing bits=32). Compilation attempt will continue, but SCons can not detect for what architecture this build is compiled for. You should check your settings/compilation setup."
- if env["bits"] == "64":
- env.Append(CCFLAGS=['/D_WIN64'])
# Incremental linking fix
env['BUILDERS']['ProgramOriginal'] = env['BUILDERS']['Program']
env['BUILDERS']['Program'] = methods.precious_program
- else:
+ else: # MinGW
# Workaround for MinGW. See:
# http://www.scons.org/wiki/LongCmdLinesOnWin32
env.use_windows_spawn_fix()
- # build using mingw
- env.Append(CCFLAGS=['-DWINVER=%s' % winver, '-D_WIN32_WINNT=%s' % winver])
+ ## Build type
+
+ if (env["target"] == "release"):
+ env.Append(CCFLAGS=['-msse2'])
+
+ if (env["bits"] == "64"):
+ env.Append(CCFLAGS=['-O3'])
+ else:
+ env.Append(CCFLAGS=['-O2'])
+
+ env.Append(LINKFLAGS=['-Wl,--subsystem,windows'])
+
+ elif (env["target"] == "release_debug"):
+ env.Append(CCFLAGS=['-O2', '-DDEBUG_ENABLED'])
+
+ elif (env["target"] == "debug"):
+ env.Append(CCFLAGS=['-g', '-DDEBUG_ENABLED', '-DDEBUG_MEMORY_ENABLED'])
+
+ ## Compiler configuration
+
if (os.name == "nt"):
env['ENV']['TMP'] = os.environ['TMP'] # way to go scons, you can be so stupid sometimes
else:
@@ -332,37 +252,6 @@ def configure(env):
env.Append(LINKFLAGS=['-static'])
mingw_prefix = env["mingw_prefix_64"]
- nulstr = ""
-
- if (os.name == "posix"):
- nulstr = ">/dev/null"
- else:
- nulstr = ">nul"
-
- # if os.system(mingw_prefix+"gcc --version"+nulstr)!=0:
- # #not really super consistent but..
- # print("Can't find Windows compiler: "+mingw_prefix)
- # sys.exit(255)
-
- if (env["target"] == "release"):
-
- env.Append(CCFLAGS=['-msse2'])
-
- if (env["bits"] == "64"):
- env.Append(CCFLAGS=['-O3'])
- else:
- env.Append(CCFLAGS=['-O2'])
-
- env.Append(LINKFLAGS=['-Wl,--subsystem,windows'])
-
- elif (env["target"] == "release_debug"):
-
- env.Append(CCFLAGS=['-O2', '-DDEBUG_ENABLED'])
-
- elif (env["target"] == "debug"):
-
- env.Append(CCFLAGS=['-g', '-Wall', '-DDEBUG_ENABLED', '-DDEBUG_MEMORY_ENABLED'])
-
env["CC"] = mingw_prefix + "gcc"
env['AS'] = mingw_prefix + "as"
env['CXX'] = mingw_prefix + "g++"
@@ -371,29 +260,15 @@ def configure(env):
env['LD'] = mingw_prefix + "g++"
env["x86_libtheora_opt_gcc"] = True
- #env['CC'] = "winegcc"
- #env['CXX'] = "wineg++"
+ ## Compile flags
env.Append(CCFLAGS=['-DWINDOWS_ENABLED', '-mwindows'])
- env.Append(CPPFLAGS=['-DRTAUDIO_ENABLED'])
env.Append(CCFLAGS=['-DOPENGL_ENABLED'])
+ env.Append(CCFLAGS=['-DRTAUDIO_ENABLED'])
+ env.Append(CCFLAGS=['-DWINVER=%s' % winver, '-D_WIN32_WINNT=%s' % winver])
env.Append(LIBS=['mingw32', 'opengl32', 'dsound', 'ole32', 'd3d9', 'winmm', 'gdi32', 'iphlpapi', 'shlwapi', 'wsock32', 'ws2_32', 'kernel32', 'oleaut32', 'dinput8', 'dxguid'])
- # if (env["bits"]=="32"):
- # env.Append(LIBS=['gcc_s'])
- # #--with-arch=i686
- # env.Append(CPPFLAGS=['-march=i686'])
- # env.Append(LINKFLAGS=['-march=i686'])
-
- #'d3dx9d'
env.Append(CPPFLAGS=['-DMINGW_ENABLED'])
- # env.Append(LINKFLAGS=['-g'])
# resrc
- env['is_mingw'] = True
env.Append(BUILDERS={'RES': env.Builder(action=build_res_file, suffix='.o', src_suffix='.rc')})
-
- env.Append(BUILDERS={'GLSL120': env.Builder(action=methods.build_legacygl_headers, suffix='glsl.h', src_suffix='.glsl')})
- env.Append(BUILDERS={'GLSL': env.Builder(action=methods.build_glsl_headers, suffix='glsl.h', src_suffix='.glsl')})
- env.Append(BUILDERS={'HLSL9': env.Builder(action=methods.build_hlsl_dx9_headers, suffix='hlsl.h', src_suffix='.hlsl')})
- env.Append(BUILDERS={'GLSL120GLES': env.Builder(action=methods.build_gles2_headers, suffix='glsl.h', src_suffix='.glsl')})
diff --git a/platform/windows/export/export.cpp b/platform/windows/export/export.cpp
index bb51474a8c..6cb33e2ff0 100644
--- a/platform/windows/export/export.cpp
+++ b/platform/windows/export/export.cpp
@@ -6,6 +6,7 @@
/* http://www.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 */
@@ -26,28 +27,26 @@
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "export.h"
#include "editor/editor_export.h"
-#include "platform/windows/logo.h"
+#include "platform/windows/logo.gen.h"
void register_windows_exporter() {
-#if 0
- Image img(_windows_logo);
- Ref<ImageTexture> logo = memnew( ImageTexture );
- logo->create_from_image(img);
+ Ref<EditorExportPlatformPC> platform;
+ platform.instance();
- {
- Ref<EditorExportPlatformPC> exporter = Ref<EditorExportPlatformPC>( memnew(EditorExportPlatformPC) );
- exporter->set_binary_extension("exe");
- exporter->set_release_binary32("windows_32_release.exe");
- exporter->set_debug_binary32("windows_32_debug.exe");
- exporter->set_release_binary64("windows_64_release.exe");
- exporter->set_debug_binary64("windows_64_debug.exe");
- exporter->set_name("Windows Desktop");
- exporter->set_logo(logo);
- EditorImportExport::get_singleton()->add_export_platform(exporter);
- }
+ Ref<Image> img = memnew(Image(_windows_logo));
+ Ref<ImageTexture> logo;
+ logo.instance();
+ logo->create_from_image(img);
+ platform->set_logo(logo);
+ platform->set_name("Windows Desktop");
+ platform->set_extension("exe");
+ platform->set_release_32("windows_32_release.exe");
+ platform->set_debug_32("windows_32_debug.exe");
+ platform->set_release_64("windows_64_release.exe");
+ platform->set_debug_64("windows_64_debug.exe");
+ platform->set_os_name("Windows");
-#endif
+ EditorExport::get_singleton()->add_export_platform(platform);
}
diff --git a/platform/windows/export/export.h b/platform/windows/export/export.h
index b437efc48e..ea9113c674 100644
--- a/platform/windows/export/export.h
+++ b/platform/windows/export/export.h
@@ -6,6 +6,7 @@
/* http://www.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 */
diff --git a/platform/windows/godot.ico b/platform/windows/godot.ico
index 3e52f2e52f..dd611e07da 100644
--- a/platform/windows/godot.ico
+++ b/platform/windows/godot.ico
Binary files differ
diff --git a/platform/windows/godot_win.cpp b/platform/windows/godot_win.cpp
index f8f5fe8231..df2d96e516 100644
--- a/platform/windows/godot_win.cpp
+++ b/platform/windows/godot_win.cpp
@@ -6,6 +6,7 @@
/* http://www.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 */
diff --git a/platform/windows/joypad.cpp b/platform/windows/joypad.cpp
index 2472940ef3..e8a5084daf 100644
--- a/platform/windows/joypad.cpp
+++ b/platform/windows/joypad.cpp
@@ -6,6 +6,7 @@
/* http://www.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 */
@@ -234,13 +235,13 @@ void JoypadWindows::setup_joypad_object(const DIDEVICEOBJECTINSTANCE *ob, int p_
}
}
-BOOL CALLBACK JoypadWindows::enumCallback(const DIDEVICEINSTANCE *instance, void *pContext) {
+BOOL CALLBACK JoypadWindows::enumCallback(const DIDEVICEINSTANCE *p_instance, void *p_context) {
- JoypadWindows *self = (JoypadWindows *)pContext;
- if (self->is_xinput_device(&instance->guidProduct)) {
+ JoypadWindows *self = (JoypadWindows *)p_context;
+ if (self->is_xinput_device(&p_instance->guidProduct)) {
return DIENUM_CONTINUE;
}
- self->setup_dinput_joypad(instance);
+ self->setup_dinput_joypad(p_instance);
return DIENUM_CONTINUE;
}
@@ -319,7 +320,7 @@ void JoypadWindows::probe_joypads() {
}
}
-unsigned int JoypadWindows::process_joypads(unsigned int p_last_id) {
+void JoypadWindows::process_joypads() {
HRESULT hr;
@@ -337,16 +338,16 @@ unsigned int JoypadWindows::process_joypads(unsigned int p_last_id) {
int button_mask = XINPUT_GAMEPAD_DPAD_UP;
for (int i = 0; i <= 16; i++) {
- p_last_id = input->joy_button(p_last_id, joy.id, i, joy.state.Gamepad.wButtons & button_mask);
+ input->joy_button(joy.id, i, joy.state.Gamepad.wButtons & button_mask);
button_mask = button_mask * 2;
}
- p_last_id = input->joy_axis(p_last_id, joy.id, JOY_AXIS_0, axis_correct(joy.state.Gamepad.sThumbLX, true));
- p_last_id = input->joy_axis(p_last_id, joy.id, JOY_AXIS_1, axis_correct(joy.state.Gamepad.sThumbLY, true, false, true));
- p_last_id = input->joy_axis(p_last_id, joy.id, JOY_AXIS_2, axis_correct(joy.state.Gamepad.sThumbRX, true));
- p_last_id = input->joy_axis(p_last_id, joy.id, JOY_AXIS_3, axis_correct(joy.state.Gamepad.sThumbRY, true, false, true));
- p_last_id = input->joy_axis(p_last_id, joy.id, JOY_AXIS_4, axis_correct(joy.state.Gamepad.bLeftTrigger, true, true));
- p_last_id = input->joy_axis(p_last_id, joy.id, JOY_AXIS_5, axis_correct(joy.state.Gamepad.bRightTrigger, true, true));
+ input->joy_axis(joy.id, JOY_AXIS_0, axis_correct(joy.state.Gamepad.sThumbLX, true));
+ input->joy_axis(joy.id, JOY_AXIS_1, axis_correct(joy.state.Gamepad.sThumbLY, true, false, true));
+ input->joy_axis(joy.id, JOY_AXIS_2, axis_correct(joy.state.Gamepad.sThumbRX, true));
+ input->joy_axis(joy.id, JOY_AXIS_3, axis_correct(joy.state.Gamepad.sThumbRY, true, false, true));
+ input->joy_axis(joy.id, JOY_AXIS_4, axis_correct(joy.state.Gamepad.bLeftTrigger, true, true));
+ input->joy_axis(joy.id, JOY_AXIS_5, axis_correct(joy.state.Gamepad.bRightTrigger, true, true));
joy.last_packet = joy.state.dwPacketNumber;
}
uint64_t timestamp = input->get_joy_vibration_timestamp(joy.id);
@@ -384,7 +385,7 @@ unsigned int JoypadWindows::process_joypads(unsigned int p_last_id) {
continue;
}
- p_last_id = post_hat(p_last_id, joy->id, js.rgdwPOV[0]);
+ post_hat(joy->id, js.rgdwPOV[0]);
for (int j = 0; j < 128; j++) {
@@ -392,14 +393,14 @@ unsigned int JoypadWindows::process_joypads(unsigned int p_last_id) {
if (!joy->last_buttons[j]) {
- p_last_id = input->joy_button(p_last_id, joy->id, j, true);
+ input->joy_button(joy->id, j, true);
joy->last_buttons[j] = true;
}
} else {
if (joy->last_buttons[j]) {
- p_last_id = input->joy_button(p_last_id, joy->id, j, false);
+ input->joy_button(joy->id, j, false);
joy->last_buttons[j] = false;
}
}
@@ -414,16 +415,16 @@ unsigned int JoypadWindows::process_joypads(unsigned int p_last_id) {
for (int k = 0; k < count; k++) {
if (joy->joy_axis[j] == axes[k]) {
- p_last_id = input->joy_axis(p_last_id, joy->id, j, axis_correct(values[k]));
+ input->joy_axis(joy->id, j, axis_correct(values[k]));
break;
};
};
};
}
- return p_last_id;
+ return;
}
-unsigned int JoypadWindows::post_hat(unsigned int p_last_id, int p_device, DWORD p_dpad) {
+void JoypadWindows::post_hat(int p_device, DWORD p_dpad) {
int dpad_val = 0;
@@ -462,7 +463,7 @@ unsigned int JoypadWindows::post_hat(unsigned int p_last_id, int p_device, DWORD
dpad_val = (InputDefault::HAT_MASK_LEFT | InputDefault::HAT_MASK_UP);
}
- return input->joy_hat(p_last_id, p_device, dpad_val);
+ input->joy_hat(p_device, dpad_val);
};
InputDefault::JoyAxis JoypadWindows::axis_correct(int p_val, bool p_xinput, bool p_trigger, bool p_negate) const {
diff --git a/platform/windows/joypad.h b/platform/windows/joypad.h
index 7e4f6ff328..7cd791e78f 100644
--- a/platform/windows/joypad.h
+++ b/platform/windows/joypad.h
@@ -6,6 +6,7 @@
/* http://www.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 */
@@ -53,7 +54,7 @@ public:
~JoypadWindows();
void probe_joypads();
- unsigned int process_joypads(unsigned int p_last_id);
+ void process_joypads();
private:
enum {
@@ -130,7 +131,7 @@ private:
void load_xinput();
void unload_xinput();
- unsigned int post_hat(unsigned int p_last_id, int p_device, DWORD p_dpad);
+ void post_hat(int p_device, DWORD p_dpad);
bool have_device(const GUID &p_guid);
bool is_xinput_device(const GUID *p_guid);
diff --git a/platform/windows/key_mapping_win.cpp b/platform/windows/key_mapping_win.cpp
index 51cdba65d5..83e2af72b2 100644
--- a/platform/windows/key_mapping_win.cpp
+++ b/platform/windows/key_mapping_win.cpp
@@ -6,6 +6,7 @@
/* http://www.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 */
@@ -43,7 +44,7 @@ static _WinTranslatePair _vk_to_keycode[] = {
//VK_CLEAR (0x0C)
- { KEY_RETURN, VK_RETURN }, //(0x0D)
+ { KEY_ENTER, VK_RETURN }, //(0x0D)
{ KEY_SHIFT, VK_SHIFT }, //(0x10)
diff --git a/platform/windows/key_mapping_win.h b/platform/windows/key_mapping_win.h
index fbc79635c2..af91676dff 100644
--- a/platform/windows/key_mapping_win.h
+++ b/platform/windows/key_mapping_win.h
@@ -6,6 +6,7 @@
/* http://www.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 */
diff --git a/platform/windows/lang_table.h b/platform/windows/lang_table.h
index 7fe509d3e0..7cf2bb391b 100644
--- a/platform/windows/lang_table.h
+++ b/platform/windows/lang_table.h
@@ -6,6 +6,7 @@
/* http://www.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 */
diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp
index 2046ae9f44..779f909a15 100644
--- a/platform/windows/os_windows.cpp
+++ b/platform/windows/os_windows.cpp
@@ -6,6 +6,7 @@
/* http://www.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 */
@@ -36,15 +37,15 @@
#include "drivers/windows/rw_lock_windows.h"
#include "drivers/windows/semaphore_windows.h"
#include "drivers/windows/thread_windows.h"
-#include "servers/audio_server.h"
-#include "servers/visual/visual_server_raster.h"
-//#include "servers/visual/visual_server_wrap_mt.h"
-#include "global_config.h"
#include "io/marshalls.h"
#include "joypad.h"
#include "lang_table.h"
#include "main/main.h"
#include "packet_peer_udp_winsock.h"
+#include "project_settings.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"
@@ -214,15 +215,11 @@ bool OS_Windows::can_draw() const {
void OS_Windows::_touch_event(bool p_pressed, int p_x, int p_y, int idx) {
- InputEvent event;
- event.type = InputEvent::SCREEN_TOUCH;
- event.ID = ++last_id;
- event.screen_touch.index = idx;
-
- event.screen_touch.pressed = p_pressed;
-
- event.screen_touch.x = p_x;
- event.screen_touch.y = p_y;
+ Ref<InputEventScreenTouch> event;
+ event.instance();
+ event->set_index(idx);
+ event->set_pressed(p_pressed);
+ event->set_position(Vector2(p_x, p_y));
if (main_loop) {
input->parse_input_event(event);
@@ -231,13 +228,10 @@ 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) {
- InputEvent event;
- event.type = InputEvent::SCREEN_DRAG;
- event.ID = ++last_id;
- event.screen_drag.index = idx;
-
- event.screen_drag.x = p_x;
- event.screen_drag.y = p_y;
+ Ref<InputEventScreenDrag> event;
+ event.instance();
+ event->set_index(idx);
+ event->set_position(Vector2(p_x, p_y));
if (main_loop)
input->parse_input_event(event);
@@ -368,23 +362,23 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
};
*/
- InputEvent event;
- event.type = InputEvent::MOUSE_MOTION;
- event.ID = ++last_id;
- InputEventMouseMotion &mm = event.mouse_motion;
+ Ref<InputEventMouseMotion> mm;
+ mm.instance();
- mm.mod.control = (wParam & MK_CONTROL) != 0;
- mm.mod.shift = (wParam & MK_SHIFT) != 0;
- mm.mod.alt = alt_mem;
+ mm->set_control((wParam & MK_CONTROL) != 0);
+ mm->set_shift((wParam & MK_SHIFT) != 0);
+ mm->set_alt(alt_mem);
- mm.button_mask |= (wParam & MK_LBUTTON) ? (1 << 0) : 0;
- mm.button_mask |= (wParam & MK_RBUTTON) ? (1 << 1) : 0;
- mm.button_mask |= (wParam & MK_MBUTTON) ? (1 << 2) : 0;
- last_button_state = mm.button_mask;
- /*mm.button_mask|=(wParam&MK_XBUTTON1)?(1<<5):0;
- mm.button_mask|=(wParam&MK_XBUTTON2)?(1<<6):0;*/
- mm.x = GET_X_LPARAM(lParam);
- mm.y = GET_Y_LPARAM(lParam);
+ int bmask = 0;
+ bmask |= (wParam & MK_LBUTTON) ? (1 << 0) : 0;
+ bmask |= (wParam & MK_RBUTTON) ? (1 << 1) : 0;
+ bmask |= (wParam & MK_MBUTTON) ? (1 << 2) : 0;
+ mm->set_button_mask(bmask);
+
+ last_button_state = mm->get_button_mask();
+ /*mm->get_button_mask()|=(wParam&MK_XBUTTON1)?(1<<5):0;
+ mm->get_button_mask()|=(wParam&MK_XBUTTON2)?(1<<6):0;*/
+ mm->set_position(Vector2(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)));
if (mouse_mode == MOUSE_MODE_CAPTURED) {
@@ -392,35 +386,33 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
old_x = c.x;
old_y = c.y;
- if (Point2i(mm.x, mm.y) == c) {
+ if (mm->get_position() == c) {
center = c;
return 0;
}
- Point2i ncenter(mm.x, mm.y);
+ Point2i ncenter = mm->get_position();
center = ncenter;
POINT pos = { (int)c.x, (int)c.y };
ClientToScreen(hWnd, &pos);
SetCursorPos(pos.x, pos.y);
}
- input->set_mouse_pos(Point2(mm.x, mm.y));
- mm.speed_x = input->get_last_mouse_speed().x;
- mm.speed_y = input->get_last_mouse_speed().y;
+ input->set_mouse_position(mm->get_position());
+ mm->set_speed(input->get_last_mouse_speed());
if (old_invalid) {
- old_x = mm.x;
- old_y = mm.y;
+ old_x = mm->get_position().x;
+ old_y = mm->get_position().y;
old_invalid = false;
}
- mm.relative_x = mm.x - old_x;
- mm.relative_y = mm.y - old_y;
- old_x = mm.x;
- old_y = mm.y;
+ mm->set_relative(Vector2(mm->get_position() - Vector2(old_x, old_y)));
+ old_x = mm->get_position().x;
+ old_y = mm->get_position().y;
if (window_has_focus && main_loop)
- input->parse_input_event(event);
+ input->parse_input_event(mm);
} break;
case WM_LBUTTONDOWN:
@@ -449,112 +441,110 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
};
*/
- InputEvent event;
- event.type = InputEvent::MOUSE_BUTTON;
- event.ID = ++last_id;
- InputEventMouseButton &mb = event.mouse_button;
+ Ref<InputEventMouseButton> mb;
+ mb.instance();
switch (uMsg) {
case WM_LBUTTONDOWN: {
- mb.pressed = true;
- mb.button_index = 1;
+ mb->set_pressed(true);
+ mb->set_button_index(1);
} break;
case WM_LBUTTONUP: {
- mb.pressed = false;
- mb.button_index = 1;
+ mb->set_pressed(false);
+ mb->set_button_index(1);
} break;
case WM_MBUTTONDOWN: {
- mb.pressed = true;
- mb.button_index = 3;
+ mb->set_pressed(true);
+ mb->set_button_index(3);
} break;
case WM_MBUTTONUP: {
- mb.pressed = false;
- mb.button_index = 3;
+ mb->set_pressed(false);
+ mb->set_button_index(3);
} break;
case WM_RBUTTONDOWN: {
- mb.pressed = true;
- mb.button_index = 2;
+ mb->set_pressed(true);
+ mb->set_button_index(2);
} break;
case WM_RBUTTONUP: {
- mb.pressed = false;
- mb.button_index = 2;
+ mb->set_pressed(false);
+ mb->set_button_index(2);
} break;
case WM_LBUTTONDBLCLK: {
- mb.pressed = true;
- mb.button_index = 1;
- mb.doubleclick = true;
+ mb->set_pressed(true);
+ mb->set_button_index(1);
+ mb->set_doubleclick(true);
} break;
case WM_RBUTTONDBLCLK: {
- mb.pressed = true;
- mb.button_index = 2;
- mb.doubleclick = true;
+ mb->set_pressed(true);
+ mb->set_button_index(2);
+ mb->set_doubleclick(true);
} break;
case WM_MOUSEWHEEL: {
- mb.pressed = true;
+ mb->set_pressed(true);
int motion = (short)HIWORD(wParam);
if (!motion)
return 0;
if (motion > 0)
- mb.button_index = BUTTON_WHEEL_UP;
+ mb->set_button_index(BUTTON_WHEEL_UP);
else
- mb.button_index = BUTTON_WHEEL_DOWN;
+ mb->set_button_index(BUTTON_WHEEL_DOWN);
} break;
case WM_MOUSEHWHEEL: {
- mb.pressed = true;
+ mb->set_pressed(true);
int motion = (short)HIWORD(wParam);
if (!motion)
return 0;
- if (motion < 0)
- mb.button_index = BUTTON_WHEEL_LEFT;
- else
- mb.button_index = BUTTON_WHEEL_RIGHT;
+ if (motion < 0) {
+ mb->set_button_index(BUTTON_WHEEL_LEFT);
+ mb->set_factor(fabs((double)motion / (double)WHEEL_DELTA));
+ } else {
+ mb->set_button_index(BUTTON_WHEEL_RIGHT);
+ mb->set_factor(fabs((double)motion / (double)WHEEL_DELTA));
+ }
} break;
/*
case WM_XBUTTONDOWN: {
- mb.pressed=true;
- mb.button_index=(HIWORD(wParam)==XBUTTON1)?6:7;
+ mb->is_pressed()=true;
+ mb->get_button_index()=(HIWORD(wParam)==XBUTTON1)?6:7;
} break;
case WM_XBUTTONUP:
- mb.pressed=true;
- mb.button_index=(HIWORD(wParam)==XBUTTON1)?6:7;
+ mb->is_pressed()=true;
+ mb->get_button_index()=(HIWORD(wParam)==XBUTTON1)?6:7;
} break;*/
default: { return 0; }
}
- mb.mod.control = (wParam & MK_CONTROL) != 0;
- mb.mod.shift = (wParam & MK_SHIFT) != 0;
- mb.mod.alt = alt_mem;
- //mb.mod.alt=(wParam&MK_MENU)!=0;
- mb.button_mask |= (wParam & MK_LBUTTON) ? (1 << 0) : 0;
- mb.button_mask |= (wParam & MK_RBUTTON) ? (1 << 1) : 0;
- mb.button_mask |= (wParam & MK_MBUTTON) ? (1 << 2) : 0;
-
- last_button_state = mb.button_mask;
+ mb->set_control((wParam & MK_CONTROL) != 0);
+ mb->set_shift((wParam & MK_SHIFT) != 0);
+ mb->set_alt(alt_mem);
+ //mb->get_alt()=(wParam&MK_MENU)!=0;
+ int bmask = 0;
+ bmask |= (wParam & MK_LBUTTON) ? (1 << 0) : 0;
+ bmask |= (wParam & MK_RBUTTON) ? (1 << 1) : 0;
+ bmask |= (wParam & MK_MBUTTON) ? (1 << 2) : 0;
+ mb->set_button_mask(bmask);
+
+ last_button_state = mb->get_button_mask();
/*
- mb.button_mask|=(wParam&MK_XBUTTON1)?(1<<5):0;
- mb.button_mask|=(wParam&MK_XBUTTON2)?(1<<6):0;*/
- mb.x = GET_X_LPARAM(lParam);
- mb.y = GET_Y_LPARAM(lParam);
+ mb->get_button_mask()|=(wParam&MK_XBUTTON1)?(1<<5):0;
+ mb->get_button_mask()|=(wParam&MK_XBUTTON2)?(1<<6):0;*/
+ mb->set_position(Vector2(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)));
if (mouse_mode == MOUSE_MODE_CAPTURED) {
- mb.x = old_x;
- mb.y = old_y;
+ mb->set_position(Vector2(old_x, old_y));
}
- mb.global_x = mb.x;
- mb.global_y = mb.y;
-
if (uMsg != WM_MOUSEWHEEL) {
- if (mb.pressed) {
+ if (mb->is_pressed()) {
if (++pressrc > 0)
SetCapture(hWnd);
@@ -568,22 +558,23 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
} else if (mouse_mode != MOUSE_MODE_CAPTURED) {
// for reasons unknown to mankind, wheel comes in screen cordinates
POINT coords;
- coords.x = mb.x;
- coords.y = mb.y;
+ coords.x = mb->get_position().x;
+ coords.y = mb->get_position().y;
ScreenToClient(hWnd, &coords);
- mb.x = coords.x;
- mb.y = coords.y;
+ mb->set_position(Vector2(coords.x, coords.y));
}
+ mb->set_global_position(mb->get_position());
+
if (main_loop) {
- input->parse_input_event(event);
- if (mb.pressed && mb.button_index > 3) {
+ input->parse_input_event(mb);
+ if (mb->is_pressed() && mb->get_button_index() > 3) {
//send release for mouse wheel
- mb.pressed = false;
- event.ID = ++last_id;
- input->parse_input_event(event);
+ Ref<InputEventMouseButton> mbd = mb->duplicate();
+ mbd->set_pressed(false);
+ input->parse_input_event(mbd);
}
}
}
@@ -639,10 +630,10 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
// Make sure we don't include modifiers for the modifier key itself.
KeyEvent ke;
- ke.mod_state.shift = (wParam != VK_SHIFT) ? shift_mem : false;
- ke.mod_state.alt = (!(wParam == VK_MENU && (uMsg == WM_KEYDOWN || uMsg == WM_SYSKEYDOWN))) ? alt_mem : false;
- ke.mod_state.control = (wParam != VK_CONTROL) ? control_mem : false;
- ke.mod_state.meta = meta_mem;
+ ke.shift = (wParam != VK_SHIFT) ? shift_mem : false;
+ ke.alt = (!(wParam == VK_MENU && (uMsg == WM_KEYDOWN || uMsg == WM_SYSKEYDOWN))) ? alt_mem : false;
+ ke.control = (wParam != VK_CONTROL) ? control_mem : false;
+ ke.meta = meta_mem;
ke.uMsg = uMsg;
if (ke.uMsg == WM_SYSKEYDOWN)
@@ -778,24 +769,25 @@ void OS_Windows::process_key_events() {
case WM_CHAR: {
if ((i == 0 && ke.uMsg == WM_CHAR) || (i > 0 && key_event_buffer[i - 1].uMsg == WM_CHAR)) {
- InputEvent event;
- event.type = InputEvent::KEY;
- event.ID = ++last_id;
- InputEventKey &k = event.key;
-
- k.mod = ke.mod_state;
- k.pressed = true;
- k.scancode = KeyMappingWindows::get_keysym(ke.wParam);
- k.unicode = ke.wParam;
- if (k.unicode && gr_mem) {
- k.mod.alt = false;
- k.mod.control = false;
+ Ref<InputEventKey> k;
+ k.instance();
+
+ k->set_shift(ke.shift);
+ k->set_alt(ke.alt);
+ k->set_control(ke.control);
+ k->set_metakey(ke.meta);
+ k->set_pressed(true);
+ k->set_scancode(KeyMappingWindows::get_keysym(ke.wParam));
+ k->set_unicode(ke.wParam);
+ if (k->get_unicode() && gr_mem) {
+ k->set_alt(false);
+ k->set_control(false);
}
- if (k.unicode < 32)
- k.unicode = 0;
+ if (k->get_unicode() < 32)
+ k->set_unicode(0);
- input->parse_input_event(event);
+ input->parse_input_event(k);
}
//do nothing
@@ -803,28 +795,37 @@ void OS_Windows::process_key_events() {
case WM_KEYUP:
case WM_KEYDOWN: {
- InputEvent event;
- event.type = InputEvent::KEY;
- event.ID = ++last_id;
- InputEventKey &k = event.key;
+ Ref<InputEventKey> k;
+ k.instance();
+
+ k->set_shift(ke.shift);
+ k->set_alt(ke.alt);
+ k->set_control(ke.control);
+ k->set_metakey(ke.meta);
- k.mod = ke.mod_state;
- k.pressed = (ke.uMsg == WM_KEYDOWN);
+ k->set_pressed(ke.uMsg == WM_KEYDOWN);
- k.scancode = KeyMappingWindows::get_keysym(ke.wParam);
- if (i + 1 < key_event_pos && key_event_buffer[i + 1].uMsg == WM_CHAR)
- k.unicode = key_event_buffer[i + 1].wParam;
- if (k.unicode && gr_mem) {
- k.mod.alt = false;
- k.mod.control = false;
+ if ((ke.lParam & (1 << 24)) && (ke.wParam == VK_RETURN)) {
+ // Special case for Numpad Enter key
+ k->set_scancode(KEY_KP_ENTER);
+ } else {
+ k->set_scancode(KeyMappingWindows::get_keysym(ke.wParam));
+ }
+
+ if (i + 1 < key_event_pos && key_event_buffer[i + 1].uMsg == WM_CHAR) {
+ k->set_unicode(key_event_buffer[i + 1].wParam);
+ }
+ if (k->get_unicode() && gr_mem) {
+ k->set_alt(false);
+ k->set_control(false);
}
- if (k.unicode < 32)
- k.unicode = 0;
+ if (k->get_unicode() < 32)
+ k->set_unicode(0);
- k.echo = (ke.uMsg == WM_KEYDOWN && (ke.lParam & (1 << 30)));
+ k->set_echo((ke.uMsg == WM_KEYDOWN && (ke.lParam & (1 << 30))));
- input->parse_input_event(event);
+ input->parse_input_event(k);
} break;
}
@@ -888,23 +889,6 @@ static int QueryDpiForMonitor(HMONITOR hmon, _MonitorDpiType dpiType = MDT_Defau
return (dpiX + dpiY) / 2;
}
-BOOL CALLBACK OS_Windows::MonitorEnumProc(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData) {
- OS_Windows *self = (OS_Windows *)OS::get_singleton();
- MonitorInfo minfo;
- minfo.hMonitor = hMonitor;
- minfo.hdcMonitor = hdcMonitor;
- minfo.rect.pos.x = lprcMonitor->left;
- minfo.rect.pos.y = lprcMonitor->top;
- minfo.rect.size.x = lprcMonitor->right - lprcMonitor->left;
- minfo.rect.size.y = lprcMonitor->bottom - lprcMonitor->top;
-
- minfo.dpi = QueryDpiForMonitor(hMonitor);
-
- self->monitor_info.push_back(minfo);
-
- return TRUE;
-}
-
void OS_Windows::initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver) {
main_loop = NULL;
@@ -940,9 +924,6 @@ void OS_Windows::initialize(const VideoMode &p_desired, int p_video_driver, int
return; // Return
}
- EnumDisplayMonitors(NULL, NULL, MonitorEnumProc, 0);
-
- print_line("DETECTED MONITORS: " + itos(monitor_info.size()));
pre_fs_valid = true;
if (video_mode.fullscreen) {
@@ -1033,12 +1014,10 @@ void OS_Windows::initialize(const VideoMode &p_desired, int p_video_driver, int
#endif
visual_server = memnew(VisualServerRaster);
- // FIXME: Reimplement threaded rendering? Or remove?
- /*
- if (get_render_thread_mode()!=RENDER_THREAD_UNSAFE) {
- visual_server =memnew(VisualServerWrapMT(visual_server,get_render_thread_mode()==RENDER_SEPARATE_THREAD));
+ if (get_render_thread_mode() != RENDER_THREAD_UNSAFE) {
+
+ visual_server = memnew(VisualServerWrapMT(visual_server, get_render_thread_mode() == RENDER_SEPARATE_THREAD));
}
- */
physics_server = memnew(PhysicsServerSW);
physics_server->init();
@@ -1193,10 +1172,6 @@ void OS_Windows::finalize() {
main_loop = NULL;
- for (int i = 0; i < get_audio_driver_count(); i++) {
- AudioDriverManager::get_driver(i)->finish();
- }
-
memdelete(joypad);
memdelete(input);
@@ -1222,8 +1197,6 @@ void OS_Windows::finalize() {
physics_2d_server->finish();
memdelete(physics_2d_server);
-
- monitor_info.clear();
}
void OS_Windows::finalize_core() {
@@ -1324,7 +1297,7 @@ void OS_Windows::warp_mouse_pos(const Point2 &p_to) {
}
}
-Point2 OS_Windows::get_mouse_pos() const {
+Point2 OS_Windows::get_mouse_position() const {
return Point2(old_x, old_y);
}
@@ -1349,51 +1322,131 @@ OS::VideoMode OS_Windows::get_video_mode(int p_screen) const {
void OS_Windows::get_fullscreen_mode_list(List<VideoMode> *p_list, int p_screen) const {
}
+static BOOL CALLBACK _MonitorEnumProcCount(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData) {
+
+ int *data = (int *)dwData;
+ (*data)++;
+ return TRUE;
+}
+
int OS_Windows::get_screen_count() const {
- return monitor_info.size();
+ int data = 0;
+ EnumDisplayMonitors(NULL, NULL, _MonitorEnumProcCount, (LPARAM)&data);
+ return data;
}
-int OS_Windows::get_current_screen() const {
- HMONITOR monitor = MonitorFromWindow(hWnd, MONITOR_DEFAULTTONEAREST);
- for (int i = 0; i < monitor_info.size(); i++) {
- if (monitor_info[i].hMonitor == monitor)
- return i;
+typedef struct {
+ int count;
+ int screen;
+ HMONITOR monitor;
+} EnumScreenData;
+
+static BOOL CALLBACK _MonitorEnumProcScreen(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData) {
+
+ EnumScreenData *data = (EnumScreenData *)dwData;
+ if (data->monitor == hMonitor) {
+ data->screen = data->count;
}
- return 0;
+ data->count++;
+ return TRUE;
}
-void OS_Windows::set_current_screen(int p_screen) {
- ERR_FAIL_INDEX(p_screen, monitor_info.size());
+int OS_Windows::get_current_screen() const {
+
+ EnumScreenData data = { 0, 0, MonitorFromWindow(hWnd, MONITOR_DEFAULTTONEAREST) };
+ EnumDisplayMonitors(NULL, NULL, _MonitorEnumProcScreen, (LPARAM)&data);
+ return data.screen;
+}
+
+void OS_Windows::set_current_screen(int p_screen) {
Vector2 ofs = get_window_position() - get_screen_position(get_current_screen());
set_window_position(ofs + get_screen_position(p_screen));
}
+typedef struct {
+ int count;
+ int screen;
+ Point2 pos;
+} EnumPosData;
+
+static BOOL CALLBACK _MonitorEnumProcPos(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData) {
+
+ EnumPosData *data = (EnumPosData *)dwData;
+ if (data->count == data->screen) {
+ data->pos.x = lprcMonitor->left;
+ data->pos.y = lprcMonitor->top;
+ }
+
+ data->count++;
+ return TRUE;
+}
+
Point2 OS_Windows::get_screen_position(int p_screen) const {
- ERR_FAIL_INDEX_V(p_screen, monitor_info.size(), Point2());
- return Vector2(monitor_info[p_screen].rect.pos);
+ EnumPosData data = { 0, p_screen, Point2() };
+ EnumDisplayMonitors(NULL, NULL, _MonitorEnumProcPos, (LPARAM)&data);
+ return data.pos;
}
+
+typedef struct {
+ int count;
+ int screen;
+ Size2 size;
+} EnumSizeData;
+
+static BOOL CALLBACK _MonitorEnumProcSize(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData) {
+
+ EnumSizeData *data = (EnumSizeData *)dwData;
+ if (data->count == data->screen) {
+ data->size.x = lprcMonitor->right - lprcMonitor->left;
+ data->size.y = lprcMonitor->bottom - lprcMonitor->top;
+ }
+
+ data->count++;
+ return TRUE;
+}
+
Size2 OS_Windows::get_screen_size(int p_screen) const {
- ERR_FAIL_INDEX_V(p_screen, monitor_info.size(), Point2());
- return Vector2(monitor_info[p_screen].rect.size);
+ EnumSizeData data = { 0, p_screen, Size2() };
+ EnumDisplayMonitors(NULL, NULL, _MonitorEnumProcSize, (LPARAM)&data);
+ return data.size;
+}
+
+typedef struct {
+ int count;
+ int screen;
+ int dpi;
+} EnumDpiData;
+
+static BOOL CALLBACK _MonitorEnumProcDpi(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData) {
+
+ EnumDpiData *data = (EnumDpiData *)dwData;
+ if (data->count == data->screen) {
+ data->dpi = QueryDpiForMonitor(hMonitor);
+ }
+
+ data->count++;
+ return TRUE;
}
int OS_Windows::get_screen_dpi(int p_screen) const {
- ERR_FAIL_INDEX_V(p_screen, monitor_info.size(), 72);
- UINT dpix, dpiy;
- return monitor_info[p_screen].dpi;
+ EnumDpiData data = { 0, p_screen, 72 };
+ EnumDisplayMonitors(NULL, NULL, _MonitorEnumProcDpi, (LPARAM)&data);
+ return data.dpi;
}
+
Point2 OS_Windows::get_window_position() const {
RECT r;
GetWindowRect(hWnd, &r);
return Point2(r.left, r.top);
}
+
void OS_Windows::set_window_position(const Point2 &p_position) {
if (video_mode.fullscreen) return;
@@ -1416,28 +1469,21 @@ void OS_Windows::set_window_size(const Size2 p_size) {
return;
}
- RECT crect;
- GetClientRect(hWnd, &crect);
+ int w = p_size.width;
+ int h = p_size.height;
RECT rect;
GetWindowRect(hWnd, &rect);
- int dx = (rect.right - rect.left) - (crect.right - crect.left);
- int dy = (rect.bottom - rect.top) - (crect.bottom - crect.top);
- rect.right = rect.left + p_size.width + dx;
- rect.bottom = rect.top + p_size.height + dy;
+ if (video_mode.borderless_window == false) {
+ RECT crect;
+ GetClientRect(hWnd, &crect);
- //print_line("PRE: "+itos(rect.left)+","+itos(rect.top)+","+itos(rect.right-rect.left)+","+itos(rect.bottom-rect.top));
-
- /*if (video_mode.resizable) {
- AdjustWindowRect(&rect, WS_OVERLAPPEDWINDOW, FALSE);
- } else {
- AdjustWindowRect(&rect, WS_CAPTION | WS_POPUPWINDOW, FALSE);
- }*/
-
- //print_line("POST: "+itos(rect.left)+","+itos(rect.top)+","+itos(rect.right-rect.left)+","+itos(rect.bottom-rect.top));
+ w += (rect.right - rect.left) - (crect.right - crect.left);
+ h += (rect.bottom - rect.top) - (crect.bottom - crect.top);
+ }
- MoveWindow(hWnd, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, TRUE);
+ MoveWindow(hWnd, rect.left, rect.top, w, h, TRUE);
}
void OS_Windows::set_window_fullscreen(bool p_enabled) {
@@ -1457,21 +1503,18 @@ void OS_Windows::set_window_fullscreen(bool p_enabled) {
Point2 pos = get_screen_position(cs);
Size2 size = get_screen_size(cs);
- /* r.left = pos.x;
- r.top = pos.y;
- r.bottom = pos.y+size.y;
- r.right = pos.x+size.x;
-*/
- SetWindowLongPtr(hWnd, GWL_STYLE,
- WS_SYSMENU | WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_VISIBLE);
- MoveWindow(hWnd, pos.x, pos.y, size.width, size.height, TRUE);
-
video_mode.fullscreen = true;
+ _update_window_style(false);
+
+ MoveWindow(hWnd, pos.x, pos.y, size.width, size.height, TRUE);
+
} else {
RECT rect;
+ video_mode.fullscreen = false;
+
if (pre_fs_valid) {
rect = pre_fs_rect;
} else {
@@ -1481,35 +1524,12 @@ void OS_Windows::set_window_fullscreen(bool p_enabled) {
rect.bottom = video_mode.height;
}
- if (video_mode.resizable) {
+ _update_window_style(false);
- SetWindowLongPtr(hWnd, GWL_STYLE, WS_OVERLAPPEDWINDOW | WS_VISIBLE);
- //AdjustWindowRect(&rect, WS_OVERLAPPEDWINDOW, FALSE);
- MoveWindow(hWnd, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, TRUE);
- } else {
-
- SetWindowLongPtr(hWnd, GWL_STYLE, WS_CAPTION | WS_POPUPWINDOW | WS_VISIBLE);
- //AdjustWindowRect(&rect, WS_CAPTION | WS_POPUPWINDOW, FALSE);
- MoveWindow(hWnd, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, TRUE);
- }
+ MoveWindow(hWnd, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, TRUE);
- video_mode.fullscreen = false;
pre_fs_valid = true;
- /*
- DWORD dwExStyle=WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;
- DWORD dwStyle=WS_OVERLAPPEDWINDOW;
- if (!video_mode.resizable) {
- dwStyle &= ~WS_THICKFRAME;
- dwStyle &= ~WS_MAXIMIZEBOX;
- }
- AdjustWindowRectEx(&pre_fs_rect, dwStyle, FALSE, dwExStyle);
- video_mode.fullscreen=false;
- video_mode.width=pre_fs_rect.right-pre_fs_rect.left;
- video_mode.height=pre_fs_rect.bottom-pre_fs_rect.top;
-*/
}
-
- //MoveWindow(hWnd,r.left,r.top,p_size.x,p_size.y,TRUE);
}
bool OS_Windows::is_window_fullscreen() const {
@@ -1519,30 +1539,10 @@ void OS_Windows::set_window_resizable(bool p_enabled) {
if (video_mode.resizable == p_enabled)
return;
- /*
- GetWindowRect(hWnd,&pre_fs_rect);
- DWORD dwExStyle=WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;
- DWORD dwStyle=WS_OVERLAPPEDWINDOW;
- if (!p_enabled) {
- dwStyle &= ~WS_THICKFRAME;
- dwStyle &= ~WS_MAXIMIZEBOX;
- }
- AdjustWindowRectEx(&pre_fs_rect, dwStyle, FALSE, dwExStyle);
- */
-
- if (!video_mode.fullscreen) {
- if (p_enabled) {
- SetWindowLongPtr(hWnd, GWL_STYLE, WS_OVERLAPPEDWINDOW | WS_VISIBLE);
- } else {
- SetWindowLongPtr(hWnd, GWL_STYLE, WS_CAPTION | WS_MINIMIZEBOX | WS_POPUPWINDOW | WS_VISIBLE);
- }
-
- RECT rect;
- GetWindowRect(hWnd, &rect);
- MoveWindow(hWnd, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, TRUE);
- }
video_mode.resizable = p_enabled;
+
+ _update_window_style();
}
bool OS_Windows::is_window_resizable() const {
@@ -1582,13 +1582,66 @@ bool OS_Windows::is_window_maximized() const {
}
void OS_Windows::set_borderless_window(int p_borderless) {
+ if (video_mode.borderless_window == p_borderless)
+ return;
+
video_mode.borderless_window = p_borderless;
+
+ _update_window_style();
}
bool OS_Windows::get_borderless_window() {
return video_mode.borderless_window;
}
+void OS_Windows::_update_window_style(bool repaint) {
+ if (video_mode.fullscreen || video_mode.borderless_window) {
+ SetWindowLongPtr(hWnd, GWL_STYLE, WS_SYSMENU | WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_VISIBLE);
+ } else {
+ if (video_mode.resizable) {
+ SetWindowLongPtr(hWnd, GWL_STYLE, WS_OVERLAPPEDWINDOW | WS_VISIBLE);
+ } else {
+ SetWindowLongPtr(hWnd, GWL_STYLE, WS_CAPTION | WS_MINIMIZEBOX | WS_POPUPWINDOW | WS_VISIBLE);
+ }
+ }
+
+ if (repaint) {
+ RECT rect;
+ GetWindowRect(hWnd, &rect);
+ MoveWindow(hWnd, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, TRUE);
+ }
+}
+
+Error OS_Windows::open_dynamic_library(const String p_path, void *&p_library_handle) {
+ p_library_handle = (void *)LoadLibrary(p_path.utf8().get_data());
+ if (!p_library_handle) {
+ ERR_EXPLAIN("Can't open dynamic library: " + p_path + ". Error: " + String::num(GetLastError()));
+ ERR_FAIL_V(ERR_CANT_OPEN);
+ }
+ return OK;
+}
+
+Error OS_Windows::close_dynamic_library(void *p_library_handle) {
+ if (!FreeLibrary((HMODULE)p_library_handle)) {
+ return FAILED;
+ }
+ return OK;
+}
+
+Error OS_Windows::get_dynamic_library_symbol_handle(void *p_library_handle, const String p_name, void *&p_symbol_handle, bool p_optional) {
+ char *error;
+ p_symbol_handle = (void *)GetProcAddress((HMODULE)p_library_handle, p_name.utf8().get_data());
+ if (!p_symbol_handle) {
+ if (!p_optional) {
+ ERR_EXPLAIN("Can't resolve symbol " + p_name + ". Error: " + String::num(GetLastError()));
+ ERR_FAIL_V(ERR_CANT_RESOLVE);
+ } else {
+ return ERR_CANT_RESOLVE;
+ }
+ }
+ return OK;
+}
+
void OS_Windows::request_attention() {
FLASHWINFO info;
@@ -1819,7 +1872,7 @@ void OS_Windows::process_events() {
MSG msg;
- last_id = joypad->process_joypads(last_id);
+ joypad->process_joypads();
while (PeekMessageW(&msg, NULL, 0, 0, PM_REMOVE)) {
@@ -1953,7 +2006,7 @@ Error OS_Windows::kill(const ProcessID &p_pid) {
return ret != 0 ? OK : FAILED;
};
-int OS_Windows::get_process_ID() const {
+int OS_Windows::get_process_id() const {
return _getpid();
}
@@ -1970,17 +2023,17 @@ String OS_Windows::get_executable_path() const {
wchar_t bufname[4096];
GetModuleFileNameW(NULL, bufname, 4096);
String s = bufname;
- print_line("EXEC PATHP??: " + s);
return s;
}
-void OS_Windows::set_icon(const Image &p_icon) {
+void OS_Windows::set_icon(const Ref<Image> &p_icon) {
- Image icon = p_icon;
- if (icon.get_format() != Image::FORMAT_RGBA8)
- icon.convert(Image::FORMAT_RGBA8);
- int w = icon.get_width();
- int h = icon.get_height();
+ ERR_FAIL_COND(!p_icon.is_valid());
+ Ref<Image> icon = p_icon->duplicate();
+ if (icon->get_format() != Image::FORMAT_RGBA8)
+ icon->convert(Image::FORMAT_RGBA8);
+ int w = icon->get_width();
+ int h = icon->get_height();
/* Create temporary bitmap buffer */
int icon_len = 40 + h * w * 4;
@@ -2001,7 +2054,7 @@ void OS_Windows::set_icon(const Image &p_icon) {
encode_uint32(0, &icon_bmp[36]);
uint8_t *wr = &icon_bmp[40];
- PoolVector<uint8_t>::Read r = icon.get_data().read();
+ PoolVector<uint8_t>::Read r = icon->get_data().read();
for (int i = 0; i < h; i++) {
@@ -2239,7 +2292,7 @@ String OS_Windows::get_data_dir() const {
if (has_environment("APPDATA")) {
- bool use_godot = GlobalConfig::get_singleton()->get("application/use_shared_user_dir");
+ 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
@@ -2247,7 +2300,7 @@ String OS_Windows::get_data_dir() const {
}
}
- return GlobalConfig::get_singleton()->get_resource_path();
+ return ProjectSettings::get_singleton()->get_resource_path();
}
bool OS_Windows::is_joy_known(int p_device) {
@@ -2284,9 +2337,9 @@ int OS_Windows::get_power_percent_left() {
return power_manager->get_power_percent_left();
}
-bool OS_Windows::check_feature_support(const String &p_feature) {
+bool OS_Windows::_check_internal_feature_support(const String &p_feature) {
- return VisualServer::get_singleton()->has_os_feature(p_feature);
+ return p_feature == "pc" || p_feature == "s3tc";
}
OS_Windows::OS_Windows(HINSTANCE _hInstance) {
@@ -2303,7 +2356,6 @@ OS_Windows::OS_Windows(HINSTANCE _hInstance) {
hInstance = _hInstance;
pressrc = 0;
old_invalid = true;
- last_id = 0;
mouse_mode = MOUSE_MODE_VISIBLE;
#ifdef STDOUT_FILE
stdo = fopen("stdout.txt", "wb");
diff --git a/platform/windows/os_windows.h b/platform/windows/os_windows.h
index e7376d6800..e9af14f11c 100644
--- a/platform/windows/os_windows.h
+++ b/platform/windows/os_windows.h
@@ -6,6 +6,7 @@
/* http://www.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 */
@@ -67,7 +68,7 @@ class OS_Windows : public OS {
struct KeyEvent {
- InputModifierState mod_state;
+ bool alt, shift, control, meta;
UINT uMsg;
WPARAM wParam;
LPARAM lParam;
@@ -83,7 +84,6 @@ class OS_Windows : public OS {
bool outside;
int old_x, old_y;
Point2i center;
- unsigned int last_id;
#if defined(OPENGL_ENABLED)
ContextGL_Win *gl_context;
#endif
@@ -133,6 +133,8 @@ class OS_Windows : public OS {
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 _update_window_style(bool repaint = true);
+
// functions used by main to initialize/deintialize the OS
protected:
virtual int get_video_driver_count() const;
@@ -162,22 +164,12 @@ protected:
};
Map<ProcessID, ProcessInfo> *process_map;
- struct MonitorInfo {
- HMONITOR hMonitor;
- HDC hdcMonitor;
- Rect2 rect;
- int dpi;
- };
-
bool pre_fs_valid;
RECT pre_fs_rect;
- Vector<MonitorInfo> monitor_info;
bool maximized;
bool minimized;
bool borderless;
- static BOOL CALLBACK MonitorEnumProc(HMONITOR hMonitor, HDC hdcMonitor, LPRECT lprcMonitor, LPARAM dwData);
-
public:
LRESULT WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
@@ -191,7 +183,7 @@ public:
MouseMode get_mouse_mode() const;
virtual void warp_mouse_pos(const Point2 &p_to);
- virtual Point2 get_mouse_pos() const;
+ virtual Point2 get_mouse_position() const;
virtual int get_mouse_button_state() const;
virtual void set_window_title(const String &p_title);
@@ -223,6 +215,10 @@ public:
virtual void set_borderless_window(int p_borderless);
virtual bool get_borderless_window();
+ virtual Error open_dynamic_library(const String p_path, void *&p_library_handle);
+ 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 MainLoop *get_main_loop() const;
virtual String get_name();
@@ -241,7 +237,7 @@ public:
virtual Error execute(const String &p_path, const List<String> &p_arguments, bool p_blocking, ProcessID *r_child_id = NULL, String *r_pipe = NULL, int *r_exitcode = NULL);
virtual Error kill(const ProcessID &p_pid);
- virtual int get_process_ID() const;
+ virtual int get_process_id() const;
virtual bool has_environment(const String &p_var) const;
virtual String get_environment(const String &p_var) const;
@@ -250,7 +246,7 @@ public:
virtual String get_clipboard() const;
void set_cursor_shape(CursorShape p_shape);
- void set_icon(const Image &p_icon);
+ void set_icon(const Ref<Image> &p_icon);
virtual String get_executable_path() const;
@@ -282,7 +278,7 @@ public:
virtual int get_power_seconds_left();
virtual int get_power_percent_left();
- virtual bool check_feature_support(const String &p_feature);
+ virtual bool _check_internal_feature_support(const String &p_feature);
OS_Windows(HINSTANCE _hInstance);
~OS_Windows();
diff --git a/platform/windows/packet_peer_udp_winsock.cpp b/platform/windows/packet_peer_udp_winsock.cpp
index d98b64df7c..3991a90423 100644
--- a/platform/windows/packet_peer_udp_winsock.cpp
+++ b/platform/windows/packet_peer_udp_winsock.cpp
@@ -6,6 +6,7 @@
/* http://www.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 */
@@ -117,7 +118,7 @@ void PacketPeerUDPWinsock::_set_sock_blocking(bool p_blocking) {
};
}
-Error PacketPeerUDPWinsock::listen(int p_port, IP_Address p_bind_address, int p_recv_buffer_size) {
+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);
@@ -202,6 +203,8 @@ Error PacketPeerUDPWinsock::_poll(bool p_wait) {
len = sizeof(struct sockaddr_storage);
++queue_count;
+ if (p_wait)
+ break;
};
if (ret == SOCKET_ERROR) {
diff --git a/platform/windows/packet_peer_udp_winsock.h b/platform/windows/packet_peer_udp_winsock.h
index 6b37aefead..01f2e5113f 100644
--- a/platform/windows/packet_peer_udp_winsock.h
+++ b/platform/windows/packet_peer_udp_winsock.h
@@ -6,6 +6,7 @@
/* http://www.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 */
@@ -66,7 +67,7 @@ public:
virtual int get_max_packet_size() const;
- virtual Error listen(int p_port, IP_Address p_bind_address = IP_Address("*"), int p_recv_buffer_size = 65536);
+ 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;
diff --git a/platform/windows/platform_config.h b/platform/windows/platform_config.h
index 0e16753156..a0fc65ca89 100644
--- a/platform/windows/platform_config.h
+++ b/platform/windows/platform_config.h
@@ -6,6 +6,7 @@
/* http://www.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 */
diff --git a/platform/windows/power_windows.cpp b/platform/windows/power_windows.cpp
index d4641cd4ec..428bc5dcc2 100644
--- a/platform/windows/power_windows.cpp
+++ b/platform/windows/power_windows.cpp
@@ -6,6 +6,7 @@
/* http://www.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 */
@@ -27,6 +28,31 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+/*
+Adapted from corresponding SDL 2.0 code.
+*/
+
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
#include "power_windows.h"
// CODE CHUNK IMPORTED FROM SDL 2.0
diff --git a/platform/windows/power_windows.h b/platform/windows/power_windows.h
index 5c26faa3d1..164f1d7d95 100644
--- a/platform/windows/power_windows.h
+++ b/platform/windows/power_windows.h
@@ -6,6 +6,7 @@
/* http://www.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 */
diff --git a/platform/windows/stream_peer_winsock.cpp b/platform/windows/stream_peer_winsock.cpp
index abf182c72a..18c5a40b80 100644
--- a/platform/windows/stream_peer_winsock.cpp
+++ b/platform/windows/stream_peer_winsock.cpp
@@ -6,6 +6,7 @@
/* http://www.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 */
diff --git a/platform/windows/stream_peer_winsock.h b/platform/windows/stream_peer_winsock.h
index c8c2dd4feb..aa60a6500b 100644
--- a/platform/windows/stream_peer_winsock.h
+++ b/platform/windows/stream_peer_winsock.h
@@ -6,6 +6,7 @@
/* http://www.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 */
diff --git a/platform/windows/tcp_server_winsock.cpp b/platform/windows/tcp_server_winsock.cpp
index 67713f5d1c..cc17c8a631 100644
--- a/platform/windows/tcp_server_winsock.cpp
+++ b/platform/windows/tcp_server_winsock.cpp
@@ -6,6 +6,7 @@
/* http://www.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 */
@@ -62,7 +63,7 @@ void TCPServerWinsock::cleanup() {
};
};
-Error TCPServerWinsock::listen(uint16_t p_port, const IP_Address p_bind_address) {
+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);
diff --git a/platform/windows/tcp_server_winsock.h b/platform/windows/tcp_server_winsock.h
index d7b1aee054..077acb94d7 100644
--- a/platform/windows/tcp_server_winsock.h
+++ b/platform/windows/tcp_server_winsock.h
@@ -6,6 +6,7 @@
/* http://www.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 */
@@ -39,7 +40,7 @@ class TCPServerWinsock : public TCP_Server {
static TCP_Server *_create();
public:
- virtual Error listen(uint16_t p_port, const IP_Address p_bind_address = IP_Address("*"));
+ 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();
diff --git a/platform/x11/context_gl_x11.cpp b/platform/x11/context_gl_x11.cpp
index 41d110a1e1..ddf17481b1 100644
--- a/platform/x11/context_gl_x11.cpp
+++ b/platform/x11/context_gl_x11.cpp
@@ -6,6 +6,7 @@
/* http://www.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 */
@@ -151,8 +152,6 @@ Error ContextGL_X11::initialize() {
XSync(x11_display, False);
XSetErrorHandler(oldHandler);
- print_line("ALL IS GOOD");
-
glXMakeCurrent(x11_display, x11_window, p->glx_context);
/*
diff --git a/platform/x11/context_gl_x11.h b/platform/x11/context_gl_x11.h
index be0f4c822c..acb3f38894 100644
--- a/platform/x11/context_gl_x11.h
+++ b/platform/x11/context_gl_x11.h
@@ -6,6 +6,7 @@
/* http://www.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 */
diff --git a/platform/x11/detect.py b/platform/x11/detect.py
index 89cf639114..79778136ad 100644
--- a/platform/x11/detect.py
+++ b/platform/x11/detect.py
@@ -1,7 +1,6 @@
-
import os
-import sys
import platform
+import sys
def is_active():
@@ -14,15 +13,12 @@ def get_name():
def can_build():
- if (os.name != "posix"):
+ if (os.name != "posix" or sys.platform == "darwin"):
return False
- if sys.platform == "darwin":
- return False # no x11 on mac for now
-
- errorval = os.system("pkg-config --version > /dev/null")
-
- if (errorval):
+ # Check the minimal dependencies
+ x11_error = os.system("pkg-config --version > /dev/null")
+ if (x11_error):
print("pkg-config not found.. x11 disabled.")
return False
@@ -31,11 +27,6 @@ def can_build():
print("X11 not found.. x11 disabled.")
return False
- ssl_error = os.system("pkg-config openssl --modversion > /dev/null ")
- if (ssl_error):
- print("OpenSSL not found.. x11 disabled.")
- return False
-
x11_error = os.system("pkg-config xcursor --modversion > /dev/null ")
if (x11_error):
print("xcursor not found.. x11 disabled.")
@@ -51,18 +42,18 @@ def can_build():
print("xrandr not found.. x11 disabled.")
return False
- return True # X11 enabled
+ return True
def get_opts():
return [
- ('use_llvm', 'Use llvm compiler', 'no'),
- ('use_static_cpp', 'link stdc++ statically', 'no'),
- ('use_sanitizer', 'Use llvm compiler sanitize address', 'no'),
- ('use_leak_sanitizer', 'Use llvm compiler sanitize memory leaks', 'no'),
+ ('use_llvm', 'Use the LLVM compiler', 'no'),
+ ('use_static_cpp', 'Link stdc++ statically', 'no'),
+ ('use_sanitizer', 'Use LLVM compiler address sanitizer', 'no'),
+ ('use_leak_sanitizer', 'Use LLVM compiler memory leaks sanitizer (implies use_sanitizer)', 'no'),
('use_lto', 'Use link time optimization', 'no'),
- ('pulseaudio', 'Detect & Use pulseaudio', 'yes'),
+ ('pulseaudio', 'Detect & use pulseaudio', 'yes'),
('udev', 'Use udev for gamepad connection callbacks', 'no'),
('debug_release', 'Add debug symbols to release version', 'no'),
]
@@ -80,67 +71,72 @@ def get_flags():
def configure(env):
- is64 = sys.maxsize > 2**32
+ ## Build type
+
+ if (env["target"] == "release"):
+ env.Prepend(CCFLAGS=['-Ofast'])
+ if (env["debug_release"] == "yes"):
+ env.Prepend(CCFLAGS=['-g2'])
+
+ elif (env["target"] == "release_debug"):
+ env.Prepend(CCFLAGS=['-O2', '-ffast-math', '-DDEBUG_ENABLED'])
+ if (env["debug_release"] == "yes"):
+ env.Prepend(CCFLAGS=['-g2'])
+ elif (env["target"] == "debug"):
+ env.Prepend(CCFLAGS=['-g2', '-DDEBUG_ENABLED', '-DDEBUG_MEMORY_ENABLED'])
+
+ ## Architecture
+
+ is64 = sys.maxsize > 2**32
if (env["bits"] == "default"):
- if (is64):
- env["bits"] = "64"
- else:
- env["bits"] = "32"
+ env["bits"] = "64" if is64 else "32"
+
+ ## Compiler configuration
- env.Append(CPPPATH=['#platform/x11'])
if (env["use_llvm"] == "yes"):
- if 'clang++' not in env['CXX']:
+ if ('clang++' not in env['CXX']):
env["CC"] = "clang"
env["CXX"] = "clang++"
env["LD"] = "clang++"
env.Append(CPPFLAGS=['-DTYPED_METHOD_BIND'])
- env.extra_suffix = ".llvm"
-
- if (env["use_sanitizer"] == "yes"):
- env.Append(CCFLAGS=['-fsanitize=address', '-fno-omit-frame-pointer'])
- env.Append(LINKFLAGS=['-fsanitize=address'])
- env.extra_suffix += "s"
+ env.extra_suffix = ".llvm" + env.extra_suffix
- if (env["use_leak_sanitizer"] == "yes"):
+ # leak sanitizer requires (address) sanitizer
+ if (env["use_sanitizer"] == "yes" or env["use_leak_sanitizer"] == "yes"):
env.Append(CCFLAGS=['-fsanitize=address', '-fno-omit-frame-pointer'])
env.Append(LINKFLAGS=['-fsanitize=address'])
env.extra_suffix += "s"
-
- # if (env["tools"]=="no"):
- # #no tools suffix
- # env['OBJSUFFIX'] = ".nt"+env['OBJSUFFIX']
- # env['LIBSUFFIX'] = ".nt"+env['LIBSUFFIX']
+ if (env["use_leak_sanitizer"] == "yes"):
+ env.Append(CCFLAGS=['-fsanitize=leak'])
+ env.Append(LINKFLAGS=['-fsanitize=leak'])
if (env["use_lto"] == "yes"):
env.Append(CCFLAGS=['-flto'])
env.Append(LINKFLAGS=['-flto'])
-
env.Append(CCFLAGS=['-pipe'])
env.Append(LINKFLAGS=['-pipe'])
- if (env["target"] == "release"):
- env.Prepend(CCFLAGS=['-Ofast'])
- if (env["debug_release"] == "yes"):
- env.Prepend(CCFLAGS=['-g2'])
-
- elif (env["target"] == "release_debug"):
-
- env.Prepend(CCFLAGS=['-O2', '-ffast-math', '-DDEBUG_ENABLED'])
- if (env["debug_release"] == "yes"):
- env.Prepend(CCFLAGS=['-g2'])
-
- elif (env["target"] == "debug"):
-
- env.Prepend(CCFLAGS=['-g2', '-Wall', '-DDEBUG_ENABLED', '-DDEBUG_MEMORY_ENABLED'])
+ ## Dependencies
env.ParseConfig('pkg-config x11 --cflags --libs')
- env.ParseConfig('pkg-config xinerama --cflags --libs')
env.ParseConfig('pkg-config xcursor --cflags --libs')
+ env.ParseConfig('pkg-config xinerama --cflags --libs')
env.ParseConfig('pkg-config xrandr --cflags --libs')
+ # FIXME: Check for existence of the libs before parsing their flags with pkg-config
+
if (env['builtin_openssl'] == 'no'):
+ # Currently not compatible with OpenSSL 1.1.0+
+ # https://github.com/godotengine/godot/issues/8624
+ import subprocess
+ openssl_version = subprocess.check_output(['pkg-config', 'openssl', '--modversion']).strip('\n')
+ if (openssl_version >= "1.1.0"):
+ print("Error: Found system-installed OpenSSL %s, currently only supporting version 1.0.x." % openssl_version)
+ print("Aborting.. You can compile with 'builtin_openssl=yes' to use the bundled version.\n")
+ sys.exit(255)
+
env.ParseConfig('pkg-config openssl --cflags --libs')
if (env['builtin_libwebp'] == 'no'):
@@ -187,47 +183,51 @@ def configure(env):
if (env['builtin_libogg'] == 'no'):
env.ParseConfig('pkg-config ogg --cflags --libs')
- env.Append(CPPFLAGS=['-DOPENGL_ENABLED'])
+ if (env['builtin_libtheora'] != 'no'):
+ list_of_x86 = ['x86_64', 'x86', 'i386', 'i586']
+ if any(platform.machine() in s for s in list_of_x86):
+ env["x86_libtheora_opt_gcc"] = True
- if os.system("pkg-config --exists alsa") == 0:
+ ## Flags
+
+ if (os.system("pkg-config --exists alsa") == 0): # 0 means found
print("Enabling ALSA")
env.Append(CPPFLAGS=["-DALSA_ENABLED"])
env.ParseConfig('pkg-config alsa --cflags --libs')
else:
print("ALSA libraries not found, disabling driver")
- if (platform.system() == "Linux"):
- env.Append(CPPFLAGS=["-DJOYDEV_ENABLED"])
- if (env["udev"] == "yes"):
- # pkg-config returns 0 when the lib exists...
- found_udev = not os.system("pkg-config --exists libudev")
-
- if (found_udev):
- print("Enabling udev support")
- env.Append(CPPFLAGS=["-DUDEV_ENABLED"])
- env.ParseConfig('pkg-config libudev --cflags --libs')
- else:
- print("libudev development libraries not found, disabling udev support")
-
if (env["pulseaudio"] == "yes"):
- if not os.system("pkg-config --exists libpulse-simple"):
+ if (os.system("pkg-config --exists libpulse-simple") == 0): # 0 means found
print("Enabling PulseAudio")
env.Append(CPPFLAGS=["-DPULSEAUDIO_ENABLED"])
env.ParseConfig('pkg-config --cflags --libs libpulse-simple')
else:
print("PulseAudio development libraries not found, disabling driver")
+ if (platform.system() == "Linux"):
+ env.Append(CPPFLAGS=["-DJOYDEV_ENABLED"])
+
+ if (env["udev"] == "yes"):
+ if (os.system("pkg-config --exists libudev") == 0): # 0 means found
+ print("Enabling udev support")
+ env.Append(CPPFLAGS=["-DUDEV_ENABLED"])
+ env.ParseConfig('pkg-config libudev --cflags --libs')
+ else:
+ print("libudev development libraries not found, disabling udev support")
+
+ # Linkflags below this line should typically stay the last ones
if (env['builtin_zlib'] == 'no'):
env.ParseConfig('pkg-config zlib --cflags --libs')
- env.Append(CPPFLAGS=['-DX11_ENABLED', '-DUNIX_ENABLED', '-DGLES2_ENABLED', '-DGLES_OVER_GL'])
+ env.Append(CPPPATH=['#platform/x11'])
+ env.Append(CPPFLAGS=['-DX11_ENABLED', '-DUNIX_ENABLED', '-DOPENGL_ENABLED', '-DGLES2_ENABLED', '-DGLES_OVER_GL'])
env.Append(LIBS=['GL', 'pthread'])
if (platform.system() == "Linux"):
env.Append(LIBS=['dl'])
- # env.Append(CPPFLAGS=['-DMPC_FIXED_POINT'])
-# host compiler is default..
+ ## Cross-compilation
if (is64 and env["bits"] == "32"):
env.Append(CPPFLAGS=['-m32'])
@@ -236,17 +236,5 @@ def configure(env):
env.Append(CPPFLAGS=['-m64'])
env.Append(LINKFLAGS=['-m64', '-L/usr/lib/i686-linux-gnu'])
- import methods
-
- # FIXME: Commented out when moving to gles3
- #env.Append(BUILDERS={'GLSL120': env.Builder(action=methods.build_legacygl_headers, suffix='glsl.h', src_suffix='.glsl')})
- #env.Append(BUILDERS={'GLSL': env.Builder(action=methods.build_glsl_headers, suffix='glsl.h', src_suffix='.glsl')})
- #env.Append(BUILDERS={'GLSL120GLES': env.Builder(action=methods.build_gles2_headers, suffix='glsl.h', src_suffix='.glsl')})
- #env.Append( BUILDERS = { 'HLSL9' : env.Builder(action = methods.build_hlsl_dx9_headers, suffix = 'hlsl.h',src_suffix = '.hlsl') } )
-
if (env["use_static_cpp"] == "yes"):
env.Append(LINKFLAGS=['-static-libstdc++'])
-
- list_of_x86 = ['x86_64', 'x86', 'i386', 'i586']
- if any(platform.machine() in s for s in list_of_x86):
- env["x86_libtheora_opt_gcc"] = True
diff --git a/platform/x11/export/export.cpp b/platform/x11/export/export.cpp
index e58c55b51d..c8d6220aed 100644
--- a/platform/x11/export/export.cpp
+++ b/platform/x11/export/export.cpp
@@ -6,6 +6,7 @@
/* http://www.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 */
@@ -28,7 +29,7 @@
/*************************************************************************/
#include "export.h"
#include "editor/editor_export.h"
-#include "platform/x11/logo.h"
+#include "platform/x11/logo.gen.h"
#include "scene/resources/texture.h"
void register_x11_exporter() {
@@ -36,7 +37,7 @@ void register_x11_exporter() {
Ref<EditorExportPlatformPC> platform;
platform.instance();
- Image img(_x11_logo);
+ Ref<Image> img = memnew(Image(_x11_logo));
Ref<ImageTexture> logo;
logo.instance();
logo->create_from_image(img);
@@ -47,6 +48,7 @@ void register_x11_exporter() {
platform->set_debug_32("linux_x11_32_debug");
platform->set_release_64("linux_x11_64_release");
platform->set_debug_64("linux_x11_64_debug");
+ platform->set_os_name("X11");
EditorExport::get_singleton()->add_export_platform(platform);
diff --git a/platform/x11/export/export.h b/platform/x11/export/export.h
index 5beaba2cfb..755b73d2c9 100644
--- a/platform/x11/export/export.h
+++ b/platform/x11/export/export.h
@@ -6,6 +6,7 @@
/* http://www.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 */
diff --git a/platform/x11/godot_x11.cpp b/platform/x11/godot_x11.cpp
index 078baf76ee..6f418b213f 100644
--- a/platform/x11/godot_x11.cpp
+++ b/platform/x11/godot_x11.cpp
@@ -6,6 +6,7 @@
/* http://www.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 */
@@ -27,6 +28,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include <limits.h>
+#include <locale.h>
#include <stdlib.h>
#include <unistd.h>
@@ -37,6 +39,8 @@ int main(int argc, char *argv[]) {
OS_X11 os;
+ setlocale(LC_CTYPE, "");
+
char *cwd = (char *)malloc(PATH_MAX);
getcwd(cwd, PATH_MAX);
diff --git a/platform/x11/joypad_linux.cpp b/platform/x11/joypad_linux.cpp
index 62ece58f58..2502b2d51f 100644
--- a/platform/x11/joypad_linux.cpp
+++ b/platform/x11/joypad_linux.cpp
@@ -6,6 +6,7 @@
/* http://www.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 */
@@ -454,10 +455,10 @@ InputDefault::JoyAxis JoypadLinux::axis_correct(const input_absinfo *p_abs, int
return jx;
}
-uint32_t JoypadLinux::process_joypads(uint32_t p_event_id) {
+void JoypadLinux::process_joypads() {
if (joy_mutex->try_lock() != OK) {
- return p_event_id;
+ return;
}
for (int i = 0; i < JOYPADS_MAX; i++) {
@@ -477,11 +478,11 @@ uint32_t JoypadLinux::process_joypads(uint32_t p_event_id) {
// ev may be tainted and out of MAX_KEY range, which will cause
// joy->key_map[ev.code] to crash
if (ev.code < 0 || ev.code >= MAX_KEY)
- return p_event_id;
+ return;
switch (ev.type) {
case EV_KEY:
- p_event_id = input->joy_button(p_event_id, i, joy->key_map[ev.code], ev.value);
+ input->joy_button(i, joy->key_map[ev.code], ev.value);
break;
case EV_ABS:
@@ -496,7 +497,7 @@ uint32_t JoypadLinux::process_joypads(uint32_t p_event_id) {
} else
joy->dpad &= ~(InputDefault::HAT_MASK_LEFT | InputDefault::HAT_MASK_RIGHT);
- p_event_id = input->joy_hat(p_event_id, i, joy->dpad);
+ input->joy_hat(i, joy->dpad);
break;
case ABS_HAT0Y:
@@ -508,7 +509,7 @@ uint32_t JoypadLinux::process_joypads(uint32_t p_event_id) {
} else
joy->dpad &= ~(InputDefault::HAT_MASK_UP | InputDefault::HAT_MASK_DOWN);
- p_event_id = input->joy_hat(p_event_id, i, joy->dpad);
+ input->joy_hat(i, joy->dpad);
break;
default:
@@ -525,7 +526,7 @@ uint32_t JoypadLinux::process_joypads(uint32_t p_event_id) {
for (int j = 0; j < MAX_ABS; j++) {
int index = joy->abs_map[j];
if (index != -1) {
- p_event_id = input->joy_axis(p_event_id, i, index, joy->curr_axis[index]);
+ input->joy_axis(i, index, joy->curr_axis[index]);
}
}
if (len == 0 || (len < 0 && errno != EAGAIN)) {
@@ -546,6 +547,5 @@ uint32_t JoypadLinux::process_joypads(uint32_t p_event_id) {
}
}
joy_mutex->unlock();
- return p_event_id;
}
#endif
diff --git a/platform/x11/joypad_linux.h b/platform/x11/joypad_linux.h
index f90ca9319a..55383885a0 100644
--- a/platform/x11/joypad_linux.h
+++ b/platform/x11/joypad_linux.h
@@ -6,6 +6,7 @@
/* http://www.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 */
@@ -42,7 +43,7 @@ class JoypadLinux {
public:
JoypadLinux(InputDefault *in);
~JoypadLinux();
- uint32_t process_joypads(uint32_t p_event_id);
+ void process_joypads();
private:
enum {
@@ -79,22 +80,22 @@ private:
static void joy_thread_func(void *p_user);
- int get_joy_from_path(String path) const;
+ int get_joy_from_path(String p_path) const;
void setup_joypad_properties(int p_id);
void close_joypad(int p_id = -1);
#ifdef UDEV_ENABLED
- void enumerate_joypads(struct udev *_udev);
- void monitor_joypads(struct udev *_udev);
+ void enumerate_joypads(struct udev *p_udev);
+ void monitor_joypads(struct udev *p_udev);
#endif
void monitor_joypads();
void run_joypad_thread();
- void open_joypad(const char *path);
+ void open_joypad(const char *p_path);
void joypad_vibration_start(int p_id, float p_weak_magnitude, float p_strong_magnitude, float p_duration, uint64_t p_timestamp);
void joypad_vibration_stop(int p_id, uint64_t p_timestamp);
- InputDefault::JoyAxis axis_correct(const input_absinfo *abs, int value) const;
+ InputDefault::JoyAxis axis_correct(const input_absinfo *p_abs, int p_value) const;
};
#endif
diff --git a/platform/x11/key_mapping_x11.cpp b/platform/x11/key_mapping_x11.cpp
index 4cfcffede0..32a9806b22 100644
--- a/platform/x11/key_mapping_x11.cpp
+++ b/platform/x11/key_mapping_x11.cpp
@@ -6,6 +6,7 @@
/* http://www.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 */
@@ -43,7 +44,7 @@ static _XTranslatePair _xkeysym_to_keycode[] = {
{ XK_Tab, KEY_TAB },
{ XK_ISO_Left_Tab, KEY_BACKTAB },
{ XK_BackSpace, KEY_BACKSPACE },
- { XK_Return, KEY_RETURN },
+ { XK_Return, KEY_ENTER },
{ XK_Insert, KEY_INSERT },
{ XK_Delete, KEY_DELETE },
{ XK_Clear, KEY_DELETE },
@@ -77,7 +78,7 @@ static _XTranslatePair _xkeysym_to_keycode[] = {
{ XK_Help, KEY_HELP },
{ XK_KP_Space, KEY_SPACE },
{ XK_KP_Tab, KEY_TAB },
- { XK_KP_Enter, KEY_ENTER },
+ { XK_KP_Enter, KEY_KP_ENTER },
{ XK_Home, KEY_HOME },
{ XK_Left, KEY_LEFT },
{ XK_Up, KEY_UP },
@@ -93,7 +94,6 @@ static _XTranslatePair _xkeysym_to_keycode[] = {
//{ XK_KP_Separator, KEY_COMMA },
{ XK_KP_Decimal, KEY_KP_PERIOD },
{ XK_KP_Delete, KEY_KP_PERIOD },
- { XK_KP_Enter, KEY_KP_ENTER },
{ XK_KP_Multiply, KEY_KP_MULTIPLY },
{ XK_KP_Divide, KEY_KP_DIVIDE },
{ XK_KP_Subtract, KEY_KP_SUBTRACT },
diff --git a/platform/x11/key_mapping_x11.h b/platform/x11/key_mapping_x11.h
index 8210df06e7..41060c9303 100644
--- a/platform/x11/key_mapping_x11.h
+++ b/platform/x11/key_mapping_x11.h
@@ -6,6 +6,7 @@
/* http://www.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 */
diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp
index fe162370aa..ade3a0a0c5 100644
--- a/platform/x11/os_x11.cpp
+++ b/platform/x11/os_x11.cpp
@@ -6,6 +6,7 @@
/* http://www.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 */
@@ -33,6 +34,7 @@
#include "print_string.h"
#include "servers/physics/physics_server_sw.h"
#include "servers/visual/visual_server_raster.h"
+#include "servers/visual/visual_server_wrap_mt.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -66,6 +68,8 @@
#undef CursorShape
+#include <X11/XKBlib.h>
+
int OS_X11::get_video_driver_count() const {
return 1;
}
@@ -91,10 +95,10 @@ const char *OS_X11::get_audio_driver_name(int p_driver) const {
void OS_X11::initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver) {
+ long im_event_mask = 0;
last_button_state = 0;
xmbstring = NULL;
- event_id = 0;
x11_window = 0;
last_click_ms = 0;
args = OS::get_singleton()->get_cmdline_args();
@@ -112,7 +116,32 @@ void OS_X11::initialize(const VideoMode &p_desired, int p_video_driver, int p_au
/** XLIB INITIALIZATION **/
x11_display = XOpenDisplay(NULL);
- char *modifiers = XSetLocaleModifiers("@im=none");
+ Bool xkb_dar = False;
+ if (x11_display) {
+ XAutoRepeatOn(x11_display);
+ xkb_dar = XkbSetDetectableAutoRepeat(x11_display, True, NULL);
+ }
+
+ char *modifiers = NULL;
+
+ // 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
+ modifiers = XSetLocaleModifiers("");
+#endif
+ }
+
+ if (modifiers == NULL) {
+ if (is_stdout_verbose()) {
+ WARN_PRINT("IME is disabled");
+ }
+ modifiers = XSetLocaleModifiers("@im=none");
+ }
if (modifiers == NULL) {
WARN_PRINT("Error setting locale modifiers");
}
@@ -152,6 +181,14 @@ void OS_X11::initialize(const VideoMode &p_desired, int p_video_driver, int p_au
WARN_PRINT("XOpenIM failed");
xim_style = 0L;
} else {
+ ::XIMCallback im_destroy_callback;
+ im_destroy_callback.client_data = (::XPointer)(this);
+ im_destroy_callback.callback = (::XIMProc)(xim_destroy_callback);
+ if (XSetIMValues(xim, XNDestroyCallback, &im_destroy_callback,
+ NULL) != NULL) {
+ WARN_PRINT("Error setting XIM destroy callback");
+ }
+
::XIMStyles *xim_styles = NULL;
xim_style = 0L;
char *imvalret = NULL;
@@ -206,12 +243,12 @@ void OS_X11::initialize(const VideoMode &p_desired, int p_video_driver, int p_au
#endif
visual_server = memnew(VisualServerRaster);
-#if 0
- if (get_render_thread_mode()!=RENDER_THREAD_UNSAFE) {
- visual_server =memnew(VisualServerWrapMT(visual_server,get_render_thread_mode()==RENDER_SEPARATE_THREAD));
+ if (get_render_thread_mode() != RENDER_THREAD_UNSAFE) {
+
+ visual_server = memnew(VisualServerWrapMT(visual_server, get_render_thread_mode() == RENDER_SEPARATE_THREAD));
}
-#endif
+
// borderless fullscreen window mode
if (current_videomode.fullscreen) {
// needed for lxde/openbox, possibly others
@@ -241,6 +278,13 @@ void OS_X11::initialize(const VideoMode &p_desired, int p_video_driver, int p_au
xev.xclient.data.l[2] = 0;
XSendEvent(x11_display, DefaultRootWindow(x11_display), False, SubstructureNotifyMask, &xev);
+ } else if (current_videomode.borderless_window) {
+ 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);
}
// disable resizable window
@@ -302,7 +346,8 @@ void OS_X11::initialize(const VideoMode &p_desired, int p_video_driver, int p_au
StructureNotifyMask |
SubstructureNotifyMask | SubstructureRedirectMask |
FocusChangeMask | PropertyChangeMask |
- ColormapChangeMask | OwnerGrabButtonMask;
+ ColormapChangeMask | OwnerGrabButtonMask |
+ im_event_mask;
XChangeWindowAttributes(x11_display, x11_window, CWEventMask, &new_attr);
@@ -326,6 +371,16 @@ void OS_X11::initialize(const VideoMode &p_desired, int p_video_driver, int p_au
if (xim && xim_style) {
xic = XCreateIC(xim, XNInputStyle, xim_style, XNClientWindow, x11_window, XNFocusWindow, x11_window, (char *)NULL);
+ if (XGetICValues(xic, XNFilterEvents, &im_event_mask, NULL) != NULL) {
+ WARN_PRINT("XGetICValues couldn't obtain XNFilterEvents value");
+ XDestroyIC(xic);
+ xic = NULL;
+ }
+ if (xic) {
+ XSetICFocus(xic);
+ } else {
+ WARN_PRINT("XCreateIC couldn't create xic");
+ }
} else {
xic = NULL;
@@ -336,7 +391,9 @@ void OS_X11::initialize(const VideoMode &p_desired, int p_video_driver, int p_au
cursor_theme = XcursorGetTheme(x11_display);
if (!cursor_theme) {
- WARN_PRINT("Could not find cursor theme");
+ if (is_stdout_verbose()) {
+ print_line("XcursorGetTheme could not get cursor theme");
+ }
cursor_theme = "default";
}
@@ -440,6 +497,30 @@ void OS_X11::initialize(const VideoMode &p_desired, int p_video_driver, int p_au
joypad = memnew(JoypadLinux(input));
#endif
_ensure_data_dir();
+
+ power_manager = memnew(PowerX11);
+}
+
+void OS_X11::xim_destroy_callback(::XIM im, ::XPointer client_data,
+ ::XPointer call_data) {
+
+ WARN_PRINT("Input method stopped");
+ OS_X11 *os = reinterpret_cast<OS_X11 *>(client_data);
+ os->xim = NULL;
+ os->xic = NULL;
+}
+
+void OS_X11::set_ime_position(const Point2 &p_pos) {
+
+ if (!xic)
+ return;
+
+ ::XPoint spot;
+ spot.x = short(p_pos.x);
+ spot.y = short(p_pos.y);
+ XVaNestedList preedit_attr = XVaCreateNestedList(0, XNSpotLocation, &spot, NULL);
+ XSetICValues(xic, XNPreeditAttributes, preedit_attr, NULL);
+ XFree(preedit_attr);
}
void OS_X11::finalize() {
@@ -448,10 +529,6 @@ void OS_X11::finalize() {
memdelete(main_loop);
main_loop = NULL;
- for (int i = 0; i < get_audio_driver_count(); i++) {
- AudioDriverManager::get_driver(i)->finish();
- }
-
/*
if (debugger_connection_console) {
memdelete(debugger_connection_console);
@@ -489,8 +566,12 @@ void OS_X11::finalize() {
XcursorImageDestroy(img[i]);
};
- XDestroyIC(xic);
- XCloseIM(xim);
+ if (xic) {
+ XDestroyIC(xic);
+ }
+ if (xim) {
+ XCloseIM(xim);
+ }
XCloseDisplay(x11_display);
if (xmbstring)
@@ -548,7 +629,7 @@ void OS_X11::set_mouse_mode(MouseMode p_mode) {
XWarpPointer(x11_display, None, x11_window,
0, 0, 0, 0, (int)center.x, (int)center.y);
- input->set_mouse_pos(center);
+ input->set_mouse_position(center);
} else {
do_mouse_warp = false;
}
@@ -580,7 +661,7 @@ int OS_X11::get_mouse_button_state() const {
return last_button_state;
}
-Point2 OS_X11::get_mouse_pos() const {
+Point2 OS_X11::get_mouse_position() const {
return last_mouse_pos;
}
@@ -603,6 +684,16 @@ 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 (p_enabled && !is_window_resizable()) {
+ // Set the window as resizable to prevent window managers to ignore the fullscreen state flag.
+ XSizeHints *xsh;
+
+ xsh = XAllocSizeHints();
+ xsh->flags = 0L;
+ XSetWMNormalHints(x11_display, x11_window, xsh);
+ XFree(xsh);
+ }
+
// Using EWMH -- Extened Window Manager Hints
XEvent xev;
Atom wm_state = XInternAtom(x11_display, "_NET_WM_STATE", False);
@@ -618,6 +709,23 @@ void OS_X11::set_wm_fullscreen(bool p_enabled) {
xev.xclient.data.l[2] = 0;
XSendEvent(x11_display, DefaultRootWindow(x11_display), False, SubstructureRedirectMask | SubstructureNotifyMask, &xev);
+ XFlush(x11_display);
+
+ if (!p_enabled && !is_window_resizable()) {
+ // Reset the non-resizable flags if we un-set these before.
+ Size2 size = get_window_size();
+ XSizeHints *xsh;
+
+ xsh = XAllocSizeHints();
+ xsh->flags = PMinSize | PMaxSize;
+ xsh->min_width = size.x;
+ xsh->max_width = size.x;
+ xsh->min_height = size.y;
+ xsh->max_height = size.y;
+
+ XSetWMNormalHints(x11_display, x11_window, xsh);
+ XFree(xsh);
+ }
}
int OS_X11::get_screen_count() const {
@@ -937,6 +1045,25 @@ bool OS_X11::is_window_maximized() const {
return false;
}
+void OS_X11::set_borderless_window(int p_borderless) {
+
+ if (current_videomode.borderless_window == p_borderless)
+ return;
+
+ current_videomode.borderless_window = p_borderless;
+
+ Hints hints;
+ Atom property;
+ hints.flags = 2;
+ hints.decorations = current_videomode.borderless_window ? 0 : 1;
+ property = XInternAtom(x11_display, "_MOTIF_WM_HINTS", True);
+ XChangeProperty(x11_display, x11_window, property, property, 32, PropModeReplace, (unsigned char *)&hints, 5);
+}
+
+bool OS_X11::get_borderless_window() {
+ return current_videomode.borderless_window;
+}
+
void OS_X11::request_attention() {
// Using EWMH -- Extended Window Manager Hints
//
@@ -958,16 +1085,12 @@ void OS_X11::request_attention() {
XSendEvent(x11_display, DefaultRootWindow(x11_display), False, SubstructureRedirectMask | SubstructureNotifyMask, &xev);
}
-InputModifierState OS_X11::get_key_modifier_state(unsigned int p_x11_state) {
-
- InputModifierState state;
+void OS_X11::get_key_modifier_state(unsigned int p_x11_state, Ref<InputEventWithModifiers> state) {
- state.shift = (p_x11_state & ShiftMask);
- state.control = (p_x11_state & ControlMask);
- state.alt = (p_x11_state & Mod1Mask /*|| p_x11_state&Mod5Mask*/); //altgr should not count as alt
- state.meta = (p_x11_state & Mod4Mask);
-
- return state;
+ state->set_shift((p_x11_state & ShiftMask));
+ state->set_control((p_x11_state & ControlMask));
+ state->set_alt((p_x11_state & Mod1Mask /*|| p_x11_state&Mod5Mask*/)); //altgr should not count as alt
+ state->set_metakey((p_x11_state & Mod4Mask));
}
unsigned int OS_X11::get_mouse_button_state(unsigned int p_x11_state) {
@@ -1042,9 +1165,61 @@ void OS_X11::handle_key_event(XKeyEvent *p_event, bool p_echo) {
xmblen = 8;
}
+ keysym_unicode = keysym_keycode;
+
if (xkeyevent->type == KeyPress && xic) {
Status status;
+#ifdef X_HAVE_UTF8_STRING
+ int utf8len = 8;
+ char *utf8string = (char *)memalloc(sizeof(char) * utf8len);
+ int utf8bytes = Xutf8LookupString(xic, xkeyevent, utf8string,
+ utf8len - 1, &keysym_unicode, &status);
+ if (status == XBufferOverflow) {
+ utf8len = utf8bytes + 1;
+ utf8string = (char *)memrealloc(utf8string, utf8len);
+ utf8bytes = Xutf8LookupString(xic, xkeyevent, utf8string,
+ utf8len - 1, &keysym_unicode, &status);
+ }
+ utf8string[utf8bytes] = '\0';
+
+ if (status == XLookupChars) {
+ bool keypress = xkeyevent->type == KeyPress;
+ unsigned int keycode = KeyMappingX11::get_keycode(keysym_keycode);
+ if (keycode >= 'a' && keycode <= 'z')
+ keycode -= 'a' - 'A';
+
+ String tmp;
+ tmp.parse_utf8(utf8string, utf8bytes);
+ for (int i = 0; i < tmp.length(); i++) {
+ Ref<InputEventKey> k;
+ k.instance();
+ if (keycode == 0 && tmp[i] == 0) {
+ continue;
+ }
+
+ get_key_modifier_state(xkeyevent->state, k);
+
+ k->set_unicode(tmp[i]);
+
+ k->set_pressed(keypress);
+
+ k->set_scancode(keycode);
+
+ k->set_echo(false);
+
+ if (k->get_scancode() == KEY_BACKTAB) {
+ //make it consistent across platforms.
+ k->set_scancode(KEY_TAB);
+ k->set_shift(true);
+ }
+
+ input->parse_input_event(k);
+ }
+ return;
+ }
+ memfree(utf8string);
+#else
do {
int mnbytes = XmbLookupString(xic, xkeyevent, xmbstring, xmblen - 1, &keysym_unicode, &status);
@@ -1055,6 +1230,7 @@ void OS_X11::handle_key_event(XKeyEvent *p_event, bool p_echo) {
xmbstring = (char *)memrealloc(xmbstring, xmblen);
}
} while (status == XBufferOverflow);
+#endif
}
/* Phase 2, obtain a pigui keycode from the keysym */
@@ -1083,11 +1259,6 @@ void OS_X11::handle_key_event(XKeyEvent *p_event, bool p_echo) {
bool keypress = xkeyevent->type == KeyPress;
- if (xkeyevent->type == KeyPress && xic) {
- if (XFilterEvent((XEvent *)xkeyevent, x11_window))
- return;
- }
-
if (keycode == 0 && unicode == 0)
return;
@@ -1099,24 +1270,29 @@ void OS_X11::handle_key_event(XKeyEvent *p_event, bool p_echo) {
//print_line("mod1: "+itos(xkeyevent->state&Mod1Mask)+" mod 5: "+itos(xkeyevent->state&Mod5Mask));
- InputModifierState state = get_key_modifier_state(xkeyevent->state);
+ Ref<InputEventKey> k;
+ k.instance();
+
+ get_key_modifier_state(xkeyevent->state, k);
/* Phase 6, determine echo character */
// Echo characters in X11 are a keyrelease and a keypress
// one after the other with the (almot) same timestamp.
// To detect them, i use XPeekEvent and check that their
- // difference in time is below a treshold.
+ // difference in time is below a threshold.
if (xkeyevent->type != KeyPress) {
+ p_echo = false;
+
// make sure there are events pending,
// so this call won't block.
if (XPending(x11_display) > 0) {
XEvent peek_event;
XPeekEvent(x11_display, &peek_event);
- // I'm using a treshold of 5 msecs,
+ // I'm using a threshold of 5 msecs,
// since sometimes there seems to be a little
// jitter. I'm still not convinced that all this approach
// is correct, but the xorg developers are
@@ -1142,41 +1318,48 @@ void OS_X11::handle_key_event(XKeyEvent *p_event, bool p_echo) {
/* Phase 7, send event to Window */
- InputEvent event;
- event.ID = ++event_id;
- event.type = InputEvent::KEY;
- event.device = 0;
- event.key.mod = state;
- event.key.pressed = keypress;
+ k->set_pressed(keypress);
if (keycode >= 'a' && keycode <= 'z')
keycode -= 'a' - 'A';
- event.key.scancode = keycode;
- event.key.unicode = unicode;
- event.key.echo = p_echo;
+ k->set_scancode(keycode);
+ k->set_unicode(unicode);
+ k->set_echo(p_echo);
- if (event.key.scancode == KEY_BACKTAB) {
+ if (k->get_scancode() == KEY_BACKTAB) {
//make it consistent across platforms.
- event.key.scancode = KEY_TAB;
- event.key.mod.shift = true;
+ k->set_scancode(KEY_TAB);
+ k->set_shift(true);
}
//don't set mod state if modifier keys are released by themselves
//else event.is_action() will not work correctly here
- if (!event.key.pressed) {
- if (event.key.scancode == KEY_SHIFT)
- event.key.mod.shift = false;
- else if (event.key.scancode == KEY_CONTROL)
- event.key.mod.control = false;
- else if (event.key.scancode == KEY_ALT)
- event.key.mod.alt = false;
- else if (event.key.scancode == KEY_META)
- event.key.mod.meta = false;
+ if (!k->is_pressed()) {
+ if (k->get_scancode() == KEY_SHIFT)
+ k->set_shift(false);
+ else if (k->get_scancode() == KEY_CONTROL)
+ k->set_control(false);
+ else if (k->get_scancode() == KEY_ALT)
+ k->set_alt(false);
+ else if (k->get_scancode() == KEY_META)
+ k->set_metakey(false);
}
- //printf("key: %x\n",event.key.scancode);
- input->parse_input_event(event);
+ bool last_is_pressed = Input::get_singleton()->is_key_pressed(k->get_scancode());
+ if (k->is_pressed()) {
+ if (last_is_pressed) {
+ k->set_echo(true);
+ }
+ } else {
+ //ignore
+ if (last_is_pressed == false) {
+ return;
+ }
+ }
+
+ //printf("key: %x\n",k->get_scancode());
+ input->parse_input_event(k);
}
struct Property {
@@ -1256,6 +1439,10 @@ void OS_X11::process_xevents() {
XEvent event;
XNextEvent(x11_display, &event);
+ if (XFilterEvent(&event, None)) {
+ continue;
+ }
+
switch (event.type) {
case Expose:
Main::force_redraw();
@@ -1298,6 +1485,9 @@ void OS_X11::process_xevents() {
ButtonPressMask | ButtonReleaseMask | PointerMotionMask,
GrabModeAsync, GrabModeAsync, x11_window, None, CurrentTime);
}
+ if (xic) {
+ XSetICFocus(xic);
+ }
break;
case FocusOut:
@@ -1311,9 +1501,16 @@ void OS_X11::process_xevents() {
}
XUngrabPointer(x11_display, CurrentTime);
}
+ 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) &&
@@ -1333,23 +1530,20 @@ void OS_X11::process_xevents() {
event.xbutton.y = last_mouse_pos.y;
}
- InputEvent mouse_event;
- mouse_event.ID = ++event_id;
- mouse_event.type = InputEvent::MOUSE_BUTTON;
- mouse_event.device = 0;
- mouse_event.mouse_button.mod = get_key_modifier_state(event.xbutton.state);
- mouse_event.mouse_button.button_mask = get_mouse_button_state(event.xbutton.state);
- mouse_event.mouse_button.x = event.xbutton.x;
- mouse_event.mouse_button.y = event.xbutton.y;
- mouse_event.mouse_button.global_x = event.xbutton.x;
- mouse_event.mouse_button.global_y = event.xbutton.y;
- mouse_event.mouse_button.button_index = event.xbutton.button;
- if (mouse_event.mouse_button.button_index == 2)
- mouse_event.mouse_button.button_index = 3;
- else if (mouse_event.mouse_button.button_index == 3)
- mouse_event.mouse_button.button_index = 2;
-
- mouse_event.mouse_button.pressed = (event.type == ButtonPress);
+ Ref<InputEventMouseButton> mb;
+ mb.instance();
+
+ get_key_modifier_state(event.xbutton.state, mb);
+ mb->set_button_mask(get_mouse_button_state(event.xbutton.state));
+ mb->set_position(Vector2(event.xbutton.x, event.xbutton.y));
+ mb->set_global_position(mb->get_position());
+ mb->set_button_index(event.xbutton.button);
+ if (mb->get_button_index() == 2)
+ mb->set_button_index(3);
+ else if (mb->get_button_index() == 3)
+ mb->set_button_index(2);
+
+ mb->set_pressed((event.type == ButtonPress));
if (event.type == ButtonPress && event.xbutton.button == 1) {
@@ -1359,8 +1553,7 @@ void OS_X11::process_xevents() {
last_click_ms = 0;
last_click_pos = Point2(-100, -100);
- mouse_event.mouse_button.doubleclick = true;
- mouse_event.ID = ++event_id;
+ mb->set_doubleclick(true);
} else {
last_click_ms += diff;
@@ -1368,7 +1561,7 @@ void OS_X11::process_xevents() {
}
}
- input->parse_input_event(mouse_event);
+ input->parse_input_event(mb);
} break;
case MotionNotify: {
@@ -1446,23 +1639,16 @@ void OS_X11::process_xevents() {
Point2i rel = pos - last_mouse_pos;
- InputEvent motion_event;
- motion_event.ID = ++event_id;
- motion_event.type = InputEvent::MOUSE_MOTION;
- motion_event.device = 0;
+ Ref<InputEventMouseMotion> mm;
+ mm.instance();
- motion_event.mouse_motion.mod = get_key_modifier_state(event.xmotion.state);
- motion_event.mouse_motion.button_mask = get_mouse_button_state(event.xmotion.state);
- motion_event.mouse_motion.x = pos.x;
- motion_event.mouse_motion.y = pos.y;
- input->set_mouse_pos(pos);
- motion_event.mouse_motion.global_x = pos.x;
- motion_event.mouse_motion.global_y = pos.y;
- motion_event.mouse_motion.speed_x = input->get_last_mouse_speed().x;
- motion_event.mouse_motion.speed_y = input->get_last_mouse_speed().y;
-
- motion_event.mouse_motion.relative_x = rel.x;
- motion_event.mouse_motion.relative_y = rel.y;
+ get_key_modifier_state(event.xmotion.state, mm);
+ mm->set_button_mask(get_mouse_button_state(event.xmotion.state));
+ mm->set_position(pos);
+ mm->set_global_position(pos);
+ input->set_mouse_position(pos);
+ mm->set_speed(input->get_last_mouse_speed());
+ mm->set_relative(rel);
last_mouse_pos = pos;
@@ -1471,7 +1657,7 @@ void OS_X11::process_xevents() {
// this is so that the relative motion doesn't get messed up
// after we regain focus.
if (window_has_focus || !mouse_mode_grab)
- input->parse_input_event(motion_event);
+ input->parse_input_event(mm);
} break;
case KeyPress:
@@ -1670,7 +1856,7 @@ void OS_X11::set_clipboard(const String &p_text) {
XSetSelectionOwner(x11_display, XInternAtom(x11_display, "CLIPBOARD", 0), x11_window, CurrentTime);
};
-static String _get_clipboard(Atom p_source, Window x11_window, ::Display *x11_display, String p_internal_clipboard) {
+static String _get_clipboard_impl(Atom p_source, Window x11_window, ::Display *x11_display, String p_internal_clipboard, Atom target) {
String ret;
@@ -1687,7 +1873,7 @@ static String _get_clipboard(Atom p_source, Window x11_window, ::Display *x11_di
};
if (Sown != None) {
- XConvertSelection(x11_display, p_source, XA_STRING, selection,
+ XConvertSelection(x11_display, p_source, target, selection,
x11_window, CurrentTime);
XFlush(x11_display);
while (true) {
@@ -1727,6 +1913,18 @@ static String _get_clipboard(Atom p_source, Window x11_window, ::Display *x11_di
return ret;
}
+static String _get_clipboard(Atom p_source, Window x11_window, ::Display *x11_display, String p_internal_clipboard) {
+ String ret;
+ Atom utf8_atom = XInternAtom(x11_display, "UTF8_STRING", True);
+ if (utf8_atom != None) {
+ ret = _get_clipboard_impl(p_source, x11_window, x11_display, p_internal_clipboard, utf8_atom);
+ }
+ if (ret == "") {
+ ret = _get_clipboard_impl(p_source, x11_window, x11_display, p_internal_clipboard, XA_STRING);
+ }
+ return ret;
+}
+
String OS_X11::get_clipboard() const {
String ret;
@@ -1759,6 +1957,11 @@ Error OS_X11::shell_open(String p_uri) {
return ok;
}
+bool OS_X11::_check_internal_feature_support(const String &p_feature) {
+
+ return p_feature == "pc" || p_feature == "s3tc";
+}
+
String OS_X11::get_system_dir(SystemDir p_dir) const {
String xdgparam;
@@ -1861,15 +2064,15 @@ void OS_X11::alert(const String &p_alert, const String &p_title) {
execute("/usr/bin/xmessage", args, true);
}
-void OS_X11::set_icon(const Image &p_icon) {
+void OS_X11::set_icon(const Ref<Image> &p_icon) {
Atom net_wm_icon = XInternAtom(x11_display, "_NET_WM_ICON", False);
- if (!p_icon.empty()) {
- Image img = p_icon;
- img.convert(Image::FORMAT_RGBA8);
+ if (p_icon.is_valid()) {
+ Ref<Image> img = p_icon->duplicate();
+ img->convert(Image::FORMAT_RGBA8);
- int w = img.get_width();
- int h = img.get_height();
+ int w = img->get_width();
+ int h = img->get_height();
// We're using long to have wordsize (32Bit build -> 32 Bits, 64 Bit build -> 64 Bits
Vector<long> pd;
@@ -1879,7 +2082,7 @@ void OS_X11::set_icon(const Image &p_icon) {
pd[0] = w;
pd[1] = h;
- PoolVector<uint8_t>::Read r = img.get_data().read();
+ PoolVector<uint8_t>::Read r = img->get_data().read();
long *wr = &pd[2];
uint8_t const *pr = r.ptr();
@@ -1916,7 +2119,7 @@ void OS_X11::run() {
process_xevents(); // get rid of pending events
#ifdef JOYDEV_ENABLED
- event_id = joypad->process_joypads(event_id);
+ joypad->process_joypads();
#endif
if (Main::iteration() == true)
break;
diff --git a/platform/x11/os_x11.h b/platform/x11/os_x11.h
index cbda18c0bc..db70f8f84a 100644
--- a/platform/x11/os_x11.h
+++ b/platform/x11/os_x11.h
@@ -6,6 +6,7 @@
/* http://www.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 */
@@ -112,16 +113,18 @@ class OS_X11 : public OS_Unix {
::XIC xic;
::XIM xim;
::XIMStyle xim_style;
+ static void xim_destroy_callback(::XIM im, ::XPointer client_data,
+ ::XPointer call_data);
+
Point2i last_mouse_pos;
bool last_mouse_pos_valid;
Point2i last_click_pos;
uint64_t last_click_ms;
- unsigned int event_id;
uint32_t last_button_state;
PhysicsServer *physics_server;
unsigned int get_mouse_button_state(unsigned int p_x11_state);
- InputModifierState get_key_modifier_state(unsigned int p_x11_state);
+ void get_key_modifier_state(unsigned int p_x11_state, Ref<InputEventWithModifiers> state);
Physics2DServer *physics_2d_server;
MouseMode mouse_mode;
@@ -202,11 +205,11 @@ public:
MouseMode get_mouse_mode() const;
virtual void warp_mouse_pos(const Point2 &p_to);
- virtual Point2 get_mouse_pos() const;
+ virtual Point2 get_mouse_position() const;
virtual int get_mouse_button_state() const;
virtual void set_window_title(const String &p_title);
- virtual void set_icon(const Image &p_icon);
+ virtual void set_icon(const Ref<Image> &p_icon);
virtual MainLoop *get_main_loop() const;
@@ -247,6 +250,10 @@ public:
virtual bool is_window_maximized() const;
virtual void request_attention();
+ virtual void set_borderless_window(int p_borderless);
+ virtual bool get_borderless_window();
+ virtual void set_ime_position(const Point2 &p_pos);
+
virtual void move_window_to_foreground();
virtual void alert(const String &p_alert, const String &p_title = "ALERT!");
@@ -262,6 +269,8 @@ public:
virtual int get_power_seconds_left();
virtual int get_power_percent_left();
+ virtual bool _check_internal_feature_support(const String &p_feature);
+
void run();
OS_X11();
diff --git a/platform/x11/platform_config.h b/platform/x11/platform_config.h
index 342270b74a..1a1de42b47 100644
--- a/platform/x11/platform_config.h
+++ b/platform/x11/platform_config.h
@@ -6,6 +6,7 @@
/* http://www.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 */
diff --git a/platform/x11/power_x11.cpp b/platform/x11/power_x11.cpp
index 2f98d2f335..8e69a2223f 100644
--- a/platform/x11/power_x11.cpp
+++ b/platform/x11/power_x11.cpp
@@ -6,6 +6,7 @@
/* http://www.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 */
@@ -27,6 +28,31 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
+/*
+Adapted from corresponding SDL 2.0 code.
+*/
+
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+
#include "power_x11.h"
#include <stdio.h>
@@ -145,25 +171,18 @@ void PowerX11::check_proc_acpi_battery(const char *node, bool *have_battery, boo
charge = true;
}
} else if (String(key) == "remaining capacity") {
- char *endptr = NULL;
- //const int cvt = (int) strtol(val, &endptr, 10);
String sval = val;
const int cvt = sval.to_int();
- if (*endptr == ' ') {
- remaining = cvt;
- }
+ remaining = cvt;
}
}
ptr = &info[0];
while (make_proc_acpi_key_val(&ptr, &key, &val)) {
if (String(key) == "design capacity") {
- char *endptr = NULL;
String sval = val;
const int cvt = sval.to_int();
- if (*endptr == ' ') {
- maximum = cvt;
- }
+ maximum = cvt;
}
}
diff --git a/platform/x11/power_x11.h b/platform/x11/power_x11.h
index 7693a5b022..64ed5fe26a 100644
--- a/platform/x11/power_x11.h
+++ b/platform/x11/power_x11.h
@@ -6,6 +6,7 @@
/* http://www.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 */