summaryrefslogtreecommitdiff
path: root/platform
diff options
context:
space:
mode:
Diffstat (limited to 'platform')
-rw-r--r--platform/android/AndroidManifest.xml.template167
-rw-r--r--platform/android/SCsub5
-rw-r--r--platform/android/audio_driver_jandroid.cpp4
-rw-r--r--platform/android/audio_driver_opensl.cpp11
-rw-r--r--platform/android/audio_driver_opensl.h3
-rw-r--r--platform/android/detect.py9
-rw-r--r--platform/android/dir_access_jandroid.cpp1
-rw-r--r--platform/android/export/export.cpp152
-rw-r--r--platform/android/java/res/drawable-hdpi/notify_panel_notification_icon_bg.pngbin715 -> 462 bytes
-rw-r--r--platform/android/java/res/drawable-mdpi/notify_panel_notification_icon_bg.pngbin361 -> 127 bytes
-rw-r--r--platform/android/java/res/drawable/icon.pngbin11155 -> 7569 bytes
-rw-r--r--platform/android/java/src/org/godotengine/godot/Godot.java2
-rw-r--r--platform/android/java/src/org/godotengine/godot/payments/ConsumeTask.java2
-rw-r--r--platform/android/java/src/org/godotengine/godot/payments/HandlePurchaseTask.java16
-rw-r--r--platform/android/java/src/org/godotengine/godot/payments/PaymentsManager.java8
-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.java2
-rw-r--r--platform/android/java_glue.cpp4
-rw-r--r--platform/android/logo.pngbin1742 -> 1461 bytes
-rw-r--r--platform/android/os_android.cpp6
-rw-r--r--platform/android/os_android.h3
-rw-r--r--platform/android/run_icon.pngbin636 -> 324 bytes
-rw-r--r--platform/android/thread_jandroid.cpp2
-rw-r--r--platform/haiku/audio_driver_media_kit.cpp2
-rw-r--r--platform/haiku/logo.pngbin1551 -> 1265 bytes
-rw-r--r--platform/haiku/os_haiku.cpp6
-rw-r--r--platform/haiku/os_haiku.h2
-rw-r--r--platform/iphone/app_delegate.mm2
-rw-r--r--platform/iphone/detect.py8
-rw-r--r--platform/iphone/export/export.cpp6
-rw-r--r--platform/iphone/game_center.mm5
-rw-r--r--platform/iphone/logo.pngbin1905 -> 1489 bytes
-rw-r--r--platform/iphone/os_iphone.cpp15
-rw-r--r--platform/iphone/os_iphone.h14
-rw-r--r--platform/iphone/view_controller.mm65
-rw-r--r--platform/javascript/dom_keys.inc (renamed from platform/javascript/dom_keys.h)17
-rw-r--r--platform/javascript/javascript_main.cpp27
-rw-r--r--platform/javascript/logo.pngbin2316 -> 1236 bytes
-rw-r--r--platform/javascript/os_javascript.cpp1163
-rw-r--r--platform/javascript/os_javascript.h135
-rw-r--r--platform/javascript/run_icon.pngbin471 -> 290 bytes
-rw-r--r--platform/osx/crash_handler_osx.mm4
-rw-r--r--platform/osx/detect.py11
-rw-r--r--platform/osx/logo.pngbin2065 -> 1752 bytes
-rw-r--r--platform/osx/os_osx.h3
-rw-r--r--platform/osx/os_osx.mm34
-rw-r--r--platform/server/logo.pngbin2331 -> 2016 bytes
-rw-r--r--platform/server/os_server.cpp11
-rw-r--r--platform/server/os_server.h9
-rw-r--r--platform/uwp/app.cpp15
-rw-r--r--platform/uwp/gl_context_egl.cpp30
-rw-r--r--platform/uwp/gl_context_egl.h11
-rw-r--r--platform/uwp/os_uwp.cpp50
-rw-r--r--platform/uwp/os_uwp.h9
-rw-r--r--platform/windows/crash_handler_win.cpp3
-rw-r--r--platform/windows/detect.py28
-rw-r--r--platform/windows/godot_win.cpp4
-rw-r--r--platform/windows/logo.pngbin1882 -> 1536 bytes
-rw-r--r--platform/windows/os_windows.cpp386
-rw-r--r--platform/windows/os_windows.h3
-rw-r--r--platform/x11/crash_handler_x11.cpp4
-rw-r--r--platform/x11/detect.py16
-rw-r--r--platform/x11/logo.pngbin2061 -> 1679 bytes
-rw-r--r--platform/x11/os_x11.cpp6
-rw-r--r--platform/x11/os_x11.h3
65 files changed, 1246 insertions, 1259 deletions
diff --git a/platform/android/AndroidManifest.xml.template b/platform/android/AndroidManifest.xml.template
index 13d10b5026..81f4c15849 100644
--- a/platform/android/AndroidManifest.xml.template
+++ b/platform/android/AndroidManifest.xml.template
@@ -32,174 +32,9 @@
$$ADD_APPLICATION_CHUNKS$$
</application>
- <uses-feature android:glEsVersion="0x00030000" android:required="true" />
+ <uses-feature android:glEsVersion="0x00020000" android:required="true" />
$$ADD_PERMISSION_CHUNKS$$
-<uses-permission android:name="godot.ACCESS_CHECKIN_PROPERTIES"/>
-<uses-permission android:name="godot.ACCESS_COARSE_LOCATION"/>
-<uses-permission android:name="godot.ACCESS_FINE_LOCATION"/>
-<uses-permission android:name="godot.ACCESS_LOCATION_EXTRA_COMMANDS"/>
-<uses-permission android:name="godot.ACCESS_MOCK_LOCATION"/>
-<uses-permission android:name="godot.ACCESS_NETWORK_STATE"/>
-<uses-permission android:name="godot.ACCESS_SURFACE_FLINGER"/>
-<uses-permission android:name="godot.ACCESS_WIFI_STATE"/>
-<uses-permission android:name="godot.ACCOUNT_MANAGER"/>
-<uses-permission android:name="godot.ADD_VOICEMAIL"/>
-<uses-permission android:name="godot.AUTHENTICATE_ACCOUNTS"/>
-<uses-permission android:name="godot.BATTERY_STATS"/>
-<uses-permission android:name="godot.BIND_ACCESSIBILITY_SERVICE"/>
-<uses-permission android:name="godot.BIND_APPWIDGET"/>
-<uses-permission android:name="godot.BIND_DEVICE_ADMIN"/>
-<uses-permission android:name="godot.BIND_INPUT_METHOD"/>
-<uses-permission android:name="godot.BIND_NFC_SERVICE"/>
-<uses-permission android:name="godot.BIND_NOTIFICATION_LISTENER_SERVICE"/>
-<uses-permission android:name="godot.BIND_PRINT_SERVICE"/>
-<uses-permission android:name="godot.BIND_REMOTEVIEWS"/>
-<uses-permission android:name="godot.BIND_TEXT_SERVICE"/>
-<uses-permission android:name="godot.BIND_VPN_SERVICE"/>
-<uses-permission android:name="godot.BIND_WALLPAPER"/>
-<uses-permission android:name="godot.BLUETOOTH"/>
-<uses-permission android:name="godot.BLUETOOTH_ADMIN"/>
-<uses-permission android:name="godot.BLUETOOTH_PRIVILEGED"/>
-<uses-permission android:name="godot.BRICK"/>
-<uses-permission android:name="godot.BROADCAST_PACKAGE_REMOVED"/>
-<uses-permission android:name="godot.BROADCAST_SMS"/>
-<uses-permission android:name="godot.BROADCAST_STICKY"/>
-<uses-permission android:name="godot.BROADCAST_WAP_PUSH"/>
-<uses-permission android:name="godot.CALL_PHONE"/>
-<uses-permission android:name="godot.CALL_PRIVILEGED"/>
-<uses-permission android:name="godot.CAMERA"/>
-<uses-permission android:name="godot.CAPTURE_AUDIO_OUTPUT"/>
-<uses-permission android:name="godot.CAPTURE_SECURE_VIDEO_OUTPUT"/>
-<uses-permission android:name="godot.CAPTURE_VIDEO_OUTPUT"/>
-<uses-permission android:name="godot.CHANGE_COMPONENT_ENABLED_STATE"/>
-<uses-permission android:name="godot.CHANGE_CONFIGURATION"/>
-<uses-permission android:name="godot.CHANGE_NETWORK_STATE"/>
-<uses-permission android:name="godot.CHANGE_WIFI_MULTICAST_STATE"/>
-<uses-permission android:name="godot.CHANGE_WIFI_STATE"/>
-<uses-permission android:name="godot.CLEAR_APP_CACHE"/>
-<uses-permission android:name="godot.CLEAR_APP_USER_DATA"/>
-<uses-permission android:name="godot.CONTROL_LOCATION_UPDATES"/>
-<uses-permission android:name="godot.DELETE_CACHE_FILES"/>
-<uses-permission android:name="godot.DELETE_PACKAGES"/>
-<uses-permission android:name="godot.DEVICE_POWER"/>
-<uses-permission android:name="godot.DIAGNOSTIC"/>
-<uses-permission android:name="godot.DISABLE_KEYGUARD"/>
-<uses-permission android:name="godot.DUMP"/>
-<uses-permission android:name="godot.EXPAND_STATUS_BAR"/>
-<uses-permission android:name="godot.FACTORY_TEST"/>
-<uses-permission android:name="godot.FLASHLIGHT"/>
-<uses-permission android:name="godot.FORCE_BACK"/>
-<uses-permission android:name="godot.GET_ACCOUNTS"/>
-<uses-permission android:name="godot.GET_PACKAGE_SIZE"/>
-<uses-permission android:name="godot.GET_TASKS"/>
-<uses-permission android:name="godot.GET_TOP_ACTIVITY_INFO"/>
-<uses-permission android:name="godot.GLOBAL_SEARCH"/>
-<uses-permission android:name="godot.HARDWARE_TEST"/>
-<uses-permission android:name="godot.INJECT_EVENTS"/>
-<uses-permission android:name="godot.INSTALL_LOCATION_PROVIDER"/>
-<uses-permission android:name="godot.INSTALL_PACKAGES"/>
-<uses-permission android:name="godot.INSTALL_SHORTCUT"/>
-<uses-permission android:name="godot.INTERNAL_SYSTEM_WINDOW"/>
-<uses-permission android:name="godot.INTERNET"/>
-<uses-permission android:name="godot.KILL_BACKGROUND_PROCESSES"/>
-<uses-permission android:name="godot.LOCATION_HARDWARE"/>
-<uses-permission android:name="godot.MANAGE_ACCOUNTS"/>
-<uses-permission android:name="godot.MANAGE_APP_TOKENS"/>
-<uses-permission android:name="godot.MANAGE_DOCUMENTS"/>
-<uses-permission android:name="godot.MASTER_CLEAR"/>
-<uses-permission android:name="godot.MEDIA_CONTENT_CONTROL"/>
-<uses-permission android:name="godot.MODIFY_AUDIO_SETTINGS"/>
-<uses-permission android:name="godot.MODIFY_PHONE_STATE"/>
-<uses-permission android:name="godot.MOUNT_FORMAT_FILESYSTEMS"/>
-<uses-permission android:name="godot.MOUNT_UNMOUNT_FILESYSTEMS"/>
-<uses-permission android:name="godot.NFC"/>
-<uses-permission android:name="godot.PERSISTENT_ACTIVITY"/>
-<uses-permission android:name="godot.PROCESS_OUTGOING_CALLS"/>
-<uses-permission android:name="godot.READ_CALENDAR"/>
-<uses-permission android:name="godot.READ_CALL_LOG"/>
-<uses-permission android:name="godot.READ_CONTACTS"/>
-<uses-permission android:name="godot.READ_EXTERNAL_STORAGE"/>
-<uses-permission android:name="godot.READ_FRAME_BUFFER"/>
-<uses-permission android:name="godot.READ_HISTORY_BOOKMARKS"/>
-<uses-permission android:name="godot.READ_INPUT_STATE"/>
-<uses-permission android:name="godot.READ_LOGS"/>
-<uses-permission android:name="godot.READ_PHONE_STATE"/>
-<uses-permission android:name="godot.READ_PROFILE"/>
-<uses-permission android:name="godot.READ_SMS"/>
-<uses-permission android:name="godot.READ_SOCIAL_STREAM"/>
-<uses-permission android:name="godot.READ_SYNC_SETTINGS"/>
-<uses-permission android:name="godot.READ_SYNC_STATS"/>
-<uses-permission android:name="godot.READ_USER_DICTIONARY"/>
-<uses-permission android:name="godot.REBOOT"/>
-<uses-permission android:name="godot.RECEIVE_BOOT_COMPLETED"/>
-<uses-permission android:name="godot.RECEIVE_MMS"/>
-<uses-permission android:name="godot.RECEIVE_SMS"/>
-<uses-permission android:name="godot.RECEIVE_WAP_PUSH"/>
-<uses-permission android:name="godot.RECORD_AUDIO"/>
-<uses-permission android:name="godot.REORDER_TASKS"/>
-<uses-permission android:name="godot.RESTART_PACKAGES"/>
-<uses-permission android:name="godot.SEND_RESPOND_VIA_MESSAGE"/>
-<uses-permission android:name="godot.SEND_SMS"/>
-<uses-permission android:name="godot.SET_ACTIVITY_WATCHER"/>
-<uses-permission android:name="godot.SET_ALARM"/>
-<uses-permission android:name="godot.SET_ALWAYS_FINISH"/>
-<uses-permission android:name="godot.SET_ANIMATION_SCALE"/>
-<uses-permission android:name="godot.SET_DEBUG_APP"/>
-<uses-permission android:name="godot.SET_ORIENTATION"/>
-<uses-permission android:name="godot.SET_POINTER_SPEED"/>
-<uses-permission android:name="godot.SET_PREFERRED_APPLICATIONS"/>
-<uses-permission android:name="godot.SET_PROCESS_LIMIT"/>
-<uses-permission android:name="godot.SET_TIME"/>
-<uses-permission android:name="godot.SET_TIME_ZONE"/>
-<uses-permission android:name="godot.SET_WALLPAPER"/>
-<uses-permission android:name="godot.SET_WALLPAPER_HINTS"/>
-<uses-permission android:name="godot.SIGNAL_PERSISTENT_PROCESSES"/>
-<uses-permission android:name="godot.STATUS_BAR"/>
-<uses-permission android:name="godot.SUBSCRIBED_FEEDS_READ"/>
-<uses-permission android:name="godot.SUBSCRIBED_FEEDS_WRITE"/>
-<uses-permission android:name="godot.SYSTEM_ALERT_WINDOW"/>
-<uses-permission android:name="godot.TRANSMIT_IR"/>
-<uses-permission android:name="godot.UNINSTALL_SHORTCUT"/>
-<uses-permission android:name="godot.UPDATE_DEVICE_STATS"/>
-<uses-permission android:name="godot.USE_CREDENTIALS"/>
-<uses-permission android:name="godot.USE_SIP"/>
-<uses-permission android:name="godot.VIBRATE"/>
-<uses-permission android:name="godot.WAKE_LOCK"/>
-<uses-permission android:name="godot.WRITE_APN_SETTINGS"/>
-<uses-permission android:name="godot.WRITE_CALENDAR"/>
-<uses-permission android:name="godot.WRITE_CALL_LOG"/>
-<uses-permission android:name="godot.WRITE_CONTACTS"/>
-<uses-permission android:name="godot.WRITE_EXTERNAL_STORAGE"/>
-<uses-permission android:name="godot.WRITE_GSERVICES"/>
-<uses-permission android:name="godot.WRITE_HISTORY_BOOKMARKS"/>
-<uses-permission android:name="godot.WRITE_PROFILE"/>
-<uses-permission android:name="godot.WRITE_SECURE_SETTINGS"/>
-<uses-permission android:name="godot.WRITE_SETTINGS"/>
-<uses-permission android:name="godot.WRITE_SMS"/>
-<uses-permission android:name="godot.WRITE_SOCIAL_STREAM"/>
-<uses-permission android:name="godot.WRITE_SYNC_SETTINGS"/>
-<uses-permission android:name="godot.WRITE_USER_DICTIONARY"/>
-<uses-permission android:name="godot.custom.0"/>
-<uses-permission android:name="godot.custom.1"/>
-<uses-permission android:name="godot.custom.2"/>
-<uses-permission android:name="godot.custom.3"/>
-<uses-permission android:name="godot.custom.4"/>
-<uses-permission android:name="godot.custom.5"/>
-<uses-permission android:name="godot.custom.6"/>
-<uses-permission android:name="godot.custom.7"/>
-<uses-permission android:name="godot.custom.8"/>
-<uses-permission android:name="godot.custom.9"/>
-<uses-permission android:name="godot.custom.10"/>
-<uses-permission android:name="godot.custom.11"/>
-<uses-permission android:name="godot.custom.12"/>
-<uses-permission android:name="godot.custom.13"/>
-<uses-permission android:name="godot.custom.14"/>
-<uses-permission android:name="godot.custom.15"/>
-<uses-permission android:name="godot.custom.16"/>
-<uses-permission android:name="godot.custom.17"/>
-<uses-permission android:name="godot.custom.18"/>
-<uses-permission android:name="godot.custom.19"/>
<uses-sdk android:minSdkVersion="18" android:targetSdkVersion="27"/>
diff --git a/platform/android/SCsub b/platform/android/SCsub
index 8c08289932..a65dab9668 100644
--- a/platform/android/SCsub
+++ b/platform/android/SCsub
@@ -53,7 +53,7 @@ if len(env.android_flat_dirs) > 0:
gradle_maven_flat_text = gradle_maven_flat_text[:-1]
gradle_maven_flat_text += "\n\t}\n"
-
+
gradle_maven_repos_text = ""
gradle_maven_repos_text += gradle_maven_flat_text
@@ -99,6 +99,9 @@ for x in env.android_jni_dirs:
gradle_asset_dirs_text = ""
+for x in env.android_asset_dirs:
+ gradle_asset_dirs_text += ",'" + x.replace("\\", "/") + "'"
+
gradle_default_config_text = ""
minSdk = 18
diff --git a/platform/android/audio_driver_jandroid.cpp b/platform/android/audio_driver_jandroid.cpp
index 3d80e76707..b9f1f1eab0 100644
--- a/platform/android/audio_driver_jandroid.cpp
+++ b/platform/android/audio_driver_jandroid.cpp
@@ -78,9 +78,9 @@ Error AudioDriverAndroid::init() {
// __android_log_print(ANDROID_LOG_VERBOSE, "SDL", "SDL audio: opening device");
JNIEnv *env = ThreadAndroid::get_env();
- int mix_rate = GLOBAL_DEF("audio/mix_rate", 44100);
+ int mix_rate = GLOBAL_DEF_RST("audio/mix_rate", 44100);
- int latency = GLOBAL_DEF("audio/output_latency", 25);
+ int latency = GLOBAL_DEF_RST("audio/output_latency", 25);
unsigned int buffer_size = next_power_of_2(latency * mix_rate / 1000);
if (OS::get_singleton()->is_stdout_verbose()) {
print_line("audio buffer size: " + itos(buffer_size));
diff --git a/platform/android/audio_driver_opensl.cpp b/platform/android/audio_driver_opensl.cpp
index e6bd3ff253..28e3ea962f 100644
--- a/platform/android/audio_driver_opensl.cpp
+++ b/platform/android/audio_driver_opensl.cpp
@@ -42,7 +42,8 @@ void AudioDriverOpenSL::_buffer_callback(
/* SLuint32 eventFlags,
const void * pBuffer,
SLuint32 bufferSize,
- SLuint32 dataUsed*/) {
+ SLuint32 dataUsed*/
+) {
bool mix = true;
@@ -145,9 +146,6 @@ void AudioDriverOpenSL::start() {
res = (*sl)->GetInterface(sl, SL_IID_ENGINE, (void *)&EngineItf);
ERR_FAIL_COND(res != SL_RESULT_SUCCESS);
- /* Initialize arrays required[] and iidArray[] */
- SLboolean required[MAX_NUMBER_INTERFACES];
- SLInterfaceID iidArray[MAX_NUMBER_INTERFACES];
{
const SLInterfaceID ids[1] = { SL_IID_ENVIRONMENTALREVERB };
@@ -187,10 +185,7 @@ void AudioDriverOpenSL::start() {
//cntxt.pDataBase = (void*)&pcmData;
//cntxt.pData = cntxt.pDataBase;
//cntxt.size = sizeof(pcmData);
- /* Set arrays required[] and iidArray[] for SEEK interface
- (PlayItf is implicit) */
- required[0] = SL_BOOLEAN_TRUE;
- iidArray[0] = SL_IID_BUFFERQUEUE;
+
/* Create the music player */
{
diff --git a/platform/android/audio_driver_opensl.h b/platform/android/audio_driver_opensl.h
index 2022bad02a..88cb122414 100644
--- a/platform/android/audio_driver_opensl.h
+++ b/platform/android/audio_driver_opensl.h
@@ -74,7 +74,8 @@ class AudioDriverOpenSL : public AudioDriver {
/* SLuint32 eventFlags,
const void * pBuffer,
SLuint32 bufferSize,
- SLuint32 dataUsed*/);
+ SLuint32 dataUsed*/
+ );
static void _buffer_callbacks(
SLAndroidSimpleBufferQueueItf queueItf,
diff --git a/platform/android/detect.py b/platform/android/detect.py
index 971368db17..ada36e2814 100644
--- a/platform/android/detect.py
+++ b/platform/android/detect.py
@@ -139,8 +139,13 @@ def configure(env):
## 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 (env["optimize"] == "speed"): #optimize for speed (default)
+ env.Append(LINKFLAGS=['-O2'])
+ env.Append(CPPFLAGS=['-O2', '-DNDEBUG', '-ffast-math', '-funsafe-math-optimizations', '-fomit-frame-pointer'])
+ else: #optimize for size
+ env.Append(CPPFLAGS=['-Os', '-DNDEBUG'])
+ env.Append(LINKFLAGS=['-Os'])
+
if (can_vectorize):
env.Append(CPPFLAGS=['-ftree-vectorize'])
if (env["target"] == "release_debug"):
diff --git a/platform/android/dir_access_jandroid.cpp b/platform/android/dir_access_jandroid.cpp
index 3e40b59de9..ee5ae156b7 100644
--- a/platform/android/dir_access_jandroid.cpp
+++ b/platform/android/dir_access_jandroid.cpp
@@ -153,7 +153,6 @@ String DirAccessJAndroid::get_current_dir() {
bool DirAccessJAndroid::file_exists(String p_file) {
- JNIEnv *env = ThreadAndroid::get_env();
String sd;
if (current_dir == "")
sd = p_file;
diff --git a/platform/android/export/export.cpp b/platform/android/export/export.cpp
index 9e6377f4fe..59e35884d1 100644
--- a/platform/android/export/export.cpp
+++ b/platform/android/export/export.cpp
@@ -228,7 +228,7 @@ class EditorExportAndroid : public EditorExportPlatform {
};
Vector<Device> devices;
- bool devices_changed;
+ volatile bool devices_changed;
Mutex *device_lock;
Thread *device_thread;
volatile bool quit_request;
@@ -528,11 +528,9 @@ class EditorExportAndroid : public EditorExportPlatform {
bool exported = false;
for (int i = 0; i < p_so.tags.size(); ++i) {
// shared objects can be fat (compatible with multiple ABIs)
- int start_pos = 0;
int abi_index = abis.find(p_so.tags[i]);
if (abi_index != -1) {
exported = true;
- start_pos = abi_index + 1;
String abi = abis[abi_index];
String dst_path = "lib/" + abi + "/" + p_so.path.get_file();
Vector<uint8_t> array = FileAccess::get_file_as_array(p_so.path);
@@ -570,7 +568,7 @@ class EditorExportAndroid : public EditorExportPlatform {
// const int CHUNK_RESOURCEIDS = 0x00080180;
const int CHUNK_STRINGS = 0x001C0001;
// const int CHUNK_XML_END_NAMESPACE = 0x00100101;
- // const int CHUNK_XML_END_TAG = 0x00100103;
+ const int CHUNK_XML_END_TAG = 0x00100103;
// const int CHUNK_XML_START_NAMESPACE = 0x00100100;
const int CHUNK_XML_START_TAG = 0x00100102;
// const int CHUNK_XML_TEXT = 0x00100104;
@@ -601,24 +599,28 @@ class EditorExportAndroid : public EditorExportPlatform {
bool screen_support_large = p_preset->get("screen/support_large");
bool screen_support_xlarge = p_preset->get("screen/support_xlarge");
- String user_perms[MAX_USER_PERMISSIONS];
-
- for (int i = 0; i < MAX_USER_PERMISSIONS; i++) {
-
- user_perms[i] = p_preset->get("user_permissions/" + itos(i));
- }
-
- Set<String> perms;
+ Vector<String> perms;
const char **aperms = android_perms;
while (*aperms) {
bool enabled = p_preset->get("permissions/" + String(*aperms).to_lower());
if (enabled)
- perms.insert(String(*aperms));
+ perms.push_back("android.permission." + String(*aperms));
aperms++;
}
+ for (int i = 0; i < MAX_USER_PERMISSIONS; i++) {
+ String user_perm = p_preset->get("user_permissions/" + itos(i));
+ if (user_perm.strip_edges() != "" && user_perm.strip_edges() != "False")
+ perms.push_back(user_perm.strip_edges());
+ }
+
+ if (p_give_internet) {
+ if (perms.find("android.permission.INTERNET") == -1)
+ perms.push_back("android.permission.INTERNET");
+ }
+
while (ofs < (uint32_t)p_manifest.size()) {
uint32_t chunk = decode_uint32(&p_manifest[ofs]);
@@ -741,27 +743,6 @@ class EditorExportAndroid : public EditorExportPlatform {
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")) {
-
- int which = value.get_slice(".", 2).to_int();
- if (which >= 0 && which < MAX_USER_PERMISSIONS && user_perms[which].strip_edges() != "") {
-
- string_table[attr_value] = user_perms[which].strip_edges();
- }
-
- } else if (value.begins_with("godot.")) {
- String perm = value.get_slice(".", 1);
-
- if (perms.has(perm) || (p_give_internet && perm == "INTERNET")) {
-
- print_line("PERM: " + perm);
- string_table[attr_value] = "android.permission." + perm;
- }
- }
- }
-
if (tname == "supports-screens") {
if (attrname == "smallScreens") {
@@ -786,6 +767,91 @@ class EditorExportAndroid : public EditorExportPlatform {
}
} break;
+ case CHUNK_XML_END_TAG: {
+ int iofs = ofs + 8;
+ uint32_t name = decode_uint32(&p_manifest[iofs + 12]);
+ String tname = string_table[name];
+
+ if (tname == "manifest") {
+ print_line("Found manifest end");
+
+ // save manifest ending so we can restore it
+ Vector<uint8_t> manifest_end;
+ uint32_t manifest_cur_size = p_manifest.size();
+ uint32_t node_size = size;
+
+ manifest_end.resize(p_manifest.size() - ofs);
+ memcpy(manifest_end.ptrw(), &p_manifest[ofs], manifest_end.size());
+
+ int32_t attr_name_string = string_table.find("name");
+ ERR_EXPLAIN("Template does not have 'name' attribute");
+ ERR_FAIL_COND(attr_name_string == -1);
+
+ int32_t ns_android_string = string_table.find("android");
+ ERR_EXPLAIN("Template does not have 'android' namespace");
+ ERR_FAIL_COND(ns_android_string == -1);
+
+ int32_t attr_uses_permission_string = string_table.find("uses-permission");
+ if (attr_uses_permission_string == -1) {
+ string_table.push_back("uses-permission");
+ attr_uses_permission_string = string_table.size() - 1;
+ }
+
+ for (int i = 0; i < perms.size(); ++i) {
+ print_line("Adding permission " + perms[i]);
+
+ manifest_cur_size += 56 + 24; // node + end node
+ p_manifest.resize(manifest_cur_size);
+
+ // Add permission to the string pool
+ int32_t perm_string = string_table.find(perms[i]);
+ if (perm_string == -1) {
+ string_table.push_back(perms[i]);
+ perm_string = string_table.size() - 1;
+ }
+
+ // start tag
+ encode_uint16(0x102, &p_manifest[ofs]); // type
+ encode_uint16(16, &p_manifest[ofs + 2]); // headersize
+ encode_uint32(56, &p_manifest[ofs + 4]); // size
+ encode_uint32(0, &p_manifest[ofs + 8]); // lineno
+ encode_uint32(-1, &p_manifest[ofs + 12]); // comment
+ encode_uint32(-1, &p_manifest[ofs + 16]); // ns
+ encode_uint32(attr_uses_permission_string, &p_manifest[ofs + 20]); // name
+ encode_uint16(20, &p_manifest[ofs + 24]); // attr_start
+ encode_uint16(20, &p_manifest[ofs + 26]); // attr_size
+ encode_uint16(1, &p_manifest[ofs + 28]); // num_attrs
+ encode_uint16(0, &p_manifest[ofs + 30]); // id_index
+ encode_uint16(0, &p_manifest[ofs + 32]); // class_index
+ encode_uint16(0, &p_manifest[ofs + 34]); // style_index
+
+ // attribute
+ encode_uint32(ns_android_string, &p_manifest[ofs + 36]); // ns
+ encode_uint32(attr_name_string, &p_manifest[ofs + 40]); // 'name'
+ encode_uint32(perm_string, &p_manifest[ofs + 44]); // raw_value
+ encode_uint16(8, &p_manifest[ofs + 48]); // typedvalue_size
+ p_manifest[ofs + 50] = 0; // typedvalue_always0
+ p_manifest[ofs + 51] = 0x03; // typedvalue_type (string)
+ encode_uint32(perm_string, &p_manifest[ofs + 52]); // typedvalue reference
+
+ ofs += 56;
+
+ // end tag
+ encode_uint16(0x103, &p_manifest[ofs]); // type
+ encode_uint16(16, &p_manifest[ofs + 2]); // headersize
+ encode_uint32(24, &p_manifest[ofs + 4]); // size
+ encode_uint32(0, &p_manifest[ofs + 8]); // lineno
+ encode_uint32(-1, &p_manifest[ofs + 12]); // comment
+ encode_uint32(-1, &p_manifest[ofs + 16]); // ns
+ encode_uint32(attr_uses_permission_string, &p_manifest[ofs + 20]); // name
+
+ ofs += 24;
+ }
+
+ // copy footer back in
+ memcpy(&p_manifest[ofs], manifest_end.ptr(), manifest_end.size());
+ }
+ } break;
}
ofs += size;
@@ -806,17 +872,17 @@ class EditorExportAndroid : public EditorExportPlatform {
encode_uint32(ofs, &ret[string_table_begins + i * 4]);
ofs += string_table[i].length() * 2 + 2 + 2;
- //print_line("ofs: "+itos(i)+": "+itos(ofs));
}
+
ret.resize(ret.size() + ofs);
- uint8_t *chars = &ret[ret.size() - ofs];
+ string_data_offset = ret.size() - ofs;
+ uint8_t *chars = &ret[string_data_offset];
for (int i = 0; i < string_table.size(); i++) {
String s = string_table[i];
- //print_line("savint string :"+s);
encode_uint16(s.length(), chars);
chars += 2;
- for (int j = 0; j < s.length(); j++) { //include zero?
+ for (int j = 0; j < s.length(); j++) {
encode_uint16(s[j], chars);
chars += 2;
}
@@ -828,6 +894,7 @@ class EditorExportAndroid : public EditorExportPlatform {
ret.push_back(stable_extra[i]);
}
+ //pad
while (ret.size() % 4)
ret.push_back(0);
@@ -843,6 +910,8 @@ class EditorExportAndroid : public EditorExportPlatform {
encode_uint32(ret.size(), &ret[4]); //update new file size
encode_uint32(new_stable_end - 8, &ret[12]); //update new string table size
+ encode_uint32(string_table.size(), &ret[16]); //update new number of strings
+ encode_uint32(string_data_offset - 8, &ret[28]); //update new string data offset
//print_line("file size: "+itos(ret.size()));
@@ -1083,7 +1152,10 @@ public:
virtual bool poll_devices() {
bool dc = devices_changed;
- devices_changed = false;
+ if (dc) {
+ // don't clear unless we're reporting true, to avoid race
+ devices_changed = false;
+ }
return dc;
}
@@ -1786,9 +1858,9 @@ public:
run_icon->create_from_image(img);
device_lock = Mutex::create();
- device_thread = Thread::create(_device_poll_thread, this);
devices_changed = true;
quit_request = false;
+ device_thread = Thread::create(_device_poll_thread, this);
}
~EditorExportAndroid() {
diff --git a/platform/android/java/res/drawable-hdpi/notify_panel_notification_icon_bg.png b/platform/android/java/res/drawable-hdpi/notify_panel_notification_icon_bg.png
index 94bc406416..372b763ec5 100644
--- a/platform/android/java/res/drawable-hdpi/notify_panel_notification_icon_bg.png
+++ b/platform/android/java/res/drawable-hdpi/notify_panel_notification_icon_bg.png
Binary files differ
diff --git a/platform/android/java/res/drawable-mdpi/notify_panel_notification_icon_bg.png b/platform/android/java/res/drawable-mdpi/notify_panel_notification_icon_bg.png
index ef6fe4e836..c61c440636 100644
--- a/platform/android/java/res/drawable-mdpi/notify_panel_notification_icon_bg.png
+++ b/platform/android/java/res/drawable-mdpi/notify_panel_notification_icon_bg.png
Binary files differ
diff --git a/platform/android/java/res/drawable/icon.png b/platform/android/java/res/drawable/icon.png
index 29c4a7b8fc..6ad9b43117 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/org/godotengine/godot/Godot.java b/platform/android/java/src/org/godotengine/godot/Godot.java
index 8a2d789dc5..ef798fc790 100644
--- a/platform/android/java/src/org/godotengine/godot/Godot.java
+++ b/platform/android/java/src/org/godotengine/godot/Godot.java
@@ -297,7 +297,7 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC
runOnUiThread(new Runnable() {
@Override
public void run() {
- view.setKeepScreenOn("True".equals(GodotLib.getGlobal("display/driver/keep_screen_on")));
+ view.setKeepScreenOn("True".equals(GodotLib.getGlobal("display/window/energy_saving/keep_screen_on")));
}
});
}
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 afe5f81b6d..5d94e77cd7 100644
--- a/platform/android/java/src/org/godotengine/godot/payments/ConsumeTask.java
+++ b/platform/android/java/src/org/godotengine/godot/payments/ConsumeTask.java
@@ -66,7 +66,6 @@ abstract public class ConsumeTask {
}
final String token = _token;
new AsyncTask<String, String, String>() {
-
@Override
protected String doInBackground(String... params) {
try {
@@ -89,7 +88,6 @@ abstract public class ConsumeTask {
error(param);
}
}
-
}
.execute();
}
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 766989f953..aaf18c74bf 100644
--- a/platform/android/java/src/org/godotengine/godot/payments/HandlePurchaseTask.java
+++ b/platform/android/java/src/org/godotengine/godot/payments/HandlePurchaseTask.java
@@ -58,17 +58,15 @@ abstract public class HandlePurchaseTask {
public void handlePurchaseRequest(int resultCode, Intent data) {
//Log.d("XXX", "Handling purchase response");
- //int responseCode = data.getIntExtra("RESPONSE_CODE", 0);
- PaymentsCache pc = new PaymentsCache(context);
-
- String purchaseData = data.getStringExtra("INAPP_PURCHASE_DATA");
- //Log.d("XXX", "Purchase data:" + purchaseData);
- String dataSignature = data.getStringExtra("INAPP_DATA_SIGNATURE");
- //Log.d("XXX", "Purchase signature:" + dataSignature);
-
if (resultCode == Activity.RESULT_OK) {
-
try {
+ //int responseCode = data.getIntExtra("RESPONSE_CODE", 0);
+ PaymentsCache pc = new PaymentsCache(context);
+
+ String purchaseData = data.getStringExtra("INAPP_PURCHASE_DATA");
+ //Log.d("XXX", "Purchase data:" + purchaseData);
+ String dataSignature = data.getStringExtra("INAPP_DATA_SIGNATURE");
+ //Log.d("XXX", "Purchase signature:" + dataSignature);
//Log.d("SARLANGA", purchaseData);
JSONObject jo = new JSONObject(purchaseData);
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 b7bf2362cc..d4c7380424 100644
--- a/platform/android/java/src/org/godotengine/godot/payments/PaymentsManager.java
+++ b/platform/android/java/src/org/godotengine/godot/payments/PaymentsManager.java
@@ -113,7 +113,6 @@ public class PaymentsManager {
public void requestPurchase(final String sku, String transactionId) {
new PurchaseTask(mService, Godot.getInstance()) {
-
@Override
protected void error(String message) {
godotPaymentV3.callbackFail(message);
@@ -128,7 +127,6 @@ public class PaymentsManager {
protected void alreadyOwned() {
godotPaymentV3.callbackAlreadyOwned(sku);
}
-
}
.purchase(sku, transactionId);
}
@@ -139,7 +137,6 @@ public class PaymentsManager {
public void consumeUnconsumedPurchases() {
new ReleaseAllConsumablesTask(mService, activity) {
-
@Override
protected void success(String sku, String receipt, String signature, String token) {
godotPaymentV3.callbackSuccessProductMassConsumed(receipt, signature, sku);
@@ -208,14 +205,12 @@ public class PaymentsManager {
public void processPurchaseResponse(int resultCode, Intent data) {
new HandlePurchaseTask(activity) {
-
@Override
protected void success(final String sku, final String signature, final String ticket) {
godotPaymentV3.callbackSuccess(ticket, signature, sku);
if (auto_consume) {
new ConsumeTask(mService, activity) {
-
@Override
protected void success(String ticket) {
}
@@ -245,12 +240,10 @@ public class PaymentsManager {
public void validatePurchase(String purchaseToken, final String sku) {
new ValidateTask(activity, godotPaymentV3) {
-
@Override
protected void success() {
new ConsumeTask(mService, activity) {
-
@Override
protected void success(String ticket) {
godotPaymentV3.callbackSuccess(ticket, null, sku);
@@ -283,7 +276,6 @@ public class PaymentsManager {
public void consume(final String sku) {
new ConsumeTask(mService, activity) {
-
@Override
protected void success(String ticket) {
godotPaymentV3.callbackSuccessProductMassConsumed(ticket, "", sku);
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 e00e37f9d1..eccc6f671b 100644
--- a/platform/android/java/src/org/godotengine/godot/payments/ReleaseAllConsumablesTask.java
+++ b/platform/android/java/src/org/godotengine/godot/payments/ReleaseAllConsumablesTask.java
@@ -88,7 +88,6 @@ abstract public class ReleaseAllConsumablesTask {
String signature = mySignatures.get(i);
//Log.d("godot", "A punto de consumir un item con token:" + token + "\n" + receipt);
new GenericConsumeTask(context, mService, sku, receipt, signature, token) {
-
@Override
public void onSuccess(String sku, String receipt, String signature, String token) {
ReleaseAllConsumablesTask.this.success(sku, receipt, signature, token);
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 1eb9d001e0..0626e50bb1 100644
--- a/platform/android/java/src/org/godotengine/godot/payments/ValidateTask.java
+++ b/platform/android/java/src/org/godotengine/godot/payments/ValidateTask.java
@@ -63,7 +63,6 @@ abstract public class ValidateTask {
public void validatePurchase(final String sku) {
new AsyncTask<String, String, String>() {
-
private ProgressDialog dialog;
@Override
@@ -113,7 +112,6 @@ abstract public class ValidateTask {
error(e.getMessage());
}
}
-
}
.execute();
}
diff --git a/platform/android/java_glue.cpp b/platform/android/java_glue.cpp
index e6240ad9e9..8bb1c38345 100644
--- a/platform/android/java_glue.cpp
+++ b/platform/android/java_glue.cpp
@@ -880,7 +880,6 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_setup(JNIEnv *env, jo
const char **cmdline = NULL;
int cmdlen = 0;
- bool use_apk_expansion = false;
if (p_cmdline) {
cmdlen = env->GetArrayLength(p_cmdline);
if (cmdlen) {
@@ -891,9 +890,6 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_setup(JNIEnv *env, jo
jstring string = (jstring)env->GetObjectArrayElement(p_cmdline, i);
const char *rawString = env->GetStringUTFChars(string, 0);
- if (rawString && strcmp(rawString, "--main-pack") == 0) {
- use_apk_expansion = true;
- }
cmdline[i] = rawString;
}
diff --git a/platform/android/logo.png b/platform/android/logo.png
index fcf684c026..ba2a0e366a 100644
--- a/platform/android/logo.png
+++ b/platform/android/logo.png
Binary files differ
diff --git a/platform/android/os_android.cpp b/platform/android/os_android.cpp
index 9188f09f21..cc512263bc 100644
--- a/platform/android/os_android.cpp
+++ b/platform/android/os_android.cpp
@@ -124,6 +124,10 @@ void OS_Android::set_opengl_extensions(const char *p_gl_extensions) {
gl_extensions = p_gl_extensions;
}
+int OS_Android::get_current_video_driver() const {
+ return video_driver_index;
+}
+
Error OS_Android::initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver) {
bool use_gl3 = get_gl_version_code_func() >= 0x00030000;
@@ -136,9 +140,11 @@ Error OS_Android::initialize(const VideoMode &p_desired, int p_video_driver, int
if (use_gl2) {
RasterizerGLES2::register_config();
RasterizerGLES2::make_current();
+ video_driver_index = VIDEO_DRIVER_GLES2;
} else {
RasterizerGLES3::register_config();
RasterizerGLES3::make_current();
+ video_driver_index = VIDEO_DRIVER_GLES3;
}
visual_server = memnew(VisualServerRaster);
diff --git a/platform/android/os_android.h b/platform/android/os_android.h
index ac901d4832..c4220906a3 100644
--- a/platform/android/os_android.h
+++ b/platform/android/os_android.h
@@ -137,6 +137,7 @@ private:
AlertFunc alert_func;
//power_android *power_manager;
+ int video_driver_index;
public:
// functions used by main to initialize/deintialize the OS
@@ -146,6 +147,8 @@ public:
virtual int get_audio_driver_count() const;
virtual const char *get_audio_driver_name(int p_driver) const;
+ virtual int get_current_video_driver() const;
+
virtual void initialize_core();
virtual Error initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver);
diff --git a/platform/android/run_icon.png b/platform/android/run_icon.png
index e53f8e9da5..b687c9ac31 100644
--- a/platform/android/run_icon.png
+++ b/platform/android/run_icon.png
Binary files differ
diff --git a/platform/android/thread_jandroid.cpp b/platform/android/thread_jandroid.cpp
index e85813605f..b13baf69c2 100644
--- a/platform/android/thread_jandroid.cpp
+++ b/platform/android/thread_jandroid.cpp
@@ -132,7 +132,7 @@ JNIEnv *ThreadAndroid::get_env() {
}
JNIEnv *env = NULL;
- int status = java_vm->AttachCurrentThread(&env, NULL);
+ java_vm->AttachCurrentThread(&env, NULL);
return env;
}
diff --git a/platform/haiku/audio_driver_media_kit.cpp b/platform/haiku/audio_driver_media_kit.cpp
index 278a994c54..1f901c4919 100644
--- a/platform/haiku/audio_driver_media_kit.cpp
+++ b/platform/haiku/audio_driver_media_kit.cpp
@@ -43,7 +43,7 @@ Error AudioDriverMediaKit::init() {
speaker_mode = SPEAKER_MODE_STEREO;
channels = 2;
- int latency = GLOBAL_DEF("audio/output_latency", 25);
+ int latency = GLOBAL_DEF_RST("audio/output_latency", 25);
buffer_size = next_power_of_2(latency * mix_rate / 1000);
samples_in = memnew_arr(int32_t, buffer_size * channels);
diff --git a/platform/haiku/logo.png b/platform/haiku/logo.png
index d5d98e4cc6..a2d8e242a6 100644
--- a/platform/haiku/logo.png
+++ b/platform/haiku/logo.png
Binary files differ
diff --git a/platform/haiku/os_haiku.cpp b/platform/haiku/os_haiku.cpp
index 97fab5ca0d..209cb5cec4 100644
--- a/platform/haiku/os_haiku.cpp
+++ b/platform/haiku/os_haiku.cpp
@@ -80,6 +80,10 @@ const char *OS_Haiku::get_video_driver_name(int p_driver) const {
return "GLES3";
}
+int OS_Haiku::get_current_video_driver() const {
+ return video_driver_index;
+}
+
Error OS_Haiku::initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver) {
main_loop = NULL;
current_video_mode = p_desired;
@@ -124,6 +128,8 @@ Error OS_Haiku::initialize(const VideoMode &p_desired, int p_video_driver, int p
}
*/
+ video_driver_index = p_video_driver;
+
input = memnew(InputDefault);
window->SetInput(input);
diff --git a/platform/haiku/os_haiku.h b/platform/haiku/os_haiku.h
index 615ae682ef..13d4420bde 100644
--- a/platform/haiku/os_haiku.h
+++ b/platform/haiku/os_haiku.h
@@ -51,6 +51,7 @@ private:
Rasterizer *rasterizer;
VisualServer *visual_server;
VideoMode current_video_mode;
+ int video_driver_index;
PowerHaiku *power_manager;
#ifdef MEDIA_KIT_ENABLED
@@ -66,6 +67,7 @@ private:
protected:
virtual int get_video_driver_count() const;
virtual const char *get_video_driver_name(int p_driver) const;
+ virtual int get_current_video_driver() const;
virtual Error initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver);
virtual void finalize();
diff --git a/platform/iphone/app_delegate.mm b/platform/iphone/app_delegate.mm
index dd5ce4ab10..cc4985eb0c 100644
--- a/platform/iphone/app_delegate.mm
+++ b/platform/iphone/app_delegate.mm
@@ -643,7 +643,7 @@ static int frame_count = 0;
view_controller.view = glView;
window.rootViewController = view_controller;
- _set_keep_screen_on(bool(GLOBAL_DEF("display/window/keep_screen_on", true)) ? YES : NO);
+ _set_keep_screen_on(bool(GLOBAL_DEF("display/window/energy_saving/keep_screen_on", true)) ? YES : NO);
glView.useCADisplayLink =
bool(GLOBAL_DEF("display.iOS/use_cadisplaylink", true)) ? YES : NO;
printf("cadisaplylink: %d", glView.useCADisplayLink);
diff --git a/platform/iphone/detect.py b/platform/iphone/detect.py
index 25674c2b47..b13a1e9643 100644
--- a/platform/iphone/detect.py
+++ b/platform/iphone/detect.py
@@ -47,8 +47,12 @@ def configure(env):
if (env["target"].startswith("release")):
env.Append(CPPFLAGS=['-DNDEBUG', '-DNS_BLOCK_ASSERTIONS=1'])
- env.Append(CPPFLAGS=['-O2', '-ftree-vectorize', '-fomit-frame-pointer', '-ffast-math', '-funsafe-math-optimizations'])
- env.Append(LINKFLAGS=['-O2'])
+ if (env["optimize"] == "speed"): #optimize for speed (default)
+ env.Append(CPPFLAGS=['-O2', '-ftree-vectorize', '-fomit-frame-pointer', '-ffast-math', '-funsafe-math-optimizations'])
+ env.Append(LINKFLAGS=['-O2'])
+ else: #optimize for size
+ env.Append(CPPFLAGS=['-Os', '-ftree-vectorize'])
+ env.Append(LINKFLAGS=['-Os'])
if env["target"] == "release_debug":
env.Append(CPPFLAGS=['-DDEBUG_ENABLED'])
diff --git a/platform/iphone/export/export.cpp b/platform/iphone/export/export.cpp
index 4c1e02baf7..5480d30e7a 100644
--- a/platform/iphone/export/export.cpp
+++ b/platform/iphone/export/export.cpp
@@ -781,7 +781,9 @@ Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_p
int ret = unzGoToFirstFile(src_pkg_zip);
Vector<uint8_t> project_file_data;
while (ret == UNZ_OK) {
+#if defined(OSX_ENABLED) || defined(X11_ENABLED)
bool is_execute = false;
+#endif
//get filename
unz_file_info info;
@@ -812,7 +814,9 @@ Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_p
continue; //ignore!
}
found_library = true;
+#if defined(OSX_ENABLED) || defined(X11_ENABLED)
is_execute = true;
+#endif
file = "godot_ios.a";
}
if (file == project_file) {
@@ -855,7 +859,7 @@ Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_p
f->close();
memdelete(f);
-#ifdef OSX_ENABLED
+#if defined(OSX_ENABLED) || defined(X11_ENABLED)
if (is_execute) {
// we need execute rights on this file
chmod(file.utf8().get_data(), 0755);
diff --git a/platform/iphone/game_center.mm b/platform/iphone/game_center.mm
index 57ff79f7bc..e210bfb862 100644
--- a/platform/iphone/game_center.mm
+++ b/platform/iphone/game_center.mm
@@ -139,7 +139,6 @@ Error GameCenter::post_score(Variant p_score) {
[GKScore reportScores:@[ reporter ]
withCompletionHandler:^(NSError *error) {
-
Dictionary ret;
ret["type"] = "post_score";
if (error == nil) {
@@ -177,7 +176,6 @@ Error GameCenter::award_achievement(Variant p_params) {
[GKAchievement reportAchievements:@[ achievement ]
withCompletionHandler:^(NSError *error) {
-
Dictionary ret;
ret["type"] = "award_achievement";
if (error == nil) {
@@ -196,7 +194,6 @@ Error GameCenter::award_achievement(Variant p_params) {
void GameCenter::request_achievement_descriptions() {
[GKAchievementDescription loadAchievementDescriptionsWithCompletionHandler:^(NSArray *descriptions, NSError *error) {
-
Dictionary ret;
ret["type"] = "achievement_descriptions";
if (error == nil) {
@@ -252,7 +249,6 @@ void GameCenter::request_achievement_descriptions() {
void GameCenter::request_achievements() {
[GKAchievement loadAchievementsWithCompletionHandler:^(NSArray *achievements, NSError *error) {
-
Dictionary ret;
ret["type"] = "achievements";
if (error == nil) {
@@ -347,7 +343,6 @@ Error GameCenter::request_identity_verification_signature() {
GKLocalPlayer *player = [GKLocalPlayer localPlayer];
[player generateIdentityVerificationSignatureWithCompletionHandler:^(NSURL *publicKeyUrl, NSData *signature, NSData *salt, uint64_t timestamp, NSError *error) {
-
Dictionary ret;
ret["type"] = "identity_verification_signature";
if (error == nil) {
diff --git a/platform/iphone/logo.png b/platform/iphone/logo.png
index 8dd718524c..405b6f93ca 100644
--- a/platform/iphone/logo.png
+++ b/platform/iphone/logo.png
Binary files differ
diff --git a/platform/iphone/os_iphone.cpp b/platform/iphone/os_iphone.cpp
index f618c80a77..a4538a6673 100644
--- a/platform/iphone/os_iphone.cpp
+++ b/platform/iphone/os_iphone.cpp
@@ -64,11 +64,6 @@ OSIPhone *OSIPhone::get_singleton() {
return (OSIPhone *)OS::get_singleton();
};
-uint8_t OSIPhone::get_orientations() const {
-
- return supported_orientations;
-};
-
extern int gl_view_base_fb; // from gl_view.mm
void OSIPhone::set_data_dir(String p_dir) {
@@ -98,13 +93,13 @@ void OSIPhone::initialize_core() {
set_data_dir(data_dir);
};
+int OSIPhone::get_current_video_driver() const {
+ return video_driver_index;
+}
+
Error OSIPhone::initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver) {
- supported_orientations = 0;
- supported_orientations |= ((GLOBAL_DEF("video_mode/allow_horizontal", true) ? 1 : 0) << LandscapeLeft);
- supported_orientations |= ((GLOBAL_DEF("video_mode/allow_horizontal_flipped", false) ? 1 : 0) << LandscapeRight);
- supported_orientations |= ((GLOBAL_DEF("video_mode/allow_vertical", false) ? 1 : 0) << PortraitDown);
- supported_orientations |= ((GLOBAL_DEF("video_mode/allow_vertical_flipped", false) ? 1 : 0) << PortraitUp);
+ video_driver_index = p_video_driver; //this may be misleading
RasterizerGLES3::register_config();
RasterizerGLES3::make_current();
diff --git a/platform/iphone/os_iphone.h b/platform/iphone/os_iphone.h
index 7d73a6fe5c..db2912ad93 100644
--- a/platform/iphone/os_iphone.h
+++ b/platform/iphone/os_iphone.h
@@ -47,14 +47,6 @@
class OSIPhone : public OS_Unix {
-public:
- enum Orientations {
- PortraitDown,
- PortraitUp,
- LandscapeLeft,
- LandscapeRight,
- };
-
private:
enum {
MAX_MOUSE_COUNT = 8,
@@ -64,8 +56,6 @@ private:
static HashMap<String, void *> dynamic_symbol_lookup_table;
friend void register_dynamic_symbol(char *name, void *address);
- uint8_t supported_orientations;
-
VisualServer *visual_server;
AudioDriverCoreAudio audio_driver;
@@ -87,6 +77,8 @@ private:
virtual int get_video_driver_count() const;
virtual const char *get_video_driver_name(int p_driver) const;
+ virtual int get_current_video_driver() const;
+
virtual void initialize_core();
virtual Error initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver);
@@ -122,6 +114,8 @@ private:
int virtual_keyboard_height;
+ int video_driver_index;
+
public:
bool iterate();
diff --git a/platform/iphone/view_controller.mm b/platform/iphone/view_controller.mm
index cdaae0cb81..f75f0fd812 100644
--- a/platform/iphone/view_controller.mm
+++ b/platform/iphone/view_controller.mm
@@ -83,51 +83,36 @@ int add_cmdline(int p_argc, char **p_args) {
printf("*********** did receive memory warning!\n");
};
-- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)p_orientation {
-
- if (/*OSIPhone::get_singleton() == NULL*/ TRUE) {
-
- printf("checking on info.plist\n");
- NSArray *arr = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"UISupportedInterfaceOrientations"];
- switch (p_orientation) {
-
- case UIInterfaceOrientationLandscapeLeft:
- return [arr indexOfObject:@"UIInterfaceOrientationLandscapeLeft"] != NSNotFound ? YES : NO;
-
- case UIInterfaceOrientationLandscapeRight:
- return [arr indexOfObject:@"UIInterfaceOrientationLandscapeRight"] != NSNotFound ? YES : NO;
-
- case UIInterfaceOrientationPortrait:
- return [arr indexOfObject:@"UIInterfaceOrientationPortrait"] != NSNotFound ? YES : NO;
-
- case UIInterfaceOrientationPortraitUpsideDown:
- return [arr indexOfObject:@"UIInterfaceOrientationPortraitUpsideDown"] != NSNotFound ? YES : NO;
-
- default:
- return NO;
- }
- };
-
- uint8_t supported = OSIPhone::get_singleton()->get_orientations();
- switch (p_orientation) {
-
- case UIInterfaceOrientationLandscapeLeft:
- return supported & (1 << OSIPhone::LandscapeLeft) ? YES : NO;
-
- case UIInterfaceOrientationLandscapeRight:
- return supported & (1 << OSIPhone::LandscapeRight) ? YES : NO;
-
- case UIInterfaceOrientationPortrait:
- return supported & (1 << OSIPhone::PortraitDown) ? YES : NO;
-
- case UIInterfaceOrientationPortraitUpsideDown:
- return supported & (1 << OSIPhone::PortraitUp) ? YES : NO;
-
+- (BOOL)shouldAutorotate {
+ switch (OS::get_singleton()->get_screen_orientation()) {
+ case OS::SCREEN_SENSOR:
+ case OS::SCREEN_SENSOR_LANDSCAPE:
+ case OS::SCREEN_SENSOR_PORTRAIT:
+ return YES;
default:
return NO;
}
};
+- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
+ switch (OS::get_singleton()->get_screen_orientation()) {
+ case OS::SCREEN_PORTRAIT:
+ return UIInterfaceOrientationMaskPortrait;
+ case OS::SCREEN_REVERSE_LANDSCAPE:
+ return UIInterfaceOrientationMaskLandscapeRight;
+ case OS::SCREEN_REVERSE_PORTRAIT:
+ return UIInterfaceOrientationMaskPortraitUpsideDown;
+ case OS::SCREEN_SENSOR_LANDSCAPE:
+ return UIInterfaceOrientationMaskLandscape;
+ case OS::SCREEN_SENSOR_PORTRAIT:
+ return UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown;
+ case OS::SCREEN_SENSOR:
+ return UIInterfaceOrientationMaskAll;
+ case OS::SCREEN_LANDSCAPE:
+ return UIInterfaceOrientationMaskLandscapeLeft;
+ }
+};
+
- (BOOL)prefersStatusBarHidden {
return YES;
}
diff --git a/platform/javascript/dom_keys.h b/platform/javascript/dom_keys.inc
index 4edca63c6d..dc8d67d52b 100644
--- a/platform/javascript/dom_keys.h
+++ b/platform/javascript/dom_keys.inc
@@ -1,5 +1,5 @@
/*************************************************************************/
-/* dom_keys.h */
+/* dom_keys.inc */
/*************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
@@ -28,9 +28,6 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#ifndef DOM_KEYS_H
-#define DOM_KEYS_H
-
#include "os/keyboard.h"
// https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode#Constants_for_keyCode_value
@@ -295,8 +292,8 @@ int dom2godot_scancode(int dom_keycode) {
//case DOM_VK_SELECT: return KEY_UNKNOWN;
- case DOM_VK_PRINTSCREEN: // this is the usual printScreen key
- case DOM_VK_PRINT: // maybe for alt+printScreen or physical printers?
+ case DOM_VK_PRINTSCREEN:
+ case DOM_VK_PRINT:
return KEY_PRINT;
//case DOM_VK_EXECUTE: return KEY_UNKNOWN;
@@ -311,11 +308,11 @@ int dom2godot_scancode(int dom_keycode) {
case DOM_VK_SLEEP:
return KEY_STANDBY;
- // these are numpad keys according to MDN
+ // Numpad keys
case DOM_VK_MULTIPLY: return KEY_KP_MULTIPLY;
case DOM_VK_ADD: return KEY_KP_ADD;
case DOM_VK_SEPARATOR:
- return KEY_KP_PERIOD; // good enough?
+ return KEY_KP_PERIOD; // Good enough?
case DOM_VK_SUBTRACT: return KEY_KP_SUBTRACT;
case DOM_VK_DECIMAL: return KEY_KP_PERIOD;
case DOM_VK_DIVIDE:
@@ -376,10 +373,8 @@ int dom2godot_scancode(int dom_keycode) {
case DOM_VK_QUOTE:
return KEY_APOSTROPHE;
- // rest is OEM/unusual
+ // The rest is OEM/unusual.
default: return KEY_UNKNOWN;
};
}
-
-#endif
diff --git a/platform/javascript/javascript_main.cpp b/platform/javascript/javascript_main.cpp
index 68a2d72464..3829e8d406 100644
--- a/platform/javascript/javascript_main.cpp
+++ b/platform/javascript/javascript_main.cpp
@@ -28,17 +28,11 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
-#include "emscripten.h"
#include "io/resource_loader.h"
#include "main/main.h"
#include "os_javascript.h"
-OS_JavaScript *os = NULL;
-
-static void main_loop() {
-
- os->main_loop_iterate();
-}
+#include <emscripten/emscripten.h>
extern "C" EMSCRIPTEN_KEEPALIVE void main_after_fs_sync(char *p_idbfs_err) {
@@ -46,18 +40,18 @@ extern "C" EMSCRIPTEN_KEEPALIVE void main_after_fs_sync(char *p_idbfs_err) {
if (!idbfs_err.empty()) {
print_line("IndexedDB not available: " + idbfs_err);
}
- os->set_idbfs_available(idbfs_err.empty());
- // Ease up compatibility
+ OS_JavaScript *os = OS_JavaScript::get_singleton();
+ os->set_idb_available(idbfs_err.empty());
+ // Ease up compatibility.
ResourceLoader::set_abort_on_missing_resources(false);
Main::start();
- os->main_loop_begin();
- emscripten_set_main_loop(main_loop, 0, false);
+ os->run_async();
}
int main(int argc, char *argv[]) {
- // sync from persistent state into memory and then
- // run the 'main_after_fs_sync' function
+ // Sync from persistent state into memory and then
+ // run the 'main_after_fs_sync' function.
/* clang-format off */
EM_ASM(
FS.mkdir('/userfs');
@@ -68,9 +62,10 @@ int main(int argc, char *argv[]) {
);
/* clang-format on */
- os = new OS_JavaScript(argv[0], NULL);
- Error err = Main::setup(argv[0], argc - 1, &argv[1]);
+ new OS_JavaScript(argc, argv);
+ // TODO: Check error return value.
+ Main::setup(argv[0], argc - 1, &argv[1]);
return 0;
- // continued async in main_after_fs_sync() from syncfs() callback
+ // Continued async in main_after_fs_sync() from the syncfs() callback.
}
diff --git a/platform/javascript/logo.png b/platform/javascript/logo.png
index ce911180ac..36832d93ba 100644
--- a/platform/javascript/logo.png
+++ b/platform/javascript/logo.png
Binary files differ
diff --git a/platform/javascript/os_javascript.cpp b/platform/javascript/os_javascript.cpp
index 6c6e4d2d1c..b9d586e233 100644
--- a/platform/javascript/os_javascript.cpp
+++ b/platform/javascript/os_javascript.cpp
@@ -30,290 +30,196 @@
#include "os_javascript.h"
-#include "core/engine.h"
-#include "core/io/file_access_buffered_fa.h"
-#include "dom_keys.h"
-#include "drivers/gles2/rasterizer_gles2.h"
-#include "drivers/gles3/rasterizer_gles3.h"
-#include "drivers/unix/dir_access_unix.h"
-#include "drivers/unix/file_access_unix.h"
+#include "gles2/rasterizer_gles2.h"
+#include "gles3/rasterizer_gles3.h"
+#include "io/file_access_buffered_fa.h"
#include "main/main.h"
#include "servers/visual/visual_server_raster.h"
+#include "unix/dir_access_unix.h"
+#include "unix/file_access_unix.h"
#include <emscripten.h>
#include <stdlib.h>
+#include "dom_keys.inc"
+
#define DOM_BUTTON_LEFT 0
#define DOM_BUTTON_MIDDLE 1
#define DOM_BUTTON_RIGHT 2
+#define DOM_BUTTON_XBUTTON1 3
+#define DOM_BUTTON_XBUTTON2 4
-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 {
+// Window (canvas)
- return VIDEO_DRIVER_MAX;
-}
-
-const char *OS_JavaScript::get_video_driver_name(int p_driver) const {
-
- switch (p_driver) {
- case VIDEO_DRIVER_GLES3:
- return "GLES3";
- case VIDEO_DRIVER_GLES2:
- return "GLES2";
- }
- ERR_EXPLAIN("Invalid video driver index " + itos(p_driver));
- ERR_FAIL_V(NULL);
-}
-
-int OS_JavaScript::get_audio_driver_count() const {
-
- return 1;
-}
-
-const char *OS_JavaScript::get_audio_driver_name(int p_driver) const {
+static void focus_canvas() {
- return "JavaScript";
+ /* clang-format off */
+ EM_ASM(
+ Module.canvas.focus();
+ );
+ /* clang-format on */
}
-void OS_JavaScript::initialize_core() {
+static bool is_canvas_focused() {
- OS_Unix::initialize_core();
- FileAccess::make_default<FileAccessBufferedFA<FileAccessUnix> >(FileAccess::ACCESS_RESOURCES);
+ /* clang-format off */
+ return EM_ASM_INT_V(
+ return document.activeElement == Module.canvas;
+ );
+ /* clang-format on */
}
-static EM_BOOL _browser_resize_callback(int event_type, const EmscriptenUiEvent *ui_event, void *user_data) {
+static bool cursor_inside_canvas = true;
- ERR_FAIL_COND_V(event_type != EMSCRIPTEN_EVENT_RESIZE, false);
+EM_BOOL OS_JavaScript::browser_resize_callback(int p_event_type, const EmscriptenUiEvent *p_event, void *p_user_data) {
- OS_JavaScript *os = static_cast<OS_JavaScript *>(user_data);
// 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();
+ // event varies, even within just one browser, so defer handling.
+ get_singleton()->canvas_size_adjustment_requested = true;
return false;
}
-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);
+EM_BOOL OS_JavaScript::fullscreen_change_callback(int p_event_type, const EmscriptenFullscreenChangeEvent *p_event, void *p_user_data) {
- OS_JavaScript *os = static_cast<OS_JavaScript *>(user_data);
- String id = String::utf8(event->id);
- // empty id is canvas
- if (id.empty() || id == "canvas") {
-
- OS::VideoMode vm = os->get_video_mode();
- // 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();
+ OS_JavaScript *os = get_singleton();
+ // Empty ID is canvas.
+ String target_id = String::utf8(p_event->id);
+ if (target_id.empty() || target_id == "canvas") {
+ // This event property is the only reliable data on
+ // browser fullscreen state.
+ os->video_mode.fullscreen = p_event->isFullscreen;
+ os->canvas_size_adjustment_requested = true;
}
return false;
}
-static InputDefault *_input;
-
-static bool is_canvas_focused() {
+void OS_JavaScript::set_video_mode(const VideoMode &p_video_mode, int p_screen) {
- /* clang-format off */
- return EM_ASM_INT_V(
- return document.activeElement == Module.canvas;
- );
- /* clang-format on */
+ video_mode = p_video_mode;
}
-static void focus_canvas() {
+OS::VideoMode OS_JavaScript::get_video_mode(int p_screen) const {
- /* clang-format off */
- EM_ASM(
- Module.canvas.focus();
- );
- /* clang-format on */
+ return video_mode;
}
-static bool _cursor_inside_canvas = true;
-
-static bool is_cursor_inside_canvas() {
+Size2 OS_JavaScript::get_screen_size(int p_screen) const {
- return _cursor_inside_canvas;
+ EmscriptenFullscreenChangeEvent ev;
+ EMSCRIPTEN_RESULT result = emscripten_get_fullscreen_status(&ev);
+ ERR_FAIL_COND_V(result != EMSCRIPTEN_RESULT_SUCCESS, Size2());
+ return Size2(ev.screenWidth, ev.screenHeight);
}
-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;
- }
+void OS_JavaScript::set_window_size(const Size2 p_size) {
- int mask = _input->get_mouse_button_mask();
- int button_flag = 1 << (ev->get_button_index() - 1);
- if (ev->is_pressed()) {
- // Since the event is consumed, focus manually. The containing iframe,
- // if used, may not have focus yet, so focus even if already focused.
- focus_canvas();
- mask |= button_flag;
- } else if (mask & button_flag) {
- mask &= ~button_flag;
+ 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 {
- // release event, but press was outside the canvas, so ignore
- return false;
+ video_mode.width = p_size.x;
+ video_mode.height = p_size.y;
+ emscripten_set_canvas_size(p_size.x, p_size.y);
}
- ev->set_button_mask(mask);
-
- _input->parse_input_event(ev);
- // Prevent multi-click text selection and wheel-click scrolling anchor.
- // Context menu is prevented through contextmenu event.
- 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);
-
- ev->set_position(pos);
- ev->set_global_position(ev->get_position());
-
- ev->set_relative(Vector2(mouse_event->movementX, mouse_event->movementY));
- _input->set_mouse_position(ev->get_position());
- ev->set_speed(_input->get_last_mouse_speed());
+Size2 OS_JavaScript::get_window_size() const {
- _input->parse_input_event(ev);
- // don't suppress mouseover/leave events
- return false;
+ int canvas[3];
+ emscripten_get_canvas_size(canvas, canvas + 1, canvas + 2);
+ return Size2(canvas[0], canvas[1]);
}
-static EM_BOOL _wheel_callback(int event_type, const EmscriptenWheelEvent *wheel_event, void *user_data) {
+void OS_JavaScript::set_window_maximized(bool p_enabled) {
- ERR_FAIL_COND_V(event_type != EMSCRIPTEN_EVENT_WHEEL, false);
- if (!is_canvas_focused()) {
- if (is_cursor_inside_canvas()) {
- focus_canvas();
- } else {
- return false;
- }
+ window_maximized = p_enabled;
+ 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_fullscreen_enabled) {
- Ref<InputEventMouseButton> ev;
- ev.instance();
- ev->set_button_mask(_input->get_mouse_button_mask());
- 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
+ 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_fullscreen_enabled = true;
+ video_mode.width = get_window_size().width;
+ video_mode.height = get_window_size().height;
+ } else if (!p_enabled) {
- ev->set_pressed(true);
- _input->parse_input_event(ev);
+ emscripten_exit_soft_fullscreen();
+ soft_fullscreen_enabled = false;
+ video_mode.width = windowed_size.width;
+ video_mode.height = windowed_size.height;
+ emscripten_set_canvas_size(video_mode.width, video_mode.height);
+ }
+}
- ev->set_pressed(false);
- _input->parse_input_event(ev);
+bool OS_JavaScript::is_window_maximized() const {
- return true;
+ return window_maximized;
}
-static Point2 _prev_touches[32];
+void OS_JavaScript::set_window_fullscreen(bool p_enabled) {
-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);
+ if (p_enabled == is_window_fullscreen()) {
+ return;
+ }
- Ref<InputEventScreenTouch> ev;
- ev.instance();
- int lowest_id_index = -1;
- for (int i = 0; i < touch_event->numTouches; ++i) {
+ // Just request changes here, if successful, canvas is resized in
+ // _browser_resize_callback or _fullscreen_change_callback.
+ EMSCRIPTEN_RESULT result;
+ if (p_enabled) {
+ if (window_maximized) {
+ // Soft fullsreen during real fulllscreen 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) {
+ ERR_PRINTS("Failed to exit fullscreen: Code " + itos(result));
+ }
+ }
+}
- 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);
+bool OS_JavaScript::is_window_fullscreen() const {
- _input->parse_input_event(ev);
- }
- return true;
+ return video_mode.fullscreen;
}
-static EM_BOOL _touchmove_callback(int event_type, const EmscriptenTouchEvent *touch_event, void *user_data) {
+void OS_JavaScript::get_fullscreen_mode_list(List<VideoMode> *p_list, int p_screen) const {
- ERR_FAIL_COND_V(event_type != EMSCRIPTEN_EVENT_TOUCHMOVE, false);
+ Size2 screen = get_screen_size();
+ p_list->push_back(OS::VideoMode(screen.width, screen.height, true));
+}
- Ref<InputEventScreenDrag> ev;
- ev.instance();
- int lowest_id_index = -1;
- for (int i = 0; i < touch_event->numTouches; ++i) {
+// Keys
- 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();
+template <typename T>
+static void dom2godot_mod(T *emscripten_event_ptr, Ref<InputEventWithModifiers> godot_event) {
- _input->parse_input_event(ev);
- }
- return true;
+ 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);
}
-static Ref<InputEventKey> _setup_key_event(const EmscriptenKeyboardEvent *emscripten_event) {
+static Ref<InputEventKey> setup_key_event(const EmscriptenKeyboardEvent *emscripten_event) {
Ref<InputEventKey> ev;
ev.instance();
@@ -322,9 +228,9 @@ static Ref<InputEventKey> _setup_key_event(const EmscriptenKeyboardEvent *emscri
ev->set_scancode(dom2godot_scancode(emscripten_event->keyCode));
String unicode = String::utf8(emscripten_event->key);
- // check if empty or multi-character (e.g. `CapsLock`)
+ // Check if empty or multi-character (e.g. `CapsLock`).
if (unicode.length() != 1) {
- // might be empty as well, but better than nonsense
+ // Might be empty as well, but better than nonsense.
unicode = String::utf8(emscripten_event->charValue);
}
if (unicode.length() == 1) {
@@ -334,175 +240,115 @@ static Ref<InputEventKey> _setup_key_event(const EmscriptenKeyboardEvent *emscri
return ev;
}
-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);
+EM_BOOL OS_JavaScript::keydown_callback(int p_event_type, const EmscriptenKeyboardEvent *p_event, void *p_user_data) {
- Ref<InputEventKey> ev = _setup_key_event(key_event);
+ OS_JavaScript *os = get_singleton();
+ Ref<InputEventKey> ev = setup_key_event(p_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
+ // Defer to keypress event for legacy unicode retrieval.
+ os->deferred_key_event = ev;
+ // Do not suppress keypress event.
+ return false;
}
- _input->parse_input_event(ev);
+ os->input->parse_input_event(ev);
return true;
}
-static EM_BOOL _keypress_callback(int event_type, const EmscriptenKeyboardEvent *key_event, void *user_data) {
-
- ERR_FAIL_COND_V(event_type != EMSCRIPTEN_EVENT_KEYPRESS, false);
+EM_BOOL OS_JavaScript::keypress_callback(int p_event_type, const EmscriptenKeyboardEvent *p_event, void *p_user_data) {
- deferred_key_event->set_unicode(key_event->charCode);
- _input->parse_input_event(deferred_key_event);
+ OS_JavaScript *os = get_singleton();
+ os->deferred_key_event->set_unicode(p_event->charCode);
+ os->input->parse_input_event(os->deferred_key_event);
return true;
}
-static EM_BOOL _keyup_callback(int event_type, const EmscriptenKeyboardEvent *key_event, void *user_data) {
-
- ERR_FAIL_COND_V(event_type != EMSCRIPTEN_EVENT_KEYUP, false);
+EM_BOOL OS_JavaScript::keyup_callback(int p_event_type, const EmscriptenKeyboardEvent *p_event, void *p_user_data) {
- Ref<InputEventKey> ev = _setup_key_event(key_event);
+ Ref<InputEventKey> ev = setup_key_event(p_event);
ev->set_pressed(false);
- _input->parse_input_event(ev);
+ get_singleton()->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) {
- OS_JavaScript *os = (OS_JavaScript *)OS::get_singleton();
- if (os) {
- return os->joy_connection_changed(p_type, p_event);
- }
- return false;
+// Mouse
+
+Point2 OS_JavaScript::get_mouse_position() const {
+
+ return input->get_mouse_position();
}
-extern "C" EMSCRIPTEN_KEEPALIVE void send_notification(int notif) {
+int OS_JavaScript::get_mouse_button_state() const {
- 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);
+ return input->get_mouse_button_mask();
}
-Error OS_JavaScript::initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver) {
+EM_BOOL OS_JavaScript::mouse_button_callback(int p_event_type, const EmscriptenMouseEvent *p_event, void *p_user_data) {
- print_line("Init OS");
+ OS_JavaScript *os = get_singleton();
- EmscriptenWebGLContextAttributes attributes;
- emscripten_webgl_init_context_attributes(&attributes);
- attributes.alpha = false;
- attributes.antialias = false;
- ERR_FAIL_INDEX_V(p_video_driver, VIDEO_DRIVER_MAX, ERR_INVALID_PARAMETER);
- switch (p_video_driver) {
- case VIDEO_DRIVER_GLES3:
- attributes.majorVersion = 2;
- RasterizerGLES3::register_config();
- RasterizerGLES3::make_current();
- break;
- case VIDEO_DRIVER_GLES2:
- attributes.majorVersion = 1;
- RasterizerGLES2::register_config();
- RasterizerGLES2::make_current();
- break;
+ Ref<InputEventMouseButton> ev;
+ ev.instance();
+ ev->set_pressed(p_event_type == EMSCRIPTEN_EVENT_MOUSEDOWN);
+ ev->set_position(Point2(p_event->canvasX, p_event->canvasY));
+ ev->set_global_position(ev->get_position());
+ dom2godot_mod(p_event, ev);
+ switch (p_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;
+ case DOM_BUTTON_XBUTTON1: ev->set_button_index(BUTTON_XBUTTON1); break;
+ case DOM_BUTTON_XBUTTON2: ev->set_button_index(BUTTON_XBUTTON2); break;
+ default: return false;
}
- EMSCRIPTEN_WEBGL_CONTEXT_HANDLE ctx = emscripten_webgl_create_context(NULL, &attributes);
- ERR_EXPLAIN("WebGL " + itos(attributes.majorVersion) + ".0 not available");
- ERR_FAIL_COND_V(emscripten_webgl_make_context_current(ctx) != EMSCRIPTEN_RESULT_SUCCESS, ERR_UNAVAILABLE);
- video_mode = p_desired;
- // can't fulfil fullscreen request due to browser security
- video_mode.fullscreen = false;
- /* clang-format off */
- if (EM_ASM_INT_V({ return Module.resizeCanvasOnStart })) {
- /* clang-format on */
- set_window_size(Size2(video_mode.width, video_mode.height));
+ int mask = os->input->get_mouse_button_mask();
+ int button_flag = 1 << (ev->get_button_index() - 1);
+ if (ev->is_pressed()) {
+ // Since the event is consumed, focus manually. The containing iframe,
+ // if exists, may not have focus yet, so focus even if already focused.
+ focus_canvas();
+ mask |= button_flag;
+ } else if (mask & button_flag) {
+ mask &= ~button_flag;
} else {
- set_window_size(get_window_size());
+ // Received release event, but press was outside the canvas, so ignore.
+ return false;
}
+ ev->set_button_mask(mask);
- char locale_ptr[16];
- /* clang-format off */
- EM_ASM_ARGS({
- stringToUTF8(Module.locale, $0, 16);
- }, locale_ptr);
- /* clang-format on */
- setenv("LANG", locale_ptr, true);
-
- print_line("Init Audio");
-
- AudioDriverManager::initialize(p_audio_driver);
-
- print_line("Init VS");
-
- visual_server = memnew(VisualServerRaster());
- // visual_server->cursor_set_visible(false, 0);
-
- print_line("Init Physicsserver");
-
- input = memnew(InputDefault);
- _input = input;
-
-#define EM_CHECK(ev) \
- if (result != EMSCRIPTEN_RESULT_SUCCESS) \
- ERR_PRINTS("Error while setting " #ev " callback: Code " + itos(result))
-#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("#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)
-
-#undef SET_EM_CALLBACK_NODATA
-#undef SET_EM_CALLBACK
-#undef EM_CHECK
-
- visual_server->init();
-
- return OK;
+ os->input->parse_input_event(ev);
+ // Prevent multi-click text selection and wheel-click scrolling anchor.
+ // Context menu is prevented through contextmenu event.
+ return true;
}
-void OS_JavaScript::set_main_loop(MainLoop *p_main_loop) {
+EM_BOOL OS_JavaScript::mousemove_callback(int p_event_type, const EmscriptenMouseEvent *p_event, void *p_user_data) {
- main_loop = p_main_loop;
- input->set_main_loop(p_main_loop);
-}
-
-void OS_JavaScript::delete_main_loop() {
+ OS_JavaScript *os = get_singleton();
- memdelete(main_loop);
-}
+ int input_mask = os->input->get_mouse_button_mask();
+ Point2 pos = Point2(p_event->canvasX, p_event->canvasY);
+ // For motion outside the canvas, only read mouse movement if dragging
+ // started inside the canvas; imitating desktop app behaviour.
+ if (!cursor_inside_canvas && !input_mask)
+ return false;
-void OS_JavaScript::finalize() {
+ Ref<InputEventMouseMotion> ev;
+ ev.instance();
+ dom2godot_mod(p_event, ev);
+ ev->set_button_mask(input_mask);
- memdelete(input);
-}
+ ev->set_position(pos);
+ ev->set_global_position(ev->get_position());
-void OS_JavaScript::alert(const String &p_alert, const String &p_title) {
+ ev->set_relative(Vector2(p_event->movementX, p_event->movementY));
+ os->input->set_mouse_position(ev->get_position());
+ ev->set_speed(os->input->get_last_mouse_speed());
- /* clang-format off */
- EM_ASM_({
- window.alert(UTF8ToString($0));
- }, p_alert.utf8().get_data());
- /* clang-format on */
+ os->input->parse_input_event(ev);
+ // Don't suppress mouseover/-leave events.
+ return false;
}
static const char *godot2dom_cursor(OS::CursorShape p_shape) {
@@ -530,7 +376,7 @@ static const char *godot2dom_cursor(OS::CursorShape p_shape) {
}
}
-void OS_JavaScript::set_css_cursor(const char *p_cursor) {
+static void set_css_cursor(const char *p_cursor) {
/* clang-format off */
EM_ASM_({
@@ -539,7 +385,7 @@ void OS_JavaScript::set_css_cursor(const char *p_cursor) {
/* clang-format on */
}
-const char *OS_JavaScript::get_css_cursor() const {
+static const char *get_css_cursor() {
char cursor[16];
/* clang-format off */
@@ -550,9 +396,20 @@ const char *OS_JavaScript::get_css_cursor() const {
return cursor;
}
+void OS_JavaScript::set_cursor_shape(CursorShape p_shape) {
+
+ 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::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) {
+}
+
void OS_JavaScript::set_mouse_mode(OS::MouseMode p_mode) {
- 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())
@@ -580,190 +437,308 @@ void OS_JavaScript::set_mouse_mode(OS::MouseMode p_mode) {
OS::MouseMode OS_JavaScript::get_mouse_mode() const {
- if (!strcmp(get_css_cursor(), "none"))
+ if (String::utf8(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;
+ return (ev.isActive && String::utf8(ev.id) == "canvas") ? MOUSE_MODE_CAPTURED : MOUSE_MODE_VISIBLE;
}
-Point2 OS_JavaScript::get_mouse_position() const {
+// Wheel
- return input->get_mouse_position();
-}
+EM_BOOL OS_JavaScript::wheel_callback(int p_event_type, const EmscriptenWheelEvent *p_event, void *p_user_data) {
-int OS_JavaScript::get_mouse_button_state() const {
+ ERR_FAIL_COND_V(p_event_type != EMSCRIPTEN_EVENT_WHEEL, false);
+ if (!is_canvas_focused()) {
+ if (cursor_inside_canvas) {
+ focus_canvas();
+ } else {
+ return false;
+ }
+ }
- return input->get_mouse_button_mask();
-}
+ InputDefault *input = get_singleton()->input;
+ Ref<InputEventMouseButton> ev;
+ ev.instance();
+ ev->set_button_mask(input->get_mouse_button_mask());
+ ev->set_position(input->get_mouse_position());
+ ev->set_global_position(ev->get_position());
-void OS_JavaScript::set_window_title(const String &p_title) {
+ 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));
- /* clang-format off */
- EM_ASM_({
- document.title = UTF8ToString($0);
- }, p_title.utf8().get_data());
- /* clang-format on */
-}
+ if (p_event->deltaY < 0)
+ ev->set_button_index(BUTTON_WHEEL_UP);
+ else if (p_event->deltaY > 0)
+ ev->set_button_index(BUTTON_WHEEL_DOWN);
+ else if (p_event->deltaX > 0)
+ ev->set_button_index(BUTTON_WHEEL_LEFT);
+ else if (p_event->deltaX < 0)
+ ev->set_button_index(BUTTON_WHEEL_RIGHT);
+ else
+ return false;
-//interesting byt not yet
-//void set_clipboard(const String& p_text);
-//String get_clipboard() const;
+ // Different browsers give wildly different delta values, and we can't
+ // interpret deltaMode, so use default value for wheel events' factor.
-void OS_JavaScript::set_video_mode(const VideoMode &p_video_mode, int p_screen) {
+ ev->set_pressed(true);
+ input->parse_input_event(ev);
- video_mode = p_video_mode;
+ ev->set_pressed(false);
+ input->parse_input_event(ev);
+
+ return true;
}
-OS::VideoMode OS_JavaScript::get_video_mode(int p_screen) const {
+// Touch
- return video_mode;
+bool OS_JavaScript::has_touchscreen_ui_hint() const {
+
+ /* clang-format off */
+ return EM_ASM_INT_V(
+ return 'ontouchstart' in window;
+ );
+ /* clang-format on */
}
-Size2 OS_JavaScript::get_screen_size(int p_screen) const {
+EM_BOOL OS_JavaScript::touch_press_callback(int p_event_type, const EmscriptenTouchEvent *p_event, void *p_user_data) {
- EmscriptenFullscreenChangeEvent ev;
- EMSCRIPTEN_RESULT result = emscripten_get_fullscreen_status(&ev);
- ERR_FAIL_COND_V(result != EMSCRIPTEN_RESULT_SUCCESS, Size2());
- return Size2(ev.screenWidth, ev.screenHeight);
-}
+ OS_JavaScript *os = get_singleton();
+ Ref<InputEventScreenTouch> ev;
+ ev.instance();
+ int lowest_id_index = -1;
+ for (int i = 0; i < p_event->numTouches; ++i) {
-void OS_JavaScript::set_window_size(const Size2 p_size) {
+ const EmscriptenTouchPoint &touch = p_event->touches[i];
+ if (lowest_id_index == -1 || touch.identifier < p_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));
+ os->touches[i] = ev->get_position();
+ ev->set_pressed(p_event_type == EMSCRIPTEN_EVENT_TOUCHSTART);
- 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);
+ os->input->parse_input_event(ev);
}
+ return true;
}
-Size2 OS_JavaScript::get_window_size() const {
+EM_BOOL OS_JavaScript::touchmove_callback(int p_event_type, const EmscriptenTouchEvent *p_event, void *p_user_data) {
- int canvas[3];
- emscripten_get_canvas_size(canvas, canvas + 1, canvas + 2);
- return Size2(canvas[0], canvas[1]);
-}
+ OS_JavaScript *os = get_singleton();
+ Ref<InputEventScreenDrag> ev;
+ ev.instance();
+ int lowest_id_index = -1;
+ for (int i = 0; i < p_event->numTouches; ++i) {
-void OS_JavaScript::set_window_maximized(bool p_enabled) {
+ const EmscriptenTouchPoint &touch = p_event->touches[i];
+ if (lowest_id_index == -1 || touch.identifier < p_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 = os->touches[i];
+ ev->set_relative(ev->get_position() - prev);
+ prev = ev->get_position();
- window_maximized = p_enabled;
- if (is_window_fullscreen()) {
- set_window_fullscreen(false);
- return;
+ os->input->parse_input_event(ev);
}
- // Calling emscripten_enter_soft_fullscreen mutltiple times hides all
- // page elements except the canvas permanently, so track state
- if (p_enabled && !soft_fs_enabled) {
+ return 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_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) {
+// Gamepad
- 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);
+EM_BOOL OS_JavaScript::gamepad_change_callback(int p_event_type, const EmscriptenGamepadEvent *p_event, void *p_user_data) {
+
+ InputDefault *input = get_singleton()->input;
+ if (p_event_type == EMSCRIPTEN_EVENT_GAMEPADCONNECTED) {
+
+ String guid = "";
+ if (String::utf8(p_event->mapping) == "standard")
+ guid = "Default HTML5 Gamepad";
+ input->joy_connection_changed(p_event->index, true, String::utf8(p_event->id), guid);
+ } else {
+ input->joy_connection_changed(p_event->index, false, "");
}
+ return true;
}
-void OS_JavaScript::set_window_fullscreen(bool p_enable) {
+void OS_JavaScript::process_joypads() {
- if (p_enable == is_window_fullscreen()) {
- return;
- }
+ int joypad_count = emscripten_get_num_gamepads();
+ for (int joypad = 0; joypad < joypad_count; joypad++) {
+ EmscriptenGamepadEvent state;
+ emscripten_get_gamepad_status(joypad, &state);
+ if (state.connected) {
- // only requesting changes here, if successful, canvas is resized in
- // _browser_resize_callback or _fullscreen_change_callback
- EMSCRIPTEN_RESULT result;
- if (p_enable) {
- 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) {
- ERR_PRINTS("Failed to exit fullscreen: Code " + itos(result));
+ int button_count = MIN(state.numButtons, 18);
+ int axis_count = MIN(state.numAxes, 8);
+ for (int button = 0; button < button_count; button++) {
+
+ float value = state.analogButton[button];
+ if (String::utf8(state.mapping) == "standard" && (button == JOY_ANALOG_L2 || button == JOY_ANALOG_R2)) {
+ InputDefault::JoyAxis joy_axis;
+ joy_axis.min = 0;
+ joy_axis.value = value;
+ input->joy_axis(joypad, button, joy_axis);
+ } else {
+ input->joy_button(joypad, button, value);
+ }
+ }
+ for (int axis = 0; axis < axis_count; axis++) {
+
+ InputDefault::JoyAxis joy_axis;
+ joy_axis.min = -1;
+ joy_axis.value = state.axis[axis];
+ input->joy_axis(joypad, axis, joy_axis);
+ }
}
}
}
-bool OS_JavaScript::is_window_fullscreen() const {
+bool OS_JavaScript::is_joy_known(int p_device) {
- return video_mode.fullscreen;
+ return input->is_joy_mapped(p_device);
}
-void OS_JavaScript::request_canvas_size_adjustment() {
+String OS_JavaScript::get_joy_guid(int p_device) const {
- canvas_size_adjustment_requested = true;
+ return input->get_joy_guid_remapped(p_device);
}
-void OS_JavaScript::get_fullscreen_mode_list(List<VideoMode> *p_list, int p_screen) const {
+// Video
- Size2 screen = get_screen_size();
- p_list->push_back(OS::VideoMode(screen.width, screen.height, true));
+int OS_JavaScript::get_video_driver_count() const {
+
+ return VIDEO_DRIVER_MAX;
}
-String OS_JavaScript::get_name() {
+const char *OS_JavaScript::get_video_driver_name(int p_driver) const {
- return "HTML5";
+ switch (p_driver) {
+ case VIDEO_DRIVER_GLES3:
+ return "GLES3";
+ case VIDEO_DRIVER_GLES2:
+ return "GLES2";
+ }
+ ERR_EXPLAIN("Invalid video driver index " + itos(p_driver));
+ ERR_FAIL_V(NULL);
}
-MainLoop *OS_JavaScript::get_main_loop() const {
+// Audio
- return main_loop;
+int OS_JavaScript::get_audio_driver_count() const {
+
+ return 1;
}
-bool OS_JavaScript::can_draw() const {
+const char *OS_JavaScript::get_audio_driver_name(int p_driver) const {
- return true; //always?
+ return "JavaScript";
}
-void OS_JavaScript::set_cursor_shape(CursorShape p_shape) {
+// Lifecycle
+int OS_JavaScript::get_current_video_driver() const {
+ return video_driver_index;
+}
- ERR_FAIL_INDEX(p_shape, CURSOR_MAX);
+void OS_JavaScript::initialize_core() {
- cursor_shape = p_shape;
- if (get_mouse_mode() != MOUSE_MODE_HIDDEN)
- set_css_cursor(godot2dom_cursor(cursor_shape));
+ OS_Unix::initialize_core();
+ FileAccess::make_default<FileAccessBufferedFA<FileAccessUnix> >(FileAccess::ACCESS_RESOURCES);
}
-void OS_JavaScript::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot) {
-}
+Error OS_JavaScript::initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver) {
-void OS_JavaScript::main_loop_begin() {
+ EmscriptenWebGLContextAttributes attributes;
+ emscripten_webgl_init_context_attributes(&attributes);
+ attributes.alpha = false;
+ attributes.antialias = false;
+ ERR_FAIL_INDEX_V(p_video_driver, VIDEO_DRIVER_MAX, ERR_INVALID_PARAMETER);
+ switch (p_video_driver) {
+ case VIDEO_DRIVER_GLES3:
+ attributes.majorVersion = 2;
+ RasterizerGLES3::register_config();
+ RasterizerGLES3::make_current();
+ break;
+ case VIDEO_DRIVER_GLES2:
+ attributes.majorVersion = 1;
+ RasterizerGLES2::register_config();
+ RasterizerGLES2::make_current();
+ break;
+ }
+
+ video_driver_index = p_video_driver;
+ EMSCRIPTEN_WEBGL_CONTEXT_HANDLE ctx = emscripten_webgl_create_context(NULL, &attributes);
+ ERR_EXPLAIN("WebGL " + itos(attributes.majorVersion) + ".0 not available");
+ ERR_FAIL_COND_V(emscripten_webgl_make_context_current(ctx) != EMSCRIPTEN_RESULT_SUCCESS, ERR_UNAVAILABLE);
+
+ video_mode = p_desired;
+ // Can't fulfil fullscreen request during start-up due to browser security.
+ video_mode.fullscreen = false;
+ /* clang-format off */
+ if (EM_ASM_INT_V({ return Module.resizeCanvasOnStart })) {
+ /* clang-format on */
+ set_window_size(Size2(video_mode.width, video_mode.height));
+ } else {
+ set_window_size(get_window_size());
+ }
- if (main_loop)
- main_loop->init();
+ char locale_ptr[16];
+ /* clang-format off */
+ EM_ASM_ARGS({
+ stringToUTF8(Module.locale, $0, 16);
+ }, locale_ptr);
+ /* clang-format on */
+ setenv("LANG", locale_ptr, true);
+
+ AudioDriverManager::initialize(p_audio_driver);
+ VisualServer *visual_server = memnew(VisualServerRaster());
+ input = memnew(InputDefault);
+
+ EMSCRIPTEN_RESULT result;
+#define EM_CHECK(ev) \
+ if (result != EMSCRIPTEN_RESULT_SUCCESS) \
+ ERR_PRINTS("Error while setting " #ev " callback: Code " + itos(result))
+#define SET_EM_CALLBACK(target, ev, cb) \
+ result = emscripten_set_##ev##_callback(target, NULL, true, &cb); \
+ EM_CHECK(ev)
+#define SET_EM_CALLBACK_NOTARGET(ev, cb) \
+ result = emscripten_set_##ev##_callback(NULL, true, &cb); \
+ EM_CHECK(ev)
+ // These callbacks from Emscripten's html5.h suffice to access most
+ // JavaScript APIs. For APIs that are not (sufficiently) exposed, EM_ASM
+ // is used below.
+ SET_EM_CALLBACK("#window", mousemove, mousemove_callback)
+ SET_EM_CALLBACK("#canvas", mousedown, mouse_button_callback)
+ SET_EM_CALLBACK("#window", mouseup, mouse_button_callback)
+ SET_EM_CALLBACK("#window", wheel, wheel_callback)
+ SET_EM_CALLBACK("#window", touchstart, touch_press_callback)
+ SET_EM_CALLBACK("#window", touchmove, touchmove_callback)
+ SET_EM_CALLBACK("#window", touchend, touch_press_callback)
+ SET_EM_CALLBACK("#window", touchcancel, touch_press_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_NOTARGET(gamepadconnected, gamepad_change_callback)
+ SET_EM_CALLBACK_NOTARGET(gamepaddisconnected, gamepad_change_callback)
+#undef SET_EM_CALLBACK_NODATA
+#undef SET_EM_CALLBACK
+#undef EM_CHECK
/* clang-format off */
EM_ASM_ARGS({
const send_notification = cwrap('send_notification', null, ['number']);
- const notifs = arguments;
- (['mouseover', 'mouseleave', 'focus', 'blur']).forEach(function(event, i) {
- Module.canvas.addEventListener(event, send_notification.bind(null, notifs[i]));
+ const notifications = arguments;
+ (['mouseover', 'mouseleave', 'focus', 'blur']).forEach(function(event, index) {
+ Module.canvas.addEventListener(event, send_notification.bind(null, notifications[index]));
});
},
MainLoop::NOTIFICATION_WM_MOUSE_ENTER,
@@ -772,22 +747,44 @@ void OS_JavaScript::main_loop_begin() {
MainLoop::NOTIFICATION_WM_FOCUS_OUT
);
/* clang-format on */
+
+ visual_server->init();
+
+ return OK;
}
-bool OS_JavaScript::main_loop_iterate() {
+void OS_JavaScript::set_main_loop(MainLoop *p_main_loop) {
- if (!main_loop)
- return false;
+ main_loop = p_main_loop;
+ input->set_main_loop(p_main_loop);
+}
+
+MainLoop *OS_JavaScript::get_main_loop() const {
+
+ return main_loop;
+}
+
+void OS_JavaScript::run_async() {
+
+ main_loop->init();
+ emscripten_set_main_loop(main_loop_callback, -1, false);
+}
+
+void OS_JavaScript::main_loop_callback() {
+
+ get_singleton()->main_loop_iterate();
+}
+
+bool OS_JavaScript::main_loop_iterate() {
- if (idbfs_available && time_to_save_sync >= 0) {
- int64_t newtime = get_ticks_msec();
- int64_t elapsed = newtime - last_sync_time;
- last_sync_time = newtime;
+ if (is_userfs_persistent() && sync_wait_time >= 0) {
+ int64_t current_time = get_ticks_msec();
+ int64_t elapsed_time = current_time - last_sync_check_time;
+ last_sync_check_time = current_time;
- time_to_save_sync -= elapsed;
+ sync_wait_time -= elapsed_time;
- if (time_to_save_sync < 0) {
- //time to sync, for real
+ if (sync_wait_time < 0) {
/* clang-format off */
EM_ASM(
FS.syncfs(function(err) {
@@ -812,121 +809,101 @@ bool OS_JavaScript::main_loop_iterate() {
return Main::iteration();
}
-void OS_JavaScript::main_loop_end() {
+void OS_JavaScript::delete_main_loop() {
- if (main_loop)
- main_loop->finish();
+ memdelete(main_loop);
}
-void OS_JavaScript::process_accelerometer(const Vector3 &p_accelerometer) {
+void OS_JavaScript::finalize() {
- input->set_accelerometer(p_accelerometer);
+ memdelete(input);
}
-bool OS_JavaScript::has_touchscreen_ui_hint() const {
+// Miscellaneous
- /* clang-format off */
- return EM_ASM_INT_V(
- return 'ontouchstart' in window;
- );
- /* clang-format on */
+extern "C" EMSCRIPTEN_KEEPALIVE void send_notification(int p_notification) {
+
+ if (p_notification == MainLoop::NOTIFICATION_WM_MOUSE_ENTER || p_notification == MainLoop::NOTIFICATION_WM_MOUSE_EXIT) {
+ cursor_inside_canvas = p_notification == MainLoop::NOTIFICATION_WM_MOUSE_ENTER;
+ }
+ OS_JavaScript::get_singleton()->get_main_loop()->notification(p_notification);
}
-void OS_JavaScript::main_loop_request_quit() {
+bool OS_JavaScript::_check_internal_feature_support(const String &p_feature) {
+
+ if (p_feature == "HTML5" || p_feature == "web")
+ return true;
+
+#ifdef JAVASCRIPT_EVAL_ENABLED
+ if (p_feature == "JavaScript")
+ return true;
+#endif
+
+ EMSCRIPTEN_WEBGL_CONTEXT_HANDLE ctx = emscripten_webgl_get_current_context();
+ // All extensions are already automatically enabled, this function allows
+ // checking WebGL extension support without inline JavaScript
+ if (p_feature == "s3tc")
+ return emscripten_webgl_enable_extension(ctx, "WEBGL_compressed_texture_s3tc_srgb");
+ if (p_feature == "etc")
+ return emscripten_webgl_enable_extension(ctx, "WEBGL_compressed_texture_etc1");
+ if (p_feature == "etc2")
+ return emscripten_webgl_enable_extension(ctx, "WEBGL_compressed_texture_etc");
- if (main_loop)
- main_loop->notification(MainLoop::NOTIFICATION_WM_QUIT_REQUEST);
+ return false;
}
-Error OS_JavaScript::shell_open(String p_uri) {
+void OS_JavaScript::alert(const String &p_alert, const String &p_title) {
+
/* clang-format off */
EM_ASM_({
- window.open(UTF8ToString($0), '_blank');
- }, p_uri.utf8().get_data());
+ window.alert(UTF8ToString($0));
+ }, p_alert.utf8().get_data());
/* clang-format on */
- return OK;
}
-String OS_JavaScript::get_resource_dir() const {
+void OS_JavaScript::set_window_title(const String &p_title) {
- return "/"; //javascript has it's own filesystem for resources inside the APK
+ /* clang-format off */
+ EM_ASM_({
+ document.title = UTF8ToString($0);
+ }, p_title.utf8().get_data());
+ /* clang-format on */
}
-String OS_JavaScript::get_user_data_dir() const {
-
- /*
- if (get_user_data_dir_func)
- return get_user_data_dir_func();
- */
- return "/userfs";
-};
-
String OS_JavaScript::get_executable_path() const {
return OS::get_executable_path();
}
-void OS_JavaScript::_close_notification_funcs(const String &p_file, int p_flags) {
+Error OS_JavaScript::shell_open(String p_uri) {
- OS_JavaScript *os = static_cast<OS_JavaScript *>(get_singleton());
- if (os->idbfs_available && p_file.begins_with("/userfs") && p_flags & FileAccess::WRITE) {
- os->last_sync_time = OS::get_singleton()->get_ticks_msec();
- os->time_to_save_sync = 5000; //five seconds since last save
- }
+ // Open URI in a new tab, browser will deal with it by protocol.
+ /* clang-format off */
+ EM_ASM_({
+ window.open(UTF8ToString($0), '_blank');
+ }, p_uri.utf8().get_data());
+ /* clang-format on */
+ return OK;
}
-void OS_JavaScript::process_joypads() {
-
- int joy_count = emscripten_get_num_gamepads();
- for (int i = 0; i < joy_count; i++) {
- EmscriptenGamepadEvent state;
- emscripten_get_gamepad_status(i, &state);
- if (state.connected) {
+String OS_JavaScript::get_name() {
- int num_buttons = MIN(state.numButtons, 18);
- int num_axes = MIN(state.numAxes, 8);
- for (int j = 0; j < num_buttons; j++) {
+ return "HTML5";
+}
- float value = state.analogButton[j];
- if (String(state.mapping) == "standard" && (j == 6 || j == 7)) {
- InputDefault::JoyAxis jx;
- jx.min = 0;
- jx.value = value;
- input->joy_axis(i, j, jx);
- } else {
- input->joy_button(i, j, value);
- }
- }
- for (int j = 0; j < num_axes; j++) {
+bool OS_JavaScript::can_draw() const {
- InputDefault::JoyAxis jx;
- jx.min = -1;
- jx.value = state.axis[j];
- input->joy_axis(i, j, jx);
- }
- }
- }
+ return true; // Always?
}
-bool OS_JavaScript::joy_connection_changed(int p_type, const EmscriptenGamepadEvent *p_event) {
- if (p_type == EMSCRIPTEN_EVENT_GAMEPADCONNECTED) {
+String OS_JavaScript::get_user_data_dir() const {
- String guid = "";
- if (String(p_event->mapping) == "standard")
- guid = "Default HTML5 Gamepad";
- input->joy_connection_changed(p_event->index, true, String(p_event->id), guid);
- } else {
- input->joy_connection_changed(p_event->index, false, "");
- }
- return true;
-}
+ return "/userfs";
+};
-bool OS_JavaScript::is_joy_known(int p_device) {
- return input->is_joy_mapped(p_device);
-}
+String OS_JavaScript::get_resource_dir() const {
-String OS_JavaScript::get_joy_guid(int p_device) const {
- return input->get_joy_guid_remapped(p_device);
+ return "/";
}
OS::PowerState OS_JavaScript::get_power_state() {
@@ -947,59 +924,53 @@ int OS_JavaScript::get_power_percent_left() {
return -1;
}
-bool OS_JavaScript::_check_internal_feature_support(const String &p_feature) {
+void OS_JavaScript::file_access_close_callback(const String &p_file, int p_flags) {
- if (p_feature == "HTML5" || p_feature == "web")
- return true;
-
-#ifdef JAVASCRIPT_EVAL_ENABLED
- if (p_feature == "JavaScript")
- return true;
-#endif
+ OS_JavaScript *os = get_singleton();
+ if (os->is_userfs_persistent() && p_file.begins_with("/userfs") && p_flags & FileAccess::WRITE) {
+ os->last_sync_check_time = OS::get_singleton()->get_ticks_msec();
+ // Wait five seconds in case more files are about to be closed.
+ os->sync_wait_time = 5000;
+ }
+}
- EMSCRIPTEN_WEBGL_CONTEXT_HANDLE ctx = emscripten_webgl_get_current_context();
- // all extensions are already automatically enabled, this function allows
- // checking WebGL extension support without inline JavaScript
- if (p_feature == "s3tc" && emscripten_webgl_enable_extension(ctx, "WEBGL_compressed_texture_s3tc_srgb"))
- return true;
- if (p_feature == "etc" && emscripten_webgl_enable_extension(ctx, "WEBGL_compressed_texture_etc1"))
- return true;
- if (p_feature == "etc2" && emscripten_webgl_enable_extension(ctx, "WEBGL_compressed_texture_etc"))
- return true;
+void OS_JavaScript::set_idb_available(bool p_idb_available) {
- return false;
+ idb_available = p_idb_available;
}
-void OS_JavaScript::set_idbfs_available(bool p_idbfs_available) {
+bool OS_JavaScript::is_userfs_persistent() const {
- idbfs_available = p_idbfs_available;
+ return idb_available;
}
-bool OS_JavaScript::is_userfs_persistent() const {
+OS_JavaScript *OS_JavaScript::get_singleton() {
- return idbfs_available;
+ return static_cast<OS_JavaScript *>(OS::get_singleton());
}
-OS_JavaScript::OS_JavaScript(const char *p_execpath, GetUserDataDirFunc p_get_user_data_dir_func) {
+OS_JavaScript::OS_JavaScript(int p_argc, char *p_argv[]) {
+
+ List<String> arguments;
+ for (int i = 1; i < p_argc; i++) {
+ arguments.push_back(String::utf8(p_argv[i]));
+ }
+ set_cmdline(p_argv[0], arguments);
- set_cmdline(p_execpath, get_cmdline_args());
- main_loop = NULL;
window_maximized = false;
- soft_fs_enabled = false;
+ soft_fullscreen_enabled = false;
canvas_size_adjustment_requested = false;
- get_user_data_dir_func = p_get_user_data_dir_func;
- FileAccessUnix::close_notification_func = _close_notification_funcs;
+ main_loop = NULL;
- idbfs_available = false;
- time_to_save_sync = -1;
+ idb_available = false;
+ sync_wait_time = -1;
+
+ AudioDriverManager::add_driver(&audio_driver_javascript);
Vector<Logger *> loggers;
loggers.push_back(memnew(StdLogger));
_set_logger(memnew(CompositeLogger(loggers)));
- AudioDriverManager::add_driver(&audio_driver_javascript);
-}
-
-OS_JavaScript::~OS_JavaScript() {
+ FileAccessUnix::close_notification_func = file_access_close_callback;
}
diff --git a/platform/javascript/os_javascript.h b/platform/javascript/os_javascript.h
index 46eb1b3f13..915320fe39 100644
--- a/platform/javascript/os_javascript.h
+++ b/platform/javascript/os_javascript.h
@@ -32,51 +32,59 @@
#define OS_JAVASCRIPT_H
#include "audio_driver_javascript.h"
-#include "drivers/unix/os_unix.h"
#include "main/input_default.h"
-#include "os/input.h"
-#include "os/main_loop.h"
#include "servers/audio_server.h"
#include "servers/visual/rasterizer.h"
+#include "unix/os_unix.h"
#include <emscripten/html5.h>
-typedef String (*GetUserDataDirFunc)();
-
class OS_JavaScript : public OS_Unix {
- bool idbfs_available;
- int64_t time_to_save_sync;
- int64_t last_sync_time;
-
- VisualServer *visual_server;
- AudioDriverJavaScript audio_driver_javascript;
-
- InputDefault *input;
+ VideoMode video_mode;
Vector2 windowed_size;
bool window_maximized;
- bool soft_fs_enabled;
+ bool soft_fullscreen_enabled;
bool canvas_size_adjustment_requested;
- VideoMode video_mode;
+
+ InputDefault *input;
+ Ref<InputEventKey> deferred_key_event;
CursorShape cursor_shape;
+ Point2 touches[32];
+
MainLoop *main_loop;
+ AudioDriverJavaScript audio_driver_javascript;
+
+ bool idb_available;
+ int64_t sync_wait_time;
+ int64_t last_sync_check_time;
+
+ static EM_BOOL browser_resize_callback(int p_event_type, const EmscriptenUiEvent *p_event, void *p_user_data);
+ static EM_BOOL fullscreen_change_callback(int p_event_type, const EmscriptenFullscreenChangeEvent *p_event, void *p_user_data);
+
+ static EM_BOOL keydown_callback(int p_event_type, const EmscriptenKeyboardEvent *p_event, void *p_user_data);
+ static EM_BOOL keypress_callback(int p_event_type, const EmscriptenKeyboardEvent *p_event, void *p_user_data);
+ static EM_BOOL keyup_callback(int p_event_type, const EmscriptenKeyboardEvent *p_event, void *p_user_data);
+
+ static EM_BOOL mousemove_callback(int p_event_type, const EmscriptenMouseEvent *p_event, void *p_user_data);
+ static EM_BOOL mouse_button_callback(int p_event_type, const EmscriptenMouseEvent *p_event, void *p_user_data);
- GetUserDataDirFunc get_user_data_dir_func;
+ static EM_BOOL wheel_callback(int p_event_type, const EmscriptenWheelEvent *p_event, void *p_user_data);
- static void _close_notification_funcs(const String &p_file, int p_flags);
+ static EM_BOOL touch_press_callback(int p_event_type, const EmscriptenTouchEvent *p_event, void *p_user_data);
+ static EM_BOOL touchmove_callback(int p_event_type, const EmscriptenTouchEvent *p_event, void *p_user_data);
+ static EM_BOOL gamepad_change_callback(int p_event_type, const EmscriptenGamepadEvent *p_event, void *p_user_data);
void process_joypads();
- void set_css_cursor(const char *);
- const char *get_css_cursor() const;
+ static void main_loop_callback();
-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;
+ static void file_access_close_callback(const String &p_file, int p_flags);
- virtual int get_audio_driver_count() const;
- virtual const char *get_audio_driver_name(int p_driver) const;
+ int video_driver_index;
+
+protected:
+ virtual int get_current_video_driver() const;
virtual void initialize_core();
virtual Error initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver);
@@ -86,77 +94,64 @@ public:
virtual void finalize();
- typedef int64_t ProcessID;
-
- //static OS* get_singleton();
-
- virtual void alert(const String &p_alert, const String &p_title = "ALERT!");
-
- 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);
+ virtual bool _check_internal_feature_support(const String &p_feature);
- //virtual void set_clipboard(const String& p_text);
- //virtual String get_clipboard() const;
+public:
+ // Override return type to make writing static callbacks less tedious.
+ static OS_JavaScript *get_singleton();
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_screen_size(int p_screen = -1) const;
-
virtual void set_window_size(const Size2);
virtual Size2 get_window_size() const;
virtual void set_window_maximized(bool p_enabled);
- virtual bool is_window_maximized() const { return window_maximized; }
- virtual void set_window_fullscreen(bool p_enable);
+ virtual bool is_window_maximized() const;
+ virtual void set_window_fullscreen(bool p_enabled);
virtual bool is_window_fullscreen() const;
+ virtual Size2 get_screen_size(int p_screen = -1) const;
- void request_canvas_size_adjustment();
+ virtual Point2 get_mouse_position() const;
+ virtual int get_mouse_button_state() const;
+ virtual void set_cursor_shape(CursorShape p_shape);
+ virtual void set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot);
+ virtual void set_mouse_mode(MouseMode p_mode);
+ virtual MouseMode get_mouse_mode() const;
- virtual String get_name();
- virtual MainLoop *get_main_loop() const;
+ virtual bool has_touchscreen_ui_hint() const;
- virtual bool can_draw() const;
+ virtual bool is_joy_known(int p_device);
+ virtual String get_joy_guid(int p_device) const;
- virtual bool is_userfs_persistent() const;
+ virtual int get_video_driver_count() const;
+ virtual const char *get_video_driver_name(int p_driver) const;
- virtual void set_cursor_shape(CursorShape p_shape);
- virtual void set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, const Vector2 &p_hotspot);
+ virtual int get_audio_driver_count() const;
+ virtual const char *get_audio_driver_name(int p_driver) const;
- void main_loop_begin();
+ virtual MainLoop *get_main_loop() const;
+ void run_async();
bool main_loop_iterate();
- void main_loop_request_quit();
- void main_loop_end();
- void main_loop_focusout();
- void main_loop_focusin();
- virtual bool has_touchscreen_ui_hint() const;
-
- virtual Error shell_open(String p_uri);
- virtual String get_user_data_dir() const;
+ virtual void alert(const String &p_alert, const String &p_title = "ALERT!");
+ virtual void set_window_title(const String &p_title);
String get_executable_path() const;
- virtual String get_resource_dir() const;
-
- void process_accelerometer(const Vector3 &p_accelerometer);
- void push_input(const Ref<InputEvent> &p_ev);
+ virtual Error shell_open(String p_uri);
+ virtual String get_name();
+ virtual bool can_draw() const;
- virtual bool is_joy_known(int p_device);
- virtual String get_joy_guid(int p_device) const;
- bool joy_connection_changed(int p_type, const EmscriptenGamepadEvent *p_event);
+ virtual String get_resource_dir() const;
+ virtual String get_user_data_dir() const;
virtual OS::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 set_idbfs_available(bool p_idbfs_available);
+ void set_idb_available(bool p_idb_available);
+ virtual bool is_userfs_persistent() const;
- OS_JavaScript(const char *p_execpath, GetUserDataDirFunc p_get_user_data_dir_func);
- ~OS_JavaScript();
+ OS_JavaScript(int p_argc, char *p_argv[]);
};
#endif
diff --git a/platform/javascript/run_icon.png b/platform/javascript/run_icon.png
index dedee6f479..574abb0150 100644
--- a/platform/javascript/run_icon.png
+++ b/platform/javascript/run_icon.png
Binary files differ
diff --git a/platform/osx/crash_handler_osx.mm b/platform/osx/crash_handler_osx.mm
index 99ce25adfb..1664c5ce8e 100644
--- a/platform/osx/crash_handler_osx.mm
+++ b/platform/osx/crash_handler_osx.mm
@@ -78,6 +78,10 @@ static void handle_crash(int sig) {
// Dump the backtrace to stderr with a message to the user
fprintf(stderr, "%s: Program crashed with signal %d\n", __FUNCTION__, sig);
+
+ if (OS::get_singleton()->get_main_loop())
+ OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_CRASH);
+
fprintf(stderr, "Dumping the backtrace. %ls\n", msg.c_str());
char **strings = backtrace_symbols(bt_buffer, size);
if (strings) {
diff --git a/platform/osx/detect.py b/platform/osx/detect.py
index 72b8aa99f8..1cc5c619fe 100644
--- a/platform/osx/detect.py
+++ b/platform/osx/detect.py
@@ -39,14 +39,21 @@ def configure(env):
## Build type
if (env["target"] == "release"):
- env.Prepend(CCFLAGS=['-O3', '-ffast-math', '-fomit-frame-pointer', '-ftree-vectorize', '-msse2'])
+ if (env["optimize"] == "speed"): #optimize for speed (default)
+ env.Prepend(CCFLAGS=['-O3', '-ffast-math', '-fomit-frame-pointer', '-ftree-vectorize', '-msse2'])
+ else: #optimize for size
+ env.Prepend(CCFLAGS=['-Os','-ftree-vectorize', '-msse2'])
+
if (env["debug_symbols"] == "yes"):
env.Prepend(CCFLAGS=['-g1'])
if (env["debug_symbols"] == "full"):
env.Prepend(CCFLAGS=['-g2'])
elif (env["target"] == "release_debug"):
- env.Prepend(CCFLAGS=['-O2', '-DDEBUG_ENABLED'])
+ if (env["optimize"] == "speed"): #optimize for speed (default)
+ env.Prepend(CCFLAGS=['-O2', '-DDEBUG_ENABLED'])
+ else: #optimize for size
+ env.Prepend(CCFLAGS=['-Os', '-DDEBUG_ENABLED'])
if (env["debug_symbols"] == "yes"):
env.Prepend(CCFLAGS=['-g1'])
if (env["debug_symbols"] == "full"):
diff --git a/platform/osx/logo.png b/platform/osx/logo.png
index 93c6890e85..62086fc415 100644
--- a/platform/osx/logo.png
+++ b/platform/osx/logo.png
Binary files differ
diff --git a/platform/osx/os_osx.h b/platform/osx/os_osx.h
index 7bd5b16f36..3d14a6d4fb 100644
--- a/platform/osx/os_osx.h
+++ b/platform/osx/os_osx.h
@@ -137,6 +137,9 @@ public:
void _update_window();
+ int video_driver_index;
+ virtual int get_current_video_driver() const;
+
protected:
virtual void initialize_core();
virtual Error initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver);
diff --git a/platform/osx/os_osx.mm b/platform/osx/os_osx.mm
index 4ece1e0325..282f5e2d1b 100644
--- a/platform/osx/os_osx.mm
+++ b/platform/osx/os_osx.mm
@@ -625,10 +625,18 @@ static void _mouseDownEvent(NSEvent *event, int index, int mask, bool pressed) {
- (void)otherMouseDown:(NSEvent *)event {
- if ((int)[event buttonNumber] != 2)
- return;
+ if ((int)[event buttonNumber] == 2) {
+ _mouseDownEvent(event, BUTTON_MIDDLE, BUTTON_MASK_MIDDLE, true);
+
+ } else if ((int)[event buttonNumber] == 3) {
+ _mouseDownEvent(event, BUTTON_XBUTTON1, BUTTON_MASK_XBUTTON1, true);
- _mouseDownEvent(event, BUTTON_MIDDLE, BUTTON_MASK_MIDDLE, true);
+ } else if ((int)[event buttonNumber] == 4) {
+ _mouseDownEvent(event, BUTTON_XBUTTON2, BUTTON_MASK_XBUTTON2, true);
+
+ } else {
+ return;
+ }
}
- (void)otherMouseDragged:(NSEvent *)event {
@@ -637,10 +645,18 @@ static void _mouseDownEvent(NSEvent *event, int index, int mask, bool pressed) {
- (void)otherMouseUp:(NSEvent *)event {
- if ((int)[event buttonNumber] != 2)
- return;
+ if ((int)[event buttonNumber] == 2) {
+ _mouseDownEvent(event, BUTTON_MIDDLE, BUTTON_MASK_MIDDLE, false);
+
+ } else if ((int)[event buttonNumber] == 3) {
+ _mouseDownEvent(event, BUTTON_XBUTTON1, BUTTON_MASK_XBUTTON1, false);
- _mouseDownEvent(event, BUTTON_MIDDLE, BUTTON_MASK_MIDDLE, false);
+ } else if ((int)[event buttonNumber] == 4) {
+ _mouseDownEvent(event, BUTTON_XBUTTON2, BUTTON_MASK_XBUTTON2, false);
+
+ } else {
+ return;
+ }
}
- (void)mouseExited:(NSEvent *)event {
@@ -1160,6 +1176,10 @@ static void displays_arrangement_changed(CGDirectDisplayID display_id, CGDisplay
displays_arrangement_dirty = true;
}
+int OS_OSX::get_current_video_driver() const {
+ return video_driver_index;
+}
+
Error OS_OSX::initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver) {
/*** OSX INITIALIZATION ***/
@@ -1256,6 +1276,8 @@ Error OS_OSX::initialize(const VideoMode &p_desired, int p_video_driver, int p_a
ADD_ATTR2(NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core);
}
+ video_driver_index = p_video_driver;
+
ADD_ATTR2(NSOpenGLPFAColorSize, colorBits);
/*
diff --git a/platform/server/logo.png b/platform/server/logo.png
index 5e98ac26ec..8666ada9ca 100644
--- a/platform/server/logo.png
+++ b/platform/server/logo.png
Binary files differ
diff --git a/platform/server/os_server.cpp b/platform/server/os_server.cpp
index 3b1be780d4..1c17780ad7 100644
--- a/platform/server/os_server.cpp
+++ b/platform/server/os_server.cpp
@@ -28,16 +28,17 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "os_server.h"
+
#include "drivers/dummy/audio_driver_dummy.h"
#include "drivers/dummy/rasterizer_dummy.h"
#include "drivers/dummy/texture_loader_dummy.h"
#include "print_string.h"
#include "servers/visual/visual_server_raster.h"
-#include <stdio.h>
-#include <stdlib.h>
#include "main/main.h"
+#include <stdio.h>
+#include <stdlib.h>
#include <unistd.h>
int OS_Server::get_video_driver_count() const {
@@ -58,6 +59,10 @@ const char *OS_Server::get_audio_driver_name(int p_driver) const {
return "Dummy";
}
+int OS_Server::get_current_video_driver() const {
+ return video_driver_index;
+}
+
void OS_Server::initialize_core() {
crash_handler.initialize();
@@ -73,6 +78,8 @@ Error OS_Server::initialize(const VideoMode &p_desired, int p_video_driver, int
RasterizerDummy::make_current();
+ video_driver_index = p_video_driver; // unused in server platform, but should still be initialized
+
visual_server = memnew(VisualServerRaster);
visual_server->init();
diff --git a/platform/server/os_server.h b/platform/server/os_server.h
index f1a880ecc2..07d70e5236 100644
--- a/platform/server/os_server.h
+++ b/platform/server/os_server.h
@@ -30,12 +30,12 @@
#ifndef OS_SERVER_H
#define OS_SERVER_H
-#include "../x11/crash_handler_x11.h"
-#include "../x11/power_x11.h"
#include "drivers/dummy/texture_loader_dummy.h"
#include "drivers/rtaudio/audio_driver_rtaudio.h"
#include "drivers/unix/os_unix.h"
#include "main/input_default.h"
+#include "platform/x11/crash_handler_x11.h"
+#include "platform/x11/power_x11.h"
#include "servers/audio_server.h"
#include "servers/visual/rasterizer.h"
#include "servers/visual_server.h"
@@ -47,7 +47,6 @@
class OS_Server : public OS_Unix {
- //Rasterizer *rasterizer;
VisualServer *visual_server;
VideoMode current_videomode;
List<String> args;
@@ -66,12 +65,14 @@ class OS_Server : public OS_Unix {
CrashHandler crash_handler;
+ int video_driver_index;
+
ResourceFormatDummyTexture *resource_loader_dummy;
protected:
virtual int get_video_driver_count() const;
virtual const char *get_video_driver_name(int p_driver) const;
-
+ virtual int get_current_video_driver() const;
virtual int get_audio_driver_count() const;
virtual const char *get_audio_driver_name(int p_driver) const;
diff --git a/platform/uwp/app.cpp b/platform/uwp/app.cpp
index c18aa36402..b769925849 100644
--- a/platform/uwp/app.cpp
+++ b/platform/uwp/app.cpp
@@ -143,14 +143,13 @@ void App::SetWindow(CoreWindow ^ p_window) {
window->KeyUp +=
ref new TypedEventHandler<CoreWindow ^, KeyEventArgs ^>(this, &App::OnKeyUp);
+ os->set_window(window);
+
unsigned int argc;
char **argv = get_command_line(&argc);
Main::setup("uwp", argc, argv, false);
- // The CoreWindow has been created, so EGL can be initialized.
- ContextEGL *context = memnew(ContextEGL(window));
- os->set_gl_context(context);
UpdateWindowSize(Size(window->Bounds.Width, window->Bounds.Height));
Main::setup2();
@@ -513,7 +512,7 @@ char **App::get_command_line(unsigned int *out_argc) {
if (f == NULL) {
- wprintf(L"Couldn't open command line file.");
+ wprintf(L"Couldn't open command line file.\n");
return fail_cl;
}
@@ -527,7 +526,7 @@ char **App::get_command_line(unsigned int *out_argc) {
if (r < 4) {
fclose(f);
- wprintf(L"Wrong cmdline length.");
+ wprintf(L"Wrong cmdline length.\n");
return (fail_cl);
}
@@ -539,7 +538,7 @@ char **App::get_command_line(unsigned int *out_argc) {
if (r < 4) {
fclose(f);
- wprintf(L"Wrong cmdline param length.");
+ wprintf(L"Wrong cmdline param length.\n");
return (fail_cl);
}
@@ -547,7 +546,7 @@ char **App::get_command_line(unsigned int *out_argc) {
if (strlen > CMD_MAX_LEN) {
fclose(f);
- wprintf(L"Wrong command length.");
+ wprintf(L"Wrong command length.\n");
return (fail_cl);
}
@@ -568,7 +567,7 @@ char **App::get_command_line(unsigned int *out_argc) {
delete[] arg;
fclose(f);
- wprintf(L"Error reading command.");
+ wprintf(L"Error reading command.\n");
return (fail_cl);
}
}
diff --git a/platform/uwp/gl_context_egl.cpp b/platform/uwp/gl_context_egl.cpp
index 88c9c8d687..6c60b27f5a 100644
--- a/platform/uwp/gl_context_egl.cpp
+++ b/platform/uwp/gl_context_egl.cpp
@@ -93,12 +93,26 @@ Error ContextEGL::initialize() {
EGLint numConfigs = 0;
EGLint majorVersion = 1;
- EGLint minorVersion = 0;
+ EGLint minorVersion;
+ if (driver == GLES_2_0) {
+ minorVersion = 0;
+ } else {
+ minorVersion = 5;
+ }
EGLDisplay display = EGL_NO_DISPLAY;
EGLContext context = EGL_NO_CONTEXT;
EGLSurface surface = EGL_NO_SURFACE;
EGLConfig config = nullptr;
- EGLint contextAttribs[] = { EGL_CONTEXT_CLIENT_VERSION, 3, EGL_NONE, EGL_NONE };
+ EGLint contextAttribs[3];
+ if (driver == GLES_2_0) {
+ contextAttribs[0] = EGL_CONTEXT_CLIENT_VERSION;
+ contextAttribs[1] = 2;
+ contextAttribs[2] = EGL_NONE;
+ } else {
+ contextAttribs[0] = EGL_CONTEXT_CLIENT_VERSION;
+ contextAttribs[1] = 3;
+ contextAttribs[2] = EGL_NONE;
+ }
try {
@@ -114,7 +128,8 @@ Error ContextEGL::initialize() {
// EGL_ANGLE_DISPLAY_ALLOW_RENDER_TO_BACK_BUFFER is an optimization that can have large performance benefits on mobile devices.
// Its syntax is subject to change, though. Please update your Visual Studio templates if you experience compilation issues with it.
- //EGL_ANGLE_DISPLAY_ALLOW_RENDER_TO_BACK_BUFFER, EGL_TRUE,
+ EGL_ANGLE_DISPLAY_ALLOW_RENDER_TO_BACK_BUFFER,
+ EGL_TRUE,
// EGL_PLATFORM_ANGLE_ENABLE_AUTOMATIC_TRIM_ANGLE is an option that enables ANGLE to automatically call
// the IDXGIDevice3::Trim method on behalf of the application when it gets suspended.
@@ -193,13 +208,12 @@ void ContextEGL::cleanup() {
}
};
-ContextEGL::ContextEGL(CoreWindow ^ p_window) :
+ContextEGL::ContextEGL(CoreWindow ^ p_window, Driver p_driver) :
mEglDisplay(EGL_NO_DISPLAY),
mEglContext(EGL_NO_CONTEXT),
- mEglSurface(EGL_NO_SURFACE) {
-
- window = p_window;
-};
+ mEglSurface(EGL_NO_SURFACE),
+ driver(p_driver),
+ window(p_window) {}
ContextEGL::~ContextEGL() {
diff --git a/platform/uwp/gl_context_egl.h b/platform/uwp/gl_context_egl.h
index 527baf1054..df0108c124 100644
--- a/platform/uwp/gl_context_egl.h
+++ b/platform/uwp/gl_context_egl.h
@@ -42,6 +42,13 @@ using namespace Windows::UI::Core;
class ContextEGL : public ContextGL {
+public:
+ enum Driver {
+ GLES_2_0,
+ GLES_3_0,
+ };
+
+private:
CoreWindow ^ window;
EGLDisplay mEglDisplay;
@@ -53,6 +60,8 @@ class ContextEGL : public ContextGL {
bool vsync;
+ Driver driver;
+
public:
virtual void release_current();
@@ -70,7 +79,7 @@ public:
void cleanup();
- ContextEGL(CoreWindow ^ p_window);
+ ContextEGL(CoreWindow ^ p_window, Driver p_driver);
~ContextEGL();
};
diff --git a/platform/uwp/os_uwp.cpp b/platform/uwp/os_uwp.cpp
index d00da3dbcd..8549a44ce5 100644
--- a/platform/uwp/os_uwp.cpp
+++ b/platform/uwp/os_uwp.cpp
@@ -30,6 +30,7 @@
#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"
@@ -66,12 +67,7 @@ using namespace Windows::ApplicationModel::DataTransfer;
using namespace concurrency;
int OSUWP::get_video_driver_count() const {
-
- return 1;
-}
-const char *OSUWP::get_video_driver_name(int p_driver) const {
-
- return "GLES3";
+ return 2;
}
Size2 OSUWP::get_window_size() const {
@@ -81,6 +77,10 @@ Size2 OSUWP::get_window_size() const {
return size;
}
+int OSUWP::get_current_video_driver() const {
+ return video_driver_index;
+}
+
void OSUWP::set_window_size(const Size2 p_size) {
Windows::Foundation::Size new_size;
@@ -133,18 +133,6 @@ void OSUWP::set_keep_screen_on(bool p_enabled) {
OS::set_keep_screen_on(p_enabled);
}
-int OSUWP::get_audio_driver_count() const {
-
- return AudioDriverManager::get_driver_count();
-}
-
-const char *OSUWP::get_audio_driver_name(int p_driver) const {
-
- AudioDriver *driver = AudioDriverManager::get_driver(p_driver);
- ERR_FAIL_COND_V(!driver, "");
- return AudioDriverManager::get_driver(p_driver)->get_name();
-}
-
void OSUWP::initialize_core() {
last_button_state = 0;
@@ -185,10 +173,9 @@ bool OSUWP::can_draw() const {
return !minimized;
};
-void OSUWP::set_gl_context(ContextEGL *p_context) {
-
- gl_context = p_context;
-};
+void OSUWP::set_window(Windows::UI::Core::CoreWindow ^ p_window) {
+ window = p_window;
+}
void OSUWP::screen_size_changed() {
@@ -200,6 +187,11 @@ Error OSUWP::initialize(const VideoMode &p_desired, int p_video_driver, int p_au
main_loop = NULL;
outside = true;
+ if (p_video_driver == VIDEO_DRIVER_GLES2) {
+ gl_context = memnew(ContextEGL(window, ContextEGL::GLES_2_0));
+ } else {
+ gl_context = memnew(ContextEGL(window, ContextEGL::GLES_3_0));
+ }
gl_context->initialize();
VideoMode vm;
vm.width = gl_context->get_window_width();
@@ -240,10 +232,17 @@ Error OSUWP::initialize(const VideoMode &p_desired, int p_video_driver, int p_au
gl_context->make_current();
- RasterizerGLES3::register_config();
- RasterizerGLES3::make_current();
+ if (p_video_driver == VIDEO_DRIVER_GLES2) {
+ RasterizerGLES2::register_config();
+ RasterizerGLES2::make_current();
+ } else {
+ RasterizerGLES3::register_config();
+ RasterizerGLES3::make_current();
+ }
gl_context->set_use_vsync(vm.use_vsync);
+ video_driver_index = p_video_driver;
+
visual_server = memnew(VisualServerRaster);
// FIXME: Reimplement threaded rendering? Or remove?
/*
@@ -297,7 +296,7 @@ Error OSUWP::initialize(const VideoMode &p_desired, int p_video_driver, int p_au
if (is_keep_screen_on())
display_request->RequestActive();
- set_keep_screen_on(GLOBAL_DEF("display/window/keep_screen_on", true));
+ set_keep_screen_on(GLOBAL_DEF("display/window/energy_saving/keep_screen_on", true));
return OK;
}
@@ -392,7 +391,6 @@ void OSUWP::ManagedType::update_clipboard() {
if (data->Contains(StandardDataFormats::Text)) {
create_task(data->GetTextAsync()).then([this](Platform::String ^ clipboard_content) {
-
this->clipboard = clipboard_content;
});
}
diff --git a/platform/uwp/os_uwp.h b/platform/uwp/os_uwp.h
index 95afdab469..3b48063fe9 100644
--- a/platform/uwp/os_uwp.h
+++ b/platform/uwp/os_uwp.h
@@ -96,8 +96,10 @@ private:
int pressrc;
ContextEGL *gl_context;
+ Windows::UI::Core::CoreWindow ^ window;
VideoMode video_mode;
+ int video_driver_index;
MainLoop *main_loop;
@@ -153,10 +155,7 @@ private:
// functions used by main to initialize/deintialize the OS
protected:
virtual int get_video_driver_count() const;
- virtual const char *get_video_driver_name(int p_driver) const;
-
- virtual int get_audio_driver_count() const;
- virtual const char *get_audio_driver_name(int p_driver) const;
+ virtual int get_current_video_driver() const;
virtual void initialize_core();
virtual Error initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver);
@@ -231,7 +230,7 @@ public:
virtual bool _check_internal_feature_support(const String &p_feature);
- void set_gl_context(ContextEGL *p_context);
+ void set_window(Windows::UI::Core::CoreWindow ^ p_window);
void screen_size_changed();
virtual void release_rendering_thread();
diff --git a/platform/windows/crash_handler_win.cpp b/platform/windows/crash_handler_win.cpp
index 804c2d44eb..76a227c608 100644
--- a/platform/windows/crash_handler_win.cpp
+++ b/platform/windows/crash_handler_win.cpp
@@ -124,6 +124,9 @@ DWORD CrashHandlerException(EXCEPTION_POINTERS *ep) {
fprintf(stderr, "%s: Program crashed\n", __FUNCTION__);
+ if (OS::get_singleton()->get_main_loop())
+ OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_CRASH);
+
// Load the symbols:
if (!SymInitialize(process, NULL, false))
return EXCEPTION_CONTINUE_SEARCH;
diff --git a/platform/windows/detect.py b/platform/windows/detect.py
index 05806d2fe8..cacb573236 100644
--- a/platform/windows/detect.py
+++ b/platform/windows/detect.py
@@ -166,12 +166,18 @@ def configure_msvc(env, manual_msvc_config):
# Build type
if (env["target"] == "release"):
- env.Append(CCFLAGS=['/O2'])
+ if (env["optimize"] == "speed"): #optimize for speed (default)
+ env.Append(CCFLAGS=['/O2'])
+ else: # optimize for size
+ env.Append(CCFLAGS=['/O1'])
env.Append(LINKFLAGS=['/SUBSYSTEM:WINDOWS'])
env.Append(LINKFLAGS=['/ENTRY:mainCRTStartup'])
elif (env["target"] == "release_debug"):
- env.Append(CCFLAGS=['/O2'])
+ if (env["optimize"] == "speed"): #optimize for speed (default)
+ env.Append(CCFLAGS=['/O2'])
+ else: # optimize for size
+ env.Append(CCFLAGS=['/O1'])
env.AppendUnique(CPPDEFINES = ['DEBUG_ENABLED'])
env.Append(LINKFLAGS=['/SUBSYSTEM:CONSOLE'])
@@ -247,10 +253,14 @@ def configure_mingw(env):
if (env["target"] == "release"):
env.Append(CCFLAGS=['-msse2'])
- if (env["bits"] == "64"):
- env.Append(CCFLAGS=['-O3'])
- else:
- env.Append(CCFLAGS=['-O2'])
+ if (env["optimize"] == "speed"): #optimize for speed (default)
+ if (env["bits"] == "64"):
+ env.Append(CCFLAGS=['-O3'])
+ else:
+ env.Append(CCFLAGS=['-O2'])
+ else: #optimize for size
+ env.Prepend(CCFLAGS=['-Os'])
+
env.Append(LINKFLAGS=['-Wl,--subsystem,windows'])
@@ -265,7 +275,11 @@ def configure_mingw(env):
env.Prepend(CCFLAGS=['-g1'])
if (env["debug_symbols"] == "full"):
env.Prepend(CCFLAGS=['-g2'])
-
+ if (env["optimize"] == "speed"): #optimize for speed (default)
+ env.Append(CCFLAGS=['-O2'])
+ else: #optimize for size
+ env.Prepend(CCFLAGS=['-Os'])
+
elif (env["target"] == "debug"):
env.Append(CCFLAGS=['-g3', '-DDEBUG_ENABLED', '-DDEBUG_MEMORY_ENABLED'])
diff --git a/platform/windows/godot_win.cpp b/platform/windows/godot_win.cpp
index 80f53dd1a1..504a9a0380 100644
--- a/platform/windows/godot_win.cpp
+++ b/platform/windows/godot_win.cpp
@@ -176,8 +176,8 @@ int _main() {
}
int main(int _argc, char **_argv) {
-// _argc and _argv are ignored
-// we are going to use the WideChar version of them instead
+ // _argc and _argv are ignored
+ // we are going to use the WideChar version of them instead
#ifdef CRASH_HANDLER_EXCEPTION
__try {
diff --git a/platform/windows/logo.png b/platform/windows/logo.png
index 4376abd563..f06b463850 100644
--- a/platform/windows/logo.png
+++ b/platform/windows/logo.png
Binary files differ
diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp
index ca6c793d5d..ac37e1246d 100644
--- a/platform/windows/os_windows.cpp
+++ b/platform/windows/os_windows.cpp
@@ -70,6 +70,30 @@ __attribute__((visibility("default"))) DWORD NvOptimusEnablement = 0x00000001;
#define WM_TOUCH 576
#endif
+typedef struct {
+ int count;
+ int screen;
+ Size2 size;
+} EnumSizeData;
+
+typedef struct {
+ int count;
+ int screen;
+ Point2 pos;
+} EnumPosData;
+
+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;
+}
+
static String format_error_message(DWORD id) {
LPWSTR messageBuffer = NULL;
@@ -410,11 +434,12 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
bmask |= (wParam & MK_LBUTTON) ? (1 << 0) : 0;
bmask |= (wParam & MK_RBUTTON) ? (1 << 1) : 0;
bmask |= (wParam & MK_MBUTTON) ? (1 << 2) : 0;
+ bmask |= (wParam & MK_XBUTTON1) ? (1 << 7) : 0;
+ bmask |= (wParam & MK_XBUTTON2) ? (1 << 8) : 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)));
mm->set_global_position(Vector2(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)));
@@ -455,6 +480,13 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
} break;
case WM_LBUTTONDOWN:
case WM_LBUTTONUP:
+ if (input->is_emulating_mouse_from_touch()) {
+ // Universal translation enabled; ignore OS translations for left button
+ LPARAM extra = GetMessageExtraInfo();
+ if (IsPenEvent(extra)) {
+ break;
+ }
+ }
case WM_MBUTTONDOWN:
case WM_MBUTTONUP:
case WM_RBUTTONDOWN:
@@ -464,161 +496,168 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
case WM_LBUTTONDBLCLK:
case WM_MBUTTONDBLCLK:
case WM_RBUTTONDBLCLK:
- /*case WM_XBUTTONDOWN:
- case WM_XBUTTONUP: */ {
-
- if (input->is_emulating_mouse_from_touch()) {
- // Universal translation enabled; ignore OS translation
- LPARAM extra = GetMessageExtraInfo();
- if (IsPenEvent(extra)) {
- break;
- }
- }
+ case WM_XBUTTONDBLCLK:
+ case WM_XBUTTONDOWN:
+ case WM_XBUTTONUP: {
- Ref<InputEventMouseButton> mb;
- mb.instance();
-
- switch (uMsg) {
- case WM_LBUTTONDOWN: {
- mb->set_pressed(true);
- mb->set_button_index(1);
- } break;
- case WM_LBUTTONUP: {
- mb->set_pressed(false);
- mb->set_button_index(1);
- } break;
- case WM_MBUTTONDOWN: {
- mb->set_pressed(true);
- mb->set_button_index(3);
-
- } break;
- case WM_MBUTTONUP: {
- mb->set_pressed(false);
- mb->set_button_index(3);
- } break;
- case WM_RBUTTONDOWN: {
- mb->set_pressed(true);
- mb->set_button_index(2);
- } break;
- case WM_RBUTTONUP: {
- mb->set_pressed(false);
- mb->set_button_index(2);
- } break;
- case WM_LBUTTONDBLCLK: {
-
- mb->set_pressed(true);
- mb->set_button_index(1);
- mb->set_doubleclick(true);
- } break;
- case WM_RBUTTONDBLCLK: {
-
- mb->set_pressed(true);
- mb->set_button_index(2);
- mb->set_doubleclick(true);
- } break;
- case WM_MBUTTONDBLCLK: {
-
- mb->set_pressed(true);
- mb->set_button_index(3);
- mb->set_doubleclick(true);
- } break;
- case WM_MOUSEWHEEL: {
-
- mb->set_pressed(true);
- int motion = (short)HIWORD(wParam);
- if (!motion)
- return 0;
-
- if (motion > 0)
- mb->set_button_index(BUTTON_WHEEL_UP);
- else
- mb->set_button_index(BUTTON_WHEEL_DOWN);
-
- } break;
- case WM_MOUSEHWHEEL: {
-
- mb->set_pressed(true);
- int motion = (short)HIWORD(wParam);
- if (!motion)
- return 0;
-
- 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->is_pressed()=true;
- mb->get_button_index()=(HIWORD(wParam)==XBUTTON1)?6:7;
+ Ref<InputEventMouseButton> mb;
+ mb.instance();
+
+ switch (uMsg) {
+ case WM_LBUTTONDOWN: {
+ mb->set_pressed(true);
+ mb->set_button_index(1);
} break;
- case WM_XBUTTONUP:
- mb->is_pressed()=true;
- mb->get_button_index()=(HIWORD(wParam)==XBUTTON1)?6:7;
- } break;*/
- default: { return 0; }
- }
+ case WM_LBUTTONUP: {
+ mb->set_pressed(false);
+ mb->set_button_index(1);
+ } break;
+ case WM_MBUTTONDOWN: {
+ mb->set_pressed(true);
+ mb->set_button_index(3);
- 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->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->set_position(Vector2(old_x, old_y));
- }
+ } break;
+ case WM_MBUTTONUP: {
+ mb->set_pressed(false);
+ mb->set_button_index(3);
+ } break;
+ case WM_RBUTTONDOWN: {
+ mb->set_pressed(true);
+ mb->set_button_index(2);
+ } break;
+ case WM_RBUTTONUP: {
+ mb->set_pressed(false);
+ mb->set_button_index(2);
+ } break;
+ case WM_LBUTTONDBLCLK: {
- if (uMsg != WM_MOUSEWHEEL && uMsg != WM_MOUSEHWHEEL) {
- if (mb->is_pressed()) {
+ mb->set_pressed(true);
+ mb->set_button_index(1);
+ mb->set_doubleclick(true);
+ } break;
+ case WM_RBUTTONDBLCLK: {
- if (++pressrc > 0)
- SetCapture(hWnd);
- } else {
+ mb->set_pressed(true);
+ mb->set_button_index(2);
+ mb->set_doubleclick(true);
+ } break;
+ case WM_MBUTTONDBLCLK: {
+
+ mb->set_pressed(true);
+ mb->set_button_index(3);
+ mb->set_doubleclick(true);
+ } break;
+ case WM_MOUSEWHEEL: {
- if (--pressrc <= 0) {
- ReleaseCapture();
- pressrc = 0;
- }
+ mb->set_pressed(true);
+ int motion = (short)HIWORD(wParam);
+ if (!motion)
+ return 0;
+
+ if (motion > 0)
+ mb->set_button_index(BUTTON_WHEEL_UP);
+ else
+ mb->set_button_index(BUTTON_WHEEL_DOWN);
+
+ } break;
+ case WM_MOUSEHWHEEL: {
+
+ mb->set_pressed(true);
+ int motion = (short)HIWORD(wParam);
+ if (!motion)
+ return 0;
+
+ 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));
}
- } else if (mouse_mode != MOUSE_MODE_CAPTURED) {
- // for reasons unknown to mankind, wheel comes in screen cordinates
- POINT coords;
- coords.x = mb->get_position().x;
- coords.y = mb->get_position().y;
+ } break;
+ case WM_XBUTTONDOWN: {
- ScreenToClient(hWnd, &coords);
+ mb->set_pressed(true);
+ if (HIWORD(wParam) == XBUTTON1)
+ mb->set_button_index(BUTTON_XBUTTON1);
+ else
+ mb->set_button_index(BUTTON_XBUTTON2);
+ } break;
+ case WM_XBUTTONUP: {
- mb->set_position(Vector2(coords.x, coords.y));
- }
+ mb->set_pressed(false);
+ if (HIWORD(wParam) == XBUTTON1)
+ mb->set_button_index(BUTTON_XBUTTON1);
+ else
+ mb->set_button_index(BUTTON_XBUTTON2);
+ } break;
+ case WM_XBUTTONDBLCLK: {
- mb->set_global_position(mb->get_position());
+ mb->set_pressed(true);
+ if (HIWORD(wParam) == XBUTTON1)
+ mb->set_button_index(BUTTON_XBUTTON1);
+ else
+ mb->set_button_index(BUTTON_XBUTTON2);
+ mb->set_doubleclick(true);
+ } break;
+ default: { return 0; }
+ }
+
+ 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;
+ bmask |= (wParam & MK_XBUTTON1) ? (1 << 7) : 0;
+ bmask |= (wParam & MK_XBUTTON2) ? (1 << 8) : 0;
+ mb->set_button_mask(bmask);
+
+ last_button_state = mb->get_button_mask();
+ mb->set_position(Vector2(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam)));
+
+ if (mouse_mode == MOUSE_MODE_CAPTURED) {
+
+ mb->set_position(Vector2(old_x, old_y));
+ }
+
+ if (uMsg != WM_MOUSEWHEEL && uMsg != WM_MOUSEHWHEEL) {
+ if (mb->is_pressed()) {
+
+ if (++pressrc > 0)
+ SetCapture(hWnd);
+ } else {
- if (main_loop) {
- input->parse_input_event(mb);
- if (mb->is_pressed() && mb->get_button_index() > 3) {
- //send release for mouse wheel
- Ref<InputEventMouseButton> mbd = mb->duplicate();
- mbd->set_pressed(false);
- input->parse_input_event(mbd);
+ if (--pressrc <= 0) {
+ ReleaseCapture();
+ pressrc = 0;
}
}
+ } else if (mouse_mode != MOUSE_MODE_CAPTURED) {
+ // for reasons unknown to mankind, wheel comes in screen cordinates
+ POINT coords;
+ coords.x = mb->get_position().x;
+ coords.y = mb->get_position().y;
+
+ ScreenToClient(hWnd, &coords);
+
+ mb->set_position(Vector2(coords.x, coords.y));
}
- break;
+
+ mb->set_global_position(mb->get_position());
+
+ if (main_loop) {
+ input->parse_input_event(mb);
+ if (mb->is_pressed() && mb->get_button_index() > 3 && mb->get_button_index() < 8) {
+ //send release for mouse wheel
+ Ref<InputEventMouseButton> mbd = mb->duplicate();
+ mbd->set_pressed(false);
+ input->parse_input_event(mbd);
+ }
+ }
+ } break;
case WM_SIZE: {
int window_w = LOWORD(lParam);
@@ -742,13 +781,18 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
if (GetTouchInputInfo((HTOUCHINPUT)lParam, cInputs, pInputs, sizeof(TOUCHINPUT))) {
for (UINT i = 0; i < cInputs; i++) {
TOUCHINPUT ti = pInputs[i];
+ POINT touch_pos = {
+ TOUCH_COORD_TO_PIXEL(ti.x),
+ TOUCH_COORD_TO_PIXEL(ti.y),
+ };
+ ScreenToClient(hWnd, &touch_pos);
//do something with each touch input entry
if (ti.dwFlags & TOUCHEVENTF_MOVE) {
- _drag_event(ti.x / 100.0f, ti.y / 100.0f, ti.dwID);
+ _drag_event(touch_pos.x, touch_pos.y, ti.dwID);
} else if (ti.dwFlags & (TOUCHEVENTF_UP | TOUCHEVENTF_DOWN)) {
- _touch_event(ti.dwFlags & TOUCHEVENTF_DOWN, ti.x / 100.0f, ti.y / 100.0f, ti.dwID);
+ _touch_event(ti.dwFlags & TOUCHEVENTF_DOWN, touch_pos.x, touch_pos.y, ti.dwID);
};
}
bHandled = TRUE;
@@ -968,6 +1012,10 @@ typedef enum _SHC_PROCESS_DPI_AWARENESS {
SHC_PROCESS_PER_MONITOR_DPI_AWARE = 2
} SHC_PROCESS_DPI_AWARENESS;
+int OS_Windows::get_current_video_driver() const {
+ return video_driver_index;
+}
+
Error OS_Windows::initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver) {
main_loop = NULL;
@@ -976,6 +1024,7 @@ Error OS_Windows::initialize(const VideoMode &p_desired, int p_video_driver, int
WNDCLASSEXW wc;
if (is_hidpi_allowed()) {
+ print_line("hidpi aware?");
HMODULE Shcore = LoadLibraryW(L"Shcore.dll");
if (Shcore != NULL) {
@@ -1020,6 +1069,7 @@ Error OS_Windows::initialize(const VideoMode &p_desired, int p_video_driver, int
pre_fs_valid = true;
if (video_mode.fullscreen) {
+ /* this returns DPI unaware size, commenting
DEVMODE current;
memset(&current, 0, sizeof(current));
EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &current);
@@ -1027,6 +1077,16 @@ Error OS_Windows::initialize(const VideoMode &p_desired, int p_video_driver, int
WindowRect.right = current.dmPelsWidth;
WindowRect.bottom = current.dmPelsHeight;
+ */
+
+ EnumSizeData data = { 0, 0, Size2() };
+ EnumDisplayMonitors(NULL, NULL, _MonitorEnumProcSize, (LPARAM)&data);
+
+ WindowRect.right = data.size.width;
+ WindowRect.bottom = data.size.height;
+
+ print_line("wr right " + itos(WindowRect.right) + ", " + itos(WindowRect.bottom));
+
/* DEVMODE dmScreenSettings;
memset(&dmScreenSettings,0,sizeof(dmScreenSettings));
dmScreenSettings.dmSize=sizeof(dmScreenSettings);
@@ -1125,6 +1185,8 @@ Error OS_Windows::initialize(const VideoMode &p_desired, int p_video_driver, int
RasterizerGLES3::make_current();
}
+ video_driver_index = p_video_driver; // FIXME TODO - FIX IF DRIVER DETECTION HAPPENS AND GLES2 MUST BE USED
+
gl_context->set_use_vsync(video_mode.use_vsync);
#endif
@@ -1451,12 +1513,6 @@ void OS_Windows::set_current_screen(int p_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;
@@ -1476,24 +1532,6 @@ Point2 OS_Windows::get_screen_position(int p_screen) const {
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 {
EnumSizeData data = { 0, p_screen == -1 ? get_current_screen() : p_screen, Size2() };
@@ -1553,16 +1591,16 @@ Size2 OS_Windows::get_real_window_size() const {
}
void OS_Windows::set_window_size(const Size2 p_size) {
- video_mode.width = p_size.width;
- video_mode.height = p_size.height;
+ int w = p_size.width;
+ int h = p_size.height;
+
+ video_mode.width = w;
+ video_mode.height = h;
if (video_mode.fullscreen) {
return;
}
- int w = p_size.width;
- int h = p_size.height;
-
RECT rect;
GetWindowRect(hWnd, &rect);
diff --git a/platform/windows/os_windows.h b/platform/windows/os_windows.h
index 19af63bae0..b99d3e3422 100644
--- a/platform/windows/os_windows.h
+++ b/platform/windows/os_windows.h
@@ -134,6 +134,7 @@ class OS_Windows : public OS {
PowerWindows *power_manager;
+ int video_driver_index;
#ifdef WASAPI_ENABLED
AudioDriverWASAPI driver_wasapi;
#endif
@@ -153,6 +154,8 @@ class OS_Windows : public OS {
// functions used by main to initialize/deintialize the OS
protected:
+ virtual int get_current_video_driver() const;
+
virtual void initialize_core();
virtual Error initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver);
diff --git a/platform/x11/crash_handler_x11.cpp b/platform/x11/crash_handler_x11.cpp
index d39fc33f81..960105271b 100644
--- a/platform/x11/crash_handler_x11.cpp
+++ b/platform/x11/crash_handler_x11.cpp
@@ -55,6 +55,10 @@ static void handle_crash(int sig) {
// Dump the backtrace to stderr with a message to the user
fprintf(stderr, "%s: Program crashed with signal %d\n", __FUNCTION__, sig);
+
+ if (OS::get_singleton()->get_main_loop())
+ OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_CRASH);
+
fprintf(stderr, "Dumping the backtrace. %ls\n", msg.c_str());
char **strings = backtrace_symbols(bt_buffer, size);
if (strings) {
diff --git a/platform/x11/detect.py b/platform/x11/detect.py
index 09e16ad078..feaa2e598f 100644
--- a/platform/x11/detect.py
+++ b/platform/x11/detect.py
@@ -62,6 +62,7 @@ def get_opts():
EnumVariable('debug_symbols', 'Add debugging symbols to release builds', 'yes', ('yes', 'no', 'full')),
BoolVariable('separate_debug_symbols', 'Create a separate file containing debugging symbols', False),
BoolVariable('touch', 'Enable touch events', True),
+ BoolVariable('execinfo', 'Use libexecinfo on systems where glibc is not available', False),
]
@@ -81,14 +82,22 @@ def configure(env):
if (env["target"] == "release"):
# -O3 -ffast-math is identical to -Ofast. We need to split it out so we can selectively disable
# -ffast-math in code for which it generates wrong results.
- env.Prepend(CCFLAGS=['-O3', '-ffast-math'])
+ if (env["optimize"] == "speed"): #optimize for speed (default)
+ env.Prepend(CCFLAGS=['-O3', '-ffast-math'])
+ else: #optimize for size
+ env.Prepend(CCFLAGS=['-Os'])
+
if (env["debug_symbols"] == "yes"):
env.Prepend(CCFLAGS=['-g1'])
if (env["debug_symbols"] == "full"):
env.Prepend(CCFLAGS=['-g2'])
elif (env["target"] == "release_debug"):
- env.Prepend(CCFLAGS=['-O2', '-ffast-math', '-DDEBUG_ENABLED'])
+ if (env["optimize"] == "speed"): #optimize for speed (default)
+ env.Prepend(CCFLAGS=['-O2', '-ffast-math', '-DDEBUG_ENABLED'])
+ else: #optimize for size
+ env.Prepend(CCFLAGS=['-Os', '-DDEBUG_ENABLED'])
+
if (env["debug_symbols"] == "yes"):
env.Prepend(CCFLAGS=['-g1'])
if (env["debug_symbols"] == "full"):
@@ -276,6 +285,9 @@ def configure(env):
env.Append(LIBS=['dl'])
if (platform.system().find("BSD") >= 0):
+ env["execinfo"] = True
+
+ if env["execinfo"]:
env.Append(LIBS=['execinfo'])
## Cross-compilation
diff --git a/platform/x11/logo.png b/platform/x11/logo.png
index 1cc93b46ac..078654b757 100644
--- a/platform/x11/logo.png
+++ b/platform/x11/logo.png
Binary files differ
diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp
index 2bc85f76c9..af0e02173f 100644
--- a/platform/x11/os_x11.cpp
+++ b/platform/x11/os_x11.cpp
@@ -84,6 +84,10 @@ void OS_X11::initialize_core() {
OS_Unix::initialize_core();
}
+int OS_X11::get_current_video_driver() const {
+ return video_driver_index;
+}
+
Error OS_X11::initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver) {
long im_event_mask = 0;
@@ -285,6 +289,8 @@ Error OS_X11::initialize(const VideoMode &p_desired, int p_video_driver, int p_a
} break;
}
+ video_driver_index = p_video_driver; // FIXME TODO - FIX IF DRIVER DETECTION HAPPENS AND GLES2 MUST BE USED
+
context_gl->set_use_vsync(current_videomode.use_vsync);
#endif
diff --git a/platform/x11/os_x11.h b/platform/x11/os_x11.h
index 8cab23fe63..b67bc824be 100644
--- a/platform/x11/os_x11.h
+++ b/platform/x11/os_x11.h
@@ -180,6 +180,7 @@ class OS_X11 : public OS_Unix {
CrashHandler crash_handler;
+ int video_driver_index;
int audio_driver_index;
unsigned int capture_idle;
bool maximized;
@@ -195,6 +196,8 @@ class OS_X11 : public OS_Unix {
Bool xrandr_ext_ok;
protected:
+ virtual int get_current_video_driver() const;
+
virtual void initialize_core();
virtual Error initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver);
virtual void finalize();