diff options
Diffstat (limited to 'platform')
233 files changed, 5547 insertions, 10684 deletions
diff --git a/platform/android/AndroidManifest.xml.template b/platform/android/AndroidManifest.xml.template index 2a24c7cdc2..be5afb406a 100644 --- a/platform/android/AndroidManifest.xml.template +++ b/platform/android/AndroidManifest.xml.template @@ -31,7 +31,7 @@ $$ADD_APPLICATION_CHUNKS$$ </application> - <uses-feature android:glEsVersion="0x00020000"/> + <uses-feature android:glEsVersion="0x00030000"/> $$ADD_PERMISSION_CHUNKS$$ <uses-permission android:name="godot.ACCESS_CHECKIN_PROPERTIES"/> diff --git a/platform/android/SCsub b/platform/android/SCsub index 86f8c40f83..7fb3c876be 100644 --- a/platform/android/SCsub +++ b/platform/android/SCsub @@ -19,8 +19,8 @@ android_files = [ 'android_native_app_glue.c', 'java_glue.cpp', 'cpu-features.c', - 'java_class_wrapper.cpp' - 'power_android.cpp' + 'java_class_wrapper.cpp', +# 'power_android.cpp' ] # env.Depends('#core/math/vector3.h', 'vector3_psp.h') @@ -49,22 +49,30 @@ gradle_text = gradle_basein.read() gradle_maven_repos_text = "" if len(env.android_maven_repos) > 0: - gradle_maven_repos_text += "maven {\n" + gradle_maven_repos_text += "" for x in env.android_maven_repos: - gradle_maven_repos_text += "\t\t" + x + "\n" - gradle_maven_repos_text += "\t}\n" + gradle_maven_repos_text += "\tmaven {\n" + gradle_maven_repos_text += "\t" + x + "\n" + gradle_maven_repos_text += "\t}\n" gradle_maven_dependencies_text = "" for x in env.android_dependencies: - gradle_maven_dependencies_text += x + "\n" + gradle_maven_dependencies_text += x + "\n\t" gradle_java_dirs_text = "" for x in env.android_java_dirs: gradle_java_dirs_text += ",'" + x.replace("\\", "/") + "'" +gradle_plugins = "" +for x in env.android_gradle_plugins: + gradle_plugins += "apply plugin: \"" + x + "\"\n" +gradle_classpath = "" +for x in env.android_gradle_classpath: + gradle_classpath += "\t\tclasspath \"" + x + "\"\n" + gradle_res_dirs_text = "" for x in env.android_res_dirs: @@ -84,9 +92,23 @@ gradle_asset_dirs_text = "" gradle_default_config_text = "" +minSdk = 14 +targetSdk = 23 + for x in env.android_default_config: + if x.startswith("minSdkVersion") and int(x.split(" ")[-1]) < minSdk: + x = "minSdkVersion " + str(minSdk) + if x.startswith("targetSdkVersion") and int(x.split(" ")[-1]) > targetSdk: + x = "targetSdkVersion " + str(targetSdk) + gradle_default_config_text += x + "\n\t\t" +if "minSdkVersion" not in gradle_default_config_text: + gradle_default_config_text += ("minSdkVersion " + str(minSdk) + "\n\t\t") + +if "targetSdkVersion" not in gradle_default_config_text: + gradle_default_config_text += ("targetSdkVersion " + str(targetSdk) + "\n\t\t") + gradle_text = gradle_text.replace("$$GRADLE_REPOSITORY_URLS$$", gradle_maven_repos_text) gradle_text = gradle_text.replace("$$GRADLE_DEPENDENCIES$$", gradle_maven_dependencies_text) gradle_text = gradle_text.replace("$$GRADLE_JAVA_DIRS$$", gradle_java_dirs_text) @@ -95,7 +117,8 @@ gradle_text = gradle_text.replace("$$GRADLE_ASSET_DIRS$$", gradle_asset_dirs_tex gradle_text = gradle_text.replace("$$GRADLE_AIDL_DIRS$$", gradle_aidl_dirs_text) gradle_text = gradle_text.replace("$$GRADLE_JNI_DIRS$$", gradle_jni_dirs_text) gradle_text = gradle_text.replace("$$GRADLE_DEFAULT_CONFIG$$", gradle_default_config_text) - +gradle_text = gradle_text.replace("$$GRADLE_PLUGINS$$", gradle_plugins) +gradle_text = gradle_text.replace("$$GRADLE_CLASSPATH$$", gradle_classpath) gradle_baseout.write(gradle_text) gradle_baseout.close() diff --git a/platform/android/audio_driver_jandroid.cpp b/platform/android/audio_driver_jandroid.cpp index 5e30289310..7b2127a211 100644 --- a/platform/android/audio_driver_jandroid.cpp +++ b/platform/android/audio_driver_jandroid.cpp @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/android/audio_driver_jandroid.h b/platform/android/audio_driver_jandroid.h index 4b5131cdc0..e2bb5ede86 100644 --- a/platform/android/audio_driver_jandroid.h +++ b/platform/android/audio_driver_jandroid.h @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/android/audio_driver_opensl.cpp b/platform/android/audio_driver_opensl.cpp index bba98dd623..acd94d2bdd 100644 --- a/platform/android/audio_driver_opensl.cpp +++ b/platform/android/audio_driver_opensl.cpp @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/android/audio_driver_opensl.h b/platform/android/audio_driver_opensl.h index 306589aa23..f6270a3084 100644 --- a/platform/android/audio_driver_opensl.h +++ b/platform/android/audio_driver_opensl.h @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/android/build.gradle.template b/platform/android/build.gradle.template index c46a15bd12..fd0907f820 100644 --- a/platform/android/build.gradle.template +++ b/platform/android/build.gradle.template @@ -3,7 +3,8 @@ buildscript { jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:2.1.0' + classpath 'com.android.tools.build:gradle:2.3.1' + $$GRADLE_CLASSPATH$$ } } @@ -11,6 +12,7 @@ apply plugin: 'com.android.application' allprojects { repositories { + jcenter() mavenCentral() $$GRADLE_REPOSITORY_URLS$$ } @@ -29,7 +31,7 @@ android { } compileSdkVersion 23 - buildToolsVersion "23.0.3" + buildToolsVersion "25.0.3" useLibrary 'org.apache.http.legacy' packagingOptions { @@ -37,8 +39,6 @@ android { exclude 'META-INF/NOTICE' } defaultConfig { - minSdkVersion 14 - targetSdkVersion 23 $$GRADLE_DEFAULT_CONFIG$$ } // Both signing and zip-aligning will be done at export time @@ -56,7 +56,6 @@ android { 'res' $$GRADLE_RES_DIRS$$ ] - // libs.srcDirs = ['libs'] aidl.srcDirs = [ 'aidl' $$GRADLE_AIDL_DIRS$$ @@ -65,9 +64,6 @@ android { 'assets' $$GRADLE_ASSET_DIRS$$ ] - jniLibs.srcDirs = [ - $$GRADLE_JNI_DIRS$$ - ] } debug.jniLibs.srcDirs = [ 'libs/debug' @@ -83,3 +79,5 @@ android { variant.outputs.get(0).setOutputFile(new File("${projectDir}/../../../bin", "android_${variant.name}.apk")) } } + +$$GRADLE_PLUGINS$$ diff --git a/platform/android/detect.py b/platform/android/detect.py index d1073e0c7b..ce44ffbf74 100644 --- a/platform/android/detect.py +++ b/platform/android/detect.py @@ -26,7 +26,7 @@ def get_opts(): return [ ('ANDROID_NDK_ROOT', 'the path to Android NDK', os.environ.get("ANDROID_NDK_ROOT", 0)), - ('ndk_platform', 'compile for platform: (android-<api> , example: android-14)', "android-14"), + ('ndk_platform', 'compile for platform: (android-<api> , example: android-18)', "android-18"), ('android_arch', 'select compiler architecture: (armv7/armv6/x86)', "armv7"), ('android_neon', 'enable neon (armv7 only)', "yes"), ('android_stl', 'enable STL support in android port (for modules)', "no") @@ -168,15 +168,15 @@ def configure(env): env.Append(CPPFLAGS=["-isystem", sysroot + "/usr/include"]) env.Append(CPPFLAGS=string.split( - '-Wno-invalid-command-line-argument -Wno-unused-command-line-argument')) - env.Append(CPPFLAGS=string.split( - '-fpic -ffunction-sections -funwind-tables -fstack-protector-strong -fvisibility=hidden -fno-strict-aliasing -Wa,--noexecstack')) + '-fpic -ffunction-sections -funwind-tables -fstack-protector-strong -fvisibility=hidden -fno-strict-aliasing')) env.Append(CPPFLAGS=string.split('-DANDROID -DNO_STATVFS -DGLES2_ENABLED')) env['neon_enabled'] = False if env['android_arch'] == 'x86': can_vectorize = True target_opts = ['-target', 'i686-none-linux-android'] + # The NDK adds this if targeting API < 21, so we can drop it when Godot targets it at least + env.Append(CPPFLAGS=['-mstackrealign']) elif env["android_arch"] == "armv6": can_vectorize = False target_opts = ['-target', 'armv6-none-linux-androideabi'] @@ -198,7 +198,7 @@ def configure(env): env.Append(LIBS=['OpenSLES']) env.Append(LIBS=['EGL', 'OpenSLES', 'android']) - env.Append(LIBS=['log', 'GLESv1_CM', 'GLESv2', 'z']) + env.Append(LIBS=['log', 'GLESv1_CM', 'GLESv2', 'GLESv3','z']) if (sys.platform.startswith("darwin")): env['SHLIBSUFFIX'] = '.so' @@ -232,7 +232,7 @@ def configure(env): elif (env["target"] == "debug"): env.Append(LINKFLAGS=['-O0']) env.Append(CPPFLAGS=['-O0', '-D_DEBUG', '-UNDEBUG', '-DDEBUG_ENABLED', - '-DDEBUG_MEMORY_ALLOC', '-g', '-fno-limit-debug-info']) + '-DDEBUG_MEMORY_ENABLED', '-g', '-fno-limit-debug-info']) env.Append(CPPFLAGS=['-DANDROID_ENABLED', '-DUNIX_ENABLED', '-DNO_FCNTL', '-DMPC_FIXED_POINT']) diff --git a/platform/android/dir_access_android.cpp b/platform/android/dir_access_android.cpp index 989bd02bd9..67aa7750cd 100644 --- a/platform/android/dir_access_android.cpp +++ b/platform/android/dir_access_android.cpp @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/android/dir_access_android.h b/platform/android/dir_access_android.h index 640800584a..32986f524b 100644 --- a/platform/android/dir_access_android.h +++ b/platform/android/dir_access_android.h @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/android/dir_access_jandroid.cpp b/platform/android/dir_access_jandroid.cpp index 68446302ff..34f4afa331 100644 --- a/platform/android/dir_access_jandroid.cpp +++ b/platform/android/dir_access_jandroid.cpp @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/android/dir_access_jandroid.h b/platform/android/dir_access_jandroid.h index 096858ddf7..0175595543 100644 --- a/platform/android/dir_access_jandroid.h +++ b/platform/android/dir_access_jandroid.h @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/android/export/export.cpp b/platform/android/export/export.cpp index 31fa4c18bd..a72e8aa90e 100644 --- a/platform/android/export/export.cpp +++ b/platform/android/export/export.cpp @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -35,7 +36,8 @@ #include "io/zip_io.h" #include "os/file_access.h" #include "os/os.h" -#include "platform/android/logo.h" +#include "platform/android/logo.gen.h" +#include "platform/android/run_icon.gen.h" #include "version.h" #include <string.h> #if 0 @@ -1713,7 +1715,7 @@ Error EditorExportPlatformAndroid::run(int p_device, int p_flags) { args.push_back("--remove-all"); err = OS::get_singleton()->execute(adb,args,true,NULL,NULL,&rv); - int port = GlobalConfig::get_singleton()->get("network/debug/remote_port"); + int port = (int)EditorSettings::get_singleton()->get("network/debug/remote_port"); args.clear(); args.push_back("reverse"); args.push_back("tcp:"+itos(port)); @@ -1792,7 +1794,6 @@ EditorExportPlatformAndroid::EditorExportPlatformAndroid() { name=""; _signed=true; apk_expansion=false; - device_lock = Mutex::create(); quit_request=false; orientation=0; remove_prev=true; @@ -1888,26 +1889,1688 @@ EditorExportPlatformAndroid::~EditorExportPlatformAndroid() { #endif -void register_android_exporter() { +static const char *android_perms[] = { + "ACCESS_CHECKIN_PROPERTIES", + "ACCESS_COARSE_LOCATION", + "ACCESS_FINE_LOCATION", + "ACCESS_LOCATION_EXTRA_COMMANDS", + "ACCESS_MOCK_LOCATION", + "ACCESS_NETWORK_STATE", + "ACCESS_SURFACE_FLINGER", + "ACCESS_WIFI_STATE", + "ACCOUNT_MANAGER", + "ADD_VOICEMAIL", + "AUTHENTICATE_ACCOUNTS", + "BATTERY_STATS", + "BIND_ACCESSIBILITY_SERVICE", + "BIND_APPWIDGET", + "BIND_DEVICE_ADMIN", + "BIND_INPUT_METHOD", + "BIND_NFC_SERVICE", + "BIND_NOTIFICATION_LISTENER_SERVICE", + "BIND_PRINT_SERVICE", + "BIND_REMOTEVIEWS", + "BIND_TEXT_SERVICE", + "BIND_VPN_SERVICE", + "BIND_WALLPAPER", + "BLUETOOTH", + "BLUETOOTH_ADMIN", + "BLUETOOTH_PRIVILEGED", + "BRICK", + "BROADCAST_PACKAGE_REMOVED", + "BROADCAST_SMS", + "BROADCAST_STICKY", + "BROADCAST_WAP_PUSH", + "CALL_PHONE", + "CALL_PRIVILEGED", + "CAMERA", + "CAPTURE_AUDIO_OUTPUT", + "CAPTURE_SECURE_VIDEO_OUTPUT", + "CAPTURE_VIDEO_OUTPUT", + "CHANGE_COMPONENT_ENABLED_STATE", + "CHANGE_CONFIGURATION", + "CHANGE_NETWORK_STATE", + "CHANGE_WIFI_MULTICAST_STATE", + "CHANGE_WIFI_STATE", + "CLEAR_APP_CACHE", + "CLEAR_APP_USER_DATA", + "CONTROL_LOCATION_UPDATES", + "DELETE_CACHE_FILES", + "DELETE_PACKAGES", + "DEVICE_POWER", + "DIAGNOSTIC", + "DISABLE_KEYGUARD", + "DUMP", + "EXPAND_STATUS_BAR", + "FACTORY_TEST", + "FLASHLIGHT", + "FORCE_BACK", + "GET_ACCOUNTS", + "GET_PACKAGE_SIZE", + "GET_TASKS", + "GET_TOP_ACTIVITY_INFO", + "GLOBAL_SEARCH", + "HARDWARE_TEST", + "INJECT_EVENTS", + "INSTALL_LOCATION_PROVIDER", + "INSTALL_PACKAGES", + "INSTALL_SHORTCUT", + "INTERNAL_SYSTEM_WINDOW", + "INTERNET", + "KILL_BACKGROUND_PROCESSES", + "LOCATION_HARDWARE", + "MANAGE_ACCOUNTS", + "MANAGE_APP_TOKENS", + "MANAGE_DOCUMENTS", + "MASTER_CLEAR", + "MEDIA_CONTENT_CONTROL", + "MODIFY_AUDIO_SETTINGS", + "MODIFY_PHONE_STATE", + "MOUNT_FORMAT_FILESYSTEMS", + "MOUNT_UNMOUNT_FILESYSTEMS", + "NFC", + "PERSISTENT_ACTIVITY", + "PROCESS_OUTGOING_CALLS", + "READ_CALENDAR", + "READ_CALL_LOG", + "READ_CONTACTS", + "READ_EXTERNAL_STORAGE", + "READ_FRAME_BUFFER", + "READ_HISTORY_BOOKMARKS", + "READ_INPUT_STATE", + "READ_LOGS", + "READ_PHONE_STATE", + "READ_PROFILE", + "READ_SMS", + "READ_SOCIAL_STREAM", + "READ_SYNC_SETTINGS", + "READ_SYNC_STATS", + "READ_USER_DICTIONARY", + "REBOOT", + "RECEIVE_BOOT_COMPLETED", + "RECEIVE_MMS", + "RECEIVE_SMS", + "RECEIVE_WAP_PUSH", + "RECORD_AUDIO", + "REORDER_TASKS", + "RESTART_PACKAGES", + "SEND_RESPOND_VIA_MESSAGE", + "SEND_SMS", + "SET_ACTIVITY_WATCHER", + "SET_ALARM", + "SET_ALWAYS_FINISH", + "SET_ANIMATION_SCALE", + "SET_DEBUG_APP", + "SET_ORIENTATION", + "SET_POINTER_SPEED", + "SET_PREFERRED_APPLICATIONS", + "SET_PROCESS_LIMIT", + "SET_TIME", + "SET_TIME_ZONE", + "SET_WALLPAPER", + "SET_WALLPAPER_HINTS", + "SIGNAL_PERSISTENT_PROCESSES", + "STATUS_BAR", + "SUBSCRIBED_FEEDS_READ", + "SUBSCRIBED_FEEDS_WRITE", + "SYSTEM_ALERT_WINDOW", + "TRANSMIT_IR", + "UNINSTALL_SHORTCUT", + "UPDATE_DEVICE_STATS", + "USE_CREDENTIALS", + "USE_SIP", + "VIBRATE", + "WAKE_LOCK", + "WRITE_APN_SETTINGS", + "WRITE_CALENDAR", + "WRITE_CALL_LOG", + "WRITE_CONTACTS", + "WRITE_EXTERNAL_STORAGE", + "WRITE_GSERVICES", + "WRITE_HISTORY_BOOKMARKS", + "WRITE_PROFILE", + "WRITE_SECURE_SETTINGS", + "WRITE_SETTINGS", + "WRITE_SMS", + "WRITE_SOCIAL_STREAM", + "WRITE_SYNC_SETTINGS", + "WRITE_USER_DICTIONARY", + NULL +}; + +class EditorExportAndroid : public EditorExportPlatform { + + GDCLASS(EditorExportAndroid, EditorExportPlatform) + + Ref<ImageTexture> logo; + Ref<ImageTexture> run_icon; + + struct Device { + + String id; + String name; + String description; + }; + + struct APKExportData { + + zipFile apk; + EditorProgress *ep; + }; + + Vector<Device> devices; + bool devices_changed; + Mutex *device_lock; + Thread *device_thread; + volatile bool quit_request; + + static void _device_poll_thread(void *ud) { + + EditorExportAndroid *ea = (EditorExportAndroid *)ud; + + while (!ea->quit_request) { + + String adb = EditorSettings::get_singleton()->get("export/android/adb"); + if (FileAccess::exists(adb)) { + + String devices; + List<String> args; + args.push_back("devices"); + int ec; + OS::get_singleton()->execute(adb, args, true, NULL, &devices, &ec); + + Vector<String> ds = devices.split("\n"); + Vector<String> ldevices; + for (int i = 1; i < ds.size(); i++) { + + String d = ds[i]; + int dpos = d.find("device"); + if (dpos == -1) + continue; + d = d.substr(0, dpos).strip_edges(); + //print_line("found devuce: "+d); + ldevices.push_back(d); + } + + ea->device_lock->lock(); + + bool different = false; + + if (ea->devices.size() != ldevices.size()) { + + different = true; + } else { + + for (int i = 0; i < ea->devices.size(); i++) { + + if (ea->devices[i].id != ldevices[i]) { + different = true; + break; + } + } + } + + if (different) { + + print_line("DIFFERENT!"); + Vector<Device> ndevices; + + for (int i = 0; i < ldevices.size(); i++) { + + Device d; + d.id = ldevices[i]; + for (int j = 0; j < ea->devices.size(); j++) { + if (ea->devices[j].id == ldevices[i]) { + d.description = ea->devices[j].description; + d.name = ea->devices[j].name; + } + } + + if (d.description == "") { + //in the oven, request! + args.clear(); + args.push_back("-s"); + args.push_back(d.id); + args.push_back("shell"); + args.push_back("cat"); + args.push_back("/system/build.prop"); + int ec; + String dp; + + OS::get_singleton()->execute(adb, args, true, NULL, &dp, &ec); + + Vector<String> props = dp.split("\n"); + String vendor; + String device; + d.description + "Device ID: " + d.id + "\n"; + for (int j = 0; j < props.size(); j++) { + + String p = props[j]; + if (p.begins_with("ro.product.model=")) { + device = p.get_slice("=", 1).strip_edges(); + } else if (p.begins_with("ro.product.brand=")) { + vendor = p.get_slice("=", 1).strip_edges().capitalize(); + } else if (p.begins_with("ro.build.display.id=")) { + d.description += "Build: " + p.get_slice("=", 1).strip_edges() + "\n"; + } else if (p.begins_with("ro.build.version.release=")) { + d.description += "Release: " + p.get_slice("=", 1).strip_edges() + "\n"; + } else if (p.begins_with("ro.product.cpu.abi=")) { + d.description += "CPU: " + p.get_slice("=", 1).strip_edges() + "\n"; + } else if (p.begins_with("ro.product.manufacturer=")) { + d.description += "Manufacturer: " + p.get_slice("=", 1).strip_edges() + "\n"; + } else if (p.begins_with("ro.board.platform=")) { + d.description += "Chipset: " + p.get_slice("=", 1).strip_edges() + "\n"; + } else if (p.begins_with("ro.opengles.version=")) { + uint32_t opengl = p.get_slice("=", 1).to_int(); + d.description += "OpenGL: " + itos(opengl >> 16) + "." + itos((opengl >> 8) & 0xFF) + "." + itos((opengl)&0xFF) + "\n"; + } + } + + d.name = vendor + " " + device; + //print_line("name: "+d.name); + //print_line("description: "+d.description); + } + + ndevices.push_back(d); + } + + ea->devices = ndevices; + ea->devices_changed = true; + } + + ea->device_lock->unlock(); + } + + uint64_t wait = 3000000; + uint64_t time = OS::get_singleton()->get_ticks_usec(); + while (OS::get_singleton()->get_ticks_usec() - time < wait) { + OS::get_singleton()->delay_usec(1000); + if (ea->quit_request) + break; + } + } + + if (EditorSettings::get_singleton()->get("export/android/shutdown_adb_on_exit")) { + String adb = EditorSettings::get_singleton()->get("export/android/adb"); + if (!FileAccess::exists(adb)) { + return; //adb not configured + } + + List<String> args; + args.push_back("kill-server"); + OS::get_singleton()->execute(adb, args, true); + }; + } + + String get_project_name(const String &p_name) const { + + String aname; + if (p_name != "") { + aname = p_name; + } else { + aname = GlobalConfig::get_singleton()->get("application/name"); + } + + if (aname == "") { + aname = _MKSTR(VERSION_NAME); + } + + return aname; + } + + String get_package_name(const String &p_package) { + + String pname = p_package; + String basename = GlobalConfig::get_singleton()->get("application/name"); + basename = basename.to_lower(); + + String name; + bool first = true; + for (int i = 0; i < basename.length(); i++) { + CharType c = basename[i]; + if (c >= '0' && c <= '9' && first) { + continue; + } + if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9')) { + name += String::chr(c); + first = false; + } + } + if (name == "") + name = "noname"; + + pname = pname.replace("$genname", name); + return pname; + } + + static bool _should_compress_asset(const String &p_path, const Vector<uint8_t> &p_data) { + + /* + * By not compressing files with little or not benefit in doing so, + * a performance gain is expected attime. Moreover, if the APK is + * zip-aligned, assets stored as they are can be efficiently read by + * Android by memory-mapping them. + */ + + // -- Unconditional uncompress to mimic AAPT plus some other + + static const char *unconditional_compress_ext[] = { + // From https://github.com/android/platform_frameworks_base/blob/master/tools/aapt/Package.cpp + // These formats are already compressed, or don't compress well: + ".jpg", ".jpeg", ".png", ".gif", + ".wav", ".mp2", ".mp3", ".ogg", ".aac", + ".mpg", ".mpeg", ".mid", ".midi", ".smf", ".jet", + ".rtttl", ".imy", ".xmf", ".mp4", ".m4a", + ".m4v", ".3gp", ".3gpp", ".3g2", ".3gpp2", + ".amr", ".awb", ".wma", ".wmv", + // Godot-specific: + ".webp", // Same reasoning as .png + ".cfb", // Don't let small config files slow-down startup + ".scn", // Binary scenes are usually already compressed + ".stex", // Streamable textures are usually already compressed + // Trailer for easier processing + NULL + }; + + for (const char **ext = unconditional_compress_ext; *ext; ++ext) { + if (p_path.to_lower().ends_with(String(*ext))) { + return false; + } + } + + // -- Compressed resource? + + if (p_data.size() >= 4 && p_data[0] == 'R' && p_data[1] == 'S' && p_data[2] == 'C' && p_data[3] == 'C') { + // Already compressed + return false; + } + + // --- TODO: Decide on texture resources according to their image compression setting + + return true; + } + + static zip_fileinfo get_zip_fileinfo() { + + OS::Time time = OS::get_singleton()->get_time(); + OS::Date date = OS::get_singleton()->get_date(); + + zip_fileinfo zipfi; + zipfi.tmz_date.tm_hour = time.hour; + zipfi.tmz_date.tm_mday = date.day; + zipfi.tmz_date.tm_min = time.min; + zipfi.tmz_date.tm_mon = date.month; + zipfi.tmz_date.tm_sec = time.sec; + zipfi.tmz_date.tm_year = date.year; + zipfi.dosDate = 0; + zipfi.external_fa = 0; + zipfi.internal_fa = 0; + + return zipfi; + } + + static Error save_apk_file(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total) { + + APKExportData *ed = (APKExportData *)p_userdata; + String dst_path = p_path; + dst_path = dst_path.replace_first("res://", "assets/"); + + zip_fileinfo zipfi = get_zip_fileinfo(); + + zipOpenNewFileInZip(ed->apk, + dst_path.utf8().get_data(), + &zipfi, + NULL, + 0, + NULL, + 0, + NULL, + _should_compress_asset(p_path, p_data) ? Z_DEFLATED : 0, + Z_DEFAULT_COMPRESSION); + + zipWriteInFileInZip(ed->apk, p_data.ptr(), p_data.size()); + zipCloseFileInZip(ed->apk); + ed->ep->step("File: " + p_path, 3 + p_file * 100 / p_total); + return OK; + } + + void _fix_manifest(const Ref<EditorExportPreset> &p_preset, Vector<uint8_t> &p_manifest, bool p_give_internet) { + + const int CHUNK_AXML_FILE = 0x00080003; + 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_START_NAMESPACE = 0x00100100; + const int CHUNK_XML_START_TAG = 0x00100102; + const int CHUNK_XML_TEXT = 0x00100104; + const int UTF8_FLAG = 0x00000100; + + Vector<String> string_table; + + uint32_t ofs = 0; + + uint32_t header = decode_uint32(&p_manifest[ofs]); + uint32_t filesize = decode_uint32(&p_manifest[ofs + 4]); + ofs += 8; + + //print_line("FILESIZE: "+itos(filesize)+" ACTUAL: "+itos(p_manifest.size())); + + uint32_t string_count; + uint32_t styles_count; + uint32_t string_flags; + uint32_t string_data_offset; + + uint32_t styles_offset; + uint32_t string_table_begins; + uint32_t string_table_ends; + Vector<uint8_t> stable_extra; + + String version_name = p_preset->get("version/name"); + int version_code = p_preset->get("version/code"); + String package_name = p_preset->get("package/unique_name"); + + int orientation = p_preset->get("screen/orientation"); + + bool screen_support_small = p_preset->get("screen/support_small"); + bool screen_support_normal = p_preset->get("screen/support_normal"); + 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; + + const char **aperms = android_perms; + while (*aperms) { + + bool enabled = p_preset->get("permissions/" + String(*aperms).to_lower()); + if (enabled) + perms.insert(String(*aperms)); + aperms++; + } + + while (ofs < (uint32_t)p_manifest.size()) { + + uint32_t chunk = decode_uint32(&p_manifest[ofs]); + uint32_t size = decode_uint32(&p_manifest[ofs + 4]); + + switch (chunk) { + + case CHUNK_STRINGS: { + + int iofs = ofs + 8; + + string_count = decode_uint32(&p_manifest[iofs]); + styles_count = decode_uint32(&p_manifest[iofs + 4]); + string_flags = decode_uint32(&p_manifest[iofs + 8]); + string_data_offset = decode_uint32(&p_manifest[iofs + 12]); + styles_offset = decode_uint32(&p_manifest[iofs + 16]); + /* + printf("string count: %i\n",string_count); + printf("flags: %i\n",string_flags); + printf("sdata ofs: %i\n",string_data_offset); + printf("styles ofs: %i\n",styles_offset); + */ + uint32_t st_offset = iofs + 20; + string_table.resize(string_count); + uint32_t string_end = 0; + + string_table_begins = st_offset; + + for (uint32_t i = 0; i < string_count; i++) { + + uint32_t string_at = decode_uint32(&p_manifest[st_offset + i * 4]); + string_at += st_offset + string_count * 4; + + ERR_EXPLAIN("Unimplemented, can't read utf8 string table."); + ERR_FAIL_COND(string_flags & UTF8_FLAG); + + if (string_flags & UTF8_FLAG) { + + } else { + uint32_t len = decode_uint16(&p_manifest[string_at]); + Vector<CharType> ucstring; + ucstring.resize(len + 1); + for (uint32_t j = 0; j < len; j++) { + uint16_t c = decode_uint16(&p_manifest[string_at + 2 + 2 * j]); + ucstring[j] = c; + } + string_end = MAX(string_at + 2 + 2 * len, string_end); + ucstring[len] = 0; + string_table[i] = ucstring.ptr(); + } + + //print_line("String "+itos(i)+": "+string_table[i]); + } + + for (uint32_t i = string_end; i < (ofs + size); i++) { + stable_extra.push_back(p_manifest[i]); + } + + //printf("stable extra: %i\n",int(stable_extra.size())); + string_table_ends = ofs + size; + + //print_line("STABLE SIZE: "+itos(size)+" ACTUAL: "+itos(string_table_ends)); + + } break; + case CHUNK_XML_START_TAG: { + + int iofs = ofs + 8; + uint32_t line = decode_uint32(&p_manifest[iofs]); + uint32_t nspace = decode_uint32(&p_manifest[iofs + 8]); + uint32_t name = decode_uint32(&p_manifest[iofs + 12]); + uint32_t check = decode_uint32(&p_manifest[iofs + 16]); + + String tname = string_table[name]; + + //printf("NSPACE: %i\n",nspace); + //printf("NAME: %i (%s)\n",name,tname.utf8().get_data()); + //printf("CHECK: %x\n",check); + uint32_t attrcount = decode_uint32(&p_manifest[iofs + 20]); + iofs += 28; + //printf("ATTRCOUNT: %x\n",attrcount); + for (uint32_t i = 0; i < attrcount; i++) { + uint32_t attr_nspace = decode_uint32(&p_manifest[iofs]); + uint32_t attr_name = decode_uint32(&p_manifest[iofs + 4]); + uint32_t attr_value = decode_uint32(&p_manifest[iofs + 8]); + uint32_t attr_flags = decode_uint32(&p_manifest[iofs + 12]); + uint32_t attr_resid = decode_uint32(&p_manifest[iofs + 16]); + + String value; + if (attr_value != 0xFFFFFFFF) + value = string_table[attr_value]; + else + value = "Res #" + itos(attr_resid); + String attrname = string_table[attr_name]; + String nspace; + if (attr_nspace != 0xFFFFFFFF) + nspace = string_table[attr_nspace]; + else + nspace = ""; + + //printf("ATTR %i NSPACE: %i\n",i,attr_nspace); + //printf("ATTR %i NAME: %i (%s)\n",i,attr_name,attrname.utf8().get_data()); + //printf("ATTR %i VALUE: %i (%s)\n",i,attr_value,value.utf8().get_data()); + //printf("ATTR %i FLAGS: %x\n",i,attr_flags); + //printf("ATTR %i RESID: %x\n",i,attr_resid); + + //replace project information + if (tname == "manifest" && attrname == "package") { + + print_line("FOUND package"); + string_table[attr_value] = get_package_name(package_name); + } + + //print_line("tname: "+tname); + //print_line("nspace: "+nspace); + //print_line("attrname: "+attrname); + if (tname == "manifest" && /*nspace=="android" &&*/ attrname == "versionCode") { + + print_line("FOUND versionCode"); + encode_uint32(version_code, &p_manifest[iofs + 16]); + } + + if (tname == "manifest" && /*nspace=="android" &&*/ attrname == "versionName") { + + print_line("FOUND versionName"); + if (attr_value == 0xFFFFFFFF) { + WARN_PRINT("Version name in a resource, should be plaintext") + } else + string_table[attr_value] = version_name; + } + + if (tname == "activity" && /*nspace=="android" &&*/ attrname == "screenOrientation") { + + encode_uint32(orientation == 0 ? 0 : 1, &p_manifest[iofs + 16]); + /* + print_line("FOUND screen orientation"); + if (attr_value==0xFFFFFFFF) { + WARN_PRINT("Version name in a resource, should be plaintext") + } else { + string_table[attr_value]=(orientation==0?"landscape":"portrait"); + }*/ + } + + 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") { + + encode_uint32(screen_support_small ? 0xFFFFFFFF : 0, &p_manifest[iofs + 16]); + + } else if (attrname == "normalScreens") { + + encode_uint32(screen_support_normal ? 0xFFFFFFFF : 0, &p_manifest[iofs + 16]); + + } else if (attrname == "largeScreens") { + + encode_uint32(screen_support_large ? 0xFFFFFFFF : 0, &p_manifest[iofs + 16]); + + } else if (attrname == "xlargeScreens") { + + encode_uint32(screen_support_xlarge ? 0xFFFFFFFF : 0, &p_manifest[iofs + 16]); + } + } + + iofs += 20; + } + + } break; + } + //printf("chunk %x: size: %d\n",chunk,size); + + ofs += size; + } + + //printf("end\n"); + + //create new andriodmanifest binary + + Vector<uint8_t> ret; + ret.resize(string_table_begins + string_table.size() * 4); + + for (uint32_t i = 0; i < string_table_begins; i++) { + + ret[i] = p_manifest[i]; + } + + ofs = 0; + for (int i = 0; i < string_table.size(); i++) { + + 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]; + 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? + encode_uint16(s[j], chars); + chars += 2; + } + encode_uint16(0, chars); + chars += 2; + } + + for (int i = 0; i < stable_extra.size(); i++) { + ret.push_back(stable_extra[i]); + } + + while (ret.size() % 4) + ret.push_back(0); + + uint32_t new_stable_end = ret.size(); + + uint32_t extra = (p_manifest.size() - string_table_ends); + ret.resize(new_stable_end + extra); + for (uint32_t i = 0; i < extra; i++) + ret[new_stable_end + i] = p_manifest[string_table_ends + i]; + + while (ret.size() % 4) + ret.push_back(0); + encode_uint32(ret.size(), &ret[4]); //update new file size + + encode_uint32(new_stable_end - 8, &ret[12]); //update new string table size + + //print_line("file size: "+itos(ret.size())); + + p_manifest = ret; + +#if 0 + uint32_t header[9]; + for(int i=0;i<9;i++) { + header[i]=decode_uint32(&p_manifest[i*4]); + } + + //print_line("STO: "+itos(header[3])); + uint32_t st_offset=9*4; + //ERR_FAIL_COND(header[3]!=0x24) + uint32_t string_count=header[4]; + + + string_table.resize(string_count); + + for(int i=0;i<string_count;i++) { + + uint32_t string_at = decode_uint32(&p_manifest[st_offset+i*4]); + string_at+=st_offset+string_count*4; + uint32_t len = decode_uint16(&p_manifest[string_at]); + Vector<CharType> ucstring; + ucstring.resize(len+1); + for(int j=0;j<len;j++) { + uint16_t c=decode_uint16(&p_manifest[string_at+2+2*j]); + ucstring[j]=c; + } + ucstring[len]=0; + string_table[i]=ucstring.ptr(); + } + +#endif + } + + static String _parse_string(const uint8_t *p_bytes, bool p_utf8) { + + uint32_t offset = 0; + uint32_t len = decode_uint16(&p_bytes[offset]); + + if (p_utf8) { + //don't know how to read extended utf8, this will have to be for now + len >>= 8; + } + offset += 2; + //printf("len %i, unicode: %i\n",len,int(p_utf8)); + + if (p_utf8) { + + Vector<uint8_t> str8; + str8.resize(len + 1); + for (uint32_t i = 0; i < len; i++) { + str8[i] = p_bytes[offset + i]; + } + str8[len] = 0; + String str; + str.parse_utf8((const char *)str8.ptr()); + return str; + } else { + + String str; + for (uint32_t i = 0; i < len; i++) { + CharType c = decode_uint16(&p_bytes[offset + i * 2]); + if (c == 0) + break; + str += String::chr(c); + } + return str; + } + } + void _fix_resources(const Ref<EditorExportPreset> &p_preset, Vector<uint8_t> &p_manifest) { + + const int UTF8_FLAG = 0x00000100; + print_line("*******************GORRRGLE***********************"); + + uint32_t header = decode_uint32(&p_manifest[0]); + uint32_t filesize = decode_uint32(&p_manifest[4]); + uint32_t string_block_len = decode_uint32(&p_manifest[16]); + uint32_t string_count = decode_uint32(&p_manifest[20]); + uint32_t string_flags = decode_uint32(&p_manifest[28]); + const uint32_t string_table_begins = 40; + + Vector<String> string_table; + + String package_name = p_preset->get("package/name"); + + //printf("stirng block len: %i\n",string_block_len); + //printf("stirng count: %i\n",string_count); + //printf("flags: %x\n",string_flags); + + for (uint32_t i = 0; i < string_count; i++) { + + uint32_t offset = decode_uint32(&p_manifest[string_table_begins + i * 4]); + offset += string_table_begins + string_count * 4; + + String str = _parse_string(&p_manifest[offset], string_flags & UTF8_FLAG); + + if (str.begins_with("godot-project-name")) { + + if (str == "godot-project-name") { + //project name + str = get_project_name(package_name); + + } else { + + String lang = str.substr(str.find_last("-") + 1, str.length()).replace("-", "_"); + String prop = "application/name_" + lang; + if (GlobalConfig::get_singleton()->has(prop)) { + str = GlobalConfig::get_singleton()->get(prop); + } else { + str = get_project_name(package_name); + } + } + } + + string_table.push_back(str); + } + + //write a new string table, but use 16 bits + Vector<uint8_t> ret; + ret.resize(string_table_begins + string_table.size() * 4); + + for (uint32_t i = 0; i < string_table_begins; i++) { + + ret[i] = p_manifest[i]; + } + + int ofs = 0; + for (int i = 0; i < string_table.size(); i++) { + + encode_uint32(ofs, &ret[string_table_begins + i * 4]); + ofs += string_table[i].length() * 2 + 2 + 2; + } + + ret.resize(ret.size() + ofs); + uint8_t *chars = &ret[ret.size() - ofs]; + for (int i = 0; i < string_table.size(); i++) { + + String s = string_table[i]; + encode_uint16(s.length(), chars); + chars += 2; + for (int j = 0; j < s.length(); j++) { + encode_uint16(s[j], chars); + chars += 2; + } + encode_uint16(0, chars); + chars += 2; + } + + //pad + while (ret.size() % 4) + ret.push_back(0); + + //change flags to not use utf8 + encode_uint32(string_flags & ~0x100, &ret[28]); + //change length + encode_uint32(ret.size() - 12, &ret[16]); + //append the rest... + int rest_from = 12 + string_block_len; + int rest_to = ret.size(); + int rest_len = (p_manifest.size() - rest_from); + ret.resize(ret.size() + (p_manifest.size() - rest_from)); + for (int i = 0; i < rest_len; i++) { + ret[rest_to + i] = p_manifest[rest_from + i]; + } + //finally update the size + encode_uint32(ret.size(), &ret[4]); + p_manifest = ret; + //printf("end\n"); + } + +public: + enum { + MAX_USER_PERMISSIONS = 20 + }; + + typedef Error (*EditorExportSaveFunction)(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total); + +public: + virtual void get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) { + + r_features->push_back("etc"); + } + + virtual void get_export_options(List<ExportOption> *r_options) { + + r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "one_click_deploy/clear_previous_install"), true)); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_package/debug", PROPERTY_HINT_GLOBAL_FILE, "apk"), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_package/release", PROPERTY_HINT_GLOBAL_FILE, "apk"), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "command_line/extra_args"), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "version/code", PROPERTY_HINT_RANGE, "1,65535,1"), 1)); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "version/name"), "1.0")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "package/unique_name"), "org.godotengine.$genname")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "package/name"), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "package/icon", PROPERTY_HINT_FILE, "png"), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "package/signed"), true)); + r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "architecture/arm"), true)); + r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "architecture/x86"), false)); + r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "screen/use_32_bits_view"), true)); + r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "screen/immersive_mode"), true)); + r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "screen/orientation", PROPERTY_HINT_ENUM, "Landscape,Portrait"), 0)); + r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "screen/support_small"), true)); + r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "screen/support_normal"), true)); + r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "screen/support_large"), true)); + r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "screen/support_xlarge"), true)); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "keystore/release", PROPERTY_HINT_GLOBAL_FILE, "keystore"), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "keystore/release_user"), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "keystore/release_password"), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "apk_expansion/enable"), false)); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "apk_expansion/SALT"), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "apk_expansion/public_key", PROPERTY_HINT_MULTILINE_TEXT), "")); + + const char **perms = android_perms; + while (*perms) { + + r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "permissions/" + String(*perms).to_lower()), false)); + perms++; + } + + for (int i = 0; i < MAX_USER_PERMISSIONS; i++) { + + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "user_permissions/" + itos(i)), false)); + } + + //r_options->push_back( PropertyInfo( Variant::INT, "resources/pack_mode", PROPERTY_HINT_ENUM,"Copy,Single Exec.,Pack (.pck),Bundles (Optical)")); + } + + virtual String get_name() const { + return "Android"; + } + virtual Ref<Texture> get_logo() const { + return logo; + } + + virtual bool poll_devices() { + + bool dc = devices_changed; + devices_changed = false; + return dc; + } + + virtual int get_device_count() const { + + device_lock->lock(); + int dc = devices.size(); + device_lock->unlock(); + + return dc; + } + + virtual String get_device_name(int p_device) const { + + ERR_FAIL_INDEX_V(p_device, devices.size(), ""); + device_lock->lock(); + String s = devices[p_device].name; + device_lock->unlock(); + return s; + } + + virtual String get_device_info(int p_device) const { + + ERR_FAIL_INDEX_V(p_device, devices.size(), ""); + device_lock->lock(); + String s = devices[p_device].description; + device_lock->unlock(); + return s; + } + + virtual Error run(const Ref<EditorExportPreset> &p_preset, int p_device, int p_debug_flags) { + + ERR_FAIL_INDEX_V(p_device, devices.size(), ERR_INVALID_PARAMETER); + device_lock->lock(); + + EditorProgress ep("run", "Running on " + devices[p_device].name, 3); + + String adb = EditorSettings::get_singleton()->get("export/android/adb"); + if (adb == "") { + + EditorNode::add_io_error("ADB executable not configured in settings, can't run."); + device_lock->unlock(); + return ERR_UNCONFIGURED; + } + + //export_temp + ep.step("Exporting APK", 0); + + bool use_adb_over_usb = bool(EDITOR_DEF("export/android/use_remote_debug_over_adb", true)); + + if (use_adb_over_usb) { + p_debug_flags |= DEBUG_FLAG_REMOTE_DEBUG_LOCALHOST; + } + + String export_to = EditorSettings::get_singleton()->get_settings_path() + "/tmp/tmpexport.apk"; + Error err = export_project(p_preset, true, export_to, p_debug_flags); + if (err) { + device_lock->unlock(); + return err; + } + + List<String> args; + int rv; + + bool remove_prev = p_preset->get("one_click_deploy/clear_previous_install"); + String version_name = p_preset->get("version/name"); + String package_name = p_preset->get("package/unique_name"); + + if (remove_prev) { + ep.step("Uninstalling..", 1); + + print_line("Uninstalling previous version: " + devices[p_device].name); + + args.push_back("-s"); + args.push_back(devices[p_device].id); + args.push_back("uninstall"); + args.push_back(get_package_name(package_name)); + + err = OS::get_singleton()->execute(adb, args, true, NULL, NULL, &rv); #if 0 - String exe_ext=OS::get_singleton()->get_name()=="Windows"?"exe":""; - EDITOR_DEF("export/android/adb",""); - EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::STRING,"android/adb",PROPERTY_HINT_GLOBAL_FILE,exe_ext)); - EDITOR_DEF("export/android/jarsigner",""); - EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::STRING,"android/jarsigner",PROPERTY_HINT_GLOBAL_FILE,exe_ext)); - EDITOR_DEF("export/android/debug_keystore",""); - EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::STRING,"android/debug_keystore",PROPERTY_HINT_GLOBAL_FILE,"keystore")); - EDITOR_DEF("export/android/debug_keystore_user","androiddebugkey"); - EDITOR_DEF("export/android/debug_keystore_pass","android"); - //EDITOR_DEF("android/release_keystore",""); - //EDITOR_DEF("android/release_username",""); - //EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::STRING,"android/release_keystore",PROPERTY_HINT_GLOBAL_FILE,"*.keystore")); - EDITOR_DEF("export/android/timestamping_authority_url",""); - EDITOR_DEF("export/android/use_remote_debug_over_adb",false); - EDITOR_DEF("export/android/shutdown_adb_on_exit",true); - - Ref<EditorExportPlatformAndroid> exporter = Ref<EditorExportPlatformAndroid>( memnew(EditorExportPlatformAndroid) ); - EditorImportExport::get_singleton()->add_export_platform(exporter); + if (err || rv!=0) { + EditorNode::add_io_error("Could not install to device."); + device_lock->unlock(); + return ERR_CANT_CREATE; + } #endif + } + + print_line("Installing into device (please wait..): " + devices[p_device].name); + ep.step("Installing to Device (please wait..)..", 2); + + args.clear(); + args.push_back("-s"); + args.push_back(devices[p_device].id); + args.push_back("install"); + args.push_back("-r"); + args.push_back(export_to); + + err = OS::get_singleton()->execute(adb, args, true, NULL, NULL, &rv); + if (err || rv != 0) { + EditorNode::add_io_error("Could not install to device."); + device_lock->unlock(); + return ERR_CANT_CREATE; + } + + if (use_adb_over_usb) { + + args.clear(); + args.push_back("reverse"); + args.push_back("--remove-all"); + err = OS::get_singleton()->execute(adb, args, true, NULL, NULL, &rv); + + int port = (int)EditorSettings::get_singleton()->get("network/debug/remote_port"); + args.clear(); + args.push_back("reverse"); + args.push_back("tcp:" + itos(port)); + args.push_back("tcp:" + itos(port)); + + err = OS::get_singleton()->execute(adb, args, true, NULL, NULL, &rv); + print_line("Reverse result: " + itos(rv)); + + int fs_port = EditorSettings::get_singleton()->get("filesystem/file_server/port"); + + args.clear(); + args.push_back("reverse"); + args.push_back("tcp:" + itos(fs_port)); + args.push_back("tcp:" + itos(fs_port)); + + err = OS::get_singleton()->execute(adb, args, true, NULL, NULL, &rv); + print_line("Reverse result2: " + itos(rv)); + } + + ep.step("Running on Device..", 3); + args.clear(); + args.push_back("-s"); + args.push_back(devices[p_device].id); + args.push_back("shell"); + args.push_back("am"); + args.push_back("start"); + args.push_back("--user 0"); + args.push_back("-a"); + args.push_back("android.intent.action.MAIN"); + args.push_back("-n"); + args.push_back(get_package_name(package_name) + "/org.godotengine.godot.Godot"); + + err = OS::get_singleton()->execute(adb, args, true, NULL, NULL, &rv); + if (err || rv != 0) { + EditorNode::add_io_error("Could not execute ondevice."); + device_lock->unlock(); + return ERR_CANT_CREATE; + } + device_lock->unlock(); + return OK; + } + + virtual Ref<Texture> get_run_icon() const { + return run_icon; + } + + virtual bool can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const { + + r_missing_templates = find_export_template("android_debug.apk") == String() || find_export_template("android_release.apk") == String(); + + bool valid = !r_missing_templates; + + String adb = EditorSettings::get_singleton()->get("export/android/adb"); + String err; + + if (!FileAccess::exists(adb)) { + + valid = false; + err += "ADB executable not configured in editor settings.\n"; + } + + String js = EditorSettings::get_singleton()->get("export/android/jarsigner"); + + if (!FileAccess::exists(js)) { + + valid = false; + err += "OpenJDK 6 jarsigner not configured in editor settings.\n"; + } + + String dk = EditorSettings::get_singleton()->get("export/android/debug_keystore"); + + if (!FileAccess::exists(dk)) { + + valid = false; + err += "Debug Keystore not configured in editor settings.\n"; + } + + bool apk_expansion = p_preset->get("apk_expansion/enable"); + + if (apk_expansion) { + + /* + if (apk_expansion_salt=="") { + valid=false; + err+="Invalid SALT for apk expansion.\n"; + } + */ + + String apk_expansion_pkey = p_preset->get("apk_expansion/public_key"); + + if (apk_expansion_pkey == "") { + valid = false; + + err += "Invalid public key for apk expansion.\n"; + } + } + + r_error = err; + return valid; + } + + virtual String get_binary_extension() const { + return "apk"; + } + + virtual Error export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags = 0) { + + String src_apk; + + EditorProgress ep("export", "Exporting for Android", 105); + + if (p_debug) + src_apk = p_preset->get("custom_package/debug"); + else + src_apk = p_preset->get("custom_package/release"); + + src_apk = src_apk.strip_edges(); + if (src_apk == "") { + if (p_debug) { + src_apk = find_export_template("android_debug.apk"); + } else { + src_apk = find_export_template("android_release.apk"); + } + if (src_apk == "") { + EditorNode::add_io_error("Package not found: " + src_apk); + return ERR_FILE_NOT_FOUND; + } + } + + FileAccess *src_f = NULL; + zlib_filefunc_def io = zipio_create_io_from_file(&src_f); + + ep.step("Creating APK", 0); + + unzFile pkg = unzOpen2(src_apk.utf8().get_data(), &io); + if (!pkg) { + + EditorNode::add_io_error("Could not find template APK to export:\n" + src_apk); + return ERR_FILE_NOT_FOUND; + } + + ERR_FAIL_COND_V(!pkg, ERR_CANT_OPEN); + int ret = unzGoToFirstFile(pkg); + + zlib_filefunc_def io2 = io; + FileAccess *dst_f = NULL; + io2.opaque = &dst_f; + String unaligned_path = EditorSettings::get_singleton()->get_settings_path() + "/tmp/tmpexport-unaligned.apk"; + zipFile unaligned_apk = zipOpen2(unaligned_path.utf8().get_data(), APPEND_STATUS_CREATE, NULL, &io2); + + bool export_x86 = p_preset->get("architecture/x86"); + bool export_arm = p_preset->get("architecture/arm"); + + bool use_32_fb = p_preset->get("screen/use_32_bits_view"); + bool immersive = p_preset->get("screen/immersive_mode"); + + bool _signed = p_preset->get("package/signed"); + + bool apk_expansion = p_preset->get("apk_expansion/enable"); + + String cmdline = p_preset->get("command_line/extra_args"); + + int version_code = p_preset->get("version/code"); + String version_name = p_preset->get("version/name"); + String package_name = p_preset->get("package/unique_name"); + + String apk_expansion_pkey = p_preset->get("apk_expansion/public_key"); + + String release_keystore = p_preset->get("keystore/release"); + String release_username = p_preset->get("keystore/release_user"); + String release_password = p_preset->get("keystore/release_password"); + + while (ret == UNZ_OK) { + + //get filename + unz_file_info info; + char fname[16384]; + ret = unzGetCurrentFileInfo(pkg, &info, fname, 16384, NULL, 0, NULL, 0); + + bool skip = false; + + String file = fname; + + Vector<uint8_t> data; + data.resize(info.uncompressed_size); + + //read + unzOpenCurrentFile(pkg); + unzReadCurrentFile(pkg, data.ptr(), data.size()); + unzCloseCurrentFile(pkg); + + //write + + if (file == "AndroidManifest.xml") { + + _fix_manifest(p_preset, data, p_flags & (DEBUG_FLAG_DUMB_CLIENT | DEBUG_FLAG_REMOTE_DEBUG)); + } + + if (file == "resources.arsc") { + + _fix_resources(p_preset, data); + } + + if (file == "res/drawable/icon.png") { + + String icon = p_preset->get("package/icon"); + icon = icon.strip_edges(); + bool found = false; + + if (icon != "" && icon.ends_with(".png")) { + + FileAccess *f = FileAccess::open(icon, FileAccess::READ); + if (f) { + + data.resize(f->get_len()); + f->get_buffer(data.ptr(), data.size()); + memdelete(f); + found = true; + } + } + + if (!found) { + + String appicon = GlobalConfig::get_singleton()->get("application/icon"); + if (appicon != "" && appicon.ends_with(".png")) { + FileAccess *f = FileAccess::open(appicon, FileAccess::READ); + if (f) { + data.resize(f->get_len()); + f->get_buffer(data.ptr(), data.size()); + memdelete(f); + } + } + } + } + + if (file == "lib/x86/libgodot_android.so" && !export_x86) { + skip = true; + } + + if (file.match("lib/armeabi*/libgodot_android.so") && !export_arm) { + skip = true; + } + + if (file.begins_with("META-INF") && _signed) { + skip = true; + } + + print_line("ADDING: " + file); + + if (!skip) { + + // Respect decision on compression made by AAPT for the export template + const bool uncompressed = info.compression_method == 0; + + zip_fileinfo zipfi = get_zip_fileinfo(); + + zipOpenNewFileInZip(unaligned_apk, + file.utf8().get_data(), + &zipfi, + NULL, + 0, + NULL, + 0, + NULL, + uncompressed ? 0 : Z_DEFLATED, + Z_DEFAULT_COMPRESSION); + + zipWriteInFileInZip(unaligned_apk, data.ptr(), data.size()); + zipCloseFileInZip(unaligned_apk); + } + + ret = unzGoToNextFile(pkg); + } + + ep.step("Adding Files..", 1); + Error err = OK; + Vector<String> cl = cmdline.strip_edges().split(" "); + for (int i = 0; i < cl.size(); i++) { + if (cl[i].strip_edges().length() == 0) { + cl.remove(i); + i--; + } + } + + gen_export_flags(cl, p_flags); + + if (p_flags & DEBUG_FLAG_DUMB_CLIENT) { + + /*String host = EditorSettings::get_singleton()->get("filesystem/file_server/host"); + int port = EditorSettings::get_singleton()->get("filesystem/file_server/post"); + String passwd = EditorSettings::get_singleton()->get("filesystem/file_server/password"); + cl.push_back("-rfs"); + cl.push_back(host+":"+itos(port)); + if (passwd!="") { + cl.push_back("-rfs_pass"); + cl.push_back(passwd); + }*/ + + } else { + //all files + + if (apk_expansion) { + + String apkfname = "main." + itos(version_code) + "." + get_package_name(package_name) + ".obb"; + String fullpath = p_path.get_base_dir().plus_file(apkfname); + err = save_pack(p_preset, fullpath); + if (err != OK) { + EditorNode::add_io_error("Could not write expansion package file: " + apkfname); + return OK; + } + + cl.push_back("-use_apk_expansion"); + cl.push_back("-apk_expansion_md5"); + cl.push_back(FileAccess::get_md5(fullpath)); + cl.push_back("-apk_expansion_key"); + cl.push_back(apk_expansion_pkey.strip_edges()); + + } else { + + APKExportData ed; + ed.ep = &ep; + ed.apk = unaligned_apk; + + err = export_project_files(p_preset, save_apk_file, &ed); + } + } + + if (use_32_fb) + cl.push_back("-use_depth_32"); + + if (immersive) + cl.push_back("-use_immersive"); + + if (cl.size()) { + //add comandline + Vector<uint8_t> clf; + clf.resize(4); + encode_uint32(cl.size(), &clf[0]); + for (int i = 0; i < cl.size(); i++) { + + CharString txt = cl[i].utf8(); + int base = clf.size(); + clf.resize(base + 4 + txt.length()); + encode_uint32(txt.length(), &clf[base]); + copymem(&clf[base + 4], txt.ptr(), txt.length()); + print_line(itos(i) + " param: " + cl[i]); + } + + zip_fileinfo zipfi = get_zip_fileinfo(); + + zipOpenNewFileInZip(unaligned_apk, + "assets/_cl_", + &zipfi, + NULL, + 0, + NULL, + 0, + NULL, + 0, // No compress (little size gain and potentially slower startup) + Z_DEFAULT_COMPRESSION); + + zipWriteInFileInZip(unaligned_apk, clf.ptr(), clf.size()); + zipCloseFileInZip(unaligned_apk); + } + + zipClose(unaligned_apk, NULL); + unzClose(pkg); + + if (err) { + return err; + } + + if (_signed) { + + String jarsigner = EditorSettings::get_singleton()->get("export/android/jarsigner"); + if (!FileAccess::exists(jarsigner)) { + EditorNode::add_io_error("'jarsigner' could not be found.\nPlease supply a path in the editor settings.\nResulting apk is unsigned."); + return OK; + } + + String keystore; + String password; + String user; + if (p_debug) { + keystore = EditorSettings::get_singleton()->get("export/android/debug_keystore"); + password = EditorSettings::get_singleton()->get("export/android/debug_keystore_pass"); + user = EditorSettings::get_singleton()->get("export/android/debug_keystore_user"); + + ep.step("Signing Debug APK..", 103); + + } else { + keystore = release_keystore; + password = release_password; + user = release_username; + + ep.step("Signing Release APK..", 103); + } + + if (!FileAccess::exists(keystore)) { + EditorNode::add_io_error("Could not find keystore, unable to export."); + return ERR_FILE_CANT_OPEN; + } + + List<String> args; + args.push_back("-digestalg"); + args.push_back("SHA1"); + args.push_back("-sigalg"); + args.push_back("MD5withRSA"); + String tsa_url = EditorSettings::get_singleton()->get("export/android/timestamping_authority_url"); + if (tsa_url != "") { + args.push_back("-tsa"); + args.push_back(tsa_url); + } + args.push_back("-verbose"); + args.push_back("-keystore"); + args.push_back(keystore); + args.push_back("-storepass"); + args.push_back(password); + args.push_back(unaligned_path); + args.push_back(user); + int retval; + OS::get_singleton()->execute(jarsigner, args, true, NULL, NULL, &retval); + if (retval) { + EditorNode::add_io_error("'jarsigner' returned with error #" + itos(retval)); + return ERR_CANT_CREATE; + } + + ep.step("Verifying APK..", 104); + + args.clear(); + args.push_back("-verify"); + args.push_back("-keystore"); + args.push_back(keystore); + args.push_back(unaligned_path); + args.push_back("-verbose"); + + OS::get_singleton()->execute(jarsigner, args, true, NULL, NULL, &retval); + if (retval) { + EditorNode::add_io_error("'jarsigner' verification of APK failed. Make sure to use jarsigner from Java 6."); + return ERR_CANT_CREATE; + } + } + + // Let's zip-align (must be done after signing) + + static const int ZIP_ALIGNMENT = 4; + + ep.step("Aligning APK..", 105); + + unzFile tmp_unaligned = unzOpen2(unaligned_path.utf8().get_data(), &io); + if (!tmp_unaligned) { + + EditorNode::add_io_error("Could not find temp unaligned APK."); + return ERR_FILE_NOT_FOUND; + } + + ERR_FAIL_COND_V(!tmp_unaligned, ERR_CANT_OPEN); + ret = unzGoToFirstFile(tmp_unaligned); + + io2 = io; + dst_f = NULL; + io2.opaque = &dst_f; + zipFile final_apk = zipOpen2(p_path.utf8().get_data(), APPEND_STATUS_CREATE, NULL, &io2); + + // Take files from the unaligned APK and write them out to the aligned one + // in raw mode, i.e. not uncompressing and recompressing, aligning them as needed, + // following what is done in https://github.com/android/platform_build/blob/master/tools/zipalign/ZipAlign.cpp + int bias = 0; + while (ret == UNZ_OK) { + + unz_file_info info; + memset(&info, 0, sizeof(info)); + + char fname[16384]; + char extra[16384]; + ret = unzGetCurrentFileInfo(tmp_unaligned, &info, fname, 16384, extra, 16384 - ZIP_ALIGNMENT, NULL, 0); + + String file = fname; + + Vector<uint8_t> data; + data.resize(info.compressed_size); + + // read + int method, level; + unzOpenCurrentFile2(tmp_unaligned, &method, &level, 1); // raw read + long file_offset = unzGetCurrentFileZStreamPos64(tmp_unaligned); + unzReadCurrentFile(tmp_unaligned, data.ptr(), data.size()); + unzCloseCurrentFile(tmp_unaligned); + + // align + int padding = 0; + if (!info.compression_method) { + // Uncompressed file => Align + long new_offset = file_offset + bias; + padding = (ZIP_ALIGNMENT - (new_offset % ZIP_ALIGNMENT)) % ZIP_ALIGNMENT; + } + + memset(extra + info.size_file_extra, 0, padding); + + // write + zip_fileinfo zipfi = get_zip_fileinfo(); + + zipOpenNewFileInZip2(final_apk, + file.utf8().get_data(), + &zipfi, + extra, + info.size_file_extra + padding, + NULL, + 0, + NULL, + method, + level, + 1); // raw write + zipWriteInFileInZip(final_apk, data.ptr(), data.size()); + zipCloseFileInZipRaw(final_apk, info.uncompressed_size, info.crc); + + bias += padding; + + ret = unzGoToNextFile(tmp_unaligned); + } + + zipClose(final_apk, NULL); + unzClose(tmp_unaligned); + + if (err) { + return err; + } + + return OK; + } + + EditorExportAndroid() { + + Ref<Image> img = memnew(Image(_android_logo)); + logo.instance(); + logo->create_from_image(img); + + img = Ref<Image>(memnew(Image(_android_run_icon))); + run_icon.instance(); + run_icon->create_from_image(img); + + device_lock = Mutex::create(); + device_thread = Thread::create(_device_poll_thread, this); + devices_changed = true; + quit_request = false; + } + + ~EditorExportAndroid() { + quit_request = true; + Thread::wait_to_finish(device_thread); + memdelete(device_lock); + memdelete(device_thread); + } +}; + +void register_android_exporter() { + + String exe_ext; + if (OS::get_singleton()->get_name() == "Windows") { + exe_ext = "*.exe"; + } + + EDITOR_DEF("export/android/adb", ""); + EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::STRING, "export/android/adb", PROPERTY_HINT_GLOBAL_FILE, exe_ext)); + EDITOR_DEF("export/android/jarsigner", ""); + EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::STRING, "export/android/jarsigner", PROPERTY_HINT_GLOBAL_FILE, exe_ext)); + EDITOR_DEF("export/android/debug_keystore", ""); + EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::STRING, "export/android/debug_keystore", PROPERTY_HINT_GLOBAL_FILE, "keystore")); + EDITOR_DEF("export/android/debug_keystore_user", "androiddebugkey"); + EDITOR_DEF("export/android/debug_keystore_pass", "android"); + + EDITOR_DEF("export/android/timestamping_authority_url", ""); + EDITOR_DEF("export/android/use_remote_debug_over_adb", false); + EDITOR_DEF("export/android/shutdown_adb_on_exit", true); + + Ref<EditorExportAndroid> exporter = Ref<EditorExportAndroid>(memnew(EditorExportAndroid)); + EditorExport::get_singleton()->add_export_platform(exporter); } diff --git a/platform/android/export/export.h b/platform/android/export/export.h index 468b484177..e3b0b4aab6 100644 --- a/platform/android/export/export.h +++ b/platform/android/export/export.h @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/android/file_access_android.cpp b/platform/android/file_access_android.cpp index 4426af4dad..be19f056b0 100644 --- a/platform/android/file_access_android.cpp +++ b/platform/android/file_access_android.cpp @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/android/file_access_android.h b/platform/android/file_access_android.h index de131f19bc..0ee8cd7efe 100644 --- a/platform/android/file_access_android.h +++ b/platform/android/file_access_android.h @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/android/file_access_jandroid.cpp b/platform/android/file_access_jandroid.cpp index b3624e9f26..e20ffd4f8a 100644 --- a/platform/android/file_access_jandroid.cpp +++ b/platform/android/file_access_jandroid.cpp @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/android/file_access_jandroid.h b/platform/android/file_access_jandroid.h index b78d5e603c..9bb471246a 100644 --- a/platform/android/file_access_jandroid.h +++ b/platform/android/file_access_jandroid.h @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/android/globals/global_defaults.cpp b/platform/android/globals/global_defaults.cpp index 60d7d8cb6b..f708ad5dd7 100644 --- a/platform/android/globals/global_defaults.cpp +++ b/platform/android/globals/global_defaults.cpp @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/android/globals/global_defaults.h b/platform/android/globals/global_defaults.h index 49d7f6393c..d524b56af6 100644 --- a/platform/android/globals/global_defaults.h +++ b/platform/android/globals/global_defaults.h @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/android/godot_android.cpp b/platform/android/godot_android.cpp index 9d300940b0..3a21f9212f 100644 --- a/platform/android/godot_android.cpp +++ b/platform/android/godot_android.cpp @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/android/java/gradle/wrapper/gradle-wrapper.properties b/platform/android/java/gradle/wrapper/gradle-wrapper.properties index d57051703e..a11cc1b825 100644 --- a/platform/android/java/gradle/wrapper/gradle-wrapper.properties +++ b/platform/android/java/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,7 @@ -#Wed Apr 10 15:27:10 PDT 2013 +#Fri May 12 08:50:03 KST 2017 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-bin.zip +org.gradle.jvmargs=-Xmx1536M diff --git a/platform/android/java/res/drawable/icon.png b/platform/android/java/res/drawable/icon.png Binary files differindex a0a0f4af25..29c4a7b8fc 100644 --- a/platform/android/java/res/drawable/icon.png +++ b/platform/android/java/res/drawable/icon.png diff --git a/platform/android/java/src/com/android/vending/licensing/ILicenseResultListener.java b/platform/android/java/src/com/android/vending/licensing/ILicenseResultListener.java index d90d6eac7b..63720999a7 100644 --- a/platform/android/java/src/com/android/vending/licensing/ILicenseResultListener.java +++ b/platform/android/java/src/com/android/vending/licensing/ILicenseResultListener.java @@ -1,4 +1,20 @@ /* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +/* * This file is auto-generated. DO NOT MODIFY. * Original file: aidl/ILicenseResultListener.aidl */ diff --git a/platform/android/java/src/com/android/vending/licensing/ILicensingService.java b/platform/android/java/src/com/android/vending/licensing/ILicensingService.java index 95599544e4..36afc0537d 100644 --- a/platform/android/java/src/com/android/vending/licensing/ILicensingService.java +++ b/platform/android/java/src/com/android/vending/licensing/ILicensingService.java @@ -1,4 +1,20 @@ /* + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +*/ + +/* * This file is auto-generated. DO NOT MODIFY. * Original file: aidl/ILicensingService.aidl */ diff --git a/platform/android/java/src/com/android/vending/licensing/Obfuscator.java b/platform/android/java/src/com/android/vending/licensing/Obfuscator.java index b5d510d72d..88891728e6 100644 --- a/platform/android/java/src/com/android/vending/licensing/Obfuscator.java +++ b/platform/android/java/src/com/android/vending/licensing/Obfuscator.java @@ -20,7 +20,7 @@ package com.google.android.vending.licensing; * Interface used as part of a {@link Policy} to allow application authors to obfuscate * licensing data that will be stored into a SharedPreferences file. * <p> - * Any transformation scheme must be reversable. Implementing classes may optionally implement an + * Any transformation scheme must be reversible. Implementing classes may optionally implement an * integrity check to further prevent modification to preference data. Implementing classes * should use device-specific information as a key in the obfuscation algorithm to prevent * obfuscated preferences from being shared among devices. diff --git a/platform/android/java/src/com/google/android/vending/expansion/downloader/Helpers.java b/platform/android/java/src/com/google/android/vending/expansion/downloader/Helpers.java index ae3fe957cb..fb56f917be 100644 --- a/platform/android/java/src/com/google/android/vending/expansion/downloader/Helpers.java +++ b/platform/android/java/src/com/google/android/vending/expansion/downloader/Helpers.java @@ -221,7 +221,11 @@ public class Helpers { static public String getSaveFilePath(Context c) { File root = Environment.getExternalStorageDirectory(); - String path = Build.VERSION.SDK_INT >= 23 ? Constants.EXP_PATH_API23 : Constants.EXP_PATH; + // this makes several issues with Android SDK >= 23 devices. + // https://github.com/danikula/Google-Play-Expansion-File/commit/93a03bd34acad67c6ea34cfb6c3f02c93bdcea85 + // https://issuetracker.google.com/issues/37075181 + //String path = Build.VERSION.SDK_INT >= 23 ? Constants.EXP_PATH_API23 : Constants.EXP_PATH; + String path = Constants.EXP_PATH; return root.toString() + path + c.getPackageName(); } diff --git a/platform/android/java/src/com/google/android/vending/expansion/downloader/impl/DownloaderService.java b/platform/android/java/src/com/google/android/vending/expansion/downloader/impl/DownloaderService.java index 627bf3eedd..e83faa2756 100644 --- a/platform/android/java/src/com/google/android/vending/expansion/downloader/impl/DownloaderService.java +++ b/platform/android/java/src/com/google/android/vending/expansion/downloader/impl/DownloaderService.java @@ -569,10 +569,10 @@ public abstract class DownloaderService extends CustomIntentService implements I */ void pollNetworkState() { if (null == mConnectivityManager) { - mConnectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); + mConnectivityManager = (ConnectivityManager) getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE); } if (null == mWifiManager) { - mWifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE); + mWifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE); } if (mConnectivityManager == null) { Log.w(Constants.TAG, diff --git a/platform/android/java/src/org/godotengine/godot/Dictionary.java b/platform/android/java/src/org/godotengine/godot/Dictionary.java index 72f0b7a60e..b9501e0858 100644 --- a/platform/android/java/src/org/godotengine/godot/Dictionary.java +++ b/platform/android/java/src/org/godotengine/godot/Dictionary.java @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/android/java/src/org/godotengine/godot/Godot.java b/platform/android/java/src/org/godotengine/godot/Godot.java index 610f707b47..88928089b6 100644 --- a/platform/android/java/src/org/godotengine/godot/Godot.java +++ b/platform/android/java/src/org/godotengine/godot/Godot.java @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -340,7 +341,7 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC r = is.read(len); if (r<4) { - Log.d("GODOT", "**ERROR** Wrong cmdline param lenght.\n"); + Log.d("GODOT", "**ERROR** Wrong cmdline param length.\n"); return new String[0]; } int strlen=((int)(len[3]&0xFF)<<24) | ((int)(len[2]&0xFF)<<16) | ((int)(len[1]&0xFF)<<8) | ((int)(len[0]&0xFF)); @@ -721,7 +722,7 @@ public class Godot extends Activity implements SensorEventListener, IDownloaderC @Override public void onBackPressed() { System.out.printf("** BACK REQUEST!\n"); - GodotLib.back(); + //GodotLib.back(); } public void forceQuit() { diff --git a/platform/android/java/src/org/godotengine/godot/GodotDownloaderAlarmReceiver.java b/platform/android/java/src/org/godotengine/godot/GodotDownloaderAlarmReceiver.java index 5a07d680b3..6cdc6be793 100644 --- a/platform/android/java/src/org/godotengine/godot/GodotDownloaderAlarmReceiver.java +++ b/platform/android/java/src/org/godotengine/godot/GodotDownloaderAlarmReceiver.java @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/android/java/src/org/godotengine/godot/GodotDownloaderService.java b/platform/android/java/src/org/godotengine/godot/GodotDownloaderService.java index fba082e80d..38d30c108c 100644 --- a/platform/android/java/src/org/godotengine/godot/GodotDownloaderService.java +++ b/platform/android/java/src/org/godotengine/godot/GodotDownloaderService.java @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/android/java/src/org/godotengine/godot/GodotIO.java b/platform/android/java/src/org/godotengine/godot/GodotIO.java index 33c1c03ace..ecb623452c 100644 --- a/platform/android/java/src/org/godotengine/godot/GodotIO.java +++ b/platform/android/java/src/org/godotengine/godot/GodotIO.java @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -469,7 +470,7 @@ public class GodotIO { } ///////////////////////// - // MISCELANEOUS OS IO + // MISCELLANEOUS OS IO ///////////////////////// diff --git a/platform/android/java/src/org/godotengine/godot/GodotLib.java b/platform/android/java/src/org/godotengine/godot/GodotLib.java index 57856cfd6b..1ed04d9d27 100644 --- a/platform/android/java/src/org/godotengine/godot/GodotLib.java +++ b/platform/android/java/src/org/godotengine/godot/GodotLib.java @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/android/java/src/org/godotengine/godot/GodotPaymentV3.java b/platform/android/java/src/org/godotengine/godot/GodotPaymentV3.java index 6eee8da91b..3cb8fd3da8 100644 --- a/platform/android/java/src/org/godotengine/godot/GodotPaymentV3.java +++ b/platform/android/java/src/org/godotengine/godot/GodotPaymentV3.java @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/android/java/src/org/godotengine/godot/GodotView.java b/platform/android/java/src/org/godotengine/godot/GodotView.java index 4cfe295835..c6c68c36b0 100644 --- a/platform/android/java/src/org/godotengine/godot/GodotView.java +++ b/platform/android/java/src/org/godotengine/godot/GodotView.java @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -77,18 +78,18 @@ public class GodotView extends GLSurfaceView implements InputDeviceListener { private static GodotIO io; private static boolean firsttime=true; - private static boolean use_gl2=false; + private static boolean use_gl3=false; private static boolean use_32=false; private Godot activity; private InputManagerCompat mInputManager; - public GodotView(Context context,GodotIO p_io,boolean p_use_gl2, boolean p_use_32_bits, Godot p_activity) { + public GodotView(Context context,GodotIO p_io,boolean p_use_gl3, boolean p_use_32_bits, Godot p_activity) { super(context); ctx=context; io=p_io; - use_gl2=p_use_gl2; + use_gl3=p_use_gl3; use_32=p_use_32_bits; activity = p_activity; @@ -362,14 +363,15 @@ public class GodotView extends GLSurfaceView implements InputDeviceListener { private static class ContextFactory implements GLSurfaceView.EGLContextFactory { private static int EGL_CONTEXT_CLIENT_VERSION = 0x3098; public EGLContext createContext(EGL10 egl, EGLDisplay display, EGLConfig eglConfig) { - if (use_gl2) - Log.w(TAG, "creating OpenGL ES 2.0 context :"); + if (use_gl3) + Log.w(TAG, "creating OpenGL ES 3.0 context :"); else - Log.w(TAG, "creating OpenGL ES 1.1 context :"); + Log.w(TAG, "creating OpenGL ES 2.0 context :"); checkEglError("Before eglCreateContext", egl); int[] attrib_list2 = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL10.EGL_NONE }; - EGLContext context = egl.eglCreateContext(display, eglConfig, EGL10.EGL_NO_CONTEXT, use_gl2?attrib_list2:null); + int[] attrib_list3 = {EGL_CONTEXT_CLIENT_VERSION, 3, EGL10.EGL_NONE }; + EGLContext context = egl.eglCreateContext(display, eglConfig, EGL10.EGL_NO_CONTEXT, use_gl3?attrib_list3:attrib_list2); checkEglError("After eglCreateContext", egl); return context; } @@ -432,13 +434,14 @@ public class GodotView extends GLSurfaceView implements InputDeviceListener { EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, EGL10.EGL_NONE }; - private static int[] s_configAttribs = + private static int[] s_configAttribs3 = { EGL10.EGL_RED_SIZE, 4, EGL10.EGL_GREEN_SIZE, 4, EGL10.EGL_BLUE_SIZE, 4, // EGL10.EGL_DEPTH_SIZE, 16, // EGL10.EGL_STENCIL_SIZE, EGL10.EGL_DONT_CARE, + EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, //apparently there is no EGL_OPENGL_ES3_BIT EGL10.EGL_NONE }; @@ -447,7 +450,7 @@ public class GodotView extends GLSurfaceView implements InputDeviceListener { /* Get the number of minimally matching EGL configurations */ int[] num_config = new int[1]; - egl.eglChooseConfig(display, use_gl2?s_configAttribs2:s_configAttribs, null, 0, num_config); + egl.eglChooseConfig(display, use_gl3?s_configAttribs3:s_configAttribs2, null, 0, num_config); int numConfigs = num_config[0]; @@ -458,7 +461,7 @@ public class GodotView extends GLSurfaceView implements InputDeviceListener { /* Allocate then read the array of minimally matching EGL configs */ EGLConfig[] configs = new EGLConfig[numConfigs]; - egl.eglChooseConfig(display, use_gl2?s_configAttribs2:s_configAttribs, configs, numConfigs, num_config); + egl.eglChooseConfig(display, use_gl3?s_configAttribs3:s_configAttribs2, configs, numConfigs, num_config); if (DEBUG) { printConfigs(egl, display, configs); diff --git a/platform/android/java/src/org/godotengine/godot/input/GodotEditText.java b/platform/android/java/src/org/godotengine/godot/input/GodotEditText.java index f0dae03a81..bf5239aa77 100644 --- a/platform/android/java/src/org/godotengine/godot/input/GodotEditText.java +++ b/platform/android/java/src/org/godotengine/godot/input/GodotEditText.java @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/android/java/src/org/godotengine/godot/input/GodotTextInputWrapper.java b/platform/android/java/src/org/godotengine/godot/input/GodotTextInputWrapper.java index 3c8207fae1..1dbcb78ada 100644 --- a/platform/android/java/src/org/godotengine/godot/input/GodotTextInputWrapper.java +++ b/platform/android/java/src/org/godotengine/godot/input/GodotTextInputWrapper.java @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/android/java/src/org/godotengine/godot/payments/ConsumeTask.java b/platform/android/java/src/org/godotengine/godot/payments/ConsumeTask.java index 67293df2a8..c37821ffd9 100644 --- a/platform/android/java/src/org/godotengine/godot/payments/ConsumeTask.java +++ b/platform/android/java/src/org/godotengine/godot/payments/ConsumeTask.java @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/android/java/src/org/godotengine/godot/payments/GenericConsumeTask.java b/platform/android/java/src/org/godotengine/godot/payments/GenericConsumeTask.java index dfa363ed75..72126a8f64 100644 --- a/platform/android/java/src/org/godotengine/godot/payments/GenericConsumeTask.java +++ b/platform/android/java/src/org/godotengine/godot/payments/GenericConsumeTask.java @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/android/java/src/org/godotengine/godot/payments/HandlePurchaseTask.java b/platform/android/java/src/org/godotengine/godot/payments/HandlePurchaseTask.java index 3850453a77..e223bbb8c0 100644 --- a/platform/android/java/src/org/godotengine/godot/payments/HandlePurchaseTask.java +++ b/platform/android/java/src/org/godotengine/godot/payments/HandlePurchaseTask.java @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/android/java/src/org/godotengine/godot/payments/PaymentsCache.java b/platform/android/java/src/org/godotengine/godot/payments/PaymentsCache.java index 4678dae1b3..fa5564a3f4 100644 --- a/platform/android/java/src/org/godotengine/godot/payments/PaymentsCache.java +++ b/platform/android/java/src/org/godotengine/godot/payments/PaymentsCache.java @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/android/java/src/org/godotengine/godot/payments/PaymentsManager.java b/platform/android/java/src/org/godotengine/godot/payments/PaymentsManager.java index 73d1cc3bc8..6f308af360 100644 --- a/platform/android/java/src/org/godotengine/godot/payments/PaymentsManager.java +++ b/platform/android/java/src/org/godotengine/godot/payments/PaymentsManager.java @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -354,36 +355,35 @@ public class PaymentsManager { tempList.add(s); } packs.add(tempList); - - for (ArrayList<String> skuPartList : packs) { - Bundle querySkus = new Bundle(); - querySkus.putStringArrayList("ITEM_ID_LIST", skuPartList); - Bundle skuDetails = null; - try { - skuDetails = mService.getSkuDetails(3, activity.getPackageName(), "inapp", querySkus); - if (!skuDetails.containsKey("DETAILS_LIST")) { - int response = getResponseCodeFromBundle(skuDetails); - if (response != BILLING_RESPONSE_RESULT_OK) { - godotPaymentV3.errorSkuDetail(getResponseDesc(response)); - } else { - godotPaymentV3.errorSkuDetail("No error but no detail list."); - } - return; + } + for (ArrayList<String> skuPartList : packs) { + Bundle querySkus = new Bundle(); + querySkus.putStringArrayList("ITEM_ID_LIST", skuPartList); + Bundle skuDetails = null; + try { + skuDetails = mService.getSkuDetails(3, activity.getPackageName(), "inapp", querySkus); + if (!skuDetails.containsKey("DETAILS_LIST")) { + int response = getResponseCodeFromBundle(skuDetails); + if (response != BILLING_RESPONSE_RESULT_OK) { + godotPaymentV3.errorSkuDetail(getResponseDesc(response)); + } else { + godotPaymentV3.errorSkuDetail("No error but no detail list."); } + return; + } - ArrayList<String> responseList = skuDetails.getStringArrayList("DETAILS_LIST"); + ArrayList<String> responseList = skuDetails.getStringArrayList("DETAILS_LIST"); - for (String thisResponse : responseList) { - Log.d("godot", "response = "+thisResponse); - godotPaymentV3.addSkuDetail(thisResponse); - } - } catch (RemoteException e) { - e.printStackTrace(); - godotPaymentV3.errorSkuDetail("RemoteException error!"); + for (String thisResponse : responseList) { + Log.d("godot", "response = "+thisResponse); + godotPaymentV3.addSkuDetail(thisResponse); } + } catch (RemoteException e) { + e.printStackTrace(); + godotPaymentV3.errorSkuDetail("RemoteException error!"); } - godotPaymentV3.completeSkuDetail(); } + godotPaymentV3.completeSkuDetail(); } })).start(); } diff --git a/platform/android/java/src/org/godotengine/godot/payments/PurchaseTask.java b/platform/android/java/src/org/godotengine/godot/payments/PurchaseTask.java index 5ad96b35ee..81352b0cf4 100644 --- a/platform/android/java/src/org/godotengine/godot/payments/PurchaseTask.java +++ b/platform/android/java/src/org/godotengine/godot/payments/PurchaseTask.java @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/android/java/src/org/godotengine/godot/payments/ReleaseAllConsumablesTask.java b/platform/android/java/src/org/godotengine/godot/payments/ReleaseAllConsumablesTask.java index 60a43a9070..9d40371b9b 100644 --- a/platform/android/java/src/org/godotengine/godot/payments/ReleaseAllConsumablesTask.java +++ b/platform/android/java/src/org/godotengine/godot/payments/ReleaseAllConsumablesTask.java @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/android/java/src/org/godotengine/godot/payments/ValidateTask.java b/platform/android/java/src/org/godotengine/godot/payments/ValidateTask.java index f09bcbf9a4..09f80df403 100644 --- a/platform/android/java/src/org/godotengine/godot/payments/ValidateTask.java +++ b/platform/android/java/src/org/godotengine/godot/payments/ValidateTask.java @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/android/java/src/org/godotengine/godot/utils/Crypt.java b/platform/android/java/src/org/godotengine/godot/utils/Crypt.java index f8936bef2b..02a2fba854 100644 --- a/platform/android/java/src/org/godotengine/godot/utils/Crypt.java +++ b/platform/android/java/src/org/godotengine/godot/utils/Crypt.java @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/android/java/src/org/godotengine/godot/utils/CustomSSLSocketFactory.java b/platform/android/java/src/org/godotengine/godot/utils/CustomSSLSocketFactory.java index 823c75d186..7881754fb2 100644 --- a/platform/android/java/src/org/godotengine/godot/utils/CustomSSLSocketFactory.java +++ b/platform/android/java/src/org/godotengine/godot/utils/CustomSSLSocketFactory.java @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/android/java/src/org/godotengine/godot/utils/HttpRequester.java b/platform/android/java/src/org/godotengine/godot/utils/HttpRequester.java index faefbbd2c6..b314fb721b 100644 --- a/platform/android/java/src/org/godotengine/godot/utils/HttpRequester.java +++ b/platform/android/java/src/org/godotengine/godot/utils/HttpRequester.java @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/android/java/src/org/godotengine/godot/utils/RequestParams.java b/platform/android/java/src/org/godotengine/godot/utils/RequestParams.java index bb00f1f468..41d26ba70f 100644 --- a/platform/android/java/src/org/godotengine/godot/utils/RequestParams.java +++ b/platform/android/java/src/org/godotengine/godot/utils/RequestParams.java @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/android/java_class_wrapper.cpp b/platform/android/java_class_wrapper.cpp index eb208f0ee0..56a27fa0e0 100644 --- a/platform/android/java_class_wrapper.cpp +++ b/platform/android/java_class_wrapper.cpp @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/android/java_class_wrapper.h b/platform/android/java_class_wrapper.h index dcc9973446..f990708bdf 100644 --- a/platform/android/java_class_wrapper.h +++ b/platform/android/java_class_wrapper.h @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -68,9 +69,9 @@ class JavaClass : public Reference { jmethodID method; }; - _FORCE_INLINE_ static void _convert_to_variant_type(int p_sig, Variant::Type &r_type, float &likelyhood) { + _FORCE_INLINE_ static void _convert_to_variant_type(int p_sig, Variant::Type &r_type, float &likelihood) { - likelyhood = 1.0; + likelihood = 1.0; r_type = Variant::NIL; switch (p_sig) { @@ -81,37 +82,37 @@ class JavaClass : public Reference { case ARG_TYPE_BYTE | ARG_NUMBER_CLASS_BIT: case ARG_TYPE_BYTE: r_type = Variant::INT; - likelyhood = 0.1; + likelihood = 0.1; break; case ARG_TYPE_CHAR | ARG_NUMBER_CLASS_BIT: case ARG_TYPE_CHAR: r_type = Variant::INT; - likelyhood = 0.2; + likelihood = 0.2; break; case ARG_TYPE_SHORT | ARG_NUMBER_CLASS_BIT: case ARG_TYPE_SHORT: r_type = Variant::INT; - likelyhood = 0.3; + likelihood = 0.3; break; case ARG_TYPE_INT | ARG_NUMBER_CLASS_BIT: case ARG_TYPE_INT: r_type = Variant::INT; - likelyhood = 1.0; + likelihood = 1.0; break; case ARG_TYPE_LONG | ARG_NUMBER_CLASS_BIT: case ARG_TYPE_LONG: r_type = Variant::INT; - likelyhood = 0.5; + likelihood = 0.5; break; case ARG_TYPE_FLOAT | ARG_NUMBER_CLASS_BIT: case ARG_TYPE_FLOAT: r_type = Variant::REAL; - likelyhood = 1.0; + likelihood = 1.0; break; case ARG_TYPE_DOUBLE | ARG_NUMBER_CLASS_BIT: case ARG_TYPE_DOUBLE: r_type = Variant::REAL; - likelyhood = 0.5; + likelihood = 0.5; break; case ARG_TYPE_STRING: r_type = Variant::STRING; break; case ARG_TYPE_CLASS: r_type = Variant::OBJECT; break; @@ -119,31 +120,31 @@ class JavaClass : public Reference { case ARG_ARRAY_BIT | ARG_TYPE_BOOLEAN: r_type = Variant::ARRAY; break; case ARG_ARRAY_BIT | ARG_TYPE_BYTE: r_type = Variant::POOL_BYTE_ARRAY; - likelyhood = 1.0; + likelihood = 1.0; break; case ARG_ARRAY_BIT | ARG_TYPE_CHAR: r_type = Variant::POOL_BYTE_ARRAY; - likelyhood = 0.5; + likelihood = 0.5; break; case ARG_ARRAY_BIT | ARG_TYPE_SHORT: r_type = Variant::POOL_INT_ARRAY; - likelyhood = 0.3; + likelihood = 0.3; break; case ARG_ARRAY_BIT | ARG_TYPE_INT: r_type = Variant::POOL_INT_ARRAY; - likelyhood = 1.0; + likelihood = 1.0; break; case ARG_ARRAY_BIT | ARG_TYPE_LONG: r_type = Variant::POOL_INT_ARRAY; - likelyhood = 0.5; + likelihood = 0.5; break; case ARG_ARRAY_BIT | ARG_TYPE_FLOAT: r_type = Variant::POOL_REAL_ARRAY; - likelyhood = 1.0; + likelihood = 1.0; break; case ARG_ARRAY_BIT | ARG_TYPE_DOUBLE: r_type = Variant::POOL_REAL_ARRAY; - likelyhood = 0.5; + likelihood = 0.5; break; case ARG_ARRAY_BIT | ARG_TYPE_STRING: r_type = Variant::POOL_STRING_ARRAY; break; case ARG_ARRAY_BIT | ARG_TYPE_CLASS: r_type = Variant::ARRAY; break; diff --git a/platform/android/java_glue.cpp b/platform/android/java_glue.cpp index 4016b44434..d4bd443689 100644 --- a/platform/android/java_glue.cpp +++ b/platform/android/java_glue.cpp @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -350,7 +351,7 @@ Variant _jobject_to_variant(JNIEnv *env, jobject obj) { jobjectArray arr = (jobjectArray)obj; int objCount = env->GetArrayLength(arr); - Array varr(true); + Array varr; for (int i = 0; i < objCount; i++) { jobject jobj = env->GetObjectArrayElement(arr, i); @@ -364,7 +365,7 @@ Variant _jobject_to_variant(JNIEnv *env, jobject obj) { if (name == "java.util.HashMap" || name == "org.godotengine.godot.Dictionary") { - Dictionary ret(true); + Dictionary ret; jclass oclass = c; jmethodID get_keys = env->GetMethodID(oclass, "get_keys", "()[Ljava/lang/String;"); jobjectArray arr = (jobjectArray)env->CallObjectMethod(obj, get_keys); @@ -609,7 +610,7 @@ struct JAndroidPointerEvent { }; static List<JAndroidPointerEvent> pointer_events; -static List<InputEvent> key_events; +static List<Ref<InputEvent> > key_events; static List<OS_Android::JoypadEvent> joy_events; static bool initialized = false; static Mutex *input_mutex = NULL; @@ -881,7 +882,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_initialize(JNIEnv *en __android_log_print(ANDROID_LOG_INFO, "godot", "*****SETUP OK"); - //video driver is determined here, because once initialized, it cant be changed + //video driver is determined here, because once initialized, it can't be changed String vd = GlobalConfig::get_singleton()->get("display/driver"); env->CallVoidMethod(_godot_instance, _on_video_init, (jboolean) true); @@ -929,7 +930,16 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_back(JNIEnv *env, job static void _initialize_java_modules() { + if (!GlobalConfig::get_singleton()->has("android/modules")) { + print_line("ANDROID MODULES: Nothing to load, aborting"); + return; + } + String modules = GlobalConfig::get_singleton()->get("android/modules"); + modules = modules.strip_edges(); + if (modules == String()) { + return; + } Vector<String> mods = modules.split(",", false); print_line("ANDROID MODULES : " + modules); __android_log_print(ANDROID_LOG_INFO, "godot", "mod count: %i", mods.size()); @@ -1026,7 +1036,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_step(JNIEnv *env, job while (key_events.size()) { - InputEvent event = key_events.front()->get(); + Ref<InputEvent> event = key_events.front()->get(); os_android->process_event(event); key_events.pop_front(); @@ -1409,30 +1419,23 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joyconnectionchanged( JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_key(JNIEnv *env, jobject obj, jint p_scancode, jint p_unicode_char, jboolean p_pressed) { - InputEvent ievent; - ievent.type = InputEvent::KEY; - ievent.device = 0; + Ref<InputEventKey> ievent; int val = p_unicode_char; int scancode = android_get_keysym(p_scancode); - ievent.key.scancode = scancode; - ievent.key.unicode = val; - ievent.key.pressed = p_pressed; - - print_line("Scancode: " + String::num(p_scancode) + ":" + String::num(ievent.key.scancode) + " Unicode: " + String::num(val)); + ievent->set_scancode(scancode); + ievent->set_unicode(val); + ievent->set_pressed(p_pressed); - ievent.key.mod.shift = false; - ievent.key.mod.alt = false; - ievent.key.mod.control = false; - ievent.key.echo = false; + print_line("Scancode: " + String::num(p_scancode) + ":" + String::num(ievent->get_scancode()) + " Unicode: " + String::num(val)); if (val == '\n') { - ievent.key.scancode = KEY_ENTER; + ievent->set_scancode(KEY_ENTER); } else if (val == 61448) { - ievent.key.scancode = KEY_BACKSPACE; - ievent.key.unicode = KEY_BACKSPACE; + ievent->set_scancode(KEY_BACKSPACE); + ievent->set_unicode(KEY_BACKSPACE); } else if (val == 61453) { - ievent.key.scancode = KEY_ENTER; - ievent.key.unicode = KEY_ENTER; + ievent->set_scancode(KEY_ENTER); + ievent->set_unicode(KEY_ENTER); } else if (p_scancode == 4) { go_back_request = true; diff --git a/platform/android/java_glue.h b/platform/android/java_glue.h index 51a2031867..f400f41e28 100644 --- a/platform/android/java_glue.h +++ b/platform/android/java_glue.h @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/android/os_android.cpp b/platform/android/os_android.cpp index 60719f6d42..9010b9e7da 100644 --- a/platform/android/os_android.cpp +++ b/platform/android/os_android.cpp @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -30,13 +31,13 @@ #include "core/global_config.h" #include "core/io/file_access_buffered_fa.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 "file_access_android.h" #include "main/main.h" #include "servers/visual/visual_server_raster.h" -#include "servers/visual/visual_server_wrap_mt.h" +//#include "servers/visual/visual_server_wrap_mt.h" #ifdef ANDROID_NATIVE_ACTIVITY #include "dir_access_android.h" @@ -125,18 +126,14 @@ void OS_Android::initialize(const VideoMode &p_desired, int p_video_driver, int AudioDriverManager::add_driver(&audio_driver_android); - RasterizerGLES2 *rasterizer_gles22 = memnew(RasterizerGLES2(false, use_reload_hooks, false, use_reload_hooks)); - if (gl_extensions) - rasterizer_gles22->set_extensions(gl_extensions); - rasterizer = rasterizer_gles22; + RasterizerGLES3::register_config(); + RasterizerGLES3::make_current(); - rasterizer->set_force_16_bits_fbo(use_16bits_fbo); - - visual_server = memnew(VisualServerRaster(rasterizer)); - if (get_render_thread_mode() != RENDER_THREAD_UNSAFE) { + visual_server = memnew(VisualServerRaster); + /* if (get_render_thread_mode() != RENDER_THREAD_UNSAFE) { visual_server = memnew(VisualServerWrapMT(visual_server, false)); - }; + };*/ visual_server->init(); visual_server->cursor_set_visible(false, 0); @@ -156,7 +153,7 @@ void OS_Android::initialize(const VideoMode &p_desired, int p_video_driver, int input = memnew(InputDefault); input->set_fallback_mapping("Default Android Gamepad"); - power_manager = memnew(power_android); + //power_manager = memnew(power_android); } void OS_Android::set_main_loop(MainLoop *p_main_loop) { @@ -227,7 +224,7 @@ void OS_Android::print(const char *p_format, ...) { void OS_Android::alert(const String &p_alert, const String &p_title) { - print("ALERT: %s\n", p_alert.utf8().get_data()); + //print("ALERT: %s\n", p_alert.utf8().get_data()); if (alert_func) alert_func(p_alert, p_title); } @@ -248,7 +245,7 @@ bool OS_Android::is_mouse_grab_enabled() const { return false; } -Point2 OS_Android::get_mouse_pos() const { +Point2 OS_Android::get_mouse_position() const { return Point2(); } @@ -347,25 +344,24 @@ void OS_Android::process_joy_event(OS_Android::JoypadEvent p_event) { switch (p_event.type) { case JOY_EVENT_BUTTON: - last_id = input->joy_button(last_id, p_event.device, p_event.index, p_event.pressed); + input->joy_button(p_event.device, p_event.index, p_event.pressed); break; case JOY_EVENT_AXIS: InputDefault::JoyAxis value; value.min = -1; value.value = p_event.value; - last_id = input->joy_axis(last_id, p_event.device, p_event.index, value); + input->joy_axis(p_event.device, p_event.index, value); break; case JOY_EVENT_HAT: - last_id = input->joy_hat(last_id, p_event.device, p_event.hat); + input->joy_hat(p_event.device, p_event.hat); break; default: return; } } -void OS_Android::process_event(InputEvent p_event) { +void OS_Android::process_event(Ref<InputEvent> p_event) { - p_event.ID = last_id++; input->parse_input_event(p_event); } @@ -378,27 +374,24 @@ void OS_Android::process_touch(int p_what, int p_pointer, const Vector<TouchPos> if (touch.size()) { //end all if exist - InputEvent ev; - ev.type = InputEvent::MOUSE_BUTTON; - ev.ID = last_id++; - ev.mouse_button.button_index = BUTTON_LEFT; - ev.mouse_button.button_mask = BUTTON_MASK_LEFT; - ev.mouse_button.pressed = false; - ev.mouse_button.x = touch[0].pos.x; - ev.mouse_button.y = touch[0].pos.y; - ev.mouse_button.global_x = touch[0].pos.x; - ev.mouse_button.global_y = touch[0].pos.y; - input->parse_input_event(ev); + { + Ref<InputEventMouseButton> ev; + ev.instance(); + ev->set_button_index(BUTTON_LEFT); + ev->set_button_mask(BUTTON_MASK_LEFT); + ev->set_pressed(false); + ev->set_position(touch[0].pos); + ev->set_global_position(touch[0].pos); + input->parse_input_event(ev); + } for (int i = 0; i < touch.size(); i++) { - InputEvent ev; - ev.type = InputEvent::SCREEN_TOUCH; - ev.ID = last_id++; - ev.screen_touch.index = touch[i].id; - ev.screen_touch.pressed = false; - ev.screen_touch.x = touch[i].pos.x; - ev.screen_touch.y = touch[i].pos.y; + Ref<InputEventScreenTouch> ev; + ev.instance(); + ev->set_index(touch[i].id); + ev->set_pressed(false); + ev->set_position(touch[i].pos); input->parse_input_event(ev); } } @@ -411,16 +404,15 @@ void OS_Android::process_touch(int p_what, int p_pointer, const Vector<TouchPos> { //send mouse - InputEvent ev; - ev.type = InputEvent::MOUSE_BUTTON; - ev.ID = last_id++; - ev.mouse_button.button_index = BUTTON_LEFT; - ev.mouse_button.button_mask = BUTTON_MASK_LEFT; - ev.mouse_button.pressed = true; - ev.mouse_button.x = touch[0].pos.x; - ev.mouse_button.y = touch[0].pos.y; - ev.mouse_button.global_x = touch[0].pos.x; - ev.mouse_button.global_y = touch[0].pos.y; + Ref<InputEventMouseButton> ev; + ev.instance(); + // ev.type = Ref<InputEvent>::MOUSE_BUTTON; + ev->set_button_index(BUTTON_LEFT); + ev->set_button_mask(BUTTON_MASK_LEFT); + ev->set_pressed(true); + ev->set_position(touch[0].pos); + ev->set_global_position(touch[0].pos); + input->set_mouse_position(Point2(touch[0].pos.x, touch[0].pos.y)); last_mouse = touch[0].pos; input->parse_input_event(ev); } @@ -428,13 +420,11 @@ void OS_Android::process_touch(int p_what, int p_pointer, const Vector<TouchPos> //send touch for (int i = 0; i < touch.size(); i++) { - InputEvent ev; - ev.type = InputEvent::SCREEN_TOUCH; - ev.ID = last_id++; - ev.screen_touch.index = touch[i].id; - ev.screen_touch.pressed = true; - ev.screen_touch.x = touch[i].pos.x; - ev.screen_touch.y = touch[i].pos.y; + Ref<InputEventScreenTouch> ev; + ev.instance(); + ev->set_index(touch[i].id); + ev->set_pressed(true); + ev->set_position(touch[i].pos); input->parse_input_event(ev); } @@ -443,17 +433,13 @@ void OS_Android::process_touch(int p_what, int p_pointer, const Vector<TouchPos> if (p_points.size()) { //send mouse, should look for point 0? - InputEvent ev; - ev.type = InputEvent::MOUSE_MOTION; - ev.ID = last_id++; - ev.mouse_motion.button_mask = BUTTON_MASK_LEFT; - ev.mouse_motion.x = p_points[0].pos.x; - ev.mouse_motion.y = p_points[0].pos.y; - input->set_mouse_pos(Point2(ev.mouse_motion.x, ev.mouse_motion.y)); - ev.mouse_motion.speed_x = input->get_last_mouse_speed().x; - ev.mouse_motion.speed_y = input->get_last_mouse_speed().y; - ev.mouse_motion.relative_x = p_points[0].pos.x - last_mouse.x; - ev.mouse_motion.relative_y = p_points[0].pos.y - last_mouse.y; + Ref<InputEventMouseMotion> ev; + ev.instance(); + ev->set_button_mask(BUTTON_MASK_LEFT); + ev->set_position(p_points[0].pos); + input->set_mouse_position(Point2(ev->get_position().x, ev->get_position().y)); + ev->set_speed(input->get_last_mouse_speed()); + ev->set_relative(p_points[0].pos - last_mouse); last_mouse = p_points[0].pos; input->parse_input_event(ev); } @@ -476,14 +462,11 @@ void OS_Android::process_touch(int p_what, int p_pointer, const Vector<TouchPos> if (touch[i].pos == p_points[idx].pos) continue; //no move unncesearily - InputEvent ev; - ev.type = InputEvent::SCREEN_DRAG; - ev.ID = last_id++; - ev.screen_drag.index = touch[i].id; - ev.screen_drag.x = p_points[idx].pos.x; - ev.screen_drag.y = p_points[idx].pos.y; - ev.screen_drag.relative_x = p_points[idx].pos.x - touch[i].pos.x; - ev.screen_drag.relative_y = p_points[idx].pos.y - touch[i].pos.y; + Ref<InputEventScreenDrag> ev; + ev.instance(); + ev->set_index(touch[i].id); + ev->set_position(p_points[idx].pos); + ev->set_relative(p_points[idx].pos - touch[i].pos); input->parse_input_event(ev); touch[i].pos = p_points[idx].pos; } @@ -493,27 +476,23 @@ void OS_Android::process_touch(int p_what, int p_pointer, const Vector<TouchPos> if (touch.size()) { //end all if exist - InputEvent ev; - ev.type = InputEvent::MOUSE_BUTTON; - ev.ID = last_id++; - ev.mouse_button.button_index = BUTTON_LEFT; - ev.mouse_button.button_mask = BUTTON_MASK_LEFT; - ev.mouse_button.pressed = false; - ev.mouse_button.x = touch[0].pos.x; - ev.mouse_button.y = touch[0].pos.y; - ev.mouse_button.global_x = touch[0].pos.x; - ev.mouse_button.global_y = touch[0].pos.y; + Ref<InputEventMouseButton> ev; + ev.instance(); + ev->set_button_index(BUTTON_LEFT); + ev->set_button_mask(BUTTON_MASK_LEFT); + ev->set_pressed(false); + ev->set_position(touch[0].pos); + ev->set_global_position(touch[0].pos); + input->set_mouse_position(Point2(touch[0].pos.x, touch[0].pos.y)); input->parse_input_event(ev); for (int i = 0; i < touch.size(); i++) { - InputEvent ev; - ev.type = InputEvent::SCREEN_TOUCH; - ev.ID = last_id++; - ev.screen_touch.index = touch[i].id; - ev.screen_touch.pressed = false; - ev.screen_touch.x = touch[i].pos.x; - ev.screen_touch.y = touch[i].pos.y; + Ref<InputEventScreenTouch> ev; + ev.instance(); + ev->set_index(touch[i].id); + ev->set_pressed(false); + ev->set_position(touch[i].pos); input->parse_input_event(ev); } touch.clear(); @@ -527,13 +506,12 @@ void OS_Android::process_touch(int p_what, int p_pointer, const Vector<TouchPos> TouchPos tp = p_points[p_pointer]; touch.push_back(tp); - InputEvent ev; - ev.type = InputEvent::SCREEN_TOUCH; - ev.ID = last_id++; - ev.screen_touch.index = tp.id; - ev.screen_touch.pressed = true; - ev.screen_touch.x = tp.pos.x; - ev.screen_touch.y = tp.pos.y; + Ref<InputEventScreenTouch> ev; + ev.instance(); + + ev->set_index(tp.id); + ev->set_pressed(true); + ev->set_position(tp.pos); input->parse_input_event(ev); } break; @@ -542,13 +520,11 @@ void OS_Android::process_touch(int p_what, int p_pointer, const Vector<TouchPos> for (int i = 0; i < touch.size(); i++) { if (touch[i].id == p_pointer) { - InputEvent ev; - ev.type = InputEvent::SCREEN_TOUCH; - ev.ID = last_id++; - ev.screen_touch.index = touch[i].id; - ev.screen_touch.pressed = false; - ev.screen_touch.x = touch[i].pos.x; - ev.screen_touch.y = touch[i].pos.y; + Ref<InputEventScreenTouch> ev; + ev.instance(); + ev->set_index(touch[i].id); + ev->set_pressed(false); + ev->set_position(touch[i].pos); input->parse_input_event(ev); touch.remove(i); i--; @@ -629,8 +605,8 @@ void OS_Android::reload_gfx() { if (gfx_init_func) gfx_init_func(gfx_init_ud, use_gl2); - if (rasterizer) - rasterizer->reload_vram(); + //if (rasterizer) + // rasterizer->reload_vram(); } Error OS_Android::shell_open(String p_uri) { @@ -748,9 +724,9 @@ void OS_Android::native_video_stop() { void OS_Android::set_context_is_16_bits(bool p_is_16) { - use_16bits_fbo = p_is_16; - if (rasterizer) - rasterizer->set_force_16_bits_fbo(p_is_16); + //use_16bits_fbo = p_is_16; + //if (rasterizer) + // rasterizer->set_force_16_bits_fbo(p_is_16); } void OS_Android::joy_connection_changed(int p_device, bool p_connected, String p_name) { @@ -776,9 +752,8 @@ OS_Android::OS_Android(GFXInitFunc p_gfx_init_func, void *p_gfx_init_ud, OpenURI gfx_init_func = p_gfx_init_func; gfx_init_ud = p_gfx_init_ud; main_loop = NULL; - last_id = 1; gl_extensions = NULL; - rasterizer = NULL; + //rasterizer = NULL; use_gl2 = false; open_uri_func = p_open_uri_func; diff --git a/platform/android/os_android.h b/platform/android/os_android.h index 2c0be8e3c1..897c71a7df 100644 --- a/platform/android/os_android.h +++ b/platform/android/os_android.h @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -35,7 +36,7 @@ #include "main/input_default.h" #include "os/input.h" #include "os/main_loop.h" -#include "power_android.h" +//#include "power_android.h" #include "servers/audio_server.h" #include "servers/physics/physics_server_sw.h" #include "servers/physics_2d/physics_2d_server_sw.h" @@ -94,7 +95,6 @@ private: Vector<TouchPos> touch; Point2 last_mouse; - unsigned int last_id; GFXInitFunc gfx_init_func; void *gfx_init_ud; @@ -104,7 +104,6 @@ private: bool use_16bits_fbo; - Rasterizer *rasterizer; VisualServer *visual_server; PhysicsServer *physics_server; Physics2DServer *physics_2d_server; @@ -141,7 +140,7 @@ private: SetKeepScreenOnFunc set_keep_screen_on_func; AlertFunc alert_func; - power_android *power_manager; + //power_android *power_manager; public: // functions used by main to initialize/deintialize the OS @@ -172,7 +171,7 @@ public: virtual void set_mouse_show(bool p_show); virtual void set_mouse_grab(bool p_grab); virtual bool is_mouse_grab_enabled() const; - virtual Point2 get_mouse_pos() const; + virtual Point2 get_mouse_position() const; virtual int get_mouse_button_state() const; virtual void set_window_title(const String &p_title); @@ -232,7 +231,7 @@ public: void process_gyroscope(const Vector3 &p_gyroscope); void process_touch(int p_what, int p_pointer, const Vector<TouchPos> &p_points); void process_joy_event(JoypadEvent p_event); - void process_event(InputEvent p_event); + void process_event(Ref<InputEvent> p_event); void init_video_mode(int p_video_width, int p_video_height); virtual Error native_video_play(String p_path, float p_volume); diff --git a/platform/android/platform_config.h b/platform/android/platform_config.h index cdef185ff0..48bcadcc29 100644 --- a/platform/android/platform_config.h +++ b/platform/android/platform_config.h @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/android/power_android.cpp b/platform/android/power_android.cpp index aa37dc51e2..bb5a1db250 100644 --- a/platform/android/power_android.cpp +++ b/platform/android/power_android.cpp @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -27,10 +28,35 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "core/error_macros.h" +/* +Adapted from corresponding SDL 2.0 code. +*/ + +/* + Simple DirectMedia Layer + Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org> + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ #include "power_android.h" +#include "core/error_macros.h" + static void LocalReferenceHolder_Cleanup(struct LocalReferenceHolder *refholder) { if (refholder->m_env) { JNIEnv *env = refholder->m_env; diff --git a/platform/android/power_android.h b/platform/android/power_android.h index df4983bbf3..328a4506a1 100644 --- a/platform/android/power_android.h +++ b/platform/android/power_android.h @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/android/run_icon.png b/platform/android/run_icon.png Binary files differnew file mode 100644 index 0000000000..e53f8e9da5 --- /dev/null +++ b/platform/android/run_icon.png diff --git a/platform/android/thread_jandroid.cpp b/platform/android/thread_jandroid.cpp index 854cdb1e34..401f3cd73b 100644 --- a/platform/android/thread_jandroid.cpp +++ b/platform/android/thread_jandroid.cpp @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/android/thread_jandroid.h b/platform/android/thread_jandroid.h index a8d8a4d8b1..6174066968 100644 --- a/platform/android/thread_jandroid.h +++ b/platform/android/thread_jandroid.h @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/bb10/SCsub b/platform/bb10/SCsub deleted file mode 100644 index c19f46d579..0000000000 --- a/platform/bb10/SCsub +++ /dev/null @@ -1,23 +0,0 @@ -#!/usr/bin/env python - -Import('env') - -bb10_lib = [ - - 'bbutil.c', - 'os_bb10.cpp', - 'audio_driver_bb10.cpp', - 'godot_bb10.cpp', - 'payment_service.cpp', -] - -env_bps = env.Clone() -if env['bb10_payment_service'] == "yes": - env_bps.Append(CPPFLAGS=['-DPAYMENT_SERVICE_ENABLED']) - -if env['bb10_lgles_override'] == "yes": - env_bps.Append(CPPFLAGS=['-DBB10_LGLES_OVERRIDE']) - - -prog = None -prog = env_bps.Program('#bin/godot', bb10_lib) diff --git a/platform/bb10/audio_driver_bb10.cpp b/platform/bb10/audio_driver_bb10.cpp deleted file mode 100644 index 5416fc5f02..0000000000 --- a/platform/bb10/audio_driver_bb10.cpp +++ /dev/null @@ -1,253 +0,0 @@ -/*************************************************************************/ -/* audio_driver_bb10.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* http://www.godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ -#include "audio_driver_bb10.h" - -#include <errno.h> - -Error AudioDriverBB10::init() { - return init(NULL); -}; - -Error AudioDriverBB10::init(const char *p_name) { - - active = false; - thread_exited = false; - exit_thread = false; - pcm_open = false; - samples_in = NULL; - samples_out = NULL; - - mix_rate = 44100; - speaker_mode = SPEAKER_MODE_STEREO; - - char *dev_name; - if (p_name == NULL) { - dev_name = "pcmPreferred"; - } else { - dev_name = (char *)p_name; - } - printf("******** reconnecting to device %s\n", dev_name); - int ret = snd_pcm_open_name(&pcm_handle, dev_name, SND_PCM_OPEN_PLAYBACK); - ERR_FAIL_COND_V(ret < 0, FAILED); - pcm_open = true; - - snd_pcm_channel_info_t cinfo; - zeromem(&cinfo, sizeof(cinfo)); - cinfo.channel = SND_PCM_CHANNEL_PLAYBACK; - snd_pcm_plugin_info(pcm_handle, &cinfo); - - printf("rates %i, %i, %i, %i, %i\n", cinfo.rates, cinfo.rates & SND_PCM_RATE_44100, cinfo.rates & SND_PCM_RATE_32000, cinfo.rates & SND_PCM_RATE_22050, cinfo.max_rate); - - mix_rate = cinfo.max_rate; - - printf("formats %i, %i, %i\n", cinfo.formats, cinfo.formats & SND_PCM_FMT_S16_BE, cinfo.formats & SND_PCM_FMT_S16_LE); - ERR_FAIL_COND_V(!(cinfo.formats & SND_PCM_FMT_S16_LE), FAILED); - - printf("voices %i\n", cinfo.max_voices); - speaker_mode = SPEAKER_MODE_STEREO; - - snd_pcm_channel_params_t cp; - zeromem(&cp, sizeof(cp)); - cp.mode = SND_PCM_MODE_BLOCK; - cp.channel = SND_PCM_CHANNEL_PLAYBACK; - cp.start_mode = SND_PCM_START_DATA; - cp.stop_mode = SND_PCM_STOP_STOP; - //cp.buf.block.frag_size = cinfo.max_fragment_size; - cp.buf.block.frag_size = 512; - cp.buf.block.frags_max = 1; - cp.buf.block.frags_min = 1; - cp.format.interleave = 1; - cp.format.rate = mix_rate; - cp.format.voices = speaker_mode; - cp.format.format = SND_PCM_SFMT_S16_LE; - - ret = snd_pcm_plugin_params(pcm_handle, &cp); - printf("ret is %i, %i\n", ret, cp.why_failed); - ERR_FAIL_COND_V(ret < 0, FAILED); - - ret = snd_pcm_plugin_prepare(pcm_handle, SND_PCM_CHANNEL_PLAYBACK); - ERR_FAIL_COND_V(ret < 0, FAILED); - - snd_mixer_group_t group; - zeromem(&group, sizeof(group)); - snd_pcm_channel_setup_t setup; - zeromem(&setup, sizeof(setup)); - setup.channel = SND_PCM_CHANNEL_PLAYBACK; - setup.mode = SND_PCM_MODE_BLOCK; - setup.mixer_gid = &group.gid; - ret = snd_pcm_plugin_setup(pcm_handle, &setup); - ERR_FAIL_COND_V(ret < 0, FAILED); - - pcm_frag_size = setup.buf.block.frag_size; - pcm_max_frags = 1; - - sample_buf_count = pcm_frag_size * pcm_max_frags / 2; - printf("sample count %i, %i, %i\n", sample_buf_count, pcm_frag_size, pcm_max_frags); - samples_in = memnew_arr(int32_t, sample_buf_count); - samples_out = memnew_arr(int16_t, sample_buf_count); - - thread = Thread::create(AudioDriverBB10::thread_func, this); - - return OK; -}; - -void AudioDriverBB10::thread_func(void *p_udata) { - - AudioDriverBB10 *ad = (AudioDriverBB10 *)p_udata; - - int channels = speaker_mode; - int frame_count = ad->sample_buf_count / channels; - int bytes_out = frame_count * channels * 2; - - while (!ad->exit_thread) { - - if (!ad->active) { - - for (int i = 0; i < ad->sample_buf_count; i++) { - - ad->samples_out[i] = 0; - }; - } else { - - ad->lock(); - - ad->audio_server_process(frame_count, ad->samples_in); - - ad->unlock(); - - for (int i = 0; i < frame_count * channels; i++) { - - ad->samples_out[i] = ad->samples_in[i] >> 16; - } - }; - - int todo = bytes_out; - int total = 0; - - while (todo) { - - uint8_t *src = (uint8_t *)ad->samples_out; - int wrote = snd_pcm_plugin_write(ad->pcm_handle, (void *)(src + total), todo); - if (wrote < 0) { - // error? - break; - }; - total += wrote; - todo -= wrote; - if (wrote < todo) { - if (ad->thread_exited) { - break; - }; - printf("pcm_write underrun %i, errno %i\n", (int)ad->thread_exited, errno); - snd_pcm_channel_status_t status; - zeromem(&status, sizeof(status)); - // put in non-blocking mode - snd_pcm_nonblock_mode(ad->pcm_handle, 1); - status.channel = SND_PCM_CHANNEL_PLAYBACK; - int ret = snd_pcm_plugin_status(ad->pcm_handle, &status); - //printf("status return %i, %i, %i, %i, %i\n", ret, errno, status.status, SND_PCM_STATUS_READY, SND_PCM_STATUS_UNDERRUN); - snd_pcm_nonblock_mode(ad->pcm_handle, 0); - if (ret < 0) { - break; - }; - if (status.status == SND_PCM_STATUS_READY || - status.status == SND_PCM_STATUS_UNDERRUN) { - snd_pcm_plugin_prepare(ad->pcm_handle, SND_PCM_CHANNEL_PLAYBACK); - } else { - break; - }; - }; - }; - }; - - snd_pcm_plugin_flush(ad->pcm_handle, SND_PCM_CHANNEL_PLAYBACK); - - ad->thread_exited = true; - printf("**************** audio thread exit\n"); -}; - -void AudioDriverBB10::start() { - - active = true; -}; - -int AudioDriverBB10::get_mix_rate() const { - - return mix_rate; -}; - -AudioDriver::SpeakerMode AudioDriverBB10::get_speaker_mode() const { - - return speaker_mode; -}; - -void AudioDriverBB10::lock() { - - if (!thread) - return; - mutex->lock(); -}; - -void AudioDriverBB10::unlock() { - - if (!thread) - return; - mutex->unlock(); -}; - -void AudioDriverBB10::finish() { - - if (!thread) - return; - - exit_thread = true; - Thread::wait_to_finish(thread); - - if (pcm_open) - snd_pcm_close(pcm_handle); - - if (samples_in) { - memdelete_arr(samples_in); - memdelete_arr(samples_out); - }; - - memdelete(thread); - thread = NULL; -}; - -AudioDriverBB10::AudioDriverBB10() { - - mutex = Mutex::create(); -}; - -AudioDriverBB10::~AudioDriverBB10() { - - memdelete(mutex); - mutex = NULL; -}; diff --git a/platform/bb10/audio_driver_bb10.h b/platform/bb10/audio_driver_bb10.h deleted file mode 100644 index 2a0ed9c545..0000000000 --- a/platform/bb10/audio_driver_bb10.h +++ /dev/null @@ -1,76 +0,0 @@ -/*************************************************************************/ -/* audio_driver_bb10.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* http://www.godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ -#include "servers/audio_server.h" - -#include "core/os/mutex.h" -#include "core/os/thread.h" - -#include <sys/asoundlib.h> - -class AudioDriverBB10 : public AudioDriver { - - Thread *thread; - Mutex *mutex; - - snd_pcm_t *pcm_handle; - - int32_t *samples_in; - int16_t *samples_out; - int sample_buf_count; - - static void thread_func(void *p_udata); - - int mix_rate; - SpeakerMode speaker_mode; - - int pcm_frag_size; - int pcm_max_frags; - - bool active; - bool thread_exited; - mutable bool exit_thread; - bool pcm_open; - -public: - const char *get_name() const { - return "BB10"; - }; - - virtual Error init(); - virtual Error init(const char *p_name); - virtual void start(); - virtual int get_mix_rate() const; - virtual SpeakerMode get_speaker_mode() const; - virtual void lock(); - virtual void unlock(); - virtual void finish(); - - AudioDriverBB10(); - ~AudioDriverBB10(); -}; diff --git a/platform/bb10/bar/bar-descriptor.xml b/platform/bb10/bar/bar-descriptor.xml deleted file mode 100644 index 0ba70b7180..0000000000 --- a/platform/bb10/bar/bar-descriptor.xml +++ /dev/null @@ -1,53 +0,0 @@ -<?xml version='1.0' encoding='utf-8' standalone='no'?> -<qnx xmlns="http://www.qnx.com/schemas/application/1.0"> - <!-- BlackBerry® 10 application descriptor file. - - Specifies parameters for identifying, installing, and launching native applications on BlackBerry® 10 OS. ---> - <!-- A universally unique application identifier. Must be unique across all BlackBerry applications. - Using a reverse DNS-style name as the id is recommended. (Eg. com.example.ExampleApplication.) Required. --> - <id>com.godot.game</id> - <!-- The name that is displayed in the BlackBerry application installer. - May have multiple values for each language. See samples or xsd schema file. Optional. --> - <name>Godot Game</name> - <!-- A string value of the format <0-999>.<0-999>.<0-999> that represents application version which can be used to check for application upgrade. - Values can also be 1-part or 2-part. It is not necessary to have a 3-part value. - An updated version of application must have a versionNumber value higher than the previous version. Required. --> - <versionNumber>0.0.1</versionNumber> - <!-- Fourth digit segment of the package version. First three segments are taken from the - <versionNumber> element. Must be an integer from 0 to 2^16-1 --> - <buildId>0</buildId> - <!-- Description, displayed in the BlackBerry application installer. - May have multiple values for each language. See samples or xsd schema file. Optional. --> - <description>Game made with Godot Engine</description> - <!-- Name of author which is used for signing. Must match the developer name of your development certificate. --> - <author>You Name or Company</author> - <authorId>authorIDherePlease</authorId> - <!-- Unique author ID assigned by signing authority. Required if using debug tokens. --> - <!-- <authorId>ABC1234YjsnUk235h</authorId> --> - <initialWindow> - <aspectRatio>landscape</aspectRatio> - <autoOrients>false</autoOrients> - <systemChrome>none</systemChrome> - <transparent>false</transparent> - </initialWindow> - <!-- The category where the application appears. Either core.games or core.media. --> - <category>core.games</category> - <permission>read_device_identifying_information</permission> - <permission>access_internet</permission> - <asset path="data.pck">data.pck</asset> - <configuration name="Device-Debug"> - <platformArchitecture>armle-v7</platformArchitecture> - <asset type="Qnx/Elf" path="godot.bb10.debug.qnx.armle" entry="true">godot.bb10.debug.qnx.armle</asset> - </configuration> - <configuration name="Device-Release"> - <platformArchitecture>armle-v7</platformArchitecture> - <asset type="Qnx/Elf" path="godot.bb10.opt.qnx.armle" entry="true">godot.bb10.opt.qnx.armle</asset> - </configuration> - <!-- The icon for the application. --> - <icon> - <image>icon.png</image> - </icon> - <!-- Ensure that shared libraries in the package are found at run-time. --> - <env value="app/native/lib:/usr/lib/qt4/lib" var="LD_LIBRARY_PATH"/> -</qnx> diff --git a/platform/bb10/bar/icon.png b/platform/bb10/bar/icon.png Binary files differdeleted file mode 100644 index 2161402438..0000000000 --- a/platform/bb10/bar/icon.png +++ /dev/null diff --git a/platform/bb10/bbutil.c b/platform/bb10/bbutil.c deleted file mode 100644 index ab3dcf69b2..0000000000 --- a/platform/bb10/bbutil.c +++ /dev/null @@ -1,513 +0,0 @@ -#include <assert.h> -#include <ctype.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sys/keycodes.h> -#include <time.h> - -#include "bbutil.h" - -EGLDisplay egl_disp; -EGLSurface egl_surf; - -static EGLConfig egl_conf; -static EGLContext egl_ctx; - -static screen_context_t screen_ctx; -static screen_window_t screen_win; -static screen_display_t screen_disp; - - -static void -bbutil_egl_perror(const char *msg) { - static const char *errmsg[] = { - "function succeeded", - "EGL is not initialized, or could not be initialized, for the specified display", - "cannot access a requested resource", - "failed to allocate resources for the requested operation", - "an unrecognized attribute or attribute value was passed in an attribute list", - "an EGLConfig argument does not name a valid EGLConfig", - "an EGLContext argument does not name a valid EGLContext", - "the current surface of the calling thread is no longer valid", - "an EGLDisplay argument does not name a valid EGLDisplay", - "arguments are inconsistent", - "an EGLNativePixmapType argument does not refer to a valid native pixmap", - "an EGLNativeWindowType argument does not refer to a valid native window", - "one or more argument values are invalid", - "an EGLSurface argument does not name a valid surface configured for rendering", - "a power management event has occurred", - }; - - fprintf(stderr, "%s: %s\n", msg, errmsg[eglGetError() - EGL_SUCCESS]); -} -EGLConfig bbutil_choose_config(EGLDisplay egl_disp, enum RENDERING_API api) { - EGLConfig egl_conf = (EGLConfig)0; - EGLConfig *egl_configs; - EGLint egl_num_configs; - EGLint val; - EGLBoolean rc; - EGLint i; - - rc = eglGetConfigs(egl_disp, NULL, 0, &egl_num_configs); - if (rc != EGL_TRUE) { - bbutil_egl_perror("eglGetConfigs"); - return egl_conf; - } - if (egl_num_configs == 0) { - fprintf(stderr, "eglGetConfigs: could not find a configuration\n"); - return egl_conf; - } - - egl_configs = malloc(egl_num_configs * sizeof(*egl_configs)); - if (egl_configs == NULL) { - fprintf(stderr, "could not allocate memory for %d EGL configs\n", egl_num_configs); - return egl_conf; - } - - rc = eglGetConfigs(egl_disp, egl_configs, - egl_num_configs, &egl_num_configs); - if (rc != EGL_TRUE) { - bbutil_egl_perror("eglGetConfigs"); - free(egl_configs); - return egl_conf; - } - - for (i = 0; i < egl_num_configs; i++) { - eglGetConfigAttrib(egl_disp, egl_configs[i], EGL_SURFACE_TYPE, &val); - if (!(val & EGL_WINDOW_BIT)) { - continue; - } - - eglGetConfigAttrib(egl_disp, egl_configs[i], EGL_RENDERABLE_TYPE, &val); - if (!(val & api)) { - continue; - } - - eglGetConfigAttrib(egl_disp, egl_configs[i], EGL_DEPTH_SIZE, &val); - if ((api & (GL_ES_1|GL_ES_2)) && (val == 0)) { - continue; - } - - eglGetConfigAttrib(egl_disp, egl_configs[i], EGL_RED_SIZE, &val); - if (val != 8) { - continue; - } - eglGetConfigAttrib(egl_disp, egl_configs[i], EGL_GREEN_SIZE, &val); - if (val != 8) { - continue; - } - - eglGetConfigAttrib(egl_disp, egl_configs[i], EGL_BLUE_SIZE, &val); - if (val != 8) { - continue; - } - - eglGetConfigAttrib(egl_disp, egl_configs[i], EGL_BUFFER_SIZE, &val); - if (val != 32) { - continue; - } - - egl_conf = egl_configs[i]; - break; - } - - free(egl_configs); - - if (egl_conf == (EGLConfig)0) { - fprintf(stderr, "bbutil_choose_config: could not find a matching configuration\n"); - } - - return egl_conf; -} - -int -bbutil_init_egl(screen_context_t ctx, enum RENDERING_API api) { - int usage; - int format = SCREEN_FORMAT_RGBX8888; - int nbuffers = 2; - EGLint interval = 1; - int rc; - EGLint attributes[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE }; - - if (api == GL_ES_1) { - usage = SCREEN_USAGE_OPENGL_ES1 | SCREEN_USAGE_ROTATION; - } else if (api == GL_ES_2) { - usage = SCREEN_USAGE_OPENGL_ES2 | SCREEN_USAGE_ROTATION; - } else if (api == VG) { - usage = SCREEN_USAGE_OPENVG | SCREEN_USAGE_ROTATION; - } else { - fprintf(stderr, "invalid api setting\n"); - return EXIT_FAILURE; - } - - //Simple egl initialization - screen_ctx = ctx; - - egl_disp = eglGetDisplay(EGL_DEFAULT_DISPLAY); - if (egl_disp == EGL_NO_DISPLAY) { - bbutil_egl_perror("eglGetDisplay"); - bbutil_terminate(); - return EXIT_FAILURE; - } - - rc = eglInitialize(egl_disp, NULL, NULL); - if (rc != EGL_TRUE) { - bbutil_egl_perror("eglInitialize"); - bbutil_terminate(); - return EXIT_FAILURE; - } - - if ((api == GL_ES_1) || (api == GL_ES_2)) { - rc = eglBindAPI(EGL_OPENGL_ES_API); - } else if (api == VG) { - rc = eglBindAPI(EGL_OPENVG_API); - } - - if (rc != EGL_TRUE) { - bbutil_egl_perror("eglBindApi"); - bbutil_terminate(); - return EXIT_FAILURE; - } - - egl_conf = bbutil_choose_config(egl_disp, api); - if (egl_conf == (EGLConfig)0) { - bbutil_terminate(); - return EXIT_FAILURE; - } - - if (api == GL_ES_2) { - egl_ctx = eglCreateContext(egl_disp, egl_conf, EGL_NO_CONTEXT, attributes); - } else { - egl_ctx = eglCreateContext(egl_disp, egl_conf, EGL_NO_CONTEXT, NULL); - } - - if (egl_ctx == EGL_NO_CONTEXT) { - bbutil_egl_perror("eglCreateContext"); - bbutil_terminate(); - return EXIT_FAILURE; - } - - rc = screen_create_window(&screen_win, screen_ctx); - if (rc) { - perror("screen_create_window"); - bbutil_terminate(); - return EXIT_FAILURE; - } - - rc = screen_set_window_property_iv(screen_win, SCREEN_PROPERTY_FORMAT, &format); - if (rc) { - perror("screen_set_window_property_iv(SCREEN_PROPERTY_FORMAT)"); - bbutil_terminate(); - return EXIT_FAILURE; - } - - rc = screen_set_window_property_iv(screen_win, SCREEN_PROPERTY_USAGE, &usage); - if (rc) { - perror("screen_set_window_property_iv(SCREEN_PROPERTY_USAGE)"); - bbutil_terminate(); - return EXIT_FAILURE; - } - - rc = screen_get_window_property_pv(screen_win, SCREEN_PROPERTY_DISPLAY, (void **)&screen_disp); - if (rc) { - perror("screen_get_window_property_pv"); - bbutil_terminate(); - return EXIT_FAILURE; - } - - int screen_resolution[2]; - - rc = screen_get_display_property_iv(screen_disp, SCREEN_PROPERTY_SIZE, screen_resolution); - if (rc) { - perror("screen_get_display_property_iv"); - bbutil_terminate(); - return EXIT_FAILURE; - } - - int angle = atoi(getenv("ORIENTATION")); - - screen_display_mode_t screen_mode; - rc = screen_get_display_property_pv(screen_disp, SCREEN_PROPERTY_MODE, (void**)&screen_mode); - if (rc) { - perror("screen_get_display_property_pv"); - bbutil_terminate(); - return EXIT_FAILURE; - } - - int size[2]; - rc = screen_get_window_property_iv(screen_win, SCREEN_PROPERTY_BUFFER_SIZE, size); - if (rc) { - perror("screen_get_window_property_iv"); - bbutil_terminate(); - return EXIT_FAILURE; - } - - int buffer_size[2] = {size[0], size[1]}; - - if ((angle == 0) || (angle == 180)) { - if (((screen_mode.width > screen_mode.height) && (size[0] < size[1])) || - ((screen_mode.width < screen_mode.height) && (size[0] > size[1]))) { - buffer_size[1] = size[0]; - buffer_size[0] = size[1]; - } - } else if ((angle == 90) || (angle == 270)){ - if (((screen_mode.width > screen_mode.height) && (size[0] > size[1])) || - ((screen_mode.width < screen_mode.height && size[0] < size[1]))) { - buffer_size[1] = size[0]; - buffer_size[0] = size[1]; - } - } else { - fprintf(stderr, "Navigator returned an unexpected orientation angle.\n"); - bbutil_terminate(); - return EXIT_FAILURE; - } - - rc = screen_set_window_property_iv(screen_win, SCREEN_PROPERTY_BUFFER_SIZE, buffer_size); - if (rc) { - perror("screen_set_window_property_iv"); - bbutil_terminate(); - return EXIT_FAILURE; - } - - rc = screen_set_window_property_iv(screen_win, SCREEN_PROPERTY_ROTATION, &angle); - if (rc) { - perror("screen_set_window_property_iv"); - bbutil_terminate(); - return EXIT_FAILURE; - } - - rc = screen_create_window_buffers(screen_win, nbuffers); - if (rc) { - perror("screen_create_window_buffers"); - bbutil_terminate(); - return EXIT_FAILURE; - } - - rc = screen_create_window_group(screen_win, get_window_group_id()); - if (rc) { - perror("screen_create_window_group"); - bbutil_terminate(); - return EXIT_FAILURE; - } - /* if (screen_create_window_group(screen_win, get_window_group_id()) != 0) goto fail; */ - - int idle_mode = SCREEN_IDLE_MODE_KEEP_AWAKE; - screen_set_window_property_iv(screen_win, SCREEN_PROPERTY_IDLE_MODE, &idle_mode); - - egl_surf = eglCreateWindowSurface(egl_disp, egl_conf, screen_win, NULL); - if (egl_surf == EGL_NO_SURFACE) { - bbutil_egl_perror("eglCreateWindowSurface"); - bbutil_terminate(); - return EXIT_FAILURE; - } - - rc = eglMakeCurrent(egl_disp, egl_surf, egl_surf, egl_ctx); - if (rc != EGL_TRUE) { - bbutil_egl_perror("eglMakeCurrent"); - bbutil_terminate(); - return EXIT_FAILURE; - } - - rc = eglSwapInterval(egl_disp, interval); - if (rc != EGL_TRUE) { - bbutil_egl_perror("eglSwapInterval"); - bbutil_terminate(); - return EXIT_FAILURE; - } - - return EXIT_SUCCESS; -} - -int -bbutil_init_gl2d() { -#if 0 - EGLint surface_width, surface_height; - - if ((egl_disp == EGL_NO_DISPLAY) || (egl_surf == EGL_NO_SURFACE) ){ - return EXIT_FAILURE; - } - - eglQuerySurface(egl_disp, egl_surf, EGL_WIDTH, &surface_width); - eglQuerySurface(egl_disp, egl_surf, EGL_HEIGHT, &surface_height); - - glShadeModel(GL_SMOOTH); - - glClearColor(1.0f, 1.0f, 1.0f, 1.0f); - - glViewport(0, 0, surface_width, surface_height); - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - - glOrthof(0.0f, (float)(surface_width) / (float)(surface_height), 0.0f, 1.0f, -1.0f, 1.0f); - - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); -#endif - - return EXIT_SUCCESS; -} - -int -bbutil_init(screen_context_t ctx, enum RENDERING_API api) { - if (EXIT_SUCCESS != bbutil_init_egl(ctx, api)) { - return EXIT_FAILURE; - } - - if ((GL_ES_1 == api) && (EXIT_SUCCESS != bbutil_init_gl2d())) { - return EXIT_FAILURE; - } - - return EXIT_SUCCESS; -} - -int bbutil_is_flipped() { - - int ret; - screen_get_window_property_iv(screen_win, SCREEN_PROPERTY_FLIP, &ret); - return ret; -}; - -int bbutil_get_rotation() { - - int ret; - screen_get_window_property_iv(screen_win, SCREEN_PROPERTY_ROTATION, &ret); - return ret; -}; - - -void -bbutil_terminate() { - //Typical EGL cleanup - if (egl_disp != EGL_NO_DISPLAY) { - eglMakeCurrent(egl_disp, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); - if (egl_surf != EGL_NO_SURFACE) { - eglDestroySurface(egl_disp, egl_surf); - egl_surf = EGL_NO_SURFACE; - } - if (egl_ctx != EGL_NO_CONTEXT) { - eglDestroyContext(egl_disp, egl_ctx); - egl_ctx = EGL_NO_CONTEXT; - } - if (screen_win != NULL) { - screen_destroy_window(screen_win); - screen_win = NULL; - } - eglTerminate(egl_disp); - egl_disp = EGL_NO_DISPLAY; - } - eglReleaseThread(); -} - -void -bbutil_swap() { - int rc = eglSwapBuffers(egl_disp, egl_surf); - if (rc != EGL_TRUE) { - bbutil_egl_perror("eglSwapBuffers"); - } -} - -void -bbutil_clear() { - glClear(GL_COLOR_BUFFER_BIT); -} - -char * -get_window_group_id() -{ - static char s_window_group_id[16] = ""; - - if (s_window_group_id[0] == '\0') { - snprintf(s_window_group_id, sizeof(s_window_group_id), "%d", getpid()); - } - - return s_window_group_id; -} - - -int bbutil_rotate_screen_surface(int angle) { - int rc, rotation, skip = 1, temp; - EGLint interval = 1; - int size[2]; - - if ((angle != 0) && (angle != 90) && (angle != 180) && (angle != 270)) { - fprintf(stderr, "Invalid angle\n"); - return EXIT_FAILURE; - } - - rc = screen_get_window_property_iv(screen_win, SCREEN_PROPERTY_ROTATION, &rotation); - if (rc) { - perror("screen_set_window_property_iv"); - return EXIT_FAILURE; - } - - rc = screen_get_window_property_iv(screen_win, SCREEN_PROPERTY_BUFFER_SIZE, size); - if (rc) { - perror("screen_set_window_property_iv"); - return EXIT_FAILURE; - } - - switch (angle - rotation) { - case -270: - case -90: - case 90: - case 270: - temp = size[0]; - size[0] = size[1]; - size[1] = temp; - skip = 0; - break; - } - - if (!skip) { - rc = eglMakeCurrent(egl_disp, NULL, NULL, NULL); - if (rc != EGL_TRUE) { - bbutil_egl_perror("eglMakeCurrent"); - return EXIT_FAILURE; - } - - rc = eglDestroySurface(egl_disp, egl_surf); - if (rc != EGL_TRUE) { - bbutil_egl_perror("eglMakeCurrent"); - return EXIT_FAILURE; - } - - rc = screen_set_window_property_iv(screen_win, SCREEN_PROPERTY_SOURCE_SIZE, size); - if (rc) { - perror("screen_set_window_property_iv"); - return EXIT_FAILURE; - } - - rc = screen_set_window_property_iv(screen_win, SCREEN_PROPERTY_BUFFER_SIZE, size); - if (rc) { - perror("screen_set_window_property_iv"); - return EXIT_FAILURE; - } - egl_surf = eglCreateWindowSurface(egl_disp, egl_conf, screen_win, NULL); - if (egl_surf == EGL_NO_SURFACE) { - bbutil_egl_perror("eglCreateWindowSurface"); - return EXIT_FAILURE; - } - - rc = eglMakeCurrent(egl_disp, egl_surf, egl_surf, egl_ctx); - if (rc != EGL_TRUE) { - bbutil_egl_perror("eglMakeCurrent"); - return EXIT_FAILURE; - } - - rc = eglSwapInterval(egl_disp, interval); - if (rc != EGL_TRUE) { - bbutil_egl_perror("eglSwapInterval"); - return EXIT_FAILURE; - } - } - - rc = screen_set_window_property_iv(screen_win, SCREEN_PROPERTY_ROTATION, &angle); - if (rc) { - perror("screen_set_window_property_iv"); - return EXIT_FAILURE; - } - - return EXIT_SUCCESS; -} - diff --git a/platform/bb10/bbutil.h b/platform/bb10/bbutil.h deleted file mode 100644 index 77f4402fbd..0000000000 --- a/platform/bb10/bbutil.h +++ /dev/null @@ -1,72 +0,0 @@ -#ifndef _UTILITY_H_INCLUDED -#define _UTILITY_H_INCLUDED - -#include <EGL/egl.h> -#include <GLES2/gl2.h> -#include <screen/screen.h> -#include <sys/platform.h> - -#ifdef __cplusplus -extern "C" { -#endif - -extern EGLDisplay egl_disp; -extern EGLSurface egl_surf; - -enum RENDERING_API { - GL_ES_1 = EGL_OPENGL_ES_BIT, - GL_ES_2 = EGL_OPENGL_ES2_BIT, - VG = EGL_OPENVG_BIT -}; - -/** - * Initializes EGL, GL and loads a default font - * - * \param libscreen context that will be used for EGL setup - * \return EXIT_SUCCESS if initialization succeeded otherwise EXIT_FAILURE - */ -int bbutil_init(screen_context_t ctx, enum RENDERING_API api); - -/** - * Initializes EGL - * - * \param libscreen context that will be used for EGL setup - * \return EXIT_SUCCESS if initialization succeeded otherwise EXIT_FAILURE - */ -int bbutil_init_egl(screen_context_t ctx, enum RENDERING_API api); - -/** - * Initializes GL 1.1 for simple 2D rendering. GL2 initialization will be added at a later point. - * - * \return EXIT_SUCCESS if initialization succeeded otherwise EXIT_FAILURE - */ -int bbutil_init_gl2d(); - -int bbutil_is_flipped(); -int bbutil_get_rotation(); - -char *get_window_group_id(); - -int bbutil_rotate_screen_surface(int angle); - -/** - * Terminates EGL - */ -void bbutil_terminate(); - -/** - * Swaps default bbutil window surface to the screen - */ -void bbutil_swap(); - -/** - * Clears the screen of any existing text. - * NOTE: must be called after a successful return from bbutil_init() or bbutil_init_egl() call - */ -void bbutil_clear(); - -#ifdef __cplusplus -}; -#endif - -#endif diff --git a/platform/bb10/detect.py b/platform/bb10/detect.py deleted file mode 100644 index d3ee9f0124..0000000000 --- a/platform/bb10/detect.py +++ /dev/null @@ -1,92 +0,0 @@ -import os -import sys -import string -import methods - - -def is_active(): - return True - - -def get_name(): - return "BlackBerry 10" - - -def can_build(): - - import os - if (not os.environ.has_key("QNX_TARGET")): - return False - return True - - -def get_opts(): - - return [ - ('QNX_HOST', 'path to qnx host', os.environ.get("QNX_HOST", 0)), - ('QNX_TARGET', 'path to qnx target', os.environ.get("QNX_TARGET", 0)), - ('QNX_CONFIGURATION', 'path to qnx configuration', os.environ.get("QNX_CONFIGURATION", 0)), - ('qnx_target', 'Qnx target (armle or x86', 'armle'), - ('bb10_payment_service', 'Enable Payment Service for BlackBerry10', 'yes'), - ('bb10_lgles_override', 'Force legacy GLES (1.1) on iOS', 'no'), - ('bb10_exceptions', 'Use exceptions when compiling on bb10', 'no'), - ] - - -def get_flags(): - - return [ - ('tools', 'no'), - ('module_theora_enabled', 'no'), - ] - - -def configure(env): - - if env['PLATFORM'] == 'win32': - env.Tool('mingw') - env['SPAWN'] = methods.win32_spawn - - env['qnx_target_ver'] = env['qnx_target'] - if env['qnx_target'] == "armle": - env['qnx_prefix'] = 'ntoarmv7' - env['qnx_target_ver'] = 'armle-v7' - else: - env['qnx_prefix'] = 'ntox86' - - env['OBJSUFFIX'] = ".qnx.${qnx_target}.o" - env['LIBSUFFIX'] = ".qnx.${qnx_target}.a" - env['PROGSUFFIX'] = ".qnx.${qnx_target}" - print("PROGSUFFIX: " + env['PROGSUFFIX'] + " target: " + env['qnx_target']) - - env.PrependENVPath('PATH', env['QNX_CONFIGURATION'] + '/bin') - env.PrependENVPath('PATH', env['QNX_CONFIGURATION'] + '/usr/bin') - env['ENV']['QNX_HOST'] = env['QNX_HOST'] - env['ENV']['QNX_TARGET'] = env['QNX_TARGET'] - env['ENV']['QNX_CONFIGURATION'] = env['QNX_CONFIGURATION'] - - env['CC'] = '$qnx_prefix-gcc' - env['CXX'] = '$qnx_prefix-g++' - env['AR'] = '$qnx_prefix-ar' - env['RANLIB'] = '$qnx_prefix-ranlib' - - env.Append(CPPPATH=['#platform/bb10']) - env.Append(LIBPATH=['#platform/bb10/lib/$qnx_target', '#platform/bb10/lib/$qnx_target_ver']) - env.Append(CCFLAGS=string.split('-DBB10_ENABLED -DUNIX_ENABLED -DGLES2_ENABLED -DGLES1_ENABLED -D_LITTLE_ENDIAN -DNO_THREADS -DNO_FCNTL')) - if env['bb10_exceptions'] == "yes": - env.Append(CCFLAGS=['-fexceptions']) - else: - env.Append(CCFLAGS=['-fno-exceptions']) - - # env.Append(LINKFLAGS = string.split() - - if (env["target"] == "release"): - - env.Append(CCFLAGS=['-O3', '-DRELEASE_BUILD']) - - elif (env["target"] == "debug"): - - env.Append(CCFLAGS=['-g', '-O0', '-DDEBUG_ENABLED', '-D_DEBUG']) - env.Append(LINKFLAGS=['-g']) - - env.Append(LIBS=['bps', 'pps', 'screen', 'socket', 'EGL', 'GLESv2', 'GLESv1_CM', 'm', 'asound']) diff --git a/platform/bb10/export/export.cpp b/platform/bb10/export/export.cpp deleted file mode 100644 index c958bf7ff4..0000000000 --- a/platform/bb10/export/export.cpp +++ /dev/null @@ -1,828 +0,0 @@ -/*************************************************************************/ -/* export.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* http://www.godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ -#include "export.h" -#include "editor/editor_export.h" -#include "editor/editor_node.h" -#include "editor/editor_settings.h" -#include "global_config.h" -#include "io/marshalls.h" -#include "io/xml_parser.h" -#include "io/zip_io.h" -#include "os/file_access.h" -#include "os/os.h" -#include "platform/bb10/logo.h" -#include "version.h" - -#define MAX_DEVICES 5 -#if 0 -class EditorExportPlatformBB10 : public EditorExportPlatform { - - GDCLASS( EditorExportPlatformBB10,EditorExportPlatform ); - - String custom_package; - - int version_code; - String version_name; - String package; - String name; - String category; - String description; - String author_name; - String author_id; - String icon; - - - - struct Device { - - int index; - String name; - String description; - }; - - Vector<Device> devices; - bool devices_changed; - Mutex *device_lock; - Thread *device_thread; - Ref<ImageTexture> logo; - - volatile bool quit_request; - - - static void _device_poll_thread(void *ud); - - void _fix_descriptor(Vector<uint8_t>& p_manifest); -protected: - - bool _set(const StringName& p_name, const Variant& p_value); - bool _get(const StringName& p_name,Variant &r_ret) const; - void _get_property_list( List<PropertyInfo> *p_list) const; - -public: - - virtual String get_name() const { return "BlackBerry 10"; } - virtual ImageCompression get_image_compression() const { return IMAGE_COMPRESSION_ETC1; } - virtual Ref<Texture> get_logo() const { return logo; } - - - virtual bool poll_devices(); - virtual int get_device_count() const; - virtual String get_device_name(int p_device) const; - virtual String get_device_info(int p_device) const; - virtual Error run(int p_device,int p_flags=0); - - virtual bool requires_password(bool p_debug) const { return !p_debug; } - virtual String get_binary_extension() const { return "bar"; } - virtual Error export_project(const String& p_path,bool p_debug,int p_flags=0); - - virtual bool can_export(String *r_error=NULL) const; - - EditorExportPlatformBB10(); - ~EditorExportPlatformBB10(); -}; - -bool EditorExportPlatformBB10::_set(const StringName& p_name, const Variant& p_value) { - - String n=p_name; - - if (n=="version/code") - version_code=p_value; - else if (n=="version/name") - version_name=p_value; - else if (n=="package/unique_name") - package=p_value; - else if (n=="package/category") - category=p_value; - else if (n=="package/name") - name=p_value; - else if (n=="package/description") - description=p_value; - else if (n=="package/icon") - icon=p_value; - else if (n=="package/custom_template") - custom_package=p_value; - else if (n=="release/author") - author_name=p_value; - else if (n=="release/author_id") - author_id=p_value; - else - return false; - - return true; -} - -bool EditorExportPlatformBB10::_get(const StringName& p_name,Variant &r_ret) const{ - - String n=p_name; - - if (n=="version/code") - r_ret=version_code; - else if (n=="version/name") - r_ret=version_name; - else if (n=="package/unique_name") - r_ret=package; - else if (n=="package/category") - r_ret=category; - else if (n=="package/name") - r_ret=name; - else if (n=="package/description") - r_ret=description; - else if (n=="package/icon") - r_ret=icon; - else if (n=="package/custom_template") - r_ret=custom_package; - else if (n=="release/author") - r_ret=author_name; - else if (n=="release/author_id") - r_ret=author_id; - else - return false; - - return true; -} -void EditorExportPlatformBB10::_get_property_list( List<PropertyInfo> *p_list) const{ - - p_list->push_back( PropertyInfo( Variant::INT, "version/code", PROPERTY_HINT_RANGE,"1,65535,1")); - p_list->push_back( PropertyInfo( Variant::STRING, "version/name") ); - p_list->push_back( PropertyInfo( Variant::STRING, "package/unique_name") ); - p_list->push_back( PropertyInfo( Variant::STRING, "package/category") ); - p_list->push_back( PropertyInfo( Variant::STRING, "package/name") ); - p_list->push_back( PropertyInfo( Variant::STRING, "package/description",PROPERTY_HINT_MULTILINE_TEXT) ); - p_list->push_back( PropertyInfo( Variant::STRING, "package/icon",PROPERTY_HINT_FILE,"png") ); - p_list->push_back( PropertyInfo( Variant::STRING, "package/custom_template", PROPERTY_HINT_GLOBAL_FILE,"zip")); - p_list->push_back( PropertyInfo( Variant::STRING, "release/author") ); - p_list->push_back( PropertyInfo( Variant::STRING, "release/author_id") ); - - //p_list->push_back( PropertyInfo( Variant::INT, "resources/pack_mode", PROPERTY_HINT_ENUM,"Copy,Single Exec.,Pack (.pck),Bundles (Optical)")); - -} - -void EditorExportPlatformBB10::_fix_descriptor(Vector<uint8_t>& p_descriptor) { - - String fpath = EditorSettings::get_singleton()->get_settings_path().plus_file("tmp_bar-settings.xml"); - { - FileAccessRef f = FileAccess::open(fpath,FileAccess::WRITE); - f->store_buffer(p_descriptor.ptr(),p_descriptor.size()); - } - - Ref<XMLParser> parser = memnew( XMLParser ); - Error err = parser->open(fpath); - ERR_FAIL_COND(err!=OK); - - String txt; - err = parser->read(); - Vector<String> depth; - - while(err!=ERR_FILE_EOF) { - - ERR_FAIL_COND(err!=OK); - - switch(parser->get_node_type()) { - - case XMLParser::NODE_NONE: { - print_line("???"); - } break; - case XMLParser::NODE_ELEMENT: { - String e="<"; - e+=parser->get_node_name(); - for(int i=0;i<parser->get_attribute_count();i++) { - e+=" "; - e+=parser->get_attribute_name(i)+"=\""; - e+=parser->get_attribute_value(i)+"\" "; - } - - - - if (parser->is_empty()) { - e+="/"; - } else { - depth.push_back(parser->get_node_name()); - } - - e+=">"; - txt+=e; - - } break; - case XMLParser::NODE_ELEMENT_END: { - - txt+="</"+parser->get_node_name()+">"; - if (depth.size() && depth[depth.size()-1]==parser->get_node_name()) { - depth.resize(depth.size()-1); - } - - - } break; - case XMLParser::NODE_TEXT: { - if (depth.size()==2 && depth[0]=="qnx" && depth[1]=="id") { - - txt+=package; - } else if (depth.size()==2 && depth[0]=="qnx" && depth[1]=="name") { - - String aname; - if (this->name!="") { - aname=this->name; - } else { - aname = GlobalConfig::get_singleton()->get("application/name"); - - } - - if (aname=="") { - aname=_MKSTR(VERSION_NAME); - } - - txt+=aname; - - } else if (depth.size()==2 && depth[0]=="qnx" && depth[1]=="versionNumber") { - txt+=itos(version_code); - } else if (depth.size()==2 && depth[0]=="qnx" && depth[1]=="description") { - txt+=description; - } else if (depth.size()==2 && depth[0]=="qnx" && depth[1]=="author") { - txt+=author_name; - } else if (depth.size()==2 && depth[0]=="qnx" && depth[1]=="authorId") { - txt+=author_id; - } else if (depth.size()==2 && depth[0]=="qnx" && depth[1]=="category") { - txt+=category; - } else { - txt+=parser->get_node_data(); - } - } break; - case XMLParser::NODE_COMMENT: { - txt+="<!--"+parser->get_node_name()+"-->"; - } break; - case XMLParser::NODE_CDATA: { - //ignore - //print_line("cdata"); - } break; - case XMLParser::NODE_UNKNOWN: { - //ignore - txt+="<"+parser->get_node_name()+">"; - } break; - } - - err = parser->read(); - } - - - CharString cs = txt.utf8(); - p_descriptor.resize(cs.length()); - for(int i=0;i<cs.length();i++) - p_descriptor[i]=cs[i]; - -} - - - -Error EditorExportPlatformBB10::export_project(const String& p_path, bool p_debug, int p_flags) { - - - EditorProgress ep("export","Exporting for BlackBerry 10",104); - - String src_template=custom_package; - - if (src_template=="") { - String err; - src_template = find_export_template("bb10.zip", &err); - if (src_template=="") { - EditorNode::add_io_error(err); - return ERR_FILE_NOT_FOUND; - } - } - - FileAccess *src_f=NULL; - zlib_filefunc_def io = zipio_create_io_from_file(&src_f); - - ep.step("Creating FileSystem for BAR",0); - - unzFile pkg = unzOpen2(src_template.utf8().get_data(), &io); - if (!pkg) { - - EditorNode::add_io_error("Could not find template zip to export:\n"+src_template); - return ERR_FILE_NOT_FOUND; - } - - DirAccessRef da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); - da->change_dir(EditorSettings::get_singleton()->get_settings_path()); - - - if (da->change_dir("tmp")!=OK) { - da->make_dir("tmp"); - if (da->change_dir("tmp")!=OK) - return ERR_CANT_CREATE; - } - - if (da->change_dir("bb10_export")!=OK) { - da->make_dir("bb10_export"); - if (da->change_dir("bb10_export")!=OK) { - return ERR_CANT_CREATE; - } - } - - - String bar_dir = da->get_current_dir(); - if (bar_dir.ends_with("/")) { - bar_dir=bar_dir.substr(0,bar_dir.length()-1); - } - - //THIS IS SUPER, SUPER DANGEROUS!!!! - //CAREFUL WITH THIS CODE, MIGHT DELETE USERS HARD DRIVE OR HOME DIR - //EXTRA CHECKS ARE IN PLACE EVERYWERE TO MAKE SURE NOTHING BAD HAPPENS BUT STILL.... - //BE SUPER CAREFUL WITH THIS PLEASE!!! - //BLACKBERRY THIS IS YOUR FAULT FOR NOT MAKING A BETTER WAY!! - - bool berr = bar_dir.ends_with("bb10_export"); - if (berr) { - if (da->list_dir_begin()) { - EditorNode::add_io_error("Can't ensure that dir is empty:\n"+bar_dir); - ERR_FAIL_COND_V(berr,FAILED); - }; - - String f = da->get_next(); - while (f != "") { - - if (f == "." || f == "..") { - f = da->get_next(); - continue; - }; - Error err = da->remove(bar_dir + "/" + f); - if (err != OK) { - EditorNode::add_io_error("Can't ensure that dir is empty:\n"+bar_dir); - ERR_FAIL_COND_V(err!=OK,err); - }; - f = da->get_next(); - }; - - da->list_dir_end(); - - } else { - print_line("ARE YOU CRAZY??? THIS IS A SERIOUS BUG HERE!!!"); - ERR_FAIL_V(ERR_OMFG_THIS_IS_VERY_VERY_BAD); - } - - - ERR_FAIL_COND_V(!pkg, ERR_CANT_OPEN); - int ret = unzGoToFirstFile(pkg); - - - - while(ret==UNZ_OK) { - - //get filename - unz_file_info info; - char fname[16384]; - ret = unzGetCurrentFileInfo(pkg,&info,fname,16384,NULL,0,NULL,0); - - String file=fname; - - Vector<uint8_t> data; - data.resize(info.uncompressed_size); - - //read - unzOpenCurrentFile(pkg); - unzReadCurrentFile(pkg,data.ptr(),data.size()); - unzCloseCurrentFile(pkg); - - //write - - if (file=="bar-descriptor.xml") { - - _fix_descriptor(data); - } - - if (file=="icon.png") { - bool found=false; - - if (this->icon!="" && this->icon.ends_with(".png")) { - - FileAccess *f = FileAccess::open(this->icon,FileAccess::READ); - if (f) { - - data.resize(f->get_len()); - f->get_buffer(data.ptr(),data.size()); - memdelete(f); - found=true; - } - - } - - if (!found) { - - String appicon = GlobalConfig::get_singleton()->get("application/icon"); - if (appicon!="" && appicon.ends_with(".png")) { - FileAccess*f = FileAccess::open(appicon,FileAccess::READ); - if (f) { - data.resize(f->get_len()); - f->get_buffer(data.ptr(),data.size()); - memdelete(f); - } - } - } - } - - - if (file.find("/")) { - - da->make_dir_recursive(file.get_base_dir()); - } - - FileAccessRef wf = FileAccess::open(bar_dir.plus_file(file),FileAccess::WRITE); - wf->store_buffer(data.ptr(),data.size()); - - ret = unzGoToNextFile(pkg); - } - - ep.step("Adding Files..",2); - - FileAccess* dst = FileAccess::open(bar_dir+"/data.pck", FileAccess::WRITE); - if (!dst) { - EditorNode::add_io_error("Can't copy executable file to:\n "+p_path); - return ERR_FILE_CANT_WRITE; - } - save_pack(dst, false, 1024); - dst->close(); - memdelete(dst); - - ep.step("Creating BAR Package..",104); - - String bb_packager=EditorSettings::get_singleton()->get("export/blackberry/host_tools"); - bb_packager=bb_packager.plus_file("blackberry-nativepackager"); - if (OS::get_singleton()->get_name()=="Windows") - bb_packager+=".bat"; - - - if (!FileAccess::exists(bb_packager)) { - EditorNode::add_io_error("Can't find packager:\n"+bb_packager); - return ERR_CANT_OPEN; - } - - List<String> args; - args.push_back("-package"); - args.push_back(p_path); - if (p_debug) { - - String debug_token=EditorSettings::get_singleton()->get("export/blackberry/debug_token"); - if (!FileAccess::exists(debug_token)) { - EditorNode::add_io_error("Debug token not found!"); - } else { - args.push_back("-debugToken"); - args.push_back(debug_token); - } - args.push_back("-devMode"); - args.push_back("-configuration"); - args.push_back("Device-Debug"); - } else { - - args.push_back("-configuration"); - args.push_back("Device-Release"); - } - args.push_back(bar_dir.plus_file("bar-descriptor.xml")); - - int ec; - - Error err = OS::get_singleton()->execute(bb_packager,args,true,NULL,NULL,&ec); - - if (err!=OK) - return err; - if (ec!=0) - return ERR_CANT_CREATE; - - return OK; - -} - -bool EditorExportPlatformBB10::poll_devices() { - - bool dc=devices_changed; - devices_changed=false; - return dc; -} - -int EditorExportPlatformBB10::get_device_count() const { - - device_lock->lock(); - int dc=devices.size(); - device_lock->unlock(); - - return dc; - -} -String EditorExportPlatformBB10::get_device_name(int p_device) const { - - ERR_FAIL_INDEX_V(p_device,devices.size(),""); - device_lock->lock(); - String s=devices[p_device].name; - device_lock->unlock(); - return s; -} -String EditorExportPlatformBB10::get_device_info(int p_device) const { - - ERR_FAIL_INDEX_V(p_device,devices.size(),""); - device_lock->lock(); - String s=devices[p_device].description; - device_lock->unlock(); - return s; -} - -void EditorExportPlatformBB10::_device_poll_thread(void *ud) { - - EditorExportPlatformBB10 *ea=(EditorExportPlatformBB10 *)ud; - - while(!ea->quit_request) { - - String bb_deploy=EditorSettings::get_singleton()->get("export/blackberry/host_tools"); - bb_deploy=bb_deploy.plus_file("blackberry-deploy"); - bool windows = OS::get_singleton()->get_name()=="Windows"; - if (windows) - bb_deploy+=".bat"; - - if (FileAccess::exists(bb_deploy)) { - - Vector<Device> devices; - - - for (int i=0;i<MAX_DEVICES;i++) { - - String host = EditorSettings::get_singleton()->get("export/blackberry/device_"+itos(i+1)+"/host"); - if (host==String()) - continue; - String pass = EditorSettings::get_singleton()->get("export/blackberry/device_"+itos(i+1)+"/password"); - if (pass==String()) - continue; - - List<String> args; - args.push_back("-listDeviceInfo"); - args.push_back(host); - args.push_back("-password"); - args.push_back(pass); - - - int ec; - String dp; - - Error err = OS::get_singleton()->execute(bb_deploy,args,true,NULL,&dp,&ec); - - if (err==OK && ec==0) { - - Device dev; - dev.index=i; - String descr; - Vector<String> ls=dp.split("\n"); - - for(int i=0;i<ls.size();i++) { - - String l = ls[i].strip_edges(); - if (l.begins_with("modelfullname::")) { - dev.name=l.get_slice("::",1); - descr+="Model: "+dev.name+"\n"; - } - if (l.begins_with("modelnumber::")) { - String s = l.get_slice("::",1); - dev.name+=" ("+s+")"; - descr+="Model Number: "+s+"\n"; - } - if (l.begins_with("scmbundle::")) - descr+="OS Version: "+l.get_slice("::",1)+"\n"; - if (l.begins_with("[n]debug_token_expiration::")) - descr+="Debug Token Expires:: "+l.get_slice("::",1)+"\n"; - - } - - dev.description=descr; - devices.push_back(dev); - } - - } - - bool changed=false; - - - ea->device_lock->lock(); - - if (ea->devices.size()!=devices.size()) { - changed=true; - } else { - - for(int i=0;i<ea->devices.size();i++) { - - if (ea->devices[i].index!=devices[i].index) { - changed=true; - break; - } - } - } - - if (changed) { - - ea->devices=devices; - ea->devices_changed=true; - } - - ea->device_lock->unlock(); - } - - - uint64_t wait = 3000000; - uint64_t time = OS::get_singleton()->get_ticks_usec(); - while(OS::get_singleton()->get_ticks_usec() - time < wait ) { - OS::get_singleton()->delay_usec(1000); - if (ea->quit_request) - break; - } - } - -} - -Error EditorExportPlatformBB10::run(int p_device, int p_flags) { - - ERR_FAIL_INDEX_V(p_device,devices.size(),ERR_INVALID_PARAMETER); - - String bb_deploy=EditorSettings::get_singleton()->get("export/blackberry/host_tools"); - bb_deploy=bb_deploy.plus_file("blackberry-deploy"); - if (OS::get_singleton()->get_name()=="Windows") - bb_deploy+=".bat"; - - if (!FileAccess::exists(bb_deploy)) { - EditorNode::add_io_error("Blackberry Deploy not found:\n"+bb_deploy); - return ERR_FILE_NOT_FOUND; - } - - - device_lock->lock(); - - - EditorProgress ep("run","Running on "+devices[p_device].name,3); - - //export_temp - ep.step("Exporting APK",0); - - String export_to=EditorSettings::get_singleton()->get_settings_path().plus_file("/tmp/tmpexport.bar"); - Error err = export_project(export_to,true,p_flags); - if (err) { - device_lock->unlock(); - return err; - } -#if 0 - ep.step("Uninstalling..",1); - - print_line("Uninstalling previous version: "+devices[p_device].name); - List<String> args; - args.push_back("-s"); - args.push_back(devices[p_device].id); - args.push_back("uninstall"); - args.push_back(package); - int rv; - err = OS::get_singleton()->execute(adb,args,true,NULL,NULL,&rv); - - if (err || rv!=0) { - EditorNode::add_io_error("Could not install to device."); - device_lock->unlock(); - return ERR_CANT_CREATE; - } - - print_line("Installing into device (please wait..): "+devices[p_device].name); - -#endif - ep.step("Installing to Device (please wait..)..",2); - - List<String> args; - args.clear(); - args.push_back("-installApp"); - args.push_back("-launchApp"); - args.push_back("-device"); - String host = EditorSettings::get_singleton()->get("export/blackberry/device_"+itos(p_device+1)+"/host"); - String pass = EditorSettings::get_singleton()->get("export/blackberry/device_"+itos(p_device+1)+"/password"); - args.push_back(host); - args.push_back("-password"); - args.push_back(pass); - args.push_back(export_to); - - int rv; - err = OS::get_singleton()->execute(bb_deploy,args,true,NULL,NULL,&rv); - if (err || rv!=0) { - EditorNode::add_io_error("Could not install to device."); - device_lock->unlock(); - return ERR_CANT_CREATE; - } - - device_lock->unlock(); - return OK; - - -} - - -EditorExportPlatformBB10::EditorExportPlatformBB10() { - - version_code=1; - version_name="1.0"; - package="com.godot.noname"; - category="core.games"; - name=""; - author_name="Cert. Name"; - author_id="Cert. ID"; - description="Game made with Godot Engine"; - - device_lock = Mutex::create(); - quit_request=false; - - device_thread=Thread::create(_device_poll_thread,this); - devices_changed=true; - - Image img( _bb10_logo ); - logo = Ref<ImageTexture>( memnew( ImageTexture )); - logo->create_from_image(img); -} - -bool EditorExportPlatformBB10::can_export(String *r_error) const { - - bool valid=true; - String bb_deploy=EditorSettings::get_singleton()->get("export/blackberry/host_tools"); - String err; - - if (!FileAccess::exists(bb_deploy.plus_file("blackberry-deploy"))) { - - valid=false; - err+="Blackberry host tools not configured in editor settings.\n"; - } - - if (!exists_export_template("bb10.zip")) { - valid=false; - err+="No export template found.\nDownload and install export templates.\n"; - } - - String debug_token=EditorSettings::get_singleton()->get("export/blackberry/debug_token"); - - if (!FileAccess::exists(debug_token)) { - valid=false; - err+="No debug token set, will not be able to test on device.\n"; - } - - - if (custom_package!="" && !FileAccess::exists(custom_package)) { - valid=false; - err+="Custom release package not found.\n"; - } - - if (r_error) - *r_error=err; - - return valid; -} - - -EditorExportPlatformBB10::~EditorExportPlatformBB10() { - - quit_request=true; - Thread::wait_to_finish(device_thread); - memdelete(device_lock); - memdelete(device_thread); -} - -#endif -void register_bb10_exporter() { -#if 0 - EDITOR_DEF("export/blackberry/host_tools",""); - EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::STRING,"export/blackberry/host_tools",PROPERTY_HINT_GLOBAL_DIR)); - EDITOR_DEF("export/blackberry/debug_token",""); - EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::STRING,"export/blackberry/debug_token",PROPERTY_HINT_GLOBAL_FILE,"bar")); - EDITOR_DEF("export/blackberry/device_1/host",""); - EDITOR_DEF("export/blackberry/device_1/password",""); - EDITOR_DEF("export/blackberry/device_2/host",""); - EDITOR_DEF("export/blackberry/device_2/password",""); - EDITOR_DEF("export/blackberry/device_3/host",""); - EDITOR_DEF("export/blackberry/device_3/password",""); - EDITOR_DEF("export/blackberry/device_4/host",""); - EDITOR_DEF("export/blackberry/device_4/password",""); - EDITOR_DEF("export/blackberry/device_5/host",""); - EDITOR_DEF("export/blackberry/device_5/password",""); - - Ref<EditorExportPlatformBB10> exporter = Ref<EditorExportPlatformBB10>( memnew(EditorExportPlatformBB10) ); - EditorImportExport::get_singleton()->add_export_platform(exporter); - -#endif -} diff --git a/platform/bb10/export/export.h b/platform/bb10/export/export.h deleted file mode 100644 index d8407c4152..0000000000 --- a/platform/bb10/export/export.h +++ /dev/null @@ -1,29 +0,0 @@ -/*************************************************************************/ -/* export.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* http://www.godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ -void register_bb10_exporter(); diff --git a/platform/bb10/godot_bb10.cpp b/platform/bb10/godot_bb10.cpp deleted file mode 100644 index e1826450a6..0000000000 --- a/platform/bb10/godot_bb10.cpp +++ /dev/null @@ -1,47 +0,0 @@ -/*************************************************************************/ -/* godot_bb10.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* http://www.godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ -#include "main/main.h" -#include "os_bb10.h" - -#include <unistd.h> - -int main(int argc, char *argv[]) { - - OSBB10 os; - - Error err = Main::setup(argv[0], argc - 1, &argv[1]); - if (err != OK) - return 255; - - if (Main::start()) - os.run(); // it is actually the OS that decides how to run - Main::cleanup(); - - return os.get_exit_code(); -} diff --git a/platform/bb10/logo.png b/platform/bb10/logo.png Binary files differdeleted file mode 100644 index abf0d2cc69..0000000000 --- a/platform/bb10/logo.png +++ /dev/null diff --git a/platform/bb10/os_bb10.cpp b/platform/bb10/os_bb10.cpp deleted file mode 100644 index 80e846d3cd..0000000000 --- a/platform/bb10/os_bb10.cpp +++ /dev/null @@ -1,613 +0,0 @@ -/*************************************************************************/ -/* os_bb10.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* http://www.godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ -#include "os_bb10.h" - -#include "bbutil.h" -#include "core/global_config.h" -#include "core/os/dir_access.h" -#include "core/os/keyboard.h" -#include "drivers/gles2/rasterizer_gles2.h" -#include "main/main.h" -#include "servers/visual/visual_server_raster.h" - -#include <assert.h> -#include <bps/accelerometer.h> -#include <bps/audiodevice.h> -#include <bps/bps.h> -#include <bps/navigator.h> -#include <bps/orientation.h> -#include <bps/screen.h> -#include <bps/virtualkeyboard.h> -#include <stdbool.h> -#include <stdlib.h> - -#ifdef BB10_SCORELOOP_ENABLED -#include "modules/scoreloop/scoreloop_bb10.h" -#endif - -static char launch_dir[512]; -char *launch_dir_ptr; - -int OSBB10::get_video_driver_count() const { - - return 1; -} -const char *OSBB10::get_video_driver_name(int p_driver) const { - - return "GLES2"; -} - -OS::VideoMode OSBB10::get_default_video_mode() const { - - return OS::VideoMode(); -} - -int OSBB10::get_audio_driver_count() const { - - return 1; -} -const char *OSBB10::get_audio_driver_name(int p_driver) const { - - return "BB10"; -} - -void OSBB10::initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver) { - - data_dir = getenv("HOME"); - - //Create a screen context that will be used to create an EGL surface to to receive libscreen events - screen_create_context(&screen_cxt, 0); - - //Initialize BPS library - bps_initialize(); - - //Use utility code to initialize EGL for 2D rendering with GL ES 1.1 - enum RENDERING_API api = GL_ES_2; -#ifdef BB10_LGLES_OVERRIDE - api = GL_ES_1; -#endif - if (EXIT_SUCCESS != bbutil_init(screen_cxt, api)) { - bbutil_terminate(); - screen_destroy_context(screen_cxt); - return; - }; - - EGLint surface_width, surface_height; - - eglQuerySurface(egl_disp, egl_surf, EGL_WIDTH, &surface_width); - eglQuerySurface(egl_disp, egl_surf, EGL_HEIGHT, &surface_height); - printf("screen size: %ix%i\n", surface_width, surface_height); - VideoMode mode; - mode.width = surface_width; - mode.height = surface_height; - mode.fullscreen = true; - mode.resizable = false; - set_video_mode(mode); - - //Signal BPS library that navigator and screen events will be requested - screen_request_events(screen_cxt); - navigator_request_events(0); - virtualkeyboard_request_events(0); - audiodevice_request_events(0); - -#ifdef DEBUG_ENABLED - bps_set_verbosity(3); -#endif - - accel_supported = accelerometer_is_supported(); - if (accel_supported) - accelerometer_set_update_frequency(FREQ_40_HZ); - pitch = 0; - roll = 0; - -#ifdef BB10_LGLES_OVERRIDE - rasterizer = memnew(RasterizerGLES1(false)); -#else - rasterizer = memnew(RasterizerGLES2(false, false)); -#endif - - visual_server = memnew(VisualServerRaster(rasterizer)); - visual_server->init(); - visual_server->cursor_set_visible(false, 0); - - audio_driver = memnew(AudioDriverBB10); - audio_driver->set_singleton(); - audio_driver->init(NULL); - - physics_server = memnew(PhysicsServerSW); - physics_server->init(); - physics_2d_server = memnew(Physics2DServerSW); - physics_2d_server->init(); - - input = memnew(InputDefault); - - power_manager = memnew(PowerBB10); - -#ifdef PAYMENT_SERVICE_ENABLED - payment_service = memnew(PaymentService); - Globals::get_singleton()->add_singleton(Globals::Singleton("InAppStore", payment_service)); -#endif -} - -void OSBB10::set_main_loop(MainLoop *p_main_loop) { - - input->set_main_loop(p_main_loop); - main_loop = p_main_loop; -} - -void OSBB10::delete_main_loop() { - - memdelete(main_loop); - main_loop = NULL; -} - -void OSBB10::finalize() { - - if (main_loop) - memdelete(main_loop); - main_loop = NULL; - - /* - if (debugger_connection_console) { - memdelete(debugger_connection_console); - } - */ - - visual_server->finish(); - memdelete(visual_server); - memdelete(rasterizer); - - physics_server->finish(); - memdelete(physics_server); - - physics_2d_server->finish(); - memdelete(physics_2d_server); - -#ifdef PAYMENT_SERVICE_ENABLED - memdelete(payment_service); -#endif - - memdelete(input); - - bbutil_terminate(); - screen_destroy_context(screen_cxt); - - bps_shutdown(); -} - -void OSBB10::set_mouse_show(bool p_show) { - - //android has no mouse... -} - -void OSBB10::set_mouse_grab(bool p_grab) { - - //it really has no mouse...! -} - -bool OSBB10::is_mouse_grab_enabled() const { - - //*sigh* technology has evolved so much since i was a kid.. - return false; -} -Point2 OSBB10::get_mouse_pos() const { - - return Point2(); -} -int OSBB10::get_mouse_button_state() const { - - return 0; -} -void OSBB10::set_window_title(const String &p_title) { -} - -//interesting byt not yet -//void set_clipboard(const String& p_text); -//String get_clipboard() const; - -void OSBB10::set_video_mode(const VideoMode &p_video_mode, int p_screen) { - - default_videomode = p_video_mode; -} - -OS::VideoMode OSBB10::get_video_mode(int p_screen) const { - - return default_videomode; -} -void OSBB10::get_fullscreen_mode_list(List<VideoMode> *p_list, int p_screen) const { - - p_list->push_back(default_videomode); -} - -String OSBB10::get_name() { - - return "BlackBerry 10"; -} - -MainLoop *OSBB10::get_main_loop() const { - - return main_loop; -} - -bool OSBB10::can_draw() const { - - return !minimized; -} - -void OSBB10::set_cursor_shape(CursorShape p_shape) { - - //android really really really has no mouse.. how amazing.. -} - -void OSBB10::handle_screen_event(bps_event_t *event) { - - screen_event_t screen_event = screen_event_get_event(event); - - int screen_val; - screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_TYPE, &screen_val); - - int pos[2]; - - switch (screen_val) { - case SCREEN_EVENT_MTOUCH_TOUCH: - case SCREEN_EVENT_MTOUCH_RELEASE: { - - screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_POSITION, pos); - - InputEvent ievent; - ievent.type = InputEvent::SCREEN_TOUCH; - ievent.ID = ++last_id; - ievent.device = 0; - ievent.screen_touch.pressed = (screen_val == SCREEN_EVENT_MTOUCH_TOUCH); - ievent.screen_touch.x = pos[0]; - ievent.screen_touch.y = pos[1]; - Point2 mpos(ievent.screen_touch.x, ievent.screen_touch.y); - - screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_TOUCH_ID, &pos[0]); - ievent.screen_touch.index = pos[0]; - - last_touch_x[pos[0]] = ievent.screen_touch.x; - last_touch_y[pos[0]] = ievent.screen_touch.y; - - input->parse_input_event(ievent); - - if (ievent.screen_touch.index == 0) { - - InputEvent ievent; - ievent.type = InputEvent::MOUSE_BUTTON; - ievent.ID = ++last_id; - ievent.device = 0; - ievent.mouse_button.pressed = (screen_val == SCREEN_EVENT_MTOUCH_TOUCH); - ievent.mouse_button.button_index = BUTTON_LEFT; - ievent.mouse_button.doubleclick = 0; - ievent.mouse_button.x = ievent.mouse_button.global_x = mpos.x; - ievent.mouse_button.y = ievent.mouse_button.global_y = mpos.y; - input->parse_input_event(ievent); - }; - - } break; - case SCREEN_EVENT_MTOUCH_MOVE: { - - screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_POSITION, pos); - - InputEvent ievent; - ievent.type = InputEvent::SCREEN_DRAG; - ievent.ID = ++last_id; - ievent.device = 0; - ievent.screen_drag.x = pos[0]; - ievent.screen_drag.y = pos[1]; - - /* - screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_SOURCE_POSITION, pos); - ievent.screen_drag.relative_x = ievent.screen_drag.x - pos[0]; - ievent.screen_drag.relative_y = ievent.screen_drag.y - pos[1]; - */ - - screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_TOUCH_ID, &pos[0]); - ievent.screen_drag.index = pos[0]; - - ievent.screen_drag.relative_x = ievent.screen_drag.x - last_touch_x[ievent.screen_drag.index]; - ievent.screen_drag.relative_y = ievent.screen_drag.y - last_touch_y[ievent.screen_drag.index]; - - last_touch_x[ievent.screen_drag.index] = ievent.screen_drag.x; - last_touch_y[ievent.screen_drag.index] = ievent.screen_drag.y; - - Point2 mpos(ievent.screen_drag.x, ievent.screen_drag.y); - Point2 mrel(ievent.screen_drag.relative_x, ievent.screen_drag.relative_y); - - input->parse_input_event(ievent); - - if (ievent.screen_touch.index == 0) { - - InputEvent ievent; - ievent.type = InputEvent::MOUSE_MOTION; - ievent.ID = ++last_id; - ievent.device = 0; - ievent.mouse_motion.x = ievent.mouse_motion.global_x = mpos.x; - ievent.mouse_motion.y = ievent.mouse_motion.global_y = mpos.y; - input->set_mouse_pos(Point2(ievent.mouse_motion.x, ievent.mouse_motion.y)); - ievent.mouse_motion.speed_x = input->get_last_mouse_speed().x; - ievent.mouse_motion.speed_y = input->get_last_mouse_speed().y; - ievent.mouse_motion.relative_x = mrel.x; - ievent.mouse_motion.relative_y = mrel.y; - ievent.mouse_motion.button_mask = 1; // pressed - - input->parse_input_event(ievent); - }; - } break; - - case SCREEN_EVENT_KEYBOARD: { - - InputEvent ievent; - ievent.type = InputEvent::KEY; - ievent.ID = ++last_id; - ievent.device = 0; - int val = 0; - screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_KEY_SCAN, &val); - ievent.key.scancode = val; - screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_KEY_SYM, &val); - ievent.key.unicode = val; - if (val == 61448) { - ievent.key.scancode = KEY_BACKSPACE; - ievent.key.unicode = KEY_BACKSPACE; - }; - if (val == 61453) { - ievent.key.scancode = KEY_ENTER; - ievent.key.unicode = KEY_ENTER; - }; - - int flags; - screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_KEY_FLAGS, &flags); - ievent.key.pressed = flags & 1; // bit 1 is pressed apparently - - int mod; - screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_KEY_MODIFIERS, &mod); - - input->parse_input_event(ievent); - } break; - - default: - break; - } -}; - -void OSBB10::handle_accelerometer() { - - if (!accel_supported) - return; - - if (!fullscreen) - return; - - double force_x, force_y, force_z; - accelerometer_read_forces(&force_x, &force_y, &force_z); - Vector3 accel = Vector3(force_x, flip_accelerometer ? force_y : -force_y, force_z); - input->set_accelerometer(accel); - // rotate 90 degrees - //input->set_accelerometer(Vector3(force_y, flip_accelerometer?force_x:(-force_x), force_z)); -}; - -void OSBB10::_resize(bps_event_t *event) { - - int angle = navigator_event_get_orientation_angle(event); - bbutil_rotate_screen_surface(angle); - - EGLint surface_width, surface_height; - eglQuerySurface(egl_disp, egl_surf, EGL_WIDTH, &surface_width); - eglQuerySurface(egl_disp, egl_surf, EGL_HEIGHT, &surface_height); - - VideoMode mode; - mode.width = surface_width; - mode.height = surface_height; - mode.fullscreen = true; - mode.resizable = false; - set_video_mode(mode); -}; - -void OSBB10::process_events() { - - handle_accelerometer(); - - bps_event_t *event = NULL; - - do { - int rc = bps_get_event(&event, 0); - assert(rc == BPS_SUCCESS); - - if (!event) break; - -#ifdef BB10_SCORELOOP_ENABLED - ScoreloopBB10 *sc = Globals::get_singleton()->get_singleton_object("Scoreloop")->cast_to<ScoreloopBB10>(); - if (sc->handle_event(event)) - continue; -#endif - -#ifdef PAYMENT_SERVICE_ENABLED - if (payment_service->handle_event(event)) - continue; -#endif - - int domain = bps_event_get_domain(event); - if (domain == screen_get_domain()) { - - handle_screen_event(event); - - } else if (domain == navigator_get_domain()) { - - if (NAVIGATOR_EXIT == bps_event_get_code(event)) { - if (main_loop) - main_loop->notification(MainLoop::NOTIFICATION_WM_QUIT_REQUEST); - bps_event_destroy(event); - exit(0); - return; - /* - } else if (bps_event_get_code(event) == NAVIGATOR_ORIENTATION_CHECK) { - - int angle = navigator_event_get_orientation_angle(event); - navigator_orientation_check_response(event, false); - - } else if (bps_event_get_code(event) == NAVIGATOR_ORIENTATION) { - - _resize(event); - */ - } else if (bps_event_get_code(event) == NAVIGATOR_WINDOW_STATE) { - - int state = navigator_event_get_window_state(event); - bool was_fullscreen = fullscreen; - minimized = state == NAVIGATOR_WINDOW_INVISIBLE; - fullscreen = state == NAVIGATOR_WINDOW_FULLSCREEN; - set_low_processor_usage_mode(!fullscreen); - if (fullscreen != was_fullscreen) { - if (fullscreen) { - audio_server->set_fx_global_volume_scale(fullscreen_mixer_volume); - audio_server->set_stream_global_volume_scale(fullscreen_stream_volume); - } else { - fullscreen_mixer_volume = audio_server->get_fx_global_volume_scale(); - fullscreen_stream_volume = audio_server->get_stream_global_volume_scale(); - audio_server->set_fx_global_volume_scale(0); - audio_server->set_stream_global_volume_scale(0); - }; - }; - }; - } else if (domain == audiodevice_get_domain()) { - - const char *audiodevice_path = audiodevice_event_get_path(event); - printf("************* got audiodevice event, path %s\n", audiodevice_path); - audio_driver->finish(); - audio_driver->init(audiodevice_path); - audio_driver->start(); - }; - - //bps_event_destroy(event); - } while (event); -}; - -bool OSBB10::has_virtual_keyboard() const { - - return true; -}; - -void OSBB10::show_virtual_keyboard(const String &p_existing_text, const Rect2 &p_screen_rect) { - - virtualkeyboard_show(); -}; - -void OSBB10::hide_virtual_keyboard() { - - virtualkeyboard_hide(); -}; - -void OSBB10::run() { - - if (!main_loop) - return; - - main_loop->init(); - - int flip = bbutil_is_flipped(); - int rot = bbutil_get_rotation(); - flip_accelerometer = rot == 90; - printf("**************** rot is %i, flip %i\n", rot, (int)flip_accelerometer); - /* - orientation_direction_t orientation; - int angle; - orientation_get(&orientation, &angle); - printf("******************** orientation %i, %i, %i\n", orientation, ORIENTATION_BOTTOM_UP, ORIENTATION_TOP_UP); - if (orientation == ORIENTATION_BOTTOM_UP) { - flip_accelerometer = true; - }; - */ - - while (true) { - - process_events(); // get rid of pending events - if (Main::iteration() == true) - break; - bbutil_swap(); - //#ifdef DEBUG_ENABLED - fflush(stdout); - //#endif - }; - - main_loop->finish(); -}; - -bool OSBB10::has_touchscreen_ui_hint() const { - - return true; -} - -Error OSBB10::shell_open(String p_uri) { - - char *msg = NULL; - int ret = navigator_invoke(p_uri.utf8().get_data(), &msg); - - return ret == BPS_SUCCESS ? OK : FAILED; -}; - -String OSBB10::get_data_dir() const { - - return data_dir; -}; - -Size2 OSBB10::get_window_size() const { - return Vector2(default_videomode.width, default_videomode.height); -} - -PowerState OSBB10::get_power_state() { - return power_manager->get_power_state(); -} - -int OSBB10::get_power_seconds_left() { - return power_manager->get_power_seconds_left(); -} - -int OSBB10::get_power_percent_left() { - return power_manager->get_power_percent_left(); -} - -OSBB10::OSBB10() { - - main_loop = NULL; - last_id = 1; - minimized = false; - fullscreen = true; - flip_accelerometer = true; - fullscreen_mixer_volume = 1; - fullscreen_stream_volume = 1; - - printf("godot bb10!\n"); - getcwd(launch_dir, sizeof(launch_dir)); - printf("launch dir %s\n", launch_dir); - chdir("app/native"); - launch_dir_ptr = launch_dir; -} - -OSBB10::~OSBB10() { -} diff --git a/platform/bb10/os_bb10.h b/platform/bb10/os_bb10.h deleted file mode 100644 index 313f9c9e6b..0000000000 --- a/platform/bb10/os_bb10.h +++ /dev/null @@ -1,154 +0,0 @@ -/*************************************************************************/ -/* os_bb10.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* http://www.godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ -#ifndef OS_BB10_H -#define OS_BB10_H - -#include "audio_driver_bb10.h" -#include "drivers/unix/os_unix.h" -#include "main/input_default.h" -#include "os/input.h" -#include "os/main_loop.h" -#include "payment_service.h" -#include "power_bb10.h" -#include "servers/audio_server.h" -#include "servers/physics/physics_server_sw.h" -#include "servers/physics_2d/physics_2d_server_sw.h" -#include "servers/visual/rasterizer.h" - -#include <bps/event.h> -#include <screen/screen.h> -#include <stdint.h> -#include <sys/platform.h> - -class OSBB10 : public OS_Unix { - - unsigned int last_id; - - screen_context_t screen_cxt; - float fullscreen_mixer_volume; - float fullscreen_stream_volume; - - Rasterizer *rasterizer; - VisualServer *visual_server; - PhysicsServer *physics_server; - Physics2DServer *physics_2d_server; - AudioDriverBB10 *audio_driver; - PowerBB10 *power_manager; - -#ifdef PAYMENT_SERVICE_ENABLED - PaymentService *payment_service; -#endif - - VideoMode default_videomode; - MainLoop *main_loop; - - void process_events(); - - void _resize(bps_event_t *event); - void handle_screen_event(bps_event_t *event); - void handle_accelerometer(); - - int last_touch_x[16]; - int last_touch_y[16]; - - bool accel_supported; - float pitch; - float roll; - - bool minimized; - bool fullscreen; - bool flip_accelerometer; - String data_dir; - - InputDefault *input; - -public: - // functions used by main to initialize/deintialize the OS - virtual int get_video_driver_count() const; - virtual const char *get_video_driver_name(int p_driver) const; - - virtual VideoMode get_default_video_mode() const; - - virtual String get_data_dir() const; - - virtual int get_audio_driver_count() const; - virtual const char *get_audio_driver_name(int p_driver) const; - - virtual void initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver); - - virtual void set_main_loop(MainLoop *p_main_loop); - virtual void delete_main_loop(); - - virtual void finalize(); - - typedef int64_t ProcessID; - - static OS *get_singleton(); - - virtual void set_mouse_show(bool p_show); - virtual void set_mouse_grab(bool p_grab); - virtual bool is_mouse_grab_enabled() const; - virtual Point2 get_mouse_pos() const; - virtual int get_mouse_button_state() const; - virtual void set_window_title(const String &p_title); - - //virtual void set_clipboard(const String& p_text); - //virtual String get_clipboard() const; - - virtual bool has_virtual_keyboard() const; - virtual void show_virtual_keyboard(const String &p_existing_text, const Rect2 &p_screen_rect); - virtual void hide_virtual_keyboard(); - - virtual void set_video_mode(const VideoMode &p_video_mode, int p_screen = 0); - virtual VideoMode get_video_mode(int p_screen = 0) const; - virtual void get_fullscreen_mode_list(List<VideoMode> *p_list, int p_screen = 0) const; - - virtual Size2 get_window_size() const; - virtual String get_name(); - virtual MainLoop *get_main_loop() const; - - virtual bool can_draw() const; - - virtual void set_cursor_shape(CursorShape p_shape); - - virtual bool has_touchscreen_ui_hint() const; - - virtual Error shell_open(String p_uri); - - void run(); - - virtual PowerState get_power_state(); - virtual int get_power_seconds_left(); - virtual int get_power_percent_left(); - - OSBB10(); - ~OSBB10(); -}; - -#endif diff --git a/platform/bb10/payment_service.cpp b/platform/bb10/payment_service.cpp deleted file mode 100644 index e78326e8b1..0000000000 --- a/platform/bb10/payment_service.cpp +++ /dev/null @@ -1,148 +0,0 @@ -/*************************************************************************/ -/* payment_service.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* http://www.godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ -#ifdef PAYMENT_SERVICE_ENABLED - -#include "payment_service.h" - -#include "bbutil.h" -#include <errno.h> -#include <string.h> -#include <unistd.h> -extern char *launch_dir_ptr; - -void PaymentService::_bind_methods() { - - ClassDB::bind_method(D_METHOD("request_product_info"), &PaymentService::request_product_info); - ClassDB::bind_method(D_METHOD("purchase"), &PaymentService::purchase); - - ClassDB::bind_method(D_METHOD("get_pending_event_count"), &PaymentService::get_pending_event_count); - ClassDB::bind_method(D_METHOD("pop_pending_event"), &PaymentService::pop_pending_event); -}; - -Error PaymentService::request_product_info(Variant p_params) { - - return ERR_UNAVAILABLE; -}; - -Error PaymentService::purchase(Variant p_params) { - - Dictionary params = p_params; - ERR_FAIL_COND_V((!params.has("product_id")) && (!params.has("product_sku")), ERR_INVALID_PARAMETER); - - char *id = NULL; - char *sku = NULL; - - CharString p_id = params.has("product_id") ? String(params["product_id"]).ascii() : CharString(); - CharString p_sku = params.has("product_sku") ? String(params["product_sku"]).ascii() : CharString(); - unsigned int request_id; - chdir(launch_dir_ptr); - int ret = paymentservice_purchase_request(params.has("product_sku") ? NULL : p_id.get_data(), - params.has("product_sku") ? p_sku.get_data() : NULL, - NULL, NULL, NULL, NULL, get_window_group_id(), &request_id); - chdir("app/native"); - - if (ret != BPS_SUCCESS) { - int eret = errno; - printf("purchase error %i, %x, %i, %x\n", ret, ret, eret, eret); - ERR_FAIL_V((Error)eret); - return (Error)eret; - }; - return OK; -}; - -bool PaymentService::handle_event(bps_event_t *p_event) { - - if (bps_event_get_domain(p_event) != paymentservice_get_domain()) { - return false; - }; - - Dictionary dict; - int res = paymentservice_event_get_response_code(p_event); - if (res == SUCCESS_RESPONSE) { - dict["result"] = "ok"; - - res = bps_event_get_code(p_event); - if (res == PURCHASE_RESPONSE) { - dict["type"] = "purchase"; - const char *pid = paymentservice_event_get_digital_good_id(p_event, 0); - dict["product_id"] = String(pid ? pid : ""); - }; - - } else { - const char *desc = paymentservice_event_get_error_text(p_event); - if (strcmp(desc, "alreadyPurchased") == 0) { - dict["result"] = "ok"; - } else { - dict["result"] = "error"; - dict["error_description"] = paymentservice_event_get_error_text(p_event); - dict["error_code"] = paymentservice_event_get_error_id(p_event); - printf("error code is %i\n", paymentservice_event_get_error_id(p_event)); - printf("error description is %s\n", paymentservice_event_get_error_text(p_event)); - }; - dict["product_id"] = ""; - }; - - res = bps_event_get_code(p_event); - if (res == PURCHASE_RESPONSE) { - dict["type"] = "purchase"; - }; - - printf("********** adding event with result %ls\n", String(dict["result"]).c_str()); - pending_events.push_back(dict); - - return true; -}; - -int PaymentService::get_pending_event_count() { - return pending_events.size(); -}; - -Variant PaymentService::pop_pending_event() { - - Variant front = pending_events.front()->get(); - pending_events.pop_front(); - - return front; -}; - -PaymentService::PaymentService() { - - paymentservice_request_events(0); -#ifdef DEBUG_ENABLED - paymentservice_set_connection_mode(true); -#else - paymentservice_set_connection_mode(false); -#endif -}; - -PaymentService::~PaymentService(){ - -}; - -#endif diff --git a/platform/bb10/payment_service.h b/platform/bb10/payment_service.h deleted file mode 100644 index d5b4cc3d60..0000000000 --- a/platform/bb10/payment_service.h +++ /dev/null @@ -1,63 +0,0 @@ -/*************************************************************************/ -/* payment_service.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* http://www.godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ -#ifdef PAYMENT_SERVICE_ENABLED - -#ifndef PAYMENT_SERVICE_H -#define PAYMENT_SERVICE_H - -#include <bps/bps.h> -#include <bps/event.h> -#include <bps/paymentservice.h> - -#include "core/object.h" - -class PaymentService : public Object { - - GDCLASS(PaymentService, Object); - - static void _bind_methods(); - - List<Variant> pending_events; - -public: - Error request_product_info(Variant p_params); - Error purchase(Variant p_params); - - int get_pending_event_count(); - Variant pop_pending_event(); - - bool handle_event(bps_event_t *p_event); - - PaymentService(); - ~PaymentService(); -}; - -#endif - -#endif diff --git a/platform/bb10/platform_config.h b/platform/bb10/platform_config.h deleted file mode 100644 index cdef185ff0..0000000000 --- a/platform/bb10/platform_config.h +++ /dev/null @@ -1,29 +0,0 @@ -/*************************************************************************/ -/* platform_config.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* http://www.godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ -#include <alloca.h> diff --git a/platform/haiku/audio_driver_media_kit.cpp b/platform/haiku/audio_driver_media_kit.cpp index 0f969d25ab..9c4f6d3aba 100644 --- a/platform/haiku/audio_driver_media_kit.cpp +++ b/platform/haiku/audio_driver_media_kit.cpp @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/haiku/audio_driver_media_kit.h b/platform/haiku/audio_driver_media_kit.h index e9282c8471..2cceb279e8 100644 --- a/platform/haiku/audio_driver_media_kit.h +++ b/platform/haiku/audio_driver_media_kit.h @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/haiku/context_gl_haiku.cpp b/platform/haiku/context_gl_haiku.cpp index f345928005..eb5e60152f 100644 --- a/platform/haiku/context_gl_haiku.cpp +++ b/platform/haiku/context_gl_haiku.cpp @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/haiku/context_gl_haiku.h b/platform/haiku/context_gl_haiku.h index c0030fad41..074b4bf0d1 100644 --- a/platform/haiku/context_gl_haiku.h +++ b/platform/haiku/context_gl_haiku.h @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/haiku/detect.py b/platform/haiku/detect.py index 71202a9a49..54e227cd19 100644 --- a/platform/haiku/detect.py +++ b/platform/haiku/detect.py @@ -53,7 +53,7 @@ def configure(env): elif (env["target"] == "release_debug"): env.Append(CCFLAGS=['-O2', '-ffast-math', '-DDEBUG_ENABLED']) elif (env["target"] == "debug"): - env.Append(CCFLAGS=['-g2', '-Wall', '-DDEBUG_ENABLED', '-DDEBUG_MEMORY_ENABLED']) + env.Append(CCFLAGS=['-g2', '-DDEBUG_ENABLED', '-DDEBUG_MEMORY_ENABLED']) # env.Append(CCFLAGS=['-DFREETYPE_ENABLED']) env.Append(CPPFLAGS=['-DPTHREAD_NO_RENAME']) # TODO: enable when we have pthread_setname_np diff --git a/platform/haiku/godot_haiku.cpp b/platform/haiku/godot_haiku.cpp index 47cfbe55d7..3a8206d9d5 100644 --- a/platform/haiku/godot_haiku.cpp +++ b/platform/haiku/godot_haiku.cpp @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/haiku/haiku_application.cpp b/platform/haiku/haiku_application.cpp index f675d4216d..1f0c9fdcbf 100644 --- a/platform/haiku/haiku_application.cpp +++ b/platform/haiku/haiku_application.cpp @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/haiku/haiku_application.h b/platform/haiku/haiku_application.h index 7fbce5dcbc..6e690d4ab8 100644 --- a/platform/haiku/haiku_application.h +++ b/platform/haiku/haiku_application.h @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/haiku/haiku_direct_window.cpp b/platform/haiku/haiku_direct_window.cpp index bc2dbb9b8f..4a9f8c780d 100644 --- a/platform/haiku/haiku_direct_window.cpp +++ b/platform/haiku/haiku_direct_window.cpp @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -150,36 +151,35 @@ void HaikuDirectWindow::HandleMouseButton(BMessage *message) { } */ - InputEvent mouse_event; - mouse_event.ID = ++event_id; - mouse_event.type = InputEvent::MOUSE_BUTTON; + Ref<InputEvent> mouse_event; + mouse_event.type = Ref<InputEvent>::MOUSE_BUTTON; mouse_event.device = 0; mouse_event.mouse_button.mod = GetKeyModifierState(modifiers); - mouse_event.mouse_button.button_mask = GetMouseButtonState(buttons); - mouse_event.mouse_button.x = where.x; - mouse_event.mouse_button.y = where.y; + mouse_event->get_button_mask() = GetMouseButtonState(buttons); + mouse_event->get_pos().x = where.x; + mouse_event->get_pos().y = where.y; mouse_event.mouse_button.global_x = where.x; mouse_event.mouse_button.global_y = where.y; switch (button) { default: case B_PRIMARY_MOUSE_BUTTON: - mouse_event.mouse_button.button_index = 1; + mouse_event->get_button_index() = 1; break; case B_SECONDARY_MOUSE_BUTTON: - mouse_event.mouse_button.button_index = 2; + mouse_event->get_button_index() = 2; break; case B_TERTIARY_MOUSE_BUTTON: - mouse_event.mouse_button.button_index = 3; + mouse_event->get_button_index() = 3; break; } - mouse_event.mouse_button.pressed = (message->what == B_MOUSE_DOWN); + mouse_event->is_pressed() = (message->what == B_MOUSE_DOWN); - if (message->what == B_MOUSE_DOWN && mouse_event.mouse_button.button_index == 1) { + if (message->what == B_MOUSE_DOWN && mouse_event->get_button_index() == 1) { int32 clicks = message->FindInt32("clicks"); if (clicks > 1) { @@ -207,23 +207,22 @@ void HaikuDirectWindow::HandleMouseMoved(BMessage *message) { Point2i rel = pos - last_mouse_position; - InputEvent motion_event; - motion_event.ID = ++event_id; - motion_event.type = InputEvent::MOUSE_MOTION; + Ref<InputEvent> motion_event; + motion_event.type = Ref<InputEvent>::MOUSE_MOTION; motion_event.device = 0; motion_event.mouse_motion.mod = GetKeyModifierState(modifiers); - motion_event.mouse_motion.button_mask = GetMouseButtonState(buttons); + motion_event->get_button_mask() = GetMouseButtonState(buttons); motion_event.mouse_motion.x = pos.x; motion_event.mouse_motion.y = pos.y; - input->set_mouse_pos(pos); + input->set_mouse_position(pos); motion_event.mouse_motion.global_x = pos.x; motion_event.mouse_motion.global_y = pos.y; motion_event.mouse_motion.speed_x = input->get_last_mouse_speed().x; motion_event.mouse_motion.speed_y = input->get_last_mouse_speed().y; - motion_event.mouse_motion.relative_x = rel.x; - motion_event.mouse_motion.relative_y = rel.y; + motion_event->get_relative().x = rel.x; + motion_event->get_relative().y = rel.y; last_mouse_position = pos; @@ -236,24 +235,22 @@ void HaikuDirectWindow::HandleMouseWheelChanged(BMessage *message) { return; } - InputEvent mouse_event; - mouse_event.ID = ++event_id; - mouse_event.type = InputEvent::MOUSE_BUTTON; + Ref<InputEvent> mouse_event; + mouse_event.type = Ref<InputEvent>::MOUSE_BUTTON; mouse_event.device = 0; - mouse_event.mouse_button.button_index = wheel_delta_y < 0 ? 4 : 5; + mouse_event->get_button_index() = wheel_delta_y < 0 ? 4 : 5; mouse_event.mouse_button.mod = GetKeyModifierState(last_key_modifier_state); - mouse_event.mouse_button.button_mask = last_button_mask; - mouse_event.mouse_button.x = last_mouse_position.x; - mouse_event.mouse_button.y = last_mouse_position.y; + mouse_event->get_button_mask() = last_button_mask; + mouse_event->get_pos().x = last_mouse_position.x; + mouse_event->get_pos().y = last_mouse_position.y; mouse_event.mouse_button.global_x = last_mouse_position.x; mouse_event.mouse_button.global_y = last_mouse_position.y; - mouse_event.mouse_button.pressed = true; + mouse_event->is_pressed() = true; input->parse_input_event(mouse_event); - mouse_event.ID = ++event_id; - mouse_event.mouse_button.pressed = false; + mouse_event->is_pressed() = false; input->parse_input_event(mouse_event); } @@ -274,14 +271,13 @@ void HaikuDirectWindow::HandleKeyboardEvent(BMessage *message) { return; } - InputEvent event; - event.ID = ++event_id; - event.type = InputEvent::KEY; + Ref<InputEvent> event; + event.type = Ref<InputEvent>::KEY; event.device = 0; event.key.mod = GetKeyModifierState(modifiers); - event.key.pressed = (message->what == B_KEY_DOWN); - event.key.scancode = KeyMappingHaiku::get_keysym(raw_char, key); - event.key.echo = message->HasInt32("be:key_repeat"); + event->is_pressed() = (message->what == B_KEY_DOWN); + event->get_scancode() = KeyMappingHaiku::get_keysym(raw_char, key); + event->is_echo() = message->HasInt32("be:key_repeat"); event.key.unicode = 0; const char *bytes = NULL; @@ -289,10 +285,10 @@ void HaikuDirectWindow::HandleKeyboardEvent(BMessage *message) { event.key.unicode = BUnicodeChar::FromUTF8(&bytes); } - //make it consistent accross platforms. - if (event.key.scancode == KEY_BACKTAB) { - event.key.scancode = KEY_TAB; - event.key.mod.shift = true; + //make it consistent across platforms. + if (event->get_scancode() == KEY_BACKTAB) { + event->get_scancode() = KEY_TAB; + event->get_shift() = true; } input->parse_input_event(event); @@ -312,14 +308,13 @@ void HaikuDirectWindow::HandleKeyboardModifierEvent(BMessage *message) { int32 key = old_modifiers ^ modifiers; - InputEvent event; - event.ID = ++event_id; - event.type = InputEvent::KEY; + Ref<InputEvent> event; + event.type = Ref<InputEvent>::KEY; event.device = 0; event.key.mod = GetKeyModifierState(modifiers); - event.key.pressed = ((modifiers & key) != 0); - event.key.scancode = KeyMappingHaiku::get_modifier_keysym(key); - event.key.echo = false; + event->is_pressed() = ((modifiers & key) != 0); + event->get_scancode() = KeyMappingHaiku::get_modifier_keysym(key); + event->is_echo() = false; event.key.unicode = 0; input->parse_input_event(event); diff --git a/platform/haiku/haiku_direct_window.h b/platform/haiku/haiku_direct_window.h index 7fcea7a6f6..3671c3c9cb 100644 --- a/platform/haiku/haiku_direct_window.h +++ b/platform/haiku/haiku_direct_window.h @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -43,7 +44,6 @@ class HaikuDirectWindow : public BDirectWindow { private: - unsigned int event_id; Point2i last_mouse_position; bool last_mouse_pos_valid; uint32 last_buttons_state; diff --git a/platform/haiku/haiku_gl_view.cpp b/platform/haiku/haiku_gl_view.cpp index ded15e12a7..dd568f281e 100644 --- a/platform/haiku/haiku_gl_view.cpp +++ b/platform/haiku/haiku_gl_view.cpp @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/haiku/haiku_gl_view.h b/platform/haiku/haiku_gl_view.h index f06bc64794..14e2889d6c 100644 --- a/platform/haiku/haiku_gl_view.h +++ b/platform/haiku/haiku_gl_view.h @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/haiku/key_mapping_haiku.cpp b/platform/haiku/key_mapping_haiku.cpp index 1bc3467914..9df7b2f047 100644 --- a/platform/haiku/key_mapping_haiku.cpp +++ b/platform/haiku/key_mapping_haiku.cpp @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/haiku/key_mapping_haiku.h b/platform/haiku/key_mapping_haiku.h index 0f2e2e64bd..8d09203737 100644 --- a/platform/haiku/key_mapping_haiku.h +++ b/platform/haiku/key_mapping_haiku.h @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/haiku/os_haiku.cpp b/platform/haiku/os_haiku.cpp index 0853fac393..3131f2bf1e 100644 --- a/platform/haiku/os_haiku.cpp +++ b/platform/haiku/os_haiku.cpp @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -206,7 +207,7 @@ void OS_Haiku::swap_buffers() { context_gl->swap_buffers(); } -Point2 OS_Haiku::get_mouse_pos() const { +Point2 OS_Haiku::get_mouse_position() const { return window->GetLastMousePosition(); } diff --git a/platform/haiku/os_haiku.h b/platform/haiku/os_haiku.h index 827814c7e9..83e44734a6 100644 --- a/platform/haiku/os_haiku.h +++ b/platform/haiku/os_haiku.h @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -88,7 +89,7 @@ public: virtual void make_rendering_thread(); virtual void swap_buffers(); - virtual Point2 get_mouse_pos() const; + virtual Point2 get_mouse_position() const; virtual int get_mouse_button_state() const; virtual void set_cursor_shape(CursorShape p_shape); diff --git a/platform/haiku/platform_config.h b/platform/haiku/platform_config.h index a3aa918ba8..e59b9bac80 100644 --- a/platform/haiku/platform_config.h +++ b/platform/haiku/platform_config.h @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/haiku/power_haiku.cpp b/platform/haiku/power_haiku.cpp index d70aad9d5f..b0d01df982 100644 --- a/platform/haiku/power_haiku.cpp +++ b/platform/haiku/power_haiku.cpp @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/haiku/power_haiku.h b/platform/haiku/power_haiku.h index 8e7b050cd6..711ad86a02 100644 --- a/platform/haiku/power_haiku.h +++ b/platform/haiku/power_haiku.h @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/iphone/SCsub b/platform/iphone/SCsub index 5d3267cff3..466b8241de 100644 --- a/platform/iphone/SCsub +++ b/platform/iphone/SCsub @@ -5,7 +5,6 @@ Import('env') iphone_lib = [ 'os_iphone.cpp', - #'rasterizer_iphone.cpp', 'audio_driver_iphone.cpp', 'sem_iphone.cpp', 'gl_view.mm', diff --git a/platform/iphone/app_delegate.h b/platform/iphone/app_delegate.h index eaa74946ee..f357427144 100644 --- a/platform/iphone/app_delegate.h +++ b/platform/iphone/app_delegate.h @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/iphone/app_delegate.mm b/platform/iphone/app_delegate.mm index 00bb4b9fad..1f81f0f86e 100644 --- a/platform/iphone/app_delegate.mm +++ b/platform/iphone/app_delegate.mm @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -27,11 +28,12 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ #import "app_delegate.h" -#import "gl_view.h" -#include "os_iphone.h" #include "core/global_config.h" +#import "gl_view.h" #include "main/main.h" +#include "os_iphone.h" +#include "audio_driver_iphone.h" #ifdef MODULE_FACEBOOKSCORER_IOS_ENABLED #include "modules/FacebookScorer_ios/FacebookScorer.h" @@ -44,24 +46,26 @@ #endif #ifdef MODULE_PARSE_ENABLED -#import <Parse/Parse.h> #import "FBSDKCoreKit/FBSDKCoreKit.h" +#import <Parse/Parse.h> #endif -#define kFilteringFactor 0.1 -#define kRenderingFrequency 60 -#define kAccelerometerFrequency 100.0 // Hz +#import "GameController/GameController.h" + +#define kFilteringFactor 0.1 +#define kRenderingFrequency 60 +#define kAccelerometerFrequency 100.0 // Hz Error _shell_open(String); void _set_keep_screen_on(bool p_enabled); Error _shell_open(String p_uri) { - NSString* url = [[NSString alloc] initWithUTF8String:p_uri.utf8().get_data()]; + NSString *url = [[NSString alloc] initWithUTF8String:p_uri.utf8().get_data()]; - if (![[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:url]]) - return ERR_CANT_OPEN; + if (![[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:url]]) + return ERR_CANT_OPEN; - printf("opening url %ls\n", p_uri.c_str()); + printf("opening url %ls\n", p_uri.c_str()); [[UIApplication sharedApplication] openURL:[NSURL URLWithString:url]]; [url release]; return OK; @@ -76,325 +80,665 @@ void _set_keep_screen_on(bool p_enabled) { @synthesize window; extern int gargc; -extern char** gargv; -extern int iphone_main(int, int, int, char**); +extern char **gargv; +extern int iphone_main(int, int, int, char **); extern void iphone_finish(); CMMotionManager *motionManager; -bool motionInitialised; +bool motionInitialised; -static ViewController* mainViewController = nil; -+ (ViewController*) getViewController -{ +static ViewController *mainViewController = nil; ++ (ViewController *)getViewController { return mainViewController; } -static int frame_count = 0; -- (void)drawView:(GLView*)view; { +NSMutableDictionary *ios_joysticks = nil; + +- (GCControllerPlayerIndex)getFreePlayerIndex { + bool have_player_1 = false; + bool have_player_2 = false; + bool have_player_3 = false; + bool have_player_4 = false; + + if (ios_joysticks == nil) { + NSArray *keys = [ios_joysticks allKeys]; + for (NSNumber *key in keys) { + GCController *controller = [ios_joysticks objectForKey:key]; + if (controller.playerIndex == GCControllerPlayerIndex1) { + have_player_1 = true; + } else if (controller.playerIndex == GCControllerPlayerIndex2) { + have_player_2 = true; + } else if (controller.playerIndex == GCControllerPlayerIndex3) { + have_player_3 = true; + } else if (controller.playerIndex == GCControllerPlayerIndex4) { + have_player_4 = true; + }; + }; + }; - switch (frame_count) { + if (!have_player_1) { + return GCControllerPlayerIndex1; + } else if (!have_player_2) { + return GCControllerPlayerIndex2; + } else if (!have_player_3) { + return GCControllerPlayerIndex3; + } else if (!have_player_4) { + return GCControllerPlayerIndex4; + } else { + return GCControllerPlayerIndexUnset; + }; +}; - case 0: { - int backingWidth; - int backingHeight; - glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &backingWidth); - glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &backingHeight); +- (void)controllerWasConnected:(NSNotification *)notification { + // create our dictionary if we don't have one yet + if (ios_joysticks == nil) { + ios_joysticks = [[NSMutableDictionary alloc] init]; + }; + // get our controller + GCController *controller = (GCController *)notification.object; + if (controller == nil) { + printf("Couldn't retrieve new controller\n"); + } else if ([[ios_joysticks allKeysForObject:controller] count] != 0) { + printf("Controller is already registered\n"); + } else { + // get a new id for our controller + int joy_id = OSIPhone::get_singleton()->get_unused_joy_id(); + if (joy_id != -1) { + // assign our player index + if (controller.playerIndex == GCControllerPlayerIndexUnset) { + controller.playerIndex = [self getFreePlayerIndex]; + }; - OS::VideoMode vm; - vm.fullscreen = true; - vm.width = backingWidth; - vm.height = backingHeight; - vm.resizable = false; - OS::get_singleton()->set_video_mode(vm); + // tell Godot about our new controller + OSIPhone::get_singleton()->joy_connection_changed( + joy_id, true, [controller.vendorName UTF8String]); - if (!OS::get_singleton()) { - exit(0); + // add it to our dictionary, this will retain our controllers + [ios_joysticks setObject:controller + forKey:[NSNumber numberWithInt:joy_id]]; + + // set our input handler + [self setControllerInputHandler:controller]; + } else { + printf("Couldn't retrieve new joy id\n"); }; - ++frame_count; - - NSArray* paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); - NSString *documentsDirectory = [paths objectAtIndex:0]; - //NSString *documentsDirectory = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject]; - OSIPhone::get_singleton()->set_data_dir(String::utf8([documentsDirectory UTF8String])); - - NSString *locale_code = [[[NSLocale preferredLanguages] objectAtIndex:0] substringToIndex:2]; - OSIPhone::get_singleton()->set_locale(String::utf8([locale_code UTF8String])); - - NSString* uuid; - if ([[UIDevice currentDevice]respondsToSelector:@selector(identifierForVendor)]) { - uuid = [UIDevice currentDevice].identifierForVendor.UUIDString; - }else{ - - // before iOS 6, so just generate an identifier and store it - uuid = [[NSUserDefaults standardUserDefaults] objectForKey:@"identiferForVendor"]; - if( !uuid ) { - CFUUIDRef cfuuid = CFUUIDCreate(NULL); - uuid = (__bridge_transfer NSString*)CFUUIDCreateString(NULL, cfuuid); - CFRelease(cfuuid); - [[NSUserDefaults standardUserDefaults] setObject:uuid forKey:@"identifierForVendor"]; - } - } + }; +}; - OSIPhone::get_singleton()->set_unique_ID(String::utf8([uuid UTF8String])); +- (void)controllerWasDisconnected:(NSNotification *)notification { + if (ios_joysticks != nil) { + // find our joystick, there should be only one in our dictionary + GCController *controller = (GCController *)notification.object; + NSArray *keys = [ios_joysticks allKeysForObject:controller]; + for (NSNumber *key in keys) { + // tell Godot this joystick is no longer there + int joy_id = [key intValue]; + OSIPhone::get_singleton()->joy_connection_changed(joy_id, false, ""); + + // and remove it from our dictionary + [ios_joysticks removeObjectForKey:key]; + }; + }; +}; - }; break; -/* - case 1: { - ++frame_count; - } break; -*/ - case 1: { +- (int)getJoyIdForController:(GCController *)controller { + if (ios_joysticks != nil) { + // find our joystick, there should be only one in our dictionary + NSArray *keys = [ios_joysticks allKeysForObject:controller]; + for (NSNumber *key in keys) { + int joy_id = [key intValue]; + return joy_id; + }; + }; - Main::setup2(); - ++frame_count; + return -1; +}; - // this might be necessary before here - NSDictionary* dict = [[NSBundle mainBundle] infoDictionary]; - for (NSString* key in dict) { - NSObject* value = [dict objectForKey:key]; - String ukey = String::utf8([key UTF8String]); +- (void)setControllerInputHandler:(GCController *)controller { + // Hook in the callback handler for the correct gamepad profile. + // This is a bit of a weird design choice on Apples part. + // You need to select the most capable gamepad profile for the + // gamepad attached. + if (controller.extendedGamepad != nil) { + // The extended gamepad profile has all the input you could possibly find on + // a gamepad but will only be active if your gamepad actually has all of + // these... + controller.extendedGamepad.valueChangedHandler = ^( + GCExtendedGamepad *gamepad, GCControllerElement *element) { + int joy_id = [self getJoyIdForController:controller]; + + if (element == gamepad.buttonA) { + OSIPhone::get_singleton()->joy_button(joy_id, JOY_BUTTON_0, + gamepad.buttonA.isPressed); + } else if (element == gamepad.buttonB) { + OSIPhone::get_singleton()->joy_button(joy_id, JOY_BUTTON_1, + gamepad.buttonB.isPressed); + } else if (element == gamepad.buttonX) { + OSIPhone::get_singleton()->joy_button(joy_id, JOY_BUTTON_2, + gamepad.buttonX.isPressed); + } else if (element == gamepad.buttonY) { + OSIPhone::get_singleton()->joy_button(joy_id, JOY_BUTTON_3, + gamepad.buttonY.isPressed); + } else if (element == gamepad.leftShoulder) { + OSIPhone::get_singleton()->joy_button(joy_id, JOY_L, + gamepad.leftShoulder.isPressed); + } else if (element == gamepad.rightShoulder) { + OSIPhone::get_singleton()->joy_button(joy_id, JOY_R, + gamepad.rightShoulder.isPressed); + } else if (element == gamepad.leftTrigger) { + OSIPhone::get_singleton()->joy_button(joy_id, JOY_L2, + gamepad.leftTrigger.isPressed); + } else if (element == gamepad.rightTrigger) { + OSIPhone::get_singleton()->joy_button(joy_id, JOY_R2, + gamepad.rightTrigger.isPressed); + } else if (element == gamepad.dpad) { + OSIPhone::get_singleton()->joy_button(joy_id, JOY_DPAD_UP, + gamepad.dpad.up.isPressed); + OSIPhone::get_singleton()->joy_button(joy_id, JOY_DPAD_DOWN, + gamepad.dpad.down.isPressed); + OSIPhone::get_singleton()->joy_button(joy_id, JOY_DPAD_LEFT, + gamepad.dpad.left.isPressed); + OSIPhone::get_singleton()->joy_button(joy_id, JOY_DPAD_RIGHT, + gamepad.dpad.right.isPressed); + }; - // we need a NSObject to Variant conversor + InputDefault::JoyAxis jx; + jx.min = -1; + if (element == gamepad.leftThumbstick) { + jx.value = gamepad.leftThumbstick.xAxis.value; + OSIPhone::get_singleton()->joy_axis(joy_id, JOY_ANALOG_LX, jx); + jx.value = -gamepad.leftThumbstick.yAxis.value; + OSIPhone::get_singleton()->joy_axis(joy_id, JOY_ANALOG_LY, jx); + } else if (element == gamepad.rightThumbstick) { + jx.value = gamepad.rightThumbstick.xAxis.value; + OSIPhone::get_singleton()->joy_axis(joy_id, JOY_ANALOG_RX, jx); + jx.value = -gamepad.rightThumbstick.yAxis.value; + OSIPhone::get_singleton()->joy_axis(joy_id, JOY_ANALOG_RY, jx); + } else if (element == gamepad.leftTrigger) { + jx.value = gamepad.leftTrigger.value; + OSIPhone::get_singleton()->joy_axis(joy_id, JOY_ANALOG_L2, jx); + } else if (element == gamepad.rightTrigger) { + jx.value = gamepad.rightTrigger.value; + OSIPhone::get_singleton()->joy_axis(joy_id, JOY_ANALOG_R2, jx); + }; + }; + } else if (controller.gamepad != nil) { + // gamepad is the standard profile with 4 buttons, shoulder buttons and a + // D-pad + controller.gamepad.valueChangedHandler = ^(GCGamepad *gamepad, + GCControllerElement *element) { + int joy_id = [self getJoyIdForController:controller]; + + if (element == gamepad.buttonA) { + OSIPhone::get_singleton()->joy_button(joy_id, JOY_BUTTON_0, + gamepad.buttonA.isPressed); + } else if (element == gamepad.buttonB) { + OSIPhone::get_singleton()->joy_button(joy_id, JOY_BUTTON_1, + gamepad.buttonB.isPressed); + } else if (element == gamepad.buttonX) { + OSIPhone::get_singleton()->joy_button(joy_id, JOY_BUTTON_2, + gamepad.buttonX.isPressed); + } else if (element == gamepad.buttonY) { + OSIPhone::get_singleton()->joy_button(joy_id, JOY_BUTTON_3, + gamepad.buttonY.isPressed); + } else if (element == gamepad.leftShoulder) { + OSIPhone::get_singleton()->joy_button(joy_id, JOY_L, + gamepad.leftShoulder.isPressed); + } else if (element == gamepad.rightShoulder) { + OSIPhone::get_singleton()->joy_button(joy_id, JOY_R, + gamepad.rightShoulder.isPressed); + } else if (element == gamepad.dpad) { + OSIPhone::get_singleton()->joy_button(joy_id, JOY_DPAD_UP, + gamepad.dpad.up.isPressed); + OSIPhone::get_singleton()->joy_button(joy_id, JOY_DPAD_DOWN, + gamepad.dpad.down.isPressed); + OSIPhone::get_singleton()->joy_button(joy_id, JOY_DPAD_LEFT, + gamepad.dpad.left.isPressed); + OSIPhone::get_singleton()->joy_button(joy_id, JOY_DPAD_RIGHT, + gamepad.dpad.right.isPressed); + }; + }; +#ifdef ADD_MICRO_GAMEPAD // disabling this for now, only available on iOS 9+, + // while we are setting that as the minimum, seems our + // build environment doesn't like it + } else if (controller.microGamepad != nil) { + // micro gamepads were added in OS 9 and feature just 2 buttons and a d-pad + controller.microGamepad.valueChangedHandler = + ^(GCMicroGamepad *gamepad, GCControllerElement *element) { + int joy_id = [self getJoyIdForController:controller]; + + if (element == gamepad.buttonA) { + OSIPhone::get_singleton()->joy_button(joy_id, JOY_BUTTON_0, + gamepad.buttonA.isPressed); + } else if (element == gamepad.buttonX) { + OSIPhone::get_singleton()->joy_button(joy_id, JOY_BUTTON_2, + gamepad.buttonX.isPressed); + } else if (element == gamepad.dpad) { + OSIPhone::get_singleton()->joy_button(joy_id, JOY_DPAD_UP, + gamepad.dpad.up.isPressed); + OSIPhone::get_singleton()->joy_button(joy_id, JOY_DPAD_DOWN, + gamepad.dpad.down.isPressed); + OSIPhone::get_singleton()->joy_button(joy_id, JOY_DPAD_LEFT, + gamepad.dpad.left.isPressed); + OSIPhone::get_singleton()->joy_button(joy_id, JOY_DPAD_RIGHT, + gamepad.dpad.right.isPressed); + }; + }; +#endif + }; - if ([value isKindOfClass:[NSString class]]) { - NSString* str = (NSString*)value; - String uval = String::utf8([str UTF8String]); + ///@TODO need to add support for controller.motion which gives us access to + /// the orientation of the device (if supported) - GlobalConfig::get_singleton()->set("Info.plist/"+ukey, uval); + ///@TODO need to add support for controllerPausedHandler which should be a + /// toggle +}; - } else if ([value isKindOfClass:[NSNumber class]]) { +- (void)initGameControllers { + // get told when controllers connect, this will be called right away for + // already connected controllers + [[NSNotificationCenter defaultCenter] + addObserver:self + selector:@selector(controllerWasConnected:) + name:GCControllerDidConnectNotification + object:nil]; + + // get told when controllers disconnect + [[NSNotificationCenter defaultCenter] + addObserver:self + selector:@selector(controllerWasDisconnected:) + name:GCControllerDidDisconnectNotification + object:nil]; +}; + +- (void)deinitGameControllers { + [[NSNotificationCenter defaultCenter] + removeObserver:self + name:GCControllerDidConnectNotification + object:nil]; + [[NSNotificationCenter defaultCenter] + removeObserver:self + name:GCControllerDidDisconnectNotification + object:nil]; + + if (ios_joysticks != nil) { + [ios_joysticks dealloc]; + ios_joysticks = nil; + }; +}; - NSNumber* n = (NSNumber*)value; - double dval = [n doubleValue]; +static int frame_count = 0; +- (void)drawView:(GLView *)view; +{ - GlobalConfig::get_singleton()->set("Info.plist/"+ukey, dval); + switch (frame_count) { + case 0: { + int backingWidth; + int backingHeight; + glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, + GL_RENDERBUFFER_WIDTH_OES, &backingWidth); + glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, + GL_RENDERBUFFER_HEIGHT_OES, &backingHeight); + + OS::VideoMode vm; + vm.fullscreen = true; + vm.width = backingWidth; + vm.height = backingHeight; + vm.resizable = false; + OS::get_singleton()->set_video_mode(vm); + + if (!OS::get_singleton()) { + exit(0); }; - // do stuff - } + ++frame_count; + + NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, + NSUserDomainMask, YES); + NSString *documentsDirectory = [paths objectAtIndex:0]; + // NSString *documentsDirectory = [[[NSFileManager defaultManager] + // URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] + // lastObject]; + OSIPhone::get_singleton()->set_data_dir( + String::utf8([documentsDirectory UTF8String])); + + NSString *locale_code = [[NSLocale currentLocale] localeIdentifier]; + OSIPhone::get_singleton()->set_locale( + String::utf8([locale_code UTF8String])); + + NSString *uuid; + if ([[UIDevice currentDevice] + respondsToSelector:@selector(identifierForVendor)]) { + uuid = [UIDevice currentDevice].identifierForVendor.UUIDString; + } else { + // before iOS 6, so just generate an identifier and store it + uuid = [[NSUserDefaults standardUserDefaults] + objectForKey:@"identiferForVendor"]; + if (!uuid) { + CFUUIDRef cfuuid = CFUUIDCreate(NULL); + uuid = (__bridge_transfer NSString *)CFUUIDCreateString(NULL, cfuuid); + CFRelease(cfuuid); + [[NSUserDefaults standardUserDefaults] + setObject:uuid + forKey:@"identifierForVendor"]; + } + } - } break; -/* - case 3: { - ++frame_count; - } break; + OSIPhone::get_singleton()->set_unique_ID(String::utf8([uuid UTF8String])); + + }; break; + /* + case 1: { + ++frame_count; + }; break; */ - case 2: { - - Main::start(); - ++frame_count; - - }; break; // no fallthrough - - default: { - if (OSIPhone::get_singleton()) { -// OSIPhone::get_singleton()->update_accelerometer(accel[0], accel[1], accel[2]); - if (motionInitialised) { - // Just using polling approach for now, we can set this up so it sends data to us in intervals, might be better. - // See Apple reference pages for more details: - // https://developer.apple.com/reference/coremotion/cmmotionmanager?language=objc - - // Apple splits our accelerometer date into a gravity and user movement component. We add them back together - CMAcceleration gravity = motionManager.deviceMotion.gravity; - CMAcceleration acceleration = motionManager.deviceMotion.userAcceleration; - - ///@TODO We don't seem to be getting data here, is my device broken or is this code incorrect? - CMMagneticField magnetic = motionManager.deviceMotion.magneticField.field; - - ///@TODO we can access rotationRate as a CMRotationRate variable (processed date) or CMGyroData (raw data), have to see what works best - CMRotationRate rotation = motionManager.deviceMotion.rotationRate; - - // Adjust for screen orientation. - // [[UIDevice currentDevice] orientation] changes even if we've fixed our orientation which is not - // a good thing when you're trying to get your user to move the screen in all directions and want consistent output - - ///@TODO Using [[UIApplication sharedApplication] statusBarOrientation] is a bit of a hack. Godot obviously knows the orientation so maybe we - // can use that instead? (note that left and right seem swapped) - - switch ([[UIApplication sharedApplication] statusBarOrientation]) { - case UIDeviceOrientationLandscapeLeft: { - OSIPhone::get_singleton()->update_gravity(-gravity.y, gravity.x, gravity.z); - OSIPhone::get_singleton()->update_accelerometer(-(acceleration.y + gravity.y), (acceleration.x + gravity.x), acceleration.z + gravity.z); - OSIPhone::get_singleton()->update_magnetometer(-magnetic.y, magnetic.x, magnetic.z); - OSIPhone::get_singleton()->update_gyroscope(-rotation.y, rotation.x, rotation.z); - }; break; - case UIDeviceOrientationLandscapeRight: { - OSIPhone::get_singleton()->update_gravity(gravity.y, -gravity.x, gravity.z); - OSIPhone::get_singleton()->update_accelerometer((acceleration.y + gravity.y), -(acceleration.x + gravity.x), acceleration.z + gravity.z); - OSIPhone::get_singleton()->update_magnetometer(magnetic.y, -magnetic.x, magnetic.z); - OSIPhone::get_singleton()->update_gyroscope(rotation.y, -rotation.x, rotation.z); - }; break; - case UIDeviceOrientationPortraitUpsideDown: { - OSIPhone::get_singleton()->update_gravity(-gravity.x, gravity.y, gravity.z); - OSIPhone::get_singleton()->update_accelerometer(-(acceleration.x + gravity.x), (acceleration.y + gravity.y), acceleration.z + gravity.z); - OSIPhone::get_singleton()->update_magnetometer(-magnetic.x, magnetic.y, magnetic.z); - OSIPhone::get_singleton()->update_gyroscope(-rotation.x, rotation.y, rotation.z); - }; break; - default: { // assume portrait - OSIPhone::get_singleton()->update_gravity(gravity.x, gravity.y, gravity.z); - OSIPhone::get_singleton()->update_accelerometer(acceleration.x + gravity.x, acceleration.y + gravity.y, acceleration.z + gravity.z); - OSIPhone::get_singleton()->update_magnetometer(magnetic.x, magnetic.y, magnetic.z); - OSIPhone::get_singleton()->update_gyroscope(rotation.x, rotation.y, rotation.z); - }; break; + case 1: { + + Main::setup2(); + ++frame_count; + + // this might be necessary before here + NSDictionary *dict = [[NSBundle mainBundle] infoDictionary]; + for (NSString *key in dict) { + NSObject *value = [dict objectForKey:key]; + String ukey = String::utf8([key UTF8String]); + + // we need a NSObject to Variant conversor + + if ([value isKindOfClass:[NSString class]]) { + NSString *str = (NSString *)value; + String uval = String::utf8([str UTF8String]); + + GlobalConfig::get_singleton()->set("Info.plist/" + ukey, uval); + + } else if ([value isKindOfClass:[NSNumber class]]) { + + NSNumber *n = (NSNumber *)value; + double dval = [n doubleValue]; + + GlobalConfig::get_singleton()->set("Info.plist/" + ukey, dval); }; + // do stuff } - bool quit_request = OSIPhone::get_singleton()->iterate(); - }; - - }; + }; break; + /* + case 3: { + ++frame_count; + }; break; +*/ + case 2: { + + Main::start(); + ++frame_count; + + }; break; // no fallthrough + + default: { + if (OSIPhone::get_singleton()) { + // OSIPhone::get_singleton()->update_accelerometer(accel[0], accel[1], + // accel[2]); + if (motionInitialised) { + // Just using polling approach for now, we can set this up so it sends + // data to us in intervals, might be better. See Apple reference pages + // for more details: + // https://developer.apple.com/reference/coremotion/cmmotionmanager?language=objc + + // Apple splits our accelerometer date into a gravity and user movement + // component. We add them back together + CMAcceleration gravity = motionManager.deviceMotion.gravity; + CMAcceleration acceleration = + motionManager.deviceMotion.userAcceleration; + + ///@TODO We don't seem to be getting data here, is my device broken or + /// is this code incorrect? + CMMagneticField magnetic = + motionManager.deviceMotion.magneticField.field; + + ///@TODO we can access rotationRate as a CMRotationRate variable + ///(processed date) or CMGyroData (raw data), have to see what works + /// best + CMRotationRate rotation = motionManager.deviceMotion.rotationRate; + + // Adjust for screen orientation. + // [[UIDevice currentDevice] orientation] changes even if we've fixed + // our orientation which is not a good thing when you're trying to get + // your user to move the screen in all directions and want consistent + // output + + ///@TODO Using [[UIApplication sharedApplication] statusBarOrientation] + /// is a bit of a hack. Godot obviously knows the orientation so maybe + /// we + // can use that instead? (note that left and right seem swapped) + + switch ([[UIApplication sharedApplication] statusBarOrientation]) { + case UIDeviceOrientationLandscapeLeft: { + OSIPhone::get_singleton()->update_gravity(-gravity.y, gravity.x, + gravity.z); + OSIPhone::get_singleton()->update_accelerometer( + -(acceleration.y + gravity.y), (acceleration.x + gravity.x), + acceleration.z + gravity.z); + OSIPhone::get_singleton()->update_magnetometer( + -magnetic.y, magnetic.x, magnetic.z); + OSIPhone::get_singleton()->update_gyroscope(-rotation.y, rotation.x, + rotation.z); + }; break; + case UIDeviceOrientationLandscapeRight: { + OSIPhone::get_singleton()->update_gravity(gravity.y, -gravity.x, + gravity.z); + OSIPhone::get_singleton()->update_accelerometer( + (acceleration.y + gravity.y), -(acceleration.x + gravity.x), + acceleration.z + gravity.z); + OSIPhone::get_singleton()->update_magnetometer( + magnetic.y, -magnetic.x, magnetic.z); + OSIPhone::get_singleton()->update_gyroscope(rotation.y, -rotation.x, + rotation.z); + }; break; + case UIDeviceOrientationPortraitUpsideDown: { + OSIPhone::get_singleton()->update_gravity(-gravity.x, gravity.y, + gravity.z); + OSIPhone::get_singleton()->update_accelerometer( + -(acceleration.x + gravity.x), (acceleration.y + gravity.y), + acceleration.z + gravity.z); + OSIPhone::get_singleton()->update_magnetometer( + -magnetic.x, magnetic.y, magnetic.z); + OSIPhone::get_singleton()->update_gyroscope(-rotation.x, rotation.y, + rotation.z); + }; break; + default: { // assume portrait + OSIPhone::get_singleton()->update_gravity(gravity.x, gravity.y, + gravity.z); + OSIPhone::get_singleton()->update_accelerometer( + acceleration.x + gravity.x, acceleration.y + gravity.y, + acceleration.z + gravity.z); + OSIPhone::get_singleton()->update_magnetometer(magnetic.x, magnetic.y, + magnetic.z); + OSIPhone::get_singleton()->update_gyroscope(rotation.x, rotation.y, + rotation.z); + }; break; + }; + } + + bool quit_request = OSIPhone::get_singleton()->iterate(); + }; + }; break; }; }; - (void)applicationDidReceiveMemoryWarning:(UIApplication *)application { printf("****************** did receive memory warning!\n"); - OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_OS_MEMORY_WARNING); + OS::get_singleton()->get_main_loop()->notification( + MainLoop::NOTIFICATION_OS_MEMORY_WARNING); }; -- (void)applicationDidFinishLaunching:(UIApplication*)application { +- (void)applicationDidFinishLaunching:(UIApplication *)application { printf("**************** app delegate init\n"); CGRect rect = [[UIScreen mainScreen] bounds]; [application setStatusBarHidden:YES withAnimation:UIStatusBarAnimationNone]; // disable idle timer - //application.idleTimerDisabled = YES; + // application.idleTimerDisabled = YES; - //Create a full-screen window + // Create a full-screen window window = [[UIWindow alloc] initWithFrame:rect]; - //window.autoresizesSubviews = YES; - //[window setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleWidth]; + // window.autoresizesSubviews = YES; + //[window setAutoresizingMask:UIViewAutoresizingFlexibleWidth | + // UIViewAutoresizingFlexibleWidth]; - //Create the OpenGL ES view and add it to the window + // Create the OpenGL ES view and add it to the window GLView *glView = [[GLView alloc] initWithFrame:rect]; printf("glview is %p\n", glView); //[window addSubview:glView]; glView.delegate = self; - //glView.autoresizesSubviews = YES; - //[glView setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleWidth]; + // glView.autoresizesSubviews = YES; + //[glView setAutoresizingMask:UIViewAutoresizingFlexibleWidth | + // UIViewAutoresizingFlexibleWidth]; int backingWidth; int backingHeight; - glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &backingWidth); - glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &backingHeight); - - iphone_main(backingWidth, backingHeight, gargc, gargv); + glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, + GL_RENDERBUFFER_WIDTH_OES, &backingWidth); + glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, + GL_RENDERBUFFER_HEIGHT_OES, &backingHeight); + + int err = iphone_main(backingWidth, backingHeight, gargc, gargv); + if (err != 0) { + // bail, things did not go very well for us, should probably output a message on screen with our error code... + exit(0); + return; + }; view_controller = [[ViewController alloc] init]; view_controller.view = glView; window.rootViewController = view_controller; - _set_keep_screen_on(bool(GLOBAL_DEF("display/keep_screen_on",true)) ? YES : NO); - glView.useCADisplayLink = bool(GLOBAL_DEF("display.iOS/use_cadisplaylink",true)) ? YES : NO; + _set_keep_screen_on(bool(GLOBAL_DEF("display/keep_screen_on", true)) ? YES : NO); + glView.useCADisplayLink = + bool(GLOBAL_DEF("display.iOS/use_cadisplaylink", true)) ? YES : NO; printf("cadisaplylink: %d", glView.useCADisplayLink); glView.animationInterval = 1.0 / kRenderingFrequency; [glView startAnimation]; - //Show the window + // Show the window [window makeKeyAndVisible]; - //Configure and start accelerometer + // Configure and start accelerometer if (!motionInitialised) { motionManager = [[CMMotionManager alloc] init]; if (motionManager.deviceMotionAvailable) { - motionManager.deviceMotionUpdateInterval = 1.0/70.0; - [motionManager startDeviceMotionUpdates]; + motionManager.deviceMotionUpdateInterval = 1.0 / 70.0; + [motionManager startDeviceMotionUpdatesUsingReferenceFrame: + CMAttitudeReferenceFrameXMagneticNorthZVertical]; motionInitialised = YES; }; }; - //OSIPhone::screen_width = rect.size.width - rect.origin.x; - //OSIPhone::screen_height = rect.size.height - rect.origin.y; + [self initGameControllers]; + + // OSIPhone::screen_width = rect.size.width - rect.origin.x; + // OSIPhone::screen_height = rect.size.height - rect.origin.y; mainViewController = view_controller; #ifdef MODULE_GAME_ANALYTICS_ENABLED - printf("********************* didFinishLaunchingWithOptions\n"); - if(!GlobalConfig::get_singleton()->has("mobileapptracker/advertiser_id")) - { - return; - } - if(!GlobalConfig::get_singleton()->has("mobileapptracker/conversion_key")) - { - return; - } - - String adid = GLOBAL_DEF("mobileapptracker/advertiser_id",""); - String convkey = GLOBAL_DEF("mobileapptracker/conversion_key",""); - - NSString * advertiser_id = [NSString stringWithUTF8String:adid.utf8().get_data()]; - NSString * conversion_key = [NSString stringWithUTF8String:convkey.utf8().get_data()]; - - // Account Configuration info - must be set - [MobileAppTracker initializeWithMATAdvertiserId:advertiser_id - MATConversionKey:conversion_key]; - - // Used to pass us the IFA, enables highly accurate 1-to-1 attribution. - // Required for many advertising networks. - [MobileAppTracker setAppleAdvertisingIdentifier:[[ASIdentifierManager sharedManager] advertisingIdentifier] - advertisingTrackingEnabled:[[ASIdentifierManager sharedManager] isAdvertisingTrackingEnabled]]; + printf("********************* didFinishLaunchingWithOptions\n"); + if (!GlobalConfig::get_singleton()->has("mobileapptracker/advertiser_id")) { + return; + } + if (!GlobalConfig::get_singleton()->has("mobileapptracker/conversion_key")) { + return; + } + + String adid = GLOBAL_DEF("mobileapptracker/advertiser_id", ""); + String convkey = GLOBAL_DEF("mobileapptracker/conversion_key", ""); + + NSString *advertiser_id = + [NSString stringWithUTF8String:adid.utf8().get_data()]; + NSString *conversion_key = + [NSString stringWithUTF8String:convkey.utf8().get_data()]; + + // Account Configuration info - must be set + [MobileAppTracker initializeWithMATAdvertiserId:advertiser_id + MATConversionKey:conversion_key]; + + // Used to pass us the IFA, enables highly accurate 1-to-1 attribution. + // Required for many advertising networks. + [MobileAppTracker + setAppleAdvertisingIdentifier:[[ASIdentifierManager sharedManager] + advertisingIdentifier] + advertisingTrackingEnabled:[[ASIdentifierManager sharedManager] + isAdvertisingTrackingEnabled]]; #endif }; -- (void)applicationWillTerminate:(UIApplication*)application { +- (void)applicationWillTerminate:(UIApplication *)application { printf("********************* will terminate\n"); + [self deinitGameControllers]; + if (motionInitialised) { ///@TODO is this the right place to clean this up? [motionManager stopDeviceMotionUpdates]; [motionManager release]; motionManager = nil; - motionInitialised = NO; + motionInitialised = NO; }; iphone_finish(); }; -- (void)applicationDidEnterBackground:(UIApplication *)application -{ +- (void)applicationDidEnterBackground:(UIApplication *)application { printf("********************* did enter background\n"); ///@TODO maybe add pause motionManager? and where would we unpause it? if (OS::get_singleton()->get_main_loop()) - OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_WM_FOCUS_OUT); + OS::get_singleton()->get_main_loop()->notification( + MainLoop::NOTIFICATION_WM_FOCUS_OUT); + [view_controller.view stopAnimation]; if (OS::get_singleton()->native_video_is_playing()) { OSIPhone::get_singleton()->native_video_focus_out(); }; } -- (void)applicationWillEnterForeground:(UIApplication *)application -{ +- (void)applicationWillEnterForeground:(UIApplication *)application { printf("********************* did enter foreground\n"); - //OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_WM_FOCUS_IN); + // OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_WM_FOCUS_IN); [view_controller.view startAnimation]; } -- (void) applicationWillResignActive:(UIApplication *)application -{ +- (void)applicationWillResignActive:(UIApplication *)application { printf("********************* will resign active\n"); - //OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_WM_FOCUS_OUT); - [view_controller.view stopAnimation]; // FIXME: pause seems to be recommended elsewhere + // OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_WM_FOCUS_OUT); + [view_controller.view + stopAnimation]; // FIXME: pause seems to be recommended elsewhere } -- (void) applicationDidBecomeActive:(UIApplication *)application -{ +- (void)applicationDidBecomeActive:(UIApplication *)application { printf("********************* did become active\n"); #ifdef MODULE_GAME_ANALYTICS_ENABLED - printf("********************* mobile app tracker found\n"); + printf("********************* mobile app tracker found\n"); [MobileAppTracker measureSession]; #endif if (OS::get_singleton()->get_main_loop()) - OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_WM_FOCUS_IN); - [view_controller.view startAnimation]; // FIXME: resume seems to be recommended elsewhere + OS::get_singleton()->get_main_loop()->notification( + MainLoop::NOTIFICATION_WM_FOCUS_IN); + + [view_controller.view + startAnimation]; // FIXME: resume seems to be recommended elsewhere if (OSIPhone::get_singleton()->native_video_is_playing()) { OSIPhone::get_singleton()->native_video_unpause(); }; + + // Fixed audio can not resume if it is interrupted cause by an incoming phone call + if(AudioDriverIphone::get_singleton() != NULL) + AudioDriverIphone::get_singleton()->start(); } - (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url { @@ -406,16 +750,19 @@ static int frame_count = 0; } // For 4.2+ support -- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation { +- (BOOL)application:(UIApplication *)application + openURL:(NSURL *)url + sourceApplication:(NSString *)sourceApplication + annotation:(id)annotation { #ifdef MODULE_PARSE_ENABLED NSLog(@"Handling application openURL"); - return [[FBSDKApplicationDelegate sharedInstance] application:application - openURL:url - sourceApplication:sourceApplication - annotation:annotation]; + return + [[FBSDKApplicationDelegate sharedInstance] application:application + openURL:url + sourceApplication:sourceApplication + annotation:annotation]; #endif - #ifdef MODULE_FACEBOOKSCORER_IOS_ENABLED return [[[FacebookScorer sharedInstance] facebook] handleOpenURL:url]; #else @@ -423,21 +770,25 @@ static int frame_count = 0; #endif } -- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { +- (void)application:(UIApplication *)application + didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { #ifdef MODULE_PARSE_ENABLED // Store the deviceToken in the current installation and save it to Parse. PFInstallation *currentInstallation = [PFInstallation currentInstallation]; - //NSString* token = [[NSString alloc] initWithData:deviceToken encoding:NSUTF8StringEncoding]; + // NSString* token = [[NSString alloc] initWithData:deviceToken + // encoding:NSUTF8StringEncoding]; NSLog(@"Device Token : %@ ", deviceToken); [currentInstallation setDeviceTokenFromData:deviceToken]; [currentInstallation saveInBackground]; #endif } -- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo { +- (void)application:(UIApplication *)application + didReceiveRemoteNotification:(NSDictionary *)userInfo { #ifdef MODULE_PARSE_ENABLED [PFPush handlePush:userInfo]; - NSDictionary *aps = [userInfo objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey]; + NSDictionary *aps = + [userInfo objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey]; NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; NSLog(@"Push Notification Payload (app active) %@", aps); @@ -449,8 +800,7 @@ static int frame_count = 0; #endif } -- (void)dealloc -{ +- (void)dealloc { [window release]; [super dealloc]; } diff --git a/platform/iphone/audio_driver_iphone.cpp b/platform/iphone/audio_driver_iphone.cpp index eff91fa40f..57b6388016 100644 --- a/platform/iphone/audio_driver_iphone.cpp +++ b/platform/iphone/audio_driver_iphone.cpp @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -147,6 +148,11 @@ OSStatus AudioDriverIphone::output_callback(void *inRefCon, void AudioDriverIphone::start() { active = true; + // Resume audio + // iOS audio-thread stoped if it is interrupted cause by an incoming phone call + // Use AudioOutputUnitStart to re-create audio-thread + OSStatus result = AudioOutputUnitStart(audio_unit); + ERR_FAIL_COND(result != noErr); }; int AudioDriverIphone::get_mix_rate() const { diff --git a/platform/iphone/audio_driver_iphone.h b/platform/iphone/audio_driver_iphone.h index 8a0d92e070..c620e9068c 100644 --- a/platform/iphone/audio_driver_iphone.h +++ b/platform/iphone/audio_driver_iphone.h @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/iphone/detect.py b/platform/iphone/detect.py index fa6082a5a7..c20d8e90f4 100644 --- a/platform/iphone/detect.py +++ b/platform/iphone/detect.py @@ -30,7 +30,7 @@ def get_opts(): ('store_kit', 'Support for in-app store', 'yes'), ('icloud', 'Support for iCloud', 'yes'), ('ios_gles22_override', 'Force GLES2.0 on iOS', 'yes'), - ('ios_exceptions', 'Use exceptions when compiling on playbook', 'yes'), + ('ios_exceptions', 'Enable exceptions', 'no'), ('ios_triple', 'Triple for ios toolchain', ''), ('ios_sim', 'Build simulator binary', 'no'), ] @@ -58,16 +58,17 @@ def configure(env): if (env["ios_sim"] == "yes" or env["arch"] == "x86"): # i386, simulator env["arch"] = "x86" env["bits"] = "32" - env['CCFLAGS'] = string.split('-arch i386 -fobjc-abi-version=2 -fobjc-legacy-dispatch -fmessage-length=0 -fpascal-strings -fasm-blocks -Wall -D__IPHONE_OS_VERSION_MIN_REQUIRED=40100 -isysroot $IPHONESDK -mios-simulator-version-min=4.3 -DCUSTOM_MATRIX_TRANSFORM_H=\\\"build/iphone/matrix4_iphone.h\\\" -DCUSTOM_VECTOR3_TRANSFORM_H=\\\"build/iphone/vector3_iphone.h\\\"') - elif (env["arch"] == "arm64"): # arm64 + env.Append(CCFLAGS=string.split('-arch i386 -fobjc-abi-version=2 -fobjc-legacy-dispatch -fmessage-length=0 -fpascal-strings -fblocks -fasm-blocks -D__IPHONE_OS_VERSION_MIN_REQUIRED=40100 -isysroot $IPHONESDK -mios-simulator-version-min=4.3 -DCUSTOM_MATRIX_TRANSFORM_H=\\\"build/iphone/matrix4_iphone.h\\\" -DCUSTOM_VECTOR3_TRANSFORM_H=\\\"build/iphone/vector3_iphone.h\\\"')) + elif (env["arch"] == "arm" or env["arch"] == "arm32" or env["arch"] == "armv7" or env["bits"] == "32"): # arm + env["arch"] = "arm" + env["bits"] = "32" + env.Append(CCFLAGS=string.split('-fno-objc-arc -arch armv7 -fmessage-length=0 -fno-strict-aliasing -fdiagnostics-print-source-range-info -fdiagnostics-show-category=id -fdiagnostics-parseable-fixits -fpascal-strings -fblocks -isysroot $IPHONESDK -fvisibility=hidden -mthumb "-DIBOutlet=__attribute__((iboutlet))" "-DIBOutletCollection(ClassName)=__attribute__((iboutletcollection(ClassName)))" "-DIBAction=void)__attribute__((ibaction)" -miphoneos-version-min=9.0 -MMD -MT dependencies')) + else: # armv64 + env["arch"] = "arm64" env["bits"] = "64" - env['CCFLAGS'] = string.split('-fno-objc-arc -arch arm64 -fmessage-length=0 -fno-strict-aliasing -fdiagnostics-print-source-range-info -fdiagnostics-show-category=id -fdiagnostics-parseable-fixits -Wno-trigraphs -fpascal-strings -Wmissing-prototypes -Wreturn-type -Wparentheses -Wswitch -Wno-unused-parameter -Wunused-variable -Wunused-value -Wno-shorten-64-to-32 -fvisibility=hidden -Wno-sign-conversion -MMD -MT dependencies -miphoneos-version-min=7.0 -isysroot $IPHONESDK') + env.Append(CCFLAGS=string.split('-fno-objc-arc -arch arm64 -fmessage-length=0 -fno-strict-aliasing -fdiagnostics-print-source-range-info -fdiagnostics-show-category=id -fdiagnostics-parseable-fixits -fpascal-strings -fblocks -fvisibility=hidden -MMD -MT dependencies -miphoneos-version-min=9.0 -isysroot $IPHONESDK')) env.Append(CPPFLAGS=['-DNEED_LONG_INT']) env.Append(CPPFLAGS=['-DLIBYUV_DISABLE_NEON']) - else: # armv7 - env["arch"] = "arm" - env["bits"] = "32" - env['CCFLAGS'] = string.split('-fno-objc-arc -arch armv7 -fmessage-length=0 -fno-strict-aliasing -fdiagnostics-print-source-range-info -fdiagnostics-show-category=id -fdiagnostics-parseable-fixits -Wno-trigraphs -fpascal-strings -Wmissing-prototypes -Wreturn-type -Wparentheses -Wswitch -Wno-unused-parameter -Wunused-variable -Wunused-value -Wno-shorten-64-to-32 -isysroot $IPHONESDK -fvisibility=hidden -Wno-sign-conversion -mthumb "-DIBOutlet=__attribute__((iboutlet))" "-DIBOutletCollection(ClassName)=__attribute__((iboutletcollection(ClassName)))" "-DIBAction=void)__attribute__((ibaction)" -miphoneos-version-min=7.0 -MMD -MT dependencies -isysroot $IPHONESDK') if (env["arch"] == "x86"): env['IPHONEPLATFORM'] = 'iPhoneSimulator' @@ -90,10 +91,11 @@ def configure(env): '-framework', 'OpenGLES', '-framework', 'QuartzCore', '-framework', 'SystemConfiguration', + '-framework', 'GameController', '-F$IPHONESDK', ]) elif (env["arch"] == "arm64"): - env.Append(LINKFLAGS=['-arch', 'arm64', '-Wl,-dead_strip', '-miphoneos-version-min=7.0', + env.Append(LINKFLAGS=['-arch', 'arm64', '-Wl,-dead_strip', '-miphoneos-version-min=9.0', '-isysroot', '$IPHONESDK', #'-stdlib=libc++', '-framework', 'Foundation', @@ -110,9 +112,10 @@ def configure(env): '-framework', 'AVFoundation', '-framework', 'CoreMedia', '-framework', 'CoreMotion', + '-framework', 'GameController', ]) else: - env.Append(LINKFLAGS=['-arch', 'armv7', '-Wl,-dead_strip', '-miphoneos-version-min=7.0', + env.Append(LINKFLAGS=['-arch', 'armv7', '-Wl,-dead_strip', '-miphoneos-version-min=9.0', '-isysroot', '$IPHONESDK', '-framework', 'Foundation', '-framework', 'UIKit', @@ -128,10 +131,11 @@ def configure(env): '-framework', 'AVFoundation', '-framework', 'CoreMedia', '-framework', 'CoreMotion', + '-framework', 'GameController', ]) if env['game_center'] == 'yes': - env.Append(CPPFLAGS=['-fblocks', '-DGAME_CENTER_ENABLED']) + env.Append(CPPFLAGS=['-DGAME_CENTER_ENABLED']) env.Append(LINKFLAGS=['-framework', 'GameKit']) if env['store_kit'] == 'yes': @@ -143,26 +147,20 @@ def configure(env): env.Append(CPPPATH=['$IPHONESDK/usr/include', '$IPHONESDK/System/Library/Frameworks/OpenGLES.framework/Headers', '$IPHONESDK/System/Library/Frameworks/AudioUnit.framework/Headers']) - if (env["target"] == "release"): + if (env["target"].startswith("release")): - env.Append(CCFLAGS=['-O3', '-DNS_BLOCK_ASSERTIONS=1', '-Wall', '-gdwarf-2']) # removed -ffast-math - env.Append(LINKFLAGS=['-O3']) + env.Append(CPPFLAGS=['-DNDEBUG', '-DNS_BLOCK_ASSERTIONS=1']) + env.Append(CPPFLAGS=['-O2', '-flto', '-ftree-vectorize', '-fomit-frame-pointer', '-ffast-math', '-funsafe-math-optimizations']) + env.Append(LINKFLAGS=['-O2', '-flto']) - elif env["target"] == "release_debug": - env.Append(CCFLAGS=['-Os', '-DNS_BLOCK_ASSERTIONS=1', '-Wall', '-DDEBUG_ENABLED']) - env.Append(LINKFLAGS=['-Os']) - env.Append(CPPFLAGS=['-DDEBUG_MEMORY_ENABLED']) + if env["target"] == "release_debug": + env.Append(CPPFLAGS=['-DDEBUG_ENABLED']) elif (env["target"] == "debug"): - env.Append(CCFLAGS=['-D_DEBUG', '-DDEBUG=1', '-gdwarf-2', '-Wall', '-O0', '-DDEBUG_ENABLED']) + env.Append(CPPFLAGS=['-D_DEBUG', '-DDEBUG=1', '-gdwarf-2', '-O0', '-DDEBUG_ENABLED']) env.Append(CPPFLAGS=['-DDEBUG_MEMORY_ENABLED']) - elif (env["target"] == "profile"): - - env.Append(CCFLAGS=['-g', '-pg', '-Os']) - env.Append(LINKFLAGS=['-pg']) - if (env["ios_sim"] == "yes"): # TODO: Check if needed? env['ENV']['MACOSX_DEPLOYMENT_TARGET'] = '10.6' env['ENV']['CODESIGN_ALLOCATE'] = '/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/codesign_allocate' diff --git a/platform/iphone/game_center.h b/platform/iphone/game_center.h index a732a97a4c..cda6f78a1f 100644 --- a/platform/iphone/game_center.h +++ b/platform/iphone/game_center.h @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/iphone/game_center.mm b/platform/iphone/game_center.mm index 4cfa64ae4b..f9bc70b7c4 100644 --- a/platform/iphone/game_center.mm +++ b/platform/iphone/game_center.mm @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -45,24 +46,23 @@ extern "C" { #import "app_delegate.h" }; -GameCenter* GameCenter::instance = NULL; +GameCenter *GameCenter::instance = NULL; void GameCenter::_bind_methods() { - ClassDB::bind_method(D_METHOD("connect"),&GameCenter::connect); - ClassDB::bind_method(D_METHOD("is_connected"),&GameCenter::is_connected); - - ClassDB::bind_method(D_METHOD("post_score"),&GameCenter::post_score); - ClassDB::bind_method(D_METHOD("award_achievement"),&GameCenter::award_achievement); - ClassDB::bind_method(D_METHOD("reset_achievements"),&GameCenter::reset_achievements); - ClassDB::bind_method(D_METHOD("request_achievements"),&GameCenter::request_achievements); - ClassDB::bind_method(D_METHOD("request_achievement_descriptions"),&GameCenter::request_achievement_descriptions); - ClassDB::bind_method(D_METHOD("show_game_center"),&GameCenter::show_game_center); - - ClassDB::bind_method(D_METHOD("get_pending_event_count"),&GameCenter::get_pending_event_count); - ClassDB::bind_method(D_METHOD("pop_pending_event"),&GameCenter::pop_pending_event); + ClassDB::bind_method(D_METHOD("connect"), &GameCenter::connect); + ClassDB::bind_method(D_METHOD("is_connected"), &GameCenter::is_connected); + + ClassDB::bind_method(D_METHOD("post_score"), &GameCenter::post_score); + ClassDB::bind_method(D_METHOD("award_achievement"), &GameCenter::award_achievement); + ClassDB::bind_method(D_METHOD("reset_achievements"), &GameCenter::reset_achievements); + ClassDB::bind_method(D_METHOD("request_achievements"), &GameCenter::request_achievements); + ClassDB::bind_method(D_METHOD("request_achievement_descriptions"), &GameCenter::request_achievement_descriptions); + ClassDB::bind_method(D_METHOD("show_game_center"), &GameCenter::show_game_center); + + ClassDB::bind_method(D_METHOD("get_pending_event_count"), &GameCenter::get_pending_event_count); + ClassDB::bind_method(D_METHOD("pop_pending_event"), &GameCenter::pop_pending_event); }; - Error GameCenter::connect() { //if this class isn't available, game center isn't implemented @@ -71,33 +71,34 @@ Error GameCenter::connect() { return ERR_UNAVAILABLE; } - GKLocalPlayer* player = [GKLocalPlayer localPlayer]; + GKLocalPlayer *player = [GKLocalPlayer localPlayer]; ERR_FAIL_COND_V(![player respondsToSelector:@selector(authenticateHandler)], ERR_UNAVAILABLE); - ViewController *root_controller=(ViewController *)((AppDelegate *)[[UIApplication sharedApplication] delegate]).window.rootViewController; + ViewController *root_controller = (ViewController *)((AppDelegate *)[[UIApplication sharedApplication] delegate]).window.rootViewController; ERR_FAIL_COND_V(!root_controller, FAILED); - //this handler is called serveral times. first when the view needs to be shown, then again after the view is cancelled or the user logs in. or if the user's already logged in, it's called just once to confirm they're authenticated. This is why no result needs to be specified in the presentViewController phase. in this case, more calls to this function will follow. + // This handler is called several times. First when the view needs to be shown, then again + // after the view is cancelled or the user logs in. Or if the user's already logged in, it's + // called just once to confirm they're authenticated. This is why no result needs to be specified + // in the presentViewController phase. In this case, more calls to this function will follow. player.authenticateHandler = (^(UIViewController *controller, NSError *error) { - if (controller) { - [root_controller presentViewController:controller animated:YES completion:nil]; - } - else { - Dictionary ret; - ret["type"] = "authentication"; - if (player.isAuthenticated) { - ret["result"] = "ok"; - GameCenter::get_singleton()->connected = true; - } else { - ret["result"] = "error"; - ret["error_code"] = error.code; - ret["error_description"] = [error.localizedDescription UTF8String]; - GameCenter::get_singleton()->connected = false; - }; - - pending_events.push_back(ret); - }; - + if (controller) { + [root_controller presentViewController:controller animated:YES completion:nil]; + } else { + Dictionary ret; + ret["type"] = "authentication"; + if (player.isAuthenticated) { + ret["result"] = "ok"; + GameCenter::get_singleton()->connected = true; + } else { + ret["result"] = "error"; + ret["error_code"] = error.code; + ret["error_description"] = [error.localizedDescription UTF8String]; + GameCenter::get_singleton()->connected = false; + }; + + pending_events.push_back(ret); + }; }); return OK; @@ -114,26 +115,27 @@ Error GameCenter::post_score(Variant p_score) { float score = params["score"]; String category = params["category"]; - NSString* cat_str = [[[NSString alloc] initWithUTF8String:category.utf8().get_data()] autorelease]; - GKScore* reporter = [[[GKScore alloc] initWithCategory:cat_str] autorelease]; + NSString *cat_str = [[[NSString alloc] initWithUTF8String:category.utf8().get_data()] autorelease]; + GKScore *reporter = [[[GKScore alloc] initWithCategory:cat_str] autorelease]; reporter.value = score; ERR_FAIL_COND_V([GKScore respondsToSelector:@selector(reportScores)], ERR_UNAVAILABLE); - [GKScore reportScores:@[reporter] withCompletionHandler:^(NSError* error) { + [GKScore reportScores:@[ reporter ] + withCompletionHandler:^(NSError *error) { - Dictionary ret; - ret["type"] = "post_score"; - if (error == nil) { - ret["result"] = "ok"; - } else { - ret["result"] = "error"; - ret["error_code"] = error.code; - ret["error_description"] = [error.localizedDescription UTF8String]; - }; + Dictionary ret; + ret["type"] = "post_score"; + if (error == nil) { + ret["result"] = "ok"; + } else { + ret["result"] = "error"; + ret["error_code"] = error.code; + ret["error_description"] = [error.localizedDescription UTF8String]; + }; - pending_events.push_back(ret); - }]; + pending_events.push_back(ret); + }]; return OK; }; @@ -145,8 +147,8 @@ Error GameCenter::award_achievement(Variant p_params) { String name = params["name"]; float progress = params["progress"]; - NSString* name_str = [[[NSString alloc] initWithUTF8String:name.utf8().get_data()] autorelease]; - GKAchievement* achievement = [[[GKAchievement alloc] initWithIdentifier: name_str] autorelease]; + NSString *name_str = [[[NSString alloc] initWithUTF8String:name.utf8().get_data()] autorelease]; + GKAchievement *achievement = [[[GKAchievement alloc] initWithIdentifier:name_str] autorelease]; ERR_FAIL_COND_V(!achievement, FAILED); ERR_FAIL_COND_V([GKAchievement respondsToSelector:@selector(reportAchievements)], ERR_UNAVAILABLE); @@ -157,19 +159,20 @@ Error GameCenter::award_achievement(Variant p_params) { achievement.showsCompletionBanner = params["show_completion_banner"] ? YES : NO; } - [GKAchievement reportAchievements:@[achievement] withCompletionHandler:^(NSError *error) { + [GKAchievement reportAchievements:@[ achievement ] + withCompletionHandler:^(NSError *error) { - Dictionary ret; - ret["type"] = "award_achievement"; - if (error == nil) { - ret["result"] = "ok"; - } else { - ret["result"] = "error"; - ret["error_code"] = error.code; - }; + Dictionary ret; + ret["type"] = "award_achievement"; + if (error == nil) { + ret["result"] = "ok"; + } else { + ret["result"] = "error"; + ret["error_code"] = error.code; + }; - pending_events.push_back(ret); - }]; + pending_events.push_back(ret); + }]; return OK; }; @@ -190,11 +193,11 @@ void GameCenter::request_achievement_descriptions() { Array hidden; Array replayable; - for (int i=0; i<[descriptions count]; i++) { + for (int i = 0; i < [descriptions count]; i++) { - GKAchievementDescription* description = [descriptions objectAtIndex:i]; + GKAchievementDescription *description = [descriptions objectAtIndex:i]; - const char* str = [description.identifier UTF8String]; + const char *str = [description.identifier UTF8String]; names.push_back(String::utf8(str != NULL ? str : "")); str = [description.title UTF8String]; @@ -230,7 +233,6 @@ void GameCenter::request_achievement_descriptions() { }]; }; - void GameCenter::request_achievements() { [GKAchievement loadAchievementsWithCompletionHandler:^(NSArray *achievements, NSError *error) { @@ -242,10 +244,10 @@ void GameCenter::request_achievements() { PoolStringArray names; PoolRealArray percentages; - for (int i=0; i<[achievements count]; i++) { + for (int i = 0; i < [achievements count]; i++) { - GKAchievement* achievement = [achievements objectAtIndex:i]; - const char* str = [achievement.identifier UTF8String]; + GKAchievement *achievement = [achievements objectAtIndex:i]; + const char *str = [achievement.identifier UTF8String]; names.push_back(String::utf8(str != NULL ? str : "")); percentages.push_back(achievement.percentComplete); @@ -265,8 +267,7 @@ void GameCenter::request_achievements() { void GameCenter::reset_achievements() { - [GKAchievement resetAchievementsWithCompletionHandler:^(NSError *error) - { + [GKAchievement resetAchievementsWithCompletionHandler:^(NSError *error) { Dictionary ret; ret["type"] = "reset_achievements"; if (error == nil) { @@ -291,17 +292,13 @@ Error GameCenter::show_game_center(Variant p_params) { String view_name = params["view"]; if (view_name == "default") { view_state = GKGameCenterViewControllerStateDefault; - } - else if (view_name == "leaderboards") { + } else if (view_name == "leaderboards") { view_state = GKGameCenterViewControllerStateLeaderboards; - } - else if (view_name == "achievements") { + } else if (view_name == "achievements") { view_state = GKGameCenterViewControllerStateAchievements; - } - else if (view_name == "challenges") { + } else if (view_name == "challenges") { view_state = GKGameCenterViewControllerStateChallenges; - } - else { + } else { return ERR_INVALID_PARAMETER; } } @@ -309,7 +306,7 @@ Error GameCenter::show_game_center(Variant p_params) { GKGameCenterViewController *controller = [[GKGameCenterViewController alloc] init]; ERR_FAIL_COND_V(!controller, FAILED); - ViewController *root_controller=(ViewController *)((AppDelegate *)[[UIApplication sharedApplication] delegate]).window.rootViewController; + ViewController *root_controller = (ViewController *)((AppDelegate *)[[UIApplication sharedApplication] delegate]).window.rootViewController; ERR_FAIL_COND_V(!root_controller, FAILED); controller.gameCenterDelegate = root_controller; @@ -318,12 +315,12 @@ Error GameCenter::show_game_center(Variant p_params) { controller.leaderboardIdentifier = nil; if (params.has("leaderboard_name")) { String name = params["leaderboard_name"]; - NSString* name_str = [[[NSString alloc] initWithUTF8String:name.utf8().get_data()] autorelease]; + NSString *name_str = [[[NSString alloc] initWithUTF8String:name.utf8().get_data()] autorelease]; controller.leaderboardIdentifier = name_str; } } - [root_controller presentViewController: controller animated: YES completion:nil]; + [root_controller presentViewController:controller animated:YES completion:nil]; return OK; }; @@ -331,7 +328,7 @@ Error GameCenter::show_game_center(Variant p_params) { void GameCenter::game_center_closed() { Dictionary ret; - ret["type"] = "show_game_center"; + ret["type"] = "show_game_center"; ret["result"] = "ok"; pending_events.push_back(ret); } @@ -349,7 +346,7 @@ Variant GameCenter::pop_pending_event() { return front; }; -GameCenter* GameCenter::get_singleton() { +GameCenter *GameCenter::get_singleton() { return instance; }; @@ -359,9 +356,6 @@ GameCenter::GameCenter() { connected = false; }; - -GameCenter::~GameCenter() { - -}; +GameCenter::~GameCenter(){}; #endif diff --git a/platform/iphone/gl_view.h b/platform/iphone/gl_view.h index 555e34a895..14e9a66a4a 100644 --- a/platform/iphone/gl_view.h +++ b/platform/iphone/gl_view.h @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/iphone/gl_view.mm b/platform/iphone/gl_view.mm index adc76a622e..6270fa85f2 100755..100644 --- a/platform/iphone/gl_view.mm +++ b/platform/iphone/gl_view.mm @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -26,15 +27,15 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ +#import "gl_view.h" -#import <QuartzCore/QuartzCore.h> -#import <OpenGLES/EAGLDrawable.h> -#include "os_iphone.h" -#include "core/os/keyboard.h" #include "core/global_config.h" +#include "core/os/keyboard.h" +#include "os_iphone.h" #include "servers/audio_server.h" -#import "gl_view.h" +#import <OpenGLES/EAGLDrawable.h> +#import <QuartzCore/QuartzCore.h> /* @interface GLView (private) @@ -47,7 +48,7 @@ int gl_view_base_fb; static String keyboard_text; -static GLView* _instance = NULL; +static GLView *_instance = NULL; static bool video_found_error = false; static bool video_playing = false; @@ -78,21 +79,22 @@ void _hide_keyboard() { bool _play_video(String p_path, float p_volume, String p_audio_track, String p_subtitle_track) { p_path = GlobalConfig::get_singleton()->globalize_path(p_path); - NSString* file_path = [[[NSString alloc] initWithUTF8String:p_path.utf8().get_data()] autorelease]; + NSString *file_path = [[[NSString alloc] initWithUTF8String:p_path.utf8().get_data()] autorelease]; _instance.avAsset = [AVAsset assetWithURL:[NSURL fileURLWithPath:file_path]]; - _instance.avPlayerItem =[[AVPlayerItem alloc]initWithAsset:_instance.avAsset]; + _instance.avPlayerItem = [[AVPlayerItem alloc] initWithAsset:_instance.avAsset]; [_instance.avPlayerItem addObserver:_instance forKeyPath:@"status" options:0 context:nil]; - _instance.avPlayer = [[AVPlayer alloc]initWithPlayerItem:_instance.avPlayerItem]; - _instance.avPlayerLayer =[AVPlayerLayer playerLayerWithPlayer:_instance.avPlayer]; + _instance.avPlayer = [[AVPlayer alloc] initWithPlayerItem:_instance.avPlayerItem]; + _instance.avPlayerLayer = [AVPlayerLayer playerLayerWithPlayer:_instance.avPlayer]; [_instance.avPlayer addObserver:_instance forKeyPath:@"status" options:0 context:nil]; - [[NSNotificationCenter defaultCenter] addObserver:_instance - selector:@selector(playerItemDidReachEnd:) - name:AVPlayerItemDidPlayToEndTimeNotification - object:[_instance.avPlayer currentItem]]; + [[NSNotificationCenter defaultCenter] + addObserver:_instance + selector:@selector(playerItemDidReachEnd:) + name:AVPlayerItemDidPlayToEndTimeNotification + object:[_instance.avPlayer currentItem]]; [_instance.avPlayer addObserver:_instance forKeyPath:@"rate" options:NSKeyValueObservingOptionNew context:0]; @@ -100,16 +102,14 @@ bool _play_video(String p_path, float p_volume, String p_audio_track, String p_s [_instance.layer addSublayer:_instance.avPlayerLayer]; [_instance.avPlayer play]; - AVMediaSelectionGroup *audioGroup = [_instance.avAsset mediaSelectionGroupForMediaCharacteristic: AVMediaCharacteristicAudible]; + AVMediaSelectionGroup *audioGroup = [_instance.avAsset mediaSelectionGroupForMediaCharacteristic:AVMediaCharacteristicAudible]; NSMutableArray *allAudioParams = [NSMutableArray array]; - for (id track in audioGroup.options) - { - NSString* language = [[track locale] localeIdentifier]; + for (id track in audioGroup.options) { + NSString *language = [[track locale] localeIdentifier]; NSLog(@"subtitle lang: %@", language); - if ([language isEqualToString:[NSString stringWithUTF8String:p_audio_track.utf8()]]) - { + if ([language isEqualToString:[NSString stringWithUTF8String:p_audio_track.utf8()]]) { AVMutableAudioMixInputParameters *audioInputParams = [AVMutableAudioMixInputParameters audioMixInputParameters]; [audioInputParams setVolume:p_volume atTime:kCMTimeZero]; [audioInputParams setTrackID:[track trackID]]; @@ -118,26 +118,24 @@ bool _play_video(String p_path, float p_volume, String p_audio_track, String p_s AVMutableAudioMix *audioMix = [AVMutableAudioMix audioMix]; [audioMix setInputParameters:allAudioParams]; - [_instance.avPlayer.currentItem selectMediaOption:track inMediaSelectionGroup: audioGroup]; + [_instance.avPlayer.currentItem selectMediaOption:track inMediaSelectionGroup:audioGroup]; [_instance.avPlayer.currentItem setAudioMix:audioMix]; - break; - } + break; + } } - AVMediaSelectionGroup *subtitlesGroup = [_instance.avAsset mediaSelectionGroupForMediaCharacteristic: AVMediaCharacteristicLegible]; + AVMediaSelectionGroup *subtitlesGroup = [_instance.avAsset mediaSelectionGroupForMediaCharacteristic:AVMediaCharacteristicLegible]; NSArray *useableTracks = [AVMediaSelectionGroup mediaSelectionOptionsFromArray:subtitlesGroup.options withoutMediaCharacteristics:[NSArray arrayWithObject:AVMediaCharacteristicContainsOnlyForcedSubtitles]]; - for (id track in useableTracks) - { - NSString* language = [[track locale] localeIdentifier]; + for (id track in useableTracks) { + NSString *language = [[track locale] localeIdentifier]; NSLog(@"subtitle lang: %@", language); - if ([language isEqualToString:[NSString stringWithUTF8String:p_subtitle_track.utf8()]]) - { - [_instance.avPlayer.currentItem selectMediaOption:track inMediaSelectionGroup: subtitlesGroup]; - break; - } + if ([language isEqualToString:[NSString stringWithUTF8String:p_subtitle_track.utf8()]]) { + [_instance.avPlayer.currentItem selectMediaOption:track inMediaSelectionGroup:subtitlesGroup]; + break; + } } video_playing = true; @@ -181,19 +179,19 @@ void _stop_video() { @synthesize animationInterval; static const int max_touches = 8; -static UITouch* touches[max_touches]; +static UITouch *touches[max_touches]; static void init_touches() { - for (int i=0; i<max_touches; i++) { + for (int i = 0; i < max_touches; i++) { touches[i] = NULL; }; }; -static int get_touch_id(UITouch* p_touch) { +static int get_touch_id(UITouch *p_touch) { int first = -1; - for (int i=0; i<max_touches; i++) { + for (int i = 0; i < max_touches; i++) { if (first == -1 && touches[i] == NULL) { first = i; continue; @@ -210,10 +208,10 @@ static int get_touch_id(UITouch* p_touch) { return -1; }; -static int remove_touch(UITouch* p_touch) { +static int remove_touch(UITouch *p_touch) { int remaining = 0; - for (int i=0; i<max_touches; i++) { + for (int i = 0; i < max_touches; i++) { if (touches[i] == NULL) continue; @@ -225,9 +223,9 @@ static int remove_touch(UITouch* p_touch) { return remaining; }; -static int get_first_id(UITouch* p_touch) { +static int get_first_id(UITouch *p_touch) { - for (int i=0; i<max_touches; i++) { + for (int i = 0; i < max_touches; i++) { if (touches[i] != NULL) return i; @@ -237,7 +235,7 @@ static int get_first_id(UITouch* p_touch) { static void clear_touches() { - for (int i=0; i<max_touches; i++) { + for (int i = 0; i < max_touches; i++) { touches[i] = NULL; }; @@ -245,39 +243,36 @@ static void clear_touches() { // Implement this to override the default layer class (which is [CALayer class]). // We do this so that our view will be backed by a layer that is capable of OpenGL ES rendering. -+ (Class) layerClass -{ ++ (Class)layerClass { return [CAEAGLLayer class]; } //The GL view is stored in the nib file. When it's unarchived it's sent -initWithCoder: -- (id)initWithCoder:(NSCoder*)coder -{ +- (id)initWithCoder:(NSCoder *)coder { active = FALSE; - if((self = [super initWithCoder:coder])) - { + if ((self = [super initWithCoder:coder])) { self = [self initGLES]; } return self; } --(id)initGLES -{ +- (id)initGLES { // Get our backing layer - CAEAGLLayer *eaglLayer = (CAEAGLLayer*) self.layer; + CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer; // Configure it so that it is opaque, does not retain the contents of the backbuffer when displayed, and uses RGBA8888 color. eaglLayer.opaque = YES; - eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys: - [NSNumber numberWithBool:FALSE], kEAGLDrawablePropertyRetainedBacking, - kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat, - nil]; + eaglLayer.drawableProperties = [NSDictionary + dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:FALSE], + kEAGLDrawablePropertyRetainedBacking, + kEAGLColorFormatRGBA8, + kEAGLDrawablePropertyColorFormat, + nil]; // Create our EAGLContext, and if successful make it current and create our framebuffer. context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES3]; - if(!context || ![EAGLContext setCurrentContext:context] || ![self createFramebuffer]) - { + if (!context || ![EAGLContext setCurrentContext:context] || ![self createFramebuffer]) { [self release]; return nil; } @@ -287,14 +282,12 @@ static void clear_touches() { return self; } --(id<GLViewDelegate>)delegate -{ +- (id<GLViewDelegate>)delegate { return delegate; } // Update the delegate, and if it needs a -setupView: call, set our internal flag so that it will be called. --(void)setDelegate:(id<GLViewDelegate>)d -{ +- (void)setDelegate:(id<GLViewDelegate>)d { delegate = d; delegateSetup = ![delegate respondsToSelector:@selector(setupView:)]; } @@ -305,21 +298,18 @@ static void clear_touches() { // This is the perfect opportunity to also update the framebuffer so that it is // the same size as our display area. --(void)layoutSubviews -{ +- (void)layoutSubviews { //printf("HERE\n"); [EAGLContext setCurrentContext:context]; [self destroyFramebuffer]; [self createFramebuffer]; [self drawView]; [self drawView]; - } -- (BOOL)createFramebuffer -{ +- (BOOL)createFramebuffer { // Generate IDs for a framebuffer object and a color renderbuffer - UIScreen* mainscr = [UIScreen mainScreen]; + UIScreen *mainscr = [UIScreen mainScreen]; printf("******** screen size %i, %i\n", (int)mainscr.currentMode.size.width, (int)mainscr.currentMode.size.height); float minPointSize = MIN(mainscr.bounds.size.width, mainscr.bounds.size.height); float minScreenSize = MIN(mainscr.currentMode.size.width, mainscr.currentMode.size.height); @@ -331,7 +321,7 @@ static void clear_touches() { glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer); glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer); // This call associates the storage for the current render buffer with the EAGLDrawable (our CAEAGLLayer) - // allowing us to draw into a buffer that will later be rendered to screen whereever the layer is (which corresponds with our view). + // allowing us to draw into a buffer that will later be rendered to screen wherever the layer is (which corresponds with our view). [context renderbufferStorage:GL_RENDERBUFFER_OES fromDrawable:(id<EAGLDrawable>)self.layer]; glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, GL_RENDERBUFFER_OES, viewRenderbuffer); @@ -344,8 +334,7 @@ static void clear_touches() { glRenderbufferStorageOES(GL_RENDERBUFFER_OES, GL_DEPTH_COMPONENT16_OES, backingWidth, backingHeight); glFramebufferRenderbufferOES(GL_FRAMEBUFFER_OES, GL_DEPTH_ATTACHMENT_OES, GL_RENDERBUFFER_OES, depthRenderbuffer); - if(glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) != GL_FRAMEBUFFER_COMPLETE_OES) - { + if (glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES) != GL_FRAMEBUFFER_COMPLETE_OES) { NSLog(@"failed to make complete framebuffer object %x", glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES)); return NO; } @@ -365,22 +354,19 @@ static void clear_touches() { } // Clean up any buffers we have allocated. -- (void)destroyFramebuffer -{ +- (void)destroyFramebuffer { glDeleteFramebuffersOES(1, &viewFramebuffer); viewFramebuffer = 0; glDeleteRenderbuffersOES(1, &viewRenderbuffer); viewRenderbuffer = 0; - if(depthRenderbuffer) - { + if (depthRenderbuffer) { glDeleteRenderbuffersOES(1, &depthRenderbuffer); depthRenderbuffer = 0; } } -- (void)startAnimation -{ +- (void)startAnimation { if (active) return; active = TRUE; @@ -389,26 +375,23 @@ static void clear_touches() { // Approximate frame rate // assumes device refreshes at 60 fps - int frameInterval = (int) floor(animationInterval * 60.0f); + int frameInterval = (int)floor(animationInterval * 60.0f); displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(drawView)]; [displayLink setFrameInterval:frameInterval]; // Setup DisplayLink in main thread [displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes]; - } - else { + } else { animationTimer = [NSTimer scheduledTimerWithTimeInterval:animationInterval target:self selector:@selector(drawView) userInfo:nil repeats:YES]; } - if (video_playing) - { + if (video_playing) { _unpause_video(); } } -- (void)stopAnimation -{ +- (void)stopAnimation { if (!active) return; active = FALSE; @@ -417,41 +400,38 @@ static void clear_touches() { if (useCADisplayLink) { [displayLink invalidate]; displayLink = nil; - } - else { + } else { [animationTimer invalidate]; animationTimer = nil; } clear_touches(); - if (video_playing) - { + if (video_playing) { // save position } } -- (void)setAnimationInterval:(NSTimeInterval)interval -{ +- (void)setAnimationInterval:(NSTimeInterval)interval { animationInterval = interval; - if ( (useCADisplayLink && displayLink) || ( !useCADisplayLink && animationTimer ) ) { + if ((useCADisplayLink && displayLink) || (!useCADisplayLink && animationTimer)) { [self stopAnimation]; [self startAnimation]; } } // Updates the OpenGL view when the timer fires -- (void)drawView -{ +- (void)drawView { if (useCADisplayLink) { // Pause the CADisplayLink to avoid recursion - [displayLink setPaused: YES]; + [displayLink setPaused:YES]; // Process all input events - while(CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, TRUE) == kCFRunLoopRunHandledSource); + while (CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, TRUE) == kCFRunLoopRunHandledSource) + ; // We are good to go, resume the CADisplayLink - [displayLink setPaused: NO]; + [displayLink setPaused:NO]; } if (!active) { @@ -463,8 +443,7 @@ static void clear_touches() { [EAGLContext setCurrentContext:context]; // If our drawing delegate needs to have the view setup, then call -setupView: and flag that it won't need to be called again. - if(!delegateSetup) - { + if (!delegateSetup) { [delegate setupView:self]; delegateSetup = YES; } @@ -478,19 +457,18 @@ static void clear_touches() { #ifdef DEBUG_ENABLED GLenum err = glGetError(); - if(err) + if (err) NSLog(@"%x error", err); #endif } -- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event -{ - NSArray* tlist = [[event allTouches] allObjects]; - for (unsigned int i=0; i< [tlist count]; i++) { +- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { + NSArray *tlist = [[event allTouches] allObjects]; + for (unsigned int i = 0; i < [tlist count]; i++) { - if ( [touches containsObject:[tlist objectAtIndex:i]] ) { + if ([touches containsObject:[tlist objectAtIndex:i]]) { - UITouch* touch = [tlist objectAtIndex:i]; + UITouch *touch = [tlist objectAtIndex:i]; if (touch.phase != UITouchPhaseBegan) continue; int tid = get_touch_id(touch); @@ -501,15 +479,14 @@ static void clear_touches() { }; } -- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event -{ +- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { - NSArray* tlist = [[event allTouches] allObjects]; - for (unsigned int i=0; i< [tlist count]; i++) { + NSArray *tlist = [[event allTouches] allObjects]; + for (unsigned int i = 0; i < [tlist count]; i++) { - if ( [touches containsObject:[tlist objectAtIndex:i]] ) { + if ([touches containsObject:[tlist objectAtIndex:i]]) { - UITouch* touch = [tlist objectAtIndex:i]; + UITouch *touch = [tlist objectAtIndex:i]; if (touch.phase != UITouchPhaseMoved) continue; int tid = get_touch_id(touch); @@ -520,17 +497,15 @@ static void clear_touches() { OSIPhone::get_singleton()->mouse_move(tid, prev_point.x * self.contentScaleFactor, prev_point.y * self.contentScaleFactor, touchPoint.x * self.contentScaleFactor, touchPoint.y * self.contentScaleFactor, first == tid); }; }; - } -- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event -{ - NSArray* tlist = [[event allTouches] allObjects]; - for (unsigned int i=0; i< [tlist count]; i++) { +- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { + NSArray *tlist = [[event allTouches] allObjects]; + for (unsigned int i = 0; i < [tlist count]; i++) { - if ( [touches containsObject:[tlist objectAtIndex:i]] ) { + if ([touches containsObject:[tlist objectAtIndex:i]]) { - UITouch* touch = [tlist objectAtIndex:i]; + UITouch *touch = [tlist objectAtIndex:i]; if (touch.phase != UITouchPhaseEnded) continue; int tid = get_touch_id(touch); @@ -552,7 +527,6 @@ static void clear_touches() { return YES; }; - - (void)open_keyboard { //keyboard_text = p_existing; [self becomeFirstResponder]; @@ -577,12 +551,11 @@ static void clear_touches() { String character; character.parse_utf8([p_text UTF8String]); keyboard_text = keyboard_text + character; - OSIPhone::get_singleton()->key(character[0] == 10 ? KEY_ENTER : character[0] , true); + OSIPhone::get_singleton()->key(character[0] == 10 ? KEY_ENTER : character[0], true); printf("inserting text with character %i\n", character[0]); }; -- (void)audioRouteChangeListenerCallback:(NSNotification*)notification -{ +- (void)audioRouteChangeListenerCallback:(NSNotification *)notification { printf("*********** route changed!\n"); NSDictionary *interuptionDict = notification.userInfo; @@ -590,49 +563,48 @@ static void clear_touches() { switch (routeChangeReason) { - case AVAudioSessionRouteChangeReasonNewDeviceAvailable: + case AVAudioSessionRouteChangeReasonNewDeviceAvailable: { NSLog(@"AVAudioSessionRouteChangeReasonNewDeviceAvailable"); NSLog(@"Headphone/Line plugged in"); - break; + }; break; - case AVAudioSessionRouteChangeReasonOldDeviceUnavailable: + case AVAudioSessionRouteChangeReasonOldDeviceUnavailable: { NSLog(@"AVAudioSessionRouteChangeReasonOldDeviceUnavailable"); NSLog(@"Headphone/Line was pulled. Resuming video play...."); if (_is_video_playing()) { dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.5f * NSEC_PER_SEC), dispatch_get_main_queue(), ^{ - [_instance.avPlayer play]; // NOTE: change this line according your current player implementation - NSLog(@"resumed play"); + [_instance.avPlayer play]; // NOTE: change this line according your current player implementation + NSLog(@"resumed play"); }); }; - break; + }; break; - case AVAudioSessionRouteChangeReasonCategoryChange: + case AVAudioSessionRouteChangeReasonCategoryChange: { // called at start - also when other audio wants to play NSLog(@"AVAudioSessionRouteChangeReasonCategoryChange"); - break; + }; break; } } - // When created via code however, we get initWithFrame --(id)initWithFrame:(CGRect)frame -{ +- (id)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; _instance = self; printf("after init super %p\n", self); - if(self != nil) - { + if (self != nil) { self = [self initGLES]; printf("after init gles %p\n", self); } init_touches(); - self. multipleTouchEnabled = YES; + self.multipleTouchEnabled = YES; printf("******** adding observer for sound routing changes\n"); - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(audioRouteChangeListenerCallback:) - name:AVAudioSessionRouteChangeNotification - object:nil]; + [[NSNotificationCenter defaultCenter] + addObserver:self + selector:@selector(audioRouteChangeListenerCallback:) + name:AVAudioSessionRouteChangeNotification + object:nil]; //self.autoresizesSubviews = YES; //[self setAutoresizingMask:UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleWidth]; @@ -640,21 +612,19 @@ static void clear_touches() { return self; } -// -(BOOL)automaticallyForwardAppearanceAndRotationMethodsToChildViewControllers { -// return YES; -// } +//- (BOOL)automaticallyForwardAppearanceAndRotationMethodsToChildViewControllers { +// return YES; +//} -// - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation{ -// return YES; -// } +//- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation{ +// return YES; +//} // Stop animating and release resources when they are no longer needed. -- (void)dealloc -{ +- (void)dealloc { [self stopAnimation]; - if([EAGLContext currentContext] == context) - { + if ([EAGLContext currentContext] == context) { [EAGLContext setCurrentContext:nil]; } @@ -664,32 +634,31 @@ static void clear_touches() { [super dealloc]; } -- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object - change:(NSDictionary *)change context:(void *)context { +- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { if (object == _instance.avPlayerItem && [keyPath isEqualToString:@"status"]) { - if (_instance.avPlayerItem.status == AVPlayerStatusFailed || _instance.avPlayer.status == AVPlayerStatusFailed) { - _stop_video(); - video_found_error = true; - } + if (_instance.avPlayerItem.status == AVPlayerStatusFailed || _instance.avPlayer.status == AVPlayerStatusFailed) { + _stop_video(); + video_found_error = true; + } - if(_instance.avPlayer.status == AVPlayerStatusReadyToPlay && - _instance.avPlayerItem.status == AVPlayerItemStatusReadyToPlay && - CMTIME_COMPARE_INLINE(video_current_time, ==, kCMTimeZero)) { + if (_instance.avPlayer.status == AVPlayerStatusReadyToPlay && + _instance.avPlayerItem.status == AVPlayerItemStatusReadyToPlay && + CMTIME_COMPARE_INLINE(video_current_time, ==, kCMTimeZero)) { - //NSLog(@"time: %@", video_current_time); + //NSLog(@"time: %@", video_current_time); - [_instance.avPlayer seekToTime:video_current_time]; - video_current_time = kCMTimeZero; + [_instance.avPlayer seekToTime:video_current_time]; + video_current_time = kCMTimeZero; } - } + } if (object == _instance.avPlayer && [keyPath isEqualToString:@"rate"]) { NSLog(@"Player playback rate changed: %.5f", _instance.avPlayer.rate); if (_is_video_playing() && _instance.avPlayer.rate == 0.0 && !_instance.avPlayer.error) { dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.5f * NSEC_PER_SEC), dispatch_get_main_queue(), ^{ - [_instance.avPlayer play]; // NOTE: change this line according your current player implementation - NSLog(@"resumed play"); + [_instance.avPlayer play]; // NOTE: change this line according your current player implementation + NSLog(@"resumed play"); }); NSLog(@" . . . PAUSED (or just started)"); @@ -698,40 +667,40 @@ static void clear_touches() { } - (void)playerItemDidReachEnd:(NSNotification *)notification { - _stop_video(); + _stop_video(); } /* - (void)moviePlayBackDidFinish:(NSNotification*)notification { - NSNumber* reason = [[notification userInfo] objectForKey:MPMoviePlayerPlaybackDidFinishReasonUserInfoKey]; - switch ([reason intValue]) { - case MPMovieFinishReasonPlaybackEnded: - //NSLog(@"Playback Ended"); - break; - case MPMovieFinishReasonPlaybackError: - //NSLog(@"Playback Error"); - video_found_error = true; - break; - case MPMovieFinishReasonUserExited: - //NSLog(@"User Exited"); - video_found_error = true; - break; - default: - //NSLog(@"Unsupported reason!"); - break; - } - - MPMoviePlayerController *player = [notification object]; - - [[NSNotificationCenter defaultCenter] - removeObserver:self - name:MPMoviePlayerPlaybackDidFinishNotification - object:player]; - - [_instance.moviePlayerController stop]; - [_instance.moviePlayerController.view removeFromSuperview]; + NSNumber* reason = [[notification userInfo] objectForKey:MPMoviePlayerPlaybackDidFinishReasonUserInfoKey]; + switch ([reason intValue]) { + case MPMovieFinishReasonPlaybackEnded: + //NSLog(@"Playback Ended"); + break; + case MPMovieFinishReasonPlaybackError: + //NSLog(@"Playback Error"); + video_found_error = true; + break; + case MPMovieFinishReasonUserExited: + //NSLog(@"User Exited"); + video_found_error = true; + break; + default: + //NSLog(@"Unsupported reason!"); + break; + } + + MPMoviePlayerController *player = [notification object]; + + [[NSNotificationCenter defaultCenter] + removeObserver:self + name:MPMoviePlayerPlaybackDidFinishNotification + object:player]; + + [_instance.moviePlayerController stop]; + [_instance.moviePlayerController.view removeFromSuperview]; //[[MPMusicPlayerController applicationMusicPlayer] setVolume: video_previous_volume]; video_playing = false; diff --git a/platform/iphone/globals/global_defaults.cpp b/platform/iphone/globals/global_defaults.cpp index b3067dc0c4..b320be2f85 100644 --- a/platform/iphone/globals/global_defaults.cpp +++ b/platform/iphone/globals/global_defaults.cpp @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/iphone/globals/global_defaults.h b/platform/iphone/globals/global_defaults.h index 1432b74425..6fe1027287 100644 --- a/platform/iphone/globals/global_defaults.h +++ b/platform/iphone/globals/global_defaults.h @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/iphone/godot_iphone.cpp b/platform/iphone/godot_iphone.cpp index 626c78fdf4..4d34ebedf9 100644 --- a/platform/iphone/godot_iphone.cpp +++ b/platform/iphone/godot_iphone.cpp @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/iphone/icloud.h b/platform/iphone/icloud.h index 743a9a5de3..67d12a990a 100644 --- a/platform/iphone/icloud.h +++ b/platform/iphone/icloud.h @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/iphone/icloud.mm b/platform/iphone/icloud.mm index a9b23baaeb..94c3d2ef91 100644 --- a/platform/iphone/icloud.mm +++ b/platform/iphone/icloud.mm @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -34,24 +35,25 @@ extern "C" { #endif -#import <Foundation/Foundation.h> #import "app_delegate.h" +#import <Foundation/Foundation.h> + #ifndef __IPHONE_9_0 }; #endif -ICloud* ICloud::instance = NULL; +ICloud *ICloud::instance = NULL; void ICloud::_bind_methods() { - ClassDB::bind_method(D_METHOD("remove_key"),&ICloud::remove_key); - ClassDB::bind_method(D_METHOD("set_key_values"),&ICloud::set_key_values); - ClassDB::bind_method(D_METHOD("get_key_value"),&ICloud::get_key_value); - ClassDB::bind_method(D_METHOD("synchronize_key_values"),&ICloud::synchronize_key_values); - ClassDB::bind_method(D_METHOD("get_all_key_values"),&ICloud::get_all_key_values); - - ClassDB::bind_method(D_METHOD("get_pending_event_count"),&ICloud::get_pending_event_count); - ClassDB::bind_method(D_METHOD("pop_pending_event"),&ICloud::pop_pending_event); + ClassDB::bind_method(D_METHOD("remove_key"), &ICloud::remove_key); + ClassDB::bind_method(D_METHOD("set_key_values"), &ICloud::set_key_values); + ClassDB::bind_method(D_METHOD("get_key_value"), &ICloud::get_key_value); + ClassDB::bind_method(D_METHOD("synchronize_key_values"), &ICloud::synchronize_key_values); + ClassDB::bind_method(D_METHOD("get_all_key_values"), &ICloud::get_all_key_values); + + ClassDB::bind_method(D_METHOD("get_pending_event_count"), &ICloud::get_pending_event_count); + ClassDB::bind_method(D_METHOD("pop_pending_event"), &ICloud::pop_pending_event); }; int ICloud::get_pending_event_count() { @@ -67,19 +69,18 @@ Variant ICloud::pop_pending_event() { return front; }; -ICloud* ICloud::get_singleton() { +ICloud *ICloud::get_singleton() { return instance; }; //convert from apple's abstract type to godot's abstract type.... -Variant nsobject_to_variant(NSObject* object) { +Variant nsobject_to_variant(NSObject *object) { if ([object isKindOfClass:[NSString class]]) { - const char* str = [(NSString*)object UTF8String]; + const char *str = [(NSString *)object UTF8String]; return String::utf8(str != NULL ? str : ""); - } - else if ([object isKindOfClass:[NSData class]]) { + } else if ([object isKindOfClass:[NSData class]]) { PoolByteArray ret; - NSData* data = (NSData*)object; + NSData *data = (NSData *)object; if ([data length] > 0) { ret.resize([data length]); { @@ -88,95 +89,78 @@ Variant nsobject_to_variant(NSObject* object) { } } return ret; - } - else if ([object isKindOfClass:[NSArray class]]) { + } else if ([object isKindOfClass:[NSArray class]]) { Array result; - NSArray* array = (NSArray*)object; + NSArray *array = (NSArray *)object; for (unsigned int i = 0; i < [array count]; ++i) { - NSObject* value = [array objectAtIndex:i]; + NSObject *value = [array objectAtIndex:i]; result.push_back(nsobject_to_variant(value)); } return result; - } - else if ([object isKindOfClass:[NSDictionary class]]) { + } else if ([object isKindOfClass:[NSDictionary class]]) { Dictionary result; - NSDictionary* dic = (NSDictionary*)object; + NSDictionary *dic = (NSDictionary *)object; - - NSArray* keys = [dic allKeys]; + NSArray *keys = [dic allKeys]; int count = [keys count]; - for (int i=0; i < count; ++i) { - NSObject* k = [ keys objectAtIndex:i]; - NSObject* v = [dic objectForKey:k]; + for (int i = 0; i < count; ++i) { + NSObject *k = [keys objectAtIndex:i]; + NSObject *v = [dic objectForKey:k]; result[nsobject_to_variant(k)] = nsobject_to_variant(v); } return result; - } - else if ([object isKindOfClass:[NSNumber class]]) { + } else if ([object isKindOfClass:[NSNumber class]]) { //Every type except numbers can reliably identify its type. The following is comparing to the *internal* representation, which isn't guaranteed to match the type that was used to create it, and is not advised, particularly when dealing with potential platform differences (ie, 32/64 bit) //To avoid errors, we'll cast as broadly as possible, and only return int or float. //bool, char, int, uint, longlong -> int //float, double -> float - NSNumber* num = (NSNumber*)object; - if(strcmp([num objCType], @encode(BOOL)) == 0) { + NSNumber *num = (NSNumber *)object; + if (strcmp([num objCType], @encode(BOOL)) == 0) { return Variant((int)[num boolValue]); - } - else if(strcmp([num objCType], @encode(char)) == 0) { + } else if (strcmp([num objCType], @encode(char)) == 0) { return Variant((int)[num charValue]); - } - else if(strcmp([num objCType], @encode(int)) == 0) { + } else if (strcmp([num objCType], @encode(int)) == 0) { return Variant([num intValue]); - } - else if(strcmp([num objCType], @encode(unsigned int)) == 0) { + } else if (strcmp([num objCType], @encode(unsigned int)) == 0) { return Variant((int)[num unsignedIntValue]); - } - else if(strcmp([num objCType], @encode(long long)) == 0) { + } else if (strcmp([num objCType], @encode(long long)) == 0) { return Variant((int)[num longValue]); - } - else if(strcmp([num objCType], @encode(float)) == 0) { + } else if (strcmp([num objCType], @encode(float)) == 0) { return Variant([num floatValue]); - } - else if(strcmp([num objCType], @encode(double)) == 0) { + } else if (strcmp([num objCType], @encode(double)) == 0) { return Variant((float)[num doubleValue]); } - } - else if ([object isKindOfClass:[NSDate class]]) { + } else if ([object isKindOfClass:[NSDate class]]) { //this is a type that icloud supports...but how did you submit it in the first place? //I guess this is a type that *might* show up, if you were, say, trying to make your game //compatible with existing cloud data written by another engine's version of your game WARN_PRINT("NSDate unsupported, returning null Variant") return Variant(); - } - else if ([object isKindOfClass:[NSNull class]] or object == nil) { + } else if ([object isKindOfClass:[NSNull class]] or object == nil) { return Variant(); - } - else { + } else { WARN_PRINT("Trying to convert unknown NSObject type to Variant"); return Variant(); } } -NSObject* variant_to_nsobject(Variant v) { +NSObject *variant_to_nsobject(Variant v) { if (v.get_type() == Variant::STRING) { return [[[NSString alloc] initWithUTF8String:((String)v).utf8().get_data()] autorelease]; - } - else if (v.get_type() == Variant::REAL) { + } else if (v.get_type() == Variant::REAL) { return [NSNumber numberWithDouble:(double)v]; - } - else if (v.get_type() == Variant::INT) { + } else if (v.get_type() == Variant::INT) { return [NSNumber numberWithLongLong:(long)(int)v]; - } - else if (v.get_type() == Variant::BOOL) { + } else if (v.get_type() == Variant::BOOL) { return [NSNumber numberWithBool:BOOL((bool)v)]; - } - else if (v.get_type() == Variant::DICTIONARY) { - NSMutableDictionary* result = [[[NSMutableDictionary alloc] init] autorelease]; + } else if (v.get_type() == Variant::DICTIONARY) { + NSMutableDictionary *result = [[[NSMutableDictionary alloc] init] autorelease]; Dictionary dic = v; Array keys = dic.keys(); for (unsigned int i = 0; i < keys.size(); ++i) { - NSString* key = [[[NSString alloc] initWithUTF8String:((String)(keys[i])).utf8().get_data()] autorelease]; - NSObject* value = variant_to_nsobject(dic[keys[i]]); + NSString *key = [[[NSString alloc] initWithUTF8String:((String)(keys[i])).utf8().get_data()] autorelease]; + NSObject *value = variant_to_nsobject(dic[keys[i]]); if (key == NULL || value == NULL) { return NULL; @@ -185,12 +169,11 @@ NSObject* variant_to_nsobject(Variant v) { [result setObject:value forKey:key]; } return result; - } - else if (v.get_type() == Variant::ARRAY) { - NSMutableArray* result = [[[NSMutableArray alloc] init] autorelease]; + } else if (v.get_type() == Variant::ARRAY) { + NSMutableArray *result = [[[NSMutableArray alloc] init] autorelease]; Array arr = v; for (unsigned int i = 0; i < arr.size(); ++i) { - NSObject* value = variant_to_nsobject(arr[i]); + NSObject *value = variant_to_nsobject(arr[i]); if (value == NULL) { //trying to add something unsupported to the array. cancel the whole array return NULL; @@ -198,21 +181,19 @@ NSObject* variant_to_nsobject(Variant v) { [result addObject:value]; } return result; - } - else if (v.get_type() == Variant::POOL_BYTE_ARRAY) { + } else if (v.get_type() == Variant::POOL_BYTE_ARRAY) { PoolByteArray arr = v; PoolByteArray::Read r = arr.read(); - NSData* result = [NSData dataWithBytes:r.ptr() length:arr.size()]; + NSData *result = [NSData dataWithBytes:r.ptr() length:arr.size()]; return result; } - WARN_PRINT(String("Could not add unsupported type to iCloud: '" + Variant::get_type_name(v.get_type())+"'").utf8().get_data()); + WARN_PRINT(String("Could not add unsupported type to iCloud: '" + Variant::get_type_name(v.get_type()) + "'").utf8().get_data()); return NULL; } - Error ICloud::remove_key(Variant p_param) { String param = p_param; - NSString* key = [[[NSString alloc] initWithUTF8String:param.utf8().get_data()] autorelease]; + NSString *key = [[[NSString alloc] initWithUTF8String:param.utf8().get_data()] autorelease]; NSUbiquitousKeyValueStore *store = [NSUbiquitousKeyValueStore defaultStore]; @@ -235,13 +216,13 @@ Variant ICloud::set_key_values(Variant p_params) { String variant_key = keys[i]; Variant variant_value = params[variant_key]; - NSString* key = [[[NSString alloc] initWithUTF8String:variant_key.utf8().get_data()] autorelease]; + NSString *key = [[[NSString alloc] initWithUTF8String:variant_key.utf8().get_data()] autorelease]; if (key == NULL) { error_keys.push_back(variant_key); continue; } - NSObject* value = variant_to_nsobject(variant_value); + NSObject *value = variant_to_nsobject(variant_value); if (value == NULL) { error_keys.push_back(variant_key); @@ -258,7 +239,7 @@ Variant ICloud::set_key_values(Variant p_params) { Variant ICloud::get_key_value(Variant p_param) { String param = p_param; - NSString* key = [[[NSString alloc] initWithUTF8String:param.utf8().get_data()] autorelease]; + NSString *key = [[[NSString alloc] initWithUTF8String:param.utf8().get_data()] autorelease]; NSUbiquitousKeyValueStore *store = [NSUbiquitousKeyValueStore defaultStore]; if (![[store dictionaryRepresentation] objectForKey:key]) { @@ -273,16 +254,16 @@ Variant ICloud::get_key_value(Variant p_param) { Variant ICloud::get_all_key_values() { Dictionary result; - NSUbiquitousKeyValueStore* store = [NSUbiquitousKeyValueStore defaultStore]; - NSDictionary* store_dictionary = [store dictionaryRepresentation]; + NSUbiquitousKeyValueStore *store = [NSUbiquitousKeyValueStore defaultStore]; + NSDictionary *store_dictionary = [store dictionaryRepresentation]; - NSArray* keys = [store_dictionary allKeys]; + NSArray *keys = [store_dictionary allKeys]; int count = [keys count]; - for (int i=0; i < count; ++i) { - NSString* k = [ keys objectAtIndex:i]; - NSObject* v = [store_dictionary objectForKey:k]; + for (int i = 0; i < count; ++i) { + NSString *k = [keys objectAtIndex:i]; + NSObject *v = [store_dictionary objectForKey:k]; - const char* str = [k UTF8String]; + const char *str = [k UTF8String]; if (str != NULL) { result[String::utf8(str)] = nsobject_to_variant(v); } @@ -296,8 +277,7 @@ Error ICloud::synchronize_key_values() { BOOL result = [store synchronize]; if (result == YES) { return OK; - } - else { + } else { return FAILED; } } @@ -306,14 +286,14 @@ Error ICloud::initial_sync() { //you sometimes have to write something to the store to get it to download new data. go apple! NSUbiquitousKeyValueStore *store = [NSUbiquitousKeyValueStore defaultStore]; if ([store boolForKey:@"isb"]) - { - [store setBool:NO forKey:@"isb"]; - } - else - { - [store setBool:YES forKey:@"isb"]; - } - return synchronize(); + { + [store setBool:NO forKey:@"isb"]; + } + else + { + [store setBool:YES forKey:@"isb"]; + } + return synchronize(); } */ ICloud::ICloud() { @@ -321,65 +301,56 @@ ICloud::ICloud() { instance = this; //connected = false; - [ - //[NSNotificationCenter defaultCenter] addObserverForName: @"notify" - [NSNotificationCenter defaultCenter] addObserverForName: NSUbiquitousKeyValueStoreDidChangeExternallyNotification - object: [NSUbiquitousKeyValueStore defaultStore] - queue: nil - usingBlock: ^ (NSNotification * notification) { - NSDictionary* userInfo = [notification userInfo]; - NSInteger change = [[userInfo objectForKey:NSUbiquitousKeyValueStoreChangeReasonKey] integerValue]; - - Dictionary ret; - ret["type"] = "key_value_changed"; - - //PoolStringArray result_keys; - //Array result_values; - Dictionary keyValues; - String reason = ""; - - if (change == NSUbiquitousKeyValueStoreServerChange) { - reason = "server"; - } - else if (change == NSUbiquitousKeyValueStoreInitialSyncChange) { - reason = "initial_sync"; - } - else if (change == NSUbiquitousKeyValueStoreQuotaViolationChange) { - reason = "quota_violation"; - } - else if (change == NSUbiquitousKeyValueStoreAccountChange) { - reason = "account"; - } - - ret["reason"] = reason; - - - NSUbiquitousKeyValueStore *store = [NSUbiquitousKeyValueStore defaultStore]; - - NSArray * keys = [userInfo objectForKey:NSUbiquitousKeyValueStoreChangedKeysKey]; - for (NSString* key in keys) { - const char* str = [key UTF8String]; - if (str == NULL) { - continue; - } - - NSObject* object = [store objectForKey:key]; - - //figure out what kind of object it is - Variant value = nsobject_to_variant(object); - - keyValues[String::utf8(str)] = value; - } - - ret["changed_values"] = keyValues; - pending_events.push_back(ret); - } - ]; + [[NSNotificationCenter defaultCenter] + addObserverForName:NSUbiquitousKeyValueStoreDidChangeExternallyNotification + object:[NSUbiquitousKeyValueStore defaultStore] + queue:nil + usingBlock:^(NSNotification *notification) { + NSDictionary *userInfo = [notification userInfo]; + NSInteger change = [[userInfo objectForKey:NSUbiquitousKeyValueStoreChangeReasonKey] integerValue]; + + Dictionary ret; + ret["type"] = "key_value_changed"; + + //PoolStringArray result_keys; + //Array result_values; + Dictionary keyValues; + String reason = ""; + + if (change == NSUbiquitousKeyValueStoreServerChange) { + reason = "server"; + } else if (change == NSUbiquitousKeyValueStoreInitialSyncChange) { + reason = "initial_sync"; + } else if (change == NSUbiquitousKeyValueStoreQuotaViolationChange) { + reason = "quota_violation"; + } else if (change == NSUbiquitousKeyValueStoreAccountChange) { + reason = "account"; + } + + ret["reason"] = reason; + + NSUbiquitousKeyValueStore *store = [NSUbiquitousKeyValueStore defaultStore]; + + NSArray *keys = [userInfo objectForKey:NSUbiquitousKeyValueStoreChangedKeysKey]; + for (NSString *key in keys) { + const char *str = [key UTF8String]; + if (str == NULL) { + continue; + } + + NSObject *object = [store objectForKey:key]; + + //figure out what kind of object it is + Variant value = nsobject_to_variant(object); + + keyValues[String::utf8(str)] = value; + } + + ret["changed_values"] = keyValues; + pending_events.push_back(ret); + }]; } - -ICloud::~ICloud() { - -}; +ICloud::~ICloud(){}; #endif diff --git a/platform/iphone/in_app_store.h b/platform/iphone/in_app_store.h index b2ed6f70e4..153c46bd7b 100644 --- a/platform/iphone/in_app_store.h +++ b/platform/iphone/in_app_store.h @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/iphone/in_app_store.mm b/platform/iphone/in_app_store.mm index b63d7b42ab..710df0f757 100644 --- a/platform/iphone/in_app_store.mm +++ b/platform/iphone/in_app_store.mm @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -28,30 +29,29 @@ /*************************************************************************/ #ifdef STOREKIT_ENABLED +#include "in_app_store.h" + #ifdef MODULE_FUSEBOXX_ENABLED #import "modules/fuseboxx/ios/FuseSDK.h" #endif -#include "in_app_store.h" - extern "C" { -#import <StoreKit/StoreKit.h> #import <Foundation/Foundation.h> +#import <StoreKit/StoreKit.h> }; bool auto_finish_transactions = true; -NSMutableDictionary* pending_transactions = [NSMutableDictionary dictionary]; +NSMutableDictionary *pending_transactions = [NSMutableDictionary dictionary]; @interface SKProduct (LocalizedPrice) -@property (nonatomic, readonly) NSString *localizedPrice; +@property(nonatomic, readonly) NSString *localizedPrice; @end //----------------------------------// // SKProduct extension //----------------------------------// @implementation SKProduct (LocalizedPrice) -- (NSString *)localizedPrice -{ +- (NSString *)localizedPrice { NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init]; [numberFormatter setFormatterBehavior:NSNumberFormatterBehavior10_4]; [numberFormatter setNumberStyle:NSNumberFormatterCurrencyStyle]; @@ -62,30 +62,28 @@ NSMutableDictionary* pending_transactions = [NSMutableDictionary dictionary]; } @end - -InAppStore* InAppStore::instance = NULL; +InAppStore *InAppStore::instance = NULL; void InAppStore::_bind_methods() { - ClassDB::bind_method(D_METHOD("request_product_info"),&InAppStore::request_product_info); - ClassDB::bind_method(D_METHOD("purchase"),&InAppStore::purchase); + ClassDB::bind_method(D_METHOD("request_product_info"), &InAppStore::request_product_info); + ClassDB::bind_method(D_METHOD("purchase"), &InAppStore::purchase); - ClassDB::bind_method(D_METHOD("get_pending_event_count"),&InAppStore::get_pending_event_count); - ClassDB::bind_method(D_METHOD("pop_pending_event"),&InAppStore::pop_pending_event); - ClassDB::bind_method(D_METHOD("finish_transaction"),&InAppStore::finish_transaction); - ClassDB::bind_method(D_METHOD("set_auto_finish_transaction"),&InAppStore::set_auto_finish_transaction); + ClassDB::bind_method(D_METHOD("get_pending_event_count"), &InAppStore::get_pending_event_count); + ClassDB::bind_method(D_METHOD("pop_pending_event"), &InAppStore::pop_pending_event); + ClassDB::bind_method(D_METHOD("finish_transaction"), &InAppStore::finish_transaction); + ClassDB::bind_method(D_METHOD("set_auto_finish_transaction"), &InAppStore::set_auto_finish_transaction); }; -@interface ProductsDelegate : NSObject<SKProductsRequestDelegate> { - +@interface ProductsDelegate : NSObject <SKProductsRequestDelegate> { }; @end @implementation ProductsDelegate -- (void)productsRequest:(SKProductsRequest*)request didReceiveResponse:(SKProductsResponse*)response { +- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response { - NSArray* products = response.products; + NSArray *products = response.products; Dictionary ret; ret["type"] = "product_info"; ret["result"] = "ok"; @@ -95,11 +93,11 @@ void InAppStore::_bind_methods() { PoolStringArray ids; PoolStringArray localized_prices; - for (int i=0; i<[products count]; i++) { + for (int i = 0; i < [products count]; i++) { - SKProduct* product = [products objectAtIndex:i]; + SKProduct *product = [products objectAtIndex:i]; - const char* str = [product.localizedTitle UTF8String]; + const char *str = [product.localizedTitle UTF8String]; titles.push_back(String::utf8(str != NULL ? str : "")); str = [product.localizedDescription UTF8String]; @@ -116,7 +114,7 @@ void InAppStore::_bind_methods() { PoolStringArray invalid_ids; - for (NSString* ipid in response.invalidProductIdentifiers) { + for (NSString *ipid in response.invalidProductIdentifiers) { invalid_ids.push_back(String::utf8([ipid UTF8String])); }; @@ -137,15 +135,15 @@ Error InAppStore::request_product_info(Variant p_params) { PoolStringArray pids = params["product_ids"]; printf("************ request product info! %i\n", pids.size()); - NSMutableArray* array = [[[NSMutableArray alloc] initWithCapacity:pids.size()] autorelease]; - for (int i=0; i<pids.size(); i++) { + NSMutableArray *array = [[[NSMutableArray alloc] initWithCapacity:pids.size()] autorelease]; + for (int i = 0; i < pids.size(); i++) { printf("******** adding %ls to product list\n", pids[i].c_str()); - NSString* pid = [[[NSString alloc] initWithUTF8String:pids[i].utf8().get_data()] autorelease]; + NSString *pid = [[[NSString alloc] initWithUTF8String:pids[i].utf8().get_data()] autorelease]; [array addObject:pid]; }; - NSSet* products = [[[NSSet alloc] initWithArray:array] autorelease]; - SKProductsRequest* request = [[SKProductsRequest alloc] initWithProductIdentifiers:products]; + NSSet *products = [[[NSSet alloc] initWithArray:array] autorelease]; + SKProductsRequest *request = [[SKProductsRequest alloc] initWithProductIdentifiers:products]; ProductsDelegate *delegate = [[ProductsDelegate alloc] init]; @@ -155,131 +153,123 @@ Error InAppStore::request_product_info(Variant p_params) { return OK; }; -@interface TransObserver : NSObject<SKPaymentTransactionObserver> { - +@interface TransObserver : NSObject <SKPaymentTransactionObserver> { }; @end @implementation TransObserver -- (void)paymentQueue:(SKPaymentQueue*)queue updatedTransactions:(NSArray*) transactions { +- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions { - printf("transactions updated!\n"); - for (SKPaymentTransaction* transaction in transactions) { + printf("transactions updated!\n"); + for (SKPaymentTransaction *transaction in transactions) { switch (transaction.transactionState) { + case SKPaymentTransactionStatePurchased: { + printf("status purchased!\n"); + String pid = String::utf8([transaction.payment.productIdentifier UTF8String]); + String transactionId = String::utf8([transaction.transactionIdentifier UTF8String]); + InAppStore::get_singleton()->_record_purchase(pid); + Dictionary ret; + ret["type"] = "purchase"; + ret["result"] = "ok"; + ret["product_id"] = pid; + ret["transaction_id"] = transactionId; + + NSData *receipt = nil; + int sdk_version = 6; + + if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0) { + + NSURL *receiptFileURL = nil; + NSBundle *bundle = [NSBundle mainBundle]; + if ([bundle respondsToSelector:@selector(appStoreReceiptURL)]) { + + // Get the transaction receipt file path location in the app bundle. + receiptFileURL = [bundle appStoreReceiptURL]; + + // Read in the contents of the transaction file. + receipt = [NSData dataWithContentsOfURL:receiptFileURL]; + sdk_version = 7; + + } else { + // Fall back to deprecated transaction receipt, + // which is still available in iOS 7. + + // Use SKPaymentTransaction's transactionReceipt. + receipt = transaction.transactionReceipt; + } + + } else { + receipt = transaction.transactionReceipt; + } + + NSString *receipt_to_send = nil; + if (receipt != nil) { + receipt_to_send = [receipt description]; + } + Dictionary receipt_ret; + receipt_ret["receipt"] = String::utf8(receipt_to_send != nil ? [receipt_to_send UTF8String] : ""); + receipt_ret["sdk"] = sdk_version; + ret["receipt"] = receipt_ret; + + InAppStore::get_singleton()->_post_event(ret); + + if (auto_finish_transactions) { + [[SKPaymentQueue defaultQueue] finishTransaction:transaction]; + } else { + [pending_transactions setObject:transaction forKey:transaction.payment.productIdentifier]; + } - case SKPaymentTransactionStatePurchased: { - printf("status purchased!\n"); - String pid = String::utf8([transaction.payment.productIdentifier UTF8String]); - String transactionId = String::utf8([transaction.transactionIdentifier UTF8String]); - InAppStore::get_singleton()->_record_purchase(pid); - Dictionary ret; - ret["type"] = "purchase"; - ret["result"] = "ok"; - ret["product_id"] = pid; - ret["transaction_id"] = transactionId; - - NSData* receipt = nil; - int sdk_version = 6; - - if([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0){ - - NSURL *receiptFileURL = nil; - NSBundle *bundle = [NSBundle mainBundle]; - if ([bundle respondsToSelector:@selector(appStoreReceiptURL)]) { - - // Get the transaction receipt file path location in the app bundle. - receiptFileURL = [bundle appStoreReceiptURL]; - - // Read in the contents of the transaction file. - receipt = [NSData dataWithContentsOfURL:receiptFileURL]; - sdk_version = 7; - - } else { - // Fall back to deprecated transaction receipt, - // which is still available in iOS 7. - - // Use SKPaymentTransaction's transactionReceipt. - receipt = transaction.transactionReceipt; - } - - }else{ - receipt = transaction.transactionReceipt; - } - - NSString* receipt_to_send = nil; - if (receipt != nil) - { - receipt_to_send = [receipt description]; - } - Dictionary receipt_ret; - receipt_ret["receipt"] = String::utf8(receipt_to_send != nil ? [receipt_to_send UTF8String] : ""); - receipt_ret["sdk"] = sdk_version; - ret["receipt"] = receipt_ret; - - InAppStore::get_singleton()->_post_event(ret); - - if (auto_finish_transactions){ - [[SKPaymentQueue defaultQueue] finishTransaction:transaction]; - } - else{ - [pending_transactions setObject:transaction forKey:transaction.payment.productIdentifier]; - } - - #ifdef MODULE_FUSEBOXX_ENABLED - printf("Registering transaction on Fuseboxx!\n"); - [FuseSDK registerInAppPurchase: transaction]; - #endif - } break; - case SKPaymentTransactionStateFailed: { - printf("status transaction failed!\n"); - String pid = String::utf8([transaction.payment.productIdentifier UTF8String]); - Dictionary ret; - ret["type"] = "purchase"; - ret["result"] = "error"; - ret["product_id"] = pid; - InAppStore::get_singleton()->_post_event(ret); - [[SKPaymentQueue defaultQueue] finishTransaction:transaction]; - } break; - case SKPaymentTransactionStateRestored: { - printf("status transaction restored!\n"); - String pid = String::utf8([transaction.originalTransaction.payment.productIdentifier UTF8String]); - InAppStore::get_singleton()->_record_purchase(pid); - [[SKPaymentQueue defaultQueue] finishTransaction:transaction]; - } break; - - default: - printf("status default %i!\n", (int)transaction.transactionState); - - break; +#ifdef MODULE_FUSEBOXX_ENABLED + printf("Registering transaction on Fuseboxx!\n"); + [FuseSDK registerInAppPurchase:transaction]; +#endif + }; break; + case SKPaymentTransactionStateFailed: { + printf("status transaction failed!\n"); + String pid = String::utf8([transaction.payment.productIdentifier UTF8String]); + Dictionary ret; + ret["type"] = "purchase"; + ret["result"] = "error"; + ret["product_id"] = pid; + InAppStore::get_singleton()->_post_event(ret); + [[SKPaymentQueue defaultQueue] finishTransaction:transaction]; + } break; + case SKPaymentTransactionStateRestored: { + printf("status transaction restored!\n"); + String pid = String::utf8([transaction.originalTransaction.payment.productIdentifier UTF8String]); + InAppStore::get_singleton()->_record_purchase(pid); + [[SKPaymentQueue defaultQueue] finishTransaction:transaction]; + } break; + default: { + printf("status default %i!\n", (int)transaction.transactionState); + }; break; }; }; }; @end - Error InAppStore::purchase(Variant p_params) { ERR_FAIL_COND_V(![SKPaymentQueue canMakePayments], ERR_UNAVAILABLE); if (![SKPaymentQueue canMakePayments]) return ERR_UNAVAILABLE; - printf("purchasing!\n"); + printf("purchasing!\n"); Dictionary params = p_params; ERR_FAIL_COND_V(!params.has("product_id"), ERR_INVALID_PARAMETER); NSString *pid = [[[NSString alloc] initWithUTF8String:String(params["product_id"]).utf8().get_data()] autorelease]; SKPayment *payment = [SKPayment paymentWithProductIdentifier:pid]; - SKPaymentQueue* defq = [SKPaymentQueue defaultQueue]; + SKPaymentQueue *defq = [SKPaymentQueue defaultQueue]; [defq addPayment:payment]; - printf("purchase sent!\n"); + printf("purchase sent!\n"); return OK; }; - int InAppStore::get_pending_event_count() { return pending_events.size(); }; @@ -299,13 +289,13 @@ void InAppStore::_post_event(Variant p_event) { void InAppStore::_record_purchase(String product_id) { - String skey = "purchased/"+product_id; - NSString* key = [[[NSString alloc] initWithUTF8String:skey.utf8().get_data()] autorelease]; + String skey = "purchased/" + product_id; + NSString *key = [[[NSString alloc] initWithUTF8String:skey.utf8().get_data()] autorelease]; [[NSUserDefaults standardUserDefaults] setBool:YES forKey:key]; [[NSUserDefaults standardUserDefaults] synchronize]; }; -InAppStore* InAppStore::get_singleton() { +InAppStore *InAppStore::get_singleton() { return instance; }; @@ -315,27 +305,24 @@ InAppStore::InAppStore() { instance = this; auto_finish_transactions = false; - TransObserver* observer = [[TransObserver alloc] init]; + TransObserver *observer = [[TransObserver alloc] init]; [[SKPaymentQueue defaultQueue] addTransactionObserver:observer]; - //pending_transactions = [NSMutableDictionary dictionary]; + //pending_transactions = [NSMutableDictionary dictionary]; }; -void InAppStore::finish_transaction(String product_id){ - NSString* prod_id = [NSString stringWithCString:product_id.utf8().get_data() encoding:NSUTF8StringEncoding]; +void InAppStore::finish_transaction(String product_id) { + NSString *prod_id = [NSString stringWithCString:product_id.utf8().get_data() encoding:NSUTF8StringEncoding]; - if ([pending_transactions objectForKey:prod_id]){ + if ([pending_transactions objectForKey:prod_id]) { [[SKPaymentQueue defaultQueue] finishTransaction:[pending_transactions objectForKey:prod_id]]; - [pending_transactions removeObjectForKey:prod_id]; + [pending_transactions removeObjectForKey:prod_id]; } }; -void InAppStore::set_auto_finish_transaction(bool b){ - auto_finish_transactions = b; +void InAppStore::set_auto_finish_transaction(bool b) { + auto_finish_transactions = b; } -InAppStore::~InAppStore() { - -}; - +InAppStore::~InAppStore(){}; #endif diff --git a/platform/iphone/ios.h b/platform/iphone/ios.h index e5baf8f4d2..2572d626d2 100644 --- a/platform/iphone/ios.h +++ b/platform/iphone/ios.h @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -38,6 +39,8 @@ class iOS : public Object { static void _bind_methods(); public: + static void alert(const char *p_alert, const char *p_title); + String get_rate_url(int p_app_id) const; iOS(); diff --git a/platform/iphone/ios.mm b/platform/iphone/ios.mm index 4aca85dafc..e9c164393b 100644 --- a/platform/iphone/ios.mm +++ b/platform/iphone/ios.mm @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -32,9 +33,14 @@ void iOS::_bind_methods() { - ClassDB::bind_method(D_METHOD("get_rate_url","app_id"),&iOS::get_rate_url); + ClassDB::bind_method(D_METHOD("get_rate_url", "app_id"), &iOS::get_rate_url); }; +void iOS::alert(const char* p_alert, const char* p_title) { + UIAlertView *alert = [[[UIAlertView alloc] initWithTitle:[NSString stringWithUTF8String:p_title] message:[NSString stringWithUTF8String:p_alert] delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil, nil] autorelease]; + [alert show]; +} + String iOS::get_rate_url(int p_app_id) const { String templ = "itms-apps://ax.itunes.apple.com/WebObjects/MZStore.woa/wa/viewContentsUserReviews?type=Purple+Software&id=APP_ID"; String templ_iOS7 = "itms-apps://itunes.apple.com/app/idAPP_ID"; @@ -43,14 +49,11 @@ String iOS::get_rate_url(int p_app_id) const { //ios7 before String ret = templ; - // iOS 7 needs a different templateReviewURL @see https://github.com/arashpayan/appirater/issues/131 - if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0 && [[[UIDevice currentDevice] systemVersion] floatValue] < 7.1) - { + if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0 && [[[UIDevice currentDevice] systemVersion] floatValue] < 7.1) { + // iOS 7 needs a different templateReviewURL @see https://github.com/arashpayan/appirater/issues/131 ret = templ_iOS7; - } - // iOS 8 needs a different templateReviewURL also @see https://github.com/arashpayan/appirater/issues/182 - else if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0) - { + } else if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0) { + // iOS 8 needs a different templateReviewURL also @see https://github.com/arashpayan/appirater/issues/182 ret = templ_iOS8; } @@ -61,4 +64,4 @@ String iOS::get_rate_url(int p_app_id) const { return ret; }; -iOS::iOS() {}; +iOS::iOS(){}; diff --git a/platform/iphone/main.m b/platform/iphone/main.m index 02a45737c5..6757cc8146 100644 --- a/platform/iphone/main.m +++ b/platform/iphone/main.m @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -26,25 +27,24 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#import <UIKit/UIKit.h> #import "app_delegate.h" + +#import <UIKit/UIKit.h> #include <stdio.h> int gargc; -char** gargv; +char **gargv; -int main(int argc, char *argv[]) -{ +int main(int argc, char *argv[]) { printf("*********** main.m\n"); gargc = argc; gargv = argv; NSAutoreleasePool *pool = [NSAutoreleasePool new]; - AppDelegate* app = [AppDelegate alloc]; + AppDelegate *app = [AppDelegate alloc]; printf("running app main\n"); UIApplicationMain(argc, argv, nil, @"AppDelegate"); printf("main done, pool release\n"); [pool release]; return 0; } - diff --git a/platform/iphone/os_iphone.cpp b/platform/iphone/os_iphone.cpp index 57862131f9..b244edbff6 100644 --- a/platform/iphone/os_iphone.cpp +++ b/platform/iphone/os_iphone.cpp @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -194,26 +195,24 @@ bool OSIPhone::iterate() { void OSIPhone::key(uint32_t p_key, bool p_pressed) { - InputEvent ev; - ev.type = InputEvent::KEY; - ev.ID = ++last_event_id; - ev.key.echo = false; - ev.key.pressed = p_pressed; - ev.key.scancode = p_key; - ev.key.unicode = p_key; + Ref<InputEventKey> ev; + ev.instance(); + ev->set_echo(false); + ev->set_pressed(p_pressed); + ev->set_scancode(p_key); + ev->set_unicode(p_key); queue_event(ev); }; void OSIPhone::mouse_button(int p_idx, int p_x, int p_y, bool p_pressed, bool p_doubleclick, bool p_use_as_mouse) { if (!GLOBAL_DEF("debug/disable_touch", false)) { - InputEvent ev; - ev.type = InputEvent::SCREEN_TOUCH; - ev.ID = ++last_event_id; - ev.screen_touch.index = p_idx; - ev.screen_touch.pressed = p_pressed; - ev.screen_touch.x = p_x; - ev.screen_touch.y = p_y; + Ref<InputEventScreenTouch> ev; + ev.instance(); + + ev->set_index(p_idx); + ev->set_pressed(p_pressed); + ev->set_position(Vector2(p_x, p_y)); queue_event(ev); }; @@ -221,24 +220,20 @@ void OSIPhone::mouse_button(int p_idx, int p_x, int p_y, bool p_pressed, bool p_ if (p_use_as_mouse) { - InputEvent ev; - ev.type = InputEvent::MOUSE_BUTTON; - ev.device = 0; - ev.mouse_button.pointer_index = p_idx; - ev.ID = ++last_event_id; - + Ref<InputEventMouseButton> ev; + ev.instance(); // swaped it for tilted screen - //ev.mouse_button.x = ev.mouse_button.global_x = video_mode.height - p_y; - //ev.mouse_button.y = ev.mouse_button.global_y = p_x; - ev.mouse_button.x = ev.mouse_button.global_x = p_x; - ev.mouse_button.y = ev.mouse_button.global_y = p_y; + //ev->get_pos().x = ev.mouse_button.global_x = video_mode.height - p_y; + //ev->get_pos().y = ev.mouse_button.global_y = p_x; + ev->set_position(Vector2(video_mode.height - p_y, p_x)); + ev->set_global_position(Vector2(video_mode.height - p_y, p_x)); //mouse_list.pressed[p_idx] = p_pressed; - input->set_mouse_pos(Point2(ev.mouse_motion.x, ev.mouse_motion.y)); - ev.mouse_button.button_index = BUTTON_LEFT; - ev.mouse_button.doubleclick = p_doubleclick; - ev.mouse_button.pressed = p_pressed; + input->set_mouse_position(ev->get_position()); + ev->set_button_index(BUTTON_LEFT); + ev->set_doubleclick(p_doubleclick); + ev->set_pressed(p_pressed); queue_event(ev); }; @@ -248,48 +243,31 @@ void OSIPhone::mouse_move(int p_idx, int p_prev_x, int p_prev_y, int p_x, int p_ if (!GLOBAL_DEF("debug/disable_touch", false)) { - InputEvent ev; - ev.type = InputEvent::SCREEN_DRAG; - ev.ID = ++last_event_id; - ev.screen_drag.index = p_idx; - ev.screen_drag.x = p_x; - ev.screen_drag.y = p_y; - ev.screen_drag.relative_x = p_x - p_prev_x; - ev.screen_drag.relative_y = p_y - p_prev_y; + Ref<InputEventScreenDrag> ev; + ev.instance(); + ev->set_index(p_idx); + ev->set_position(Vector2(p_x, p_y)); + ev->set_relative(Vector2(p_x - p_prev_x, p_y - p_prev_y)); queue_event(ev); }; if (p_use_as_mouse) { - InputEvent ev; - ev.type = InputEvent::MOUSE_MOTION; - ev.device = 0; - ev.mouse_motion.pointer_index = p_idx; - ev.ID = ++last_event_id; - - if (true) { // vertical + Ref<InputEventMouseMotion> ev; + ev.instance(); - ev.mouse_motion.x = ev.mouse_button.global_x = p_x; - ev.mouse_motion.y = ev.mouse_button.global_y = p_y; - ev.mouse_motion.relative_x = ev.mouse_motion.x - p_prev_x; - ev.mouse_motion.relative_y = ev.mouse_motion.y - p_prev_y; - - } else { // horizontal? - ev.mouse_motion.x = ev.mouse_button.global_x = video_mode.height - p_y; - ev.mouse_motion.y = ev.mouse_button.global_y = p_x; - ev.mouse_motion.relative_x = ev.mouse_motion.x - (video_mode.height - p_prev_x); - ev.mouse_motion.relative_y = ev.mouse_motion.y - p_prev_x; - }; + ev->set_position(Vector2(p_x, p_y)); + ev->set_global_position(Vector2(p_x, p_y)); + ev->set_relative(Vector2(p_x - p_prev_x, p_y - p_prev_y)); - input->set_mouse_pos(Point2(ev.mouse_motion.x, ev.mouse_motion.y)); - ev.mouse_motion.speed_x = input->get_last_mouse_speed().x; - ev.mouse_motion.speed_y = input->get_last_mouse_speed().y; - ev.mouse_motion.button_mask = 1; // pressed + input->set_mouse_position(ev->get_position()); + ev->set_speed(input->get_last_mouse_speed()); + ev->set_button_mask(BUTTON_LEFT); // pressed queue_event(ev); }; }; -void OSIPhone::queue_event(const InputEvent &p_event) { +void OSIPhone::queue_event(const Ref<InputEvent> &p_event) { ERR_FAIL_INDEX(event_count, MAX_EVENTS); @@ -325,9 +303,8 @@ void OSIPhone::update_accelerometer(float p_x, float p_y, float p_z) { InputEvent ev; ev.type = InputEvent::JOYPAD_MOTION; ev.device = 0; - ev.joy_motion.axis = JOY_ANALOG_0_X; + ev.joy_motion.axis = JOY_ANALOG_0; ev.joy_motion.axis_value = (p_x / (float)ACCEL_RANGE); - ev.ID = ++last_event_id; last_accel.x = p_x; queue_event(ev); }; @@ -336,9 +313,8 @@ void OSIPhone::update_accelerometer(float p_x, float p_y, float p_z) { InputEvent ev; ev.type = InputEvent::JOYPAD_MOTION; ev.device = 0; - ev.joy_motion.axis = JOY_ANALOG_0_Y; + ev.joy_motion.axis = JOY_ANALOG_1; ev.joy_motion.axis_value = (p_y / (float)ACCEL_RANGE); - ev.ID = ++last_event_id; last_accel.y = p_y; queue_event(ev); }; @@ -347,9 +323,8 @@ void OSIPhone::update_accelerometer(float p_x, float p_y, float p_z) { InputEvent ev; ev.type = InputEvent::JOYPAD_MOTION; ev.device = 0; - ev.joy_motion.axis = JOY_ANALOG_1_X; + ev.joy_motion.axis = JOY_ANALOG_2; ev.joy_motion.axis_value = ( (1.0 - p_z) / (float)ACCEL_RANGE); - ev.ID = ++last_event_id; last_accel.z = p_z; queue_event(ev); }; @@ -364,6 +339,22 @@ void OSIPhone::update_gyroscope(float p_x, float p_y, float p_z) { input->set_gyroscope(Vector3(p_x, p_y, p_z)); }; +int OSIPhone::get_unused_joy_id() { + return input->get_unused_joy_id(); +}; + +void OSIPhone::joy_connection_changed(int p_idx, bool p_connected, String p_name) { + input->joy_connection_changed(p_idx, p_connected, p_name); +}; + +void OSIPhone::joy_button(int p_device, int p_button, bool p_pressed) { + input->joy_button(p_device, p_button, p_pressed); +}; + +void OSIPhone::joy_axis(int p_device, int p_axis, const InputDefault::JoyAxis &p_value) { + input->joy_axis(p_device, p_axis, p_value); +}; + void OSIPhone::delete_main_loop() { if (main_loop) { @@ -400,7 +391,7 @@ bool OSIPhone::is_mouse_grab_enabled() const { return true; }; -Point2 OSIPhone::get_mouse_pos() const { +Point2 OSIPhone::get_mouse_position() const { return Point2(); }; @@ -412,6 +403,13 @@ int OSIPhone::get_mouse_button_state() const { void OSIPhone::set_window_title(const String &p_title){}; +void OSIPhone::alert(const String &p_alert, const String &p_title) { + + const CharString utf8_alert = p_alert.utf8(); + const CharString utf8_title = p_title.utf8(); + iOS::alert(utf8_alert.get_data(), utf8_title.get_data()); +} + void OSIPhone::set_video_mode(const VideoMode &p_video_mode, int p_screen) { video_mode = p_video_mode; @@ -566,7 +564,6 @@ OSIPhone::OSIPhone(int width, int height) { vm.resizable = false; set_video_mode(vm); event_count = 0; - last_event_id = 0; }; OSIPhone::~OSIPhone() { diff --git a/platform/iphone/os_iphone.h b/platform/iphone/os_iphone.h index 36261a62c2..4031b7524c 100644 --- a/platform/iphone/os_iphone.h +++ b/platform/iphone/os_iphone.h @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -117,10 +118,9 @@ private: Vector3 last_accel; - InputEvent event_queue[MAX_EVENTS]; + Ref<InputEvent> event_queue[MAX_EVENTS]; int event_count; - int last_event_id; - void queue_event(const InputEvent &p_event); + void queue_event(const Ref<InputEvent> &p_event); String data_dir; String unique_ID; @@ -145,15 +145,22 @@ public: void update_magnetometer(float p_x, float p_y, float p_z); void update_gyroscope(float p_x, float p_y, float p_z); + int get_unused_joy_id(); + void joy_connection_changed(int p_idx, bool p_connected, String p_name); + void joy_button(int p_device, int p_button, bool p_pressed); + void joy_axis(int p_device, int p_axis, const InputDefault::JoyAxis &p_value); + static OSIPhone *get_singleton(); virtual void set_mouse_show(bool p_show); virtual void set_mouse_grab(bool p_grab); virtual bool is_mouse_grab_enabled() const; - virtual Point2 get_mouse_pos() const; + virtual Point2 get_mouse_position() const; virtual int get_mouse_button_state() const; virtual void set_window_title(const String &p_title); + virtual void alert(const String &p_alert, const String &p_title = "ALERT!"); + virtual void set_video_mode(const VideoMode &p_video_mode, int p_screen = 0); virtual VideoMode get_video_mode(int p_screen = 0) const; virtual void get_fullscreen_mode_list(List<VideoMode> *p_list, int p_screen = 0) const; diff --git a/platform/iphone/platform_config.h b/platform/iphone/platform_config.h index 64e9388910..7e4b533254 100644 --- a/platform/iphone/platform_config.h +++ b/platform/iphone/platform_config.h @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/iphone/platform_refcount.h b/platform/iphone/platform_refcount.h index 6cfdc49369..c02e709ea1 100644 --- a/platform/iphone/platform_refcount.h +++ b/platform/iphone/platform_refcount.h @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/iphone/power_iphone.cpp b/platform/iphone/power_iphone.cpp index 7b1f9246f4..5192f8e593 100644 --- a/platform/iphone/power_iphone.cpp +++ b/platform/iphone/power_iphone.cpp @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/iphone/power_iphone.h b/platform/iphone/power_iphone.h index 8890c33e74..174ee6c63b 100644 --- a/platform/iphone/power_iphone.h +++ b/platform/iphone/power_iphone.h @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/iphone/rasterizer_iphone.cpp b/platform/iphone/rasterizer_iphone.cpp deleted file mode 100644 index 1a619f4305..0000000000 --- a/platform/iphone/rasterizer_iphone.cpp +++ /dev/null @@ -1,2584 +0,0 @@ -/*************************************************************************/ -/* rasterizer_iphone.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* http://www.godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ -#ifdef IPHONE_ENABLED - -#include "rasterizer_iphone.h" -#include "global_config.h" -#include "os/os.h" -#include <stdio.h> - -_FORCE_INLINE_ static void _gl_load_transform(const Transform &tr) { - - GLfloat matrix[16] = { /* build a 16x16 matrix */ - tr.basis.elements[0][0], - tr.basis.elements[1][0], - tr.basis.elements[2][0], - 0, - tr.basis.elements[0][1], - tr.basis.elements[1][1], - tr.basis.elements[2][1], - 0, - tr.basis.elements[0][2], - tr.basis.elements[1][2], - tr.basis.elements[2][2], - 0, - tr.origin.x, - tr.origin.y, - tr.origin.z, - 1 - }; - - glLoadMatrixf(matrix); -}; - -_FORCE_INLINE_ static void _gl_mult_transform(const Transform &tr) { - - GLfloat matrix[16] = { /* build a 16x16 matrix */ - tr.basis.elements[0][0], - tr.basis.elements[1][0], - tr.basis.elements[2][0], - 0, - tr.basis.elements[0][1], - tr.basis.elements[1][1], - tr.basis.elements[2][1], - 0, - tr.basis.elements[0][2], - tr.basis.elements[1][2], - tr.basis.elements[2][2], - 0, - tr.origin.x, - tr.origin.y, - tr.origin.z, - 1 - }; - - glMultMatrixf(matrix); -}; - -static const GLenum prim_type[] = { GL_POINTS, GL_LINES, GL_TRIANGLES, GL_TRIANGLE_FAN }; - -static void _draw_primitive(int p_points, const float *p_vertices, const float *p_normals, const float *p_colors, const float *p_uvs, const Plane *p_tangents = NULL, int p_instanced = 1) { - - ERR_FAIL_COND(!p_vertices); - ERR_FAIL_COND(p_points < 1 || p_points > 4); - - GLenum type = prim_type[p_points - 1]; - - if (!p_colors) { - glColor4f(1, 1, 1, 1); - }; - - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(3, GL_FLOAT, 0, (GLvoid *)p_vertices); - - if (p_normals) { - - glEnableClientState(GL_NORMAL_ARRAY); - glNormalPointer(GL_FLOAT, 0, (GLvoid *)p_normals); - }; - - if (p_colors) { - glEnableClientState(GL_COLOR_ARRAY); - glColorPointer(4, GL_FLOAT, 0, p_colors); - }; - - if (p_uvs) { - - glClientActiveTexture(GL_TEXTURE0); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glTexCoordPointer(2, GL_FLOAT, 0, p_uvs); - }; - - glDrawArrays(type, 0, p_points); - - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_NORMAL_ARRAY); - glDisableClientState(GL_COLOR_ARRAY); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); -}; - -/* TEXTURE API */ - -static Image _get_gl_image_and_format(const Image &p_image, Image::Format p_format, uint32_t p_flags, GLenum &r_gl_format, int &r_gl_components, bool &r_has_alpha_cache) { - - r_has_alpha_cache = false; - Image image = p_image; - - switch (p_format) { - - case Image::FORMAT_L8: { - r_gl_components = 1; - r_gl_format = GL_LUMINANCE; - - } break; - case Image::FORMAT_INTENSITY: { - - image.convert(Image::FORMAT_RGBA8); - r_gl_components = 4; - r_gl_format = GL_RGBA; - r_has_alpha_cache = true; - } break; - case Image::FORMAT_LA8: { - - image.convert(Image::FORMAT_RGBA8); - r_gl_components = 4; - r_gl_format = GL_RGBA; - r_has_alpha_cache = true; - } break; - - case Image::FORMAT_INDEXED: { - - image.convert(Image::FORMAT_RGB8); - r_gl_components = 3; - r_gl_format = GL_RGB; - - } break; - - case Image::FORMAT_INDEXED_ALPHA: { - - image.convert(Image::FORMAT_RGBA8); - r_gl_components = 4; - r_gl_format = GL_RGB; - r_has_alpha_cache = true; - - } break; - case Image::FORMAT_RGB8: { - - r_gl_components = 3; - r_gl_format = GL_RGB; - } break; - case Image::FORMAT_RGBA8: { - - r_gl_components = 4; - r_gl_format = GL_RGBA; - r_has_alpha_cache = true; - } break; - default: { - - ERR_FAIL_V(Image()); - } - } - - return image; -} - -RID RasterizerIPhone::texture_create() { - - Texture *texture = memnew(Texture); - ERR_FAIL_COND_V(!texture, RID()); - glGenTextures(1, &texture->tex_id); - texture->active = false; - - return texture_owner.make_rid(texture); -} - -void RasterizerIPhone::texture_allocate(RID p_texture, int p_width, int p_height, Image::Format p_format, uint32_t p_flags) { - - bool has_alpha_cache; - int components; - GLenum format; - - Texture *texture = texture_owner.get(p_texture); - ERR_FAIL_COND(!texture); - texture->width = p_width; - texture->height = p_height; - texture->format = p_format; - texture->flags = p_flags; - //texture->target = (p_flags & VS::TEXTURE_FLAG_CUBEMAP) ? GL_TEXTURE_CUBE_MAP : GL_TEXTURE_2D; - texture->target = GL_TEXTURE_2D; - - _get_gl_image_and_format(Image(), texture->format, texture->flags, format, components, has_alpha_cache); - - texture->gl_components_cache = components; - texture->gl_format_cache = format; - texture->format_has_alpha = has_alpha_cache; - texture->has_alpha = false; //by default it doesn't have alpha unless something with alpha is blitteds - - glBindTexture(texture->target, texture->tex_id); - - if (texture->flags & VS::TEXTURE_FLAG_MIPMAPS) { - glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE); - } - - if (texture->target == GL_TEXTURE_2D) { - glTexImage2D(texture->target, 0, format, texture->width, texture->height, 0, format, GL_UNSIGNED_BYTE, NULL); - } - - /* - else { - //cubemappor - for (int i=0;i<6;i++) - glTexImage2D(_cube_side_enum[i], 0, format, texture->width, texture->height, 0, format, GL_UNSIGNED_BYTE,NULL); - } - */ - - glTexParameteri(texture->target, GL_TEXTURE_MIN_FILTER, GL_LINEAR); // Linear Filtering - - if (texture->flags & VS::TEXTURE_FLAG_FILTER) { - - glTexParameteri(texture->target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // Linear Filtering - if (texture->flags & VS::TEXTURE_FLAG_MIPMAPS) { - //glTexParameteri(texture->target,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_LINEAR); - }; - } - - if (texture->flags & VS::TEXTURE_FLAG_REPEAT /* && texture->target != GL_TEXTURE_CUBE_MAP*/) { - - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - } else { - - //glTexParameterf( texture->target, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE ); - glTexParameterf(texture->target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameterf(texture->target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - } - - texture->active = true; -} - -void RasterizerIPhone::texture_blit_rect(RID p_texture, int p_x, int p_y, const Image &p_image, VS::CubeMapSide p_cube_side) { - - Texture *texture = texture_owner.get(p_texture); - - ERR_FAIL_COND(!texture); - ERR_FAIL_COND(!texture->active); - ERR_FAIL_COND(texture->format != p_image.get_format()); - - int components; - GLenum format; - bool alpha; - - Image img = _get_gl_image_and_format(p_image, p_image.get_format(), texture->flags, format, components, alpha); - - if (img.detect_alpha()) - texture->has_alpha = true; - - GLenum blit_target = GL_TEXTURE_2D; //(texture->target == GL_TEXTURE_CUBE_MAP)?_cube_side_enum[p_cube_side]:GL_TEXTURE_2D; - - PoolVector<uint8_t>::Read read = img.get_data().read(); - - glBindTexture(texture->target, texture->tex_id); - glTexSubImage2D(blit_target, 0, p_x, p_y, img.get_width(), img.get_height(), format, GL_UNSIGNED_BYTE, read.ptr()); - - //glGenerateMipmap( texture->target ); -} - -Image RasterizerIPhone::texture_get_rect(RID p_texture, int p_x, int p_y, int p_width, int p_height, VS::CubeMapSide p_cube_side) const { - - return Image(); -} -void RasterizerIPhone::texture_set_flags(RID p_texture, uint32_t p_flags) { - - Texture *texture = texture_owner.get(p_texture); - ERR_FAIL_COND(!texture); - - glBindTexture(texture->target, texture->tex_id); - uint32_t cube = texture->flags & VS::TEXTURE_FLAG_CUBEMAP; - texture->flags = p_flags | cube; // can't remove a cube from being a cube - - if (texture->flags & VS::TEXTURE_FLAG_REPEAT /*&& texture->target != GL_TEXTURE_CUBE_MAP*/) { - - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - } else { - //glTexParameterf( texture->target, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE ); - glTexParameterf(texture->target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameterf(texture->target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - } - - if (texture->flags & VS::TEXTURE_FLAG_FILTER) { - - glTexParameteri(texture->target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // Linear Filtering - if (texture->flags & VS::TEXTURE_FLAG_MIPMAPS) - glTexParameteri(texture->target, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); - - } else { - - glTexParameteri(texture->target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); // nearest - } -} -uint32_t RasterizerIPhone::texture_get_flags(RID p_texture) const { - - Texture *texture = texture_owner.get(p_texture); - - ERR_FAIL_COND_V(!texture, 0); - - return texture->flags; -} -Image::Format RasterizerIPhone::texture_get_format(RID p_texture) const { - - Texture *texture = texture_owner.get(p_texture); - - ERR_FAIL_COND_V(!texture, Image::FORMAT_L8); - - return texture->format; -} -uint32_t RasterizerIPhone::texture_get_width(RID p_texture) const { - - Texture *texture = texture_owner.get(p_texture); - - ERR_FAIL_COND_V(!texture, 0); - - return texture->width; -} -uint32_t RasterizerIPhone::texture_get_height(RID p_texture) const { - - Texture *texture = texture_owner.get(p_texture); - - ERR_FAIL_COND_V(!texture, 0); - - return texture->height; -} - -bool RasterizerIPhone::texture_has_alpha(RID p_texture) const { - - Texture *texture = texture_owner.get(p_texture); - - ERR_FAIL_COND_V(!texture, 0); - - return texture->has_alpha; -} - -/* SHADER API */ - -RID RasterizerIPhone::shader_create() { - - return RID(); -} - -void RasterizerIPhone::shader_node_add(RID p_shader, VS::ShaderNodeType p_type, int p_id) { -} -void RasterizerIPhone::shader_node_remove(RID p_shader, int p_id) { -} -void RasterizerIPhone::shader_node_change_type(RID p_shader, int p_id, VS::ShaderNodeType p_type) { -} -void RasterizerIPhone::shader_node_set_param(RID p_shader, int p_id, const Variant &p_value) { -} - -void RasterizerIPhone::shader_get_node_list(RID p_shader, List<int> *p_node_list) const { -} -VS::ShaderNodeType RasterizerIPhone::shader_node_get_type(RID p_shader, int p_id) const { - - return VS::NODE_ADD; -} -Variant RasterizerIPhone::shader_node_get_param(RID p_shader, int p_id) const { - - return Variant(); -} - -void RasterizerIPhone::shader_connect(RID p_shader, int p_src_id, int p_src_slot, int p_dst_id, int p_dst_slot) { -} -bool RasterizerIPhone::shader_is_connected(RID p_shader, int p_src_id, int p_src_slot, int p_dst_id, int p_dst_slot) const { - - return false; -} - -void RasterizerIPhone::shader_disconnect(RID p_shader, int p_src_id, int p_src_slot, int p_dst_id, int p_dst_slot) { -} - -void RasterizerIPhone::shader_get_connections(RID p_shader, List<VS::ShaderConnection> *p_connections) const { -} - -void RasterizerIPhone::shader_clear(RID p_shader) { -} - -/* COMMON MATERIAL API */ - -void RasterizerIPhone::material_set_param(RID p_material, const StringName &p_param, const Variant &p_value) { -} -Variant RasterizerIPhone::material_get_param(RID p_material, const StringName &p_param) const { - - return Variant(); -} -void RasterizerIPhone::material_get_param_list(RID p_material, List<String> *p_param_list) const { -} - -void RasterizerIPhone::material_set_flag(RID p_material, VS::MaterialFlag p_flag, bool p_enabled) { -} -bool RasterizerIPhone::material_get_flag(RID p_material, VS::MaterialFlag p_flag) const { - - return false; -} - -void RasterizerIPhone::material_set_blend_mode(RID p_material, VS::MaterialBlendMode p_mode) { -} -VS::MaterialBlendMode RasterizerIPhone::material_get_blend_mode(RID p_material) const { - - return VS::MATERIAL_BLEND_MODE_ADD; -} - -void RasterizerIPhone::material_set_line_width(RID p_material, float p_line_width) { -} -float RasterizerIPhone::material_get_line_width(RID p_material) const { - - return 0; -} - -/* FIXED MATERIAL */ - -RID RasterizerIPhone::material_create() { - - return material_owner.make_rid(memnew(Material)); -} - -void RasterizerIPhone::fixed_material_set_parameter(RID p_material, VS::FixedSpatialMaterialParam p_parameter, const Variant &p_value) { - - Material *m = material_owner.get(p_material); - ERR_FAIL_COND(!m); - ERR_FAIL_INDEX(p_parameter, VisualServer::FIXED_MATERIAL_PARAM_MAX); - - m->parameters[p_parameter] = p_value; -} -Variant RasterizerIPhone::fixed_material_get_parameter(RID p_material, VS::FixedSpatialMaterialParam p_parameter) const { - - Material *m = material_owner.get(p_material); - ERR_FAIL_COND_V(!m, Variant()); - ERR_FAIL_INDEX_V(p_parameter, VisualServer::FIXED_MATERIAL_PARAM_MAX, Variant()); - - return m->parameters[p_parameter]; -} - -void RasterizerIPhone::fixed_material_set_texture(RID p_material, VS::FixedSpatialMaterialParam p_parameter, RID p_texture) { - - Material *m = material_owner.get(p_material); - ERR_FAIL_COND(!m); - ERR_FAIL_INDEX(p_parameter, VisualServer::FIXED_MATERIAL_PARAM_MAX); - - m->textures[p_parameter] = p_texture; -} -RID RasterizerIPhone::fixed_material_get_texture(RID p_material, VS::FixedSpatialMaterialParam p_parameter) const { - - Material *m = material_owner.get(p_material); - ERR_FAIL_COND_V(!m, RID()); - ERR_FAIL_INDEX_V(p_parameter, VisualServer::FIXED_MATERIAL_PARAM_MAX, Variant()); - - return m->textures[p_parameter]; -} - -void RasterizerIPhone::fixed_material_set_detail_blend_mode(RID p_material, VS::MaterialBlendMode p_mode) { - - Material *m = material_owner.get(p_material); - ERR_FAIL_COND(!m); - - m->detail_blend_mode = p_mode; -} -VS::MaterialBlendMode RasterizerIPhone::fixed_material_get_detail_blend_mode(RID p_material) const { - - Material *m = material_owner.get(p_material); - ERR_FAIL_COND_V(!m, VS::MATERIAL_BLEND_MODE_MIX); - - return m->detail_blend_mode; -} - -void RasterizerIPhone::fixed_material_set_texcoord_mode(RID p_material, VS::FixedSpatialMaterialParam p_parameter, VS::FixedSpatialMaterialTexCoordMode p_mode) { - - Material *m = material_owner.get(p_material); - ERR_FAIL_COND(!m); - ERR_FAIL_INDEX(p_parameter, VisualServer::FIXED_MATERIAL_PARAM_MAX); - - m->texcoord_mode[p_parameter] = p_mode; -} -VS::FixedSpatialMaterialTexCoordMode RasterizerIPhone::fixed_material_get_texcoord_mode(RID p_material, VS::FixedSpatialMaterialParam p_parameter) const { - - Material *m = material_owner.get(p_material); - ERR_FAIL_COND_V(!m, VS::FIXED_MATERIAL_TEXCOORD_TEXGEN); - ERR_FAIL_INDEX_V(p_parameter, VisualServer::FIXED_MATERIAL_PARAM_MAX, VS::FIXED_MATERIAL_TEXCOORD_UV); - - return m->texcoord_mode[p_parameter]; // for now -} - -void RasterizerIPhone::fixed_material_set_texgen_mode(RID p_material, VS::FixedSpatialMaterialTexGenMode p_mode) { - - Material *m = material_owner.get(p_material); - ERR_FAIL_COND(!m); - - m->texgen_mode = p_mode; -}; - -VS::FixedSpatialMaterialTexGenMode RasterizerIPhone::fixed_material_get_texgen_mode(RID p_material) const { - - Material *m = material_owner.get(p_material); - ERR_FAIL_COND_V(!m, VS::FIXED_MATERIAL_TEXGEN_SPHERE); - - return m->texgen_mode; -}; - -void RasterizerIPhone::fixed_material_set_uv_transform(RID p_material, const Transform &p_transform) { - - Material *m = material_owner.get(p_material); - ERR_FAIL_COND(!m); - - m->uv_transform = p_transform; -} -Transform RasterizerIPhone::fixed_material_get_uv_transform(RID p_material) const { - - Material *m = material_owner.get(p_material); - ERR_FAIL_COND_V(!m, Transform()); - - return m->uv_transform; -} - -/* SHADER MATERIAL */ - -RID RasterizerIPhone::shader_material_create() const { - - return RID(); -} - -void RasterizerIPhone::shader_material_set_vertex_shader(RID p_material, RID p_shader, bool p_owned) { -} -RID RasterizerIPhone::shader_material_get_vertex_shader(RID p_material) const { - - return RID(); -} - -void RasterizerIPhone::shader_material_set_fragment_shader(RID p_material, RID p_shader, bool p_owned) { -} -RID RasterizerIPhone::shader_material_get_fragment_shader(RID p_material) const { - - return RID(); -} - -/* MESH API */ - -RID RasterizerIPhone::mesh_create() { - - return mesh_owner.make_rid(memnew(Mesh)); -} - -void RasterizerIPhone::mesh_add_surface(RID p_mesh, VS::PrimitiveType p_primitive, uint32_t p_format, int p_array_len, int p_index_array_len) { - - Mesh *mesh = mesh_owner.get(p_mesh); - ERR_FAIL_COND(!mesh); - - ERR_FAIL_COND((p_format & VS::ARRAY_FORMAT_VERTEX) == 0); // mandatory - ERR_FAIL_COND(p_array_len <= 0); - ERR_FAIL_COND(p_index_array_len == 0); - ERR_FAIL_INDEX(p_primitive, VS::PRIMITIVE_MAX); - - Surface *surface = memnew(Surface); - ERR_FAIL_COND(!surface); - - int total_elem_size = 0; - - bool use_VBO = true; //glGenBuffersARB!=NULL; // TODO detect if it's in there - if (p_format & VS::ARRAY_FORMAT_WEIGHTS) { - - use_VBO = false; - } - - for (int i = 0; i < VS::ARRAY_MAX; i++) { - - Surface::ArrayData &ad = surface->array[i]; - ad.size = 0; - ad.configured = false; - ad.ofs = 0; - int elem_size = 0; - int elem_count = 0; - - if (!(p_format & (1 << i))) // no array - continue; - - switch (i) { - - case VS::ARRAY_VERTEX: - case VS::ARRAY_NORMAL: { - - elem_size = 3 * sizeof(GLfloat); // vertex - elem_count = 3; - } break; - case VS::ARRAY_TANGENT: { - elem_size = 4 * sizeof(GLfloat); // vertex - elem_count = 4; - - } break; - case VS::ARRAY_COLOR: { - - elem_size = 4; /* RGBA */ - elem_count = 4; - } break; - case VS::ARRAY_TEX_UV: { - elem_size = 2 * sizeof(GLfloat); - elem_count = 2; - - } break; - case VS::ARRAY_WEIGHTS: - case VS::ARRAY_BONES: { - - elem_size = VS::ARRAY_WEIGHTS_SIZE * sizeof(GLfloat); - elem_count = VS::ARRAY_WEIGHTS_SIZE; - - } break; - case VS::ARRAY_INDEX: { - - if (p_index_array_len <= 0) { - ERR_PRINT("p_index_array_len==NO_INDEX_ARRAY"); - break; - } - /* determine wether using 8 or 16 bits indices */ - if (p_index_array_len > (1 << 8)) { - - elem_size = 2; - } else { - elem_size = 1; - } - - if (use_VBO) { - - glGenBuffers(1, &surface->index_id); - ERR_FAIL_COND(surface->index_id == 0); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, surface->index_id); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, p_index_array_len * elem_size, NULL, GL_STATIC_DRAW); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); //unbind - } else { - surface->index_array_local = (uint8_t *)memalloc(p_index_array_len * elem_size); - }; - - surface->index_array_len = p_index_array_len; // only way it can exist - ad.ofs = 0; - ad.size = elem_size; - ad.configured = false; - ad.components = 1; - - continue; - } break; - default: { - ERR_FAIL(); - } - } - - ad.ofs = total_elem_size; - ad.size = elem_size; - ad.components = elem_count; - total_elem_size += elem_size; - ad.configured = false; - } - - surface->stride = total_elem_size; - surface->array_len = p_array_len; - surface->format = p_format; - surface->primitive = p_primitive; - - /* bind the bigass buffers */ - if (use_VBO) { - - glGenBuffers(1, &surface->vertex_id); - ERR_FAIL_COND(surface->vertex_id == 0); - glBindBuffer(GL_ARRAY_BUFFER, surface->vertex_id); - glBufferData(GL_ARRAY_BUFFER, surface->array_len * surface->stride, NULL, GL_STATIC_DRAW); - glBindBuffer(GL_ARRAY_BUFFER, 0); //unbind - } else { - surface->array_local = (uint8_t *)memalloc(surface->array_len * surface->stride); - }; - - mesh->surfaces.push_back(surface); -} - -Error RasterizerIPhone::mesh_surface_set_array(RID p_mesh, int p_surface, VS::ArrayType p_type, const Variant &p_array) { - - ERR_FAIL_INDEX_V(p_type, VS::ARRAY_MAX, ERR_INVALID_PARAMETER); - - Mesh *mesh = mesh_owner.get(p_mesh); - ERR_FAIL_COND_V(!mesh, ERR_INVALID_PARAMETER); - ERR_FAIL_INDEX_V(p_surface, mesh->surfaces.size(), ERR_INVALID_PARAMETER); - Surface *surface = mesh->surfaces[p_surface]; - ERR_FAIL_COND_V(!surface, ERR_INVALID_PARAMETER); - - ERR_FAIL_COND_V(surface->array[p_type].size == 0, ERR_INVALID_PARAMETER); - - Surface::ArrayData &a = surface->array[p_type]; - - switch (p_type) { - - case VS::ARRAY_INDEX: { - ERR_FAIL_COND_V(surface->index_array_len <= 0, ERR_INVALID_DATA); - ERR_FAIL_COND_V(p_array.get_type() != Variant::INT_ARRAY, ERR_INVALID_PARAMETER); - - PoolVector<int> indices = p_array; - ERR_FAIL_COND_V(indices.size() == 0, ERR_INVALID_PARAMETER); - ERR_FAIL_COND_V(indices.size() != surface->index_array_len, ERR_INVALID_PARAMETER); - - /* determine wether using 16 or 32 bits indices */ - - if (surface->index_array_local == 0) { - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, surface->index_id); - }; - - PoolVector<int>::Read read = indices.read(); - const int *src = read.ptr(); - - for (int i = 0; i < surface->index_array_len; i++) { - - if (surface->index_array_local) { - - if (a.size <= (1 << 8)) { - uint8_t v = src[i]; - - copymem(&surface->array_local[i * a.size], &v, a.size); - } else { - uint16_t v = src[i]; - - copymem(&surface->array_local[i * a.size], &v, a.size); - } - - } else { - if (a.size <= (1 << 8)) { - uint8_t v = src[i]; - - glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, i * a.size, a.size, &v); - } else { - uint16_t v = src[i]; - - glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, i * a.size, a.size, &v); - } - }; - } - if (surface->index_array_local == 0) { - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - }; - a.configured = true; - return OK; - } break; - case VS::ARRAY_VERTEX: - case VS::ARRAY_NORMAL: { - - ERR_FAIL_COND_V(p_array.get_type() != Variant::VECTOR3_ARRAY, ERR_INVALID_PARAMETER); - - PoolVector<Vector3> array = p_array; - ERR_FAIL_COND_V(array.size() != surface->array_len, ERR_INVALID_PARAMETER); - - if (surface->array_local == 0) { - glBindBuffer(GL_ARRAY_BUFFER, surface->vertex_id); - }; - - PoolVector<Vector3>::Read read = array.read(); - const Vector3 *src = read.ptr(); - - // setting vertices means regenerating the AABB - if (p_type == VS::ARRAY_VERTEX) - surface->aabb = AABB(); - - for (int i = 0; i < surface->array_len; i++) { - - GLfloat vector[3] = { src[i].x, src[i].y, src[i].z }; - - if (surface->array_local == 0) { - glBufferSubData(GL_ARRAY_BUFFER, a.ofs + i * surface->stride, a.size, vector); - } else { - copymem(&surface->array_local[a.ofs + i * surface->stride], vector, a.size); - } - - if (p_type == VS::ARRAY_VERTEX) { - - if (i == 0) { - - surface->aabb = AABB(src[i], Vector3()); - } else { - - surface->aabb.expand_to(src[i]); - } - } - } - - if (surface->array_local == 0) { - glBindBuffer(GL_ARRAY_BUFFER, 0); - }; - - } break; - case VS::ARRAY_TANGENT: { - - ERR_FAIL_COND_V(p_array.get_type() != Variant::REAL_ARRAY, ERR_INVALID_PARAMETER); - - PoolVector<real_t> array = p_array; - - ERR_FAIL_COND_V(array.size() != surface->array_len * 4, ERR_INVALID_PARAMETER); - - if (surface->array_local == 0) { - glBindBuffer(GL_ARRAY_BUFFER, surface->vertex_id); - }; - - PoolVector<real_t>::Read read = array.read(); - const real_t *src = read.ptr(); - - for (int i = 0; i < surface->array_len; i++) { - - GLfloat xyzw[4] = { - src[i * 4 + 0], - src[i * 4 + 1], - src[i * 4 + 2], - src[i * 4 + 3] - }; - - if (surface->array_local == 0) { - - glBufferSubData(GL_ARRAY_BUFFER, a.ofs + i * surface->stride, a.size, xyzw); - } else { - - copymem(&surface->array_local[a.ofs + i * surface->stride], xyzw, a.size); - }; - } - - if (surface->array_local == 0) { - glBindBuffer(GL_ARRAY_BUFFER, 0); - }; - } break; - case VS::ARRAY_COLOR: { - - ERR_FAIL_COND_V(p_array.get_type() != Variant::COLOR_ARRAY, ERR_INVALID_PARAMETER); - - PoolVector<Color> array = p_array; - - ERR_FAIL_COND_V(array.size() != surface->array_len, ERR_INVALID_PARAMETER); - - if (surface->array_local == 0) - glBindBuffer(GL_ARRAY_BUFFER, surface->vertex_id); - - PoolVector<Color>::Read read = array.read(); - const Color *src = read.ptr(); - surface->has_alpha_cache = false; - - for (int i = 0; i < surface->array_len; i++) { - - if (src[i].a < 0.98) // tolerate alpha a bit, for crappy exporters - surface->has_alpha_cache = true; - uint8_t colors[4] = { src[i].r * 255.0, src[i].g * 255.0, src[i].b * 255.0, src[i].a * 255.0 }; - // I'm not sure if this is correct, endianness-wise, i should re-check the GL spec - - if (surface->array_local == 0) - glBufferSubData(GL_ARRAY_BUFFER, a.ofs + i * surface->stride, a.size, colors); - else - copymem(&surface->array_local[a.ofs + i * surface->stride], colors, a.size); - } - - if (surface->array_local == 0) - glBindBuffer(GL_ARRAY_BUFFER, 0); - - } break; - case VS::ARRAY_TEX_UV: { - - ERR_FAIL_COND_V(p_array.get_type() != Variant::VECTOR3_ARRAY, ERR_INVALID_PARAMETER); - - PoolVector<Vector3> array = p_array; - - ERR_FAIL_COND_V(array.size() != surface->array_len, ERR_INVALID_PARAMETER); - - if (surface->array_local == 0) - glBindBuffer(GL_ARRAY_BUFFER, surface->vertex_id); - - PoolVector<Vector3>::Read read = array.read(); - - const Vector3 *src = read.ptr(); - - for (int i = 0; i < surface->array_len; i++) { - - GLfloat uv[2] = { src[i].x, src[i].y }; - - if (surface->array_local == 0) - glBufferSubData(GL_ARRAY_BUFFER, a.ofs + i * surface->stride, a.size, uv); - else - copymem(&surface->array_local[a.ofs + i * surface->stride], uv, a.size); - } - - if (surface->array_local == 0) - glBindBuffer(GL_ARRAY_BUFFER, 0); - - } break; - case VS::ARRAY_BONES: - case VS::ARRAY_WEIGHTS: { - - ERR_FAIL_COND_V(p_array.get_type() != Variant::REAL_ARRAY, ERR_INVALID_PARAMETER); - - PoolVector<real_t> array = p_array; - - ERR_FAIL_COND_V(array.size() != surface->array_len * VS::ARRAY_WEIGHTS_SIZE, ERR_INVALID_PARAMETER); - - if (surface->array_local == 0) - glBindBuffer(GL_ARRAY_BUFFER, surface->vertex_id); - - PoolVector<real_t>::Read read = array.read(); - - const real_t *src = read.ptr(); - - for (int i = 0; i < surface->array_len; i++) { - - GLfloat data[VS::ARRAY_WEIGHTS_SIZE]; - for (int j = 0; j < VS::ARRAY_WEIGHTS_SIZE; j++) - data[j] = src[i * VS::ARRAY_WEIGHTS_SIZE + j]; - - if (surface->array_local == 0) - glBufferSubData(GL_ARRAY_BUFFER, a.ofs + i * surface->stride, a.size, data); - else - copymem(&surface->array_local[a.ofs + i * surface->stride], data, a.size); - } - - if (surface->array_local == 0) - glBindBuffer(GL_ARRAY_BUFFER, 0); - } break; - default: { ERR_FAIL_V(ERR_INVALID_PARAMETER); } - } - - a.configured = true; - - return OK; -} -Variant RasterizerIPhone::mesh_surface_get_array(RID p_mesh, int p_surface, VS::ArrayType p_type) const { - - return Variant(); -} - -void RasterizerIPhone::mesh_surface_set_material(RID p_mesh, int p_surface, RID p_material, bool p_owned) { - - Mesh *mesh = mesh_owner.get(p_mesh); - ERR_FAIL_COND(!mesh); - ERR_FAIL_INDEX(p_surface, mesh->surfaces.size()); - Surface *surface = mesh->surfaces[p_surface]; - ERR_FAIL_COND(!surface); - - if (surface->material_owned && surface->material.is_valid()) - free(surface->material); - - surface->material_owned = p_owned; - - surface->material = p_material; -} - -RID RasterizerIPhone::mesh_surface_get_material(RID p_mesh, int p_surface) const { - - Mesh *mesh = mesh_owner.get(p_mesh); - ERR_FAIL_COND_V(!mesh, RID()); - ERR_FAIL_INDEX_V(p_surface, mesh->surfaces.size(), RID()); - Surface *surface = mesh->surfaces[p_surface]; - ERR_FAIL_COND_V(!surface, RID()); - - return surface->material; -} - -int RasterizerIPhone::mesh_surface_get_array_len(RID p_mesh, int p_surface) const { - - Mesh *mesh = mesh_owner.get(p_mesh); - ERR_FAIL_COND_V(!mesh, -1); - ERR_FAIL_INDEX_V(p_surface, mesh->surfaces.size(), -1); - Surface *surface = mesh->surfaces[p_surface]; - ERR_FAIL_COND_V(!surface, -1); - - return surface->array_len; -} -int RasterizerIPhone::mesh_surface_get_array_index_len(RID p_mesh, int p_surface) const { - - Mesh *mesh = mesh_owner.get(p_mesh); - ERR_FAIL_COND_V(!mesh, -1); - ERR_FAIL_INDEX_V(p_surface, mesh->surfaces.size(), -1); - Surface *surface = mesh->surfaces[p_surface]; - ERR_FAIL_COND_V(!surface, -1); - - return surface->index_array_len; -} -uint32_t RasterizerIPhone::mesh_surface_get_format(RID p_mesh, int p_surface) const { - - Mesh *mesh = mesh_owner.get(p_mesh); - ERR_FAIL_COND_V(!mesh, 0); - ERR_FAIL_INDEX_V(p_surface, mesh->surfaces.size(), 0); - Surface *surface = mesh->surfaces[p_surface]; - ERR_FAIL_COND_V(!surface, 0); - - return surface->format; -} -VS::PrimitiveType RasterizerIPhone::mesh_surface_get_primitive_type(RID p_mesh, int p_surface) const { - - Mesh *mesh = mesh_owner.get(p_mesh); - ERR_FAIL_COND_V(!mesh, VS::PRIMITIVE_POINTS); - ERR_FAIL_INDEX_V(p_surface, mesh->surfaces.size(), VS::PRIMITIVE_POINTS); - Surface *surface = mesh->surfaces[p_surface]; - ERR_FAIL_COND_V(!surface, VS::PRIMITIVE_POINTS); - - return surface->primitive; -} - -void RasterizerIPhone::mesh_erase_surface(RID p_mesh, int p_index) { - - Mesh *mesh = mesh_owner.get(p_mesh); - ERR_FAIL_COND(!mesh); - ERR_FAIL_INDEX(p_index, mesh->surfaces.size()); - Surface *surface = mesh->surfaces[p_index]; - ERR_FAIL_COND(!surface); - - memdelete(mesh->surfaces[p_index]); - mesh->surfaces.remove(p_index); -} -int RasterizerIPhone::mesh_get_surface_count(RID p_mesh) const { - - Mesh *mesh = mesh_owner.get(p_mesh); - ERR_FAIL_COND_V(!mesh, -1); - - return mesh->surfaces.size(); -} - -AABB RasterizerIPhone::mesh_get_aabb(RID p_mesh) const { - - Mesh *mesh = mesh_owner.get(p_mesh); - ERR_FAIL_COND_V(!mesh, AABB()); - - AABB aabb; - - for (int i = 0; i < mesh->surfaces.size(); i++) { - - if (i == 0) - aabb = mesh->surfaces[i]->aabb; - else - aabb.merge_with(mesh->surfaces[i]->aabb); - } - - return aabb; -} - -/* MULTIMESH API */ - -RID RasterizerIPhone::multimesh_create() { - - return RID(); -} - -void RasterizerIPhone::multimesh_set_instance_count(RID p_multimesh, int p_count) { -} -int RasterizerIPhone::multimesh_get_instance_count(RID p_multimesh) const { - - return 0; -} - -void RasterizerIPhone::multimesh_set_mesh(RID p_multimesh, RID p_mesh) { -} -void RasterizerIPhone::multimesh_set_aabb(RID p_multimesh, const AABB &p_aabb) { -} -void RasterizerIPhone::multimesh_instance_set_transform(RID p_multimesh, int p_index, const Transform &p_transform) { -} -void RasterizerIPhone::multimesh_instance_set_color(RID p_multimesh, int p_index, const Color &p_color) { -} - -RID RasterizerIPhone::multimesh_get_mesh(RID p_multimesh) const { - - return RID(); -} -AABB RasterizerIPhone::multimesh_get_aabb(RID p_multimesh) const { - - return AABB(); -} - -Transform RasterizerIPhone::multimesh_instance_get_transform(RID p_multimesh, int p_index) const { - - return Transform(); -} -Color RasterizerIPhone::multimesh_instance_get_color(RID p_multimesh, int p_index) const { - - return Color(); -} - -/* POLY API */ - -RID RasterizerIPhone::poly_create() { - - return RID(); -} -void RasterizerIPhone::poly_set_material(RID p_poly, RID p_material, bool p_owned) { -} -void RasterizerIPhone::poly_add_primitive(RID p_poly, const Vector<Vector3> &p_points, const Vector<Vector3> &p_normals, const Vector<Color> &p_colors, const Vector<Vector3> &p_uvs) { -} -void RasterizerIPhone::poly_clear(RID p_poly) { -} - -AABB RasterizerIPhone::poly_get_aabb(RID p_poly) const { - - return AABB(); -} - -/* PARTICLES API */ - -RID RasterizerIPhone::particles_create() { - - return RID(); -} - -void RasterizerIPhone::particles_set_amount(RID p_particles, int p_amount) { -} -int RasterizerIPhone::particles_get_amount(RID p_particles) const { - - return 0; -} - -void RasterizerIPhone::particles_set_emitting(RID p_particles, bool p_emitting) { -} - -bool RasterizerIPhone::particles_is_emitting(RID p_particles) const { - - return false; -} - -void RasterizerIPhone::particles_set_visibility_aabb(RID p_particles, const AABB &p_visibility) { -} -AABB RasterizerIPhone::particles_get_visibility_aabb(RID p_particles) const { - - return AABB(); -} - -void RasterizerIPhone::particles_set_emission_half_extents(RID p_particles, const Vector3 &p_half_extents) { -} -Vector3 RasterizerIPhone::particles_get_emission_half_extents(RID p_particles) const { - - return Vector3(); -} - -void RasterizerIPhone::particles_set_gravity_normal(RID p_particles, const Vector3 &p_normal) { -} -Vector3 RasterizerIPhone::particles_get_gravity_normal(RID p_particles) const { - - return Vector3(); -} - -void RasterizerIPhone::particles_set_variable(RID p_particles, VS::ParticleVariable p_variable, float p_value) { -} -float RasterizerIPhone::particles_get_variable(RID p_particles, VS::ParticleVariable p_variable) const { - - return 0; -} - -void RasterizerIPhone::particles_set_randomness(RID p_particles, VS::ParticleVariable p_variable, float p_randomness) { -} -float RasterizerIPhone::particles_get_randomness(RID p_particles, VS::ParticleVariable p_variable) const { - - return 0; -} - -void RasterizerIPhone::particles_set_color_phase_pos(RID p_particles, int p_phase, float p_pos) { -} -float RasterizerIPhone::particles_get_color_phase_pos(RID p_particles, int p_phase) const { - - return 0; -} - -void RasterizerIPhone::particles_set_color_phases(RID p_particles, int p_phases) { -} -int RasterizerIPhone::particles_get_color_phases(RID p_particles) const { - - return 0; -} - -void RasterizerIPhone::particles_set_color_phase_color(RID p_particles, int p_phase, const Color &p_color) { -} -Color RasterizerIPhone::particles_get_color_phase_color(RID p_particles, int p_phase) const { - - return Color(); -} - -void RasterizerIPhone::particles_set_attractors(RID p_particles, int p_attractors) { -} -int RasterizerIPhone::particles_get_attractors(RID p_particles) const { - - return 0; -} - -void RasterizerIPhone::particles_set_attractor_pos(RID p_particles, int p_attractor, const Vector3 &p_pos) { -} -Vector3 RasterizerIPhone::particles_get_attractor_pos(RID p_particles, int p_attractor) const { - - return Vector3(); -} - -void RasterizerIPhone::particles_set_attractor_strength(RID p_particles, int p_attractor, float p_force) { -} -float RasterizerIPhone::particles_get_attractor_strength(RID p_particles, int p_attractor) const { - - return 0; -} - -void RasterizerIPhone::particles_set_material(RID p_particles, RID p_material, bool p_owned) { -} - -RID RasterizerIPhone::particles_get_material(RID p_particles) const { - - return RID(); -} - -AABB RasterizerIPhone::particles_get_aabb(RID p_particles) const { - - return AABB(); -} -/* BEAM API */ - -RID RasterizerIPhone::beam_create() { - - return RID(); -} - -void RasterizerIPhone::beam_set_point_count(RID p_beam, int p_count) { -} -int RasterizerIPhone::beam_get_point_count(RID p_beam) const { - - return 0; -} -void RasterizerIPhone::beam_clear(RID p_beam) { -} - -void RasterizerIPhone::beam_set_point(RID p_beam, int p_point, Vector3 &p_pos) { -} -Vector3 RasterizerIPhone::beam_get_point(RID p_beam, int p_point) const { - - return Vector3(); -} - -void RasterizerIPhone::beam_set_primitive(RID p_beam, VS::BeamPrimitive p_primitive) { -} - -VS::BeamPrimitive RasterizerIPhone::beam_get_primitive(RID p_beam) const { - - return VS::BEAM_CUBIC; -} - -void RasterizerIPhone::beam_set_material(RID p_beam, RID p_material) { -} -RID RasterizerIPhone::beam_get_material(RID p_beam) const { - - return RID(); -} - -AABB RasterizerIPhone::beam_get_aabb(RID p_particles) const { - - return AABB(); -} -/* SKELETON API */ - -RID RasterizerIPhone::skeleton_create() { - - Skeleton *skeleton = memnew(Skeleton); - ERR_FAIL_COND_V(!skeleton, RID()); - return skeleton_owner.make_rid(skeleton); -} -void RasterizerIPhone::skeleton_resize(RID p_skeleton, int p_bones) { - - Skeleton *skeleton = skeleton_owner.get(p_skeleton); - ERR_FAIL_COND(!skeleton); - if (p_bones == skeleton->bones.size()) { - return; - }; - ERR_FAIL_COND(p_bones < 0 || p_bones > 256); - - skeleton->bones.resize(p_bones); -} -int RasterizerIPhone::skeleton_get_bone_count(RID p_skeleton) const { - - Skeleton *skeleton = skeleton_owner.get(p_skeleton); - ERR_FAIL_COND_V(!skeleton, -1); - return skeleton->bones.size(); -} -void RasterizerIPhone::skeleton_bone_set_transform(RID p_skeleton, int p_bone, const Transform &p_transform) { - - Skeleton *skeleton = skeleton_owner.get(p_skeleton); - ERR_FAIL_COND(!skeleton); - ERR_FAIL_INDEX(p_bone, skeleton->bones.size()); - - skeleton->bones[p_bone] = p_transform; -} -Transform RasterizerIPhone::skeleton_bone_get_transform(RID p_skeleton, int p_bone) { - - Skeleton *skeleton = skeleton_owner.get(p_skeleton); - ERR_FAIL_COND_V(!skeleton, Transform()); - ERR_FAIL_INDEX_V(p_bone, skeleton->bones.size(), Transform()); - - // something - return skeleton->bones[p_bone]; -} - -/* LIGHT API */ - -RID RasterizerIPhone::light_create(VS::LightType p_type) { - - Light *light = memnew(Light); - light->type = p_type; - return light_owner.make_rid(light); -} - -VS::LightType RasterizerIPhone::light_get_type(RID p_light) const { - - Light *light = light_owner.get(p_light); - ERR_FAIL_COND_V(!light, VS::LIGHT_OMNI); - return light->type; -} - -void RasterizerIPhone::light_set_color(RID p_light, VS::LightColor p_type, const Color &p_color) { - - Light *light = light_owner.get(p_light); - ERR_FAIL_COND(!light); - ERR_FAIL_INDEX(p_type, 3); - light->colors[p_type] = p_color; -} -Color RasterizerIPhone::light_get_color(RID p_light, VS::LightColor p_type) const { - - Light *light = light_owner.get(p_light); - ERR_FAIL_COND_V(!light, Color()); - ERR_FAIL_INDEX_V(p_type, 3, Color()); - return light->colors[p_type]; -} - -void RasterizerIPhone::light_set_shadow(RID p_light, bool p_enabled) { - - Light *light = light_owner.get(p_light); - ERR_FAIL_COND(!light); - light->shadow_enabled = p_enabled; -} - -bool RasterizerIPhone::light_has_shadow(RID p_light) const { - - Light *light = light_owner.get(p_light); - ERR_FAIL_COND_V(!light, false); - return light->shadow_enabled; -} - -void RasterizerIPhone::light_set_volumetric(RID p_light, bool p_enabled) { - - Light *light = light_owner.get(p_light); - ERR_FAIL_COND(!light); - light->volumetric_enabled = p_enabled; -} -bool RasterizerIPhone::light_is_volumetric(RID p_light) const { - - Light *light = light_owner.get(p_light); - ERR_FAIL_COND_V(!light, false); - return light->volumetric_enabled; -} - -void RasterizerIPhone::light_set_projector(RID p_light, RID p_texture) { - - Light *light = light_owner.get(p_light); - ERR_FAIL_COND(!light); - light->projector = p_texture; -} -RID RasterizerIPhone::light_get_projector(RID p_light) const { - - Light *light = light_owner.get(p_light); - ERR_FAIL_COND_V(!light, RID()); - return light->projector; -} - -void RasterizerIPhone::light_set_var(RID p_light, VS::LightParam p_var, float p_value) { - - Light *light = light_owner.get(p_light); - ERR_FAIL_COND(!light); - ERR_FAIL_INDEX(p_var, VS::LIGHT_PARAM_MAX); - - light->vars[p_var] = p_value; -} -float RasterizerIPhone::light_get_var(RID p_light, VS::LightParam p_var) const { - - Light *light = light_owner.get(p_light); - ERR_FAIL_COND_V(!light, 0); - - ERR_FAIL_INDEX_V(p_var, VS::LIGHT_PARAM_MAX, 0); - - return light->vars[p_var]; -} - -AABB RasterizerIPhone::light_get_aabb(RID p_light) const { - - Light *light = light_owner.get(p_light); - ERR_FAIL_COND_V(!light, AABB()); - - switch (light->type) { - - case VS::LIGHT_SPOT: { - - float len = light->vars[VS::LIGHT_PARAM_RADIUS]; - float size = Math::tan(Math::deg2rad(light->vars[VS::LIGHT_PARAM_SPOT_ANGLE])) * len; - return AABB(Vector3(-size, -size, -len), Vector3(size * 2, size * 2, len)); - } break; - case VS::LIGHT_OMNI: { - - float r = light->vars[VS::LIGHT_PARAM_RADIUS]; - return AABB(-Vector3(r, r, r), Vector3(r, r, r) * 2); - } break; - case VS::LIGHT_DIRECTIONAL: { - - return AABB(); - } break; - default: {} - } - - ERR_FAIL_V(AABB()); -} - -RID RasterizerIPhone::light_instance_create(RID p_light) { - - Light *light = light_owner.get(p_light); - ERR_FAIL_COND_V(!light, RID()); - - LightInstance *light_instance = memnew(LightInstance); - - light_instance->light = p_light; - light_instance->base = light; - light_instance->last_pass = 0; - - return light_instance_owner.make_rid(light_instance); -} -void RasterizerIPhone::light_instance_set_transform(RID p_light_instance, const Transform &p_transform) { - - LightInstance *lighti = light_instance_owner.get(p_light_instance); - ERR_FAIL_COND(!lighti); - lighti->transform = p_transform; -} - -void RasterizerIPhone::light_instance_set_active_hint(RID p_light_instance) { - - LightInstance *lighti = light_instance_owner.get(p_light_instance); - ERR_FAIL_COND(!lighti); - lighti->last_pass = frame; -} -bool RasterizerIPhone::light_instance_has_shadow(RID p_light_instance) const { - - return false; -} -bool RasterizerIPhone::light_instance_assign_shadow(RID p_light_instance) { - - return false; -} -Rasterizer::ShadowType RasterizerIPhone::light_instance_get_shadow_type(RID p_light_instance) const { - - return Rasterizer::SHADOW_CUBE; -} -int RasterizerIPhone::light_instance_get_shadow_passes(RID p_light_instance) const { - - return 0; -} -void RasterizerIPhone::light_instance_set_pssm_split_info(RID p_light_instance, int p_split, float p_near, float p_far, const CameraMatrix &p_camera, const Transform &p_transform) { -} - -/* PARTICLES INSTANCE */ - -RID RasterizerIPhone::particles_instance_create(RID p_particles) { - - return RID(); -} -void RasterizerIPhone::particles_instance_set_transform(RID p_particles_instance, const Transform &p_transform) { -} - -/* RENDER API */ -/* all calls (inside begin/end shadow) are always warranted to be in the following order: */ - -static GLfloat rtri; // Angle For The Triangle ( NEW ) -static GLfloat rquad; // Angle For The Quad ( NEW ) - -void RasterizerIPhone::begin_frame() { - - window_size = Size2(OS::get_singleton()->get_video_mode().width, OS::get_singleton()->get_video_mode().height); - - double time = (OS::get_singleton()->get_ticks_usec() / 1000); // get msec - time /= 1000.0; // make secs - time_delta = time - last_time; - last_time = time; - frame++; - glClearColor(0, 0, 1, 1); - glClear(GL_COLOR_BUFFER_BIT); - -/* nehe ?*/ - -#if 0 - glViewport(0,0,window_size.width,window_size.height); // Reset The Current Viewport - - glMatrixMode(GL_PROJECTION); // Select The Projection Matrix - glLoadIdentity(); // Reset The Projection Matrix - - // Calculate The Aspect Ratio Of The Window - gluPerspective(45.0f,(GLfloat)window_size.width/(GLfloat)window_size.height,0.1f,100.0f); - - glMatrixMode(GL_MODELVIEW); // Select The Modelview Matrix - glLoadIdentity(); // Reset The Modelview Matrix - - - - glShadeModel(GL_SMOOTH); // Enable Smooth Shading - glClearColor(0.0f, 0.0f, 0.0f, 0.5f); // Black Background - glClearDepth(1.0f); // Depth Buffer Setup - glEnable(GL_DEPTH_TEST); // Enables Depth Testing - glDepthFunc(GL_LEQUAL); // The Type Of Depth Testing To Do - glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Really Nice Perspective Calculations - - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear Screen And Depth Buffer - glLoadIdentity(); // Reset The Current Modelview Matrix - glTranslatef(-1.5f,0.0f,-6.0f); // Move Left 1.5 Units And Into The Screen 6.0 - glRotatef(rtri,0.0f,1.0f,0.0f); // Rotate The Triangle On The Y axis ( NEW ) - glBegin(GL_TRIANGLES); // Start Drawing A Triangle - glColor3f(1.0f,0.0f,0.0f); // Red - glVertex3f( 0.0f, 1.0f, 0.0f); // Top Of Triangle (Front) - glColor3f(0.0f,1.0f,0.0f); // Green - glVertex3f(-1.0f,-1.0f, 1.0f); // Left Of Triangle (Front) - glColor3f(0.0f,0.0f,1.0f); // Blue - glVertex3f( 1.0f,-1.0f, 1.0f); // Right Of Triangle (Front) - glColor3f(1.0f,0.0f,0.0f); // Red - glVertex3f( 0.0f, 1.0f, 0.0f); // Top Of Triangle (Right) - glColor3f(0.0f,0.0f,1.0f); // Blue - glVertex3f( 1.0f,-1.0f, 1.0f); // Left Of Triangle (Right) - glColor3f(0.0f,1.0f,0.0f); // Green - glVertex3f( 1.0f,-1.0f, -1.0f); // Right Of Triangle (Right) - glColor3f(1.0f,0.0f,0.0f); // Red - glVertex3f( 0.0f, 1.0f, 0.0f); // Top Of Triangle (Back) - glColor3f(0.0f,1.0f,0.0f); // Green - glVertex3f( 1.0f,-1.0f, -1.0f); // Left Of Triangle (Back) - glColor3f(0.0f,0.0f,1.0f); // Blue - glVertex3f(-1.0f,-1.0f, -1.0f); // Right Of Triangle (Back) - glColor3f(1.0f,0.0f,0.0f); // Red - glVertex3f( 0.0f, 1.0f, 0.0f); // Top Of Triangle (Left) - glColor3f(0.0f,0.0f,1.0f); // Blue - glVertex3f(-1.0f,-1.0f,-1.0f); // Left Of Triangle (Left) - glColor3f(0.0f,1.0f,0.0f); // Green - glVertex3f(-1.0f,-1.0f, 1.0f); // Right Of Triangle (Left) - glEnd(); // Done Drawing The Pyramid - - glLoadIdentity(); // Reset The Current Modelview Matrix - glTranslatef(1.5f,0.0f,-7.0f); // Move Right 1.5 Units And Into The Screen 7.0 - glRotatef(rquad,1.0f,1.0f,1.0f); // Rotate The Quad On The X axis ( NEW ) - glBegin(GL_QUADS); // Draw A Quad - glColor3f(0.0f,1.0f,0.0f); // Set The Color To Green - glVertex3f( 1.0f, 1.0f,-1.0f); // Top Right Of The Quad (Top) - glVertex3f(-1.0f, 1.0f,-1.0f); // Top Left Of The Quad (Top) - glVertex3f(-1.0f, 1.0f, 1.0f); // Bottom Left Of The Quad (Top) - glVertex3f( 1.0f, 1.0f, 1.0f); // Bottom Right Of The Quad (Top) - glColor3f(1.0f,0.5f,0.0f); // Set The Color To Orange - glVertex3f( 1.0f,-1.0f, 1.0f); // Top Right Of The Quad (Bottom) - glVertex3f(-1.0f,-1.0f, 1.0f); // Top Left Of The Quad (Bottom) - glVertex3f(-1.0f,-1.0f,-1.0f); // Bottom Left Of The Quad (Bottom) - glVertex3f( 1.0f,-1.0f,-1.0f); // Bottom Right Of The Quad (Bottom) - glColor3f(1.0f,0.0f,0.0f); // Set The Color To Red - glVertex3f( 1.0f, 1.0f, 1.0f); // Top Right Of The Quad (Front) - glVertex3f(-1.0f, 1.0f, 1.0f); // Top Left Of The Quad (Front) - glVertex3f(-1.0f,-1.0f, 1.0f); // Bottom Left Of The Quad (Front) - glVertex3f( 1.0f,-1.0f, 1.0f); // Bottom Right Of The Quad (Front) - glColor3f(1.0f,1.0f,0.0f); // Set The Color To Yellow - glVertex3f( 1.0f,-1.0f,-1.0f); // Top Right Of The Quad (Back) - glVertex3f(-1.0f,-1.0f,-1.0f); // Top Left Of The Quad (Back) - glVertex3f(-1.0f, 1.0f,-1.0f); // Bottom Left Of The Quad (Back) - glVertex3f( 1.0f, 1.0f,-1.0f); // Bottom Right Of The Quad (Back) - glColor3f(0.0f,0.0f,1.0f); // Set The Color To Blue - glVertex3f(-1.0f, 1.0f, 1.0f); // Top Right Of The Quad (Left) - glVertex3f(-1.0f, 1.0f,-1.0f); // Top Left Of The Quad (Left) - glVertex3f(-1.0f,-1.0f,-1.0f); // Bottom Left Of The Quad (Left) - glVertex3f(-1.0f,-1.0f, 1.0f); // Bottom Right Of The Quad (Left) - glColor3f(1.0f,0.0f,1.0f); // Set The Color To Violet - glVertex3f( 1.0f, 1.0f,-1.0f); // Top Right Of The Quad (Right) - glVertex3f( 1.0f, 1.0f, 1.0f); // Top Left Of The Quad (Right) - glVertex3f( 1.0f,-1.0f, 1.0f); // Bottom Left Of The Quad (Right) - glVertex3f( 1.0f,-1.0f,-1.0f); // Bottom Right Of The Quad (Right) - glEnd(); // Done Drawing The Quad - - rtri+=0.2f; // Increase The Rotation Variable For The Triangle ( NEW ) - rquad-=0.15f; // Decrease The Rotation Variable For The Quad ( NEW ) - -#endif -} - -void RasterizerIPhone::set_viewport(const VS::ViewportRect &p_viewport) { - - viewport = p_viewport; - canvas_transform = Transform(); - canvas_transform.translate(-(viewport.width / 2.0f), -(viewport.height / 2.0f), 0.0f); - canvas_transform.scale(Vector3(2.0f / viewport.width, -2.0f / viewport.height, 1.0f)); - - glViewport(viewport.x, window_size.height - (viewport.height + viewport.y), viewport.width, viewport.height); -} - -void RasterizerIPhone::begin_scene(RID p_fx, VS::ScenarioDebugMode p_debug) { - - opaque_render_list.clear(); - alpha_render_list.clear(); - light_instance_count = 0; - scene_fx = p_fx.is_valid() ? fx_owner.get(p_fx) : NULL; -}; - -void RasterizerIPhone::begin_shadow_map(RID p_light_instance, int p_shadow_pass) { -} - -void RasterizerIPhone::set_camera(const Transform &p_world, const CameraMatrix &p_projection) { - - camera_transform = p_world; - camera_transform_inverse = camera_transform.inverse(); - camera_projection = p_projection; - camera_plane = Plane(camera_transform.origin, camera_transform.basis.get_axis(2)); - camera_z_near = camera_projection.get_z_near(); - camera_z_far = camera_projection.get_z_far(); - camera_projection.get_viewport_size(camera_vp_size.x, camera_vp_size.y); -} - -void RasterizerIPhone::add_light(RID p_light_instance) { - -#define LIGHT_FADE_TRESHOLD 0.05 - - ERR_FAIL_COND(light_instance_count >= MAX_LIGHTS); - - LightInstance *li = light_instance_owner.get(p_light_instance); - ERR_FAIL_COND(!li); - - /* make light hash */ - - // actually, not really a hash, but helps to sort the lights - // and avoid recompiling redudant shader versions - - li->hash_aux = li->base->type; - - if (li->base->shadow_enabled) - li->hash_aux |= (1 << 3); - - if (li->base->projector.is_valid()) - li->hash_aux |= (1 << 4); - - if (li->base->shadow_enabled && li->base->volumetric_enabled) - li->hash_aux |= (1 << 5); - - switch (li->base->type) { - - case VisualServer::LIGHT_DIRECTIONAL: { - - Vector3 dir = li->transform.basis.get_axis(2); - li->light_vector.x = dir.x; - li->light_vector.y = dir.y; - li->light_vector.z = dir.z; - - } break; - case VisualServer::LIGHT_OMNI: { - - float radius = li->base->vars[VisualServer::LIGHT_PARAM_RADIUS]; - if (radius == 0) - radius = 0.0001; - li->linear_att = (1 / LIGHT_FADE_TRESHOLD) / radius; - li->light_vector.x = li->transform.origin.x; - li->light_vector.y = li->transform.origin.y; - li->light_vector.z = li->transform.origin.z; - - } break; - case VisualServer::LIGHT_SPOT: { - - float radius = li->base->vars[VisualServer::LIGHT_PARAM_RADIUS]; - if (radius == 0) - radius = 0.0001; - li->linear_att = (1 / LIGHT_FADE_TRESHOLD) / radius; - li->light_vector.x = li->transform.origin.x; - li->light_vector.y = li->transform.origin.y; - li->light_vector.z = li->transform.origin.z; - Vector3 dir = -li->transform.basis.get_axis(2); - li->spot_vector.x = dir.x; - li->spot_vector.y = dir.y; - li->spot_vector.z = dir.z; - - } break; - } - - light_instances[light_instance_count++] = li; -} - -void RasterizerIPhone::_add_geometry(const Geometry *p_geometry, const Transform &p_world, uint32_t p_vertex_format, const RID *p_light_instances, int p_light_count, const ParamOverrideMap *p_material_overrides, const Skeleton *p_skeleton, GeometryOwner *p_owner) { - - Material *m = NULL; - - if (p_geometry->material.is_valid()) - m = material_owner.get(p_geometry->material); - - if (!m) { - m = material_owner.get(default_material); - } - - ERR_FAIL_COND(!m); - - LightInstance *lights[RenderList::MAX_LIGHTS]; - int light_count = 0; - - RenderList *render_list = &opaque_render_list; - if (p_geometry->has_alpha || m->detail_blend_mode != VS::MATERIAL_BLEND_MODE_MIX) { - render_list = &alpha_render_list; - }; - - if (!m->flags[VS::MATERIAL_FLAG_UNSHADED]) { - - light_count = p_light_count; - for (int i = 0; i < light_count; i++) { - lights[i] = light_instance_owner.get(p_light_instances[i]); - } - } - - render_list->add_element(p_geometry, m, p_world, lights, light_count, p_material_overrides, p_skeleton, camera_plane.distance(p_world.origin), p_owner); -} - -void RasterizerIPhone::add_mesh(RID p_mesh, const Transform *p_world, const RID *p_light_instances, int p_light_count, const ParamOverrideMap *p_material_overrides, RID p_skeleton) { - - Mesh *mesh = mesh_owner.get(p_mesh); - - int ssize = mesh->surfaces.size(); - - for (int i = 0; i < ssize; i++) { - - Surface *s = mesh->surfaces[i]; - Skeleton *sk = p_skeleton.is_valid() ? skeleton_owner.get(p_skeleton) : NULL; - - _add_geometry(s, *p_world, s->format, p_light_instances, p_light_count, p_material_overrides, sk, NULL); - } - - mesh->last_pass = frame; -} - -void RasterizerIPhone::add_multimesh(RID p_multimesh, const Transform *p_world, const RID *p_light_instances, int p_light_count, const ParamOverrideMap *p_material_overrides) { -} - -void RasterizerIPhone::add_poly(RID p_poly, const Transform *p_world, const RID *p_light_instances, int p_light_count, const ParamOverrideMap *p_material_overrides) { - - Poly *p = poly_owner.get(p_poly); - if (!p->primitives.empty()) { - const Poly::Primitive *pp = &p->primitives[0]; - - uint32_t format = VisualServer::ARRAY_FORMAT_VERTEX; - - if (!pp->normals.empty()) - format |= VisualServer::ARRAY_FORMAT_NORMAL; - if (!pp->colors.empty()) - format |= VisualServer::ARRAY_FORMAT_COLOR; - if (!pp->uvs.empty()) - format |= VisualServer::ARRAY_TEX_UV; - - _add_geometry(p, *p_world, format, p_light_instances, p_light_count, p_material_overrides, NULL, NULL); - } -} - -void RasterizerIPhone::add_beam(RID p_beam, const Transform *p_world, const RID *p_light_instances, int p_light_count, const ParamOverrideMap *p_material_overrides) { -} - -void RasterizerIPhone::add_particles(RID p_particle_instance, const RID *p_light_instances, int p_light_count, const ParamOverrideMap *p_material_overrides) { -} - -void RasterizerIPhone::_setup_material(const Geometry *p_geometry, const Material *p_material) { - - if (p_material->flags[VS::MATERIAL_FLAG_DOUBLE_SIDED]) - glDisable(GL_CULL_FACE); - else { - glEnable(GL_CULL_FACE); - glCullFace((p_material->flags[VS::MATERIAL_FLAG_INVERT_FACES]) ? GL_FRONT : GL_BACK); - } - - glEnable(GL_COLOR_MATERIAL); /* unused, unless color array */ - //glColorMaterial( GL_FRONT_AND_BACK, GL_DIFFUSE ); - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - - ///ambient @TODO offer global ambient group option - float ambient_rgba[4] = { - 1, - 1, - 1, - 1.0 - }; - glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, ambient_rgba); - - ///diffuse - const Color &diffuse_color = p_material->parameters[VS::FIXED_MATERIAL_PARAM_DIFFUSE]; - float diffuse_rgba[4] = { - (float)diffuse_color.r, - (float)diffuse_color.g, - (float)diffuse_color.b, - (float)diffuse_color.a - }; - - glColor4f(diffuse_rgba[0], diffuse_rgba[1], diffuse_rgba[2], diffuse_rgba[3]); - - glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diffuse_rgba); - - //specular - - const Color &specular_color = p_material->parameters[VS::FIXED_MATERIAL_PARAM_SPECULAR]; - float specular_rgba[4] = { - (float)specular_color.r, - (float)specular_color.g, - (float)specular_color.b, - 1.0 - }; - - glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specular_rgba); - - const Color &emission_color = p_material->parameters[VS::FIXED_MATERIAL_PARAM_EMISSION]; - float emission_rgba[4] = { - (float)emission_color.r, - (float)emission_color.g, - (float)emission_color.b, - 1.0 - }; - - glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, emission_rgba); - - glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, p_material->parameters[VS::FIXED_MATERIAL_PARAM_SPECULAR_EXP]); - - if (p_material->flags[VS::MATERIAL_FLAG_UNSHADED]) { - glDisable(GL_LIGHTING); - } else { - glEnable(GL_LIGHTING); - glDisable(GL_LIGHTING); - } - - //depth test? - /* - if (p_material->flags[VS::MATERIAL_FLAG_WIREFRAME]) - glPolygonMode(GL_FRONT_AND_BACK,GL_LINE); - else - glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); - */ - if (p_material->textures[VS::FIXED_MATERIAL_PARAM_DIFFUSE]) { - - Texture *texture = texture_owner.get(p_material->textures[VS::FIXED_MATERIAL_PARAM_DIFFUSE]); - ERR_FAIL_COND(!texture); - glActiveTexture(GL_TEXTURE0); - glEnable(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D, texture->tex_id); - }; -}; - -void RasterizerIPhone::_setup_light(LightInstance *p_instance, int p_idx) { - - Light *ld = p_instance->base; - - int glid = GL_LIGHT0 + p_idx; - glLightfv(glid, GL_AMBIENT, ld->colors[VS::LIGHT_COLOR_AMBIENT].components); - glLightfv(glid, GL_DIFFUSE, ld->colors[VS::LIGHT_COLOR_DIFFUSE].components); - glLightfv(glid, GL_SPECULAR, ld->colors[VS::LIGHT_COLOR_SPECULAR].components); - - switch (ld->type) { - - case VS::LIGHT_DIRECTIONAL: { - /* This doesnt have attenuation */ - - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glLoadIdentity(); - Vector3 v(0.0, 0.0, -1.0); // directional lights point up by default - v = p_instance->transform.get_basis().xform(v); - v = camera_transform_inverse.get_basis().xform(v); - v.normalize(); // this sucks, so it will be optimized at some point - v = -v; - float lightpos[4] = { v.x, v.y, v.z, 0.0 }; - - glLightfv(glid, GL_POSITION, lightpos); //at modelview - - glPopMatrix(); - - } break; - case VS::LIGHT_OMNI: { - - glLightf(glid, GL_SPOT_CUTOFF, 180.0); - glLightf(glid, GL_CONSTANT_ATTENUATION, ld->vars[VS::LIGHT_PARAM_ATTENUATION]); - glLightf(glid, GL_LINEAR_ATTENUATION, ld->vars[VS::LIGHT_PARAM_RADIUS]); - glLightf(glid, GL_QUADRATIC_ATTENUATION, ld->vars[VS::LIGHT_PARAM_ENERGY]); // wut? - - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glLoadIdentity(); - Vector3 pos = p_instance->transform.get_origin(); - pos = camera_transform_inverse.xform(pos); - float lightpos[4] = { pos.x, pos.y, pos.z, 1.0 }; - glLightfv(glid, GL_POSITION, lightpos); //at modelview - - glPopMatrix(); - - } break; - case VS::LIGHT_SPOT: { - - glLightf(glid, GL_SPOT_CUTOFF, ld->vars[VS::LIGHT_PARAM_SPOT_ANGLE]); - glLightf(glid, GL_SPOT_EXPONENT, ld->vars[VS::LIGHT_PARAM_SPOT_ATTENUATION]); - glLightf(glid, GL_CONSTANT_ATTENUATION, ld->vars[VS::LIGHT_PARAM_ATTENUATION]); - glLightf(glid, GL_LINEAR_ATTENUATION, ld->vars[VS::LIGHT_PARAM_RADIUS]); - glLightf(glid, GL_QUADRATIC_ATTENUATION, ld->vars[VS::LIGHT_PARAM_ENERGY]); // wut? - - glMatrixMode(GL_MODELVIEW); - glPushMatrix(); - glLoadIdentity(); - - Vector3 v(0.0, 0.0, -1.0); // directional lights point up by default - v = p_instance->transform.get_basis().xform(v); - v = camera_transform_inverse.get_basis().xform(v); - v.normalize(); // this sucks, so it will be optimized at some point - float lightdir[4] = { v.x, v.y, v.z, 1.0 }; - glLightfv(glid, GL_SPOT_DIRECTION, lightdir); //at modelview - - v = p_instance->transform.get_origin(); - v = camera_transform_inverse.xform(v); - float lightpos[4] = { v.x, v.y, v.z, 1.0 }; - glLightfv(glid, GL_POSITION, lightpos); //at modelview - - glPopMatrix(); - - } break; - default: break; - } -}; - -void RasterizerIPhone::_setup_lights(LightInstance **p_lights, int p_light_count) { - - for (int i = 0; i < MAX_LIGHTS; i++) { - - if (i < p_light_count) { - glEnable(GL_LIGHT0 + i); - _setup_light(p_lights[i], i); - } else { - glDisable(GL_LIGHT0 + i); - } - } -} - -static const int gl_client_states[] = { - - GL_VERTEX_ARRAY, - GL_NORMAL_ARRAY, - -1, // ARRAY_TANGENT - GL_COLOR_ARRAY, - GL_TEXTURE_COORD_ARRAY, // ARRAY_TEX_UV - GL_TEXTURE_COORD_ARRAY, // ARRAY_TEX_UV2 - -1, // ARRAY_BONES - -1, // ARRAY_WEIGHTS - -1, // ARRAY_INDEX -}; - -void RasterizerIPhone::_setup_geometry(const Geometry *p_geometry, const Material *p_material) { - - switch (p_geometry->type) { - - case Geometry::GEOMETRY_SURFACE: { - - Surface *surf = (Surface *)p_geometry; - uint8_t *base = 0; - bool use_VBO = (surf->array_local == 0); - - if (!use_VBO) { - - base = surf->array_local; - glBindBuffer(GL_ARRAY_BUFFER, 0); - - } else { - - glBindBuffer(GL_ARRAY_BUFFER, surf->vertex_id); - }; - - const Surface::ArrayData *a = surf->array; - for (int i = 0; i < VS::ARRAY_MAX; i++) { - - const Surface::ArrayData &ad = surf->array[i]; - if (ad.size == 0) { - if (gl_client_states[i] != -1) { - glDisableClientState(gl_client_states[i]); - }; - continue; // this one is disabled. - } - ERR_CONTINUE(!ad.configured); - - if (gl_client_states[i] != -1) { - glEnableClientState(gl_client_states[i]); - }; - - switch (i) { - - case VS::ARRAY_VERTEX: - if (!use_VBO) - glVertexPointer(3, GL_FLOAT, surf->stride, (GLvoid *)&base[a->ofs]); - else if (surf->array[VS::ARRAY_BONES].size) - glVertexPointer(3, GL_FLOAT, 0, skinned_buffer); - else - glVertexPointer(3, GL_FLOAT, surf->stride, (GLvoid *)a->ofs); - break; - - case VS::ARRAY_NORMAL: - if (use_VBO) - glNormalPointer(GL_FLOAT, surf->stride, (GLvoid *)a->ofs); - else - glNormalPointer(GL_FLOAT, surf->stride, (GLvoid *)&base[a->ofs]); - break; - case VS::ARRAY_TANGENT: - break; - case VS::ARRAY_COLOR: - if (use_VBO) - glColorPointer(4, GL_UNSIGNED_BYTE, surf->stride, (GLvoid *)a->ofs); - else - glColorPointer(4, GL_UNSIGNED_BYTE, surf->stride, (GLvoid *)&base[a->ofs]); - break; - case VS::ARRAY_TEX_UV: - case VS::ARRAY_TEX_UV2: - if (use_VBO) - glTexCoordPointer(2, GL_FLOAT, surf->stride, (GLvoid *)a->ofs); - else - glTexCoordPointer(2, GL_FLOAT, surf->stride, &base[a->ofs]); - break; - case VS::ARRAY_BONES: - case VS::ARRAY_WEIGHTS: - case VS::ARRAY_INDEX: - break; - }; - } - - // process skeleton here - - } break; - - default: break; - }; -}; - -static const GLenum gl_primitive[] = { - GL_POINTS, - GL_LINES, - GL_LINE_STRIP, - GL_LINE_LOOP, - GL_TRIANGLES, - GL_TRIANGLE_STRIP, - GL_TRIANGLE_FAN -}; - -void RasterizerIPhone::_render(const Geometry *p_geometry, const Material *p_material, const Skeleton *p_skeleton) { - - switch (p_geometry->type) { - - case Geometry::GEOMETRY_SURFACE: { - - Surface *s = (Surface *)p_geometry; - - if (s->index_array_len > 0) { - - if (s->index_array_local) { - - glDrawElements(gl_primitive[s->primitive], s->index_array_len, (s->index_array_len > (1 << 8)) ? GL_UNSIGNED_SHORT : GL_UNSIGNED_BYTE, s->index_array_local); - - } else { - - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, s->index_id); - glDrawElements(gl_primitive[s->primitive], s->index_array_len, (s->index_array_len > (1 << 8)) ? GL_UNSIGNED_SHORT : GL_UNSIGNED_BYTE, 0); - } - - } else { - - glDrawArrays(gl_primitive[s->primitive], 0, s->array_len); - }; - } break; - - default: break; - }; -}; - -void RasterizerIPhone::_render_list_forward(RenderList *p_render_list) { - - const Material *prev_material = NULL; - uint64_t prev_light_hash = 0; - const Skeleton *prev_skeleton = NULL; - const Geometry *prev_geometry = NULL; - const ParamOverrideMap *prev_overrides = NULL; // make it diferent than NULL - - Geometry::Type prev_geometry_type = Geometry::GEOMETRY_INVALID; - - glMatrixMode(GL_PROJECTION); - glLoadMatrixf(&camera_projection.matrix[0][0]); - - for (int i = 0; i < p_render_list->element_count; i++) { - - RenderList::Element *e = p_render_list->elements[i]; - const Material *material = e->material; - uint64_t light_hash = e->light_hash; - const Skeleton *skeleton = e->skeleton; - const Geometry *geometry = e->geometry; - const ParamOverrideMap *material_overrides = e->material_overrides; - - if (material != prev_material || geometry->type != prev_geometry_type) { - _setup_material(e->geometry, material); - //_setup_material_overrides(e->material,NULL,material_overrides); - //_setup_material_skeleton(material,skeleton); - } else { - - if (material_overrides != prev_overrides) { - - //_setup_material_overrides(e->material,prev_overrides,material_overrides); - } - - if (prev_skeleton != skeleton) { - //_setup_material_skeleton(material,skeleton); - }; - } - - if (geometry != prev_geometry || geometry->type != prev_geometry_type) { - - _setup_geometry(geometry, material); - }; - - if (i == 0 || light_hash != prev_light_hash) - _setup_lights(e->lights, e->light_count); - - glMatrixMode(GL_MODELVIEW); - _gl_load_transform(camera_transform_inverse); - _gl_mult_transform(e->transform); - - _render(geometry, material, skeleton); - - prev_material = material; - prev_skeleton = skeleton; - prev_geometry = geometry; - prev_light_hash = e->light_hash; - prev_geometry_type = geometry->type; - prev_overrides = material_overrides; - } -}; - -void RasterizerIPhone::end_scene() { - - glEnable(GL_BLEND); - glDepthMask(GL_FALSE); - - opaque_render_list.sort_mat_light(); - _render_list_forward(&opaque_render_list); - - glDisable(GL_BLEND); - glDepthMask(GL_TRUE); - - alpha_render_list.sort_z(); - _render_list_forward(&alpha_render_list); -} -void RasterizerIPhone::end_shadow_map() { -} - -void RasterizerIPhone::end_frame() { - - //ContextGL::get_singleton()->swap_buffers(); -} - -/* CANVAS API */ - -void RasterizerIPhone::canvas_begin() { - - glDisable(GL_CULL_FACE); - glDisable(GL_DEPTH_TEST); - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glLineWidth(1.0); - glDisable(GL_LIGHTING); - - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); -} -void RasterizerIPhone::canvas_set_transparency(float p_transparency) { -} - -void RasterizerIPhone::canvas_set_rect(const Rect2 &p_rect, bool p_clip) { - - glMatrixMode(GL_MODELVIEW); - glLoadIdentity(); - glScalef(2.0 / window_size.x, -2.0 / window_size.y, 0); - glTranslatef((-(window_size.x / 2.0)) + p_rect.pos.x, (-(window_size.y / 2.0)) + p_rect.pos.y, 0); - - if (p_clip) { - - glEnable(GL_SCISSOR_TEST); - glScissor(viewport.x + p_rect.pos.x, viewport.y + (viewport.height - (p_rect.pos.y + p_rect.size.height)), - p_rect.size.width, p_rect.size.height); - } else { - - glDisable(GL_SCISSOR_TEST); - } -} -void RasterizerIPhone::canvas_draw_line(const Point2 &p_from, const Point2 &p_to, const Color &p_color, float p_width) { - - glColor4f(1, 1, 1, 1); - - float verts[6] = { - p_from.x, p_from.y, 0, - p_to.x, p_to.y, 0 - }; - - float colors[] = { - p_color.r, p_color.g, p_color.b, p_color.a, - p_color.r, p_color.g, p_color.b, p_color.a, - }; - glLineWidth(p_width); - _draw_primitive(2, verts, 0, colors, 0); -} - -static void _draw_textured_quad(const Rect2 &p_rect, const Rect2 &p_src_region, const Size2 &p_tex_size) { - - float texcoords[] = { - p_src_region.pos.x / p_tex_size.width, - p_src_region.pos.y / p_tex_size.height, - - (p_src_region.pos.x + p_src_region.size.width) / p_tex_size.width, - p_src_region.pos.y / p_tex_size.height, - - (p_src_region.pos.x + p_src_region.size.width) / p_tex_size.width, - (p_src_region.pos.y + p_src_region.size.height) / p_tex_size.height, - - p_src_region.pos.x / p_tex_size.width, - (p_src_region.pos.y + p_src_region.size.height) / p_tex_size.height, - }; - - float coords[] = { - p_rect.pos.x, p_rect.pos.y, 0, - p_rect.pos.x + p_rect.size.width, p_rect.pos.y, 0, - p_rect.pos.x + p_rect.size.width, p_rect.pos.y + p_rect.size.height, 0, - p_rect.pos.x, p_rect.pos.y + p_rect.size.height, 0 - }; - - _draw_primitive(4, coords, 0, 0, texcoords); -} - -static void _draw_quad(const Rect2 &p_rect) { - - float coords[] = { - p_rect.pos.x, p_rect.pos.y, 0, - p_rect.pos.x + p_rect.size.width, p_rect.pos.y, 0, - p_rect.pos.x + p_rect.size.width, p_rect.pos.y + p_rect.size.height, 0, - p_rect.pos.x, p_rect.pos.y + p_rect.size.height, 0 - }; - - _draw_primitive(4, coords, 0, 0, 0); -} - -void RasterizerIPhone::canvas_draw_rect(const Rect2 &p_rect, bool p_region, const Rect2 &p_source, bool p_tile, RID p_texture, const Color &p_modulate) { - - glColor4f(p_modulate.r, p_modulate.g, p_modulate.b, p_modulate.a); - - if (p_texture.is_valid()) { - - glEnable(GL_TEXTURE_2D); - Texture *texture = texture_owner.get(p_texture); - ERR_FAIL_COND(!texture); - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, texture->tex_id); - - if (!p_region) { - - Rect2 region = Rect2(0, 0, texture->width, texture->height); - _draw_textured_quad(p_rect, region, region.size); - - } else { - - _draw_textured_quad(p_rect, p_source, Size2(texture->width, texture->height)); - } - } else { - - _draw_quad(p_rect); - } -} -void RasterizerIPhone::canvas_draw_style_box(const Rect2 &p_rect, const Rect2 &p_src_region, RID p_texture, const float *p_margin, bool p_draw_center) { - - glColor4f(1, 1, 1, 1); - - Texture *texture = texture_owner.get(p_texture); - ERR_FAIL_COND(!texture); - - glEnable(GL_TEXTURE_2D); - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, texture->tex_id); - - Rect2 region = p_src_region; - if (region.size.width <= 0) - region.size.width = texture->width; - if (region.size.height <= 0) - region.size.height = texture->height; - /* CORNERS */ - _draw_textured_quad( // top left - Rect2(p_rect.pos, Size2(p_margin[MARGIN_LEFT], p_margin[MARGIN_TOP])), - Rect2(region.pos, Size2(p_margin[MARGIN_LEFT], p_margin[MARGIN_TOP])), - Size2(texture->width, texture->height)); - - _draw_textured_quad( // top right - Rect2(Point2(p_rect.pos.x + p_rect.size.width - p_margin[MARGIN_RIGHT], p_rect.pos.y), Size2(p_margin[MARGIN_RIGHT], p_margin[MARGIN_TOP])), - Rect2(Point2(region.pos.x + region.size.width - p_margin[MARGIN_RIGHT], region.pos.y), Size2(p_margin[MARGIN_RIGHT], p_margin[MARGIN_TOP])), - Size2(texture->width, texture->height)); - - _draw_textured_quad( // bottom left - Rect2(Point2(p_rect.pos.x, p_rect.pos.y + p_rect.size.height - p_margin[MARGIN_BOTTOM]), Size2(p_margin[MARGIN_LEFT], p_margin[MARGIN_BOTTOM])), - Rect2(Point2(region.pos.x, region.pos.y + region.size.height - p_margin[MARGIN_BOTTOM]), Size2(p_margin[MARGIN_LEFT], p_margin[MARGIN_BOTTOM])), - Size2(texture->width, texture->height)); - - _draw_textured_quad( // bottom right - Rect2(Point2(p_rect.pos.x + p_rect.size.width - p_margin[MARGIN_RIGHT], p_rect.pos.y + p_rect.size.height - p_margin[MARGIN_BOTTOM]), Size2(p_margin[MARGIN_RIGHT], p_margin[MARGIN_BOTTOM])), - Rect2(Point2(region.pos.x + region.size.width - p_margin[MARGIN_RIGHT], region.pos.y + region.size.height - p_margin[MARGIN_BOTTOM]), Size2(p_margin[MARGIN_RIGHT], p_margin[MARGIN_BOTTOM])), - Size2(texture->width, texture->height)); - - Rect2 rect_center(p_rect.pos + Point2(p_margin[MARGIN_LEFT], p_margin[MARGIN_TOP]), Size2(p_rect.size.width - p_margin[MARGIN_LEFT] - p_margin[MARGIN_RIGHT], p_rect.size.height - p_margin[MARGIN_TOP] - p_margin[MARGIN_BOTTOM])); - - Rect2 src_center(Point2(region.pos.x + p_margin[MARGIN_LEFT], region.pos.y + p_margin[MARGIN_TOP]), Size2(region.size.width - p_margin[MARGIN_LEFT] - p_margin[MARGIN_RIGHT], region.size.height - p_margin[MARGIN_TOP] - p_margin[MARGIN_BOTTOM])); - - _draw_textured_quad( // top - Rect2(Point2(rect_center.pos.x, p_rect.pos.y), Size2(rect_center.size.width, p_margin[MARGIN_TOP])), - Rect2(Point2(src_center.pos.x, region.pos.y), Size2(src_center.size.width, p_margin[MARGIN_TOP])), - Size2(texture->width, texture->height)); - - _draw_textured_quad( // bottom - Rect2(Point2(rect_center.pos.x, rect_center.pos.y + rect_center.size.height), Size2(rect_center.size.width, p_margin[MARGIN_BOTTOM])), - Rect2(Point2(src_center.pos.x, src_center.pos.y + src_center.size.height), Size2(src_center.size.width, p_margin[MARGIN_BOTTOM])), - Size2(texture->width, texture->height)); - - _draw_textured_quad( // left - Rect2(Point2(p_rect.pos.x, rect_center.pos.y), Size2(p_margin[MARGIN_LEFT], rect_center.size.height)), - Rect2(Point2(region.pos.x, region.pos.y + p_margin[MARGIN_TOP]), Size2(p_margin[MARGIN_LEFT], src_center.size.height)), - Size2(texture->width, texture->height)); - - _draw_textured_quad( // right - Rect2(Point2(rect_center.pos.x + rect_center.size.width, rect_center.pos.y), Size2(p_margin[MARGIN_RIGHT], rect_center.size.height)), - Rect2(Point2(src_center.pos.x + src_center.size.width, region.pos.y + p_margin[MARGIN_TOP]), Size2(p_margin[MARGIN_RIGHT], src_center.size.height)), - Size2(texture->width, texture->height)); - - if (p_draw_center) { - - _draw_textured_quad( - rect_center, - src_center, - Size2(texture->width, texture->height)); - } -} -void RasterizerIPhone::canvas_draw_primitive(const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, RID p_texture) { - - ERR_FAIL_COND(p_points.size() < 1); - float verts[12]; - float uvs[8]; - float colors[16]; - - glColor4f(1, 1, 1, 1); - - int idx = 0; - for (int i = 0; i < p_points.size(); i++) { - - verts[idx++] = p_points[i].x; - verts[idx++] = p_points[i].y; - verts[idx++] = 0; - } - - idx = 0; - for (int i = 0; i < p_uvs.size(); i++) { - - uvs[idx++] = p_uvs[i].x; - uvs[idx++] = p_uvs[i].y; - } - - idx = 0; - for (int i = 0; i < p_colors.size(); i++) { - - colors[idx++] = p_colors[i].r; - colors[idx++] = p_colors[i].g; - colors[idx++] = p_colors[i].b; - colors[idx++] = p_colors[i].a; - }; - - if (p_texture.is_valid()) { - glEnable(GL_TEXTURE_2D); - Texture *texture = texture_owner.get(p_texture); - if (texture) { - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, texture->tex_id); - } - } - - _draw_primitive(p_points.size(), &verts[0], NULL, p_colors.size() ? &colors[0] : NULL, p_uvs.size() ? uvs : NULL); -} - -/* FX */ - -RID RasterizerIPhone::fx_create() { - - return RID(); -} -void RasterizerIPhone::fx_get_effects(RID p_fx, List<String> *p_effects) const { -} -void RasterizerIPhone::fx_set_active(RID p_fx, const String &p_effect, bool p_active) { -} -bool RasterizerIPhone::fx_is_active(RID p_fx, const String &p_effect) const { - - return false; -} -void RasterizerIPhone::fx_get_effect_params(RID p_fx, const String &p_effect, List<PropertyInfo> *p_params) const { -} -Variant RasterizerIPhone::fx_get_effect_param(RID p_fx, const String &p_effect, const String &p_param) const { - - return Variant(); -} -void RasterizerIPhone::fx_set_effect_param(RID p_fx, const String &p_effect, const String &p_param, const Variant &p_pvalue) { -} - -/*MISC*/ - -bool RasterizerIPhone::is_texture(const RID &p_rid) const { - - return texture_owner.owns(p_rid); -} -bool RasterizerIPhone::is_material(const RID &p_rid) const { - - return material_owner.owns(p_rid); -} -bool RasterizerIPhone::is_mesh(const RID &p_rid) const { - - return mesh_owner.owns(p_rid); -} -bool RasterizerIPhone::is_multimesh(const RID &p_rid) const { - - return false; -} -bool RasterizerIPhone::is_poly(const RID &p_rid) const { - - return poly_owner.owns(p_rid); -} -bool RasterizerIPhone::is_particles(const RID &p_beam) const { - - return false; -} - -bool RasterizerIPhone::is_beam(const RID &p_beam) const { - - return false; -} - -bool RasterizerIPhone::is_light(const RID &p_rid) const { - - return light_owner.owns(p_rid); -} -bool RasterizerIPhone::is_light_instance(const RID &p_rid) const { - - return light_instance_owner.owns(p_rid); -} -bool RasterizerIPhone::is_particles_instance(const RID &p_rid) const { - - return false; -} -bool RasterizerIPhone::is_skeleton(const RID &p_rid) const { - - return skeleton_owner.owns(p_rid); -} -bool RasterizerIPhone::is_fx(const RID &p_rid) const { - - return fx_owner.owns(p_rid); -} -bool RasterizerIPhone::is_shader(const RID &p_rid) const { - - return false; -} - -void RasterizerIPhone::free(const RID &p_rid) const { - - if (texture_owner.owns(p_rid)) { - - // delete the texture - Texture *texture = texture_owner.get(p_rid); - - glDeleteTextures(1, &texture->tex_id); - - texture_owner.free(p_rid); - memdelete(texture); - - } else if (material_owner.owns(p_rid)) { - - Material *material = material_owner.get(p_rid); - ERR_FAIL_COND(!material); - - material_owner.free(p_rid); - memdelete(material); - - } else if (mesh_owner.owns(p_rid)) { - - Mesh *mesh = mesh_owner.get(p_rid); - ERR_FAIL_COND(!mesh); - for (int i = 0; i < mesh->surfaces.size(); i++) { - - Surface *surface = mesh->surfaces[i]; - if (surface->array_local != 0) { - memfree(surface->array_local); - }; - if (surface->index_array_local != 0) { - memfree(surface->index_array_local); - }; - - if (surface->vertex_id) - glDeleteBuffers(1, &surface->vertex_id); - if (surface->index_id) - glDeleteBuffers(1, &surface->index_id); - - memdelete(surface); - }; - - mesh->surfaces.clear(); - - mesh_owner.free(p_rid); - memdelete(mesh); - - } else if (skeleton_owner.owns(p_rid)) { - - Skeleton *skeleton = skeleton_owner.get(p_rid); - ERR_FAIL_COND(!skeleton) - - skeleton_owner.free(p_rid); - memdelete(skeleton); - - } else if (light_owner.owns(p_rid)) { - - Light *light = light_owner.get(p_rid); - ERR_FAIL_COND(!light) - - light_owner.free(p_rid); - memdelete(light); - - } else if (light_instance_owner.owns(p_rid)) { - - LightInstance *light_instance = light_instance_owner.get(p_rid); - ERR_FAIL_COND(!light_instance); - - light_instance_owner.free(p_rid); - memdelete(light_instance); - - } else if (fx_owner.owns(p_rid)) { - - FX *fx = fx_owner.get(p_rid); - ERR_FAIL_COND(!fx); - - fx_owner.free(p_rid); - memdelete(fx); - }; -} - -void RasterizerIPhone::init() { - - glEnable(GL_DEPTH_TEST); - glDepthFunc(GL_LEQUAL); - glFrontFace(GL_CW); - - glEnable(GL_TEXTURE_2D); -} - -void RasterizerIPhone::finish() { -} - -int RasterizerIPhone::get_render_info(VS::RenderInfo p_info) { - - return false; -} - -RasterizerIPhone::RasterizerIPhone() { - - frame = 0; -}; - -RasterizerIPhone::~RasterizerIPhone(){ - -}; - -#endif diff --git a/platform/iphone/rasterizer_iphone.h b/platform/iphone/rasterizer_iphone.h deleted file mode 100644 index 02cb985dc8..0000000000 --- a/platform/iphone/rasterizer_iphone.h +++ /dev/null @@ -1,880 +0,0 @@ -/*************************************************************************/ -/* rasterizer_iphone.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* http://www.godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ -#ifdef IPHONE_ENABLED - -#ifndef RASTERIZER_IPHONE_H -#define RASTERIZER_IPHONE_H - -#include "servers/visual/rasterizer.h" - -#include "camera_matrix.h" -#include "image.h" -#include "list.h" -#include "map.h" -#include "rid.h" -#include "servers/visual_server.h" -#include "sort.h" -#include <ES1/gl.h> - -/** - @author Juan Linietsky <reduzio@gmail.com> -*/ -class RasterizerIPhone : public Rasterizer { - - enum { - SKINNED_BUFFER_SIZE = 1024 * 128, // 10k vertices - MAX_LIGHTS = 8, - }; - - uint8_t skinned_buffer[SKINNED_BUFFER_SIZE]; - - struct Texture { - - uint32_t flags; - int width, height; - Image::Format format; - - GLenum target; - GLenum gl_format_cache; - int gl_components_cache; - bool has_alpha; - bool format_has_alpha; - - bool active; - GLuint tex_id; - bool mipmap_dirty; - - Texture() { - - flags = width = height = 0; - tex_id = 0; - format = Image::FORMAT_L8; - gl_components_cache = 0; - format_has_alpha = false; - has_alpha = false; - active = false; - mipmap_dirty = true; - } - - ~Texture() { - - if (tex_id != 0) { - - glDeleteTextures(1, &tex_id); - } - } - }; - - mutable RID_Owner<Texture> texture_owner; - - struct Material { - - bool flags[VS::MATERIAL_FLAG_MAX]; - Variant parameters[VisualServer::FIXED_MATERIAL_PARAM_MAX]; - RID textures[VisualServer::FIXED_MATERIAL_PARAM_MAX]; - - Transform uv_transform; - VS::FixedSpatialMaterialTexCoordMode texcoord_mode[VisualServer::FIXED_MATERIAL_PARAM_MAX]; - - VS::MaterialBlendMode detail_blend_mode; - - VS::FixedSpatialMaterialTexGenMode texgen_mode; - - Material() { - - flags[VS::MATERIAL_FLAG_VISIBLE] = true; - flags[VS::MATERIAL_FLAG_DOUBLE_SIDED] = false; - flags[VS::MATERIAL_FLAG_INVERT_FACES] = false; - flags[VS::MATERIAL_FLAG_UNSHADED] = false; - flags[VS::MATERIAL_FLAG_WIREFRAME] = false; - - parameters[VS::FIXED_MATERIAL_PARAM_DIFFUSE] = Color(0.8, 0.8, 0.8); - parameters[VS::FIXED_MATERIAL_PARAM_SPECULAR_EXP] = 12; - - for (int i = 0; i < VisualServer::FIXED_MATERIAL_PARAM_MAX; i++) { - texcoord_mode[i] = VS::FIXED_MATERIAL_TEXCOORD_UV; - }; - detail_blend_mode = VS::MATERIAL_BLEND_MODE_MIX; - texgen_mode = VS::FIXED_MATERIAL_TEXGEN_SPHERE; - } - }; - mutable RID_Owner<Material> material_owner; - - struct Geometry { - - enum Type { - GEOMETRY_INVALID, - GEOMETRY_SURFACE, - GEOMETRY_POLY, - GEOMETRY_PARTICLES, - GEOMETRY_BEAM, - GEOMETRY_DETAILER, - }; - - Type type; - RID material; - bool has_alpha; - bool material_owned; - - Vector3 scale; - Vector3 uv_scale; - - Geometry() - : scale(1, 1, 1) { - has_alpha = false; - material_owned = false; - } - virtual ~Geometry(){}; - }; - - struct GeometryOwner { - - virtual ~GeometryOwner() {} - }; - - struct Surface : public Geometry { - - struct ArrayData { - - uint32_t ofs, size; - bool configured; - int components; - ArrayData() { - ofs = 0; - size = 0; - configured = false; - } - }; - - ArrayData array[VS::ARRAY_MAX]; - // support for vertex array objects - GLuint array_object_id; - // support for vertex buffer object - GLuint vertex_id; // 0 means, unconfigured - GLuint index_id; // 0 means, unconfigured - // no support for the above, array in localmem. - uint8_t *array_local; - uint8_t *index_array_local; - - AABB aabb; - - int array_len; - int index_array_len; - - VS::PrimitiveType primitive; - - uint32_t format; - - int stride; - - bool active; - - Point2 uv_min; - Point2 uv_max; - - bool has_alpha_cache; - - Surface() { - - array_len = 0; - type = GEOMETRY_SURFACE; - primitive = VS::PRIMITIVE_POINTS; - index_array_len = VS::NO_INDEX_ARRAY; - format = 0; - stride = 0; - - array_local = index_array_local = 0; - vertex_id = index_id = 0; - - active = false; - } - - ~Surface() { - } - }; - - struct Mesh { - - bool active; - Vector<Surface *> surfaces; - - mutable uint64_t last_pass; - Mesh() { - last_pass = 0; - active = false; - } - }; - mutable RID_Owner<Mesh> mesh_owner; - - struct Poly : public Geometry { - - struct Primitive { - - Vector<Vector3> vertices; - Vector<Vector3> normals; - Vector<Vector3> uvs; - Vector<Color> colors; - }; - - AABB aabb; - List<Primitive> primitives; - Poly() { - - type = GEOMETRY_POLY; - } - }; - - mutable RID_Owner<Poly> poly_owner; - - struct Skeleton { - - Vector<Transform> bones; - }; - - mutable RID_Owner<Skeleton> skeleton_owner; - - struct Light { - - VS::LightType type; - float vars[VS::LIGHT_PARAM_MAX]; - Color colors[3]; - bool shadow_enabled; - RID projector; - bool volumetric_enabled; - Color volumetric_color; - - Light() { - - vars[VS::LIGHT_PARAM_SPOT_ATTENUATION] = 1; - vars[VS::LIGHT_PARAM_SPOT_ANGLE] = 45; - vars[VS::LIGHT_PARAM_ATTENUATION] = 1.0; - vars[VS::LIGHT_PARAM_ENERGY] = 1.0; - vars[VS::LIGHT_PARAM_RADIUS] = 1.0; - colors[VS::LIGHT_COLOR_AMBIENT] = Color(0, 0, 0); - colors[VS::LIGHT_COLOR_DIFFUSE] = Color(1, 1, 1); - colors[VS::LIGHT_COLOR_SPECULAR] = Color(1, 1, 1); - shadow_enabled = false; - volumetric_enabled = false; - } - }; - - struct ShadowBuffer; - - struct LightInstance { - - struct SplitInfo { - - CameraMatrix camera; - Transform transform; - float near; - float far; - }; - - RID light; - Light *base; - uint64_t last_pass; - Transform transform; - - CameraMatrix projection; - Vector<SplitInfo> splits; - - Vector3 light_vector; - Vector3 spot_vector; - float linear_att; - - uint64_t hash_aux; - }; - mutable RID_Owner<Light> light_owner; - mutable RID_Owner<LightInstance> light_instance_owner; - - LightInstance *light_instances[MAX_LIGHTS]; - int light_instance_count; - - struct RenderList { - - enum { - MAX_ELEMENTS = 4096, - MAX_LIGHTS = 4 - }; - - struct Element { - - float depth; - const Skeleton *skeleton; - Transform transform; - LightInstance *lights[MAX_LIGHTS]; - int light_count; - const Geometry *geometry; - const Material *material; - uint64_t light_hash; - GeometryOwner *owner; - const ParamOverrideMap *material_overrides; - }; - - Element _elements[MAX_ELEMENTS]; - Element *elements[MAX_ELEMENTS]; - int element_count; - - void clear() { - - element_count = 0; - } - - struct SortZ { - - _FORCE_INLINE_ bool operator()(const Element *A, const Element *B) const { - - return A->depth > B->depth; - } - }; - - void sort_z() { - - SortArray<Element *, SortZ> sorter; - sorter.sort(elements, element_count); - } - - struct SortSkel { - - _FORCE_INLINE_ bool operator()(const Element *A, const Element *B) const { - - if (A->geometry < B->geometry) - return true; - else if (A->geometry > B->geometry) - return false; - else - return (!A->skeleton && B->skeleton); - } - }; - - void sort_skel() { - - SortArray<Element *, SortSkel> sorter; - sorter.sort(elements, element_count); - } - - struct SortMat { - - _FORCE_INLINE_ bool operator()(const Element *A, const Element *B) const { - - if (A->geometry == B->geometry) { - - if (A->material == B->material) { - - return (A->material_overrides < B->material_overrides); - } else { - - return (A->material < B->material); - } - } else { - - return (A->geometry < B->geometry); - } - } - }; - - void sort_mat() { - - SortArray<Element *, SortMat> sorter; - sorter.sort(elements, element_count); - } - - struct SortMatLight { - - _FORCE_INLINE_ bool operator()(const Element *A, const Element *B) const { - - if (A->geometry == B->geometry) { - - if (A->material == B->material) { - - if (A->light_hash == B->light_hash) - return (A->material_overrides < B->material_overrides); - else - return A->light_hash < B->light_hash; - } else { - - return (A->material < B->material); - } - } else { - - return (A->geometry < B->geometry); - } - } - }; - - void sort_mat_light() { - - SortArray<Element *, SortMatLight> sorter; - sorter.sort(elements, element_count); - } - - struct LISort { - - _FORCE_INLINE_ bool operator()(const LightInstance *A, const LightInstance *B) const { - - return (A->hash_aux < B->hash_aux); - } - }; - - _FORCE_INLINE_ void add_element(const Geometry *p_geometry, const Material *p_material, const Transform &p_transform, LightInstance **p_light_instances, int p_light_count, const ParamOverrideMap *p_material_overrides, const Skeleton *p_skeleton, float p_depth, GeometryOwner *p_owner = NULL) { - - ERR_FAIL_COND(element_count >= MAX_ELEMENTS); - Element *e = elements[element_count++]; - - e->geometry = p_geometry; - e->material = p_material; - e->transform = p_transform; - e->skeleton = p_skeleton; - e->light_hash = 0; - e->light_count = p_light_count; - e->owner = p_owner; - e->material_overrides = p_material_overrides; - - if (e->light_count > 0) { - - SortArray<LightInstance *, LISort> light_sort; - light_sort.sort(p_light_instances, p_light_count); - //@TODO OPTIOMIZE - - for (int i = 0; i < p_light_count; i++) { - - e->lights[i] = p_light_instances[i]; - - if (i == 0) - e->light_hash = hash_djb2_one_64(make_uint64_t(e->lights[i])); - else - e->light_hash = hash_djb2_one_64(make_uint64_t(e->lights[i]), e->light_hash); - } - } - } - - RenderList() { - - for (int i = 0; i < MAX_ELEMENTS; i++) - elements[i] = &_elements[i]; // assign elements - } - }; - - RenderList opaque_render_list; - RenderList alpha_render_list; - - RID default_material; - - struct FX { - - bool bgcolor_active; - Color bgcolor; - - bool skybox_active; - RID skybox_cubemap; - - bool antialias_active; - float antialias_tolerance; - - bool glow_active; - int glow_passes; - float glow_attenuation; - float glow_bloom; - - bool ssao_active; - float ssao_attenuation; - float ssao_radius; - float ssao_max_distance; - float ssao_range_max; - float ssao_range_min; - bool ssao_only; - - bool fog_active; - float fog_distance; - float fog_attenuation; - Color fog_color_near; - Color fog_color_far; - bool fog_bg; - - bool toon_active; - float toon_treshold; - float toon_soft; - - bool edge_active; - Color edge_color; - float edge_size; - - FX(); - }; - mutable RID_Owner<FX> fx_owner; - - FX *scene_fx; - CameraMatrix camera_projection; - Transform camera_transform; - Transform camera_transform_inverse; - float camera_z_near; - float camera_z_far; - Size2 camera_vp_size; - - Plane camera_plane; - - void _add_geometry(const Geometry *p_geometry, const Transform &p_world, uint32_t p_vertex_format, const RID *p_light_instances, int p_light_count, const ParamOverrideMap *p_material_overrides, const Skeleton *p_skeleton, GeometryOwner *p_owner); - void _render_list_forward(RenderList *p_render_list); - - void _setup_light(LightInstance *p_instance, int p_idx); - void _setup_lights(LightInstance **p_lights, int p_light_count); - void _setup_material(const Geometry *p_geometry, const Material *p_material); - - void _setup_geometry(const Geometry *p_geometry, const Material *p_material); - void _render(const Geometry *p_geometry, const Material *p_material, const Skeleton *p_skeleton); - - /*********/ - /* FRAME */ - /*********/ - - Size2 window_size; - VS::ViewportRect viewport; - Transform canvas_transform; - double last_time; - double time_delta; - uint64_t frame; - -public: - /* TEXTURE API */ - - virtual RID texture_create(); - virtual void texture_allocate(RID p_texture, int p_width, int p_height, Image::Format p_format, uint32_t p_flags = VS::TEXTURE_FLAGS_DEFAULT); - virtual void texture_blit_rect(RID p_texture, int p_x, int p_y, const Image &p_image, VS::CubeMapSide p_cube_side = VS::CUBEMAP_LEFT); - virtual Image texture_get_rect(RID p_texture, int p_x, int p_y, int p_width, int p_height, VS::CubeMapSide p_cube_side = VS::CUBEMAP_LEFT) const; - virtual void texture_set_flags(RID p_texture, uint32_t p_flags); - virtual uint32_t texture_get_flags(RID p_texture) const; - virtual Image::Format texture_get_format(RID p_texture) const; - virtual uint32_t texture_get_width(RID p_texture) const; - virtual uint32_t texture_get_height(RID p_texture) const; - virtual bool texture_has_alpha(RID p_texture) const; - - /* SHADER API */ - - virtual RID shader_create(); - - virtual void shader_node_add(RID p_shader, VS::ShaderNodeType p_type, int p_id); - virtual void shader_node_remove(RID p_shader, int p_id); - virtual void shader_node_change_type(RID p_shader, int p_id, VS::ShaderNodeType p_type); - virtual void shader_node_set_param(RID p_shader, int p_id, const Variant &p_value); - - virtual void shader_get_node_list(RID p_shader, List<int> *p_node_list) const; - virtual VS::ShaderNodeType shader_node_get_type(RID p_shader, int p_id) const; - virtual Variant shader_node_get_param(RID p_shader, int p_id) const; - - virtual void shader_connect(RID p_shader, int p_src_id, int p_src_slot, int p_dst_id, int p_dst_slot); - virtual bool shader_is_connected(RID p_shader, int p_src_id, int p_src_slot, int p_dst_id, int p_dst_slot) const; - virtual void shader_disconnect(RID p_shader, int p_src_id, int p_src_slot, int p_dst_id, int p_dst_slot); - - virtual void shader_get_connections(RID p_shader, List<VS::ShaderConnection> *p_connections) const; - - virtual void shader_clear(RID p_shader); - - /* COMMON MATERIAL API */ - - virtual void material_set_param(RID p_material, const StringName &p_param, const Variant &p_value); - virtual Variant material_get_param(RID p_material, const StringName &p_param) const; - virtual void material_get_param_list(RID p_material, List<String> *p_param_list) const; - - virtual void material_set_flag(RID p_material, VS::MaterialFlag p_flag, bool p_enabled); - virtual bool material_get_flag(RID p_material, VS::MaterialFlag p_flag) const; - - virtual void material_set_blend_mode(RID p_material, VS::MaterialBlendMode p_mode); - virtual VS::MaterialBlendMode material_get_blend_mode(RID p_material) const; - - virtual void material_set_line_width(RID p_material, float p_line_width); - virtual float material_get_line_width(RID p_material) const; - - /* FIXED MATERIAL */ - - virtual RID material_create(); - - virtual void fixed_material_set_parameter(RID p_material, VS::FixedSpatialMaterialParam p_parameter, const Variant &p_value); - virtual Variant fixed_material_get_parameter(RID p_material, VS::FixedSpatialMaterialParam p_parameter) const; - - virtual void fixed_material_set_texture(RID p_material, VS::FixedSpatialMaterialParam p_parameter, RID p_texture); - virtual RID fixed_material_get_texture(RID p_material, VS::FixedSpatialMaterialParam p_parameter) const; - - virtual void fixed_material_set_detail_blend_mode(RID p_material, VS::MaterialBlendMode p_mode); - virtual VS::MaterialBlendMode fixed_material_get_detail_blend_mode(RID p_material) const; - - virtual void fixed_material_set_texgen_mode(RID p_material, VS::FixedSpatialMaterialTexGenMode p_mode); - virtual VS::FixedSpatialMaterialTexGenMode fixed_material_get_texgen_mode(RID p_material) const; - - virtual void fixed_material_set_texcoord_mode(RID p_material, VS::FixedSpatialMaterialParam p_parameter, VS::FixedSpatialMaterialTexCoordMode p_mode); - virtual VS::FixedSpatialMaterialTexCoordMode fixed_material_get_texcoord_mode(RID p_material, VS::FixedSpatialMaterialParam p_parameter) const; - - virtual void fixed_material_set_uv_transform(RID p_material, const Transform &p_transform); - virtual Transform fixed_material_get_uv_transform(RID p_material) const; - - /* SHADER MATERIAL */ - - virtual RID shader_material_create() const; - - virtual void shader_material_set_vertex_shader(RID p_material, RID p_shader, bool p_owned = false); - virtual RID shader_material_get_vertex_shader(RID p_material) const; - - virtual void shader_material_set_fragment_shader(RID p_material, RID p_shader, bool p_owned = false); - virtual RID shader_material_get_fragment_shader(RID p_material) const; - - /* MESH API */ - - virtual RID mesh_create(); - - virtual void mesh_add_surface(RID p_mesh, VS::PrimitiveType p_primitive, uint32_t p_format, int p_array_len, int p_index_array_len = VS::NO_INDEX_ARRAY); - - virtual Error mesh_surface_set_array(RID p_mesh, int p_surface, VS::ArrayType p_type, const Variant &p_array); - virtual Variant mesh_surface_get_array(RID p_mesh, int p_surface, VS::ArrayType p_type) const; - - virtual void mesh_surface_set_material(RID p_mesh, int p_surface, RID p_material, bool p_owned = false); - virtual RID mesh_surface_get_material(RID p_mesh, int p_surface) const; - - virtual int mesh_surface_get_array_len(RID p_mesh, int p_surface) const; - virtual int mesh_surface_get_array_index_len(RID p_mesh, int p_surface) const; - virtual uint32_t mesh_surface_get_format(RID p_mesh, int p_surface) const; - virtual VS::PrimitiveType mesh_surface_get_primitive_type(RID p_mesh, int p_surface) const; - - virtual void mesh_erase_surface(RID p_mesh, int p_index); - virtual int mesh_get_surface_count(RID p_mesh) const; - - virtual AABB mesh_get_aabb(RID p_mesh) const; - - /* MULTIMESH API */ - - virtual RID multimesh_create(); - - virtual void multimesh_set_instance_count(RID p_multimesh, int p_count); - virtual int multimesh_get_instance_count(RID p_multimesh) const; - - virtual void multimesh_set_mesh(RID p_multimesh, RID p_mesh); - virtual void multimesh_set_aabb(RID p_multimesh, const AABB &p_aabb); - virtual void multimesh_instance_set_transform(RID p_multimesh, int p_index, const Transform &p_transform); - virtual void multimesh_instance_set_color(RID p_multimesh, int p_index, const Color &p_color); - - virtual RID multimesh_get_mesh(RID p_multimesh) const; - virtual AABB multimesh_get_aabb(RID p_multimesh) const; - - virtual Transform multimesh_instance_get_transform(RID p_multimesh, int p_index) const; - virtual Color multimesh_instance_get_color(RID p_multimesh, int p_index) const; - - /* POLY API */ - - virtual RID poly_create(); - virtual void poly_set_material(RID p_poly, RID p_material, bool p_owned = false); - virtual void poly_add_primitive(RID p_poly, const Vector<Vector3> &p_points, const Vector<Vector3> &p_normals, const Vector<Color> &p_colors, const Vector<Vector3> &p_uvs); - virtual void poly_clear(RID p_poly); - - virtual AABB poly_get_aabb(RID p_poly) const; - - /* PARTICLES API */ - - virtual RID particles_create(); - - virtual void particles_set_amount(RID p_particles, int p_amount); - virtual int particles_get_amount(RID p_particles) const; - - virtual void particles_set_emitting(RID p_particles, bool p_emitting); - virtual bool particles_is_emitting(RID p_particles) const; - - virtual void particles_set_visibility_aabb(RID p_particles, const AABB &p_visibility); - virtual AABB particles_get_visibility_aabb(RID p_particles) const; - - virtual void particles_set_emission_half_extents(RID p_particles, const Vector3 &p_half_extents); - virtual Vector3 particles_get_emission_half_extents(RID p_particles) const; - - virtual void particles_set_gravity_normal(RID p_particles, const Vector3 &p_normal); - virtual Vector3 particles_get_gravity_normal(RID p_particles) const; - - virtual void particles_set_variable(RID p_particles, VS::ParticleVariable p_variable, float p_value); - virtual float particles_get_variable(RID p_particles, VS::ParticleVariable p_variable) const; - - virtual void particles_set_randomness(RID p_particles, VS::ParticleVariable p_variable, float p_randomness); - virtual float particles_get_randomness(RID p_particles, VS::ParticleVariable p_variable) const; - - virtual void particles_set_color_phase_pos(RID p_particles, int p_phase, float p_pos); - virtual float particles_get_color_phase_pos(RID p_particles, int p_phase) const; - - virtual void particles_set_color_phases(RID p_particles, int p_phases); - virtual int particles_get_color_phases(RID p_particles) const; - - virtual void particles_set_color_phase_color(RID p_particles, int p_phase, const Color &p_color); - virtual Color particles_get_color_phase_color(RID p_particles, int p_phase) const; - - virtual void particles_set_attractors(RID p_particles, int p_attractors); - virtual int particles_get_attractors(RID p_particles) const; - - virtual void particles_set_attractor_pos(RID p_particles, int p_attractor, const Vector3 &p_pos); - virtual Vector3 particles_get_attractor_pos(RID p_particles, int p_attractor) const; - - virtual void particles_set_attractor_strength(RID p_particles, int p_attractor, float p_force); - virtual float particles_get_attractor_strength(RID p_particles, int p_attractor) const; - - virtual void particles_set_material(RID p_particles, RID p_material, bool p_owned = false); - virtual RID particles_get_material(RID p_particles) const; - - virtual AABB particles_get_aabb(RID p_particles) const; - /* BEAM API */ - - virtual RID beam_create(); - - virtual void beam_set_point_count(RID p_beam, int p_count); - virtual int beam_get_point_count(RID p_beam) const; - virtual void beam_clear(RID p_beam); - - virtual void beam_set_point(RID p_beam, int p_point, Vector3 &p_pos); - virtual Vector3 beam_get_point(RID p_beam, int p_point) const; - - virtual void beam_set_primitive(RID p_beam, VS::BeamPrimitive p_primitive); - virtual VS::BeamPrimitive beam_get_primitive(RID p_beam) const; - - virtual void beam_set_material(RID p_beam, RID p_material); - virtual RID beam_get_material(RID p_beam) const; - - virtual AABB beam_get_aabb(RID p_particles) const; - /* SKELETON API */ - - virtual RID skeleton_create(); - virtual void skeleton_resize(RID p_skeleton, int p_bones); - virtual int skeleton_get_bone_count(RID p_skeleton) const; - virtual void skeleton_bone_set_transform(RID p_skeleton, int p_bone, const Transform &p_transform); - virtual Transform skeleton_bone_get_transform(RID p_skeleton, int p_bone); - - /* LIGHT API */ - - virtual RID light_create(VS::LightType p_type); - virtual VS::LightType light_get_type(RID p_light) const; - - virtual void light_set_color(RID p_light, VS::LightColor p_type, const Color &p_color); - virtual Color light_get_color(RID p_light, VS::LightColor p_type) const; - - virtual void light_set_shadow(RID p_light, bool p_enabled); - virtual bool light_has_shadow(RID p_light) const; - - virtual void light_set_volumetric(RID p_light, bool p_enabled); - virtual bool light_is_volumetric(RID p_light) const; - - virtual void light_set_projector(RID p_light, RID p_texture); - virtual RID light_get_projector(RID p_light) const; - - virtual void light_set_var(RID p_light, VS::LightParam p_var, float p_value); - virtual float light_get_var(RID p_light, VS::LightParam p_var) const; - - virtual AABB light_get_aabb(RID p_poly) const; - - virtual RID light_instance_create(RID p_light); - virtual void light_instance_set_transform(RID p_light_instance, const Transform &p_transform); - - virtual void light_instance_set_active_hint(RID p_light_instance); - virtual bool light_instance_has_shadow(RID p_light_instance) const; - virtual bool light_instance_assign_shadow(RID p_light_instance); - virtual ShadowType light_instance_get_shadow_type(RID p_light_instance) const; - virtual int light_instance_get_shadow_passes(RID p_light_instance) const; - virtual void light_instance_set_pssm_split_info(RID p_light_instance, int p_split, float p_near, float p_far, const CameraMatrix &p_camera, const Transform &p_transform); - - /* PARTICLES INSTANCE */ - - virtual RID particles_instance_create(RID p_particles); - virtual void particles_instance_set_transform(RID p_particles_instance, const Transform &p_transform); - - /* RENDER API */ - /* all calls (inside begin/end shadow) are always warranted to be in the following order: */ - - virtual void begin_frame(); - - virtual void set_viewport(const VS::ViewportRect &p_viewport); - - virtual void begin_scene(RID p_fx = RID(), VS::ScenarioDebugMode p_debug = VS::SCENARIO_DEBUG_DISABLED); - virtual void begin_shadow_map(RID p_light_instance, int p_shadow_pass); - - virtual void set_camera(const Transform &p_world, const CameraMatrix &p_projection); - - virtual void add_light(RID p_light_instance); ///< all "add_light" calls happen before add_geometry calls - - typedef Map<StringName, Variant> ParamOverrideMap; - - virtual void add_mesh(RID p_mesh, const Transform *p_world, const RID *p_light_instances, int p_light_count, const ParamOverrideMap *p_material_overrides = NULL, RID p_skeleton = RID()); - virtual void add_multimesh(RID p_multimesh, const Transform *p_world, const RID *p_light_instances, int p_light_count, const ParamOverrideMap *p_material_overrides = NULL); - virtual void add_poly(RID p_poly, const Transform *p_world, const RID *p_light_instances, int p_light_count, const ParamOverrideMap *p_material_overrides = NULL); - virtual void add_beam(RID p_beam, const Transform *p_world, const RID *p_light_instances, int p_light_count, const ParamOverrideMap *p_material_overrides = NULL); - virtual void add_particles(RID p_particle_instance, const RID *p_light_instances, int p_light_count, const ParamOverrideMap *p_material_overrides = NULL); - - virtual void end_scene(); - virtual void end_shadow_map(); - - virtual void end_frame(); - - /* CANVAS API */ - - virtual void canvas_begin(); - virtual void canvas_set_transparency(float p_transparency); - virtual void canvas_set_rect(const Rect2 &p_rect, bool p_clip); - virtual void canvas_draw_line(const Point2 &p_from, const Point2 &p_to, const Color &p_color, float p_width); - virtual void canvas_draw_rect(const Rect2 &p_rect, bool p_region, const Rect2 &p_source, bool p_tile, RID p_texture, const Color &p_modulate); - virtual void canvas_draw_style_box(const Rect2 &p_rect, RID p_texture, const float *p_margins, bool p_draw_center = true); - virtual void canvas_draw_primitive(const Vector<Point2> &p_points, const Vector<Color> &p_colors, const Vector<Point2> &p_uvs, RID p_texture); - - /* FX */ - - virtual RID fx_create(); - virtual void fx_get_effects(RID p_fx, List<String> *p_effects) const; - virtual void fx_set_active(RID p_fx, const String &p_effect, bool p_active); - virtual bool fx_is_active(RID p_fx, const String &p_effect) const; - virtual void fx_get_effect_params(RID p_fx, const String &p_effect, List<PropertyInfo> *p_params) const; - virtual Variant fx_get_effect_param(RID p_fx, const String &p_effect, const String &p_param) const; - virtual void fx_set_effect_param(RID p_fx, const String &p_effect, const String &p_param, const Variant &p_pvalue); - - /*MISC*/ - - virtual bool is_texture(const RID &p_rid) const; - virtual bool is_material(const RID &p_rid) const; - virtual bool is_mesh(const RID &p_rid) const; - virtual bool is_multimesh(const RID &p_rid) const; - virtual bool is_poly(const RID &p_rid) const; - virtual bool is_particles(const RID &p_beam) const; - virtual bool is_beam(const RID &p_beam) const; - - virtual bool is_light(const RID &p_rid) const; - virtual bool is_light_instance(const RID &p_rid) const; - virtual bool is_particles_instance(const RID &p_rid) const; - virtual bool is_skeleton(const RID &p_rid) const; - virtual bool is_fx(const RID &p_rid) const; - virtual bool is_shader(const RID &p_rid) const; - - virtual void free(const RID &p_rid) const; - - virtual void init(); - virtual void finish(); - - virtual int get_render_info(VS::RenderInfo p_info); - - RasterizerIPhone(); - virtual ~RasterizerIPhone(); -}; - -#endif -#endif diff --git a/platform/iphone/sem_iphone.cpp b/platform/iphone/sem_iphone.cpp index e74c696607..4614b201a4 100644 --- a/platform/iphone/sem_iphone.cpp +++ b/platform/iphone/sem_iphone.cpp @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/iphone/sem_iphone.h b/platform/iphone/sem_iphone.h index 8a87ab47ca..90db0fb74d 100644 --- a/platform/iphone/sem_iphone.h +++ b/platform/iphone/sem_iphone.h @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/iphone/view_controller.h b/platform/iphone/view_controller.h index ca05818040..57ed576c25 100644 --- a/platform/iphone/view_controller.h +++ b/platform/iphone/view_controller.h @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/iphone/view_controller.mm b/platform/iphone/view_controller.mm index 8b3dc7c984..574598e1d3 100644 --- a/platform/iphone/view_controller.mm +++ b/platform/iphone/view_controller.mm @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -32,44 +33,43 @@ extern "C" { -int add_path(int, char**); -int add_cmdline(int, char**); +int add_path(int, char **); +int add_cmdline(int, char **); -int add_path(int p_argc, char** p_args) { +int add_path(int p_argc, char **p_args) { - NSString* str = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"godot_path"]; + NSString *str = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"godot_path"]; if (!str) return p_argc; p_args[p_argc++] = "-path"; [str retain]; // memory leak lol (maybe make it static here and delete it in ViewController destructor? @todo - p_args[p_argc++] = (char*)[str cString]; + p_args[p_argc++] = (char *)[str cString]; p_args[p_argc] = NULL; return p_argc; }; -int add_cmdline(int p_argc, char** p_args) { +int add_cmdline(int p_argc, char **p_args) { - NSArray* arr = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"godot_cmdline"]; + NSArray *arr = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"godot_cmdline"]; if (!arr) return p_argc; - for (int i=0; i < [arr count]; i++) { + for (int i = 0; i < [arr count]; i++) { - NSString* str = [arr objectAtIndex:i]; + NSString *str = [arr objectAtIndex:i]; if (!str) continue; [str retain]; // @todo delete these at some point - p_args[p_argc++] = (char*)[str cString]; + p_args[p_argc++] = (char *)[str cString]; }; p_args[p_argc] = NULL; return p_argc; }; - -}; +}; // extern "C" @interface ViewController () @@ -84,59 +84,58 @@ int add_cmdline(int p_argc, char** p_args) { - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)p_orientation { - if (/*OSIPhone::get_singleton() == NULL*/TRUE) { + if (/*OSIPhone::get_singleton() == NULL*/ TRUE) { printf("checking on info.plist\n"); - NSArray* arr = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"UISupportedInterfaceOrientations"]; - switch(p_orientation) { + NSArray *arr = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"UISupportedInterfaceOrientations"]; + switch (p_orientation) { - case UIInterfaceOrientationLandscapeLeft: - return [arr indexOfObject:@"UIInterfaceOrientationLandscapeLeft"] != NSNotFound ? YES : NO; + case UIInterfaceOrientationLandscapeLeft: + return [arr indexOfObject:@"UIInterfaceOrientationLandscapeLeft"] != NSNotFound ? YES : NO; - case UIInterfaceOrientationLandscapeRight: - return [arr indexOfObject:@"UIInterfaceOrientationLandscapeRight"] != NSNotFound ? YES : NO; + case UIInterfaceOrientationLandscapeRight: + return [arr indexOfObject:@"UIInterfaceOrientationLandscapeRight"] != NSNotFound ? YES : NO; - case UIInterfaceOrientationPortrait: - return [arr indexOfObject:@"UIInterfaceOrientationPortrait"] != NSNotFound ? YES : NO; + case UIInterfaceOrientationPortrait: + return [arr indexOfObject:@"UIInterfaceOrientationPortrait"] != NSNotFound ? YES : NO; - case UIInterfaceOrientationPortraitUpsideDown: - return [arr indexOfObject:@"UIInterfaceOrientationPortraitUpsideDown"] != NSNotFound ? YES : NO; + case UIInterfaceOrientationPortraitUpsideDown: + return [arr indexOfObject:@"UIInterfaceOrientationPortraitUpsideDown"] != NSNotFound ? YES : NO; - default: - return NO; + default: + return NO; } }; uint8_t supported = OSIPhone::get_singleton()->get_orientations(); - switch(p_orientation) { + switch (p_orientation) { - case UIInterfaceOrientationLandscapeLeft: - return supported & (1<<OSIPhone::LandscapeLeft) ? YES : NO; + case UIInterfaceOrientationLandscapeLeft: + return supported & (1 << OSIPhone::LandscapeLeft) ? YES : NO; - case UIInterfaceOrientationLandscapeRight: - return supported & (1<<OSIPhone::LandscapeRight) ? YES : NO; + case UIInterfaceOrientationLandscapeRight: + return supported & (1 << OSIPhone::LandscapeRight) ? YES : NO; - case UIInterfaceOrientationPortrait: - return supported & (1<<OSIPhone::PortraitDown) ? YES : NO; + case UIInterfaceOrientationPortrait: + return supported & (1 << OSIPhone::PortraitDown) ? YES : NO; - case UIInterfaceOrientationPortraitUpsideDown: - return supported & (1<<OSIPhone::PortraitUp) ? YES : NO; + case UIInterfaceOrientationPortraitUpsideDown: + return supported & (1 << OSIPhone::PortraitUp) ? YES : NO; - default: - return NO; + default: + return NO; } }; -- (BOOL)prefersStatusBarHidden -{ +- (BOOL)prefersStatusBarHidden { return YES; } #ifdef GAME_CENTER_ENABLED -- (void) gameCenterViewControllerDidFinish:(GKGameCenterViewController*) gameCenterViewController { - //[gameCenterViewController dismissViewControllerAnimated:YES completion:^{GameCenter::get_singleton()->game_center_closed();}];//version for signaling when overlay is completely gone - GameCenter::get_singleton()->game_center_closed(); - [gameCenterViewController dismissViewControllerAnimated:YES completion:nil]; +- (void)gameCenterViewControllerDidFinish:(GKGameCenterViewController *)gameCenterViewController { + //[gameCenterViewController dismissViewControllerAnimated:YES completion:^{GameCenter::get_singleton()->game_center_closed();}];//version for signaling when overlay is completely gone + GameCenter::get_singleton()->game_center_closed(); + [gameCenterViewController dismissViewControllerAnimated:YES completion:nil]; } #endif diff --git a/platform/javascript/SCsub b/platform/javascript/SCsub index bd7b0c304d..02ff2090f9 100644 --- a/platform/javascript/SCsub +++ b/platform/javascript/SCsub @@ -2,15 +2,13 @@ Import('env') -env.Tool('textfile') -env.Tool('zip') - javascript_files = [ "os_javascript.cpp", "audio_driver_javascript.cpp", "javascript_main.cpp", "audio_server_javascript.cpp", - "javascript_eval.cpp" + "power_javascript.cpp", + "javascript_eval.cpp", ] env_javascript = env.Clone() diff --git a/platform/javascript/audio_driver_javascript.cpp b/platform/javascript/audio_driver_javascript.cpp index 80bc7047ae..3e37ec293e 100644 --- a/platform/javascript/audio_driver_javascript.cpp +++ b/platform/javascript/audio_driver_javascript.cpp @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/javascript/audio_driver_javascript.h b/platform/javascript/audio_driver_javascript.h index ca5dba7e5c..7ccaff0f43 100644 --- a/platform/javascript/audio_driver_javascript.h +++ b/platform/javascript/audio_driver_javascript.h @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/javascript/audio_server_javascript.cpp b/platform/javascript/audio_server_javascript.cpp index 7dfd562402..f9b7890e12 100644 --- a/platform/javascript/audio_server_javascript.cpp +++ b/platform/javascript/audio_server_javascript.cpp @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/javascript/audio_server_javascript.h b/platform/javascript/audio_server_javascript.h index 2f48e7e79e..58c240f793 100644 --- a/platform/javascript/audio_server_javascript.h +++ b/platform/javascript/audio_server_javascript.h @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/javascript/detect.py b/platform/javascript/detect.py index 799b550899..41fe3fb027 100644 --- a/platform/javascript/detect.py +++ b/platform/javascript/detect.py @@ -28,14 +28,13 @@ def get_flags(): return [ ('tools', 'no'), ('module_etc1_enabled', 'no'), - ('module_mpc_enabled', 'no'), ('module_theora_enabled', 'no'), ] def create(env): # remove Windows' .exe suffix - return env.Clone(PROGSUFFIX='') + return env.Clone(tools=['textfile', 'zip'], PROGSUFFIX='') def escape_sources_backslashes(target, source, env, for_signature): @@ -70,13 +69,16 @@ def configure(env): env['LIBSUFFIX'] = '.bc' if (env["target"] == "release"): - env.Append(CCFLAGS=['-O2']) + env.Append(CCFLAGS=['-O3']) + env.Append(LINKFLAGS=['-O3']) elif (env["target"] == "release_debug"): env.Append(CCFLAGS=['-O2', '-DDEBUG_ENABLED']) + env.Append(LINKFLAGS=['-O2', '-s', 'ASSERTIONS=1']) + # retain function names at the cost of file size, for backtraces and profiling + env.Append(LINKFLAGS=['--profiling-funcs']) elif (env["target"] == "debug"): - env.Append(CCFLAGS=['-D_DEBUG', '-Wall', '-O2', '-DDEBUG_ENABLED']) - #env.Append(CCFLAGS=['-D_DEBUG', '-Wall', '-g4', '-DDEBUG_ENABLED']) - env.Append(CPPFLAGS=['-DDEBUG_MEMORY_ALLOC']) + env.Append(CCFLAGS=['-O1', '-D_DEBUG', '-g', '-DDEBUG_ENABLED']) + env.Append(LINKFLAGS=['-O1', '-g']) # TODO: Move that to opus module's config if("module_opus_enabled" in env and env["module_opus_enabled"] != "no"): @@ -84,28 +86,23 @@ def configure(env): # These flags help keep the file size down env.Append(CPPFLAGS=["-fno-exceptions", '-DNO_SAFE_CAST', '-fno-rtti']) - env.Append(CPPFLAGS=['-DJAVASCRIPT_ENABLED', '-DUNIX_ENABLED', '-DPTHREAD_NO_RENAME', '-DNO_FCNTL', '-DMPC_FIXED_POINT', '-DTYPED_METHOD_BIND', '-DNO_THREADS']) + env.Append(CPPFLAGS=['-DJAVASCRIPT_ENABLED', '-DUNIX_ENABLED', '-DPTHREAD_NO_RENAME', '-DTYPED_METHOD_BIND', '-DNO_THREADS']) env.Append(CPPFLAGS=['-DGLES3_ENABLED']) + env.Append(LINKFLAGS=['-s', 'USE_WEBGL2=1']) - if env['wasm'] == 'yes': + if (env['wasm'] == 'yes'): env.Append(LINKFLAGS=['-s', 'BINARYEN=1']) - # Maximum memory size is baked into the WebAssembly binary during - # compilation, so we need to enable memory growth to allow setting - # TOTAL_MEMORY at runtime. The value set at runtime must be higher than - # what is set during compilation, check TOTAL_MEMORY in Emscripten's - # src/settings.js for the default. + # In contrast to asm.js, enabling memory growth on WebAssembly has no + # major performance impact, and causes only a negligible increase in + # memory size. env.Append(LINKFLAGS=['-s', 'ALLOW_MEMORY_GROWTH=1']) env.extra_suffix = '.webassembly' + env.extra_suffix else: - env.Append(CPPFLAGS=['-s', 'ASM_JS=1']) env.Append(LINKFLAGS=['-s', 'ASM_JS=1']) env.Append(LINKFLAGS=['--separate-asm']) if env['javascript_eval'] == 'yes': env.Append(CPPFLAGS=['-DJAVASCRIPT_EVAL_ENABLED']) - env.Append(LINKFLAGS=['-O2']) - env.Append(LINKFLAGS=['-s', 'USE_WEBGL2=1']) - # env.Append(LINKFLAGS=['-g4']) import methods diff --git a/platform/javascript/dom_keys.h b/platform/javascript/dom_keys.h index 53a2705577..979731d157 100644 --- a/platform/javascript/dom_keys.h +++ b/platform/javascript/dom_keys.h @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/javascript/export/export.cpp b/platform/javascript/export/export.cpp index 4fdb6f39c8..4bdfdae39e 100644 --- a/platform/javascript/export/export.cpp +++ b/platform/javascript/export/export.cpp @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -26,399 +27,342 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "export.h" -#include "editor/editor_export.h" #include "editor/editor_node.h" -#include "editor/editor_settings.h" -#include "global_config.h" -#include "io/marshalls.h" +#include "editor_export.h" #include "io/zip_io.h" -#include "os/file_access.h" -#include "os/os.h" -#include "platform/javascript/logo.h" -#include "string.h" -#include "version.h" +#include "platform/javascript/logo.gen.h" +#include "platform/javascript/run_icon.gen.h" -#if 0 -class EditorExportPlatformJavaScript : public EditorExportPlatform { - - GDCLASS( EditorExportPlatformJavaScript,EditorExportPlatform ); - - String custom_release_package; - String custom_debug_package; - - enum PackMode { - PACK_SINGLE_FILE, - PACK_MULTIPLE_FILES - }; - - void _fix_html(Vector<uint8_t>& p_html, const String& p_name, bool p_debug); +#define EXPORT_TEMPLATE_WEBASSEMBLY_RELEASE "webassembly_release.zip" +#define EXPORT_TEMPLATE_WEBASSEMBLY_DEBUG "webassembly_debug.zip" +#define EXPORT_TEMPLATE_ASMJS_RELEASE "javascript_release.zip" +#define EXPORT_TEMPLATE_ASMJS_DEBUG "javascript_debug.zip" - PackMode pack_mode; - - bool show_run; - - int max_memory; - int version_code; +class EditorExportPlatformJavaScript : public EditorExportPlatform { - String html_title; - String html_head_include; - String html_font_family; - String html_style_include; - bool html_controls_enabled; + GDCLASS(EditorExportPlatformJavaScript, EditorExportPlatform) Ref<ImageTexture> logo; + Ref<ImageTexture> run_icon; + bool runnable_when_last_polled; -protected: - - bool _set(const StringName& p_name, const Variant& p_value); - bool _get(const StringName& p_name,Variant &r_ret) const; - void _get_property_list( List<PropertyInfo> *p_list) const; + void _fix_html(Vector<uint8_t> &p_html, const Ref<EditorExportPreset> &p_preset, const String &p_name, bool p_debug); + void _fix_fsloader_js(Vector<uint8_t> &p_js, const String &p_pack_name, uint64_t p_pack_size); public: + enum Target { + TARGET_WEBASSEMBLY, + TARGET_ASMJS + }; - virtual String get_name() const { return "HTML5"; } - virtual ImageCompression get_image_compression() const { return IMAGE_COMPRESSION_BC; } - virtual Ref<Texture> get_logo() const { return logo; } + virtual void get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features); + virtual void get_export_options(List<ExportOption> *r_options); + virtual bool get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const; - virtual bool poll_devices() { return show_run?true:false;} - virtual int get_device_count() const { return show_run?1:0; }; - virtual String get_device_name(int p_device) const { return "Run in Browser"; } - virtual String get_device_info(int p_device) const { return "Run exported HTML in the system's default browser."; } - virtual Error run(int p_device,int p_flags=0); + virtual String get_name() const; + virtual Ref<Texture> get_logo() const; - virtual bool requires_password(bool p_debug) const { return false; } - virtual String get_binary_extension() const { return "html"; } - virtual Error export_project(const String& p_path,bool p_debug,int p_flags=0); + virtual bool can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const; + virtual String get_binary_extension() const; + virtual Error export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags = 0); - virtual bool can_export(String *r_error=NULL) const; + virtual bool poll_devices(); + virtual int get_device_count() const; + virtual String get_device_name(int p_device) const { return TTR("Run in Browser"); } + virtual String get_device_info(int p_device) const { return TTR("Run exported HTML in the system's default browser."); } + virtual Error run(const Ref<EditorExportPreset> &p_preset, int p_device, int p_debug_flags); + virtual Ref<Texture> get_run_icon() const; EditorExportPlatformJavaScript(); - ~EditorExportPlatformJavaScript(); }; -bool EditorExportPlatformJavaScript::_set(const StringName& p_name, const Variant& p_value) { - - String n=p_name; - - if (n=="custom_package/debug") - custom_debug_package=p_value; - else if (n=="custom_package/release") - custom_release_package=p_value; - else if (n=="browser/enable_run") - show_run=p_value; - else if (n=="options/memory_size") - max_memory=p_value; - else if (n=="html/title") - html_title=p_value; - else if (n=="html/head_include") - html_head_include=p_value; - else if (n=="html/font_family") - html_font_family=p_value; - else if (n=="html/style_include") - html_style_include=p_value; - else if (n=="html/controls_enabled") - html_controls_enabled=p_value; - else - return false; +void EditorExportPlatformJavaScript::_fix_html(Vector<uint8_t> &p_html, const Ref<EditorExportPreset> &p_preset, const String &p_name, bool p_debug) { - return true; -} + String str_template = String::utf8(reinterpret_cast<const char *>(p_html.ptr()), p_html.size()); + String str_export; + Vector<String> lines = str_template.split("\n"); -bool EditorExportPlatformJavaScript::_get(const StringName& p_name,Variant &r_ret) const{ - - String n=p_name; - - if (n=="custom_package/debug") - r_ret=custom_debug_package; - else if (n=="custom_package/release") - r_ret=custom_release_package; - else if (n=="browser/enable_run") - r_ret=show_run; - else if (n=="options/memory_size") - r_ret=max_memory; - else if (n=="html/title") - r_ret=html_title; - else if (n=="html/head_include") - r_ret=html_head_include; - else if (n=="html/font_family") - r_ret=html_font_family; - else if (n=="html/style_include") - r_ret=html_style_include; - else if (n=="html/controls_enabled") - r_ret=html_controls_enabled; + int memory_mb; + if (p_preset->get("options/target").operator int() != TARGET_ASMJS) + // WebAssembly allows memory growth, so start with a reasonable default + memory_mb = 1 << 4; else - return false; - - return true; -} -void EditorExportPlatformJavaScript::_get_property_list( List<PropertyInfo> *p_list) const{ - - p_list->push_back( PropertyInfo( Variant::STRING, "custom_package/debug", PROPERTY_HINT_GLOBAL_FILE,"zip")); - p_list->push_back( PropertyInfo( Variant::STRING, "custom_package/release", PROPERTY_HINT_GLOBAL_FILE,"zip")); - p_list->push_back( PropertyInfo( Variant::INT, "options/memory_size",PROPERTY_HINT_ENUM,"32mb,64mb,128mb,256mb,512mb,1024mb")); - p_list->push_back( PropertyInfo( Variant::BOOL, "browser/enable_run")); - p_list->push_back( PropertyInfo( Variant::STRING, "html/title")); - p_list->push_back( PropertyInfo( Variant::STRING, "html/head_include",PROPERTY_HINT_MULTILINE_TEXT)); - p_list->push_back( PropertyInfo( Variant::STRING, "html/font_family")); - p_list->push_back( PropertyInfo( Variant::STRING, "html/style_include",PROPERTY_HINT_MULTILINE_TEXT)); - p_list->push_back( PropertyInfo( Variant::BOOL, "html/controls_enabled")); + memory_mb = 1 << (p_preset->get("options/memory_size").operator int() + 5); + for (int i = 0; i < lines.size(); i++) { - //p_list->push_back( PropertyInfo( Variant::INT, "resources/pack_mode", PROPERTY_HINT_ENUM,"Copy,Single Exec.,Pack (.pck),Bundles (Optical)")); + String current_line = lines[i]; + current_line = current_line.replace("$GODOT_TMEM", itos(memory_mb * 1024 * 1024)); + current_line = current_line.replace("$GODOT_BASE", p_name); + current_line = current_line.replace("$GODOT_HEAD_INCLUDE", p_preset->get("html/head_include")); + current_line = current_line.replace("$GODOT_DEBUG_ENABLED", p_debug ? "true" : "false"); + str_export += current_line + "\n"; + } + CharString cs = str_export.utf8(); + p_html.resize(cs.length()); + for (int i = 0; i < cs.length(); i++) { + p_html[i] = cs[i]; + } } +void EditorExportPlatformJavaScript::_fix_fsloader_js(Vector<uint8_t> &p_js, const String &p_pack_name, uint64_t p_pack_size) { -void EditorExportPlatformJavaScript::_fix_html(Vector<uint8_t>& p_html, const String& p_name, bool p_debug) { + String str_template = String::utf8(reinterpret_cast<const char *>(p_js.ptr()), p_js.size()); + String str_export; + Vector<String> lines = str_template.split("\n"); + for (int i = 0; i < lines.size(); i++) { + if (lines[i].find("$GODOT_PACK_NAME") != -1) { + str_export += lines[i].replace("$GODOT_PACK_NAME", p_pack_name); + } else if (lines[i].find("$GODOT_PACK_SIZE") != -1) { + str_export += lines[i].replace("$GODOT_PACK_SIZE", itos(p_pack_size)); + } else { + str_export += lines[i] + "\n"; + } + } + CharString cs = str_export.utf8(); + p_js.resize(cs.length()); + for (int i = 0; i < cs.length(); i++) { + p_js[i] = cs[i]; + } +} - String str; - String strnew; - str.parse_utf8((const char*)p_html.ptr(),p_html.size()); - Vector<String> lines=str.split("\n"); - for(int i=0;i<lines.size();i++) { +void EditorExportPlatformJavaScript::get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) { - String current_line = lines[i]; - current_line = current_line.replace("$GODOT_TMEM",itos((1<<(max_memory+5))*1024*1024)); - current_line = current_line.replace("$GODOT_BASE",p_name); - current_line = current_line.replace("$GODOT_CANVAS_WIDTH",GlobalConfig::get_singleton()->get("display/window/width")); - current_line = current_line.replace("$GODOT_CANVAS_HEIGHT",GlobalConfig::get_singleton()->get("display/window/height")); - current_line = current_line.replace("$GODOT_HEAD_TITLE",!html_title.empty()?html_title:(String) GlobalConfig::get_singleton()->get("application/name")); - current_line = current_line.replace("$GODOT_HEAD_INCLUDE",html_head_include); - current_line = current_line.replace("$GODOT_STYLE_FONT_FAMILY",html_font_family); - current_line = current_line.replace("$GODOT_STYLE_INCLUDE",html_style_include); - current_line = current_line.replace("$GODOT_CONTROLS_ENABLED",html_controls_enabled?"true":"false"); - current_line = current_line.replace("$GODOT_DEBUG_ENABLED",p_debug?"true":"false"); - strnew += current_line+"\n"; + if (p_preset->get("texture_format/s3tc")) { + r_features->push_back("s3tc"); } - - CharString cs = strnew.utf8(); - p_html.resize(cs.length()); - for(int i=9;i<cs.length();i++) { - p_html[i]=cs[i]; + if (p_preset->get("texture_format/etc")) { + r_features->push_back("etc"); + } + if (p_preset->get("texture_format/etc2")) { + r_features->push_back("etc2"); } } -static void _fix_files(Vector<uint8_t>& html,uint64_t p_data_size) { +void EditorExportPlatformJavaScript::get_export_options(List<ExportOption> *r_options) { + r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "options/target", PROPERTY_HINT_ENUM, "WebAssembly,asm.js"), TARGET_WEBASSEMBLY)); + r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "options/memory_size", PROPERTY_HINT_ENUM, "32 MB,64 MB,128 MB,256 MB,512 MB,1 GB"), 3)); + r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "texture_format/s3tc"), false)); + r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "texture_format/etc"), true)); + r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "texture_format/etc2"), false)); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "html/head_include", PROPERTY_HINT_MULTILINE_TEXT), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_template/release", PROPERTY_HINT_GLOBAL_FILE, "zip"), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_template/debug", PROPERTY_HINT_GLOBAL_FILE, "zip"), "")); +} - String str; - String strnew; - str.parse_utf8((const char*)html.ptr(),html.size()); - Vector<String> lines=str.split("\n"); - for(int i=0;i<lines.size();i++) { - if (lines[i].find("$DPLEN")!=-1) { - strnew+=lines[i].replace("$DPLEN",itos(p_data_size)); - } else { - strnew+=lines[i]+"\n"; - } - } +bool EditorExportPlatformJavaScript::get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const { - CharString cs = strnew.utf8(); - html.resize(cs.length()); - for(int i=9;i<cs.length();i++) { - html[i]=cs[i]; + if (p_option == "options/memory_size") { + return p_options["options/target"].operator int() == TARGET_ASMJS; } + return true; +} +String EditorExportPlatformJavaScript::get_name() const { + + return "HTML5"; } -struct JSExportData { +Ref<Texture> EditorExportPlatformJavaScript::get_logo() const { - EditorProgress *ep; - FileAccess *f; + return logo; +} -}; +bool EditorExportPlatformJavaScript::can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const { + r_missing_templates = false; + if (p_preset->get("options/target").operator int() == TARGET_WEBASSEMBLY) { + if (find_export_template(EXPORT_TEMPLATE_WEBASSEMBLY_RELEASE) == String()) + r_missing_templates = true; + else if (find_export_template(EXPORT_TEMPLATE_WEBASSEMBLY_DEBUG) == String()) + r_missing_templates = true; + } else { + if (find_export_template(EXPORT_TEMPLATE_ASMJS_RELEASE) == String()) + r_missing_templates = true; + else if (find_export_template(EXPORT_TEMPLATE_ASMJS_DEBUG) == String()) + r_missing_templates = true; + } -Error EditorExportPlatformJavaScript::export_project(const String& p_path, bool p_debug, int p_flags) { + return !r_missing_templates; +} +String EditorExportPlatformJavaScript::get_binary_extension() const { - String src_template; + return "html"; +} - EditorProgress ep("export","Exporting for javascript",104); +Error EditorExportPlatformJavaScript::export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags) { - if (p_debug) - src_template=custom_debug_package; - else - src_template=custom_release_package; + String custom_debug = p_preset->get("custom_template/debug"); + String custom_release = p_preset->get("custom_template/release"); + + String template_path = p_debug ? custom_debug : custom_release; - if (src_template=="") { - String err; - if (p_debug) { - src_template=find_export_template("javascript_debug.zip", &err); + template_path = template_path.strip_edges(); + + if (template_path == String()) { + + if (p_preset->get("options/target").operator int() == TARGET_WEBASSEMBLY) { + if (p_debug) + template_path = find_export_template(EXPORT_TEMPLATE_WEBASSEMBLY_DEBUG); + else + template_path = find_export_template(EXPORT_TEMPLATE_WEBASSEMBLY_RELEASE); } else { - src_template=find_export_template("javascript_release.zip", &err); - } - if (src_template=="") { - EditorNode::add_io_error(err); - return ERR_FILE_NOT_FOUND; + if (p_debug) + template_path = find_export_template(EXPORT_TEMPLATE_ASMJS_DEBUG); + else + template_path = find_export_template(EXPORT_TEMPLATE_ASMJS_RELEASE); } } - FileAccess *src_f=NULL; - zlib_filefunc_def io = zipio_create_io_from_file(&src_f); - - ep.step("Exporting to HTML5",0); + if (template_path != String() && !FileAccess::exists(template_path)) { + EditorNode::get_singleton()->show_warning(TTR("Template file not found:\n") + template_path); + return ERR_FILE_NOT_FOUND; + } - ep.step("Finding Files..",1); + String pck_path = p_path.get_basename() + ".pck"; + Error error = save_pack(p_preset, pck_path); + if (error != OK) { + EditorNode::get_singleton()->show_warning(TTR("Could not write file:\n") + pck_path); + return error; + } - FileAccess *f=FileAccess::open(p_path.get_base_dir()+"/data.pck",FileAccess::WRITE); + FileAccess *f = FileAccess::open(pck_path, FileAccess::READ); if (!f) { - EditorNode::add_io_error("Could not create file for writing:\n"+p_path.get_basename()+"_files.js"); - return ERR_FILE_CANT_WRITE; + EditorNode::get_singleton()->show_warning(TTR("Could not read file:\n") + pck_path); + return ERR_FILE_CANT_READ; } - Error err = save_pack(f); - size_t len = f->get_len(); + size_t pack_size = f->get_len(); memdelete(f); - if (err) - return err; + FileAccess *src_f = NULL; + zlib_filefunc_def io = zipio_create_io_from_file(&src_f); + unzFile pkg = unzOpen2(template_path.utf8().get_data(), &io); - unzFile pkg = unzOpen2(src_template.utf8().get_data(), &io); if (!pkg) { - EditorNode::add_io_error("Could not find template HTML5 to export:\n"+src_template); + EditorNode::get_singleton()->show_warning(TTR("Could not open template for export:\n") + template_path); return ERR_FILE_NOT_FOUND; } - ERR_FAIL_COND_V(!pkg, ERR_CANT_OPEN); int ret = unzGoToFirstFile(pkg); - - - while(ret==UNZ_OK) { + while (ret == UNZ_OK) { //get filename unz_file_info info; char fname[16384]; - ret = unzGetCurrentFileInfo(pkg,&info,fname,16384,NULL,0,NULL,0); + ret = unzGetCurrentFileInfo(pkg, &info, fname, 16384, NULL, 0, NULL, 0); - String file=fname; + String file = fname; Vector<uint8_t> data; data.resize(info.uncompressed_size); //read unzOpenCurrentFile(pkg); - unzReadCurrentFile(pkg,data.ptr(),data.size()); + unzReadCurrentFile(pkg, data.ptr(), data.size()); unzCloseCurrentFile(pkg); //write - if (file=="godot.html") { + if (file == "godot.html") { - _fix_html(data,p_path.get_file().get_basename(), p_debug); - file=p_path.get_file(); - } - if (file=="godotfs.js") { - - _fix_files(data,len); - file=p_path.get_file().get_basename()+"fs.js"; - } - if (file=="godot.js") { + _fix_html(data, p_preset, p_path.get_file().get_basename(), p_debug); + file = p_path.get_file(); + } else if (file == "godotfs.js") { - file=p_path.get_file().get_basename()+".js"; - } + _fix_fsloader_js(data, pck_path.get_file(), pack_size); + file = p_path.get_file().get_basename() + "fs.js"; + } else if (file == "godot.js") { - if (file=="godot.asm.js") { + file = p_path.get_file().get_basename() + ".js"; + } else if (file == "godot.wasm") { - file=p_path.get_file().get_basename()+".asm.js"; - } + file = p_path.get_file().get_basename() + ".wasm"; + } else if (file == "godot.asm.js") { - if (file=="godot.mem") { + file = p_path.get_file().get_basename() + ".asm.js"; + } else if (file == "godot.mem") { - file=p_path.get_file().get_basename()+".mem"; - } - - if (file=="godot.wasm") { - - file=p_path.get_file().get_basename()+".wasm"; + file = p_path.get_file().get_basename() + ".mem"; } String dst = p_path.get_base_dir().plus_file(file); - FileAccess *f=FileAccess::open(dst,FileAccess::WRITE); + FileAccess *f = FileAccess::open(dst, FileAccess::WRITE); if (!f) { - EditorNode::add_io_error("Could not create file for writing:\n"+dst); + EditorNode::get_singleton()->show_warning(TTR("Could not write file:\n") + dst); unzClose(pkg); return ERR_FILE_CANT_WRITE; } - f->store_buffer(data.ptr(),data.size()); + f->store_buffer(data.ptr(), data.size()); memdelete(f); - ret = unzGoToNextFile(pkg); } - - return OK; - } +bool EditorExportPlatformJavaScript::poll_devices() { -Error EditorExportPlatformJavaScript::run(int p_device, int p_flags) { + Ref<EditorExportPreset> preset; - String path = EditorSettings::get_singleton()->get_settings_path()+"/tmp/tmp_export.html"; - Error err = export_project(path,true,p_flags); - if (err) - return err; + for (int i = 0; i < EditorExport::get_singleton()->get_export_preset_count(); i++) { - OS::get_singleton()->shell_open(path); + Ref<EditorExportPreset> ep = EditorExport::get_singleton()->get_export_preset(i); + if (ep->is_runnable() && ep->get_platform() == this) { + preset = ep; + break; + } + } - return OK; + bool prev = runnable_when_last_polled; + runnable_when_last_polled = preset.is_valid(); + return runnable_when_last_polled != prev; } +int EditorExportPlatformJavaScript::get_device_count() const { -EditorExportPlatformJavaScript::EditorExportPlatformJavaScript() { - - show_run=false; - Image img( _javascript_logo ); - logo = Ref<ImageTexture>( memnew( ImageTexture )); - logo->create_from_image(img); - max_memory=3; - html_title=""; - html_font_family="'Droid Sans',arial,sans-serif"; - html_controls_enabled=true; - pack_mode=PACK_SINGLE_FILE; + return runnable_when_last_polled; } -bool EditorExportPlatformJavaScript::can_export(String *r_error) const { - - - bool valid=true; - String err; +Error EditorExportPlatformJavaScript::run(const Ref<EditorExportPreset> &p_preset, int p_device, int p_debug_flags) { - if (!exists_export_template("javascript_debug.zip") || !exists_export_template("javascript_release.zip")) { - valid=false; - err+="No export templates found.\nDownload and install export templates.\n"; - } - - if (custom_debug_package!="" && !FileAccess::exists(custom_debug_package)) { - valid=false; - err+="Custom debug package not found.\n"; - } - - if (custom_release_package!="" && !FileAccess::exists(custom_release_package)) { - valid=false; - err+="Custom release package not found.\n"; + String path = EditorSettings::get_singleton()->get_settings_path() + "/tmp/tmp_export.html"; + Error err = export_project(p_preset, true, path, p_debug_flags); + if (err) { + return err; } + OS::get_singleton()->shell_open(path); + return OK; +} - if (r_error) - *r_error=err; +Ref<Texture> EditorExportPlatformJavaScript::get_run_icon() const { - return valid; + return run_icon; } +EditorExportPlatformJavaScript::EditorExportPlatformJavaScript() { + + Ref<Image> img = memnew(Image(_javascript_logo)); + logo.instance(); + logo->create_from_image(img); -EditorExportPlatformJavaScript::~EditorExportPlatformJavaScript() { + img = Ref<Image>(memnew(Image(_javascript_run_icon))); + run_icon.instance(); + run_icon->create_from_image(img); + runnable_when_last_polled = false; } -#endif void register_javascript_exporter() { - //Ref<EditorExportPlatformJavaScript> exporter = Ref<EditorExportPlatformJavaScript>( memnew(EditorExportPlatformJavaScript) ); - //EditorImportExport::get_singleton()->add_export_platform(exporter); + Ref<EditorExportPlatformJavaScript> platform; + platform.instance(); + EditorExport::get_singleton()->add_export_platform(platform); } diff --git a/platform/javascript/export/export.h b/platform/javascript/export/export.h index 59c0a67e6d..910c4119f7 100644 --- a/platform/javascript/export/export.h +++ b/platform/javascript/export/export.h @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/javascript/godot_shell.html b/platform/javascript/godot_shell.html index 65f3b4a340..6c7069a8f0 100644 --- a/platform/javascript/godot_shell.html +++ b/platform/javascript/godot_shell.html @@ -2,8 +2,7 @@ <html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang=""> <head> <meta charset="utf-8" /> - <title>$GODOT_HEAD_TITLE</title> -$GODOT_HEAD_INCLUDE + <title></title> <style type="text/css"> body { margin: 0; @@ -11,7 +10,7 @@ $GODOT_HEAD_INCLUDE padding: 0; text-align: center; background-color: #222226; - font-family: $GODOT_STYLE_FONT_FAMILY; + font-family: 'Droid Sans', Arial, sans-serif; } @@ -27,7 +26,7 @@ $GODOT_HEAD_INCLUDE } button.godot { - font-family: $GODOT_STYLE_FONT_FAMILY; /* override user agent style */ + font-family: 'Droid Sans', Arial, sans-serif; /* override user agent style */ padding: 1px 5px; background-color: #37353f; background-image: linear-gradient(to bottom, #413e49, #3a3842); @@ -109,53 +108,12 @@ $GODOT_HEAD_INCLUDE } - /* On-hover controls - * ================= */ - - #controls { - visibility: hidden; - opacity: 0.0; - transition: opacity 500ms ease-in-out 200ms; - position: absolute; - right: 16px; - top: 16px; - padding: 3px 5px; - font-size: small; - -moz-user-select: none; - -webkit-user-select: none; - -ms-user-select: none; - } - - :hover > #controls { - opacity: 1.0; - transition: opacity 60ms ease-in-out; - } - - #controls > button, - #controls > label { - vertical-align: middle; - margin-left: 2px; - margin-right: 2px; - } - - #controls > label > input { - vertical-align: middle; - } - - #controls > label > input[type="checkbox"] { - /* override user agent style */ - margin-left: 0; - } - - #output-toggle { display: none; } - - /* Debug output * ============ */ #output-panel { display: none; - max-width: $GODOT_CANVAS_WIDTHpx; + max-width: 700px; font-size: small; margin: 6px auto 0; padding: 0 4px 4px; @@ -184,32 +142,18 @@ $GODOT_HEAD_INCLUDE font-size: small; font-family: "Lucida Console", Monaco, monospace; } - - -/* Export style include - * ==================== */ - -$GODOT_STYLE_INCLUDE - </style> +$GODOT_HEAD_INCLUDE </head> <body> <div id="container"> - <canvas id="canvas" width="$GODOT_CANVAS_WIDTH" height="$GODOT_CANVAS_HEIGHT" onclick="canvas.ownerDocument.defaultView.focus();" oncontextmenu="event.preventDefault();"> + <canvas id="canvas" width="640" height="480" onclick="canvas.ownerDocument.defaultView.focus();" oncontextmenu="event.preventDefault();"> HTML5 canvas appears to be unsupported in the current browser.<br /> Please try updating or use a different browser. </canvas> <div id="status-container"> <span id="status" class="godot" onclick="this.style.visibility='hidden';">Downloading page...</span> </div> - <div id="controls" class="godot"> - <label id="output-toggle"><input type="checkbox" checked="checked" autocomplete="off" onchange="Presentation.setOutputVisible(this.checked);" />Display Output</label> - <!-- hidden until implemented - <label><input class="postRun-enable" type="checkbox" disabled="disabled" autocomplete="off" />lock cursor</label> - <label><input class="postRun-enable" type="checkbox" disabled="disabled" autocomplete="off" onchange="Presentation.setCanvasMaximized(this.checked);" />maximize</label> - --> - <button id="fullscreen" class="godot postRun-enable" type="button" disabled="disabled" autocomplete="off" onclick="Presentation.requestFullscreen();">Fullscreen</button> - </div> </div> <div id="output-panel" class="godot"> <div id="output-header"> @@ -226,33 +170,9 @@ $GODOT_STYLE_INCLUDE var canvasElement = document.getElementById("canvas"); var presentation = { - postRun: [ - function() { - var elements = document.getElementsByClassName("postRun-enable"); - Array.prototype.slice.call(elements).forEach(function(element) { - element.disabled = false; - }); - } - ], - requestFullscreen: function requestFullscreen() { - if (typeof Module !== "undefined" && Module.requestFullscreen) { - Module.requestFullscreen(false, false); - } - }, - /* - requestPointerlock: function requestPointerlock() { - if (typeof Module !== "undefined" && Module.requestPointerlock) { - Module.requestPointerlock(false, false); - } - }, - setCanvasMaximized: function setCanvasMaximized(enabled) { - if (typeof Module !== "undefined" && Module.setCanvasMaximized) { - Module.setCanvasMaximized(enabled); - } - }, - */ + postRun: [], setStatusVisible: function setStatusVisible(visible) { - statusElement.style.visibility = (visible?"visible":"hidden"); + statusElement.style.visibility = (visible ? "visible" : "hidden"); }, setStatus: function setStatus(text) { if (text.length === 0) { @@ -288,18 +208,13 @@ $GODOT_STYLE_INCLUDE window.onerror = function(event) { presentation.setStatus("Failure during start-up\nSee JavaScript console") }; - if ($GODOT_CONTROLS_ENABLED) { // controls enabled - document.getElementById("controls").style.visibility="visible"; - } - if ($GODOT_DEBUG_ENABLED) { // debugging enabled var outputRoot = document.getElementById("output-panel"); var outputElement = document.getElementById("output-scroll"); - var outputToggle = document.getElementById("output-toggle"); const maxOutputMessages = 400; presentation.setOutputVisible = function setOutputVisible(visible) { - outputRoot.style.display = (visible?"block":"none"); + outputRoot.style.display = (visible ? "block" : "none"); }; presentation.clearOutput = function clearOutput() { while (outputElement.firstChild) { @@ -308,7 +223,6 @@ $GODOT_STYLE_INCLUDE }; presentation.setOutputVisible(true); - outputToggle.style.display = "inline"; presentation.print = function print(text) { if (arguments.length > 1) { @@ -347,56 +261,59 @@ $GODOT_STYLE_INCLUDE })(); // Emscripten interface - var Module = { - TOTAL_MEMORY: $GODOT_TMEM, - postRun: (function() { - if (typeof Presentation !== "undefined" && Presentation.postRun instanceof Array) { - return Presentation.postRun; - } - })(), - print: function print(text) { - if (arguments.length > 1) { - text = Array.prototype.slice.call(arguments).join(" "); - } - console.log(text); - if (typeof Presentation !== "undefined" && typeof Presentation.print === "function") { - Presentation.print(text); - } - }, - printErr: function printErr(text) { - if (arguments.length > 1) { - text = Array.prototype.slice.call(arguments).join(" "); - } - console.error(text); - if (typeof Presentation !== "undefined" && typeof Presentation.print === "function") { - Presentation.print("**ERROR**:", text) - } - }, - canvas: (function() { - var canvas = document.getElementById("canvas"); - // As a default initial behavior, pop up an alert when WebGL context is lost. To make your - // application robust, you may want to override this behavior before shipping! - // See http://www.khronos.org/registry/webgl/specs/latest/1.0/#5.15.2 - canvas.addEventListener("webglcontextlost", function(e) { alert("WebGL context lost. Plase reload the page."); e.preventDefault(); }, false); - return canvas; - - })(), - setStatus: function setStatus(text) { - var m = text.match(/([^(]+)\((\d+(\.\d+)?)\/(\d+)\)/); - var now = Date.now(); - if (m) { - if (now - Date.now() < 30) // if this is a progress update, skip it if too soon - return; - text = m[1]; - } - if (typeof Presentation !== "undefined" && typeof Presentation.setStatus == "function") { - Presentation.setStatus(text); + var Module = (function() { + const BASE_NAME = '$GODOT_BASE'; + var module = { + thisProgram: BASE_NAME, + wasmBinaryFile: BASE_NAME + '.wasm', + TOTAL_MEMORY: $GODOT_TMEM, + print: function print(text) { + if (arguments.length > 1) { + text = Array.prototype.slice.call(arguments).join(" "); + } + console.log(text); + if (typeof Presentation !== "undefined" && typeof Presentation.print === "function") { + Presentation.print(text); + } + }, + printErr: function printErr(text) { + if (arguments.length > 1) { + text = Array.prototype.slice.call(arguments).join(" "); + } + console.error(text); + if (typeof Presentation !== "undefined" && typeof Presentation.print === "function") { + Presentation.print("**ERROR**:", text) + } + }, + canvas: document.getElementById("canvas"), + setStatus: function setStatus(text) { + var m = text.match(/([^(]+)\((\d+(\.\d+)?)\/(\d+)\)/); + var now = Date.now(); + if (m) { + if (now - Date.now() < 30) // if this is a progress update, skip it if too soon + return; + text = m[1]; + } + if (typeof Presentation !== "undefined" && typeof Presentation.setStatus == "function") { + Presentation.setStatus(text); + } } + }; + + // As a default initial behavior, pop up an alert when WebGL context is lost. To make your + // application robust, you may want to override this behavior before shipping! + // See http://www.khronos.org/registry/webgl/specs/latest/1.0/#5.15.2 + module.canvas.addEventListener("webglcontextlost", function(e) { alert("WebGL context lost. Plase reload the page."); e.preventDefault(); }, false); + + if (typeof Presentation !== "undefined" && Presentation.postRun instanceof Array) { + module.postRun = Presentation.postRun; } - }; + + return module; + })(); if (!Presentation.isWebGL2Available()) { - Presentation.setStatus("WebGL2 appears to be unsupported in the current browser.\nPlease try updating or use a different browser."); + Presentation.setStatus("WebGL 2 appears to be unsupported.\nPlease update browser and drivers."); Presentation.preventLoading = true; } else { Presentation.setStatus("Downloading..."); diff --git a/platform/javascript/javascript_eval.cpp b/platform/javascript/javascript_eval.cpp index 897c2276bb..c9312e8d30 100644 --- a/platform/javascript/javascript_eval.cpp +++ b/platform/javascript/javascript_eval.cpp @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/javascript/javascript_eval.h b/platform/javascript/javascript_eval.h index 0050b855d8..4a732cec76 100644 --- a/platform/javascript/javascript_eval.h +++ b/platform/javascript/javascript_eval.h @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/javascript/javascript_main.cpp b/platform/javascript/javascript_main.cpp index 00e531baa1..6b1d574496 100644 --- a/platform/javascript/javascript_main.cpp +++ b/platform/javascript/javascript_main.cpp @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -30,171 +31,50 @@ #include "io/resource_loader.h" #include "main/main.h" #include "os_javascript.h" -#include <GL/glut.h> -#include <string.h> OS_JavaScript *os = NULL; -static void _gfx_init(void *ud, bool gl2, int w, int h, bool fs) { +static void main_loop() { - glutInitWindowSize(w, h); - glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); - glutCreateWindow("godot"); + os->main_loop_iterate(); } -static uint32_t _mouse_button_mask = 0; +extern "C" void main_after_fs_sync() { -static void _glut_mouse_button(int button, int state, int x, int y) { - - InputEvent ev; - ev.type = InputEvent::MOUSE_BUTTON; - switch (button) { - case GLUT_LEFT_BUTTON: ev.mouse_button.button_index = BUTTON_LEFT; break; - case GLUT_MIDDLE_BUTTON: ev.mouse_button.button_index = BUTTON_MIDDLE; break; - case GLUT_RIGHT_BUTTON: ev.mouse_button.button_index = BUTTON_RIGHT; break; - case 3: ev.mouse_button.button_index = BUTTON_WHEEL_UP; break; - case 4: ev.mouse_button.button_index = BUTTON_WHEEL_DOWN; break; - } - - ev.mouse_button.pressed = state == GLUT_DOWN; - ev.mouse_button.x = x; - ev.mouse_button.y = y; - ev.mouse_button.global_x = x; - ev.mouse_button.global_y = y; - - if (ev.mouse_button.button_index < 4) { - if (ev.mouse_button.pressed) { - _mouse_button_mask |= 1 << (ev.mouse_button.button_index - 1); - } else { - _mouse_button_mask &= ~(1 << (ev.mouse_button.button_index - 1)); - } - } - ev.mouse_button.button_mask = _mouse_button_mask; - - uint32_t m = glutGetModifiers(); - ev.mouse_button.mod.alt = (m & GLUT_ACTIVE_ALT) != 0; - ev.mouse_button.mod.shift = (m & GLUT_ACTIVE_SHIFT) != 0; - ev.mouse_button.mod.control = (m & GLUT_ACTIVE_CTRL) != 0; - - os->push_input(ev); - - if (ev.mouse_button.button_index == BUTTON_WHEEL_UP || ev.mouse_button.button_index == BUTTON_WHEEL_DOWN) { - // GLUT doesn't send release events for mouse wheel, so send manually - ev.mouse_button.pressed = false; - os->push_input(ev); - } -} - -static int _glut_prev_x = 0; -static int _glut_prev_y = 0; - -static void _glut_mouse_motion(int x, int y) { - - InputEvent ev; - ev.type = InputEvent::MOUSE_MOTION; - ev.mouse_motion.button_mask = _mouse_button_mask; - ev.mouse_motion.x = x; - ev.mouse_motion.y = y; - ev.mouse_motion.global_x = x; - ev.mouse_motion.global_y = y; - ev.mouse_motion.relative_x = x - _glut_prev_x; - ev.mouse_motion.relative_y = y - _glut_prev_y; - _glut_prev_x = x; - _glut_prev_y = y; - - uint32_t m = glutGetModifiers(); - ev.mouse_motion.mod.alt = (m & GLUT_ACTIVE_ALT) != 0; - ev.mouse_motion.mod.shift = (m & GLUT_ACTIVE_SHIFT) != 0; - ev.mouse_motion.mod.control = (m & GLUT_ACTIVE_CTRL) != 0; - - os->push_input(ev); -} - -static void _gfx_idle() { - - glutPostRedisplay(); -} - -int start_step = 0; - -static void _godot_draw(void) { - - if (start_step == 1) { - start_step = 2; - Main::start(); - os->main_loop_begin(); - } - - if (start_step == 2) { - os->main_loop_iterate(); - } - - glutSwapBuffers(); -} - -extern "C" { - -void main_after_fs_sync() { - - start_step = 1; -} + // Ease up compatibility + ResourceLoader::set_abort_on_missing_resources(false); + Main::start(); + os->main_loop_begin(); + emscripten_set_main_loop(main_loop, 0, false); } int main(int argc, char *argv[]) { - /* Initialize the window */ printf("let it go dude!\n"); - glutInit(&argc, argv); - os = new OS_JavaScript(_gfx_init, NULL, NULL); -#if 0 - char *args[]={"-test","gui","-v",NULL}; - Error err = Main::setup("apk",3,args); -#else - char *args[] = { "-main_pack", "data.pck", NULL }; //pass location of main pack manually, because it wont get an executable name - Error err = Main::setup("", 2, args); - -#endif - ResourceLoader::set_abort_on_missing_resources(false); //ease up compatibility - - glutMouseFunc(_glut_mouse_button); - glutMotionFunc(_glut_mouse_motion); - glutPassiveMotionFunc(_glut_mouse_motion); - /* Set up glut callback functions */ - glutIdleFunc(_gfx_idle); - // glutReshapeFunc(gears_reshape); - glutDisplayFunc(_godot_draw); - //glutSpecialFunc(gears_special); - - //mount persistent file system + // sync from persistent state into memory and then + // run the 'main_after_fs_sync' function /* clang-format off */ EM_ASM( + Module.noExitRuntime = true; FS.mkdir('/userfs'); FS.mount(IDBFS, {}, '/userfs'); - - // sync from persistent state into memory and then - // run the 'main_after_fs_sync' function FS.syncfs(true, function(err) { - if (err) { Module.setStatus('Failed to load persistent data\nPlease allow (third-party) cookies'); Module.printErr('Failed to populate IDB file system: ' + err.message); - Module.exit(); + Module.noExitRuntime = false; } else { Module.print('Successfully populated IDB file system'); - ccall('main_after_fs_sync', 'void', []); + ccall('main_after_fs_sync', null); } }); ); /* clang-format on */ - glutMainLoop(); + os = new OS_JavaScript(argv[0], NULL); + Error err = Main::setup(argv[0], argc - 1, &argv[1]); return 0; + // continued async in main_after_fs_sync() from syncfs() callback } - -/* - * - *09] <azakai|2__> reduz: yes, define TOTAL_MEMORY on Module. for example var Module = { TOTAL_MEMORY: 12345.. }; before the main - * - */ diff --git a/platform/javascript/os_javascript.cpp b/platform/javascript/os_javascript.cpp index 83072c30aa..9df26f1471 100644 --- a/platform/javascript/os_javascript.cpp +++ b/platform/javascript/os_javascript.cpp @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -40,6 +41,19 @@ #include <emscripten.h> #include <stdlib.h> +#define DOM_BUTTON_LEFT 0 +#define DOM_BUTTON_MIDDLE 1 +#define DOM_BUTTON_RIGHT 2 + +template <typename T> +static void dom2godot_mod(T emscripten_event_ptr, Ref<InputEventWithModifiers> godot_event) { + + godot_event->set_shift(emscripten_event_ptr->shiftKey); + godot_event->set_alt(emscripten_event_ptr->altKey); + godot_event->set_control(emscripten_event_ptr->ctrlKey); + godot_event->set_metakey(emscripten_event_ptr->metaKey); +} + int OS_JavaScript::get_video_driver_count() const { return 1; @@ -129,16 +143,192 @@ static EM_BOOL _fullscreen_change_callback(int event_type, const EmscriptenFulls return false; } -static InputEvent _setup_key_event(const EmscriptenKeyboardEvent *emscripten_event) { +static InputDefault *_input; + +static EM_BOOL _mousebutton_callback(int event_type, const EmscriptenMouseEvent *mouse_event, void *user_data) { + + ERR_FAIL_COND_V(event_type != EMSCRIPTEN_EVENT_MOUSEDOWN && event_type != EMSCRIPTEN_EVENT_MOUSEUP, false); + + Ref<InputEventMouseButton> ev; + ev.instance(); + ev->set_pressed(event_type == EMSCRIPTEN_EVENT_MOUSEDOWN); + ev->set_position(Point2(mouse_event->canvasX, mouse_event->canvasY)); + ev->set_global_position(ev->get_position()); + dom2godot_mod(mouse_event, ev); + + switch (mouse_event->button) { + case DOM_BUTTON_LEFT: ev->set_button_index(BUTTON_LEFT); break; + case DOM_BUTTON_MIDDLE: ev->set_button_index(BUTTON_MIDDLE); break; + case DOM_BUTTON_RIGHT: ev->set_button_index(BUTTON_RIGHT); break; + default: return false; + } + + int mask = _input->get_mouse_button_mask(); + if (ev->is_pressed()) + mask |= 1 << ev->get_button_index(); + else + mask &= ~(1 << ev->get_button_index()); + ev->set_button_mask(mask >> 1); + + _input->parse_input_event(ev); + 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); + + Ref<InputEventMouseMotion> ev; + ev.instance(); + dom2godot_mod(mouse_event, ev); + ev->set_button_mask(_input->get_mouse_button_mask() >> 1); + + ev->set_position(Point2(mouse_event->canvasX, mouse_event->canvasY)); + ev->set_global_position(ev->get_position()); + + ev->set_relative(_input->get_mouse_position() - ev->get_position()); + _input->set_mouse_position(ev->get_position()); + ev->set_speed(_input->get_last_mouse_speed()); + + _input->parse_input_event(ev); + return true; +} + +static EM_BOOL _wheel_callback(int event_type, const EmscriptenWheelEvent *wheel_event, void *user_data) { + + ERR_FAIL_COND_V(event_type != EMSCRIPTEN_EVENT_WHEEL, false); + + Ref<InputEventMouseButton> ev; + ev.instance(); + ev->set_button_mask(_input->get_mouse_button_mask() >> 1); + ev->set_position(_input->get_mouse_position()); + ev->set_global_position(ev->get_position()); + + ev->set_shift(_input->is_key_pressed(KEY_SHIFT)); + ev->set_alt(_input->is_key_pressed(KEY_ALT)); + ev->set_control(_input->is_key_pressed(KEY_CONTROL)); + ev->set_metakey(_input->is_key_pressed(KEY_META)); + + if (wheel_event->deltaY < 0) + ev->set_button_index(BUTTON_WHEEL_UP); + else if (wheel_event->deltaY > 0) + ev->set_button_index(BUTTON_WHEEL_DOWN); + else if (wheel_event->deltaX > 0) + ev->set_button_index(BUTTON_WHEEL_LEFT); + else if (wheel_event->deltaX < 0) + ev->set_button_index(BUTTON_WHEEL_RIGHT); + else + return false; + + // Different browsers give wildly different delta values, and we can't + // interpret deltaMode, so use default value for wheel events' factor + + ev->set_pressed(true); + _input->parse_input_event(ev); + + ev->set_pressed(false); + _input->parse_input_event(ev); + + return true; +} + +static Point2 _prev_touches[32]; + +static EM_BOOL _touchpress_callback(int event_type, const EmscriptenTouchEvent *touch_event, void *user_data) { + + ERR_FAIL_COND_V( + event_type != EMSCRIPTEN_EVENT_TOUCHSTART && + event_type != EMSCRIPTEN_EVENT_TOUCHEND && + event_type != EMSCRIPTEN_EVENT_TOUCHCANCEL, + false); + + Ref<InputEventScreenTouch> ev; + ev.instance(); + int lowest_id_index = -1; + for (int i = 0; i < touch_event->numTouches; ++i) { + + const EmscriptenTouchPoint &touch = touch_event->touches[i]; + if (lowest_id_index == -1 || touch.identifier < touch_event->touches[lowest_id_index].identifier) + lowest_id_index = i; + if (!touch.isChanged) + continue; + ev->set_index(touch.identifier); + ev->set_position(Point2(touch.canvasX, touch.canvasY)); + _prev_touches[i] = ev->get_position(); + ev->set_pressed(event_type == EMSCRIPTEN_EVENT_TOUCHSTART); + + _input->parse_input_event(ev); + } + + if (touch_event->touches[lowest_id_index].isChanged) { + + Ref<InputEventMouseButton> ev_mouse; + ev_mouse.instance(); + ev_mouse->set_button_mask(_input->get_mouse_button_mask() >> 1); + dom2godot_mod(touch_event, ev_mouse); + + const EmscriptenTouchPoint &first_touch = touch_event->touches[lowest_id_index]; + ev_mouse->set_position(Point2(first_touch.canvasX, first_touch.canvasY)); + ev_mouse->set_global_position(ev_mouse->get_position()); + + ev_mouse->set_button_index(BUTTON_LEFT); + ev_mouse->set_pressed(event_type == EMSCRIPTEN_EVENT_TOUCHSTART); + + _input->parse_input_event(ev_mouse); + } + return true; +} + +static EM_BOOL _touchmove_callback(int event_type, const EmscriptenTouchEvent *touch_event, void *user_data) { + + ERR_FAIL_COND_V(event_type != EMSCRIPTEN_EVENT_TOUCHMOVE, false); + + Ref<InputEventScreenDrag> ev; + ev.instance(); + int lowest_id_index = -1; + for (int i = 0; i < touch_event->numTouches; ++i) { + + const EmscriptenTouchPoint &touch = touch_event->touches[i]; + if (lowest_id_index == -1 || touch.identifier < touch_event->touches[lowest_id_index].identifier) + lowest_id_index = i; + if (!touch.isChanged) + continue; + ev->set_index(touch.identifier); + ev->set_position(Point2(touch.canvasX, touch.canvasY)); + Point2 &prev = _prev_touches[i]; + ev->set_relative(ev->get_position() - prev); + prev = ev->get_position(); + + _input->parse_input_event(ev); + } + + if (touch_event->touches[lowest_id_index].isChanged) { + + Ref<InputEventMouseMotion> ev_mouse; + ev_mouse.instance(); + dom2godot_mod(touch_event, ev_mouse); + ev_mouse->set_button_mask(_input->get_mouse_button_mask() >> 1); + + const EmscriptenTouchPoint &first_touch = touch_event->touches[lowest_id_index]; + ev_mouse->set_position(Point2(first_touch.canvasX, first_touch.canvasY)); + ev_mouse->set_global_position(ev_mouse->get_position()); + + ev_mouse->set_relative(_input->get_mouse_position() - ev_mouse->get_position()); + _input->set_mouse_position(ev_mouse->get_position()); + ev_mouse->set_speed(_input->get_last_mouse_speed()); + + _input->parse_input_event(ev_mouse); + } + return true; +} + +static Ref<InputEventKey> _setup_key_event(const EmscriptenKeyboardEvent *emscripten_event) { - InputEvent ev; - ev.type = InputEvent::KEY; - ev.key.echo = emscripten_event->repeat; - ev.key.mod.alt = emscripten_event->altKey; - ev.key.mod.shift = emscripten_event->shiftKey; - ev.key.mod.control = emscripten_event->ctrlKey; - ev.key.mod.meta = emscripten_event->metaKey; - ev.key.scancode = dom2godot_scancode(emscripten_event->keyCode); + Ref<InputEventKey> ev; + ev.instance(); + ev->set_echo(emscripten_event->repeat); + dom2godot_mod(emscripten_event, ev); + ev->set_scancode(dom2godot_scancode(emscripten_event->keyCode)); String unicode = String::utf8(emscripten_event->key); // check if empty or multi-character (e.g. `CapsLock`) @@ -147,26 +337,26 @@ static InputEvent _setup_key_event(const EmscriptenKeyboardEvent *emscripten_eve unicode = String::utf8(emscripten_event->charValue); } if (unicode.length() == 1) { - ev.key.unicode = unicode[0]; + ev->set_unicode(unicode[0]); } return ev; } -static InputEvent deferred_key_event; +static Ref<InputEventKey> deferred_key_event; static EM_BOOL _keydown_callback(int event_type, const EmscriptenKeyboardEvent *key_event, void *user_data) { ERR_FAIL_COND_V(event_type != EMSCRIPTEN_EVENT_KEYDOWN, false); - InputEvent ev = _setup_key_event(key_event); - ev.key.pressed = true; - if (ev.key.unicode == 0 && keycode_has_unicode(ev.key.scancode)) { + Ref<InputEventKey> ev = _setup_key_event(key_event); + ev->set_pressed(true); + if (ev->get_unicode() == 0 && keycode_has_unicode(ev->get_scancode())) { // defer to keypress event for legacy unicode retrieval deferred_key_event = ev; return false; // do not suppress keypress event } - static_cast<OS_JavaScript *>(user_data)->push_input(ev); + _input->parse_input_event(ev); return true; } @@ -174,8 +364,8 @@ static EM_BOOL _keypress_callback(int event_type, const EmscriptenKeyboardEvent ERR_FAIL_COND_V(event_type != EMSCRIPTEN_EVENT_KEYPRESS, false); - deferred_key_event.key.unicode = key_event->charCode; - static_cast<OS_JavaScript *>(user_data)->push_input(deferred_key_event); + deferred_key_event->set_unicode(key_event->charCode); + _input->parse_input_event(deferred_key_event); return true; } @@ -183,10 +373,10 @@ static EM_BOOL _keyup_callback(int event_type, const EmscriptenKeyboardEvent *ke ERR_FAIL_COND_V(event_type != EMSCRIPTEN_EVENT_KEYUP, false); - InputEvent ev = _setup_key_event(key_event); - ev.key.pressed = false; - static_cast<OS_JavaScript *>(user_data)->push_input(ev); - return ev.key.scancode != KEY_UNKNOWN && ev.key.scancode != 0; + Ref<InputEventKey> ev = _setup_key_event(key_event); + ev->set_pressed(false); + _input->parse_input_event(ev); + return ev->get_scancode() != KEY_UNKNOWN && ev->get_scancode() != 0; } static EM_BOOL joy_callback_func(int p_type, const EmscriptenGamepadEvent *p_event, void *p_user) { @@ -201,14 +391,18 @@ void OS_JavaScript::initialize(const VideoMode &p_desired, int p_video_driver, i print_line("Init OS"); - if (gfx_init_func) - gfx_init_func(gfx_init_ud, use_gl2, p_desired.width, p_desired.height, p_desired.fullscreen); + EmscriptenWebGLContextAttributes attributes; + emscripten_webgl_init_context_attributes(&attributes); + attributes.alpha = false; + attributes.antialias = false; + attributes.majorVersion = 2; + EMSCRIPTEN_WEBGL_CONTEXT_HANDLE ctx = emscripten_webgl_create_context(NULL, &attributes); + ERR_FAIL_COND(emscripten_webgl_make_context_current(ctx) != EMSCRIPTEN_RESULT_SUCCESS); - // nothing to do here, can't fulfil fullscreen request due to - // browser security, window size is already set from HTML video_mode = p_desired; + // can't fulfil fullscreen request due to browser security video_mode.fullscreen = false; - _windowed_size = get_window_size(); + set_window_size(Size2(p_desired.width, p_desired.height)); // find locale, emscripten only sets "C" char locale_ptr[16]; @@ -256,25 +450,34 @@ void OS_JavaScript::initialize(const VideoMode &p_desired, int p_video_driver, i physics_2d_server->init(); input = memnew(InputDefault); + _input = input; power_manager = memnew(PowerJavascript); #define EM_CHECK(ev) \ if (result != EMSCRIPTEN_RESULT_SUCCESS) \ ERR_PRINTS("Error while setting " #ev " callback: Code " + itos(result)) -#define SET_EM_CALLBACK(ev, cb) \ - result = emscripten_set_##ev##_callback(NULL, this, true, &cb); \ +#define SET_EM_CALLBACK(target, ev, cb) \ + result = emscripten_set_##ev##_callback(target, this, true, &cb); \ EM_CHECK(ev) #define SET_EM_CALLBACK_NODATA(ev, cb) \ result = emscripten_set_##ev##_callback(NULL, true, &cb); \ EM_CHECK(ev) EMSCRIPTEN_RESULT result; - SET_EM_CALLBACK(keydown, _keydown_callback) - SET_EM_CALLBACK(keypress, _keypress_callback) - SET_EM_CALLBACK(keyup, _keyup_callback) - SET_EM_CALLBACK(resize, _browser_resize_callback) - SET_EM_CALLBACK(fullscreenchange, _fullscreen_change_callback) + SET_EM_CALLBACK("#canvas", mousemove, _mousemove_callback) + SET_EM_CALLBACK("#canvas", mousedown, _mousebutton_callback) + SET_EM_CALLBACK("#canvas", mouseup, _mousebutton_callback) + SET_EM_CALLBACK("#canvas", wheel, _wheel_callback) + SET_EM_CALLBACK("#canvas", touchstart, _touchpress_callback) + SET_EM_CALLBACK("#canvas", touchmove, _touchmove_callback) + SET_EM_CALLBACK("#canvas", touchend, _touchpress_callback) + SET_EM_CALLBACK("#canvas", touchcancel, _touchpress_callback) + SET_EM_CALLBACK(NULL, keydown, _keydown_callback) + SET_EM_CALLBACK(NULL, keypress, _keypress_callback) + SET_EM_CALLBACK(NULL, 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) @@ -315,30 +518,97 @@ void OS_JavaScript::alert(const String &p_alert, const String &p_title) { /* clang-format on */ } -void OS_JavaScript::set_mouse_show(bool p_show) { +static const char *godot2dom_cursor(OS::CursorShape p_shape) { + + switch (p_shape) { + case OS::CURSOR_ARROW: + default: + return "auto"; + case OS::CURSOR_IBEAM: return "text"; + case OS::CURSOR_POINTING_HAND: return "pointer"; + case OS::CURSOR_CROSS: return "crosshair"; + case OS::CURSOR_WAIT: return "progress"; + case OS::CURSOR_BUSY: return "wait"; + case OS::CURSOR_DRAG: return "grab"; + case OS::CURSOR_CAN_DROP: return "grabbing"; + case OS::CURSOR_FORBIDDEN: return "no-drop"; + case OS::CURSOR_VSIZE: return "ns-resize"; + case OS::CURSOR_HSIZE: return "ew-resize"; + case OS::CURSOR_BDIAGSIZE: return "nesw-resize"; + case OS::CURSOR_FDIAGSIZE: return "nwse-resize"; + case OS::CURSOR_MOVE: return "move"; + case OS::CURSOR_VSPLIT: return "row-resize"; + case OS::CURSOR_HSPLIT: return "col-resize"; + case OS::CURSOR_HELP: return "help"; + } +} - //javascript has no mouse... +void OS_JavaScript::set_css_cursor(const char *p_cursor) { + + /* clang-format off */ + EM_ASM_({ + Module.canvas.style.cursor = Module.UTF8ToString($0); + }, p_cursor); + /* clang-format on */ } -void OS_JavaScript::set_mouse_grab(bool p_grab) { +const char *OS_JavaScript::get_css_cursor() const { - //it really has no mouse...! + char cursor[16]; + /* clang-format off */ + EM_ASM_INT({ + Module.stringToUTF8(Module.canvas.style.cursor ? Module.canvas.style.cursor : 'auto', $0, 16); + }, cursor); + /* clang-format on */ + return cursor; } -bool OS_JavaScript::is_mouse_grab_enabled() const { +void OS_JavaScript::set_mouse_mode(OS::MouseMode p_mode) { - //*sigh* technology has evolved so much since i was a kid.. - return false; + ERR_FAIL_INDEX(p_mode, MOUSE_MODE_CONFINED + 1); + ERR_EXPLAIN("MOUSE_MODE_CONFINED is not supported for the HTML5 platform"); + ERR_FAIL_COND(p_mode == MOUSE_MODE_CONFINED); + if (p_mode == get_mouse_mode()) + return; + + if (p_mode == MOUSE_MODE_VISIBLE) { + + set_css_cursor(godot2dom_cursor(cursor_shape)); + emscripten_exit_pointerlock(); + + } else if (p_mode == MOUSE_MODE_HIDDEN) { + + set_css_cursor("none"); + emscripten_exit_pointerlock(); + + } else if (p_mode == MOUSE_MODE_CAPTURED) { + + EMSCRIPTEN_RESULT result = emscripten_request_pointerlock("canvas", false); + ERR_EXPLAIN("MOUSE_MODE_CAPTURED can only be entered from within an appropriate input callback"); + ERR_FAIL_COND(result == EMSCRIPTEN_RESULT_FAILED_NOT_DEFERRED); + ERR_FAIL_COND(result != EMSCRIPTEN_RESULT_SUCCESS); + set_css_cursor(godot2dom_cursor(cursor_shape)); + } } -Point2 OS_JavaScript::get_mouse_pos() const { +OS::MouseMode OS_JavaScript::get_mouse_mode() const { + + if (!strcmp(get_css_cursor(), "none")) + return MOUSE_MODE_HIDDEN; - return input->get_mouse_pos(); + EmscriptenPointerlockChangeEvent ev; + emscripten_get_pointerlock_status(&ev); + return ev.isActive && (strcmp(ev.id, "canvas") == 0) ? MOUSE_MODE_CAPTURED : MOUSE_MODE_VISIBLE; +} + +Point2 OS_JavaScript::get_mouse_position() const { + + return input->get_mouse_position(); } int OS_JavaScript::get_mouse_button_state() const { - return last_button_mask; + return input->get_mouse_button_mask(); } void OS_JavaScript::set_window_title(const String &p_title) { @@ -462,7 +732,11 @@ bool OS_JavaScript::can_draw() const { void OS_JavaScript::set_cursor_shape(CursorShape p_shape) { - //javascript really really really has no mouse.. how amazing.. + ERR_FAIL_INDEX(p_shape, CURSOR_MAX); + + cursor_shape = p_shape; + if (get_mouse_mode() != MOUSE_MODE_HIDDEN) + set_css_cursor(godot2dom_cursor(cursor_shape)); } void OS_JavaScript::main_loop_begin() { @@ -517,208 +791,6 @@ void OS_JavaScript::main_loop_focusin() { //audio_driver_javascript.set_pause(false); } -void OS_JavaScript::push_input(const InputEvent &p_ev) { - - InputEvent ev = p_ev; - ev.ID = last_id++; - if (ev.type == InputEvent::MOUSE_MOTION) { - input->set_mouse_pos(Point2(ev.mouse_motion.x, ev.mouse_motion.y)); - } else if (ev.type == InputEvent::MOUSE_BUTTON) { - last_button_mask = ev.mouse_button.button_mask; - } - input->parse_input_event(p_ev); -} - -void OS_JavaScript::process_touch(int p_what, int p_pointer, const Vector<TouchPos> &p_points) { - - //print_line("ev: "+itos(p_what)+" pnt: "+itos(p_pointer)+" pointc: "+itos(p_points.size())); - - switch (p_what) { - case 0: { //gesture begin - - if (touch.size()) { - //end all if exist - InputEvent ev; - ev.type = InputEvent::MOUSE_BUTTON; - ev.ID = last_id++; - ev.mouse_button.button_index = BUTTON_LEFT; - ev.mouse_button.button_mask = BUTTON_MASK_LEFT; - ev.mouse_button.pressed = false; - ev.mouse_button.x = touch[0].pos.x; - ev.mouse_button.y = touch[0].pos.y; - ev.mouse_button.global_x = touch[0].pos.x; - ev.mouse_button.global_y = touch[0].pos.y; - input->parse_input_event(ev); - - for (int i = 0; i < touch.size(); i++) { - - InputEvent ev; - ev.type = InputEvent::SCREEN_TOUCH; - ev.ID = last_id++; - ev.screen_touch.index = touch[i].id; - ev.screen_touch.pressed = false; - ev.screen_touch.x = touch[i].pos.x; - ev.screen_touch.y = touch[i].pos.y; - input->parse_input_event(ev); - } - } - - touch.resize(p_points.size()); - for (int i = 0; i < p_points.size(); i++) { - touch[i].id = p_points[i].id; - touch[i].pos = p_points[i].pos; - } - - { - //send mouse - InputEvent ev; - ev.type = InputEvent::MOUSE_BUTTON; - ev.ID = last_id++; - ev.mouse_button.button_index = BUTTON_LEFT; - ev.mouse_button.button_mask = BUTTON_MASK_LEFT; - ev.mouse_button.pressed = true; - ev.mouse_button.x = touch[0].pos.x; - ev.mouse_button.y = touch[0].pos.y; - ev.mouse_button.global_x = touch[0].pos.x; - ev.mouse_button.global_y = touch[0].pos.y; - last_mouse = touch[0].pos; - input->parse_input_event(ev); - } - - //send touch - for (int i = 0; i < touch.size(); i++) { - - InputEvent ev; - ev.type = InputEvent::SCREEN_TOUCH; - ev.ID = last_id++; - ev.screen_touch.index = touch[i].id; - ev.screen_touch.pressed = true; - ev.screen_touch.x = touch[i].pos.x; - ev.screen_touch.y = touch[i].pos.y; - input->parse_input_event(ev); - } - - } break; - case 1: { //motion - - if (p_points.size()) { - //send mouse, should look for point 0? - InputEvent ev; - ev.type = InputEvent::MOUSE_MOTION; - ev.ID = last_id++; - ev.mouse_motion.button_mask = BUTTON_MASK_LEFT; - ev.mouse_motion.x = p_points[0].pos.x; - ev.mouse_motion.y = p_points[0].pos.y; - input->set_mouse_pos(Point2(ev.mouse_motion.x, ev.mouse_motion.y)); - ev.mouse_motion.speed_x = input->get_last_mouse_speed().x; - ev.mouse_motion.speed_y = input->get_last_mouse_speed().y; - ev.mouse_motion.relative_x = p_points[0].pos.x - last_mouse.x; - ev.mouse_motion.relative_y = p_points[0].pos.y - last_mouse.y; - last_mouse = p_points[0].pos; - input->parse_input_event(ev); - } - - ERR_FAIL_COND(touch.size() != p_points.size()); - - for (int i = 0; i < touch.size(); i++) { - - int idx = -1; - for (int j = 0; j < p_points.size(); j++) { - - if (touch[i].id == p_points[j].id) { - idx = j; - break; - } - } - - ERR_CONTINUE(idx == -1); - - if (touch[i].pos == p_points[idx].pos) - continue; //no move unncesearily - - InputEvent ev; - ev.type = InputEvent::SCREEN_DRAG; - ev.ID = last_id++; - ev.screen_drag.index = touch[i].id; - ev.screen_drag.x = p_points[idx].pos.x; - ev.screen_drag.y = p_points[idx].pos.y; - ev.screen_drag.relative_x = p_points[idx].pos.x - touch[i].pos.x; - ev.screen_drag.relative_y = p_points[idx].pos.y - touch[i].pos.y; - input->parse_input_event(ev); - touch[i].pos = p_points[idx].pos; - } - - } break; - case 2: { //release - - if (touch.size()) { - //end all if exist - InputEvent ev; - ev.type = InputEvent::MOUSE_BUTTON; - ev.ID = last_id++; - ev.mouse_button.button_index = BUTTON_LEFT; - ev.mouse_button.button_mask = BUTTON_MASK_LEFT; - ev.mouse_button.pressed = false; - ev.mouse_button.x = touch[0].pos.x; - ev.mouse_button.y = touch[0].pos.y; - ev.mouse_button.global_x = touch[0].pos.x; - ev.mouse_button.global_y = touch[0].pos.y; - input->parse_input_event(ev); - - for (int i = 0; i < touch.size(); i++) { - - InputEvent ev; - ev.type = InputEvent::SCREEN_TOUCH; - ev.ID = last_id++; - ev.screen_touch.index = touch[i].id; - ev.screen_touch.pressed = false; - ev.screen_touch.x = touch[i].pos.x; - ev.screen_touch.y = touch[i].pos.y; - input->parse_input_event(ev); - } - touch.clear(); - } - - } break; - case 3: { // add tuchi - - ERR_FAIL_INDEX(p_pointer, p_points.size()); - - TouchPos tp = p_points[p_pointer]; - touch.push_back(tp); - - InputEvent ev; - ev.type = InputEvent::SCREEN_TOUCH; - ev.ID = last_id++; - ev.screen_touch.index = tp.id; - ev.screen_touch.pressed = true; - ev.screen_touch.x = tp.pos.x; - ev.screen_touch.y = tp.pos.y; - input->parse_input_event(ev); - - } break; - case 4: { - - for (int i = 0; i < touch.size(); i++) { - if (touch[i].id == p_pointer) { - - InputEvent ev; - ev.type = InputEvent::SCREEN_TOUCH; - ev.ID = last_id++; - ev.screen_touch.index = touch[i].id; - ev.screen_touch.pressed = false; - ev.screen_touch.x = touch[i].pos.x; - ev.screen_touch.y = touch[i].pos.y; - input->parse_input_event(ev); - touch.remove(i); - i--; - } - } - - } break; - } -} - void OS_JavaScript::process_accelerometer(const Vector3 &p_accelerometer) { input->set_accelerometer(p_accelerometer); @@ -761,7 +833,7 @@ String OS_JavaScript::get_data_dir() const { String OS_JavaScript::get_executable_path() const { - return String(); + return OS::get_executable_path(); } void OS_JavaScript::_close_notification_funcs(const String &p_file, int p_flags) { @@ -790,9 +862,9 @@ void OS_JavaScript::process_joypads() { InputDefault::JoyAxis jx; jx.min = 0; jx.value = value; - last_id = input->joy_axis(last_id, i, j, jx); + input->joy_axis(i, j, jx); } else { - last_id = input->joy_button(last_id, i, j, value); + input->joy_button(i, j, value); } } for (int j = 0; j < num_axes; j++) { @@ -800,7 +872,7 @@ void OS_JavaScript::process_joypads() { InputDefault::JoyAxis jx; jx.min = -1; jx.value = state.axis[j]; - last_id = input->joy_axis(last_id, i, j, jx); + input->joy_axis(i, j, jx); } } } @@ -839,12 +911,9 @@ int OS_JavaScript::get_power_percent_left() { return power_manager->get_power_percent_left(); } -OS_JavaScript::OS_JavaScript(GFXInitFunc p_gfx_init_func, void *p_gfx_init_ud, GetDataDirFunc p_get_data_dir_func) { - gfx_init_func = p_gfx_init_func; - gfx_init_ud = p_gfx_init_ud; - last_button_mask = 0; +OS_JavaScript::OS_JavaScript(const char *p_execpath, GetDataDirFunc p_get_data_dir_func) { + set_cmdline(p_execpath, get_cmdline_args()); main_loop = NULL; - last_id = 1; gl_extensions = NULL; window_maximized = false; diff --git a/platform/javascript/os_javascript.h b/platform/javascript/os_javascript.h index b16918b2da..65269148ec 100644 --- a/platform/javascript/os_javascript.h +++ b/platform/javascript/os_javascript.h @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -44,25 +45,9 @@ #include <emscripten/html5.h> -typedef void (*GFXInitFunc)(void *ud, bool gl2, int w, int h, bool fs); typedef String (*GetDataDirFunc)(); class OS_JavaScript : public OS_Unix { -public: - struct TouchPos { - int id; - Point2 pos; - }; - -private: - Vector<TouchPos> touch; - Point2 last_mouse; - int last_button_mask; - unsigned int last_id; - GFXInitFunc gfx_init_func; - void *gfx_init_ud; - - bool use_gl2; int64_t time_to_save_sync; int64_t last_sync_time; @@ -76,6 +61,7 @@ private: InputDefault *input; bool window_maximized; VideoMode video_mode; + CursorShape cursor_shape; MainLoop *main_loop; GetDataDirFunc get_data_dir_func; @@ -90,6 +76,9 @@ private: void process_joypads(); + void set_css_cursor(const char *); + const char *get_css_cursor() const; + public: // functions used by main to initialize/deintialize the OS virtual int get_video_driver_count() const; @@ -119,10 +108,9 @@ public: virtual void alert(const String &p_alert, const String &p_title = "ALERT!"); - virtual void set_mouse_show(bool p_show); - virtual void set_mouse_grab(bool p_grab); - virtual bool is_mouse_grab_enabled() const; - virtual Point2 get_mouse_pos() const; + virtual void set_mouse_mode(MouseMode p_mode); + virtual MouseMode get_mouse_mode() const; + virtual Point2 get_mouse_position() const; virtual int get_mouse_button_state() const; virtual void set_window_title(const String &p_title); @@ -166,8 +154,7 @@ public: virtual String get_resource_dir() const; void process_accelerometer(const Vector3 &p_accelerometer); - void process_touch(int p_what, int p_pointer, const Vector<TouchPos> &p_points); - void push_input(const InputEvent &p_ev); + void push_input(const Ref<InputEvent> &p_ev); virtual bool is_joy_known(int p_device); virtual String get_joy_guid(int p_device) const; @@ -177,7 +164,7 @@ public: virtual int get_power_seconds_left(); virtual int get_power_percent_left(); - OS_JavaScript(GFXInitFunc p_gfx_init_func, void *p_gfx_init_ud, GetDataDirFunc p_get_data_dir_func); + OS_JavaScript(const char *p_execpath, GetDataDirFunc p_get_data_dir_func); ~OS_JavaScript(); }; diff --git a/platform/javascript/platform_config.h b/platform/javascript/platform_config.h index cdef185ff0..48bcadcc29 100644 --- a/platform/javascript/platform_config.h +++ b/platform/javascript/platform_config.h @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/javascript/power_javascript.cpp b/platform/javascript/power_javascript.cpp index d734999917..bd4502fc2a 100644 --- a/platform/javascript/power_javascript.cpp +++ b/platform/javascript/power_javascript.cpp @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -28,7 +29,7 @@ /*************************************************************************/ #include "power_javascript.h" -#include "core/error_macros.h" +#include "error_macros.h" bool PowerJavascript::UpdatePowerInfo() { // TODO Javascript implementation diff --git a/platform/javascript/power_javascript.h b/platform/javascript/power_javascript.h index 53c702b98e..c7b853ce11 100644 --- a/platform/javascript/power_javascript.h +++ b/platform/javascript/power_javascript.h @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -30,6 +31,8 @@ #ifndef PLATFORM_JAVASCRIPT_POWER_JAVASCRIPT_H_ #define PLATFORM_JAVASCRIPT_POWER_JAVASCRIPT_H_ +#include "os/power.h" + class PowerJavascript { private: int nsecs_left; diff --git a/platform/javascript/run_icon.png b/platform/javascript/run_icon.png Binary files differnew file mode 100644 index 0000000000..dedee6f479 --- /dev/null +++ b/platform/javascript/run_icon.png diff --git a/platform/osx/SCsub b/platform/osx/SCsub index 1427c2e00d..27117c2e8d 100644 --- a/platform/osx/SCsub +++ b/platform/osx/SCsub @@ -7,7 +7,6 @@ files = [ 'godot_main_osx.mm', 'audio_driver_osx.cpp', 'sem_osx.cpp', - # 'context_gl_osx.cpp', 'dir_access_osx.mm', 'joypad_osx.cpp', 'power_osx.cpp', diff --git a/platform/osx/audio_driver_osx.cpp b/platform/osx/audio_driver_osx.cpp index 7ef0669656..7469d52976 100644 --- a/platform/osx/audio_driver_osx.cpp +++ b/platform/osx/audio_driver_osx.cpp @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/osx/audio_driver_osx.h b/platform/osx/audio_driver_osx.h index b030570a6e..9b48dab405 100644 --- a/platform/osx/audio_driver_osx.h +++ b/platform/osx/audio_driver_osx.h @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/osx/context_gl_osx.cpp b/platform/osx/context_gl_osx.cpp deleted file mode 100644 index 0737e3d3c6..0000000000 --- a/platform/osx/context_gl_osx.cpp +++ /dev/null @@ -1,102 +0,0 @@ -/*************************************************************************/ -/* context_gl_osx.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* http://www.godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ -#include "context_gl_osx.h" - -#ifdef OSX_ENABLED -#if defined(OPENGL_ENABLED) || defined(LEGACYGL_ENABLED) -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> - -#define GLX_CONTEXT_MAJOR_VERSION_ARB 0x2091 -#define GLX_CONTEXT_MINOR_VERSION_ARB 0x2092 - -void ContextGL_OSX::release_current() { - - aglSetCurrentContext(context); -} - -void ContextGL_OSX::make_current() { - - aglSetCurrentContext(NULL); -} -void ContextGL_OSX::swap_buffers() { - - aglSwapBuffers(context); -} - -Error ContextGL_OSX::initialize() { - - if ((Ptr)kUnresolvedCFragSymbolAddress == (Ptr)aglChoosePixelFormat) - return FAILED; - - GLint attributes[] = { AGL_RGBA, - AGL_DOUBLEBUFFER, - AGL_DEPTH_SIZE, 32, - AGL_NO_RECOVERY, - AGL_NONE, - AGL_NONE }; - - AGLPixelFormat format = NULL; - - format = aglChoosePixelFormat(NULL, 0, attributes); - - if (!format) - return FAILED; - - context = aglCreateContext(format, 0); - - if (!context) - return FAILED; - - aglDestroyPixelFormat(format); - - aglSetWindowRef(context, window); - - GLint swapInterval = 1; - aglSetInteger(context, AGL_SWAP_INTERVAL, &swapInterval); - - aglSetCurrentContext(context); - - return OK; -} - -ContextGL_OSX::ContextGL_OSX(WindowRef p_window) { - - window = p_window; -} - -ContextGL_OSX::~ContextGL_OSX() { - - if (context) - aglDestroyContext(context); -} - -#endif -#endif diff --git a/platform/osx/context_gl_osx.h b/platform/osx/context_gl_osx.h deleted file mode 100644 index 66da8b1ecf..0000000000 --- a/platform/osx/context_gl_osx.h +++ /dev/null @@ -1,63 +0,0 @@ -/*************************************************************************/ -/* context_gl_osx.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* http://www.godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ -#ifndef CONTEXT_GL_OSX_H -#define CONTEXT_GL_OSX_H - -/** - @author Juan Linietsky <reduzio@gmail.com> -*/ -#ifdef OSX_ENABLED - -#if defined(OPENGL_ENABLED) || defined(LEGACYGL_ENABLED) - -#include "drivers/gl_context/context_gl.h" -#include "os/os.h" -#include <AGL/agl.h> -#include <Carbon/Carbon.h> - -class ContextGL_OSX : public ContextGL { - - AGLContext context; - WindowRef window; - -public: - virtual void release_current(); - virtual void make_current(); - virtual void swap_buffers(); - - virtual Error initialize(); - - ContextGL_OSX(WindowRef window); - ~ContextGL_OSX(); -}; - -#endif - -#endif -#endif diff --git a/platform/osx/detect.py b/platform/osx/detect.py index b59dfe1afb..39ee33ae82 100644 --- a/platform/osx/detect.py +++ b/platform/osx/detect.py @@ -51,7 +51,7 @@ def configure(env): elif (env["target"] == "debug"): - env.Append(CCFLAGS=['-g3', '-Wall', '-DDEBUG_ENABLED', '-DDEBUG_MEMORY_ENABLED']) + env.Append(CCFLAGS=['-g3', '-DDEBUG_ENABLED', '-DDEBUG_MEMORY_ENABLED']) if (not os.environ.has_key("OSXCROSS_ROOT")): # regular native build diff --git a/platform/osx/dir_access_osx.h b/platform/osx/dir_access_osx.h index 56a8e057dd..6dcff3898c 100644 --- a/platform/osx/dir_access_osx.h +++ b/platform/osx/dir_access_osx.h @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/osx/dir_access_osx.mm b/platform/osx/dir_access_osx.mm index 476da2635e..37ba0e6b19 100644 --- a/platform/osx/dir_access_osx.mm +++ b/platform/osx/dir_access_osx.mm @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -34,17 +35,14 @@ #include <Foundation/NSString.h> - -String DirAccessOSX::fix_unicode_name(const char* p_name) const { +String DirAccessOSX::fix_unicode_name(const char *p_name) const { String fname; - NSString* nsstr = [[NSString stringWithUTF8String: p_name] precomposedStringWithCanonicalMapping]; + NSString *nsstr = [[NSString stringWithUTF8String:p_name] precomposedStringWithCanonicalMapping]; fname.parse_utf8([nsstr UTF8String]); return fname; } - - #endif //posix_enabled diff --git a/platform/osx/export/export.cpp b/platform/osx/export/export.cpp index ba4ef0300c..066adde780 100644 --- a/platform/osx/export/export.cpp +++ b/platform/osx/export/export.cpp @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -26,6 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + #include "export.h" #include "editor/editor_export.h" #include "editor/editor_node.h" @@ -36,384 +38,286 @@ #include "io/zip_io.h" #include "os/file_access.h" #include "os/os.h" -#include "platform/osx/logo.h" +#include "platform/osx/logo.gen.h" #include "string.h" #include "version.h" -#if 0 class EditorExportPlatformOSX : public EditorExportPlatform { - GDCLASS( EditorExportPlatformOSX,EditorExportPlatform ); - - String custom_release_package; - String custom_debug_package; - - enum BitsMode { - BITS_FAT, - BITS_64, - BITS_32 - }; + GDCLASS(EditorExportPlatformOSX, EditorExportPlatform); int version_code; - String app_name; - String info; - String icon; - String identifier; - String short_version; - String version; - String signature; - String copyright; - BitsMode bits_mode; - bool high_resolution; - Ref<ImageTexture> logo; - void _fix_plist(Vector<uint8_t>& plist, const String &p_binary); - void _make_icon(const Image& p_icon,Vector<uint8_t>& data); - + void _fix_plist(const Ref<EditorExportPreset> &p_preset, Vector<uint8_t> &plist, const String &p_binary); + void _make_icon(const Ref<Image> &p_icon, Vector<uint8_t> &p_data); protected: - - bool _set(const StringName& p_name, const Variant& p_value); - bool _get(const StringName& p_name,Variant &r_ret) const; - void _get_property_list( List<PropertyInfo> *p_list) const; + virtual void get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features); + virtual void get_export_options(List<ExportOption> *r_options); public: - virtual String get_name() const { return "Mac OSX"; } - virtual ImageCompression get_image_compression() const { return IMAGE_COMPRESSION_BC; } virtual Ref<Texture> get_logo() const { return logo; } - - virtual bool poll_devices() { return false;} - virtual int get_device_count() const { return 0; } - virtual String get_device_name(int p_device) const { return String(); } - virtual String get_device_info(int p_device) const { return String(); } - virtual Error run(int p_device,int p_flags=0); - - virtual bool requires_password(bool p_debug) const { return false; } virtual String get_binary_extension() const { return "zip"; } - virtual Error export_project(const String& p_path,bool p_debug,int p_flags=0); + virtual Error export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags = 0); - virtual bool can_export(String *r_error=NULL) const; + virtual bool can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const; EditorExportPlatformOSX(); ~EditorExportPlatformOSX(); }; -bool EditorExportPlatformOSX::_set(const StringName& p_name, const Variant& p_value) { - - String n=p_name; - - if (n=="custom_package/debug") - custom_debug_package=p_value; - else if (n=="custom_package/release") - custom_release_package=p_value; - else if (n=="application/name") - app_name=p_value; - else if (n=="application/info") - info=p_value; - else if (n=="application/icon") - icon=p_value; - else if (n=="application/identifier") - identifier=p_value; - else if (n=="application/signature") - signature=p_value; - else if (n=="application/short_version") - short_version=p_value; - else if (n=="application/version") - version=p_value; - else if (n=="application/copyright") - copyright=p_value; - else if (n=="application/bits_mode") - bits_mode=BitsMode(int(p_value)); - else if (n=="display/high_res") - high_resolution=p_value; - else - return false; - - return true; -} - -bool EditorExportPlatformOSX::_get(const StringName& p_name,Variant &r_ret) const{ - - String n=p_name; - - if (n=="custom_package/debug") - r_ret=custom_debug_package; - else if (n=="custom_package/release") - r_ret=custom_release_package; - else if (n=="application/name") - r_ret=app_name; - else if (n=="application/info") - r_ret=info; - else if (n=="application/icon") - r_ret=icon; - else if (n=="application/identifier") - r_ret=identifier; - else if (n=="application/signature") - r_ret=signature; - else if (n=="application/short_version") - r_ret=short_version; - else if (n=="application/version") - r_ret=version; - else if (n=="application/copyright") - r_ret=copyright; - else if (n=="application/bits_mode") - r_ret=bits_mode; - else if (n=="display/high_res") - r_ret=high_resolution; - else - return false; +void EditorExportPlatformOSX::get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) { - return true; + // what does this need to do? } -void EditorExportPlatformOSX::_get_property_list( List<PropertyInfo> *p_list) const{ - - p_list->push_back( PropertyInfo( Variant::STRING, "custom_package/debug", PROPERTY_HINT_GLOBAL_FILE,"zip")); - p_list->push_back( PropertyInfo( Variant::STRING, "custom_package/release", PROPERTY_HINT_GLOBAL_FILE,"zip")); - - p_list->push_back( PropertyInfo( Variant::STRING, "application/name") ); - p_list->push_back( PropertyInfo( Variant::STRING, "application/info") ); - p_list->push_back( PropertyInfo( Variant::STRING, "application/icon",PROPERTY_HINT_FILE,"png") ); - p_list->push_back( PropertyInfo( Variant::STRING, "application/identifier") ); - p_list->push_back( PropertyInfo( Variant::STRING, "application/signature") ); - p_list->push_back( PropertyInfo( Variant::STRING, "application/short_version") ); - p_list->push_back( PropertyInfo( Variant::STRING, "application/version") ); - p_list->push_back( PropertyInfo( Variant::STRING, "application/copyright") ); - p_list->push_back( PropertyInfo( Variant::INT, "application/bits_mode", PROPERTY_HINT_ENUM, "Fat (32 & 64 bits),64 bits,32 bits") ); - p_list->push_back( PropertyInfo( Variant::BOOL, "display/high_res") ); +void EditorExportPlatformOSX::get_export_options(List<ExportOption> *r_options) { + + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_package/debug", PROPERTY_HINT_GLOBAL_FILE, "zip"), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_package/release", PROPERTY_HINT_GLOBAL_FILE, "zip"), "")); + + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/name"), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/info"), "Made with Godot Engine")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/icon", PROPERTY_HINT_FILE, "png"), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/identifier"), "org.godotengine.macgame")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/signature"), "godotmacgame")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/short_version"), "1.0")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/version"), "1.0")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/copyright"), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "application/bits_mode", PROPERTY_HINT_ENUM, "Fat (32 & 64 bits),64 bits,32 bits"), 0)); + r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "display/high_res"), false)); } -void EditorExportPlatformOSX::_make_icon(const Image& p_icon,Vector<uint8_t>& icon) { +void EditorExportPlatformOSX::_make_icon(const Ref<Image> &p_icon, Vector<uint8_t> &p_data) { - - Ref<ImageTexture> it = memnew( ImageTexture ); - int size=512; + Ref<ImageTexture> it = memnew(ImageTexture); + int size = 512; Vector<uint8_t> data; data.resize(8); - data[0]='i'; - data[1]='c'; - data[2]='n'; - data[3]='s'; + data[0] = 'i'; + data[1] = 'c'; + data[2] = 'n'; + data[3] = 's'; - const char *name[]={"ic09","ic08","ic07","icp6","icp5","icp4"}; - int index=0; + const char *name[] = { "ic09", "ic08", "ic07", "icp6", "icp5", "icp4" }; + int index = 0; - while(size>=16) { + while (size >= 16) { - Image copy = p_icon; - copy.convert(Image::FORMAT_RGBA8); - copy.resize(size,size); + Ref<Image> copy = p_icon; // does this make sense? doesn't this just increase the reference count instead of making a copy? Do we even need a copy? + copy->convert(Image::FORMAT_RGBA8); + copy->resize(size, size); it->create_from_image(copy); - String path = EditorSettings::get_singleton()->get_settings_path()+"/tmp/icon.png"; - ResourceSaver::save(path,it); + String path = EditorSettings::get_singleton()->get_settings_path() + "/tmp/icon.png"; + ResourceSaver::save(path, it); - FileAccess *f = FileAccess::open(path,FileAccess::READ); + FileAccess *f = FileAccess::open(path, FileAccess::READ); ERR_FAIL_COND(!f); int ofs = data.size(); uint32_t len = f->get_len(); - data.resize(data.size()+len+8); - f->get_buffer(&data[ofs+8],len); + data.resize(data.size() + len + 8); + f->get_buffer(&data[ofs + 8], len); memdelete(f); - len+=8; - len=BSWAP32(len); - copymem(&data[ofs],name[index],4); - encode_uint32(len,&data[ofs+4]); + len += 8; + len = BSWAP32(len); + copymem(&data[ofs], name[index], 4); + encode_uint32(len, &data[ofs + 4]); index++; - size/=2; + size /= 2; } uint32_t total_len = data.size(); total_len = BSWAP32(total_len); - encode_uint32(total_len,&data[4]); + encode_uint32(total_len, &data[4]); - icon=data; + p_data = data; } - -void EditorExportPlatformOSX::_fix_plist(Vector<uint8_t>& plist,const String& p_binary) { - +void EditorExportPlatformOSX::_fix_plist(const Ref<EditorExportPreset> &p_preset, Vector<uint8_t> &plist, const String &p_binary) { String str; String strnew; - str.parse_utf8((const char*)plist.ptr(),plist.size()); - Vector<String> lines=str.split("\n"); - for(int i=0;i<lines.size();i++) { - if (lines[i].find("$binary")!=-1) { - strnew+=lines[i].replace("$binary",p_binary)+"\n"; - } else if (lines[i].find("$name")!=-1) { - strnew+=lines[i].replace("$name",p_binary)+"\n"; - } else if (lines[i].find("$info")!=-1) { - strnew+=lines[i].replace("$info",info)+"\n"; - } else if (lines[i].find("$identifier")!=-1) { - strnew+=lines[i].replace("$identifier",identifier)+"\n"; - } else if (lines[i].find("$short_version")!=-1) { - strnew+=lines[i].replace("$short_version",short_version)+"\n"; - } else if (lines[i].find("$version")!=-1) { - strnew+=lines[i].replace("$version",version)+"\n"; - } else if (lines[i].find("$signature")!=-1) { - strnew+=lines[i].replace("$signature",signature)+"\n"; - } else if (lines[i].find("$copyright")!=-1) { - strnew+=lines[i].replace("$copyright",copyright)+"\n"; - } else if (lines[i].find("$highres")!=-1) { - strnew+=lines[i].replace("$highres",high_resolution?"<true/>":"<false/>")+"\n"; + str.parse_utf8((const char *)plist.ptr(), plist.size()); + Vector<String> lines = str.split("\n"); + for (int i = 0; i < lines.size(); i++) { + if (lines[i].find("$binary") != -1) { + strnew += lines[i].replace("$binary", p_binary) + "\n"; + } else if (lines[i].find("$name") != -1) { + strnew += lines[i].replace("$name", p_binary) + "\n"; + } else if (lines[i].find("$info") != -1) { + strnew += lines[i].replace("$info", p_preset->get("application/info")) + "\n"; + } else if (lines[i].find("$identifier") != -1) { + strnew += lines[i].replace("$identifier", p_preset->get("application/identifier")) + "\n"; + } else if (lines[i].find("$short_version") != -1) { + strnew += lines[i].replace("$short_version", p_preset->get("application/short_version")) + "\n"; + } else if (lines[i].find("$version") != -1) { + strnew += lines[i].replace("$version", p_preset->get("application/version")) + "\n"; + } else if (lines[i].find("$signature") != -1) { + strnew += lines[i].replace("$signature", p_preset->get("application/signature")) + "\n"; + } else if (lines[i].find("$copyright") != -1) { + strnew += lines[i].replace("$copyright", p_preset->get("application/copyright")) + "\n"; + } else if (lines[i].find("$highres") != -1) { + strnew += lines[i].replace("$highres", p_preset->get("display/high_res") ? "<true/>" : "<false/>") + "\n"; } else { - strnew+=lines[i]+"\n"; + strnew += lines[i] + "\n"; } } CharString cs = strnew.utf8(); plist.resize(cs.size()); - for(int i=9;i<cs.size();i++) { - plist[i]=cs[i]; + for (int i = 9; i < cs.size(); i++) { + plist[i] = cs[i]; } } -Error EditorExportPlatformOSX::export_project(const String& p_path, bool p_debug, int p_flags) { +Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags) { String src_pkg; - EditorProgress ep("export","Exporting for OSX",104); - + EditorProgress ep("export", "Exporting for OSX", 104); if (p_debug) - src_pkg=custom_debug_package; + src_pkg = p_preset->get("custom_package/debug"); else - src_pkg=custom_release_package; + src_pkg = p_preset->get("custom_package/release"); - if (src_pkg=="") { + if (src_pkg == "") { String err; - src_pkg=find_export_template("osx.zip", &err); - if (src_pkg=="") { + src_pkg = find_export_template("osx.zip", &err); + if (src_pkg == "") { EditorNode::add_io_error(err); return ERR_FILE_NOT_FOUND; } } - - FileAccess *src_f=NULL; + FileAccess *src_f = NULL; zlib_filefunc_def io = zipio_create_io_from_file(&src_f); - ep.step("Creating app",0); + ep.step("Creating app", 0); unzFile pkg = unzOpen2(src_pkg.utf8().get_data(), &io); if (!pkg) { - EditorNode::add_io_error("Could not find template app to export:\n"+src_pkg); + EditorNode::add_io_error("Could not find template app to export:\n" + src_pkg); return ERR_FILE_NOT_FOUND; } ERR_FAIL_COND_V(!pkg, ERR_CANT_OPEN); int ret = unzGoToFirstFile(pkg); - zlib_filefunc_def io2=io; - FileAccess *dst_f=NULL; - io2.opaque=&dst_f; - zipFile dpkg=zipOpen2(p_path.utf8().get_data(),APPEND_STATUS_CREATE,NULL,&io2); + zlib_filefunc_def io2 = io; + FileAccess *dst_f = NULL; + io2.opaque = &dst_f; + zipFile dpkg = zipOpen2(p_path.utf8().get_data(), APPEND_STATUS_CREATE, NULL, &io2); String binary_to_use = "godot_osx_" + String(p_debug ? "debug" : "release") + "."; - binary_to_use += String(bits_mode==BITS_FAT ? "fat" : bits_mode==BITS_64 ? "64" : "32"); + int bits_mode = p_preset->get("application/bits_mode"); + binary_to_use += String(bits_mode == 0 ? "fat" : bits_mode == 1 ? "64" : "32"); - print_line("binary: "+binary_to_use); + print_line("binary: " + binary_to_use); String pkg_name; - if (app_name!="") - pkg_name=app_name; - else if (String(GlobalConfig::get_singleton()->get("application/name"))!="") - pkg_name=String(GlobalConfig::get_singleton()->get("application/name")); + if (p_preset->get("application/name") != "") + pkg_name = p_preset->get("application/name"); // app_name + else if (String(GlobalConfig::get_singleton()->get("application/name")) != "") + pkg_name = String(GlobalConfig::get_singleton()->get("application/name")); else - pkg_name="Unnamed"; - + pkg_name = "Unnamed"; bool found_binary = false; - while(ret==UNZ_OK) { + while (ret == UNZ_OK) { //get filename unz_file_info info; char fname[16384]; - ret = unzGetCurrentFileInfo(pkg,&info,fname,16384,NULL,0,NULL,0); + ret = unzGetCurrentFileInfo(pkg, &info, fname, 16384, NULL, 0, NULL, 0); - String file=fname; + String file = fname; - print_line("READ: "+file); + print_line("READ: " + file); Vector<uint8_t> data; data.resize(info.uncompressed_size); //read unzOpenCurrentFile(pkg); - unzReadCurrentFile(pkg,data.ptr(),data.size()); + unzReadCurrentFile(pkg, data.ptr(), data.size()); unzCloseCurrentFile(pkg); //write - file = file.replace_first("osx_template.app/",""); + file = file.replace_first("osx_template.app/", ""); - - if (file=="Contents/Info.plist") { + if (file == "Contents/Info.plist") { print_line("parse plist"); - _fix_plist(data,pkg_name); + _fix_plist(p_preset, data, pkg_name); } if (file.begins_with("Contents/MacOS/godot_")) { - if (file!="Contents/MacOS/"+binary_to_use) { + if (file != "Contents/MacOS/" + binary_to_use) { ret = unzGoToNextFile(pkg); continue; //ignore! } found_binary = true; - file="Contents/MacOS/"+pkg_name; + file = "Contents/MacOS/" + pkg_name; } - if (file=="Contents/Resources/icon.icns") { + if (file == "Contents/Resources/icon.icns") { //see if there is an icon - String iconpath = GlobalConfig::get_singleton()->get("application/icon"); - print_line("icon? "+iconpath); - if (iconpath!="") { - Image icon; - icon.load(iconpath); - if (!icon.empty()) { + String iconpath; + if (p_preset->get("application/icon") != "") + iconpath = p_preset->get("application/icon"); + else + iconpath = GlobalConfig::get_singleton()->get("application/icon"); + print_line("icon? " + iconpath); + if (iconpath != "") { + Ref<Image> icon; + icon.instance(); + icon->load(iconpath); + if (!icon->empty()) { print_line("loaded?"); - _make_icon(icon,data); + _make_icon(icon, data); } } //bleh? } - file=pkg_name+".app/"+file; + file = pkg_name + ".app/" + file; - if (data.size()>0) { - print_line("ADDING: "+file+" size: "+itos(data.size())); + if (data.size() > 0) { + print_line("ADDING: " + file + " size: " + itos(data.size())); zip_fileinfo fi; - fi.tmz_date.tm_hour=info.tmu_date.tm_hour; - fi.tmz_date.tm_min=info.tmu_date.tm_min; - fi.tmz_date.tm_sec=info.tmu_date.tm_sec; - fi.tmz_date.tm_mon=info.tmu_date.tm_mon; - fi.tmz_date.tm_mday=info.tmu_date.tm_mday; - fi.tmz_date.tm_year=info.tmu_date.tm_year; - fi.dosDate=info.dosDate; - fi.internal_fa=info.internal_fa; - fi.external_fa=info.external_fa; + fi.tmz_date.tm_hour = info.tmu_date.tm_hour; + fi.tmz_date.tm_min = info.tmu_date.tm_min; + fi.tmz_date.tm_sec = info.tmu_date.tm_sec; + fi.tmz_date.tm_mon = info.tmu_date.tm_mon; + fi.tmz_date.tm_mday = info.tmu_date.tm_mday; + fi.tmz_date.tm_year = info.tmu_date.tm_year; + fi.dosDate = info.dosDate; + fi.internal_fa = info.internal_fa; + fi.external_fa = info.external_fa; int err = zipOpenNewFileInZip(dpkg, - file.utf8().get_data(), - &fi, - NULL, - 0, - NULL, - 0, - NULL, - Z_DEFLATED, - Z_DEFAULT_COMPRESSION); - - print_line("OPEN ERR: "+itos(err)); - err = zipWriteInFileInZip(dpkg,data.ptr(),data.size()); - print_line("WRITE ERR: "+itos(err)); + file.utf8().get_data(), + &fi, + NULL, + 0, + NULL, + 0, + NULL, + Z_DEFLATED, + Z_DEFAULT_COMPRESSION); + + print_line("OPEN ERR: " + itos(err)); + err = zipWriteInFileInZip(dpkg, data.ptr(), data.size()); + print_line("WRITE ERR: " + itos(err)); zipCloseFileInZip(dpkg); } @@ -421,126 +325,98 @@ Error EditorExportPlatformOSX::export_project(const String& p_path, bool p_debug } if (!found_binary) { - ERR_PRINTS("Requested template binary '"+binary_to_use+"' not found. It might be missing from your template archive."); - zipClose(dpkg,NULL); + ERR_PRINTS("Requested template binary '" + binary_to_use + "' not found. It might be missing from your template archive."); + zipClose(dpkg, NULL); unzClose(pkg); return ERR_FILE_NOT_FOUND; } + ep.step("Making PKG", 1); - ep.step("Making PKG",1); - - String pack_path=EditorSettings::get_singleton()->get_settings_path()+"/tmp/data.pck"; - FileAccess *pfs = FileAccess::open(pack_path,FileAccess::WRITE); - Error err = save_pack(pfs); - memdelete(pfs); + String pack_path = EditorSettings::get_singleton()->get_settings_path() + "/tmp/data.pck"; + Error err = save_pack(p_preset, pack_path); if (err) { - zipClose(dpkg,NULL); + zipClose(dpkg, NULL); unzClose(pkg); return err; - } { //write datapack zipOpenNewFileInZip(dpkg, - (pkg_name+".app/Contents/Resources/data.pck").utf8().get_data(), - NULL, - NULL, - 0, - NULL, - 0, - NULL, - Z_DEFLATED, - Z_DEFAULT_COMPRESSION); - - - FileAccess *pf = FileAccess::open(pack_path,FileAccess::READ); - ERR_FAIL_COND_V(!pf,ERR_CANT_OPEN); + (pkg_name + ".app/Contents/Resources/data.pck").utf8().get_data(), + NULL, + NULL, + 0, + NULL, + 0, + NULL, + Z_DEFLATED, + Z_DEFAULT_COMPRESSION); + + FileAccess *pf = FileAccess::open(pack_path, FileAccess::READ); + ERR_FAIL_COND_V(!pf, ERR_CANT_OPEN); const int BSIZE = 16384; uint8_t buf[BSIZE]; - while(true) { + while (true) { - int r = pf->get_buffer(buf,BSIZE); - if (r<=0) + int r = pf->get_buffer(buf, BSIZE); + if (r <= 0) break; - zipWriteInFileInZip(dpkg,buf,r); - + zipWriteInFileInZip(dpkg, buf, r); } zipCloseFileInZip(dpkg); memdelete(pf); - } - zipClose(dpkg,NULL); + zipClose(dpkg, NULL); unzClose(pkg); return OK; } +bool EditorExportPlatformOSX::can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const { -Error EditorExportPlatformOSX::run(int p_device, int p_flags) { - - return OK; -} - - -EditorExportPlatformOSX::EditorExportPlatformOSX() { - - Image img( _osx_logo ); - logo = Ref<ImageTexture>( memnew( ImageTexture )); - logo->create_from_image(img); - - info="Made with Godot Engine"; - identifier="org.godotengine.macgame"; - signature="godotmacgame"; - short_version="1.0"; - version="1.0"; - bits_mode=BITS_FAT; - high_resolution=false; - -} - -bool EditorExportPlatformOSX::can_export(String *r_error) const { - - - bool valid=true; + bool valid = true; String err; - if (!exists_export_template("osx.zip")) { - valid=false; - err+="No export templates found.\nDownload and install export templates.\n"; + if (!exists_export_template("osx.zip", &err)) { + valid = false; } - if (custom_debug_package!="" && !FileAccess::exists(custom_debug_package)) { - valid=false; - err+="Custom debug package not found.\n"; + if (p_preset->get("custom_package/debug") != "" && !FileAccess::exists(p_preset->get("custom_package/debug"))) { + valid = false; + err += "Custom debug package not found.\n"; } - if (custom_release_package!="" && !FileAccess::exists(custom_release_package)) { - valid=false; - err+="Custom release package not found.\n"; + if (p_preset->get("custom_package/release") != "" && !FileAccess::exists(p_preset->get("custom_package/release"))) { + valid = false; + err += "Custom release package not found.\n"; } - if (r_error) - *r_error=err; + if (!err.empty()) + r_error = err; return valid; } +EditorExportPlatformOSX::EditorExportPlatformOSX() { -EditorExportPlatformOSX::~EditorExportPlatformOSX() { + Ref<Image> img = memnew(Image(_osx_logo)); + logo.instance(); + logo->create_from_image(img); +} +EditorExportPlatformOSX::~EditorExportPlatformOSX() { } -#endif void register_osx_exporter() { -#if 0 - Ref<EditorExportPlatformOSX> exporter = Ref<EditorExportPlatformOSX>( memnew(EditorExportPlatformOSX) ); - EditorImportExport::get_singleton()->add_export_platform(exporter); -#endif + Ref<EditorExportPlatformOSX> platform; + platform.instance(); + + EditorExport::get_singleton()->add_export_platform(platform); } diff --git a/platform/osx/export/export.h b/platform/osx/export/export.h index 98e63ff48e..50604f068f 100644 --- a/platform/osx/export/export.h +++ b/platform/osx/export/export.h @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/osx/godot_main_osx.mm b/platform/osx/godot_main_osx.mm index 8eedd7f6fc..0bf678f9b7 100644 --- a/platform/osx/godot_main_osx.mm +++ b/platform/osx/godot_main_osx.mm @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -26,68 +27,62 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "os_osx.h" #include "main/main.h" +#include "os_osx.h" + #include <string.h> #include <unistd.h> -//#define main godot_main - -int main(int argc, char** argv) { +int main(int argc, char **argv) { int first_arg = 1; - const char* dbg_arg = "-NSDocumentRevisionsDebugMode"; + const char *dbg_arg = "-NSDocumentRevisionsDebugMode"; printf("arguments\n"); - for (int i=0; i<argc; i++) { + for (int i = 0; i < argc; i++) { if (strcmp(dbg_arg, argv[i]) == 0) - first_arg = i+2; + first_arg = i + 2; printf("%i: %s\n", i, argv[i]); }; - - if (argc>=1 && argv[0][0]=='/') { + if (argc >= 1 && argv[0][0] == '/') { //potentially launched from finder int len = strlen(argv[0]); while (len--) { if (argv[0][len] == '/') break; } - if (len>=0) { - char *path = (char *)malloc(len+1); + if (len >= 0) { + char *path = (char *)malloc(len + 1); memcpy(path, argv[0], len); - path[len]=0; + path[len] = 0; - char *pathinfo = (char*)malloc(strlen(path)+strlen("/../Info.plist")+1); - //in real code you would check for errors in malloc here + char *pathinfo = (char *)malloc(strlen(path) + strlen("/../Info.plist") + 1); + //in real code you would check for errors in malloc here strcpy(pathinfo, path); strcat(pathinfo, "/../Info.plist"); - FILE*f=fopen(pathinfo,"rb"); + FILE *f = fopen(pathinfo, "rb"); if (f) { //running from app bundle, as Info.plist was found fclose(f); chdir(path); chdir("../Resources"); //data.pck, or just the files are here - } free(path); free(pathinfo); } - - - } OS_OSX os; - - Error err = Main::setup(argv[0],argc-first_arg,&argv[first_arg]); - if (err!=OK) + Error err = Main::setup(argv[0], argc - first_arg, &argv[first_arg]); + if (err != OK) return 255; if (Main::start()) os.run(); // it is actually the OS that decides how to run + Main::cleanup(); return 0; diff --git a/platform/osx/godot_osx.h b/platform/osx/godot_osx.h deleted file mode 100644 index b6f2b06f26..0000000000 --- a/platform/osx/godot_osx.h +++ /dev/null @@ -1,37 +0,0 @@ -/*************************************************************************/ -/* godot_osx.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* http://www.godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ -#ifndef GODOT_OSX_H -#define GODOT_OSX_H - -#import <Cocoa/Cocoa.h> - -@interface GodotMain : NSObject -@end - -#endif diff --git a/platform/osx/godot_osx.mm b/platform/osx/godot_osx.mm deleted file mode 100644 index 2296fb016f..0000000000 --- a/platform/osx/godot_osx.mm +++ /dev/null @@ -1,215 +0,0 @@ -/*************************************************************************/ -/* godot_osx.mm */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* http://www.godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ -#include <sys/param.h> /* for MAXPATHLEN */ -#include <unistd.h> -#include "godot_osx.h" - -/* For some reaon, Apple removed setAppleMenu from the headers in 10.4, - but the method still is there and works. To avoid warnings, we declare - it ourselves here. */ -@interface NSApplication() -- (void)setAppleMenu:(NSMenu *)menu; -@end - -static int global_argc; -static char **global_argv; -static BOOL gCalledAppMainline = FALSE; - -static NSString *getApplicationName(void) -{ - const NSDictionary *dict; - NSString *appName = 0; - - /* Determine the application name */ - dict = (const NSDictionary *)CFBundleGetInfoDictionary(CFBundleGetMainBundle()); - if (dict) - appName = [dict objectForKey: @"CFBundleName"]; - - if (![appName length]) - appName = [[NSProcessInfo processInfo] processName]; - - return appName; -} - -/* The main class of the application, the application's delegate */ -@implementation GodotMain - -static void setApplicationMenu(void) -{ - /* warning: this code is very odd */ - NSMenu *appleMenu; - NSMenuItem *menuItem; - NSString *title; - NSString *appName; - - appName = getApplicationName(); - appleMenu = [[NSMenu alloc] initWithTitle:@""]; - - /* Add menu items */ - title = [@"About " stringByAppendingString:appName]; - [appleMenu addItemWithTitle:title action:@selector(orderFrontStandardAboutPanel:) keyEquivalent:@""]; - - [appleMenu addItem:[NSMenuItem separatorItem]]; - - title = [@"Hide " stringByAppendingString:appName]; - [appleMenu addItemWithTitle:title action:@selector(hide:) keyEquivalent:@"h"]; - - menuItem = (NSMenuItem *)[appleMenu addItemWithTitle:@"Hide Others" action:@selector(hideOtherApplications:) keyEquivalent:@"h"]; - [menuItem setKeyEquivalentModifierMask:(NSAlternateKeyMask|NSCommandKeyMask)]; - - [appleMenu addItemWithTitle:@"Show All" action:@selector(unhideAllApplications:) keyEquivalent:@""]; - - [appleMenu addItem:[NSMenuItem separatorItem]]; - - title = [@"Quit " stringByAppendingString:appName]; - [appleMenu addItemWithTitle:title action:@selector(terminate:) keyEquivalent:@"q"]; - - - /* Put menu into the menubar */ - menuItem = [[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""]; - [menuItem setSubmenu:appleMenu]; - [[NSApp mainMenu] addItem:menuItem]; - - /* Tell the application object that this is now the application menu */ - [NSApp setAppleMenu:appleMenu]; - - /* Finally give up our references to the objects */ - [appleMenu release]; - [menuItem release]; -} - -/* Create a window menu */ -static void setupWindowMenu(void) -{ - NSMenu *windowMenu; - NSMenuItem *windowMenuItem; - NSMenuItem *menuItem; - - windowMenu = [[NSMenu alloc] initWithTitle:@"Window"]; - - /* "Minimize" item */ - menuItem = [[NSMenuItem alloc] initWithTitle:@"Minimize" action:@selector(performMiniaturize:) keyEquivalent:@"m"]; - [windowMenu addItem:menuItem]; - [menuItem release]; - - /* Put menu into the menubar */ - windowMenuItem = [[NSMenuItem alloc] initWithTitle:@"Window" action:nil keyEquivalent:@""]; - [windowMenuItem setSubmenu:windowMenu]; - [[NSApp mainMenu] addItem:windowMenuItem]; - - /* Tell the application object that this is now the window menu */ - [NSApp setWindowsMenu:windowMenu]; - - /* Finally give up our references to the objects */ - [windowMenu release]; - [windowMenuItem release]; -} - -/* Replacement for NSApplicationMain */ -static void CustomApplicationMain (int argc, char **argv) -{ - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - GodotMain *main; - - /* Ensure the application object is initialised */ - [NSApplication sharedApplication]; - - /* Set up the menubar */ - [NSApp setMainMenu:[[NSMenu alloc] init]]; - setApplicationMenu(); - setupWindowMenu(); - - main = [[main alloc] init]; - [NSApp setDelegate:main]; - - /* Start the main event loop */ - [NSApp run]; - - [main release]; - [pool release]; -} - -extern int godot_main(int argc, char** argv); - -/* Called when the internal event loop has just started running */ -- (void) applicationDidFinishLaunching: (NSNotification *) note -{ - int status; - - /* Hand off to main application code */ - gCalledAppMainline = TRUE; - - int ret = godot_main(global_argc, global_argv); - - exit(ret); -} -@end - -#ifdef main -# undef main -#endif - - -int main (int argc, char **argv) -{ - /* Copy the arguments into a global variable */ - /* This is passed if we are launched by double-clicking */ - if ( argc >= 2 && strncmp (argv[1], "-psn", 4) == 0 ) { - global_argv = (char **) malloc(sizeof (char *) * 2); - global_argv[0] = argv[0]; - global_argv[1] = NULL; - global_argc = 1; - - // chdir to binary's dir when launched from finder - int len = strlen(global_argv[0]); - - while (len--){ - if (global_argv[0][len] == '/') break; - } - - if (len>=0) { - char *path = (char *)malloc(len+1); - memcpy(path, global_argv[0], len); - path[len]=0; - printf("Path: %s\n", path); - chdir(path); - } - - } else { - int i; - global_argc = argc; - global_argv = (char **) malloc(sizeof (char *) * (argc+1)); - for (i = 0; i <= argc; i++) - global_argv[i] = argv[i]; - } - - CustomApplicationMain (argc, argv); - return 0; -} - diff --git a/platform/osx/joypad_osx.cpp b/platform/osx/joypad_osx.cpp index c2b0e1f052..1a4b3a460e 100644 --- a/platform/osx/joypad_osx.cpp +++ b/platform/osx/joypad_osx.cpp @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -458,7 +459,7 @@ static const InputDefault::JoyAxis axis_correct(int p_value, int p_min, int p_ma return jx; } -uint32_t JoypadOSX::process_joypads(uint32_t p_last_id) { +void JoypadOSX::process_joypads() { poll_joypads(); for (int i = 0; i < device_list.size(); i++) { @@ -467,17 +468,17 @@ uint32_t JoypadOSX::process_joypads(uint32_t p_last_id) { for (int j = 0; j < joy.axis_elements.size(); j++) { rec_element &elem = joy.axis_elements[j]; int value = joy.get_hid_element_state(&elem); - p_last_id = input->joy_axis(p_last_id, joy.id, j, axis_correct(value, elem.min, elem.max)); + input->joy_axis(joy.id, j, axis_correct(value, elem.min, elem.max)); } for (int j = 0; j < joy.button_elements.size(); j++) { int value = joy.get_hid_element_state(&joy.button_elements[j]); - p_last_id = input->joy_button(p_last_id, joy.id, j, (value >= 1)); + input->joy_button(joy.id, j, (value >= 1)); } for (int j = 0; j < joy.hat_elements.size(); j++) { rec_element &elem = joy.hat_elements[j]; int value = joy.get_hid_element_state(&elem); int hat_value = process_hat_value(elem.min, elem.max, value); - p_last_id = input->joy_hat(p_last_id, joy.id, hat_value); + input->joy_hat(joy.id, hat_value); } if (joy.ffservice) { @@ -494,7 +495,6 @@ uint32_t JoypadOSX::process_joypads(uint32_t p_last_id) { } } } - return p_last_id; } void JoypadOSX::joypad_vibration_start(int p_id, float p_magnitude, float p_duration, uint64_t p_timestamp) { diff --git a/platform/osx/joypad_osx.h b/platform/osx/joypad_osx.h index dabd1b8aec..bfbc523cff 100644 --- a/platform/osx/joypad_osx.h +++ b/platform/osx/joypad_osx.h @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -110,7 +111,7 @@ private: void joypad_vibration_stop(int p_id, uint64_t p_timestamp); public: - uint32_t process_joypads(uint32_t p_last_id); + void process_joypads(); void _device_added(IOReturn p_res, IOHIDDeviceRef p_device); void _device_removed(int p_id); diff --git a/platform/osx/os_osx.h b/platform/osx/os_osx.h index 2c7ad09b89..dc3e88df2c 100644 --- a/platform/osx/os_osx.h +++ b/platform/osx/os_osx.h @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -29,21 +30,21 @@ #ifndef OS_OSX_H #define OS_OSX_H +#include "drivers/alsa/audio_driver_alsa.h" +#include "drivers/rtaudio/audio_driver_rtaudio.h" #include "drivers/unix/os_unix.h" #include "joypad_osx.h" #include "main/input_default.h" #include "os/input.h" -#include "power_osx.h" -#include "servers/visual_server.h" -// #include "servers/visual/visual_server_wrap_mt.h" -#include "drivers/alsa/audio_driver_alsa.h" -#include "drivers/rtaudio/audio_driver_rtaudio.h" #include "platform/osx/audio_driver_osx.h" +#include "power_osx.h" #include "servers/audio_server.h" #include "servers/physics_2d/physics_2d_server_sw.h" #include "servers/physics_2d/physics_2d_server_wrap_mt.h" #include "servers/physics_server.h" #include "servers/visual/rasterizer.h" +#include "servers/visual/visual_server_wrap_mt.h" +#include "servers/visual_server.h" #include <ApplicationServices/ApplicationServices.h> //bitch @@ -61,7 +62,6 @@ public: List<String> args; MainLoop *main_loop; - unsigned int event_id; PhysicsServer *physics_server; Physics2DServer *physics_2d_server; @@ -83,7 +83,6 @@ public: // pthread_key_t current; bool mouse_grab; Point2 mouse_pos; - uint32_t last_id; id delegate; id window_delegate; @@ -97,6 +96,7 @@ public: CursorShape cursor_shape; MouseMode mouse_mode; + String title; bool minimized; bool maximized; bool zoomed; @@ -146,13 +146,13 @@ public: virtual void set_mouse_grab(bool p_grab); virtual bool is_mouse_grab_enabled() const; virtual void warp_mouse_pos(const Point2 &p_to); - virtual Point2 get_mouse_pos() const; + virtual Point2 get_mouse_position() const; virtual int get_mouse_button_state() const; virtual void set_window_title(const String &p_title); virtual Size2 get_window_size() const; - virtual void set_icon(const Image &p_icon); + virtual void set_icon(const Ref<Image> &p_icon); virtual MainLoop *get_main_loop() const; @@ -166,7 +166,7 @@ public: virtual void swap_buffers(); Error shell_open(String p_uri); - void push_input(const InputEvent &p_event); + void push_input(const Ref<InputEvent> &p_event); String get_locale() const; @@ -201,6 +201,9 @@ public: virtual void request_attention(); virtual String get_joy_guid(int p_device) const; + virtual void set_borderless_window(int p_borderless); + virtual bool get_borderless_window(); + virtual PowerState get_power_state(); virtual int get_power_seconds_left(); virtual int get_power_percent_left(); diff --git a/platform/osx/os_osx.mm b/platform/osx/os_osx.mm index 0699978caf..ad1e308ae0 100644 --- a/platform/osx/os_osx.mm +++ b/platform/osx/os_osx.mm @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -26,94 +27,59 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#import <Cocoa/Cocoa.h> +#include "os_osx.h" + +#include "dir_access_osx.h" +#include "drivers/gles3/rasterizer_gles3.h" +#include "main/main.h" +#include "os/keyboard.h" +#include "print_string.h" +#include "sem_osx.h" +#include "servers/physics/physics_server_sw.h" +#include "servers/visual/visual_server_raster.h" #include <Carbon/Carbon.h> -#include <IOKit/IOKitLib.h> +#import <Cocoa/Cocoa.h> #include <IOKit/IOCFPlugIn.h> -#include <IOKit/hid/IOHIDLib.h> +#include <IOKit/IOKitLib.h> #include <IOKit/hid/IOHIDKeys.h> +#include <IOKit/hid/IOHIDLib.h> -#include "sem_osx.h" -#include "servers/visual/visual_server_raster.h" -//#include "drivers/opengl/rasterizer_gl.h" -//#include "drivers/gles2/rasterizer_gles2.h" -#include "drivers/gles3/rasterizer_gles3.h" -#include "os_osx.h" +#include <fcntl.h> +#include <libproc.h> #include <stdio.h> #include <stdlib.h> -#include "print_string.h" -#include "servers/physics/physics_server_sw.h" -// #include "drivers/gles2/rasterizer_instance_gles2.h" -// #include "servers/visual/visual_server_wrap_mt.h" -#include "main/main.h" -#include "os/keyboard.h" -#include "dir_access_osx.h" - -#include <sys/types.h> #include <sys/stat.h> -#include <fcntl.h> +#include <sys/types.h> #include <unistd.h> -#include <libproc.h> -//uses portions of glfw -//======================================================================== -// GLFW 3.0 - www.glfw.org -//------------------------------------------------------------------------ -// Copyright (c) 2002-2006 Marcus Geelnard -// Copyright (c) 2006-2010 Camilla Berglund <elmindreda@elmindreda.org> -// -// This software is provided 'as-is', without any express or implied -// warranty. In no event will the authors be held liable for any damages -// arising from the use of this software. -// -// Permission is granted to anyone to use this software for any purpose, -// including commercial applications, and to alter it and redistribute it -// freely, subject to the following restrictions: -// -// 1. The origin of this software must not be misrepresented; you must not -// claim that you wrote the original software. If you use this software -// in a product, an acknowledgment in the product documentation would -// be appreciated but is not required. -// -// 2. Altered source versions must be plainly marked as such, and must not -// be misrepresented as being the original software. -// -// 3. This notice may not be removed or altered from any source -// distribution. -// -//======================================================================== +#if MAC_OS_X_VERSION_MAX_ALLOWED < 101200 +#define NSWindowStyleMaskBorderless NSBorderlessWindowMask +#endif static NSRect convertRectToBacking(NSRect contentRect) { #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 - if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6) - return [OS_OSX::singleton->window_view convertRectToBacking:contentRect]; - else + if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6) + return [OS_OSX::singleton->window_view convertRectToBacking:contentRect]; + else #endif /*MAC_OS_X_VERSION_MAX_ALLOWED*/ - return contentRect; - + return contentRect; } -static InputModifierState translateFlags(NSUInteger flags) -{ - InputModifierState mod; +static void get_key_modifier_state(unsigned int p_osx_state, Ref<InputEventWithModifiers> state) { - - mod.shift = (flags & NSShiftKeyMask); - mod.control = (flags & NSControlKeyMask); - mod.alt = (flags & NSAlternateKeyMask); - mod.meta = (flags & NSCommandKeyMask); - - return mod; + state->set_shift((p_osx_state & NSShiftKeyMask)); + state->set_control((p_osx_state & NSControlKeyMask)); + state->set_alt((p_osx_state & NSAlternateKeyMask)); + state->set_metakey((p_osx_state & NSCommandKeyMask)); } -static int mouse_x=0; -static int mouse_y=0; -static int prev_mouse_x=0; -static int prev_mouse_y=0; -static int button_mask=0; - +static int mouse_x = 0; +static int mouse_y = 0; +static int prev_mouse_x = 0; +static int prev_mouse_y = 0; +static int button_mask = 0; @interface GodotApplication : NSApplication @end @@ -123,12 +89,11 @@ static int button_mask=0; // From http://cocoadev.com/index.pl?GameKeyboardHandlingAlmost // This works around an AppKit bug, where key up events while holding // down the command key don't get sent to the key window. -- (void)sendEvent:(NSEvent *)event -{ - if ([event type] == NSKeyUp && ([event modifierFlags] & NSCommandKeyMask)) - [[self keyWindow] sendEvent:event]; - else - [super sendEvent:event]; +- (void)sendEvent:(NSEvent *)event { + if ([event type] == NSKeyUp && ([event modifierFlags] & NSCommandKeyMask)) + [[self keyWindow] sendEvent:event]; + else + [super sendEvent:event]; } @end @@ -138,45 +103,39 @@ static int button_mask=0; @implementation GodotApplicationDelegate -- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender -{ +- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender { if (OS_OSX::singleton->get_main_loop()) OS_OSX::singleton->get_main_loop()->notification(MainLoop::NOTIFICATION_WM_QUIT_REQUEST); return NSTerminateCancel; } -- (void)applicationDidHide:(NSNotification *)notification -{ +- (void)applicationDidHide:(NSNotification *)notification { /* _Godotwindow* window; for (window = _Godot.windowListHead; window; window = window->next) _GodotInputWindowVisibility(window, GL_FALSE); - */ +*/ } -- (void)applicationDidUnhide:(NSNotification *)notification -{ +- (void)applicationDidUnhide:(NSNotification *)notification { /* _Godotwindow* window; - for (window = _Godot.windowListHead; window; window = window->next) - { - if ([window_object isVisible]) - _GodotInputWindowVisibility(window, GL_TRUE); + for (window = _Godot.windowListHead; window; window = window->next) { + if ([window_object isVisible]) + _GodotInputWindowVisibility(window, GL_TRUE); } - */ +*/ } -- (void)applicationDidChangeScreenParameters:(NSNotification *) notification -{ +- (void)applicationDidChangeScreenParameters:(NSNotification *)notification { //_GodotInputMonitorChange(); } @end -@interface GodotWindowDelegate : NSObject -{ +@interface GodotWindowDelegate : NSObject { //_Godotwindow* window; } @@ -184,28 +143,22 @@ static int button_mask=0; @implementation GodotWindowDelegate - -- (BOOL)windowShouldClose:(id)sender -{ +- (BOOL)windowShouldClose:(id)sender { //_GodotInputWindowCloseRequest(window); if (OS_OSX::singleton->get_main_loop()) OS_OSX::singleton->get_main_loop()->notification(MainLoop::NOTIFICATION_WM_QUIT_REQUEST); - return NO; -} - - - -- (void)windowDidResize:(NSNotification *)notification -{ - [OS_OSX::singleton->context update]; + return NO; +} - const NSRect contentRect = [OS_OSX::singleton->window_view frame]; - const NSRect fbRect = contentRect;//convertRectToBacking(contentRect); +- (void)windowDidResize:(NSNotification *)notification { + [OS_OSX::singleton->context update]; - OS_OSX::singleton->window_size.width=fbRect.size.width*OS_OSX::singleton->display_scale; - OS_OSX::singleton->window_size.height=fbRect.size.height*OS_OSX::singleton->display_scale; + const NSRect contentRect = [OS_OSX::singleton->window_view frame]; + const NSRect fbRect = contentRect; //convertRectToBacking(contentRect); + OS_OSX::singleton->window_size.width = fbRect.size.width * OS_OSX::singleton->display_scale; + OS_OSX::singleton->window_size.height = fbRect.size.height * OS_OSX::singleton->display_scale; /* _GodotInputFramebufferSize(window, fbRect.size.width, fbRect.size.height); @@ -214,11 +167,10 @@ static int button_mask=0; if (window->cursorMode == Godot_CURSOR_DISABLED) centerCursor(window); - */ +*/ } -- (void)windowDidMove:(NSNotification *)notification -{ +- (void)windowDidMove:(NSNotification *)notification { /* [window->nsgl.context update]; @@ -228,35 +180,30 @@ static int button_mask=0; if (window->cursorMode == Godot_CURSOR_DISABLED) centerCursor(window); - */ +*/ } -- (void)windowDidBecomeKey:(NSNotification *)notification -{ +- (void)windowDidBecomeKey:(NSNotification *)notification { //_GodotInputWindowFocus(window, GL_TRUE); //_GodotPlatformSetCursorMode(window, window->cursorMode); if (OS_OSX::singleton->get_main_loop()) OS_OSX::singleton->get_main_loop()->notification(MainLoop::NOTIFICATION_WM_FOCUS_IN); } -- (void)windowDidResignKey:(NSNotification *)notification -{ +- (void)windowDidResignKey:(NSNotification *)notification { //_GodotInputWindowFocus(window, GL_FALSE); //_GodotPlatformSetCursorMode(window, Godot_CURSOR_NORMAL); if (OS_OSX::singleton->get_main_loop()) OS_OSX::singleton->get_main_loop()->notification(MainLoop::NOTIFICATION_WM_FOCUS_OUT); } -- (void)windowDidMiniaturize:(NSNotification*)notification -{ +- (void)windowDidMiniaturize:(NSNotification *)notification { OS_OSX::singleton->wm_minimized(true); if (OS_OSX::singleton->get_main_loop()) OS_OSX::singleton->get_main_loop()->notification(MainLoop::NOTIFICATION_WM_FOCUS_OUT); }; -- (void)windowDidDeminiaturize:(NSNotification*)notification -{ - +- (void)windowDidDeminiaturize:(NSNotification *)notification { OS_OSX::singleton->wm_minimized(false); if (OS_OSX::singleton->get_main_loop()) OS_OSX::singleton->get_main_loop()->notification(MainLoop::NOTIFICATION_WM_FOCUS_IN); @@ -264,659 +211,554 @@ static int button_mask=0; @end -@interface GodotContentView : NSView -{ - NSTrackingArea* trackingArea; +@interface GodotContentView : NSView { + NSTrackingArea *trackingArea; } - - @end @implementation GodotContentView -+ (void)initialize -{ - if (self == [GodotContentView class]) - { - /* - if (_glfw.ns.cursor == nil) - { - NSImage* data = [[NSImage alloc] initWithSize:NSMakeSize(1, 1)]; - _glfw.ns.cursor = [[NSCursor alloc] initWithImage:data - hotSpot:NSZeroPoint]; - [data release]; - } - */ ++ (void)initialize { + if (self == [GodotContentView class]) { + // nothing left to do here at the moment.. } } -- (id)init -{ - self = [super init]; - trackingArea = nil; - [self updateTrackingAreas]; - [self registerForDraggedTypes:[NSArray arrayWithObject:NSFilenamesPboardType]]; - return self; +- (id)init { + self = [super init]; + trackingArea = nil; + [self updateTrackingAreas]; + [self registerForDraggedTypes:[NSArray arrayWithObject:NSFilenamesPboardType]]; + return self; } - --(void)dealloc -{ - [trackingArea release]; - [super dealloc]; +- (void)dealloc { + [trackingArea release]; + [super dealloc]; } -- (NSDragOperation)draggingEntered:(id < NSDraggingInfo >)sender { - return NSDragOperationCopy; +- (NSDragOperation)draggingEntered:(id<NSDraggingInfo>)sender { + return NSDragOperationCopy; } - (NSDragOperation)draggingUpdated:(id<NSDraggingInfo>)sender { - return NSDragOperationCopy; + return NSDragOperationCopy; } - (BOOL)performDragOperation:(id<NSDraggingInfo>)sender { + NSPasteboard *pboard = [sender draggingPasteboard]; + NSArray *filenames = [pboard propertyListForType:NSFilenamesPboardType]; + + Vector<String> files; + for (int i = 0; i < filenames.count; i++) { + NSString *ns = [filenames objectAtIndex:i]; + char *utfs = strdup([ns UTF8String]); + String ret; + ret.parse_utf8(utfs); + free(utfs); + files.push_back(ret); + } - NSPasteboard *pboard = [sender draggingPasteboard]; - NSArray *filenames = [pboard propertyListForType:NSFilenamesPboardType]; - - Vector<String> files; - for(int i=0;i<filenames.count;i++) { - NSString *ns = [filenames objectAtIndex:i]; - char *utfs = strdup([ns UTF8String]); - String ret; - ret.parse_utf8(utfs); - free(utfs); - files.push_back(ret); - - - } - - if (files.size()) { - OS_OSX::singleton->main_loop->drop_files(files,0); - OS_OSX::singleton->move_window_to_foreground(); - } + if (files.size()) { + OS_OSX::singleton->main_loop->drop_files(files, 0); + OS_OSX::singleton->move_window_to_foreground(); + } - return NO; + return NO; } - -- (BOOL)isOpaque -{ - return YES; +- (BOOL)isOpaque { + return YES; } -- (BOOL)canBecomeKeyView -{ - return YES; +- (BOOL)canBecomeKeyView { + return YES; } -- (BOOL)acceptsFirstResponder -{ - return YES; +- (BOOL)acceptsFirstResponder { + return YES; } -- (void)cursorUpdate:(NSEvent *)event -{ - // setModeCursor(window, window->cursorMode); +- (void)cursorUpdate:(NSEvent *)event { + //setModeCursor(window, window->cursorMode); } -- (void)mouseDown:(NSEvent *)event -{ +- (void)mouseDown:(NSEvent *)event { - //print_line("mouse down:"); - button_mask|=BUTTON_MASK_LEFT; - InputEvent ev; - ev.type=InputEvent::MOUSE_BUTTON; - ev.mouse_button.button_index=BUTTON_LEFT; - ev.mouse_button.pressed=true; - ev.mouse_button.x=mouse_x; - ev.mouse_button.y=mouse_y; - ev.mouse_button.global_x=mouse_x; - ev.mouse_button.global_y=mouse_y; - ev.mouse_button.button_mask=button_mask; - ev.mouse_button.doubleclick = [event clickCount]==2; - ev.mouse_button.mod = translateFlags([event modifierFlags]); - OS_OSX::singleton->push_input(ev); + button_mask |= BUTTON_MASK_LEFT; + Ref<InputEventMouseButton> mb; + mb.instance(); - /* _glfwInputMouseClick(window, - GLFW_MOUSE_BUTTON_LEFT, - GLFW_PRESS, - translateFlags([event modifierFlags]));*/ + get_key_modifier_state([event modifierFlags], mb); + mb->set_button_index(BUTTON_LEFT); + mb->set_pressed(true); + mb->set_position(Vector2(mouse_x, mouse_y)); + mb->set_global_position(Vector2(mouse_x, mouse_y)); + mb->set_button_mask(button_mask); + mb->set_doubleclick([event clickCount] == 2); + OS_OSX::singleton->push_input(mb); } -- (void)mouseDragged:(NSEvent *)event -{ - [self mouseMoved:event]; +- (void)mouseDragged:(NSEvent *)event { + [self mouseMoved:event]; } -- (void)mouseUp:(NSEvent *)event -{ +- (void)mouseUp:(NSEvent *)event { - button_mask&=~BUTTON_MASK_LEFT; - InputEvent ev; - ev.type=InputEvent::MOUSE_BUTTON; - ev.mouse_button.button_index=BUTTON_LEFT; - ev.mouse_button.pressed=false; - ev.mouse_button.x=mouse_x; - ev.mouse_button.y=mouse_y; - ev.mouse_button.global_x=mouse_x; - ev.mouse_button.global_y=mouse_y; - ev.mouse_button.button_mask=button_mask; - ev.mouse_button.mod = translateFlags([event modifierFlags]); - OS_OSX::singleton->push_input(ev); + button_mask &= ~BUTTON_MASK_LEFT; + Ref<InputEventMouseButton> mb; + mb.instance(); - /* _glfwInputMouseClick(window, - GLFW_MOUSE_BUTTON_LEFT, - GLFW_RELEASE, - translateFlags([event modifierFlags]));*/ + get_key_modifier_state([event modifierFlags], mb); + mb->set_button_index(BUTTON_LEFT); + mb->set_pressed(false); + mb->set_position(Vector2(mouse_x, mouse_y)); + mb->set_global_position(Vector2(mouse_x, mouse_y)); + mb->set_button_mask(button_mask); + mb->set_doubleclick([event clickCount] == 2); + OS_OSX::singleton->push_input(mb); } -- (void)mouseMoved:(NSEvent *)event -{ +- (void)mouseMoved:(NSEvent *)event { + + Ref<InputEventMouseMotion> mm; + mm.instance(); - InputEvent ev; - ev.type=InputEvent::MOUSE_MOTION; - ev.mouse_motion.button_mask=button_mask; - prev_mouse_x=mouse_x; - prev_mouse_y=mouse_y; + mm->set_button_mask(button_mask); + prev_mouse_x = mouse_x; + prev_mouse_y = mouse_y; const NSRect contentRect = [OS_OSX::singleton->window_view frame]; const NSPoint p = [event locationInWindow]; mouse_x = p.x * OS_OSX::singleton->_mouse_scale([[event window] backingScaleFactor]); mouse_y = (contentRect.size.height - p.y) * OS_OSX::singleton->_mouse_scale([[event window] backingScaleFactor]); - ev.mouse_motion.x=mouse_x; - ev.mouse_motion.y=mouse_y; - ev.mouse_motion.global_x=mouse_x; - ev.mouse_motion.global_y=mouse_y; - ev.mouse_motion.relative_x=[event deltaX] * OS_OSX::singleton->_mouse_scale([[event window] backingScaleFactor]); - ev.mouse_motion.relative_y=[event deltaY] * OS_OSX::singleton->_mouse_scale([[event window] backingScaleFactor]); - ev.mouse_motion.mod = translateFlags([event modifierFlags]); - - OS_OSX::singleton->input->set_mouse_pos(Point2(mouse_x,mouse_y)); - OS_OSX::singleton->push_input(ev); - - - /* if (window->cursorMode == GLFW_CURSOR_DISABLED) - _glfwInputCursorMotion(window, [event deltaX], [event deltaY]); - else - { - const NSRect contentRect = [window->ns.view frame]; - const NSPoint p = [event locationInWindow]; + mm->set_position(Vector2(mouse_x, mouse_y)); + mm->set_global_position(Vector2(mouse_x, mouse_y)); + Vector2 relativeMotion = Vector2(); + relativeMotion.x = [event deltaX] * OS_OSX::singleton->_mouse_scale([[event window] backingScaleFactor]); + relativeMotion.y = [event deltaY] * OS_OSX::singleton->_mouse_scale([[event window] backingScaleFactor]); + mm->set_relative(relativeMotion); + get_key_modifier_state([event modifierFlags], mm); - _glfwInputCursorMotion(window, p.x, contentRect.size.height - p.y); - }*/ + OS_OSX::singleton->input->set_mouse_position(Point2(mouse_x, mouse_y)); + OS_OSX::singleton->push_input(mm); } -- (void)rightMouseDown:(NSEvent *)event -{ +- (void)rightMouseDown:(NSEvent *)event { + + button_mask |= BUTTON_MASK_RIGHT; - button_mask|=BUTTON_MASK_RIGHT; - InputEvent ev; - ev.type=InputEvent::MOUSE_BUTTON; - ev.mouse_button.button_index=BUTTON_RIGHT; - ev.mouse_button.pressed=true; - ev.mouse_button.x=mouse_x; - ev.mouse_button.y=mouse_y; - ev.mouse_button.global_x=mouse_x; - ev.mouse_button.global_y=mouse_y; - ev.mouse_button.button_mask=button_mask; - ev.mouse_button.mod = translateFlags([event modifierFlags]); - OS_OSX::singleton->push_input(ev); + Ref<InputEventMouseButton> mb; + mb.instance(); - /* _glfwInputMouseClick(window, - GLFW_MOUSE_BUTTON_RIGHT, - GLFW_PRESS, - translateFlags([event modifierFlags]));*/ + get_key_modifier_state([event modifierFlags], mb); + mb->set_button_index(BUTTON_RIGHT); + mb->set_pressed(true); + mb->set_position(Vector2(mouse_x, mouse_y)); + mb->set_global_position(Vector2(mouse_x, mouse_y)); + mb->set_button_mask(button_mask); + mb->set_doubleclick([event clickCount] == 2); + OS_OSX::singleton->push_input(mb); } -- (void)rightMouseDragged:(NSEvent *)event -{ - [self mouseMoved:event]; +- (void)rightMouseDragged:(NSEvent *)event { + [self mouseMoved:event]; } -- (void)rightMouseUp:(NSEvent *)event -{ +- (void)rightMouseUp:(NSEvent *)event { + + button_mask &= ~BUTTON_MASK_RIGHT; - button_mask&=~BUTTON_MASK_RIGHT; - InputEvent ev; - ev.type=InputEvent::MOUSE_BUTTON; - ev.mouse_button.button_index=BUTTON_RIGHT; - ev.mouse_button.pressed=false; - ev.mouse_button.x=mouse_x; - ev.mouse_button.y=mouse_y; - ev.mouse_button.global_x=mouse_x; - ev.mouse_button.global_y=mouse_y; - ev.mouse_button.button_mask=button_mask; - ev.mouse_button.mod = translateFlags([event modifierFlags]); - OS_OSX::singleton->push_input(ev); + Ref<InputEventMouseButton> mb; + mb.instance(); - /*_glfwInputMouseClick(window, - GLFW_MOUSE_BUTTON_RIGHT, - GLFW_RELEASE, - translateFlags([event modifierFlags]));*/ + get_key_modifier_state([event modifierFlags], mb); + mb->set_button_index(BUTTON_RIGHT); + mb->set_pressed(false); + mb->set_position(Vector2(mouse_x, mouse_y)); + mb->set_global_position(Vector2(mouse_x, mouse_y)); + mb->set_button_mask(button_mask); + mb->set_doubleclick([event clickCount] == 2); + OS_OSX::singleton->push_input(mb); } -- (void)otherMouseDown:(NSEvent *)event -{ +- (void)otherMouseDown:(NSEvent *)event { - if ((int) [event buttonNumber]!=2) + if ((int)[event buttonNumber] != 2) return; - button_mask|=BUTTON_MASK_MIDDLE; - InputEvent ev; - ev.type=InputEvent::MOUSE_BUTTON; - ev.mouse_button.button_index=BUTTON_MIDDLE; - ev.mouse_button.pressed=true; - ev.mouse_button.x=mouse_x; - ev.mouse_button.y=mouse_y; - ev.mouse_button.global_x=mouse_x; - ev.mouse_button.global_y=mouse_y; - ev.mouse_button.button_mask=button_mask; - ev.mouse_button.mod = translateFlags([event modifierFlags]); - OS_OSX::singleton->push_input(ev); + button_mask |= BUTTON_MASK_MIDDLE; - /*_glfwInputMouseClick(window, - (int) [event buttonNumber], - GLFW_PRESS, - translateFlags([event modifierFlags]));*/ + Ref<InputEventMouseButton> mb; + mb.instance(); + + get_key_modifier_state([event modifierFlags], mb); + mb->set_button_index(BUTTON_MIDDLE); + mb->set_pressed(true); + mb->set_position(Vector2(mouse_x, mouse_y)); + mb->set_global_position(Vector2(mouse_x, mouse_y)); + mb->set_button_mask(button_mask); + mb->set_doubleclick([event clickCount] == 2); + OS_OSX::singleton->push_input(mb); } -- (void)otherMouseDragged:(NSEvent *)event -{ - [self mouseMoved:event]; +- (void)otherMouseDragged:(NSEvent *)event { + [self mouseMoved:event]; } -- (void)otherMouseUp:(NSEvent *)event -{ +- (void)otherMouseUp:(NSEvent *)event { - if ((int) [event buttonNumber]!=2) + if ((int)[event buttonNumber] != 2) return; - button_mask&=~BUTTON_MASK_MIDDLE; - InputEvent ev; - ev.type=InputEvent::MOUSE_BUTTON; - ev.mouse_button.button_index=BUTTON_MIDDLE; - ev.mouse_button.pressed=false; - ev.mouse_button.x=mouse_x; - ev.mouse_button.y=mouse_y; - ev.mouse_button.global_x=mouse_x; - ev.mouse_button.global_y=mouse_y; - ev.mouse_button.button_mask=button_mask; - ev.mouse_button.mod = translateFlags([event modifierFlags]); - OS_OSX::singleton->push_input(ev); - /* _glfwInputMouseClick(window, - (int) [event buttonNumber], - GLFW_RELEASE, - translateFlags([event modifierFlags]));*/ -} - -- (void)mouseExited:(NSEvent *)event -{ + button_mask &= ~BUTTON_MASK_MIDDLE; + + Ref<InputEventMouseButton> mb; + mb.instance(); + + get_key_modifier_state([event modifierFlags], mb); + mb->set_button_index(BUTTON_MIDDLE); + mb->set_pressed(false); + mb->set_position(Vector2(mouse_x, mouse_y)); + mb->set_global_position(Vector2(mouse_x, mouse_y)); + mb->set_button_mask(button_mask); + mb->set_doubleclick([event clickCount] == 2); + OS_OSX::singleton->push_input(mb); +} + +- (void)mouseExited:(NSEvent *)event { if (!OS_OSX::singleton) return; - if (OS_OSX::singleton->main_loop && OS_OSX::singleton->mouse_mode!=OS::MOUSE_MODE_CAPTURED) + if (OS_OSX::singleton->main_loop && OS_OSX::singleton->mouse_mode != OS::MOUSE_MODE_CAPTURED) OS_OSX::singleton->main_loop->notification(MainLoop::NOTIFICATION_WM_MOUSE_EXIT); if (OS_OSX::singleton->input) OS_OSX::singleton->input->set_mouse_in_window(false); - // _glfwInputCursorEnter(window, GL_FALSE); } -- (void)mouseEntered:(NSEvent *)event -{ - // _glfwInputCursorEnter(window, GL_TRUE); +- (void)mouseEntered:(NSEvent *)event { if (!OS_OSX::singleton) return; - if (OS_OSX::singleton->main_loop && OS_OSX::singleton->mouse_mode!=OS::MOUSE_MODE_CAPTURED) + if (OS_OSX::singleton->main_loop && OS_OSX::singleton->mouse_mode != OS::MOUSE_MODE_CAPTURED) OS_OSX::singleton->main_loop->notification(MainLoop::NOTIFICATION_WM_MOUSE_ENTER); if (OS_OSX::singleton->input) OS_OSX::singleton->input->set_mouse_in_window(true); - } -- (void)viewDidChangeBackingProperties -{ - /* const NSRect contentRect = [window->ns.view frame]; - const NSRect fbRect = convertRectToBacking(window, contentRect); - - _glfwInputFramebufferSize(window, fbRect.size.width, fbRect.size.height);*/ +- (void)viewDidChangeBackingProperties { + // nothing left to do here } -- (void)updateTrackingAreas -{ - if (trackingArea != nil) - { - [self removeTrackingArea:trackingArea]; - [trackingArea release]; - } +- (void)updateTrackingAreas { + if (trackingArea != nil) { + [self removeTrackingArea:trackingArea]; + [trackingArea release]; + } - NSTrackingAreaOptions options = NSTrackingMouseEnteredAndExited | - NSTrackingActiveInKeyWindow | - NSTrackingCursorUpdate | - NSTrackingInVisibleRect; + NSTrackingAreaOptions options = + NSTrackingMouseEnteredAndExited | + NSTrackingActiveInKeyWindow | + NSTrackingCursorUpdate | + NSTrackingInVisibleRect; - trackingArea = [[NSTrackingArea alloc] initWithRect:[self bounds] - options:options - owner:self - userInfo:nil]; + trackingArea = [[NSTrackingArea alloc] + initWithRect:[self bounds] + options:options + owner:self + userInfo:nil]; - [self addTrackingArea:trackingArea]; - [super updateTrackingAreas]; + [self addTrackingArea:trackingArea]; + [super updateTrackingAreas]; } // Translates a OS X keycode to a Godot keycode // -static int translateKey(unsigned int key) -{ - // Keyboard symbol translation table - static const unsigned int table[128] = - { - /* 00 */ KEY_A, - /* 01 */ KEY_S, - /* 02 */ KEY_D, - /* 03 */ KEY_F, - /* 04 */ KEY_H, - /* 05 */ KEY_G, - /* 06 */ KEY_Z, - /* 07 */ KEY_X, - /* 08 */ KEY_C, - /* 09 */ KEY_V, - /* 0a */ KEY_UNKNOWN, - /* 0b */ KEY_B, - /* 0c */ KEY_Q, - /* 0d */ KEY_W, - /* 0e */ KEY_E, - /* 0f */ KEY_R, - /* 10 */ KEY_Y, - /* 11 */ KEY_T, - /* 12 */ KEY_1, - /* 13 */ KEY_2, - /* 14 */ KEY_3, - /* 15 */ KEY_4, - /* 16 */ KEY_6, - /* 17 */ KEY_5, - /* 18 */ KEY_EQUAL, - /* 19 */ KEY_9, - /* 1a */ KEY_7, - /* 1b */ KEY_MINUS, - /* 1c */ KEY_8, - /* 1d */ KEY_0, - /* 1e */ KEY_BRACERIGHT, - /* 1f */ KEY_O, - /* 20 */ KEY_U, - /* 21 */ KEY_BRACELEFT, - /* 22 */ KEY_I, - /* 23 */ KEY_P, - /* 24 */ KEY_RETURN, - /* 25 */ KEY_L, - /* 26 */ KEY_J, - /* 27 */ KEY_APOSTROPHE, - /* 28 */ KEY_K, - /* 29 */ KEY_SEMICOLON, - /* 2a */ KEY_BACKSLASH, - /* 2b */ KEY_COMMA, - /* 2c */ KEY_SLASH, - /* 2d */ KEY_N, - /* 2e */ KEY_M, - /* 2f */ KEY_PERIOD, - /* 30 */ KEY_TAB, - /* 31 */ KEY_SPACE, - /* 32 */ KEY_QUOTELEFT, - /* 33 */ KEY_BACKSPACE, - /* 34 */ KEY_UNKNOWN, - /* 35 */ KEY_ESCAPE, - /* 36 */ KEY_META, - /* 37 */ KEY_META, - /* 38 */ KEY_SHIFT, - /* 39 */ KEY_CAPSLOCK, - /* 3a */ KEY_ALT, - /* 3b */ KEY_CONTROL, - /* 3c */ KEY_SHIFT, - /* 3d */ KEY_ALT, - /* 3e */ KEY_CONTROL, - /* 3f */ KEY_UNKNOWN, /* Function */ - /* 40 */ KEY_UNKNOWN, - /* 41 */ KEY_KP_PERIOD, - /* 42 */ KEY_UNKNOWN, - /* 43 */ KEY_KP_MULTIPLY, - /* 44 */ KEY_UNKNOWN, - /* 45 */ KEY_KP_ADD, - /* 46 */ KEY_UNKNOWN, - /* 47 */ KEY_NUMLOCK, /* Really KeypadClear... */ - /* 48 */ KEY_UNKNOWN, /* VolumeUp */ - /* 49 */ KEY_UNKNOWN, /* VolumeDown */ - /* 4a */ KEY_UNKNOWN, /* Mute */ - /* 4b */ KEY_KP_DIVIDE, - /* 4c */ KEY_KP_ENTER, - /* 4d */ KEY_UNKNOWN, - /* 4e */ KEY_KP_SUBTRACT, - /* 4f */ KEY_UNKNOWN, - /* 50 */ KEY_UNKNOWN, - /* 51 */ KEY_EQUAL, //wtf equal? - /* 52 */ KEY_KP_0, - /* 53 */ KEY_KP_1, - /* 54 */ KEY_KP_2, - /* 55 */ KEY_KP_3, - /* 56 */ KEY_KP_4, - /* 57 */ KEY_KP_5, - /* 58 */ KEY_KP_6, - /* 59 */ KEY_KP_7, - /* 5a */ KEY_UNKNOWN, - /* 5b */ KEY_KP_8, - /* 5c */ KEY_KP_9, - /* 5d */ KEY_UNKNOWN, - /* 5e */ KEY_UNKNOWN, - /* 5f */ KEY_UNKNOWN, - /* 60 */ KEY_F5, - /* 61 */ KEY_F6, - /* 62 */ KEY_F7, - /* 63 */ KEY_F3, - /* 64 */ KEY_F8, - /* 65 */ KEY_F9, - /* 66 */ KEY_UNKNOWN, - /* 67 */ KEY_F11, - /* 68 */ KEY_UNKNOWN, - /* 69 */ KEY_F13, - /* 6a */ KEY_F16, - /* 6b */ KEY_F14, - /* 6c */ KEY_UNKNOWN, - /* 6d */ KEY_F10, - /* 6e */ KEY_UNKNOWN, - /* 6f */ KEY_F12, - /* 70 */ KEY_UNKNOWN, - /* 71 */ KEY_F15, - /* 72 */ KEY_INSERT, /* Really Help... */ - /* 73 */ KEY_HOME, - /* 74 */ KEY_PAGEUP, - /* 75 */ KEY_DELETE, - /* 76 */ KEY_F4, - /* 77 */ KEY_END, - /* 78 */ KEY_F2, - /* 79 */ KEY_PAGEDOWN, - /* 7a */ KEY_F1, - /* 7b */ KEY_LEFT, - /* 7c */ KEY_RIGHT, - /* 7d */ KEY_DOWN, - /* 7e */ KEY_UP, - /* 7f */ KEY_UNKNOWN, - }; - - if (key >= 128) - return KEY_UNKNOWN; - - return table[key]; -} -- (void)keyDown:(NSEvent *)event -{ - InputEvent ev; - ev.type=InputEvent::KEY; - ev.key.pressed=true; - ev.key.mod=translateFlags([event modifierFlags]); - ev.key.scancode = latin_keyboard_keycode_convert(translateKey([event keyCode])); - ev.key.echo = [event isARepeat]; - - NSString* characters = [event characters]; - NSUInteger i, length = [characters length]; - - - if (length>0 && keycode_has_unicode(ev.key.scancode)) { - - - for (i = 0; i < length; i++) { - ev.key.unicode=[characters characterAtIndex:i]; - OS_OSX::singleton->push_input(ev); - ev.key.scancode=0; - } +static int translateKey(unsigned int key) { + // Keyboard symbol translation table + static const unsigned int table[128] = { + /* 00 */ KEY_A, + /* 01 */ KEY_S, + /* 02 */ KEY_D, + /* 03 */ KEY_F, + /* 04 */ KEY_H, + /* 05 */ KEY_G, + /* 06 */ KEY_Z, + /* 07 */ KEY_X, + /* 08 */ KEY_C, + /* 09 */ KEY_V, + /* 0a */ KEY_UNKNOWN, + /* 0b */ KEY_B, + /* 0c */ KEY_Q, + /* 0d */ KEY_W, + /* 0e */ KEY_E, + /* 0f */ KEY_R, + /* 10 */ KEY_Y, + /* 11 */ KEY_T, + /* 12 */ KEY_1, + /* 13 */ KEY_2, + /* 14 */ KEY_3, + /* 15 */ KEY_4, + /* 16 */ KEY_6, + /* 17 */ KEY_5, + /* 18 */ KEY_EQUAL, + /* 19 */ KEY_9, + /* 1a */ KEY_7, + /* 1b */ KEY_MINUS, + /* 1c */ KEY_8, + /* 1d */ KEY_0, + /* 1e */ KEY_BRACERIGHT, + /* 1f */ KEY_O, + /* 20 */ KEY_U, + /* 21 */ KEY_BRACELEFT, + /* 22 */ KEY_I, + /* 23 */ KEY_P, + /* 24 */ KEY_RETURN, + /* 25 */ KEY_L, + /* 26 */ KEY_J, + /* 27 */ KEY_APOSTROPHE, + /* 28 */ KEY_K, + /* 29 */ KEY_SEMICOLON, + /* 2a */ KEY_BACKSLASH, + /* 2b */ KEY_COMMA, + /* 2c */ KEY_SLASH, + /* 2d */ KEY_N, + /* 2e */ KEY_M, + /* 2f */ KEY_PERIOD, + /* 30 */ KEY_TAB, + /* 31 */ KEY_SPACE, + /* 32 */ KEY_QUOTELEFT, + /* 33 */ KEY_BACKSPACE, + /* 34 */ KEY_UNKNOWN, + /* 35 */ KEY_ESCAPE, + /* 36 */ KEY_META, + /* 37 */ KEY_META, + /* 38 */ KEY_SHIFT, + /* 39 */ KEY_CAPSLOCK, + /* 3a */ KEY_ALT, + /* 3b */ KEY_CONTROL, + /* 3c */ KEY_SHIFT, + /* 3d */ KEY_ALT, + /* 3e */ KEY_CONTROL, + /* 3f */ KEY_UNKNOWN, /* Function */ + /* 40 */ KEY_UNKNOWN, + /* 41 */ KEY_KP_PERIOD, + /* 42 */ KEY_UNKNOWN, + /* 43 */ KEY_KP_MULTIPLY, + /* 44 */ KEY_UNKNOWN, + /* 45 */ KEY_KP_ADD, + /* 46 */ KEY_UNKNOWN, + /* 47 */ KEY_NUMLOCK, /* Really KeypadClear... */ + /* 48 */ KEY_UNKNOWN, /* VolumeUp */ + /* 49 */ KEY_UNKNOWN, /* VolumeDown */ + /* 4a */ KEY_UNKNOWN, /* Mute */ + /* 4b */ KEY_KP_DIVIDE, + /* 4c */ KEY_KP_ENTER, + /* 4d */ KEY_UNKNOWN, + /* 4e */ KEY_KP_SUBTRACT, + /* 4f */ KEY_UNKNOWN, + /* 50 */ KEY_UNKNOWN, + /* 51 */ KEY_EQUAL, //wtf equal? + /* 52 */ KEY_KP_0, + /* 53 */ KEY_KP_1, + /* 54 */ KEY_KP_2, + /* 55 */ KEY_KP_3, + /* 56 */ KEY_KP_4, + /* 57 */ KEY_KP_5, + /* 58 */ KEY_KP_6, + /* 59 */ KEY_KP_7, + /* 5a */ KEY_UNKNOWN, + /* 5b */ KEY_KP_8, + /* 5c */ KEY_KP_9, + /* 5d */ KEY_UNKNOWN, + /* 5e */ KEY_UNKNOWN, + /* 5f */ KEY_UNKNOWN, + /* 60 */ KEY_F5, + /* 61 */ KEY_F6, + /* 62 */ KEY_F7, + /* 63 */ KEY_F3, + /* 64 */ KEY_F8, + /* 65 */ KEY_F9, + /* 66 */ KEY_UNKNOWN, + /* 67 */ KEY_F11, + /* 68 */ KEY_UNKNOWN, + /* 69 */ KEY_F13, + /* 6a */ KEY_F16, + /* 6b */ KEY_F14, + /* 6c */ KEY_UNKNOWN, + /* 6d */ KEY_F10, + /* 6e */ KEY_UNKNOWN, + /* 6f */ KEY_F12, + /* 70 */ KEY_UNKNOWN, + /* 71 */ KEY_F15, + /* 72 */ KEY_INSERT, /* Really Help... */ + /* 73 */ KEY_HOME, + /* 74 */ KEY_PAGEUP, + /* 75 */ KEY_DELETE, + /* 76 */ KEY_F4, + /* 77 */ KEY_END, + /* 78 */ KEY_F2, + /* 79 */ KEY_PAGEDOWN, + /* 7a */ KEY_F1, + /* 7b */ KEY_LEFT, + /* 7c */ KEY_RIGHT, + /* 7d */ KEY_DOWN, + /* 7e */ KEY_UP, + /* 7f */ KEY_UNKNOWN, + }; + + if (key >= 128) + return KEY_UNKNOWN; + + return table[key]; +} + +- (void)keyDown:(NSEvent *)event { - } else { - OS_OSX::singleton->push_input(ev); - } + Ref<InputEventKey> k; + k.instance(); + + get_key_modifier_state([event modifierFlags], k); + k->set_pressed(true); + k->set_scancode(latin_keyboard_keycode_convert(translateKey([event keyCode]))); + k->set_echo([event isARepeat]); + + NSString *characters = [event characters]; + NSUInteger i, length = [characters length]; + + if (length > 0 && keycode_has_unicode(k->get_scancode())) { + for (i = 0; i < length; i++) { + k->set_unicode([characters characterAtIndex:i]); + OS_OSX::singleton->push_input(k); + k->set_scancode(0); + } + } else { + OS_OSX::singleton->push_input(k); + } } -- (void)flagsChanged:(NSEvent *)event -{ - InputEvent ev; +- (void)flagsChanged:(NSEvent *)event { + Ref<InputEventKey> k; + k.instance(); + int key = [event keyCode]; int mod = [event modifierFlags]; - ev.type=InputEvent::KEY; - if (key == 0x36 || key == 0x37) { if (mod & NSCommandKeyMask) { - mod&= ~NSCommandKeyMask; - ev.key.pressed = true; + mod &= ~NSCommandKeyMask; + k->set_pressed(true); } else { - ev.key.pressed = false; + k->set_pressed(false); } } else if (key == 0x38 || key == 0x3c) { if (mod & NSShiftKeyMask) { - mod&= ~NSShiftKeyMask; - ev.key.pressed = true; + mod &= ~NSShiftKeyMask; + k->set_pressed(true); } else { - ev.key.pressed = false; + k->set_pressed(false); } } else if (key == 0x3a || key == 0x3d) { if (mod & NSAlternateKeyMask) { - mod&= ~NSAlternateKeyMask; - ev.key.pressed = true; + mod &= ~NSAlternateKeyMask; + k->set_pressed(true); } else { - ev.key.pressed = false; + k->set_pressed(false); } } else if (key == 0x3b || key == 0x3e) { if (mod & NSControlKeyMask) { - mod&= ~NSControlKeyMask; - ev.key.pressed = true; + mod &= ~NSControlKeyMask; + k->set_pressed(true); } else { - ev.key.pressed = false; + k->set_pressed(false); } } else { return; } - ev.key.mod=translateFlags(mod); - ev.key.scancode = latin_keyboard_keycode_convert(translateKey(key)); + get_key_modifier_state(mod, k); + k->set_scancode(latin_keyboard_keycode_convert(translateKey(key))); - OS_OSX::singleton->push_input(ev); + OS_OSX::singleton->push_input(k); } -- (void)keyUp:(NSEvent *)event -{ +- (void)keyUp:(NSEvent *)event { - InputEvent ev; - ev.type=InputEvent::KEY; - ev.key.pressed=false; - ev.key.mod=translateFlags([event modifierFlags]); - ev.key.scancode = latin_keyboard_keycode_convert(translateKey([event keyCode])); - OS_OSX::singleton->push_input(ev); + Ref<InputEventKey> k; + k.instance(); + get_key_modifier_state([event modifierFlags], k); + k->set_pressed(false); + k->set_scancode(latin_keyboard_keycode_convert(translateKey([event keyCode]))); - /* const int key = translateKey([event keyCode]); - const int mods = translateFlags([event modifierFlags]); - _glfwInputKey(window, key, [event keyCode], GLFW_RELEASE, mods);*/ + OS_OSX::singleton->push_input(k); } -- (void)scrollWheel:(NSEvent *)event -{ +inline void sendScrollEvent(int button, double factor, int modifierFlags) { - double deltaX, deltaY; + Ref<InputEventMouseButton> sc; + sc.instance(); -#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 - if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6) - { - deltaX = [event scrollingDeltaX]; - deltaY = [event scrollingDeltaY]; - - if ([event hasPreciseScrollingDeltas]) - { - deltaX *= 0.1; - deltaY *= 0.1; - } - } - else -#endif /*MAC_OS_X_VERSION_MAX_ALLOWED*/ - { - deltaX = [event deltaX]; - deltaY = [event deltaY]; - } + get_key_modifier_state(modifierFlags, sc); + sc->set_button_index(button); + sc->set_factor(factor); + sc->set_pressed(true); + Vector2 mouse_pos = Vector2(mouse_x, mouse_y); + sc->set_position(mouse_pos); + sc->set_global_position(mouse_pos); + sc->set_button_mask(button_mask); + OS_OSX::singleton->push_input(sc); + sc->set_pressed(false); + OS_OSX::singleton->push_input(sc); +} +- (void)scrollWheel:(NSEvent *)event { + double deltaX, deltaY; - if (fabs(deltaY)) { +#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1070 + if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6) { + deltaX = [event scrollingDeltaX]; + deltaY = [event scrollingDeltaY]; - InputEvent ev; - ev.type=InputEvent::MOUSE_BUTTON; - ev.mouse_button.button_index=deltaY >0 ? BUTTON_WHEEL_UP : BUTTON_WHEEL_DOWN; - ev.mouse_button.pressed=true; - ev.mouse_button.x=mouse_x; - ev.mouse_button.y=mouse_y; - ev.mouse_button.global_x=mouse_x; - ev.mouse_button.global_y=mouse_y; - ev.mouse_button.button_mask=button_mask; - OS_OSX::singleton->push_input(ev); - ev.mouse_button.pressed=false; - OS_OSX::singleton->push_input(ev); + if ([event hasPreciseScrollingDeltas]) { + deltaX *= 0.03; + deltaY *= 0.03; + } + } else +#endif // MAC_OS_X_VERSION_MAX_ALLOWED + { + deltaX = [event deltaX]; + deltaY = [event deltaY]; } - if (fabs(deltaX)) { - - InputEvent ev; - ev.type=InputEvent::MOUSE_BUTTON; - ev.mouse_button.button_index=deltaX < 0 ? BUTTON_WHEEL_RIGHT : BUTTON_WHEEL_LEFT; - ev.mouse_button.pressed=true; - ev.mouse_button.x=mouse_x; - ev.mouse_button.y=mouse_y; - ev.mouse_button.global_x=mouse_x; - ev.mouse_button.global_y=mouse_y; - ev.mouse_button.button_mask=button_mask; - OS_OSX::singleton->push_input(ev); - ev.mouse_button.pressed=false; - OS_OSX::singleton->push_input(ev); + sendScrollEvent(0 > deltaX ? BUTTON_WHEEL_RIGHT : BUTTON_WHEEL_LEFT, fabs(deltaX * 0.3), [event modifierFlags]); + } + if (fabs(deltaY)) { + sendScrollEvent(0 < deltaY ? BUTTON_WHEEL_UP : BUTTON_WHEEL_DOWN, fabs(deltaY * 0.3), [event modifierFlags]); } } @end -@interface GodotWindow : NSWindow {} +@interface GodotWindow : NSWindow { +} @end @implementation GodotWindow - -- (BOOL)canBecomeKeyWindow -{ - // Required for NSBorderlessWindowMask windows - return YES; +- (BOOL)canBecomeKeyWindow { + // Required for NSBorderlessWindowMask windows + return YES; } @end - int OS_OSX::get_video_driver_count() const { - return 1; } -const char * OS_OSX::get_video_driver_name(int p_driver) const { + +const char *OS_OSX::get_video_driver_name(int p_driver) const { return "GLES2"; } @@ -924,14 +766,13 @@ const char * OS_OSX::get_video_driver_name(int p_driver) const { OS::VideoMode OS_OSX::get_default_video_mode() const { VideoMode vm; - vm.width=1024; - vm.height=600; - vm.fullscreen=false; - vm.resizable=true; + vm.width = 1024; + vm.height = 600; + vm.fullscreen = false; + vm.resizable = true; return vm; } - void OS_OSX::initialize_core() { OS_Unix::initialize_core(); @@ -941,7 +782,6 @@ void OS_OSX::initialize_core() { DirAccess::make_default<DirAccessOSX>(DirAccess::ACCESS_FILESYSTEM); SemaphoreOSX::make_default(); - } static bool keyboard_layout_dirty = true; @@ -949,7 +789,7 @@ static void keyboardLayoutChanged(CFNotificationCenterRef center, void *observer keyboard_layout_dirty = true; } -void OS_OSX::initialize(const VideoMode& p_desired,int p_video_driver,int p_audio_driver) { +void OS_OSX::initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver) { /*** OSX INITIALIZATION ***/ /*** OSX INITIALIZATION ***/ @@ -959,43 +799,48 @@ void OS_OSX::initialize(const VideoMode& p_desired,int p_video_driver,int p_audi // Register to be notified on keyboard layout changes CFNotificationCenterAddObserver(CFNotificationCenterGetDistributedCenter(), - NULL, keyboardLayoutChanged, - kTISNotifySelectedKeyboardInputSourceChanged, NULL, - CFNotificationSuspensionBehaviorDeliverImmediately); + NULL, keyboardLayoutChanged, + kTISNotifySelectedKeyboardInputSourceChanged, NULL, + CFNotificationSuspensionBehaviorDeliverImmediately); if (is_hidpi_allowed() && [[NSScreen mainScreen] respondsToSelector:@selector(backingScaleFactor)]) { - for (NSScreen *screen in [NSScreen screens]) { - float s = [screen backingScaleFactor]; - if (s > display_scale) { - display_scale=s; - } - } + for (NSScreen *screen in [NSScreen screens]) { + float s = [screen backingScaleFactor]; + if (s > display_scale) { + display_scale = s; + } + } } window_delegate = [[GodotWindowDelegate alloc] init]; - // Don't use accumulation buffer support; it's not accelerated - // Aux buffers probably aren't accelerated either + // Don't use accumulation buffer support; it's not accelerated + // Aux buffers probably aren't accelerated either - unsigned int styleMask = NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | (p_desired.resizable?NSResizableWindowMask:0); + unsigned int styleMask; + if (p_desired.borderless_window) { + styleMask = NSWindowStyleMaskBorderless; + } else { + styleMask = NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | (p_desired.resizable ? NSResizableWindowMask : 0); + } window_object = [[GodotWindow alloc] - initWithContentRect:NSMakeRect(0, 0, p_desired.width/display_scale, p_desired.height/display_scale) - styleMask:styleMask - backing:NSBackingStoreBuffered - defer:NO]; + initWithContentRect:NSMakeRect(0, 0, p_desired.width, p_desired.height) + styleMask:styleMask + backing:NSBackingStoreBuffered + defer:NO]; - ERR_FAIL_COND( window_object==nil ); + ERR_FAIL_COND(window_object == nil); window_view = [[GodotContentView alloc] init]; - window_size.width = p_desired.width; - window_size.height = p_desired.height; + window_size.width = p_desired.width * display_scale; + window_size.height = p_desired.height * display_scale; - if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6 && display_scale>1) { - [window_view setWantsBestResolutionOpenGLSurface:YES]; - //if (current_videomode.resizable) + if (floor(NSAppKitVersionNumber) > NSAppKitVersionNumber10_6 && display_scale > 1) { + [window_view setWantsBestResolutionOpenGLSurface:YES]; + //if (current_videomode.resizable) [window_object setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary]; } @@ -1013,11 +858,15 @@ void OS_OSX::initialize(const VideoMode& p_desired,int p_video_driver,int p_audi // OS X needs non-zero color size, so set resonable values int colorBits = 32; - // Fail if a robustness strategy was requested +// Fail if a robustness strategy was requested - -#define ADD_ATTR(x) { attributes[attributeCount++] = x; } -#define ADD_ATTR2(x, y) { ADD_ATTR(x); ADD_ATTR(y); } +#define ADD_ATTR(x) \ + { attributes[attributeCount++] = x; } +#define ADD_ATTR2(x, y) \ + { \ + ADD_ATTR(x); \ + ADD_ATTR(y); \ + } // Arbitrary array size here NSOpenGLPixelFormatAttribute attributes[40]; @@ -1030,21 +879,26 @@ void OS_OSX::initialize(const VideoMode& p_desired,int p_video_driver,int p_audi ADD_ATTR2(NSOpenGLPFAColorSize, colorBits); - /* if (fbconfig->alphaBits > 0) - ADD_ATTR2(NSOpenGLPFAAlphaSize, fbconfig->alphaBits);*/ + /* + if (fbconfig->alphaBits > 0) + ADD_ATTR2(NSOpenGLPFAAlphaSize, fbconfig->alphaBits); +*/ ADD_ATTR2(NSOpenGLPFADepthSize, 24); ADD_ATTR2(NSOpenGLPFAStencilSize, 8); - /*if (fbconfig->stereo) - ADD_ATTR(NSOpenGLPFAStereo);*/ + /* + if (fbconfig->stereo) + ADD_ATTR(NSOpenGLPFAStereo); +*/ - /* if (fbconfig->samples > 0) - { - ADD_ATTR2(NSOpenGLPFASampleBuffers, 1); - ADD_ATTR2(NSOpenGLPFASamples, fbconfig->samples); - }*/ + /* + if (fbconfig->samples > 0) { + ADD_ATTR2(NSOpenGLPFASampleBuffers, 1); + ADD_ATTR2(NSOpenGLPFASamples, fbconfig->samples); + } +*/ // NOTE: All NSOpenGLPixelFormats on the relevant cards support sRGB // frambuffer, so there's no need (and no way) to request it @@ -1055,14 +909,11 @@ void OS_OSX::initialize(const VideoMode& p_desired,int p_video_driver,int p_audi #undef ADD_ATTR2 pixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:attributes]; - ERR_FAIL_COND( pixelFormat == nil); + ERR_FAIL_COND(pixelFormat == nil); + context = [[NSOpenGLContext alloc] initWithFormat:pixelFormat shareContext:nil]; - context = [[NSOpenGLContext alloc] initWithFormat:pixelFormat - shareContext:nil]; - - ERR_FAIL_COND(context==nil); - + ERR_FAIL_COND(context == nil); [context setView:window_view]; @@ -1079,79 +930,75 @@ void OS_OSX::initialize(const VideoMode& p_desired,int p_video_driver,int p_audi /*** END OSX INITIALIZATION ***/ /*** END OSX INITIALIZATION ***/ - bool use_gl2=p_video_driver!=1; - - + bool use_gl2 = p_video_driver != 1; AudioDriverManager::add_driver(&audio_driver_osx); - // only opengl support here... + // only opengl support here... RasterizerGLES3::register_config(); RasterizerGLES3::make_current(); //rasterizer = instance_RasterizerGLES2(); //visual_server = memnew( VisualServerRaster(rasterizer) ); - visual_server = memnew( VisualServerRaster ); - // FIXME: Reimplement threaded rendering? Or remove? - /* - if (get_render_thread_mode()!=RENDER_THREAD_UNSAFE) { - visual_server =memnew(VisualServerWrapMT(visual_server,get_render_thread_mode()==RENDER_SEPARATE_THREAD)); + visual_server = memnew(VisualServerRaster); + if (get_render_thread_mode() != RENDER_THREAD_UNSAFE) { + + visual_server = memnew(VisualServerWrapMT(visual_server, get_render_thread_mode() == RENDER_SEPARATE_THREAD)); } - */ visual_server->init(); visual_server->cursor_set_visible(false, 0); AudioDriverManager::get_driver(p_audio_driver)->set_singleton(); - if (AudioDriverManager::get_driver(p_audio_driver)->init()!=OK) { + if (AudioDriverManager::get_driver(p_audio_driver)->init() != OK) { ERR_PRINT("Initializing audio failed."); } // - physics_server = memnew( PhysicsServerSW ); + physics_server = memnew(PhysicsServerSW); physics_server->init(); //physics_2d_server = memnew( Physics2DServerSW ); physics_2d_server = Physics2DServerWrapMT::init_server<Physics2DServerSW>(); physics_2d_server->init(); - input = memnew( InputDefault ); - joypad_osx = memnew( JoypadOSX ); + input = memnew(InputDefault); + joypad_osx = memnew(JoypadOSX); - power_manager = memnew( power_osx ); + power_manager = memnew(power_osx); _ensure_data_dir(); NSArray *screenArray = [NSScreen screens]; printf("nscreen count %i\n", (int)[screenArray count]); - for (int i=0; i<[screenArray count]; i++) { + for (int i = 0; i < [screenArray count]; i++) { float displayScale = 1.0; - if (display_scale>1.0 && [[screenArray objectAtIndex: i] respondsToSelector:@selector(backingScaleFactor)]) { - displayScale = [[screenArray objectAtIndex: i] backingScaleFactor]; + if (display_scale > 1.0 && [[screenArray objectAtIndex:i] respondsToSelector:@selector(backingScaleFactor)]) { + displayScale = [[screenArray objectAtIndex:i] backingScaleFactor]; } - NSRect nsrect = [[screenArray objectAtIndex: i] visibleFrame]; + NSRect nsrect = [[screenArray objectAtIndex:i] visibleFrame]; Rect2 rect = Rect2(nsrect.origin.x, nsrect.origin.y, nsrect.size.width, nsrect.size.height); - rect.pos*=displayScale; - rect.size*=displayScale; + rect.position *= displayScale; + rect.size *= displayScale; screens.push_back(rect); - NSDictionary *description = [[screenArray objectAtIndex: i] deviceDescription]; + NSDictionary *description = [[screenArray objectAtIndex:i] deviceDescription]; NSSize displayPixelSize = [[description objectForKey:NSDeviceSize] sizeValue]; CGSize displayPhysicalSize = CGDisplayScreenSize( - [[description objectForKey:@"NSScreenNumber"] unsignedIntValue]); + [[description objectForKey:@"NSScreenNumber"] unsignedIntValue]); //printf("width: %i pwidth %i rect width %i\n",int(displayPixelSize.width*displayScale),int(displayPhysicalSize.width*displayScale),int(nsrect.size.width)); - int dpi = (displayPixelSize.width * 25.4f / displayPhysicalSize.width)*displayScale; + int dpi = (displayPixelSize.width * 25.4f / displayPhysicalSize.width) * displayScale; screen_dpi.push_back(dpi); - }; restore_rect = Rect2(get_window_position(), get_window_size()); } + void OS_OSX::finalize() { CFNotificationCenterRemoveObserver(CFNotificationCenterGetDistributedCenter(), NULL, kTISNotifySelectedKeyboardInputSourceChanged, NULL); @@ -1171,15 +1018,12 @@ void OS_OSX::finalize() { memdelete(physics_2d_server); screens.clear(); - - } -void OS_OSX::set_main_loop( MainLoop * p_main_loop ) { +void OS_OSX::set_main_loop(MainLoop *p_main_loop) { - main_loop=p_main_loop; + main_loop = p_main_loop; input->set_main_loop(p_main_loop); - } void OS_OSX::delete_main_loop() { @@ -1187,16 +1031,15 @@ void OS_OSX::delete_main_loop() { if (!main_loop) return; memdelete(main_loop); - main_loop=NULL; + main_loop = NULL; } - String OS_OSX::get_name() { return "OSX"; } -void OS_OSX::alert(const String& p_alert, const String& p_title) { +void OS_OSX::alert(const String &p_alert, const String &p_title) { // Set OS X-compliant variables NSAlert *window = [[NSAlert alloc] init]; NSString *ns_title = [NSString stringWithUTF8String:p_title.utf8().get_data()]; @@ -1214,10 +1057,10 @@ void OS_OSX::alert(const String& p_alert, const String& p_title) { void OS_OSX::set_cursor_shape(CursorShape p_shape) { - if (cursor_shape==p_shape) + if (cursor_shape == p_shape) return; - switch(p_shape) { + switch (p_shape) { case CURSOR_ARROW: [[NSCursor arrowCursor] set]; break; case CURSOR_IBEAM: [[NSCursor IBeamCursor] set]; break; case CURSOR_POINTING_HAND: [[NSCursor pointingHandCursor] set]; break; @@ -1238,101 +1081,102 @@ void OS_OSX::set_cursor_shape(CursorShape p_shape) { default: {}; } - cursor_shape=p_shape; + cursor_shape = p_shape; } void OS_OSX::set_mouse_show(bool p_show) { - } -void OS_OSX::set_mouse_grab(bool p_grab) { +void OS_OSX::set_mouse_grab(bool p_grab) { } + bool OS_OSX::is_mouse_grab_enabled() const { return mouse_grab; } -void OS_OSX::warp_mouse_pos(const Point2& p_to) { +void OS_OSX::warp_mouse_pos(const Point2 &p_to) { - //copied from windows impl with osx native calls - if (mouse_mode == MOUSE_MODE_CAPTURED){ - mouse_x = p_to.x; - mouse_y = p_to.y; - } - else{ //set OS position + //copied from windows impl with osx native calls + if (mouse_mode == MOUSE_MODE_CAPTURED) { + mouse_x = p_to.x; + mouse_y = p_to.y; + } else { //set OS position - /* this code has not been tested, please be a kind soul and fix it if it fails! */ + /* this code has not been tested, please be a kind soul and fix it if it fails! */ - //local point in window coords - NSPoint localPoint = { p_to.x, p_to.y }; + //local point in window coords + NSPoint localPoint = { p_to.x, p_to.y }; - NSPoint pointInWindow = [window_view convertPoint:localPoint toView:nil]; - NSRect pointInWindowRect; - pointInWindowRect.origin = pointInWindow; - NSPoint pointOnScreen = [[window_view window] convertRectToScreen:pointInWindowRect].origin; + NSPoint pointInWindow = [window_view convertPoint:localPoint toView:nil]; + NSRect pointInWindowRect; + pointInWindowRect.origin = pointInWindow; + NSPoint pointOnScreen = [[window_view window] convertRectToScreen:pointInWindowRect].origin; - //point in scren coords - CGPoint lMouseWarpPos = { pointOnScreen.x, pointOnScreen.y}; + //point in scren coords + CGPoint lMouseWarpPos = { pointOnScreen.x, pointOnScreen.y }; - //do the warping - CGEventSourceRef lEventRef = CGEventSourceCreate(kCGEventSourceStateCombinedSessionState); - CGEventSourceSetLocalEventsSuppressionInterval(lEventRef, 0.0); - CGAssociateMouseAndMouseCursorPosition(false); - CGWarpMouseCursorPosition(lMouseWarpPos); - CGAssociateMouseAndMouseCursorPosition(true); - } + //do the warping + CGEventSourceRef lEventRef = CGEventSourceCreate(kCGEventSourceStateCombinedSessionState); + CGEventSourceSetLocalEventsSuppressionInterval(lEventRef, 0.0); + CGAssociateMouseAndMouseCursorPosition(false); + CGWarpMouseCursorPosition(lMouseWarpPos); + CGAssociateMouseAndMouseCursorPosition(true); + } } -Point2 OS_OSX::get_mouse_pos() const { +Point2 OS_OSX::get_mouse_position() const { - return Vector2(mouse_x,mouse_y); + return Vector2(mouse_x, mouse_y); } + int OS_OSX::get_mouse_button_state() const { return button_mask; } -void OS_OSX::set_window_title(const String& p_title) { - [window_object setTitle:[NSString stringWithUTF8String:p_title.utf8().get_data()]]; +void OS_OSX::set_window_title(const String &p_title) { + title = p_title; + [window_object setTitle:[NSString stringWithUTF8String:p_title.utf8().get_data()]]; } -void OS_OSX::set_icon(const Image& p_icon) { - - Image img=p_icon; - img.convert(Image::FORMAT_RGBA8); - NSBitmapImageRep *imgrep= [[[NSBitmapImageRep alloc] initWithBitmapDataPlanes: NULL - pixelsWide: p_icon.get_width() - pixelsHigh: p_icon.get_height() - bitsPerSample: 8 - samplesPerPixel: 4 - hasAlpha: YES - isPlanar: NO - colorSpaceName: NSDeviceRGBColorSpace - bytesPerRow: p_icon.get_width()*4 - bitsPerPixel: 32] autorelease]; - ERR_FAIL_COND(imgrep==nil); +void OS_OSX::set_icon(const Ref<Image> &p_icon) { + + Ref<Image> img = p_icon; + img = img->duplicate(); + img->convert(Image::FORMAT_RGBA8); + NSBitmapImageRep *imgrep = [[[NSBitmapImageRep alloc] + initWithBitmapDataPlanes:NULL + pixelsWide:img->get_width() + pixelsHigh:img->get_height() + bitsPerSample:8 + samplesPerPixel:4 + hasAlpha:YES + isPlanar:NO + colorSpaceName:NSDeviceRGBColorSpace + bytesPerRow:img->get_width() * 4 + bitsPerPixel:32] autorelease]; + ERR_FAIL_COND(imgrep == nil); uint8_t *pixels = [imgrep bitmapData]; - int len = img.get_width()*img.get_height(); - PoolVector<uint8_t> data = img.get_data(); + int len = img->get_width() * img->get_height(); + PoolVector<uint8_t> data = img->get_data(); PoolVector<uint8_t>::Read r = data.read(); /* Premultiply the alpha channel */ - for (int i = 0; i<len ; i++) { - uint8_t alpha = r[i*4+3]; - pixels[i*4+0] = (uint8_t)(((uint16_t)r[i*4+0] * alpha) / 255); - pixels[i*4+1] = (uint8_t)(((uint16_t)r[i*4+1] * alpha) / 255); - pixels[i*4+2] = (uint8_t)(((uint16_t)r[i*4+2] * alpha) / 255); - pixels[i*4+3] = alpha; - + for (int i = 0; i < len; i++) { + uint8_t alpha = r[i * 4 + 3]; + pixels[i * 4 + 0] = (uint8_t)(((uint16_t)r[i * 4 + 0] * alpha) / 255); + pixels[i * 4 + 1] = (uint8_t)(((uint16_t)r[i * 4 + 1] * alpha) / 255); + pixels[i * 4 + 2] = (uint8_t)(((uint16_t)r[i * 4 + 2] * alpha) / 255); + pixels[i * 4 + 3] = alpha; } - NSImage *nsimg = [[[NSImage alloc] initWithSize: NSMakeSize(img.get_width(),img.get_height())] autorelease]; + NSImage *nsimg = [[[NSImage alloc] initWithSize:NSMakeSize(img->get_width(), img->get_height())] autorelease]; ERR_FAIL_COND(nsimg == nil); - [nsimg addRepresentation: imgrep]; + [nsimg addRepresentation:imgrep]; [NSApp setApplicationIconImage:nsimg]; - } MainLoop *OS_OSX::get_main_loop() const { @@ -1345,27 +1189,26 @@ bool OS_OSX::can_draw() const { return true; } -void OS_OSX::set_clipboard(const String& p_text) { +void OS_OSX::set_clipboard(const String &p_text) { - NSArray* types = [NSArray arrayWithObjects:NSStringPboardType, nil]; + NSArray *types = [NSArray arrayWithObjects:NSStringPboardType, nil]; - NSPasteboard* pasteboard = [NSPasteboard generalPasteboard]; + NSPasteboard *pasteboard = [NSPasteboard generalPasteboard]; [pasteboard declareTypes:types owner:nil]; [pasteboard setString:[NSString stringWithUTF8String:p_text.utf8().get_data()] - forType:NSStringPboardType]; + forType:NSStringPboardType]; } + String OS_OSX::get_clipboard() const { - NSPasteboard* pasteboard = [NSPasteboard generalPasteboard]; + NSPasteboard *pasteboard = [NSPasteboard generalPasteboard]; - if (![[pasteboard types] containsObject:NSStringPboardType]) - { + if (![[pasteboard types] containsObject:NSStringPboardType]) { return ""; } - NSString* object = [pasteboard stringForType:NSStringPboardType]; - if (!object) - { + NSString *object = [pasteboard stringForType:NSStringPboardType]; + if (!object) { return ""; } @@ -1380,12 +1223,11 @@ String OS_OSX::get_clipboard() const { void OS_OSX::release_rendering_thread() { [NSOpenGLContext clearCurrentContext]; - } + void OS_OSX::make_rendering_thread() { [context makeCurrentContext]; - } Error OS_OSX::shell_open(String p_uri) { @@ -1395,14 +1237,13 @@ Error OS_OSX::shell_open(String p_uri) { } String OS_OSX::get_locale() const { - NSString* preferredLang = [[NSLocale preferredLanguages] objectAtIndex:0]; - return [preferredLang UTF8String]; + NSString *locale_code = [[NSLocale currentLocale] localeIdentifier]; + return [locale_code UTF8String]; } void OS_OSX::swap_buffers() { [context flushBuffer]; - } void OS_OSX::wm_minimized(bool p_minimized) { @@ -1410,23 +1251,21 @@ void OS_OSX::wm_minimized(bool p_minimized) { minimized = p_minimized; }; -void OS_OSX::set_video_mode(const VideoMode& p_video_mode,int p_screen) { - +void OS_OSX::set_video_mode(const VideoMode &p_video_mode, int p_screen) { } OS::VideoMode OS_OSX::get_video_mode(int p_screen) const { VideoMode vm; - vm.width=window_size.width; - vm.height=window_size.height; + vm.width = window_size.width; + vm.height = window_size.height; return vm; } -void OS_OSX::get_fullscreen_mode_list(List<VideoMode> *p_list,int p_screen) const { +void OS_OSX::get_fullscreen_mode_list(List<VideoMode> *p_list, int p_screen) const { } - int OS_OSX::get_screen_count() const { return screens.size(); @@ -1445,7 +1284,7 @@ void OS_OSX::set_current_screen(int p_screen) { Point2 OS_OSX::get_screen_position(int p_screen) const { ERR_FAIL_INDEX_V(p_screen, screens.size(), Point2()); - return screens[p_screen].pos; + return screens[p_screen].position; }; int OS_OSX::get_screen_dpi(int p_screen) const { @@ -1463,35 +1302,33 @@ Size2 OS_OSX::get_screen_size(int p_screen) const { Point2 OS_OSX::get_window_position() const { Size2 wp([window_object frame].origin.x, [window_object frame].origin.y); - wp*=display_scale; + wp *= display_scale; return wp; }; +void OS_OSX::set_window_position(const Point2 &p_position) { -void OS_OSX::set_window_position(const Point2& p_position) { - - Point2 size=p_position; - size/=display_scale; + Point2 size = p_position; + size /= display_scale; [window_object setFrame:NSMakeRect(size.x, size.y, [window_object frame].size.width, [window_object frame].size.height) display:YES]; }; Size2 OS_OSX::get_window_size() const { return window_size; - }; void OS_OSX::set_window_size(const Size2 p_size) { - Size2 size=p_size; + Size2 size = p_size; // NSRect used by setFrame includes the title bar, so add it to our size.y CGFloat menuBarHeight = [[[NSApplication sharedApplication] mainMenu] menuBarHeight]; if (menuBarHeight != 0.f) { - size.y+= menuBarHeight; + size.y += menuBarHeight; #if MAC_OS_X_VERSION_MAX_ALLOWED <= 101104 } else { - size.y+= [[NSStatusBar systemStatusBar] thickness]; + size.y += [[NSStatusBar systemStatusBar] thickness]; #endif } NSRect frame = [window_object frame]; @@ -1513,7 +1350,7 @@ void OS_OSX::set_window_fullscreen(bool p_enabled) { bool OS_OSX::is_window_fullscreen() const { #if MAC_OS_X_VERSION_MAX_ALLOWED < 1070 - if ( [window_object respondsToSelector:@selector(isZoomed)] ) + if ([window_object respondsToSelector:@selector(isZoomed)]) return [window_object isZoomed]; #endif /*MAC_OS_X_VERSION_MAX_ALLOWED*/ @@ -1523,9 +1360,9 @@ bool OS_OSX::is_window_fullscreen() const { void OS_OSX::set_window_resizable(bool p_enabled) { if (p_enabled) - [window_object setStyleMask:[window_object styleMask] | NSResizableWindowMask ]; + [window_object setStyleMask:[window_object styleMask] | NSResizableWindowMask]; else - [window_object setStyleMask:[window_object styleMask] & ~NSResizableWindowMask ]; + [window_object setStyleMask:[window_object styleMask] & ~NSResizableWindowMask]; }; bool OS_OSX::is_window_resizable() const { @@ -1543,13 +1380,12 @@ void OS_OSX::set_window_minimized(bool p_enabled) { bool OS_OSX::is_window_minimized() const { - if ( [window_object respondsToSelector:@selector(isMiniaturized)]) + if ([window_object respondsToSelector:@selector(isMiniaturized)]) return [window_object isMiniaturized]; return minimized; }; - void OS_OSX::set_window_maximized(bool p_enabled) { if (p_enabled) { @@ -1557,7 +1393,7 @@ void OS_OSX::set_window_maximized(bool p_enabled) { [window_object setFrame:[[[NSScreen screens] objectAtIndex:current_screen] visibleFrame] display:YES]; } else { set_window_size(restore_rect.size); - set_window_position(restore_rect.pos); + set_window_position(restore_rect.position); }; maximized = p_enabled; }; @@ -1568,7 +1404,6 @@ bool OS_OSX::is_window_maximized() const { return maximized; }; - void OS_OSX::move_window_to_foreground() { [window_object orderFrontRegardless]; @@ -1579,6 +1414,28 @@ void OS_OSX::request_attention() { [NSApp requestUserAttention:NSCriticalRequest]; } +void OS_OSX::set_borderless_window(int p_borderless) { + + if (p_borderless) + [window_object setStyleMask:NSWindowStyleMaskBorderless]; + else { + [window_object setStyleMask:NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | NSResizableWindowMask]; + + // Force update of the window styles + NSRect frameRect = [window_object frame]; + [window_object setFrame:NSMakeRect(frameRect.origin.x, frameRect.origin.y, frameRect.size.width + 1, frameRect.size.height) display:NO]; + [window_object setFrame:frameRect display:NO]; + + // Restore the window title + [window_object setTitle:[NSString stringWithUTF8String:title.utf8().get_data()]]; + } +} + +bool OS_OSX::get_borderless_window() { + + return [window_object styleMask] == NSWindowStyleMaskBorderless; +} + String OS_OSX::get_executable_path() const { int ret; @@ -1586,8 +1443,8 @@ String OS_OSX::get_executable_path() const { char pathbuf[PROC_PIDPATHINFO_MAXSIZE]; pid = getpid(); - ret = proc_pidpath (pid, pathbuf, sizeof(pathbuf)); - if ( ret <= 0 ) { + ret = proc_pidpath(pid, pathbuf, sizeof(pathbuf)); + if (ret <= 0) { return OS::get_executable_path(); } else { String path; @@ -1595,7 +1452,6 @@ String OS_OSX::get_executable_path() const { return path; } - } // Returns string representation of keys, if they are printable. @@ -1615,22 +1471,22 @@ static NSString *createStringForKeys(const CGKeyCode *keyCode, int length) { OSStatus err; CFMutableStringRef output = CFStringCreateMutable(NULL, 0); - for (int i=0; i<length; ++i) { + for (int i = 0; i < length; ++i) { UInt32 keysDown = 0; UniChar chars[4]; UniCharCount realLength; err = UCKeyTranslate(keyboardLayout, - keyCode[i], - kUCKeyActionDisplay, - 0, - LMGetKbdType(), - kUCKeyTranslateNoDeadKeysBit, - &keysDown, - sizeof(chars) / sizeof(chars[0]), - &realLength, - chars); + keyCode[i], + kUCKeyActionDisplay, + 0, + LMGetKbdType(), + kUCKeyTranslateNoDeadKeysBit, + &keysDown, + sizeof(chars) / sizeof(chars[0]), + &realLength, + chars); if (err != noErr) { CFRelease(output); @@ -1644,6 +1500,7 @@ static NSString *createStringForKeys(const CGKeyCode *keyCode, int length) { return (NSString *)output; } + OS::LatinKeyboardVariant OS_OSX::get_latin_keyboard_variant() const { static LatinKeyboardVariant layout = LATIN_KEYBOARD_QWERTY; @@ -1652,7 +1509,7 @@ OS::LatinKeyboardVariant OS_OSX::get_latin_keyboard_variant() const { layout = LATIN_KEYBOARD_QWERTY; - CGKeyCode keys[] = {kVK_ANSI_Q, kVK_ANSI_W, kVK_ANSI_E, kVK_ANSI_R, kVK_ANSI_T, kVK_ANSI_Y}; + CGKeyCode keys[] = { kVK_ANSI_Q, kVK_ANSI_W, kVK_ANSI_E, kVK_ANSI_R, kVK_ANSI_T, kVK_ANSI_Y }; NSString *test = createStringForKeys(keys, 6); if ([test isEqualToString:@"qwertz"]) { @@ -1679,10 +1536,12 @@ OS::LatinKeyboardVariant OS_OSX::get_latin_keyboard_variant() const { void OS_OSX::process_events() { while (true) { - NSEvent* event = [NSApp nextEventMatchingMask:NSAnyEventMask - untilDate:[NSDate distantPast] - inMode:NSDefaultRunLoopMode - dequeue:YES]; + NSEvent *event = [NSApp + nextEventMatchingMask:NSAnyEventMask + untilDate:[NSDate distantPast] + inMode:NSDefaultRunLoopMode + dequeue:YES]; + if (event == nil) break; @@ -1693,13 +1552,9 @@ void OS_OSX::process_events() { autoreleasePool = [[NSAutoreleasePool alloc] init]; } +void OS_OSX::push_input(const Ref<InputEvent> &p_event) { - -void OS_OSX::push_input(const InputEvent& p_event) { - - InputEvent ev=p_event; - ev.ID=last_id++; - //print_line("EV: "+String(ev)); + Ref<InputEvent> ev = p_event; input->parse_input_event(ev); } @@ -1725,8 +1580,8 @@ void OS_OSX::run() { while (!force_quit) { process_events(); // get rid of pending events - last_id = joypad_osx->process_joypads(last_id); - if (Main::iteration()==true) + joypad_osx->process_joypads(); + if (Main::iteration() == true) break; }; @@ -1735,32 +1590,31 @@ void OS_OSX::run() { void OS_OSX::set_mouse_mode(MouseMode p_mode) { - if (p_mode==mouse_mode) - return; + if (p_mode == mouse_mode) + return; - if (p_mode==MOUSE_MODE_CAPTURED) { - // Apple Docs state that the display parameter is not used. - // "This parameter is not used. By default, you may pass kCGDirectMainDisplay." - // https://developer.apple.com/library/mac/documentation/graphicsimaging/reference/Quartz_Services_Ref/Reference/reference.html - CGDisplayHideCursor(kCGDirectMainDisplay); - CGAssociateMouseAndMouseCursorPosition(false); - } else if (p_mode==MOUSE_MODE_HIDDEN) { - CGDisplayHideCursor(kCGDirectMainDisplay); - CGAssociateMouseAndMouseCursorPosition(true); - } else { - CGDisplayShowCursor(kCGDirectMainDisplay); - CGAssociateMouseAndMouseCursorPosition(true); - } + if (p_mode == MOUSE_MODE_CAPTURED) { + // Apple Docs state that the display parameter is not used. + // "This parameter is not used. By default, you may pass kCGDirectMainDisplay." + // https://developer.apple.com/library/mac/documentation/graphicsimaging/reference/Quartz_Services_Ref/Reference/reference.html + CGDisplayHideCursor(kCGDirectMainDisplay); + CGAssociateMouseAndMouseCursorPosition(false); + } else if (p_mode == MOUSE_MODE_HIDDEN) { + CGDisplayHideCursor(kCGDirectMainDisplay); + CGAssociateMouseAndMouseCursorPosition(true); + } else { + CGDisplayShowCursor(kCGDirectMainDisplay); + CGAssociateMouseAndMouseCursorPosition(true); + } - mouse_mode=p_mode; + mouse_mode = p_mode; } OS::MouseMode OS_OSX::get_mouse_mode() const { - return mouse_mode; + return mouse_mode; } - String OS_OSX::get_joy_guid(int p_device) const { return input->get_joy_guid_remapped(p_device); } @@ -1777,13 +1631,13 @@ int OS_OSX::get_power_percent_left() { return power_manager->get_power_percent_left(); } -OS_OSX* OS_OSX::singleton=NULL; +OS_OSX *OS_OSX::singleton = NULL; OS_OSX::OS_OSX() { - - mouse_mode=OS::MOUSE_MODE_VISIBLE; - main_loop=NULL; - singleton=this; + + mouse_mode = OS::MOUSE_MODE_VISIBLE; + main_loop = NULL; + singleton = this; autoreleasePool = [[NSAutoreleasePool alloc] init]; eventSource = CGEventSourceCreate(kCGEventSourceStateHIDSystemState); @@ -1791,13 +1645,12 @@ OS_OSX::OS_OSX() { CGEventSourceSetLocalEventsSuppressionInterval(eventSource, 0.0); - - /*if (pthread_key_create(&_Godot.nsgl.current, NULL) != 0) - { - _GodotInputError(Godot_PLATFORM_ERROR, - "NSGL: Failed to create context TLS"); - return GL_FALSE; - }*/ + /* + if (pthread_key_create(&_Godot.nsgl.current, NULL) != 0) { + _GodotInputError(Godot_PLATFORM_ERROR, "NSGL: Failed to create context TLS"); + return GL_FALSE; + } +*/ framework = CFBundleGetBundleWithIdentifier(CFSTR("com.apple.opengl")); ERR_FAIL_COND(!framework); @@ -1808,12 +1661,12 @@ OS_OSX::OS_OSX() { // In case we are unbundled, make us a proper UI application [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular]; - #if 0 +#if 0 // Menu bar setup must go between sharedApplication above and // finishLaunching below, in order to properly emulate the behavior // of NSApplicationMain createMenuBar(); - #endif +#endif [NSApp finishLaunching]; @@ -1821,15 +1674,13 @@ OS_OSX::OS_OSX() { ERR_FAIL_COND(!delegate); [NSApp setDelegate:delegate]; - - last_id=1; - cursor_shape=CURSOR_ARROW; + cursor_shape = CURSOR_ARROW; current_screen = 0; maximized = false; minimized = false; - window_size=Vector2(1024,600); + window_size = Vector2(1024, 600); zoomed = false; - display_scale=1.0; + display_scale = 1.0; } diff --git a/platform/osx/platform_config.h b/platform/osx/platform_config.h index 834d0141a3..487077e651 100644 --- a/platform/osx/platform_config.h +++ b/platform/osx/platform_config.h @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/osx/power_osx.cpp b/platform/osx/power_osx.cpp index de9bcaf6fc..2ef1a65ff1 100644 --- a/platform/osx/power_osx.cpp +++ b/platform/osx/power_osx.cpp @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -26,6 +27,32 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ + +/* +Adapted from corresponding SDL 2.0 code. +*/ + +/* + Simple DirectMedia Layer + Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org> + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + #include "power_osx.h" #include <CoreFoundation/CoreFoundation.h> diff --git a/platform/osx/power_osx.h b/platform/osx/power_osx.h index c638dc675a..6d984ec466 100644 --- a/platform/osx/power_osx.h +++ b/platform/osx/power_osx.h @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/osx/sem_osx.cpp b/platform/osx/sem_osx.cpp index 069e3a5153..b1eeccfec5 100644 --- a/platform/osx/sem_osx.cpp +++ b/platform/osx/sem_osx.cpp @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/osx/sem_osx.h b/platform/osx/sem_osx.h index a30f3fcc98..3025318c4b 100644 --- a/platform/osx/sem_osx.h +++ b/platform/osx/sem_osx.h @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/server/detect.py b/platform/server/detect.py index 8bc85f342d..32f3c55135 100644 --- a/platform/server/detect.py +++ b/platform/server/detect.py @@ -64,7 +64,7 @@ def configure(env): elif (env["target"] == "debug"): - env.Append(CCFLAGS=['-g2', '-Wall', '-DDEBUG_ENABLED', '-DDEBUG_MEMORY_ENABLED']) + env.Append(CCFLAGS=['-g2', '-DDEBUG_ENABLED', '-DDEBUG_MEMORY_ENABLED']) # Shared libraries, when requested diff --git a/platform/server/godot_server.cpp b/platform/server/godot_server.cpp index d06ade4a57..ed0100ac93 100644 --- a/platform/server/godot_server.cpp +++ b/platform/server/godot_server.cpp @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/server/os_server.cpp b/platform/server/os_server.cpp index f44d976bd6..89af785d29 100644 --- a/platform/server/os_server.cpp +++ b/platform/server/os_server.cpp @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -142,7 +143,7 @@ int OS_Server::get_mouse_button_state() const { return 0; } -Point2 OS_Server::get_mouse_pos() const { +Point2 OS_Server::get_mouse_position() const { return Point2(); } diff --git a/platform/server/os_server.h b/platform/server/os_server.h index 7484d70e06..7c29b1e232 100644 --- a/platform/server/os_server.h +++ b/platform/server/os_server.h @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -87,7 +88,7 @@ public: virtual void set_mouse_show(bool p_show); virtual void set_mouse_grab(bool p_grab); virtual bool is_mouse_grab_enabled() const; - virtual Point2 get_mouse_pos() const; + virtual Point2 get_mouse_position() const; virtual int get_mouse_button_state() const; virtual void set_window_title(const String &p_title); diff --git a/platform/server/platform_config.h b/platform/server/platform_config.h index cdef185ff0..48bcadcc29 100644 --- a/platform/server/platform_config.h +++ b/platform/server/platform_config.h @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/uwp/SCsub b/platform/uwp/SCsub index 0167ea9e02..7ee5aa2ac3 100644 --- a/platform/uwp/SCsub +++ b/platform/uwp/SCsub @@ -9,6 +9,7 @@ files = [ '#platform/windows/stream_peer_winsock.cpp', '#platform/windows/key_mapping_win.cpp', 'joypad_uwp.cpp', + 'power_uwp.cpp', 'gl_context_egl.cpp', 'app.cpp', 'os_uwp.cpp', diff --git a/platform/uwp/app.cpp b/platform/uwp/app.cpp index 35b25b1de5..c773c0b746 100644 --- a/platform/uwp/app.cpp +++ b/platform/uwp/app.cpp @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -258,45 +259,48 @@ void App::pointer_event(Windows::UI::Core::CoreWindow ^ sender, Windows::UI::Cor int but = _get_button(point); if (_is_touch(point)) { - InputEvent event; - event.type = InputEvent::SCREEN_TOUCH; - event.device = 0; - event.screen_touch.pressed = p_pressed; - event.screen_touch.x = pos.X; - event.screen_touch.y = pos.Y; - event.screen_touch.index = _get_finger(point->PointerId); + Ref<InputEventScreenTouch> screen_touch; + screen_touch.instance(); + screen_touch->set_device(0); + screen_touch->set_pressed(p_pressed); + screen_touch->set_position(Vector2(pos.X, pos.Y)); + screen_touch->set_index(_get_finger(point->PointerId)); - last_touch_x[event.screen_touch.index] = pos.X; - last_touch_y[event.screen_touch.index] = pos.Y; + last_touch_x[screen_touch->get_index()] = pos.X; + last_touch_y[screen_touch->get_index()] = pos.Y; - os->input_event(event); + os->input_event(screen_touch); if (number_of_contacts > 1) return; }; // fallthrought of sorts - InputEvent event; - event.type = InputEvent::MOUSE_BUTTON; - event.device = 0; - event.mouse_button.pressed = p_pressed; - event.mouse_button.button_index = but; - event.mouse_button.x = pos.X; - event.mouse_button.y = pos.Y; - event.mouse_button.global_x = pos.X; - event.mouse_button.global_y = pos.Y; + Ref<InputEventMouseButton> mouse_button; + mouse_button.instance(); + mouse_button->set_device(0); + mouse_button->set_pressed(p_pressed); + mouse_button->set_button_index(but); + mouse_button->set_position(Vector2(pos.X, pos.Y)); + mouse_button->set_global_position(Vector2(pos.X, pos.Y)); if (p_is_wheel) { if (point->Properties->MouseWheelDelta > 0) { - event.mouse_button.button_index = point->Properties->IsHorizontalMouseWheel ? BUTTON_WHEEL_RIGHT : BUTTON_WHEEL_UP; + mouse_button->set_button_index(point->Properties->IsHorizontalMouseWheel ? BUTTON_WHEEL_RIGHT : BUTTON_WHEEL_UP); } else if (point->Properties->MouseWheelDelta < 0) { - event.mouse_button.button_index = point->Properties->IsHorizontalMouseWheel ? BUTTON_WHEEL_LEFT : BUTTON_WHEEL_DOWN; + mouse_button->set_button_index(point->Properties->IsHorizontalMouseWheel ? BUTTON_WHEEL_LEFT : BUTTON_WHEEL_DOWN); } } last_touch_x[31] = pos.X; last_touch_y[31] = pos.Y; - os->input_event(event); + os->input_event(mouse_button); + + if (p_is_wheel) { + // Send release for mouse wheel + mouse_button->set_pressed(false); + os->input_event(mouse_button); + } }; void App::OnPointerPressed(Windows::UI::Core::CoreWindow ^ sender, Windows::UI::Core::PointerEventArgs ^ args) { @@ -348,16 +352,14 @@ void App::OnPointerMoved(Windows::UI::Core::CoreWindow ^ sender, Windows::UI::Co if (point->IsInContact && _is_touch(point)) { - InputEvent event; - event.type = InputEvent::SCREEN_DRAG; - event.device = 0; - event.screen_drag.x = pos.X; - event.screen_drag.y = pos.Y; - event.screen_drag.index = _get_finger(point->PointerId); - event.screen_drag.relative_x = event.screen_drag.x - last_touch_x[event.screen_drag.index]; - event.screen_drag.relative_y = event.screen_drag.y - last_touch_y[event.screen_drag.index]; + Ref<InputEventScreenDrag> screen_drag; + screen_drag.instance(); + screen_drag->set_device(0); + screen_drag->set_position(Vector2(pos.X, pos.Y)); + screen_drag->set_index(_get_finger(point->PointerId)); + screen_drag->set_relative(Vector2(screen_drag->get_position().x - last_touch_x[screen_drag->get_index()], screen_drag->get_position().y - last_touch_y[screen_drag->get_index()])); - os->input_event(event); + os->input_event(screen_drag); if (number_of_contacts > 1) return; @@ -367,19 +369,16 @@ void App::OnPointerMoved(Windows::UI::Core::CoreWindow ^ sender, Windows::UI::Co if (os->get_mouse_mode() == OS::MouseMode::MOUSE_MODE_CAPTURED) return; - InputEvent event; - event.type = InputEvent::MOUSE_MOTION; - event.device = 0; - event.mouse_motion.x = pos.X; - event.mouse_motion.y = pos.Y; - event.mouse_motion.global_x = pos.X; - event.mouse_motion.global_y = pos.Y; - event.mouse_motion.relative_x = pos.X - last_touch_x[31]; - event.mouse_motion.relative_y = pos.Y - last_touch_y[31]; + Ref<InputEventMouseMotion> mouse_motion; + mouse_motion.instance(); + mouse_motion->set_device(0); + mouse_motion->set_position(Vector2(pos.X, pos.Y)); + mouse_motion->set_global_position(Vector2(pos.X, pos.Y)); + mouse_motion->set_relative(Vector2(pos.X - last_touch_x[31], pos.Y - last_touch_y[31])); last_mouse_pos = pos; - os->input_event(event); + os->input_event(mouse_motion); } void App::OnMouseMoved(MouseDevice ^ mouse_device, MouseEventArgs ^ args) { @@ -392,32 +391,25 @@ void App::OnMouseMoved(MouseDevice ^ mouse_device, MouseEventArgs ^ args) { pos.X = last_mouse_pos.X + args->MouseDelta.X; pos.Y = last_mouse_pos.Y + args->MouseDelta.Y; - InputEvent event; - event.type = InputEvent::MOUSE_MOTION; - event.device = 0; - event.mouse_motion.x = pos.X; - event.mouse_motion.y = pos.Y; - event.mouse_motion.global_x = pos.X; - event.mouse_motion.global_y = pos.Y; - event.mouse_motion.relative_x = args->MouseDelta.X; - event.mouse_motion.relative_y = args->MouseDelta.Y; + Ref<InputEventMouseMotion> mouse_motion; + mouse_motion.instance(); + mouse_motion->set_device(0); + mouse_motion->set_position(Vector2(pos.X, pos.Y)); + mouse_motion->set_global_position(Vector2(pos.X, pos.Y)); + mouse_motion->set_relative(Vector2(args->MouseDelta.X, args->MouseDelta.Y)); last_mouse_pos = pos; - os->input_event(event); + os->input_event(mouse_motion); } void App::key_event(Windows::UI::Core::CoreWindow ^ sender, bool p_pressed, Windows::UI::Core::KeyEventArgs ^ key_args, Windows::UI::Core::CharacterReceivedEventArgs ^ char_args) { OSUWP::KeyEvent ke; - InputModifierState mod; - mod.meta = false; - mod.command = false; - mod.control = sender->GetAsyncKeyState(VirtualKey::Control) == CoreVirtualKeyStates::Down; - mod.alt = sender->GetAsyncKeyState(VirtualKey::Menu) == CoreVirtualKeyStates::Down; - mod.shift = sender->GetAsyncKeyState(VirtualKey::Shift) == CoreVirtualKeyStates::Down; - ke.mod_state = mod; + ke.control = sender->GetAsyncKeyState(VirtualKey::Control) == CoreVirtualKeyStates::Down; + ke.alt = sender->GetAsyncKeyState(VirtualKey::Menu) == CoreVirtualKeyStates::Down; + ke.shift = sender->GetAsyncKeyState(VirtualKey::Shift) == CoreVirtualKeyStates::Down; ke.pressed = p_pressed; diff --git a/platform/uwp/app.h b/platform/uwp/app.h index fd6fc950a7..9cbe7669c9 100644 --- a/platform/uwp/app.h +++ b/platform/uwp/app.h @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -106,7 +107,7 @@ namespace GodotUWP int last_touch_y[32]; int number_of_contacts; Windows::Foundation::Point last_mouse_pos; - } + }; } /* clang-format on */ diff --git a/platform/uwp/detect.py b/platform/uwp/detect.py index f1e0716241..baff7f9788 100644 --- a/platform/uwp/detect.py +++ b/platform/uwp/detect.py @@ -49,6 +49,8 @@ def configure(env): arch = "" env['ENV'] = os.environ + vc_base_path = os.environ['VCTOOLSINSTALLDIR'] if "VCTOOLSINSTALLDIR" in os.environ else os.environ['VCINSTALLDIR'] + # ANGLE angle_root = os.getenv("ANGLE_SRC_PATH") env.Append(CPPPATH=[angle_root + '/include']) @@ -65,7 +67,7 @@ def configure(env): arch = "arm" env["bits"] = "32" env.Append(LINKFLAGS=['/MACHINE:ARM']) - env.Append(LIBPATH=[os.environ['VCINSTALLDIR'] + 'lib/store/arm']) + env.Append(LIBPATH=[vc_base_path + 'lib/store/arm']) angle_build_cmd += "ARM" @@ -92,7 +94,7 @@ def configure(env): env.Append(CPPFLAGS=['/DPNG_ABORT=abort']) env.Append(LINKFLAGS=['/MACHINE:X86']) - env.Append(LIBPATH=[os.environ['VCINSTALLDIR'] + 'lib/store']) + env.Append(LIBPATH=[vc_base_path + 'lib/store']) env.Append(LIBPATH=[angle_root + '/winrt/10/src/Release_Win32/lib']) else: @@ -107,10 +109,9 @@ def configure(env): env.Append(CPPPATH=['#platform/uwp', '#drivers/windows']) env.Append(LINKFLAGS=['/MANIFEST:NO', '/NXCOMPAT', '/DYNAMICBASE', '/WINMD', '/APPCONTAINER', '/ERRORREPORT:PROMPT', '/NOLOGO', '/TLBID:1', '/NODEFAULTLIB:"kernel32.lib"', '/NODEFAULTLIB:"ole32.lib"']) env.Append(CPPFLAGS=['/D', '__WRL_NO_DEFAULT_LIB__', '/D', 'WIN32']) - env.Append(CPPFLAGS=['/FU', os.environ['VCINSTALLDIR'] + 'lib/store/references/platform.winmd']) - env.Append(CPPFLAGS=['/AI', os.environ['VCINSTALLDIR'] + 'lib/store/references']) - - env.Append(LIBPATH=[os.environ['VCINSTALLDIR'] + 'lib/store/references']) + + env.Append(CPPFLAGS=['/AI', vc_base_path + 'lib/store/references']) + env.Append(CPPFLAGS=['/AI', vc_base_path + 'lib/x86/store/references']) if (env["target"] == "release"): @@ -133,7 +134,7 @@ def configure(env): env.Append(CCFLAGS=string.split('/FS /MP /GS /wd"4453" /wd"28204" /wd"4291" /Zc:wchar_t /Gm- /fp:precise /D "_UNICODE" /D "UNICODE" /D "WINAPI_FAMILY=WINAPI_FAMILY_APP" /errorReport:prompt /WX- /Zc:forScope /Gd /EHsc /nologo')) env.Append(CXXFLAGS=string.split('/ZW /FS')) - env.Append(CCFLAGS=['/AI', os.environ['VCINSTALLDIR'] + '\\vcpackages', '/AI', os.environ['WINDOWSSDKDIR'] + '\\References\\CommonConfiguration\\Neutral']) + env.Append(CCFLAGS=['/AI', vc_base_path + '\\vcpackages', '/AI', os.environ['WINDOWSSDKDIR'] + '\\References\\CommonConfiguration\\Neutral']) env["PROGSUFFIX"] = "." + arch + env["PROGSUFFIX"] env["OBJSUFFIX"] = "." + arch + env["OBJSUFFIX"] diff --git a/platform/uwp/export/export.cpp b/platform/uwp/export/export.cpp index a9b26056fc..976e6208ee 100644 --- a/platform/uwp/export/export.cpp +++ b/platform/uwp/export/export.cpp @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -71,17 +72,18 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "editor/editor_import_export.h" #include "editor/editor_node.h" #include "global_config.h" -#include "io/base64.h" #include "io/marshalls.h" -#include "io/sha256.h" -#include "io/unzip.h" -#include "io/zip.h" #include "io/zip_io.h" #include "object.h" #include "os/file_access.h" #include "platform/uwp/logo.h" #include "version.h" +#include "thirdparty/minizip/unzip.h" +#include "thirdparty/minizip/zip.h" +#include "thirdparty/misc/base64.h" +#include "thirdparty/misc/sha256.h" + #include <zlib.h> // Capabilities @@ -1032,7 +1034,7 @@ void AppxPackager::finish() { Error err = read_cert_file(certificate_path, certificate_pass, &cert_file); if (err != OK) { - EditorNode::add_io_error(TTR("Couldn't read the certficate file. Are the path and password both correct?")); + EditorNode::add_io_error(TTR("Couldn't read the certificate file. Are the path and password both correct?")); package->close(); memdelete(package); package = NULL; diff --git a/platform/uwp/export/export.h b/platform/uwp/export/export.h index 2d6e02bb10..81bd848241 100644 --- a/platform/uwp/export/export.h +++ b/platform/uwp/export/export.h @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/uwp/gl_context_egl.cpp b/platform/uwp/gl_context_egl.cpp index 6c9efc26b4..57c4c5d572 100644 --- a/platform/uwp/gl_context_egl.cpp +++ b/platform/uwp/gl_context_egl.cpp @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -96,7 +97,7 @@ Error ContextEGL::initialize() { EGLContext context = EGL_NO_CONTEXT; EGLSurface surface = EGL_NO_SURFACE; EGLConfig config = nullptr; - EGLint contextAttribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE, EGL_NONE }; + EGLint contextAttribs[] = { EGL_CONTEXT_CLIENT_VERSION, 3, EGL_NONE, EGL_NONE }; try { diff --git a/platform/uwp/gl_context_egl.h b/platform/uwp/gl_context_egl.h index c397c1206b..908b8dceec 100644 --- a/platform/uwp/gl_context_egl.h +++ b/platform/uwp/gl_context_egl.h @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/uwp/joypad_uwp.cpp b/platform/uwp/joypad_uwp.cpp index dd57ed94ae..34e36f7b66 100644 --- a/platform/uwp/joypad_uwp.cpp +++ b/platform/uwp/joypad_uwp.cpp @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -40,7 +41,7 @@ void JoypadUWP::register_events() { ref new EventHandler<Gamepad ^>(this, &JoypadUWP::OnGamepadRemoved); } -uint32_t JoypadUWP::process_controllers(uint32_t p_last_id) { +void JoypadUWP::process_controllers() { for (int i = 0; i < MAX_CONTROLLERS; i++) { @@ -55,23 +56,21 @@ uint32_t JoypadUWP::process_controllers(uint32_t p_last_id) { int button_mask = (int)GamepadButtons::Menu; for (int j = 0; j < 14; j++) { - p_last_id = input->joy_button(p_last_id, controllers[i].id, j, (int)reading.Buttons & button_mask); + input->joy_button(controllers[i].id, j, (int)reading.Buttons & button_mask); button_mask *= 2; } - p_last_id = input->joy_axis(p_last_id, controllers[i].id, JOY_AXIS_0, axis_correct(reading.LeftThumbstickX)); - p_last_id = input->joy_axis(p_last_id, controllers[i].id, JOY_AXIS_1, axis_correct(reading.LeftThumbstickY, true)); - p_last_id = input->joy_axis(p_last_id, controllers[i].id, JOY_AXIS_2, axis_correct(reading.RightThumbstickX)); - p_last_id = input->joy_axis(p_last_id, controllers[i].id, JOY_AXIS_3, axis_correct(reading.RightThumbstickY, true)); - p_last_id = input->joy_axis(p_last_id, controllers[i].id, JOY_AXIS_4, axis_correct(reading.LeftTrigger, false, true)); - p_last_id = input->joy_axis(p_last_id, controllers[i].id, JOY_AXIS_5, axis_correct(reading.RightTrigger, false, true)); + input->joy_axis(controllers[i].id, JOY_AXIS_0, axis_correct(reading.LeftThumbstickX)); + input->joy_axis(controllers[i].id, JOY_AXIS_1, axis_correct(reading.LeftThumbstickY, true)); + input->joy_axis(controllers[i].id, JOY_AXIS_2, axis_correct(reading.RightThumbstickX)); + input->joy_axis(controllers[i].id, JOY_AXIS_3, axis_correct(reading.RightThumbstickY, true)); + input->joy_axis(controllers[i].id, JOY_AXIS_4, axis_correct(reading.LeftTrigger, false, true)); + input->joy_axis(controllers[i].id, JOY_AXIS_5, axis_correct(reading.RightTrigger, false, true)); break; } } } - - return p_last_id; } JoypadUWP::JoypadUWP() { diff --git a/platform/uwp/joypad_uwp.h b/platform/uwp/joypad_uwp.h index e5a961e70e..7337ffb3ce 100644 --- a/platform/uwp/joypad_uwp.h +++ b/platform/uwp/joypad_uwp.h @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -37,7 +38,7 @@ ref class JoypadUWP sealed { /* clang-format off */ internal: void register_events(); - uint32_t process_controllers(uint32_t p_last_id); + void process_controllers(); /* clang-format on */ JoypadUWP(); diff --git a/platform/uwp/os_uwp.cpp b/platform/uwp/os_uwp.cpp index 19ed2b57a3..28aaf9161b 100644 --- a/platform/uwp/os_uwp.cpp +++ b/platform/uwp/os_uwp.cpp @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -27,24 +28,22 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ #include "os_uwp.h" -#include "drivers/gles2/rasterizer_gles2.h" +#include "drivers/gles3/rasterizer_gles3.h" +#include "drivers/unix/ip_unix.h" #include "drivers/windows/dir_access_windows.h" #include "drivers/windows/file_access_windows.h" #include "drivers/windows/mutex_windows.h" +#include "drivers/windows/rw_lock_windows.h" #include "drivers/windows/semaphore_windows.h" -#include "main/main.h" -#include "os/memory_pool_dynamic_static.h" -#include "servers/audio_server.h" -#include "servers/visual/visual_server_raster.h" -#include "thread_uwp.h" -//#include "servers/visual/visual_server_wrap_mt.h" -#include "drivers/unix/ip_unix.h" #include "global_config.h" #include "io/marshalls.h" -#include "os/memory_pool_dynamic_prealloc.h" +#include "main/main.h" #include "platform/windows/packet_peer_udp_winsock.h" #include "platform/windows/stream_peer_winsock.h" #include "platform/windows/tcp_server_winsock.h" +#include "servers/audio_server.h" +#include "servers/visual/visual_server_raster.h" +#include "thread_uwp.h" #include <ppltasks.h> #include <wrl.h> @@ -148,9 +147,6 @@ const char *OSUWP::get_audio_driver_name(int p_driver) const { return AudioDriverManager::get_driver(p_driver)->get_name(); } -static MemoryPoolStatic *mempool_static = NULL; -static MemoryPoolDynamic *mempool_dynamic = NULL; - void OSUWP::initialize_core() { last_button_state = 0; @@ -160,32 +156,19 @@ void OSUWP::initialize_core() { ThreadUWP::make_default(); SemaphoreWindows::make_default(); MutexWindows::make_default(); + RWLockWindows::make_default(); FileAccess::make_default<FileAccessWindows>(FileAccess::ACCESS_RESOURCES); FileAccess::make_default<FileAccessWindows>(FileAccess::ACCESS_USERDATA); FileAccess::make_default<FileAccessWindows>(FileAccess::ACCESS_FILESYSTEM); - //FileAccessBufferedFA<FileAccessWindows>::make_default(); DirAccess::make_default<DirAccessWindows>(DirAccess::ACCESS_RESOURCES); DirAccess::make_default<DirAccessWindows>(DirAccess::ACCESS_USERDATA); DirAccess::make_default<DirAccessWindows>(DirAccess::ACCESS_FILESYSTEM); - //TCPServerWinsock::make_default(); - //StreamPeerWinsock::make_default(); - TCPServerWinsock::make_default(); StreamPeerWinsock::make_default(); PacketPeerUDPWinsock::make_default(); - mempool_static = new MemoryPoolStaticMalloc; -#if 1 - mempool_dynamic = memnew(MemoryPoolDynamicStatic); -#else -#define DYNPOOL_SIZE 4 * 1024 * 1024 - void *buffer = malloc(DYNPOOL_SIZE); - mempool_dynamic = memnew(MemoryPoolDynamicPrealloc(buffer, DYNPOOL_SIZE)); - -#endif - // We need to know how often the clock is updated if (!QueryPerformanceFrequency((LARGE_INTEGER *)&ticks_per_second)) ticks_per_second = 1000; @@ -258,13 +241,18 @@ void OSUWP::initialize(const VideoMode &p_desired, int p_video_driver, int p_aud set_video_mode(vm); gl_context->make_current(); - rasterizer = memnew(RasterizerGLES2); - visual_server = memnew(VisualServerRaster(rasterizer)); + RasterizerGLES3::register_config(); + RasterizerGLES3::make_current(); + + visual_server = memnew(VisualServerRaster); + // FIXME: Reimplement threaded rendering? Or remove? + /* if (get_render_thread_mode() != RENDER_THREAD_UNSAFE) { visual_server = memnew(VisualServerWrapMT(visual_server, get_render_thread_mode() == RENDER_SEPARATE_THREAD)); } + */ // physics_server = memnew(PhysicsServerSW); @@ -287,7 +275,7 @@ void OSUWP::initialize(const VideoMode &p_desired, int p_video_driver, int p_aud ERR_PRINT("Initializing audio failed."); } - power_manager = memnew(PowerWinRT); + power_manager = memnew(PowerUWP); managed_object->update_clipboard(); @@ -342,19 +330,9 @@ String OSUWP::get_clipboard() const { return ""; }; -void OSUWP::input_event(InputEvent &p_event) { - - p_event.ID = ++last_id; +void OSUWP::input_event(const Ref<InputEvent> &p_event) { input->parse_input_event(p_event); - - if (p_event.type == InputEvent::MOUSE_BUTTON && p_event.mouse_button.pressed && p_event.mouse_button.button_index > 3) { - - //send release for mouse wheel - p_event.mouse_button.pressed = false; - p_event.ID = ++last_id; - input->parse_input_event(p_event); - } }; void OSUWP::delete_main_loop() { @@ -383,14 +361,6 @@ void OSUWP::finalize() { if (gl_context) memdelete(gl_context); #endif - if (rasterizer) - memdelete(rasterizer); - - /* - if (debugger_connection_console) { - memdelete(debugger_connection_console); - } - */ memdelete(input); @@ -402,11 +372,8 @@ void OSUWP::finalize() { joypad = nullptr; } -void OSUWP::finalize_core() { - if (mempool_dynamic) - memdelete(mempool_dynamic); - delete mempool_static; +void OSUWP::finalize_core() { } void OSUWP::vprint(const char *p_format, va_list p_list, bool p_stderr) { @@ -534,7 +501,7 @@ OSUWP::MouseMode OSUWP::get_mouse_mode() const { return mouse_mode; } -Point2 OSUWP::get_mouse_pos() const { +Point2 OSUWP::get_mouse_position() const { return Point2(old_x, old_y); } @@ -680,7 +647,7 @@ uint64_t OSUWP::get_ticks_usec() const { void OSUWP::process_events() { - last_id = joypad->process_controllers(last_id); + joypad->process_controllers(); process_key_events(); } @@ -689,16 +656,18 @@ void OSUWP::process_key_events() { for (int i = 0; i < key_event_pos; i++) { KeyEvent &kev = key_event_buffer[i]; - InputEvent iev; - iev.type = InputEvent::KEY; - iev.key.mod = kev.mod_state; - iev.key.echo = kev.echo; - iev.key.scancode = kev.scancode; - iev.key.unicode = kev.unicode; - iev.key.pressed = kev.pressed; - - input_event(iev); + Ref<InputEventKey> key_event; + key_event.instance(); + key_event->set_alt(kev.alt); + key_event->set_shift(kev.shift); + key_event->set_control(kev.control); + key_event->set_echo(kev.echo); + key_event->set_scancode(kev.scancode); + key_event->set_unicode(kev.unicode); + key_event->set_pressed(kev.pressed); + + input_event(key_event); } key_event_pos = 0; } @@ -772,7 +741,7 @@ String OSUWP::get_executable_path() const { return ""; } -void OSUWP::set_icon(const Image &p_icon) { +void OSUWP::set_icon(const Ref<Image> &p_icon) { } bool OSUWP::has_environment(const String &p_var) const { @@ -882,15 +851,20 @@ String OSUWP::get_data_dir() const { return String(data_folder->Path->Data()).replace("\\", "/"); } -PowerState OSWinrt::get_power_state() { +bool OSUWP::check_feature_support(const String &p_feature) { + + return VisualServer::get_singleton()->has_os_feature(p_feature); +} + +PowerState OSUWP::get_power_state() { return power_manager->get_power_state(); } -int OSWinrt::get_power_seconds_left() { +int OSUWP::get_power_seconds_left() { return power_manager->get_power_seconds_left(); } -int OSWinrt::get_power_percent_left() { +int OSUWP::get_power_percent_left() { return power_manager->get_power_percent_left(); } @@ -907,7 +881,6 @@ OSUWP::OSUWP() { pressrc = 0; old_invalid = true; - last_id = 0; mouse_mode = MOUSE_MODE_VISIBLE; #ifdef STDOUT_FILE stdo = fopen("stdout.txt", "wb"); diff --git a/platform/uwp/os_uwp.h b/platform/uwp/os_uwp.h index ebbb8af39c..45b8eefdee 100644 --- a/platform/uwp/os_uwp.h +++ b/platform/uwp/os_uwp.h @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -37,7 +38,7 @@ #include "main/input_default.h" #include "os/input.h" #include "os/os.h" -#include "power_winrt.h" +#include "power_uwp.h" #include "servers/audio_server.h" #include "servers/physics/physics_server_sw.h" #include "servers/physics_2d/physics_2d_server_sw.h" @@ -62,7 +63,7 @@ public: CHAR_EVENT_MESSAGE }; - InputModifierState mod_state; + bool alt, shift, control; MessageType type; bool pressed; unsigned int scancode; @@ -92,9 +93,7 @@ private: bool outside; int old_x, old_y; Point2i center; - unsigned int last_id; VisualServer *visual_server; - Rasterizer *rasterizer; PhysicsServer *physics_server; Physics2DServer *physics_2d_server; int pressrc; @@ -107,7 +106,7 @@ private: AudioDriverXAudio2 audio_driver; - PowerWinRT *power_manager; + PowerUWP *power_manager; MouseMode mouse_mode; bool alt_mem; @@ -190,7 +189,7 @@ public: void set_mouse_mode(MouseMode p_mode); MouseMode get_mouse_mode() const; - virtual Point2 get_mouse_pos() const; + virtual Point2 get_mouse_position() const; virtual int get_mouse_button_state() const; virtual void set_window_title(const String &p_title); @@ -228,7 +227,7 @@ public: virtual String get_clipboard() const; void set_cursor_shape(CursorShape p_shape); - void set_icon(const Image &p_icon); + void set_icon(const Ref<Image> &p_icon); virtual String get_executable_path() const; @@ -237,6 +236,8 @@ public: virtual void move_window_to_foreground(); virtual String get_data_dir() const; + virtual bool check_feature_support(const String &p_feature); + void set_gl_context(ContextEGL *p_context); void screen_size_changed(); @@ -256,7 +257,7 @@ public: virtual bool get_swap_ok_cancel() { return true; } - void input_event(InputEvent &p_event); + void input_event(const Ref<InputEvent> &p_event); virtual PowerState get_power_state(); virtual int get_power_seconds_left(); diff --git a/platform/uwp/platform_config.h b/platform/uwp/platform_config.h index 7939e1c9ee..77d2c9cadb 100644 --- a/platform/uwp/platform_config.h +++ b/platform/uwp/platform_config.h @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/bb10/power_bb10.cpp b/platform/uwp/power_uwp.cpp index 29c1fe370d..ece07f84ad 100644 --- a/platform/bb10/power_bb10.cpp +++ b/platform/uwp/power_uwp.cpp @@ -1,11 +1,12 @@ /*************************************************************************/ -/* power_bb10.cpp */ +/* power_uwp.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -27,16 +28,26 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "power_bb10.h" +#include "power_uwp.h" -#include "core/error_macros.h" +PowerUWP::PowerUWP() + : nsecs_left(-1), percent_left(-1), power_state(POWERSTATE_UNKNOWN) { +} -bool PowerBB10::UpdatePowerInfo() { +PowerUWP::~PowerUWP() { +} +bool PowerUWP::UpdatePowerInfo() { + // TODO, WinRT: Battery info is available on at least one WinRT platform (Windows Phone 8). Implement UpdatePowerInfo as appropriate. */ + /* Notes from SDL: + - the Win32 function, GetSystemPowerStatus, is not available for use on WinRT + - Windows Phone 8 has a 'Battery' class, which is documented as available for C++ + - More info on WP8's Battery class can be found at http://msdn.microsoft.com/library/windowsphone/develop/jj207231 + */ return false; } -PowerState PowerBB10::get_power_state() { +PowerState PowerUWP::get_power_state() { if (UpdatePowerInfo()) { return power_state; } else { @@ -45,7 +56,7 @@ PowerState PowerBB10::get_power_state() { } } -int PowerBB10::get_power_seconds_left() { +int PowerUWP::get_power_seconds_left() { if (UpdatePowerInfo()) { return nsecs_left; } else { @@ -54,7 +65,7 @@ int PowerBB10::get_power_seconds_left() { } } -int PowerBB10::get_power_percent_left() { +int PowerUWP::get_power_percent_left() { if (UpdatePowerInfo()) { return percent_left; } else { @@ -62,10 +73,3 @@ int PowerBB10::get_power_percent_left() { return -1; } } - -PowerBB10::PowerBB10() - : nsecs_left(-1), percent_left(-1), power_state(POWERSTATE_UNKNOWN) { -} - -PowerBB10::~PowerBB10() { -} diff --git a/platform/bb10/power_bb10.h b/platform/uwp/power_uwp.h index 6c13f6e997..c23d712980 100644 --- a/platform/bb10/power_bb10.h +++ b/platform/uwp/power_uwp.h @@ -1,11 +1,12 @@ /*************************************************************************/ -/* power_bb10.h */ +/* power_uwp.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -27,10 +28,15 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef PLATFORM_BB10_POWER_BB10_H_ -#define PLATFORM_BB10_POWER_BB10_H_ +#ifndef PLATFORM_UWP_POWER_UWP_H_ +#define PLATFORM_UWP_POWER_UWP_H_ + +#include "os/dir_access.h" +#include "os/file_access.h" +#include "os/power.h" + +class PowerUWP { -class PowerBB10 { private: int nsecs_left; int percent_left; @@ -39,12 +45,12 @@ private: bool UpdatePowerInfo(); public: - PowerBB10(); - virtual ~PowerBB10(); + PowerUWP(); + virtual ~PowerUWP(); PowerState get_power_state(); int get_power_seconds_left(); int get_power_percent_left(); }; -#endif /* PLATFORM_BB10_POWER_BB10_H_ */ +#endif /* PLATFORM_UWP_POWER_UWP_H_ */ diff --git a/platform/uwp/thread_uwp.cpp b/platform/uwp/thread_uwp.cpp index ff079be375..436941707c 100644 --- a/platform/uwp/thread_uwp.cpp +++ b/platform/uwp/thread_uwp.cpp @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/uwp/thread_uwp.h b/platform/uwp/thread_uwp.h index b4e67c8b5c..0424f0f577 100644 --- a/platform/uwp/thread_uwp.h +++ b/platform/uwp/thread_uwp.h @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/windows/context_gl_win.cpp b/platform/windows/context_gl_win.cpp index d737502bf5..f8aed0ccab 100644 --- a/platform/windows/context_gl_win.cpp +++ b/platform/windows/context_gl_win.cpp @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -169,7 +170,7 @@ Error ContextGL_Win::initialize() { if (wglCreateContextAttribsARB == NULL) //OpenGL 3.0 is not supported { - MessageBox(NULL, "Cannot get Proc Adress for CreateContextAttribs", "ERROR", MB_OK | MB_ICONEXCLAMATION); + MessageBox(NULL, "Cannot get Proc Address for CreateContextAttribs", "ERROR", MB_OK | MB_ICONEXCLAMATION); wglDeleteContext(hRC); return ERR_CANT_CREATE; } diff --git a/platform/windows/context_gl_win.h b/platform/windows/context_gl_win.h index 383197ba7f..b3cab7806d 100644 --- a/platform/windows/context_gl_win.h +++ b/platform/windows/context_gl_win.h @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/windows/ctxgl_procaddr.cpp b/platform/windows/ctxgl_procaddr.cpp index 79c6f219f3..e01c3fc252 100644 --- a/platform/windows/ctxgl_procaddr.cpp +++ b/platform/windows/ctxgl_procaddr.cpp @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/windows/ctxgl_procaddr.h b/platform/windows/ctxgl_procaddr.h index da17fbcbbe..ecef01aadf 100644 --- a/platform/windows/ctxgl_procaddr.h +++ b/platform/windows/ctxgl_procaddr.h @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/windows/detect.py b/platform/windows/detect.py index 382783d6bc..5e56c1db49 100644 --- a/platform/windows/detect.py +++ b/platform/windows/detect.py @@ -242,7 +242,7 @@ def configure(env): env.Append(LINKFLAGS=['/SUBSYSTEM:CONSOLE']) env.Append(LINKFLAGS=['/DEBUG']) - env.Append(CCFLAGS=['/MT', '/Gd', '/GR', '/nologo']) + env.Append(CCFLAGS=['/MT', '/Gd', '/GR', '/nologo']) env.Append(CXXFLAGS=['/TP']) env.Append(CPPFLAGS=['/DMSVC', '/GR', ]) env.Append(CCFLAGS=['/I' + os.getenv("WindowsSdkDir") + "/Include"]) @@ -283,7 +283,7 @@ def configure(env): + " will be executed and inform you.") sys.exit() - # Forcing bits argument because MSVC does not have a flag to set this through SCons... it's different compilers (cl.exe's) called from the propper command prompt + # Forcing bits argument because MSVC does not have a flag to set this through SCons... it's different compilers (cl.exe's) called from the proper command prompt # that decide the architecture that is build for. Scons can only detect the os.getenviron (because vsvarsall.bat sets a lot of stuff for cl.exe to work with) env["bits"] = "32" env["x86_libtheora_opt_vc"] = True @@ -361,7 +361,7 @@ def configure(env): elif (env["target"] == "debug"): - env.Append(CCFLAGS=['-g', '-Wall', '-DDEBUG_ENABLED', '-DDEBUG_MEMORY_ENABLED']) + env.Append(CCFLAGS=['-g', '-DDEBUG_ENABLED', '-DDEBUG_MEMORY_ENABLED']) env["CC"] = mingw_prefix + "gcc" env['AS'] = mingw_prefix + "as" diff --git a/platform/windows/export/export.cpp b/platform/windows/export/export.cpp index bb51474a8c..c9271f6266 100644 --- a/platform/windows/export/export.cpp +++ b/platform/windows/export/export.cpp @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -26,28 +27,25 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "export.h" #include "editor/editor_export.h" -#include "platform/windows/logo.h" +#include "platform/windows/logo.gen.h" void register_windows_exporter() { -#if 0 - Image img(_windows_logo); - Ref<ImageTexture> logo = memnew( ImageTexture ); - logo->create_from_image(img); + Ref<EditorExportPlatformPC> platform; + platform.instance(); - { - Ref<EditorExportPlatformPC> exporter = Ref<EditorExportPlatformPC>( memnew(EditorExportPlatformPC) ); - exporter->set_binary_extension("exe"); - exporter->set_release_binary32("windows_32_release.exe"); - exporter->set_debug_binary32("windows_32_debug.exe"); - exporter->set_release_binary64("windows_64_release.exe"); - exporter->set_debug_binary64("windows_64_debug.exe"); - exporter->set_name("Windows Desktop"); - exporter->set_logo(logo); - EditorImportExport::get_singleton()->add_export_platform(exporter); - } + Ref<Image> img = memnew(Image(_windows_logo)); + Ref<ImageTexture> logo; + logo.instance(); + logo->create_from_image(img); + platform->set_logo(logo); + platform->set_name("Windows Desktop"); + platform->set_extension("exe"); + platform->set_release_32("windows_32_release.exe"); + platform->set_debug_32("windows_32_debug.exe"); + platform->set_release_64("windows_64_release.exe"); + platform->set_debug_64("windows_64_debug.exe"); -#endif + EditorExport::get_singleton()->add_export_platform(platform); } diff --git a/platform/windows/export/export.h b/platform/windows/export/export.h index b437efc48e..ea9113c674 100644 --- a/platform/windows/export/export.h +++ b/platform/windows/export/export.h @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/windows/godot.ico b/platform/windows/godot.ico Binary files differindex 3e52f2e52f..dd611e07da 100644 --- a/platform/windows/godot.ico +++ b/platform/windows/godot.ico diff --git a/platform/windows/godot_win.cpp b/platform/windows/godot_win.cpp index f8f5fe8231..df2d96e516 100644 --- a/platform/windows/godot_win.cpp +++ b/platform/windows/godot_win.cpp @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/windows/joypad.cpp b/platform/windows/joypad.cpp index 2472940ef3..7263e89c1a 100644 --- a/platform/windows/joypad.cpp +++ b/platform/windows/joypad.cpp @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -319,7 +320,7 @@ void JoypadWindows::probe_joypads() { } } -unsigned int JoypadWindows::process_joypads(unsigned int p_last_id) { +void JoypadWindows::process_joypads() { HRESULT hr; @@ -337,16 +338,16 @@ unsigned int JoypadWindows::process_joypads(unsigned int p_last_id) { int button_mask = XINPUT_GAMEPAD_DPAD_UP; for (int i = 0; i <= 16; i++) { - p_last_id = input->joy_button(p_last_id, joy.id, i, joy.state.Gamepad.wButtons & button_mask); + input->joy_button(joy.id, i, joy.state.Gamepad.wButtons & button_mask); button_mask = button_mask * 2; } - p_last_id = input->joy_axis(p_last_id, joy.id, JOY_AXIS_0, axis_correct(joy.state.Gamepad.sThumbLX, true)); - p_last_id = input->joy_axis(p_last_id, joy.id, JOY_AXIS_1, axis_correct(joy.state.Gamepad.sThumbLY, true, false, true)); - p_last_id = input->joy_axis(p_last_id, joy.id, JOY_AXIS_2, axis_correct(joy.state.Gamepad.sThumbRX, true)); - p_last_id = input->joy_axis(p_last_id, joy.id, JOY_AXIS_3, axis_correct(joy.state.Gamepad.sThumbRY, true, false, true)); - p_last_id = input->joy_axis(p_last_id, joy.id, JOY_AXIS_4, axis_correct(joy.state.Gamepad.bLeftTrigger, true, true)); - p_last_id = input->joy_axis(p_last_id, joy.id, JOY_AXIS_5, axis_correct(joy.state.Gamepad.bRightTrigger, true, true)); + input->joy_axis(joy.id, JOY_AXIS_0, axis_correct(joy.state.Gamepad.sThumbLX, true)); + input->joy_axis(joy.id, JOY_AXIS_1, axis_correct(joy.state.Gamepad.sThumbLY, true, false, true)); + input->joy_axis(joy.id, JOY_AXIS_2, axis_correct(joy.state.Gamepad.sThumbRX, true)); + input->joy_axis(joy.id, JOY_AXIS_3, axis_correct(joy.state.Gamepad.sThumbRY, true, false, true)); + input->joy_axis(joy.id, JOY_AXIS_4, axis_correct(joy.state.Gamepad.bLeftTrigger, true, true)); + input->joy_axis(joy.id, JOY_AXIS_5, axis_correct(joy.state.Gamepad.bRightTrigger, true, true)); joy.last_packet = joy.state.dwPacketNumber; } uint64_t timestamp = input->get_joy_vibration_timestamp(joy.id); @@ -384,7 +385,7 @@ unsigned int JoypadWindows::process_joypads(unsigned int p_last_id) { continue; } - p_last_id = post_hat(p_last_id, joy->id, js.rgdwPOV[0]); + post_hat(joy->id, js.rgdwPOV[0]); for (int j = 0; j < 128; j++) { @@ -392,14 +393,14 @@ unsigned int JoypadWindows::process_joypads(unsigned int p_last_id) { if (!joy->last_buttons[j]) { - p_last_id = input->joy_button(p_last_id, joy->id, j, true); + input->joy_button(joy->id, j, true); joy->last_buttons[j] = true; } } else { if (joy->last_buttons[j]) { - p_last_id = input->joy_button(p_last_id, joy->id, j, false); + input->joy_button(joy->id, j, false); joy->last_buttons[j] = false; } } @@ -414,16 +415,16 @@ unsigned int JoypadWindows::process_joypads(unsigned int p_last_id) { for (int k = 0; k < count; k++) { if (joy->joy_axis[j] == axes[k]) { - p_last_id = input->joy_axis(p_last_id, joy->id, j, axis_correct(values[k])); + input->joy_axis(joy->id, j, axis_correct(values[k])); break; }; }; }; } - return p_last_id; + return; } -unsigned int JoypadWindows::post_hat(unsigned int p_last_id, int p_device, DWORD p_dpad) { +void JoypadWindows::post_hat(int p_device, DWORD p_dpad) { int dpad_val = 0; @@ -462,7 +463,7 @@ unsigned int JoypadWindows::post_hat(unsigned int p_last_id, int p_device, DWORD dpad_val = (InputDefault::HAT_MASK_LEFT | InputDefault::HAT_MASK_UP); } - return input->joy_hat(p_last_id, p_device, dpad_val); + input->joy_hat(p_device, dpad_val); }; InputDefault::JoyAxis JoypadWindows::axis_correct(int p_val, bool p_xinput, bool p_trigger, bool p_negate) const { diff --git a/platform/windows/joypad.h b/platform/windows/joypad.h index 7e4f6ff328..7cd791e78f 100644 --- a/platform/windows/joypad.h +++ b/platform/windows/joypad.h @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -53,7 +54,7 @@ public: ~JoypadWindows(); void probe_joypads(); - unsigned int process_joypads(unsigned int p_last_id); + void process_joypads(); private: enum { @@ -130,7 +131,7 @@ private: void load_xinput(); void unload_xinput(); - unsigned int post_hat(unsigned int p_last_id, int p_device, DWORD p_dpad); + void post_hat(int p_device, DWORD p_dpad); bool have_device(const GUID &p_guid); bool is_xinput_device(const GUID *p_guid); diff --git a/platform/windows/key_mapping_win.cpp b/platform/windows/key_mapping_win.cpp index 51cdba65d5..bffacb3a82 100644 --- a/platform/windows/key_mapping_win.cpp +++ b/platform/windows/key_mapping_win.cpp @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/windows/key_mapping_win.h b/platform/windows/key_mapping_win.h index fbc79635c2..af91676dff 100644 --- a/platform/windows/key_mapping_win.h +++ b/platform/windows/key_mapping_win.h @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/windows/lang_table.h b/platform/windows/lang_table.h index 7fe509d3e0..7cf2bb391b 100644 --- a/platform/windows/lang_table.h +++ b/platform/windows/lang_table.h @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp index 2046ae9f44..e94529dd94 100644 --- a/platform/windows/os_windows.cpp +++ b/platform/windows/os_windows.cpp @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -36,15 +37,15 @@ #include "drivers/windows/rw_lock_windows.h" #include "drivers/windows/semaphore_windows.h" #include "drivers/windows/thread_windows.h" -#include "servers/audio_server.h" -#include "servers/visual/visual_server_raster.h" -//#include "servers/visual/visual_server_wrap_mt.h" #include "global_config.h" #include "io/marshalls.h" #include "joypad.h" #include "lang_table.h" #include "main/main.h" #include "packet_peer_udp_winsock.h" +#include "servers/audio_server.h" +#include "servers/visual/visual_server_raster.h" +#include "servers/visual/visual_server_wrap_mt.h" #include "stream_peer_winsock.h" #include "tcp_server_winsock.h" @@ -214,15 +215,11 @@ bool OS_Windows::can_draw() const { void OS_Windows::_touch_event(bool p_pressed, int p_x, int p_y, int idx) { - InputEvent event; - event.type = InputEvent::SCREEN_TOUCH; - event.ID = ++last_id; - event.screen_touch.index = idx; - - event.screen_touch.pressed = p_pressed; - - event.screen_touch.x = p_x; - event.screen_touch.y = p_y; + Ref<InputEventScreenTouch> event; + event.instance(); + event->set_index(idx); + event->set_pressed(p_pressed); + event->set_position(Vector2(p_x, p_y)); if (main_loop) { input->parse_input_event(event); @@ -231,13 +228,10 @@ void OS_Windows::_touch_event(bool p_pressed, int p_x, int p_y, int idx) { void OS_Windows::_drag_event(int p_x, int p_y, int idx) { - InputEvent event; - event.type = InputEvent::SCREEN_DRAG; - event.ID = ++last_id; - event.screen_drag.index = idx; - - event.screen_drag.x = p_x; - event.screen_drag.y = p_y; + Ref<InputEventScreenDrag> event; + event.instance(); + event->set_index(idx); + event->set_position(Vector2(p_x, p_y)); if (main_loop) input->parse_input_event(event); @@ -368,23 +362,23 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) }; */ - InputEvent event; - event.type = InputEvent::MOUSE_MOTION; - event.ID = ++last_id; - InputEventMouseMotion &mm = event.mouse_motion; + Ref<InputEventMouseMotion> mm; + mm.instance(); + + mm->set_control((wParam & MK_CONTROL) != 0); + mm->set_shift((wParam & MK_SHIFT) != 0); + mm->set_alt(alt_mem); - mm.mod.control = (wParam & MK_CONTROL) != 0; - mm.mod.shift = (wParam & MK_SHIFT) != 0; - mm.mod.alt = alt_mem; + int bmask = 0; + bmask |= (wParam & MK_LBUTTON) ? (1 << 0) : 0; + bmask |= (wParam & MK_RBUTTON) ? (1 << 1) : 0; + bmask |= (wParam & MK_MBUTTON) ? (1 << 2) : 0; + mm->set_button_mask(bmask); - mm.button_mask |= (wParam & MK_LBUTTON) ? (1 << 0) : 0; - mm.button_mask |= (wParam & MK_RBUTTON) ? (1 << 1) : 0; - mm.button_mask |= (wParam & MK_MBUTTON) ? (1 << 2) : 0; - last_button_state = mm.button_mask; - /*mm.button_mask|=(wParam&MK_XBUTTON1)?(1<<5):0; - mm.button_mask|=(wParam&MK_XBUTTON2)?(1<<6):0;*/ - mm.x = GET_X_LPARAM(lParam); - mm.y = GET_Y_LPARAM(lParam); + last_button_state = mm->get_button_mask(); + /*mm->get_button_mask()|=(wParam&MK_XBUTTON1)?(1<<5):0; + mm->get_button_mask()|=(wParam&MK_XBUTTON2)?(1<<6):0;*/ + mm->set_position(Vector2(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); if (mouse_mode == MOUSE_MODE_CAPTURED) { @@ -392,35 +386,33 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) old_x = c.x; old_y = c.y; - if (Point2i(mm.x, mm.y) == c) { + if (mm->get_position() == c) { center = c; return 0; } - Point2i ncenter(mm.x, mm.y); + Point2i ncenter = mm->get_position(); center = ncenter; POINT pos = { (int)c.x, (int)c.y }; ClientToScreen(hWnd, &pos); SetCursorPos(pos.x, pos.y); } - input->set_mouse_pos(Point2(mm.x, mm.y)); - mm.speed_x = input->get_last_mouse_speed().x; - mm.speed_y = input->get_last_mouse_speed().y; + input->set_mouse_position(mm->get_position()); + mm->set_speed(input->get_last_mouse_speed()); if (old_invalid) { - old_x = mm.x; - old_y = mm.y; + old_x = mm->get_position().x; + old_y = mm->get_position().y; old_invalid = false; } - mm.relative_x = mm.x - old_x; - mm.relative_y = mm.y - old_y; - old_x = mm.x; - old_y = mm.y; + mm->set_relative(Vector2(mm->get_position() - Vector2(old_x, old_y))); + old_x = mm->get_position().x; + old_y = mm->get_position().y; if (window_has_focus && main_loop) - input->parse_input_event(event); + input->parse_input_event(mm); } break; case WM_LBUTTONDOWN: @@ -449,112 +441,110 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) }; */ - InputEvent event; - event.type = InputEvent::MOUSE_BUTTON; - event.ID = ++last_id; - InputEventMouseButton &mb = event.mouse_button; + Ref<InputEventMouseButton> mb; + mb.instance(); switch (uMsg) { case WM_LBUTTONDOWN: { - mb.pressed = true; - mb.button_index = 1; + mb->set_pressed(true); + mb->set_button_index(1); } break; case WM_LBUTTONUP: { - mb.pressed = false; - mb.button_index = 1; + mb->set_pressed(false); + mb->set_button_index(1); } break; case WM_MBUTTONDOWN: { - mb.pressed = true; - mb.button_index = 3; + mb->set_pressed(true); + mb->set_button_index(3); } break; case WM_MBUTTONUP: { - mb.pressed = false; - mb.button_index = 3; + mb->set_pressed(false); + mb->set_button_index(3); } break; case WM_RBUTTONDOWN: { - mb.pressed = true; - mb.button_index = 2; + mb->set_pressed(true); + mb->set_button_index(2); } break; case WM_RBUTTONUP: { - mb.pressed = false; - mb.button_index = 2; + mb->set_pressed(false); + mb->set_button_index(2); } break; case WM_LBUTTONDBLCLK: { - mb.pressed = true; - mb.button_index = 1; - mb.doubleclick = true; + mb->set_pressed(true); + mb->set_button_index(1); + mb->set_doubleclick(true); } break; case WM_RBUTTONDBLCLK: { - mb.pressed = true; - mb.button_index = 2; - mb.doubleclick = true; + mb->set_pressed(true); + mb->set_button_index(2); + mb->set_doubleclick(true); } break; case WM_MOUSEWHEEL: { - mb.pressed = true; + mb->set_pressed(true); int motion = (short)HIWORD(wParam); if (!motion) return 0; if (motion > 0) - mb.button_index = BUTTON_WHEEL_UP; + mb->set_button_index(BUTTON_WHEEL_UP); else - mb.button_index = BUTTON_WHEEL_DOWN; + mb->set_button_index(BUTTON_WHEEL_DOWN); } break; case WM_MOUSEHWHEEL: { - mb.pressed = true; + mb->set_pressed(true); int motion = (short)HIWORD(wParam); if (!motion) return 0; - if (motion < 0) - mb.button_index = BUTTON_WHEEL_LEFT; - else - mb.button_index = BUTTON_WHEEL_RIGHT; + if (motion < 0) { + mb->set_button_index(BUTTON_WHEEL_LEFT); + mb->set_factor(fabs((double)motion / (double)WHEEL_DELTA)); + } else { + mb->set_button_index(BUTTON_WHEEL_RIGHT); + mb->set_factor(fabs((double)motion / (double)WHEEL_DELTA)); + } } break; /* case WM_XBUTTONDOWN: { - mb.pressed=true; - mb.button_index=(HIWORD(wParam)==XBUTTON1)?6:7; + mb->is_pressed()=true; + mb->get_button_index()=(HIWORD(wParam)==XBUTTON1)?6:7; } break; case WM_XBUTTONUP: - mb.pressed=true; - mb.button_index=(HIWORD(wParam)==XBUTTON1)?6:7; + mb->is_pressed()=true; + mb->get_button_index()=(HIWORD(wParam)==XBUTTON1)?6:7; } break;*/ default: { return 0; } } - mb.mod.control = (wParam & MK_CONTROL) != 0; - mb.mod.shift = (wParam & MK_SHIFT) != 0; - mb.mod.alt = alt_mem; - //mb.mod.alt=(wParam&MK_MENU)!=0; - mb.button_mask |= (wParam & MK_LBUTTON) ? (1 << 0) : 0; - mb.button_mask |= (wParam & MK_RBUTTON) ? (1 << 1) : 0; - mb.button_mask |= (wParam & MK_MBUTTON) ? (1 << 2) : 0; - - last_button_state = mb.button_mask; + mb->set_control((wParam & MK_CONTROL) != 0); + mb->set_shift((wParam & MK_SHIFT) != 0); + mb->set_alt(alt_mem); + //mb->get_alt()=(wParam&MK_MENU)!=0; + int bmask = 0; + bmask |= (wParam & MK_LBUTTON) ? (1 << 0) : 0; + bmask |= (wParam & MK_RBUTTON) ? (1 << 1) : 0; + bmask |= (wParam & MK_MBUTTON) ? (1 << 2) : 0; + mb->set_button_mask(bmask); + + last_button_state = mb->get_button_mask(); /* - mb.button_mask|=(wParam&MK_XBUTTON1)?(1<<5):0; - mb.button_mask|=(wParam&MK_XBUTTON2)?(1<<6):0;*/ - mb.x = GET_X_LPARAM(lParam); - mb.y = GET_Y_LPARAM(lParam); + mb->get_button_mask()|=(wParam&MK_XBUTTON1)?(1<<5):0; + mb->get_button_mask()|=(wParam&MK_XBUTTON2)?(1<<6):0;*/ + mb->set_position(Vector2(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))); if (mouse_mode == MOUSE_MODE_CAPTURED) { - mb.x = old_x; - mb.y = old_y; + mb->set_position(Vector2(old_x, old_y)); } - mb.global_x = mb.x; - mb.global_y = mb.y; - if (uMsg != WM_MOUSEWHEEL) { - if (mb.pressed) { + if (mb->is_pressed()) { if (++pressrc > 0) SetCapture(hWnd); @@ -568,22 +558,23 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) } else if (mouse_mode != MOUSE_MODE_CAPTURED) { // for reasons unknown to mankind, wheel comes in screen cordinates POINT coords; - coords.x = mb.x; - coords.y = mb.y; + coords.x = mb->get_position().x; + coords.y = mb->get_position().y; ScreenToClient(hWnd, &coords); - mb.x = coords.x; - mb.y = coords.y; + mb->set_position(Vector2(coords.x, coords.y)); } + mb->set_global_position(mb->get_position()); + if (main_loop) { - input->parse_input_event(event); - if (mb.pressed && mb.button_index > 3) { + input->parse_input_event(mb); + if (mb->is_pressed() && mb->get_button_index() > 3) { //send release for mouse wheel - mb.pressed = false; - event.ID = ++last_id; - input->parse_input_event(event); + Ref<InputEventMouseButton> mbd = mb->duplicate(); + mbd->set_pressed(false); + input->parse_input_event(mbd); } } } @@ -639,10 +630,10 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) // Make sure we don't include modifiers for the modifier key itself. KeyEvent ke; - ke.mod_state.shift = (wParam != VK_SHIFT) ? shift_mem : false; - ke.mod_state.alt = (!(wParam == VK_MENU && (uMsg == WM_KEYDOWN || uMsg == WM_SYSKEYDOWN))) ? alt_mem : false; - ke.mod_state.control = (wParam != VK_CONTROL) ? control_mem : false; - ke.mod_state.meta = meta_mem; + ke.shift = (wParam != VK_SHIFT) ? shift_mem : false; + ke.alt = (!(wParam == VK_MENU && (uMsg == WM_KEYDOWN || uMsg == WM_SYSKEYDOWN))) ? alt_mem : false; + ke.control = (wParam != VK_CONTROL) ? control_mem : false; + ke.meta = meta_mem; ke.uMsg = uMsg; if (ke.uMsg == WM_SYSKEYDOWN) @@ -778,24 +769,25 @@ void OS_Windows::process_key_events() { case WM_CHAR: { if ((i == 0 && ke.uMsg == WM_CHAR) || (i > 0 && key_event_buffer[i - 1].uMsg == WM_CHAR)) { - InputEvent event; - event.type = InputEvent::KEY; - event.ID = ++last_id; - InputEventKey &k = event.key; - - k.mod = ke.mod_state; - k.pressed = true; - k.scancode = KeyMappingWindows::get_keysym(ke.wParam); - k.unicode = ke.wParam; - if (k.unicode && gr_mem) { - k.mod.alt = false; - k.mod.control = false; + Ref<InputEventKey> k; + k.instance(); + + k->set_shift(ke.shift); + k->set_alt(ke.alt); + k->set_control(ke.control); + k->set_metakey(ke.meta); + k->set_pressed(true); + k->set_scancode(KeyMappingWindows::get_keysym(ke.wParam)); + k->set_unicode(ke.wParam); + if (k->get_unicode() && gr_mem) { + k->set_alt(false); + k->set_control(false); } - if (k.unicode < 32) - k.unicode = 0; + if (k->get_unicode() < 32) + k->set_unicode(0); - input->parse_input_event(event); + input->parse_input_event(k); } //do nothing @@ -803,28 +795,32 @@ void OS_Windows::process_key_events() { case WM_KEYUP: case WM_KEYDOWN: { - InputEvent event; - event.type = InputEvent::KEY; - event.ID = ++last_id; - InputEventKey &k = event.key; + Ref<InputEventKey> k; + k.instance(); + + k->set_shift(ke.shift); + k->set_alt(ke.alt); + k->set_control(ke.control); + k->set_metakey(ke.meta); - k.mod = ke.mod_state; - k.pressed = (ke.uMsg == WM_KEYDOWN); + k->set_pressed(ke.uMsg == WM_KEYDOWN); - k.scancode = KeyMappingWindows::get_keysym(ke.wParam); - if (i + 1 < key_event_pos && key_event_buffer[i + 1].uMsg == WM_CHAR) - k.unicode = key_event_buffer[i + 1].wParam; - if (k.unicode && gr_mem) { - k.mod.alt = false; - k.mod.control = false; + k->set_scancode(KeyMappingWindows::get_keysym(ke.wParam)); + + if (i + 1 < key_event_pos && key_event_buffer[i + 1].uMsg == WM_CHAR) { + k->set_unicode(key_event_buffer[i + 1].wParam); + } + if (k->get_unicode() && gr_mem) { + k->set_alt(false); + k->set_control(false); } - if (k.unicode < 32) - k.unicode = 0; + if (k->get_unicode() < 32) + k->set_unicode(0); - k.echo = (ke.uMsg == WM_KEYDOWN && (ke.lParam & (1 << 30))); + k->set_echo((ke.uMsg == WM_KEYDOWN && (ke.lParam & (1 << 30)))); - input->parse_input_event(event); + input->parse_input_event(k); } break; } @@ -893,8 +889,8 @@ BOOL CALLBACK OS_Windows::MonitorEnumProc(HMONITOR hMonitor, HDC hdcMonitor, LPR MonitorInfo minfo; minfo.hMonitor = hMonitor; minfo.hdcMonitor = hdcMonitor; - minfo.rect.pos.x = lprcMonitor->left; - minfo.rect.pos.y = lprcMonitor->top; + minfo.rect.position.x = lprcMonitor->left; + minfo.rect.position.y = lprcMonitor->top; minfo.rect.size.x = lprcMonitor->right - lprcMonitor->left; minfo.rect.size.y = lprcMonitor->bottom - lprcMonitor->top; @@ -1033,12 +1029,10 @@ void OS_Windows::initialize(const VideoMode &p_desired, int p_video_driver, int #endif visual_server = memnew(VisualServerRaster); - // FIXME: Reimplement threaded rendering? Or remove? - /* - if (get_render_thread_mode()!=RENDER_THREAD_UNSAFE) { - visual_server =memnew(VisualServerWrapMT(visual_server,get_render_thread_mode()==RENDER_SEPARATE_THREAD)); + if (get_render_thread_mode() != RENDER_THREAD_UNSAFE) { + + visual_server = memnew(VisualServerWrapMT(visual_server, get_render_thread_mode() == RENDER_SEPARATE_THREAD)); } - */ physics_server = memnew(PhysicsServerSW); physics_server->init(); @@ -1324,7 +1318,7 @@ void OS_Windows::warp_mouse_pos(const Point2 &p_to) { } } -Point2 OS_Windows::get_mouse_pos() const { +Point2 OS_Windows::get_mouse_position() const { return Point2(old_x, old_y); } @@ -1374,7 +1368,7 @@ void OS_Windows::set_current_screen(int p_screen) { Point2 OS_Windows::get_screen_position(int p_screen) const { ERR_FAIL_INDEX_V(p_screen, monitor_info.size(), Point2()); - return Vector2(monitor_info[p_screen].rect.pos); + return Vector2(monitor_info[p_screen].rect.position); } Size2 OS_Windows::get_screen_size(int p_screen) const { @@ -1589,6 +1583,32 @@ bool OS_Windows::get_borderless_window() { return video_mode.borderless_window; } +Error OS_Windows::open_dynamic_library(const String p_path, void *&p_library_handle) { + p_library_handle = (void *)LoadLibrary(p_path.utf8().get_data()); + if (!p_library_handle) { + ERR_EXPLAIN("Can't open dynamic library: " + p_path + ". Error: " + String::num(GetLastError())); + ERR_FAIL_V(ERR_CANT_OPEN); + } + return OK; +} + +Error OS_Windows::close_dynamic_library(void *p_library_handle) { + if (!FreeLibrary((HMODULE)p_library_handle)) { + return FAILED; + } + return OK; +} + +Error OS_Windows::get_dynamic_library_symbol_handle(void *p_library_handle, const String p_name, void *&p_symbol_handle) { + char *error; + p_symbol_handle = (void *)GetProcAddress((HMODULE)p_library_handle, p_name.utf8().get_data()); + if (!p_symbol_handle) { + ERR_EXPLAIN("Can't resolve symbol " + p_name + ". Error: " + String::num(GetLastError())); + ERR_FAIL_V(ERR_CANT_RESOLVE); + } + return OK; +} + void OS_Windows::request_attention() { FLASHWINFO info; @@ -1819,7 +1839,7 @@ void OS_Windows::process_events() { MSG msg; - last_id = joypad->process_joypads(last_id); + joypad->process_joypads(); while (PeekMessageW(&msg, NULL, 0, 0, PM_REMOVE)) { @@ -1970,17 +1990,17 @@ String OS_Windows::get_executable_path() const { wchar_t bufname[4096]; GetModuleFileNameW(NULL, bufname, 4096); String s = bufname; - print_line("EXEC PATHP??: " + s); return s; } -void OS_Windows::set_icon(const Image &p_icon) { +void OS_Windows::set_icon(const Ref<Image> &p_icon) { - Image icon = p_icon; - if (icon.get_format() != Image::FORMAT_RGBA8) - icon.convert(Image::FORMAT_RGBA8); - int w = icon.get_width(); - int h = icon.get_height(); + ERR_FAIL_COND(!p_icon.is_valid()); + Ref<Image> icon = p_icon->duplicate(); + if (icon->get_format() != Image::FORMAT_RGBA8) + icon->convert(Image::FORMAT_RGBA8); + int w = icon->get_width(); + int h = icon->get_height(); /* Create temporary bitmap buffer */ int icon_len = 40 + h * w * 4; @@ -2001,7 +2021,7 @@ void OS_Windows::set_icon(const Image &p_icon) { encode_uint32(0, &icon_bmp[36]); uint8_t *wr = &icon_bmp[40]; - PoolVector<uint8_t>::Read r = icon.get_data().read(); + PoolVector<uint8_t>::Read r = icon->get_data().read(); for (int i = 0; i < h; i++) { @@ -2303,7 +2323,6 @@ OS_Windows::OS_Windows(HINSTANCE _hInstance) { hInstance = _hInstance; pressrc = 0; old_invalid = true; - last_id = 0; mouse_mode = MOUSE_MODE_VISIBLE; #ifdef STDOUT_FILE stdo = fopen("stdout.txt", "wb"); diff --git a/platform/windows/os_windows.h b/platform/windows/os_windows.h index e7376d6800..6cbdd58830 100644 --- a/platform/windows/os_windows.h +++ b/platform/windows/os_windows.h @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -67,7 +68,7 @@ class OS_Windows : public OS { struct KeyEvent { - InputModifierState mod_state; + bool alt, shift, control, meta; UINT uMsg; WPARAM wParam; LPARAM lParam; @@ -83,7 +84,6 @@ class OS_Windows : public OS { bool outside; int old_x, old_y; Point2i center; - unsigned int last_id; #if defined(OPENGL_ENABLED) ContextGL_Win *gl_context; #endif @@ -191,7 +191,7 @@ public: MouseMode get_mouse_mode() const; virtual void warp_mouse_pos(const Point2 &p_to); - virtual Point2 get_mouse_pos() const; + virtual Point2 get_mouse_position() const; virtual int get_mouse_button_state() const; virtual void set_window_title(const String &p_title); @@ -223,6 +223,10 @@ public: virtual void set_borderless_window(int p_borderless); virtual bool get_borderless_window(); + virtual Error open_dynamic_library(const String p_path, void *&p_library_handle); + virtual Error close_dynamic_library(void *p_library_handle); + virtual Error get_dynamic_library_symbol_handle(void *p_library_handle, const String p_name, void *&p_symbol_handle); + virtual MainLoop *get_main_loop() const; virtual String get_name(); @@ -250,7 +254,7 @@ public: virtual String get_clipboard() const; void set_cursor_shape(CursorShape p_shape); - void set_icon(const Image &p_icon); + void set_icon(const Ref<Image> &p_icon); virtual String get_executable_path() const; diff --git a/platform/windows/packet_peer_udp_winsock.cpp b/platform/windows/packet_peer_udp_winsock.cpp index 2df8addece..f3b91c1b56 100644 --- a/platform/windows/packet_peer_udp_winsock.cpp +++ b/platform/windows/packet_peer_udp_winsock.cpp @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -82,7 +83,7 @@ Error PacketPeerUDPWinsock::put_packet(const uint8_t *p_buffer, int p_buffer_siz struct sockaddr_storage addr; size_t addr_size = _set_sockaddr(&addr, peer_addr, peer_port, sock_type); - _set_blocking(true); + _set_sock_blocking(blocking); errno = 0; int err; @@ -90,7 +91,9 @@ Error PacketPeerUDPWinsock::put_packet(const uint8_t *p_buffer, int p_buffer_siz if (WSAGetLastError() != WSAEWOULDBLOCK) { return FAILED; - }; + } else if (!blocking) { + return ERR_UNAVAILABLE; + } } return OK; @@ -101,15 +104,13 @@ int PacketPeerUDPWinsock::get_max_packet_size() const { return 512; // uhm maybe not } -void PacketPeerUDPWinsock::_set_blocking(bool p_blocking) { - //am no windows expert - //hope this is the right thing +void PacketPeerUDPWinsock::_set_sock_blocking(bool p_blocking) { - if (blocking == p_blocking) + if (sock_blocking == p_blocking) return; - blocking = p_blocking; - unsigned long par = blocking ? 0 : 1; + sock_blocking = p_blocking; + unsigned long par = sock_blocking ? 0 : 1; if (ioctlsocket(sockfd, FIONBIO, &par)) { perror("setting non-block mode"); //close(); @@ -139,8 +140,6 @@ Error PacketPeerUDPWinsock::listen(int p_port, IP_Address p_bind_address, int p_ return ERR_UNAVAILABLE; } - blocking = true; - printf("UDP Connection listening on port %i\n", p_port); rb.resize(nearest_shift(p_recv_buffer_size)); return OK; @@ -166,7 +165,7 @@ Error PacketPeerUDPWinsock::_poll(bool p_wait) { return FAILED; } - _set_blocking(p_wait); + _set_sock_blocking(p_wait); struct sockaddr_storage from = { 0 }; int len = sizeof(struct sockaddr_storage); @@ -204,6 +203,8 @@ Error PacketPeerUDPWinsock::_poll(bool p_wait) { len = sizeof(struct sockaddr_storage); ++queue_count; + if (p_wait) + break; }; if (ret == SOCKET_ERROR) { @@ -252,6 +253,9 @@ int PacketPeerUDPWinsock::_get_socket() { sockfd = _socket_create(sock_type, SOCK_DGRAM, IPPROTO_UDP); + if (sockfd != -1) + _set_sock_blocking(false); + return sockfd; } @@ -273,6 +277,8 @@ PacketPeerUDP *PacketPeerUDPWinsock::_create() { PacketPeerUDPWinsock::PacketPeerUDPWinsock() { + blocking = true; + sock_blocking = true; sockfd = -1; packet_port = 0; queue_count = 0; diff --git a/platform/windows/packet_peer_udp_winsock.h b/platform/windows/packet_peer_udp_winsock.h index 62107364af..ceb6df71aa 100644 --- a/platform/windows/packet_peer_udp_winsock.h +++ b/platform/windows/packet_peer_udp_winsock.h @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -45,6 +46,7 @@ class PacketPeerUDPWinsock : public PacketPeerUDP { mutable int packet_port; mutable int queue_count; int sockfd; + bool sock_blocking; IP::Type sock_type; IP_Address peer_addr; @@ -54,8 +56,7 @@ class PacketPeerUDPWinsock : public PacketPeerUDP { static PacketPeerUDP *_create(); - bool blocking; - void _set_blocking(bool p_blocking); + void _set_sock_blocking(bool p_blocking); Error _poll(bool p_wait); diff --git a/platform/windows/platform_config.h b/platform/windows/platform_config.h index 0e16753156..a0fc65ca89 100644 --- a/platform/windows/platform_config.h +++ b/platform/windows/platform_config.h @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/windows/power_windows.cpp b/platform/windows/power_windows.cpp index d4641cd4ec..428bc5dcc2 100644 --- a/platform/windows/power_windows.cpp +++ b/platform/windows/power_windows.cpp @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -27,6 +28,31 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ +/* +Adapted from corresponding SDL 2.0 code. +*/ + +/* + Simple DirectMedia Layer + Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org> + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + #include "power_windows.h" // CODE CHUNK IMPORTED FROM SDL 2.0 diff --git a/platform/windows/power_windows.h b/platform/windows/power_windows.h index 5c26faa3d1..164f1d7d95 100644 --- a/platform/windows/power_windows.h +++ b/platform/windows/power_windows.h @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/windows/stream_peer_winsock.cpp b/platform/windows/stream_peer_winsock.cpp index abf182c72a..18c5a40b80 100644 --- a/platform/windows/stream_peer_winsock.cpp +++ b/platform/windows/stream_peer_winsock.cpp @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/windows/stream_peer_winsock.h b/platform/windows/stream_peer_winsock.h index c8c2dd4feb..aa60a6500b 100644 --- a/platform/windows/stream_peer_winsock.h +++ b/platform/windows/stream_peer_winsock.h @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/windows/tcp_server_winsock.cpp b/platform/windows/tcp_server_winsock.cpp index 67713f5d1c..3292813d4e 100644 --- a/platform/windows/tcp_server_winsock.cpp +++ b/platform/windows/tcp_server_winsock.cpp @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/windows/tcp_server_winsock.h b/platform/windows/tcp_server_winsock.h index d7b1aee054..7e5d1e750e 100644 --- a/platform/windows/tcp_server_winsock.h +++ b/platform/windows/tcp_server_winsock.h @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/x11/context_gl_x11.cpp b/platform/x11/context_gl_x11.cpp index 41d110a1e1..ddf17481b1 100644 --- a/platform/x11/context_gl_x11.cpp +++ b/platform/x11/context_gl_x11.cpp @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -151,8 +152,6 @@ Error ContextGL_X11::initialize() { XSync(x11_display, False); XSetErrorHandler(oldHandler); - print_line("ALL IS GOOD"); - glXMakeCurrent(x11_display, x11_window, p->glx_context); /* diff --git a/platform/x11/context_gl_x11.h b/platform/x11/context_gl_x11.h index be0f4c822c..acb3f38894 100644 --- a/platform/x11/context_gl_x11.h +++ b/platform/x11/context_gl_x11.h @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/x11/detect.py b/platform/x11/detect.py index 89cf639114..0ba0f68393 100644 --- a/platform/x11/detect.py +++ b/platform/x11/detect.py @@ -133,7 +133,7 @@ def configure(env): elif (env["target"] == "debug"): - env.Prepend(CCFLAGS=['-g2', '-Wall', '-DDEBUG_ENABLED', '-DDEBUG_MEMORY_ENABLED']) + env.Prepend(CCFLAGS=['-g2', '-DDEBUG_ENABLED', '-DDEBUG_MEMORY_ENABLED']) env.ParseConfig('pkg-config x11 --cflags --libs') env.ParseConfig('pkg-config xinerama --cflags --libs') @@ -141,6 +141,15 @@ def configure(env): env.ParseConfig('pkg-config xrandr --cflags --libs') if (env['builtin_openssl'] == 'no'): + # Currently not compatible with OpenSSL 1.1.0+ + # https://github.com/godotengine/godot/issues/8624 + import subprocess + openssl_version = subprocess.check_output(['pkg-config', 'openssl', '--modversion']).strip('\n') + if (openssl_version >= "1.1.0"): + print("Error: Found system-installed OpenSSL %s, currently only supporting version 1.0.x." % openssl_version) + print("Aborting.. You can compile with 'builtin_openssl=yes' to use the bundled version.\n") + sys.exit(255) + env.ParseConfig('pkg-config openssl --cflags --libs') if (env['builtin_libwebp'] == 'no'): @@ -227,7 +236,7 @@ def configure(env): env.Append(LIBS=['dl']) # env.Append(CPPFLAGS=['-DMPC_FIXED_POINT']) -# host compiler is default.. + # host compiler is default.. if (is64 and env["bits"] == "32"): env.Append(CPPFLAGS=['-m32']) diff --git a/platform/x11/export/export.cpp b/platform/x11/export/export.cpp index 2659c771ca..69784a473d 100644 --- a/platform/x11/export/export.cpp +++ b/platform/x11/export/export.cpp @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -28,7 +29,7 @@ /*************************************************************************/ #include "export.h" #include "editor/editor_export.h" -#include "platform/x11/logo.h" +#include "platform/x11/logo.gen.h" #include "scene/resources/texture.h" void register_x11_exporter() { @@ -36,13 +37,17 @@ void register_x11_exporter() { Ref<EditorExportPlatformPC> platform; platform.instance(); - Image img(_x11_logo); + Ref<Image> img = memnew(Image(_x11_logo)); Ref<ImageTexture> logo; logo.instance(); logo->create_from_image(img); platform->set_logo(logo); platform->set_name("Linux/X11"); - platform->set_extension(""); + platform->set_extension("bin"); + platform->set_release_32("linux_x11_32_release"); + platform->set_debug_32("linux_x11_32_debug"); + platform->set_release_64("linux_x11_64_release"); + platform->set_debug_64("linux_x11_64_debug"); EditorExport::get_singleton()->add_export_platform(platform); diff --git a/platform/x11/export/export.h b/platform/x11/export/export.h index 5beaba2cfb..755b73d2c9 100644 --- a/platform/x11/export/export.h +++ b/platform/x11/export/export.h @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/x11/godot_x11.cpp b/platform/x11/godot_x11.cpp index 078baf76ee..b293b1bebb 100644 --- a/platform/x11/godot_x11.cpp +++ b/platform/x11/godot_x11.cpp @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/x11/joypad_linux.cpp b/platform/x11/joypad_linux.cpp index 62ece58f58..2502b2d51f 100644 --- a/platform/x11/joypad_linux.cpp +++ b/platform/x11/joypad_linux.cpp @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -454,10 +455,10 @@ InputDefault::JoyAxis JoypadLinux::axis_correct(const input_absinfo *p_abs, int return jx; } -uint32_t JoypadLinux::process_joypads(uint32_t p_event_id) { +void JoypadLinux::process_joypads() { if (joy_mutex->try_lock() != OK) { - return p_event_id; + return; } for (int i = 0; i < JOYPADS_MAX; i++) { @@ -477,11 +478,11 @@ uint32_t JoypadLinux::process_joypads(uint32_t p_event_id) { // ev may be tainted and out of MAX_KEY range, which will cause // joy->key_map[ev.code] to crash if (ev.code < 0 || ev.code >= MAX_KEY) - return p_event_id; + return; switch (ev.type) { case EV_KEY: - p_event_id = input->joy_button(p_event_id, i, joy->key_map[ev.code], ev.value); + input->joy_button(i, joy->key_map[ev.code], ev.value); break; case EV_ABS: @@ -496,7 +497,7 @@ uint32_t JoypadLinux::process_joypads(uint32_t p_event_id) { } else joy->dpad &= ~(InputDefault::HAT_MASK_LEFT | InputDefault::HAT_MASK_RIGHT); - p_event_id = input->joy_hat(p_event_id, i, joy->dpad); + input->joy_hat(i, joy->dpad); break; case ABS_HAT0Y: @@ -508,7 +509,7 @@ uint32_t JoypadLinux::process_joypads(uint32_t p_event_id) { } else joy->dpad &= ~(InputDefault::HAT_MASK_UP | InputDefault::HAT_MASK_DOWN); - p_event_id = input->joy_hat(p_event_id, i, joy->dpad); + input->joy_hat(i, joy->dpad); break; default: @@ -525,7 +526,7 @@ uint32_t JoypadLinux::process_joypads(uint32_t p_event_id) { for (int j = 0; j < MAX_ABS; j++) { int index = joy->abs_map[j]; if (index != -1) { - p_event_id = input->joy_axis(p_event_id, i, index, joy->curr_axis[index]); + input->joy_axis(i, index, joy->curr_axis[index]); } } if (len == 0 || (len < 0 && errno != EAGAIN)) { @@ -546,6 +547,5 @@ uint32_t JoypadLinux::process_joypads(uint32_t p_event_id) { } } joy_mutex->unlock(); - return p_event_id; } #endif diff --git a/platform/x11/joypad_linux.h b/platform/x11/joypad_linux.h index f90ca9319a..a0ac559b1c 100644 --- a/platform/x11/joypad_linux.h +++ b/platform/x11/joypad_linux.h @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -42,7 +43,7 @@ class JoypadLinux { public: JoypadLinux(InputDefault *in); ~JoypadLinux(); - uint32_t process_joypads(uint32_t p_event_id); + void process_joypads(); private: enum { diff --git a/platform/x11/key_mapping_x11.cpp b/platform/x11/key_mapping_x11.cpp index 4cfcffede0..362fc3618a 100644 --- a/platform/x11/key_mapping_x11.cpp +++ b/platform/x11/key_mapping_x11.cpp @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/x11/key_mapping_x11.h b/platform/x11/key_mapping_x11.h index 8210df06e7..41060c9303 100644 --- a/platform/x11/key_mapping_x11.h +++ b/platform/x11/key_mapping_x11.h @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/x11/os_x11.cpp b/platform/x11/os_x11.cpp index 4f79f2fb5d..2eebc96d2c 100644 --- a/platform/x11/os_x11.cpp +++ b/platform/x11/os_x11.cpp @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -33,6 +34,7 @@ #include "print_string.h" #include "servers/physics/physics_server_sw.h" #include "servers/visual/visual_server_raster.h" +#include "servers/visual/visual_server_wrap_mt.h" #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -94,7 +96,6 @@ void OS_X11::initialize(const VideoMode &p_desired, int p_video_driver, int p_au last_button_state = 0; xmbstring = NULL; - event_id = 0; x11_window = 0; last_click_ms = 0; args = OS::get_singleton()->get_cmdline_args(); @@ -206,12 +207,12 @@ void OS_X11::initialize(const VideoMode &p_desired, int p_video_driver, int p_au #endif visual_server = memnew(VisualServerRaster); -#if 0 - if (get_render_thread_mode()!=RENDER_THREAD_UNSAFE) { - visual_server =memnew(VisualServerWrapMT(visual_server,get_render_thread_mode()==RENDER_SEPARATE_THREAD)); + if (get_render_thread_mode() != RENDER_THREAD_UNSAFE) { + + visual_server = memnew(VisualServerWrapMT(visual_server, get_render_thread_mode() == RENDER_SEPARATE_THREAD)); } -#endif + // borderless fullscreen window mode if (current_videomode.fullscreen) { // needed for lxde/openbox, possibly others @@ -332,12 +333,13 @@ void OS_X11::initialize(const VideoMode &p_desired, int p_video_driver, int p_au WARN_PRINT("XCreateIC couldn't create xic"); } - XcursorSetTheme(x11_display, "default"); cursor_size = XcursorGetDefaultSize(x11_display); cursor_theme = XcursorGetTheme(x11_display); if (!cursor_theme) { - print_line("not found theme"); + if (is_stdout_verbose()) { + print_line("XcursorGetTheme could not get cursor theme"); + } cursor_theme = "default"; } @@ -549,7 +551,7 @@ void OS_X11::set_mouse_mode(MouseMode p_mode) { XWarpPointer(x11_display, None, x11_window, 0, 0, 0, 0, (int)center.x, (int)center.y); - input->set_mouse_pos(center); + input->set_mouse_position(center); } else { do_mouse_warp = false; } @@ -581,7 +583,7 @@ int OS_X11::get_mouse_button_state() const { return last_button_state; } -Point2 OS_X11::get_mouse_pos() const { +Point2 OS_X11::get_mouse_position() const { return last_mouse_pos; } @@ -959,16 +961,12 @@ void OS_X11::request_attention() { XSendEvent(x11_display, DefaultRootWindow(x11_display), False, SubstructureRedirectMask | SubstructureNotifyMask, &xev); } -InputModifierState OS_X11::get_key_modifier_state(unsigned int p_x11_state) { - - InputModifierState state; - - state.shift = (p_x11_state & ShiftMask); - state.control = (p_x11_state & ControlMask); - state.alt = (p_x11_state & Mod1Mask /*|| p_x11_state&Mod5Mask*/); //altgr should not count as alt - state.meta = (p_x11_state & Mod4Mask); +void OS_X11::get_key_modifier_state(unsigned int p_x11_state, Ref<InputEventWithModifiers> state) { - return state; + state->set_shift((p_x11_state & ShiftMask)); + state->set_control((p_x11_state & ControlMask)); + state->set_alt((p_x11_state & Mod1Mask /*|| p_x11_state&Mod5Mask*/)); //altgr should not count as alt + state->set_metakey((p_x11_state & Mod4Mask)); } unsigned int OS_X11::get_mouse_button_state(unsigned int p_x11_state) { @@ -1020,7 +1018,7 @@ void OS_X11::handle_key_event(XKeyEvent *p_event, bool p_echo) { // XKeycodeToKeysym to obtain internationalized // input.. WRONG!! // you must use XLookupString (???) which not only wastes - // cycles generating an unnecesary string, but also + // cycles generating an unnecessary string, but also // still works in half the cases. (won't handle deadkeys) // For more complex input methods (deadkeys and more advanced) // you have to use XmbLookupString (??). @@ -1076,7 +1074,7 @@ void OS_X11::handle_key_event(XKeyEvent *p_event, bool p_echo) { /* Phase 4, determine if event must be filtered */ // This seems to be a side-effect of using XIM. - // XEventFilter looks like a core X11 funciton, + // XEventFilter looks like a core X11 function, // but it's actually just used to see if we must // ignore a deadkey, or events XIM determines // must not reach the actual gui. @@ -1100,7 +1098,10 @@ void OS_X11::handle_key_event(XKeyEvent *p_event, bool p_echo) { //print_line("mod1: "+itos(xkeyevent->state&Mod1Mask)+" mod 5: "+itos(xkeyevent->state&Mod5Mask)); - InputModifierState state = get_key_modifier_state(xkeyevent->state); + Ref<InputEventKey> k; + k.instance(); + + get_key_modifier_state(xkeyevent->state, k); /* Phase 6, determine echo character */ @@ -1143,41 +1144,36 @@ void OS_X11::handle_key_event(XKeyEvent *p_event, bool p_echo) { /* Phase 7, send event to Window */ - InputEvent event; - event.ID = ++event_id; - event.type = InputEvent::KEY; - event.device = 0; - event.key.mod = state; - event.key.pressed = keypress; + k->set_pressed(keypress); if (keycode >= 'a' && keycode <= 'z') keycode -= 'a' - 'A'; - event.key.scancode = keycode; - event.key.unicode = unicode; - event.key.echo = p_echo; + k->set_scancode(keycode); + k->set_unicode(unicode); + k->set_echo(p_echo); - if (event.key.scancode == KEY_BACKTAB) { - //make it consistent accross platforms. - event.key.scancode = KEY_TAB; - event.key.mod.shift = true; + if (k->get_scancode() == KEY_BACKTAB) { + //make it consistent across platforms. + k->set_scancode(KEY_TAB); + k->set_shift(true); } //don't set mod state if modifier keys are released by themselves //else event.is_action() will not work correctly here - if (!event.key.pressed) { - if (event.key.scancode == KEY_SHIFT) - event.key.mod.shift = false; - else if (event.key.scancode == KEY_CONTROL) - event.key.mod.control = false; - else if (event.key.scancode == KEY_ALT) - event.key.mod.alt = false; - else if (event.key.scancode == KEY_META) - event.key.mod.meta = false; + if (!k->is_pressed()) { + if (k->get_scancode() == KEY_SHIFT) + k->set_shift(false); + else if (k->get_scancode() == KEY_CONTROL) + k->set_control(false); + else if (k->get_scancode() == KEY_ALT) + k->set_alt(false); + else if (k->get_scancode() == KEY_META) + k->set_metakey(false); } - //printf("key: %x\n",event.key.scancode); - input->parse_input_event(event); + //printf("key: %x\n",k->get_scancode()); + input->parse_input_event(k); } struct Property { @@ -1334,23 +1330,20 @@ void OS_X11::process_xevents() { event.xbutton.y = last_mouse_pos.y; } - InputEvent mouse_event; - mouse_event.ID = ++event_id; - mouse_event.type = InputEvent::MOUSE_BUTTON; - mouse_event.device = 0; - mouse_event.mouse_button.mod = get_key_modifier_state(event.xbutton.state); - mouse_event.mouse_button.button_mask = get_mouse_button_state(event.xbutton.state); - mouse_event.mouse_button.x = event.xbutton.x; - mouse_event.mouse_button.y = event.xbutton.y; - mouse_event.mouse_button.global_x = event.xbutton.x; - mouse_event.mouse_button.global_y = event.xbutton.y; - mouse_event.mouse_button.button_index = event.xbutton.button; - if (mouse_event.mouse_button.button_index == 2) - mouse_event.mouse_button.button_index = 3; - else if (mouse_event.mouse_button.button_index == 3) - mouse_event.mouse_button.button_index = 2; - - mouse_event.mouse_button.pressed = (event.type == ButtonPress); + Ref<InputEventMouseButton> mb; + mb.instance(); + + get_key_modifier_state(event.xbutton.state, mb); + mb->set_button_mask(get_mouse_button_state(event.xbutton.state)); + mb->set_position(Vector2(event.xbutton.x, event.xbutton.y)); + mb->set_global_position(mb->get_position()); + mb->set_button_index(event.xbutton.button); + if (mb->get_button_index() == 2) + mb->set_button_index(3); + else if (mb->get_button_index() == 3) + mb->set_button_index(2); + + mb->set_pressed((event.type == ButtonPress)); if (event.type == ButtonPress && event.xbutton.button == 1) { @@ -1360,8 +1353,7 @@ void OS_X11::process_xevents() { last_click_ms = 0; last_click_pos = Point2(-100, -100); - mouse_event.mouse_button.doubleclick = true; - mouse_event.ID = ++event_id; + mb->set_doubleclick(true); } else { last_click_ms += diff; @@ -1369,7 +1361,7 @@ void OS_X11::process_xevents() { } } - input->parse_input_event(mouse_event); + input->parse_input_event(mb); } break; case MotionNotify: { @@ -1447,23 +1439,16 @@ void OS_X11::process_xevents() { Point2i rel = pos - last_mouse_pos; - InputEvent motion_event; - motion_event.ID = ++event_id; - motion_event.type = InputEvent::MOUSE_MOTION; - motion_event.device = 0; - - motion_event.mouse_motion.mod = get_key_modifier_state(event.xmotion.state); - motion_event.mouse_motion.button_mask = get_mouse_button_state(event.xmotion.state); - motion_event.mouse_motion.x = pos.x; - motion_event.mouse_motion.y = pos.y; - input->set_mouse_pos(pos); - motion_event.mouse_motion.global_x = pos.x; - motion_event.mouse_motion.global_y = pos.y; - motion_event.mouse_motion.speed_x = input->get_last_mouse_speed().x; - motion_event.mouse_motion.speed_y = input->get_last_mouse_speed().y; + Ref<InputEventMouseMotion> mm; + mm.instance(); - motion_event.mouse_motion.relative_x = rel.x; - motion_event.mouse_motion.relative_y = rel.y; + get_key_modifier_state(event.xmotion.state, mm); + mm->set_button_mask(get_mouse_button_state(event.xmotion.state)); + mm->set_position(pos); + mm->set_global_position(pos); + input->set_mouse_position(pos); + mm->set_speed(input->get_last_mouse_speed()); + mm->set_relative(rel); last_mouse_pos = pos; @@ -1472,7 +1457,7 @@ void OS_X11::process_xevents() { // this is so that the relative motion doesn't get messed up // after we regain focus. if (window_has_focus || !mouse_mode_grab) - input->parse_input_event(motion_event); + input->parse_input_event(mm); } break; case KeyPress: @@ -1862,15 +1847,15 @@ void OS_X11::alert(const String &p_alert, const String &p_title) { execute("/usr/bin/xmessage", args, true); } -void OS_X11::set_icon(const Image &p_icon) { +void OS_X11::set_icon(const Ref<Image> &p_icon) { Atom net_wm_icon = XInternAtom(x11_display, "_NET_WM_ICON", False); - if (!p_icon.empty()) { - Image img = p_icon; - img.convert(Image::FORMAT_RGBA8); + if (p_icon.is_valid()) { + Ref<Image> img = p_icon->duplicate(); + img->convert(Image::FORMAT_RGBA8); - int w = img.get_width(); - int h = img.get_height(); + int w = img->get_width(); + int h = img->get_height(); // We're using long to have wordsize (32Bit build -> 32 Bits, 64 Bit build -> 64 Bits Vector<long> pd; @@ -1880,7 +1865,7 @@ void OS_X11::set_icon(const Image &p_icon) { pd[0] = w; pd[1] = h; - PoolVector<uint8_t>::Read r = img.get_data().read(); + PoolVector<uint8_t>::Read r = img->get_data().read(); long *wr = &pd[2]; uint8_t const *pr = r.ptr(); @@ -1917,7 +1902,7 @@ void OS_X11::run() { process_xevents(); // get rid of pending events #ifdef JOYDEV_ENABLED - event_id = joypad->process_joypads(event_id); + joypad->process_joypads(); #endif if (Main::iteration() == true) break; diff --git a/platform/x11/os_x11.h b/platform/x11/os_x11.h index cbda18c0bc..d62186e5bd 100644 --- a/platform/x11/os_x11.h +++ b/platform/x11/os_x11.h @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -116,12 +117,11 @@ class OS_X11 : public OS_Unix { bool last_mouse_pos_valid; Point2i last_click_pos; uint64_t last_click_ms; - unsigned int event_id; uint32_t last_button_state; PhysicsServer *physics_server; unsigned int get_mouse_button_state(unsigned int p_x11_state); - InputModifierState get_key_modifier_state(unsigned int p_x11_state); + void get_key_modifier_state(unsigned int p_x11_state, Ref<InputEventWithModifiers> state); Physics2DServer *physics_2d_server; MouseMode mouse_mode; @@ -202,11 +202,11 @@ public: MouseMode get_mouse_mode() const; virtual void warp_mouse_pos(const Point2 &p_to); - virtual Point2 get_mouse_pos() const; + virtual Point2 get_mouse_position() const; virtual int get_mouse_button_state() const; virtual void set_window_title(const String &p_title); - virtual void set_icon(const Image &p_icon); + virtual void set_icon(const Ref<Image> &p_icon); virtual MainLoop *get_main_loop() const; diff --git a/platform/x11/platform_config.h b/platform/x11/platform_config.h index 342270b74a..1a1de42b47 100644 --- a/platform/x11/platform_config.h +++ b/platform/x11/platform_config.h @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ diff --git a/platform/x11/power_x11.cpp b/platform/x11/power_x11.cpp index 2f98d2f335..093d24f406 100644 --- a/platform/x11/power_x11.cpp +++ b/platform/x11/power_x11.cpp @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -27,6 +28,31 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ +/* +Adapted from corresponding SDL 2.0 code. +*/ + +/* + Simple DirectMedia Layer + Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org> + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. +*/ + #include "power_x11.h" #include <stdio.h> diff --git a/platform/x11/power_x11.h b/platform/x11/power_x11.h index 7693a5b022..64ed5fe26a 100644 --- a/platform/x11/power_x11.h +++ b/platform/x11/power_x11.h @@ -6,6 +6,7 @@ /* http://www.godotengine.org */ /*************************************************************************/ /* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md) */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ |