diff options
Diffstat (limited to 'platform')
252 files changed, 3447 insertions, 4661 deletions
diff --git a/platform/android/SCsub b/platform/android/SCsub index 65172a12c0..fd2a774c71 100644 --- a/platform/android/SCsub +++ b/platform/android/SCsub @@ -12,12 +12,12 @@ android_files = [ 'file_access_jandroid.cpp', 'dir_access_jandroid.cpp', 'thread_jandroid.cpp', + 'net_socket_android.cpp', 'audio_driver_jandroid.cpp', 'java_godot_lib_jni.cpp', 'java_class_wrapper.cpp', 'java_godot_wrapper.cpp', 'java_godot_io_wrapper.cpp', - #'power_android.cpp' ] env_android = env.Clone() diff --git a/platform/android/power_android.h b/platform/android/api/api.cpp index 6cb745b6c0..7efb545524 100644 --- a/platform/android/power_android.h +++ b/platform/android/api/api.cpp @@ -1,12 +1,12 @@ /*************************************************************************/ -/* power_android.h */ +/* api.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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,53 +28,59 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef POWER_ANDROID_H -#define POWER_ANDROID_H +#include "api.h" -#include "core/os/os.h" +#include "core/engine.h" +#include "java_class_wrapper.h" -#include <android/native_window_jni.h> +#if !defined(ANDROID_ENABLED) +static JavaClassWrapper *java_class_wrapper = NULL; +#endif -class PowerAndroid { +void register_android_api() { - struct LocalReferenceHolder { - JNIEnv *m_env; - const char *m_func; - }; +#if !defined(ANDROID_ENABLED) + java_class_wrapper = memnew(JavaClassWrapper); // Dummy +#endif -private: - static struct LocalReferenceHolder refs; - static JNIEnv *env; - static jmethodID mid; - static jobject context; - static jstring action; - static jclass cls; - static jobject filter; - static jobject intent; - static jstring iname; - static jmethodID imid; - static jstring bname; - static jmethodID bmid; + ClassDB::register_class<JavaClass>(); + ClassDB::register_class<JavaClassWrapper>(); + Engine::get_singleton()->add_singleton(Engine::Singleton("JavaClassWrapper", JavaClassWrapper::get_singleton())); +} - int nsecs_left; - int percent_left; - OS::PowerState power_state; +void unregister_android_api() { - bool GetPowerInfo_Android(); - bool UpdatePowerInfo(); +#if !defined(ANDROID_ENABLED) + memdelete(java_class_wrapper); +#endif +} -public: - static int s_active; +void JavaClassWrapper::_bind_methods() { - PowerAndroid(); - virtual ~PowerAndroid(); - static bool LocalReferenceHolder_Init(struct LocalReferenceHolder *refholder, JNIEnv *env); - static struct LocalReferenceHolder LocalReferenceHolder_Setup(const char *func); - static void LocalReferenceHolder_Cleanup(struct LocalReferenceHolder *refholder); + ClassDB::bind_method(D_METHOD("wrap", "name"), &JavaClassWrapper::wrap); +} - OS::PowerState get_power_state(); - int get_power_seconds_left(); - int get_power_percent_left(); -}; +#if !defined(ANDROID_ENABLED) -#endif // POWER_ANDROID_H +Variant JavaClass::call(const StringName &, const Variant **, int, Callable::CallError &) { + return Variant(); +} + +JavaClass::JavaClass() { +} + +Variant JavaObject::call(const StringName &, const Variant **, int, Callable::CallError &) { + return Variant(); +} + +JavaClassWrapper *JavaClassWrapper::singleton = NULL; + +Ref<JavaClass> JavaClassWrapper::wrap(const String &) { + return Ref<JavaClass>(); +} + +JavaClassWrapper::JavaClassWrapper() { + singleton = this; +} + +#endif diff --git a/platform/iphone/camera_ios.h b/platform/android/api/api.h index ceabdba6a3..c7296d92a7 100644 --- a/platform/iphone/camera_ios.h +++ b/platform/android/api/api.h @@ -1,12 +1,12 @@ /*************************************************************************/ -/* camera_ios.h */ +/* api.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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,18 +28,5 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef CAMERAIOS_H -#define CAMERAIOS_H - -#include "servers/camera_server.h" - -class CameraIOS : public CameraServer { -private: -public: - CameraIOS(); - ~CameraIOS(); - - void update_feeds(); -}; - -#endif /* CAMERAIOS_H */
\ No newline at end of file +void register_android_api(); +void unregister_android_api(); diff --git a/platform/android/java_class_wrapper.h b/platform/android/api/java_class_wrapper.h index e9471a1897..48b581958b 100644 --- a/platform/android/java_class_wrapper.h +++ b/platform/android/api/java_class_wrapper.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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,16 +32,22 @@ #define JAVA_CLASS_WRAPPER_H #include "core/reference.h" + +#ifdef ANDROID_ENABLED #include <android/log.h> #include <jni.h> +#endif +#ifdef ANDROID_ENABLED class JavaObject; +#endif class JavaClass : public Reference { GDCLASS(JavaClass, Reference); - enum ArgumentType { +#ifdef ANDROID_ENABLED + enum ArgumentType{ ARG_TYPE_VOID, ARG_TYPE_BOOLEAN, @@ -107,12 +113,12 @@ class JavaClass : public Reference { break; case ARG_TYPE_FLOAT | ARG_NUMBER_CLASS_BIT: case ARG_TYPE_FLOAT: - r_type = Variant::REAL; + r_type = Variant::FLOAT; likelihood = 1.0; break; case ARG_TYPE_DOUBLE | ARG_NUMBER_CLASS_BIT: case ARG_TYPE_DOUBLE: - r_type = Variant::REAL; + r_type = Variant::FLOAT; likelihood = 0.5; break; case ARG_TYPE_STRING: r_type = Variant::STRING; break; @@ -120,48 +126,49 @@ class JavaClass : public Reference { case ARG_ARRAY_BIT | ARG_TYPE_VOID: r_type = Variant::NIL; break; 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; + r_type = Variant::PACKED_BYTE_ARRAY; likelihood = 1.0; break; case ARG_ARRAY_BIT | ARG_TYPE_CHAR: - r_type = Variant::POOL_BYTE_ARRAY; + r_type = Variant::PACKED_BYTE_ARRAY; likelihood = 0.5; break; case ARG_ARRAY_BIT | ARG_TYPE_SHORT: - r_type = Variant::POOL_INT_ARRAY; + r_type = Variant::PACKED_INT32_ARRAY; likelihood = 0.3; break; case ARG_ARRAY_BIT | ARG_TYPE_INT: - r_type = Variant::POOL_INT_ARRAY; + r_type = Variant::PACKED_INT32_ARRAY; likelihood = 1.0; break; case ARG_ARRAY_BIT | ARG_TYPE_LONG: - r_type = Variant::POOL_INT_ARRAY; + r_type = Variant::PACKED_INT32_ARRAY; likelihood = 0.5; break; case ARG_ARRAY_BIT | ARG_TYPE_FLOAT: - r_type = Variant::POOL_REAL_ARRAY; + r_type = Variant::PACKED_FLOAT32_ARRAY; likelihood = 1.0; break; case ARG_ARRAY_BIT | ARG_TYPE_DOUBLE: - r_type = Variant::POOL_REAL_ARRAY; + r_type = Variant::PACKED_FLOAT32_ARRAY; likelihood = 0.5; break; - case ARG_ARRAY_BIT | ARG_TYPE_STRING: r_type = Variant::POOL_STRING_ARRAY; break; + case ARG_ARRAY_BIT | ARG_TYPE_STRING: r_type = Variant::PACKED_STRING_ARRAY; break; case ARG_ARRAY_BIT | ARG_TYPE_CLASS: r_type = Variant::ARRAY; break; } } _FORCE_INLINE_ static bool _convert_object_to_variant(JNIEnv *env, jobject obj, Variant &var, uint32_t p_sig); - bool _call_method(JavaObject *p_instance, const StringName &p_method, const Variant **p_args, int p_argcount, Variant::CallError &r_error, Variant &ret); + bool _call_method(JavaObject *p_instance, const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error, Variant &ret); friend class JavaClassWrapper; Map<StringName, List<MethodInfo> > methods; jclass _class; +#endif public: - virtual Variant call(const StringName &p_method, const Variant **p_args, int p_argcount, Variant::CallError &r_error); + virtual Variant call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error); JavaClass(); }; @@ -170,22 +177,27 @@ class JavaObject : public Reference { GDCLASS(JavaObject, Reference); +#ifdef ANDROID_ENABLED Ref<JavaClass> base_class; friend class JavaClass; jobject instance; +#endif public: - virtual Variant call(const StringName &p_method, const Variant **p_args, int p_argcount, Variant::CallError &r_error); + virtual Variant call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error); +#ifdef ANDROID_ENABLED JavaObject(const Ref<JavaClass> &p_base, jobject *p_instance); ~JavaObject(); +#endif }; class JavaClassWrapper : public Object { GDCLASS(JavaClassWrapper, Object); +#ifdef ANDROID_ENABLED Map<String, Ref<JavaClass> > class_cache; friend class JavaClass; jclass activityClass; @@ -211,6 +223,7 @@ class JavaClassWrapper : public Object { jobject classLoader; bool _get_type_sig(JNIEnv *env, jobject obj, uint32_t &sig, String &strsig); +#endif static JavaClassWrapper *singleton; @@ -222,7 +235,11 @@ public: Ref<JavaClass> wrap(const String &p_class); +#ifdef ANDROID_ENABLED JavaClassWrapper(jobject p_activity = NULL); +#else + JavaClassWrapper(); +#endif }; #endif // JAVA_CLASS_WRAPPER_H diff --git a/platform/android/audio_driver_jandroid.cpp b/platform/android/audio_driver_jandroid.cpp index bcef5b0c85..5a8e3b94da 100644 --- a/platform/android/audio_driver_jandroid.cpp +++ b/platform/android/audio_driver_jandroid.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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 f92ef06052..d3d1641c20 100644 --- a/platform/android/audio_driver_jandroid.h +++ b/platform/android/audio_driver_jandroid.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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 711088c158..6e9864c803 100644 --- a/platform/android/audio_driver_opensl.cpp +++ b/platform/android/audio_driver_opensl.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -208,8 +208,8 @@ void AudioDriverOpenSL::_record_buffer_callback(SLAndroidSimpleBufferQueueItf qu for (int i = 0; i < rec_buffer.size(); i++) { int32_t sample = rec_buffer[i] << 16; - capture_buffer_write(sample); - capture_buffer_write(sample); // call twice to convert to Stereo + input_buffer_write(sample); + input_buffer_write(sample); // call twice to convert to Stereo } SLresult res = (*recordBufferQueueItf)->Enqueue(recordBufferQueueItf, rec_buffer.ptrw(), rec_buffer.size() * sizeof(int16_t)); @@ -280,7 +280,7 @@ Error AudioDriverOpenSL::capture_init_device() { const int rec_buffer_frames = 2048; rec_buffer.resize(rec_buffer_frames); - capture_buffer_init(rec_buffer_frames); + input_buffer_init(rec_buffer_frames); res = (*recordBufferQueueItf)->Enqueue(recordBufferQueueItf, rec_buffer.ptrw(), rec_buffer.size() * sizeof(int16_t)); ERR_FAIL_COND_V(res != SL_RESULT_SUCCESS, ERR_CANT_OPEN); diff --git a/platform/android/audio_driver_opensl.h b/platform/android/audio_driver_opensl.h index 2981073cec..57d9b30af6 100644 --- a/platform/android/audio_driver_opensl.h +++ b/platform/android/audio_driver_opensl.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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 8c464465ca..f52b511522 100644 --- a/platform/android/dir_access_jandroid.cpp +++ b/platform/android/dir_access_jandroid.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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 +110,6 @@ String DirAccessJAndroid::get_drive(int p_drive) { Error DirAccessJAndroid::change_dir(String p_dir) { JNIEnv *env = ThreadAndroid::get_env(); - p_dir = p_dir.simplify_path(); if (p_dir == "" || p_dir == "." || (p_dir == ".." && current_dir == "")) return OK; diff --git a/platform/android/dir_access_jandroid.h b/platform/android/dir_access_jandroid.h index cdea93ff4c..caeb4b58b9 100644 --- a/platform/android/dir_access_jandroid.h +++ b/platform/android/dir_access_jandroid.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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 6d021ad33a..50bf671a84 100644 --- a/platform/android/export/export.cpp +++ b/platform/android/export/export.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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 +30,7 @@ #include "export.h" +#include "core/io/image_loader.h" #include "core/io/marshalls.h" #include "core/io/zip_io.h" #include "core/os/dir_access.h" @@ -37,7 +38,9 @@ #include "core/os/os.h" #include "core/project_settings.h" #include "core/version.h" +#include "drivers/png/png_driver_common.h" #include "editor/editor_export.h" +#include "editor/editor_log.h" #include "editor/editor_node.h" #include "editor/editor_settings.h" #include "platform/android/logo.gen.h" @@ -195,16 +198,40 @@ static const char *android_perms[] = { }; struct LauncherIcon { - const char *option_id; const char *export_path; + int dimensions; }; -static const LauncherIcon launcher_icons[] = { - { "launcher_icons/xxxhdpi_192x192", "res/drawable-xxxhdpi-v4/icon.png" }, - { "launcher_icons/xxhdpi_144x144", "res/drawable-xxhdpi-v4/icon.png" }, - { "launcher_icons/xhdpi_96x96", "res/drawable-xhdpi-v4/icon.png" }, - { "launcher_icons/hdpi_72x72", "res/drawable-hdpi-v4/icon.png" }, - { "launcher_icons/mdpi_48x48", "res/drawable-mdpi-v4/icon.png" } +static const int icon_densities_count = 6; +static const char *launcher_icon_option = "launcher_icons/main_192x192"; +static const char *launcher_adaptive_icon_foreground_option = "launcher_icons/adaptive_foreground_432x432"; +static const char *launcher_adaptive_icon_background_option = "launcher_icons/adaptive_background_432x432"; + +static const LauncherIcon launcher_icons[icon_densities_count] = { + { "res/mipmap-xxxhdpi-v4/icon.png", 192 }, + { "res/mipmap-xxhdpi-v4/icon.png", 144 }, + { "res/mipmap-xhdpi-v4/icon.png", 96 }, + { "res/mipmap-hdpi-v4/icon.png", 72 }, + { "res/mipmap-mdpi-v4/icon.png", 48 }, + { "res/mipmap/icon.png", 192 } +}; + +static const LauncherIcon launcher_adaptive_icon_foregrounds[icon_densities_count] = { + { "res/mipmap-xxxhdpi-v4/icon_foreground.png", 432 }, + { "res/mipmap-xxhdpi-v4/icon_foreground.png", 324 }, + { "res/mipmap-xhdpi-v4/icon_foreground.png", 216 }, + { "res/mipmap-hdpi-v4/icon_foreground.png", 162 }, + { "res/mipmap-mdpi-v4/icon_foreground.png", 108 }, + { "res/mipmap/icon_foreground.png", 432 } +}; + +static const LauncherIcon launcher_adaptive_icon_backgrounds[icon_densities_count] = { + { "res/mipmap-xxxhdpi-v4/icon_background.png", 432 }, + { "res/mipmap-xxhdpi-v4/icon_background.png", 324 }, + { "res/mipmap-xhdpi-v4/icon_background.png", 216 }, + { "res/mipmap-hdpi-v4/icon_background.png", 162 }, + { "res/mipmap-mdpi-v4/icon_background.png", 108 }, + { "res/mipmap/icon_background.png", 432 } }; class EditorExportPlatformAndroid : public EditorExportPlatform { @@ -310,7 +337,7 @@ class EditorExportPlatformAndroid : public EditorExportPlatform { Vector<String> props = dp.split("\n"); String vendor; String device; - d.description + "Device ID: " + d.id + "\n"; + d.description = "Device ID: " + d.id + "\n"; d.api_level = 0; for (int j = 0; j < props.size(); j++) { @@ -358,7 +385,7 @@ class EditorExportPlatformAndroid : public EditorExportPlatform { ea->device_lock->unlock(); } - uint64_t sleep = OS::get_singleton()->get_power_state() == OS::POWERSTATE_ON_BATTERY ? 1000 : 100; + uint64_t sleep = 200; uint64_t wait = 3000000; uint64_t time = OS::get_singleton()->get_ticks_usec(); while (OS::get_singleton()->get_ticks_usec() - time < wait) { @@ -583,7 +610,7 @@ class EditorExportPlatformAndroid : public EditorExportPlatform { static Error save_apk_so(void *p_userdata, const SharedObject &p_so) { if (!p_so.path.get_file().begins_with("lib")) { String err = "Android .so file names must start with \"lib\", but got: " + p_so.path; - ERR_PRINTS(err); + ERR_PRINT(err); return FAILED; } APKExportData *ed = (APKExportData *)p_userdata; @@ -604,7 +631,7 @@ class EditorExportPlatformAndroid : public EditorExportPlatform { if (!exported) { String abis_string = String(" ").join(abis); String err = "Cannot determine ABI for library \"" + p_so.path + "\". One of the supported ABIs must be used as a tag: " + abis_string; - ERR_PRINTS(err); + ERR_PRINT(err); return FAILED; } return OK; @@ -615,9 +642,6 @@ class EditorExportPlatformAndroid : public EditorExportPlatform { String dst_path = p_path.replace_first("res://", "assets/"); store_in_apk(ed, dst_path, p_data, _should_compress_asset(p_path, p_data) ? Z_DEFLATED : 0); - if (ed->ep->step("File: " + p_path, 3 + p_file * 100 / p_total)) { - return ERR_SKIP; - } return OK; } @@ -659,14 +683,12 @@ class EditorExportPlatformAndroid : public EditorExportPlatform { int orientation = p_preset->get("screen/orientation"); - bool min_gles3 = ProjectSettings::get_singleton()->get("rendering/quality/driver/driver_name") == "GLES3" && - !ProjectSettings::get_singleton()->get("rendering/quality/driver/fallback_to_gles2"); 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"); - int xr_mode_index = p_preset->get("graphics/xr_mode"); + int xr_mode_index = p_preset->get("xr_features/xr_mode"); Vector<String> perms; @@ -679,7 +701,7 @@ class EditorExportPlatformAndroid : public EditorExportPlatform { aperms++; } - PoolStringArray user_perms = p_preset->get("permissions/custom_permissions"); + PackedStringArray user_perms = p_preset->get("permissions/custom_permissions"); for (int i = 0; i < user_perms.size(); i++) { String user_perm = user_perms[i].strip_edges(); @@ -815,11 +837,6 @@ class EditorExportPlatformAndroid : public EditorExportPlatform { } } - if (tname == "uses-feature" && attrname == "glEsVersion") { - - encode_uint32(min_gles3 ? 0x00030000 : 0x00020000, &p_manifest.write[iofs + 16]); - } - // FIXME: `attr_value != 0xFFFFFFFF` below added as a stopgap measure for GH-32553, // but the issue should be debugged further and properly addressed. if (tname == "meta-data" && attrname == "name" && value == "xr_mode_metadata_name") { @@ -845,135 +862,174 @@ class EditorExportPlatformAndroid : public EditorExportPlatform { uint32_t name = decode_uint32(&p_manifest[iofs + 12]); String tname = string_table[name]; - int dof_index = p_preset->get("graphics/degrees_of_freedom"); // 0: none, 1: 3dof and 6dof, 2: 6dof + if (tname == "uses-feature") { + Vector<String> feature_names; + Vector<bool> feature_required_list; + Vector<int> feature_versions; + + if (xr_mode_index == 1 /* XRMode.OVR */) { + // Check for degrees of freedom + int dof_index = p_preset->get("xr_features/degrees_of_freedom"); // 0: none, 1: 3dof and 6dof, 2: 6dof + + if (dof_index > 0) { + feature_names.push_back("android.hardware.vr.headtracking"); + feature_required_list.push_back(dof_index == 2); + feature_versions.push_back(1); + } + + // Check for hand tracking + int hand_tracking_index = p_preset->get("xr_features/hand_tracking"); // 0: none, 1: optional, 2: required + if (hand_tracking_index > 0) { + feature_names.push_back("oculus.software.handtracking"); + feature_required_list.push_back(hand_tracking_index == 2); + feature_versions.push_back(-1); // no version attribute should be added. - if (tname == "uses-feature" && dof_index > 0) { - if (xr_mode_index == 0) { - WARN_PRINT("VR DOF feature setting is only valid for oculus HMDs with an XR mode set to VR"); + if (perms.find("oculus.permission.handtracking") == -1) { + perms.push_back("oculus.permission.handtracking"); + } + } } - ofs += 24; // skip over end tag - // save manifest ending so we can restore it - Vector<uint8_t> manifest_end; - uint32_t manifest_cur_size = p_manifest.size(); + if (feature_names.size() > 0) { + ofs += 24; // skip over end tag - manifest_end.resize(p_manifest.size() - ofs); - memcpy(manifest_end.ptrw(), &p_manifest[ofs], manifest_end.size()); + // save manifest ending so we can restore it + Vector<uint8_t> manifest_end; + uint32_t manifest_cur_size = p_manifest.size(); - int32_t attr_name_string = string_table.find("name"); - ERR_FAIL_COND_MSG(attr_name_string == -1, "Template does not have 'name' attribute."); + manifest_end.resize(p_manifest.size() - ofs); + memcpy(manifest_end.ptrw(), &p_manifest[ofs], manifest_end.size()); - int32_t ns_android_string = string_table.find("http://schemas.android.com/apk/res/android"); - if (ns_android_string == -1) { - string_table.push_back("http://schemas.android.com/apk/res/android"); - ns_android_string = string_table.size() - 1; - } + int32_t attr_name_string = string_table.find("name"); + ERR_FAIL_COND_MSG(attr_name_string == -1, "Template does not have 'name' attribute."); - int32_t attr_uses_permission_string = string_table.find("uses-feature"); - if (attr_uses_permission_string == -1) { - string_table.push_back("uses-feature"); - attr_uses_permission_string = string_table.size() - 1; - } + int32_t ns_android_string = string_table.find("http://schemas.android.com/apk/res/android"); + if (ns_android_string == -1) { + string_table.push_back("http://schemas.android.com/apk/res/android"); + ns_android_string = string_table.size() - 1; + } - int32_t attr_required_string = string_table.find("required"); - if (attr_required_string == -1) { - string_table.push_back("required"); - attr_required_string = string_table.size() - 1; - } + int32_t attr_uses_feature_string = string_table.find("uses-feature"); + if (attr_uses_feature_string == -1) { + string_table.push_back("uses-feature"); + attr_uses_feature_string = string_table.size() - 1; + } - int32_t attr_version_string = string_table.find("version"); - if (attr_version_string == -1) { - string_table.push_back("version"); - attr_version_string = string_table.size() - 1; - } + int32_t attr_required_string = string_table.find("required"); + if (attr_required_string == -1) { + string_table.push_back("required"); + attr_required_string = string_table.size() - 1; + } - String required_value_string; - if (dof_index == 1) { - required_value_string = "false"; - } else if (dof_index == 2) { - required_value_string = "true"; - } else { - ERR_FAIL_MSG("Unknown DoF index: " + itos(dof_index) + "."); - } - int32_t required_value = string_table.find(required_value_string); - if (required_value == -1) { - string_table.push_back(required_value_string); - required_value = string_table.size() - 1; - } + for (int i = 0; i < feature_names.size(); i++) { + String feature_name = feature_names[i]; + bool feature_required = feature_required_list[i]; + int feature_version = feature_versions[i]; + bool has_version_attribute = feature_version != -1; - int32_t version_value = string_table.find("1"); - if (version_value == -1) { - string_table.push_back("1"); - version_value = string_table.size() - 1; - } + print_line("Adding feature " + feature_name); - int32_t feature_string = string_table.find("android.hardware.vr.headtracking"); - if (feature_string == -1) { - string_table.push_back("android.hardware.vr.headtracking"); - feature_string = string_table.size() - 1; - } + int32_t feature_string = string_table.find(feature_name); + if (feature_string == -1) { + string_table.push_back(feature_name); + feature_string = string_table.size() - 1; + } - { - manifest_cur_size += 96 + 20; // node and three attrs + end node - p_manifest.resize(manifest_cur_size); + String required_value_string = feature_required ? "true" : "false"; + int32_t required_value = string_table.find(required_value_string); + if (required_value == -1) { + string_table.push_back(required_value_string); + required_value = string_table.size() - 1; + } - // start tag - encode_uint16(0x102, &p_manifest.write[ofs]); // type - encode_uint16(16, &p_manifest.write[ofs + 2]); // headersize - encode_uint32(96, &p_manifest.write[ofs + 4]); // size - encode_uint32(0, &p_manifest.write[ofs + 8]); // lineno - encode_uint32(-1, &p_manifest.write[ofs + 12]); // comment - encode_uint32(-1, &p_manifest.write[ofs + 16]); // ns - encode_uint32(attr_uses_permission_string, &p_manifest.write[ofs + 20]); // name - encode_uint16(20, &p_manifest.write[ofs + 24]); // attr_start - encode_uint16(20, &p_manifest.write[ofs + 26]); // attr_size - encode_uint16(3, &p_manifest.write[ofs + 28]); // num_attrs - encode_uint16(0, &p_manifest.write[ofs + 30]); // id_index - encode_uint16(0, &p_manifest.write[ofs + 32]); // class_index - encode_uint16(0, &p_manifest.write[ofs + 34]); // style_index + int32_t attr_version_string = -1; + int32_t version_value = -1; + int tag_size; + int attr_count; + if (has_version_attribute) { + attr_version_string = string_table.find("version"); + if (attr_version_string == -1) { + string_table.push_back("version"); + attr_version_string = string_table.size() - 1; + } - // android:name attribute - encode_uint32(ns_android_string, &p_manifest.write[ofs + 36]); // ns - encode_uint32(attr_name_string, &p_manifest.write[ofs + 40]); // 'name' - encode_uint32(feature_string, &p_manifest.write[ofs + 44]); // raw_value - encode_uint16(8, &p_manifest.write[ofs + 48]); // typedvalue_size - p_manifest.write[ofs + 50] = 0; // typedvalue_always0 - p_manifest.write[ofs + 51] = 0x03; // typedvalue_type (string) - encode_uint32(feature_string, &p_manifest.write[ofs + 52]); // typedvalue reference - - // android:required attribute - encode_uint32(ns_android_string, &p_manifest.write[ofs + 56]); // ns - encode_uint32(attr_required_string, &p_manifest.write[ofs + 60]); // 'name' - encode_uint32(required_value, &p_manifest.write[ofs + 64]); // raw_value - encode_uint16(8, &p_manifest.write[ofs + 68]); // typedvalue_size - p_manifest.write[ofs + 70] = 0; // typedvalue_always0 - p_manifest.write[ofs + 71] = 0x03; // typedvalue_type (string) - encode_uint32(required_value, &p_manifest.write[ofs + 72]); // typedvalue reference - - // android:version attribute - encode_uint32(ns_android_string, &p_manifest.write[ofs + 76]); // ns - encode_uint32(attr_version_string, &p_manifest.write[ofs + 80]); // 'name' - encode_uint32(version_value, &p_manifest.write[ofs + 84]); // raw_value - encode_uint16(8, &p_manifest.write[ofs + 88]); // typedvalue_size - p_manifest.write[ofs + 90] = 0; // typedvalue_always0 - p_manifest.write[ofs + 91] = 0x03; // typedvalue_type (string) - encode_uint32(version_value, &p_manifest.write[ofs + 92]); // typedvalue reference - - ofs += 96; + version_value = string_table.find(itos(feature_version)); + if (version_value == -1) { + string_table.push_back(itos(feature_version)); + version_value = string_table.size() - 1; + } - // end tag - encode_uint16(0x103, &p_manifest.write[ofs]); // type - encode_uint16(16, &p_manifest.write[ofs + 2]); // headersize - encode_uint32(24, &p_manifest.write[ofs + 4]); // size - encode_uint32(0, &p_manifest.write[ofs + 8]); // lineno - encode_uint32(-1, &p_manifest.write[ofs + 12]); // comment - encode_uint32(-1, &p_manifest.write[ofs + 16]); // ns - encode_uint32(attr_uses_permission_string, &p_manifest.write[ofs + 20]); // name + tag_size = 96; // node and three attrs + end node + attr_count = 3; + } else { + tag_size = 76; // node and two attrs + end node + attr_count = 2; + } + manifest_cur_size += tag_size + 24; + p_manifest.resize(manifest_cur_size); + + // start tag + encode_uint16(0x102, &p_manifest.write[ofs]); // type + encode_uint16(16, &p_manifest.write[ofs + 2]); // headersize + encode_uint32(tag_size, &p_manifest.write[ofs + 4]); // size + encode_uint32(0, &p_manifest.write[ofs + 8]); // lineno + encode_uint32(-1, &p_manifest.write[ofs + 12]); // comment + encode_uint32(-1, &p_manifest.write[ofs + 16]); // ns + encode_uint32(attr_uses_feature_string, &p_manifest.write[ofs + 20]); // name + encode_uint16(20, &p_manifest.write[ofs + 24]); // attr_start + encode_uint16(20, &p_manifest.write[ofs + 26]); // attr_size + encode_uint16(attr_count, &p_manifest.write[ofs + 28]); // num_attrs + encode_uint16(0, &p_manifest.write[ofs + 30]); // id_index + encode_uint16(0, &p_manifest.write[ofs + 32]); // class_index + encode_uint16(0, &p_manifest.write[ofs + 34]); // style_index + + // android:name attribute + encode_uint32(ns_android_string, &p_manifest.write[ofs + 36]); // ns + encode_uint32(attr_name_string, &p_manifest.write[ofs + 40]); // 'name' + encode_uint32(feature_string, &p_manifest.write[ofs + 44]); // raw_value + encode_uint16(8, &p_manifest.write[ofs + 48]); // typedvalue_size + p_manifest.write[ofs + 50] = 0; // typedvalue_always0 + p_manifest.write[ofs + 51] = 0x03; // typedvalue_type (string) + encode_uint32(feature_string, &p_manifest.write[ofs + 52]); // typedvalue reference + + // android:required attribute + encode_uint32(ns_android_string, &p_manifest.write[ofs + 56]); // ns + encode_uint32(attr_required_string, &p_manifest.write[ofs + 60]); // 'name' + encode_uint32(required_value, &p_manifest.write[ofs + 64]); // raw_value + encode_uint16(8, &p_manifest.write[ofs + 68]); // typedvalue_size + p_manifest.write[ofs + 70] = 0; // typedvalue_always0 + p_manifest.write[ofs + 71] = 0x03; // typedvalue_type (string) + encode_uint32(required_value, &p_manifest.write[ofs + 72]); // typedvalue reference + + ofs += 76; + + if (has_version_attribute) { + // android:version attribute + encode_uint32(ns_android_string, &p_manifest.write[ofs]); // ns + encode_uint32(attr_version_string, &p_manifest.write[ofs + 4]); // 'name' + encode_uint32(version_value, &p_manifest.write[ofs + 8]); // raw_value + encode_uint16(8, &p_manifest.write[ofs + 12]); // typedvalue_size + p_manifest.write[ofs + 14] = 0; // typedvalue_always0 + p_manifest.write[ofs + 15] = 0x03; // typedvalue_type (string) + encode_uint32(version_value, &p_manifest.write[ofs + 16]); // typedvalue reference + + ofs += 20; + } - ofs += 24; + // end tag + encode_uint16(0x103, &p_manifest.write[ofs]); // type + encode_uint16(16, &p_manifest.write[ofs + 2]); // headersize + encode_uint32(24, &p_manifest.write[ofs + 4]); // size + encode_uint32(0, &p_manifest.write[ofs + 8]); // lineno + encode_uint32(-1, &p_manifest.write[ofs + 12]); // comment + encode_uint32(-1, &p_manifest.write[ofs + 16]); // ns + encode_uint32(attr_uses_feature_string, &p_manifest.write[ofs + 20]); // name + + ofs += 24; + } + memcpy(&p_manifest.write[ofs], manifest_end.ptr(), manifest_end.size()); + ofs -= 24; // go back over back end } - memcpy(&p_manifest.write[ofs], manifest_end.ptr(), manifest_end.size()); - ofs -= 24; // go back over back end } if (tname == "manifest") { @@ -1245,6 +1301,27 @@ class EditorExportPlatformAndroid : public EditorExportPlatform { //printf("end\n"); } + void _process_launcher_icons(const String &p_processing_file_name, const Ref<Image> &p_source_image, const LauncherIcon p_icon, Vector<uint8_t> &p_data) { + if (p_processing_file_name == p_icon.export_path) { + Ref<Image> working_image = p_source_image; + + if (p_source_image->get_width() != p_icon.dimensions || p_source_image->get_height() != p_icon.dimensions) { + working_image = p_source_image->duplicate(); + working_image->resize(p_icon.dimensions, p_icon.dimensions, Image::Interpolation::INTERPOLATE_LANCZOS); + } + + Vector<uint8_t> png_buffer; + Error err = PNGDriverCommon::image_to_png(working_image, png_buffer); + if (err == OK) { + p_data.resize(png_buffer.size()); + memcpy(p_data.ptrw(), png_buffer.ptr(), p_data.size()); + } else { + String err_str = String("Failed to convert resized icon (") + p_processing_file_name + ") to png."; + WARN_PRINT(err_str.utf8().get_data()); + } + } + } + static Vector<String> get_enabled_abis(const Ref<EditorExportPreset> &p_preset) { Vector<String> abis = get_abis(); Vector<String> enabled_abis; @@ -1266,11 +1343,10 @@ public: String driver = ProjectSettings::get_singleton()->get("rendering/quality/driver/driver_name"); if (driver == "GLES2") { r_features->push_back("etc"); - } else if (driver == "GLES3") { + } + // FIXME: Review what texture formats are used for Vulkan. + if (driver == "Vulkan") { r_features->push_back("etc2"); - if (ProjectSettings::get_singleton()->get("rendering/quality/driver/fallback_to_gles2")) { - r_features->push_back("etc"); - } } Vector<String> abis = get_enabled_abis(p_preset); @@ -1281,13 +1357,14 @@ public: virtual void get_export_options(List<ExportOption> *r_options) { - r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "graphics/xr_mode", PROPERTY_HINT_ENUM, "Regular,Oculus Mobile VR"), 0)); - r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "graphics/degrees_of_freedom", PROPERTY_HINT_ENUM, "None,3DOF and 6DOF,6DOF"), 0)); r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "graphics/32_bits_framebuffer"), true)); + r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "xr_features/xr_mode", PROPERTY_HINT_ENUM, "Regular,Oculus Mobile VR"), 0)); + r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "xr_features/degrees_of_freedom", PROPERTY_HINT_ENUM, "None,3DOF and 6DOF,6DOF"), 0)); + r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "xr_features/hand_tracking", PROPERTY_HINT_ENUM, "None,Optional,Required"), 0)); r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "one_click_deploy/clear_previous_install"), false)); - 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::BOOL, "custom_package/use_custom_build"), false)); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_template/debug", PROPERTY_HINT_GLOBAL_FILE, "*.apk"), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_template/release", PROPERTY_HINT_GLOBAL_FILE, "*.apk"), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "custom_template/use_custom_build"), false)); 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,4096,1,or_greater"), 1)); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "version/name"), "1.0")); @@ -1301,11 +1378,9 @@ public: 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::BOOL, "screen/opengl_debug"), false)); - - for (uint64_t i = 0; i < sizeof(launcher_icons) / sizeof(launcher_icons[0]); ++i) { - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, launcher_icons[i].option_id, PROPERTY_HINT_FILE, "*.png"), "")); - } - + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, launcher_icon_option, PROPERTY_HINT_FILE, "*.png"), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, launcher_adaptive_icon_foreground_option, PROPERTY_HINT_FILE, "*.png"), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, launcher_adaptive_icon_background_option, PROPERTY_HINT_FILE, "*.png"), "")); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "keystore/debug", PROPERTY_HINT_GLOBAL_FILE, "*.keystore"), "")); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "keystore/debug_user"), "")); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "keystore/debug_password"), "")); @@ -1323,7 +1398,7 @@ public: r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "architectures/" + abi), is_default)); } - r_options->push_back(ExportOption(PropertyInfo(Variant::POOL_STRING_ARRAY, "permissions/custom_permissions"), PoolStringArray())); + r_options->push_back(ExportOption(PropertyInfo(Variant::PACKED_STRING_ARRAY, "permissions/custom_permissions"), PackedStringArray())); const char **perms = android_perms; while (*perms) { @@ -1341,7 +1416,7 @@ public: return "Android"; } - virtual Ref<Texture> get_logo() const { + virtual Ref<Texture2D> get_logo() const { return logo; } @@ -1396,20 +1471,22 @@ public: 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); + + String can_export_error; + bool can_export_missing_templates; + if (!can_export(p_preset, can_export_error, can_export_missing_templates)) { + EditorNode::add_io_error(can_export_error); + return ERR_UNCONFIGURED; + } + 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 APK. - if (ep.step("Exporting APK", 0)) { + if (ep.step("Exporting APK...", 0)) { device_lock->unlock(); return ERR_SKIP; } @@ -1459,7 +1536,7 @@ public: } print_line("Installing to device (please wait...): " + devices[p_device].name); - if (ep.step("Installing to device (please wait...)", 2)) { + if (ep.step("Installing to device, please wait...", 2)) { CLEANUP_AND_RETURN(ERR_SKIP); } @@ -1526,7 +1603,7 @@ public: } } - if (ep.step("Running on Device...", 3)) { + if (ep.step("Running on device...", 3)) { CLEANUP_AND_RETURN(ERR_SKIP); } args.clear(); @@ -1554,36 +1631,41 @@ public: #undef CLEANUP_AND_RETURN } - virtual Ref<Texture> get_run_icon() const { + virtual Ref<Texture2D> get_run_icon() const { return run_icon; } virtual bool can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const { String err; + bool valid = false; - if (!bool(p_preset->get("custom_package/use_custom_build"))) { + // Look for export templates (first official, and if defined custom templates). - r_missing_templates = find_export_template("android_debug.apk") == String() || find_export_template("android_release.apk") == String(); + if (!bool(p_preset->get("custom_template/use_custom_build"))) { + bool dvalid = exists_export_template("android_debug.apk", &err); + bool rvalid = exists_export_template("android_release.apk", &err); - if (p_preset->get("custom_package/debug") != "") { - if (FileAccess::exists(p_preset->get("custom_package/debug"))) { - r_missing_templates = false; - } else { + if (p_preset->get("custom_template/debug") != "") { + dvalid = FileAccess::exists(p_preset->get("custom_template/debug")); + if (!dvalid) { err += TTR("Custom debug template not found.") + "\n"; } } - - if (p_preset->get("custom_package/release") != "") { - if (FileAccess::exists(p_preset->get("custom_package/release"))) { - r_missing_templates = false; - } else { + if (p_preset->get("custom_template/release") != "") { + rvalid = FileAccess::exists(p_preset->get("custom_template/release")); + if (!rvalid) { err += TTR("Custom release template not found.") + "\n"; } } + + valid = dvalid || rvalid; + } else { + valid = exists_export_template("android_source.zip", &err); } + r_missing_templates = !valid; - bool valid = !r_missing_templates; + // Validate the rest of the configuration. String adb = EditorSettings::get_singleton()->get("export/android/adb"); @@ -1612,7 +1694,7 @@ public: } } - if (bool(p_preset->get("custom_package/use_custom_build"))) { + if (bool(p_preset->get("custom_template/use_custom_build"))) { String sdk_path = EditorSettings::get_singleton()->get("export/android/custom_build_sdk_path"); if (sdk_path == "") { err += TTR("Custom build requires a valid Android SDK path in Editor Settings.") + "\n"; @@ -1785,7 +1867,7 @@ public: new_file += "//CHUNK_" + text + "_BEGIN\n"; if (!found) { - ERR_PRINTS("No end marker found in build.gradle for chunk: " + text); + ERR_PRINT("No end marker found in build.gradle for chunk: " + text); f->seek(pos); } else { @@ -1821,7 +1903,7 @@ public: new_file += "//DIR_" + text + "_BEGIN\n"; if (!found) { - ERR_PRINTS("No end marker found in build.gradle for dir: " + text); + ERR_PRINT("No end marker found in build.gradle for dir: " + text); f->seek(pos); } else { //add chunk lines @@ -1880,7 +1962,7 @@ public: new_file += "<!--CHUNK_" + text + "_BEGIN-->\n"; if (!found) { - ERR_PRINTS("No end marker found in AndroidManifest.xml for chunk: " + text); + ERR_PRINT("No end marker found in AndroidManifest.xml for chunk: " + text); f->seek(pos); } else { //add chunk lines @@ -1896,10 +1978,10 @@ public: } } else if (l.strip_edges().begins_with("<application")) { - String last_tag = "android:icon=\"@drawable/icon\""; + String last_tag = "android:icon=\"@mipmap/icon\""; int last_tag_pos = l.find(last_tag); if (last_tag_pos == -1) { - ERR_PRINTS("Not adding application attributes as the expected tag was not found in '<application': " + last_tag); + ERR_PRINT("Not adding application attributes as the expected tag was not found in '<application': " + last_tag); new_file += l + "\n"; } else { String base = l.substr(0, last_tag_pos + last_tag.length()); @@ -1933,7 +2015,7 @@ public: EditorProgress ep("export", "Exporting for Android", 105, true); - if (bool(p_preset->get("custom_package/use_custom_build"))) { //custom build + if (bool(p_preset->get("custom_template/use_custom_build"))) { //custom build //re-generate build.gradle and AndroidManifest.xml { //test that installed build version is alright @@ -1968,10 +2050,13 @@ public: build_command = build_path.plus_file(build_command); + String package_name = get_package_name(p_preset->get("package/unique_name")); + List<String> cmdline; cmdline.push_back("build"); - cmdline.push_back("-p"); - cmdline.push_back(build_path); + cmdline.push_back("-Pexport_package_name=" + package_name); // argument to specify the package name. + cmdline.push_back("-p"); // argument to specify the start directory. + cmdline.push_back(build_path); // start directory. /*{ used for debug int ec; String pipe; @@ -1998,9 +2083,9 @@ public: } else { if (p_debug) - src_apk = p_preset->get("custom_package/debug"); + src_apk = p_preset->get("custom_template/debug"); else - src_apk = p_preset->get("custom_package/release"); + src_apk = p_preset->get("custom_template/release"); src_apk = src_apk.strip_edges(); if (src_apk == "") { @@ -2023,7 +2108,7 @@ public: FileAccess *src_f = NULL; zlib_filefunc_def io = zipio_create_io_from_file(&src_f); - if (ep.step("Creating APK", 0)) { + if (ep.step("Creating APK...", 0)) { return ERR_SKIP; } @@ -2072,6 +2157,35 @@ public: Vector<String> enabled_abis = get_enabled_abis(p_preset); + String project_icon_path = ProjectSettings::get_singleton()->get("application/config/icon"); + + // Prepare images to be resized for the icons. If some image ends up being uninitialized, the default image from the export template will be used. + Ref<Image> launcher_icon_image; + Ref<Image> launcher_adaptive_icon_foreground_image; + Ref<Image> launcher_adaptive_icon_background_image; + + launcher_icon_image.instance(); + launcher_adaptive_icon_foreground_image.instance(); + launcher_adaptive_icon_background_image.instance(); + + // Regular icon: user selection -> project icon -> default. + String path = static_cast<String>(p_preset->get(launcher_icon_option)).strip_edges(); + if (path.empty() || ImageLoader::load_image(path, launcher_icon_image) != OK) { + ImageLoader::load_image(project_icon_path, launcher_icon_image); + } + + // Adaptive foreground: user selection -> regular icon (user selection -> project icon -> default). + path = static_cast<String>(p_preset->get(launcher_adaptive_icon_foreground_option)).strip_edges(); + if (path.empty() || ImageLoader::load_image(path, launcher_adaptive_icon_foreground_image) != OK) { + launcher_adaptive_icon_foreground_image = launcher_icon_image; + } + + // Adaptive background: user selection -> default. + path = static_cast<String>(p_preset->get(launcher_adaptive_icon_background_option)).strip_edges(); + if (!path.empty()) { + ImageLoader::load_image(path, launcher_adaptive_icon_background_image); + } + while (ret == UNZ_OK) { //get filename @@ -2094,41 +2208,22 @@ public: //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-nodpi-v4/icon.png") { - bool found = false; - for (uint64_t i = 0; i < sizeof(launcher_icons) / sizeof(launcher_icons[0]); ++i) { - String icon_path = String(p_preset->get(launcher_icons[i].option_id)).strip_edges(); - if (icon_path != "" && icon_path.ends_with(".png")) { - FileAccess *f = FileAccess::open(icon_path, FileAccess::READ); - if (f) { - data.resize(f->get_len()); - f->get_buffer(data.ptrw(), data.size()); - memdelete(f); - found = true; - break; - } - } + for (int i = 0; i < icon_densities_count; ++i) { + if (launcher_icon_image.is_valid() && !launcher_icon_image->empty()) { + _process_launcher_icons(file, launcher_icon_image, launcher_icons[i], data); } - if (!found) { - - String appicon = ProjectSettings::get_singleton()->get("application/config/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.ptrw(), data.size()); - memdelete(f); - } - } + if (launcher_adaptive_icon_foreground_image.is_valid() && !launcher_adaptive_icon_foreground_image->empty()) { + _process_launcher_icons(file, launcher_adaptive_icon_foreground_image, launcher_adaptive_icon_foregrounds[i], data); + } + if (launcher_adaptive_icon_background_image.is_valid() && !launcher_adaptive_icon_background_image->empty()) { + _process_launcher_icons(file, launcher_adaptive_icon_background_image, launcher_adaptive_icon_backgrounds[i], data); } } @@ -2175,7 +2270,7 @@ public: ret = unzGoToNextFile(pkg); } - if (ep.step("Adding Files...", 1)) { + if (ep.step("Adding files...", 1)) { CLEANUP_AND_RETURN(ERR_SKIP); } Error err = OK; @@ -2227,20 +2322,7 @@ public: } } - if (!err) { - APKExportData ed; - ed.ep = &ep; - ed.apk = unaligned_apk; - for (uint64_t i = 0; i < sizeof(launcher_icons) / sizeof(launcher_icons[0]); ++i) { - String icon_path = String(p_preset->get(launcher_icons[i].option_id)).strip_edges(); - if (icon_path != "" && icon_path.ends_with(".png") && FileAccess::exists(icon_path)) { - Vector<uint8_t> data = FileAccess::get_file_as_array(icon_path); - store_in_apk(&ed, launcher_icons[i].export_path, data); - } - } - } - - int xr_mode_index = p_preset->get("graphics/xr_mode"); + int xr_mode_index = p_preset->get("xr_features/xr_mode"); if (xr_mode_index == 1 /* XRMode.OVR */) { cl.push_back("--xr_mode_ovr"); } else { diff --git a/platform/android/export/export.h b/platform/android/export/export.h index 42f3e70450..ce786cc8b6 100644 --- a/platform/android/export/export.h +++ b/platform/android/export/export.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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 f8a2c73a1e..965342b364 100644 --- a/platform/android/file_access_android.cpp +++ b/platform/android/file_access_android.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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 b8e78627ec..6b5ec541fd 100644 --- a/platform/android/file_access_android.h +++ b/platform/android/file_access_android.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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 d4c2a23aa0..db3aa4255e 100644 --- a/platform/android/file_access_jandroid.cpp +++ b/platform/android/file_access_jandroid.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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 9429100d65..b361c64922 100644 --- a/platform/android/file_access_jandroid.h +++ b/platform/android/file_access_jandroid.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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/app/AndroidManifest.xml b/platform/android/java/app/AndroidManifest.xml index ba01ec313b..4d2eb1ef65 100644 --- a/platform/android/java/app/AndroidManifest.xml +++ b/platform/android/java/app/AndroidManifest.xml @@ -15,7 +15,6 @@ android:largeScreens="true" android:xlargeScreens="true" /> - <!-- glEsVersion is modified by the exporter, changing this value here has no effect. --> <uses-feature android:glEsVersion="0x00020000" android:required="true" /> @@ -27,7 +26,7 @@ <!-- Any tag in this line after android:icon will be erased when doing custom builds. --> <!-- If you want to add tags manually, do before it. --> <!-- WARNING: This should stay on a single line until the parsing code is improved. See GH-32414. --> - <application android:label="@string/godot_project_name_string" android:allowBackup="false" tools:ignore="GoogleAppIndexingWarning" android:icon="@drawable/icon" > + <application android:label="@string/godot_project_name_string" android:allowBackup="false" tools:ignore="GoogleAppIndexingWarning" android:icon="@mipmap/icon" > <!-- The following metadata values are replaced when Godot exports, modifying them here has no effect. --> <!-- Do these changes in the export preset. Adding new ones is fine. --> diff --git a/platform/android/java/app/build.gradle b/platform/android/java/app/build.gradle index 9f64c3dc8a..2e4f2ffab0 100644 --- a/platform/android/java/app/build.gradle +++ b/platform/android/java/app/build.gradle @@ -33,6 +33,8 @@ allprojects { } dependencies { + implementation libraries.supportCoreUtils + if (rootProject.findProject(":lib")) { implementation project(":lib") } else { @@ -51,7 +53,7 @@ android { defaultConfig { // Feel free to modify the application id to your own. - applicationId "com.godot.game" + applicationId getExportPackageName() minSdkVersion versions.minSdk targetSdkVersion versions.targetSdk //CHUNK_ANDROID_DEFAULTCONFIG_BEGIN diff --git a/platform/android/java/app/config.gradle b/platform/android/java/app/config.gradle index 20c3123221..5550d3099d 100644 --- a/platform/android/java/app/config.gradle +++ b/platform/android/java/app/config.gradle @@ -4,9 +4,21 @@ ext.versions = [ minSdk : 18, targetSdk : 28, buildTools : '28.0.3', + supportCoreUtils : '28.0.0' ] ext.libraries = [ - androidGradlePlugin : "com.android.tools.build:gradle:$versions.androidGradlePlugin" + androidGradlePlugin : "com.android.tools.build:gradle:$versions.androidGradlePlugin", + supportCoreUtils : "com.android.support:support-core-utils:$versions.supportCoreUtils" ] + +ext.getExportPackageName = { -> + // Retrieve the app id from the project property set by the Godot build command. + String appId = project.hasProperty("export_package_name") ? project.property("export_package_name") : "" + // Check if the app id is valid, otherwise use the default. + if (appId == null || appId.isEmpty()) { + appId = "com.godot.game" + } + return appId +} diff --git a/platform/android/java/app/src/com/godot/game/GodotApp.java b/platform/android/java/app/src/com/godot/game/GodotApp.java index d7469a8765..eb884404cd 100644 --- a/platform/android/java/app/src/com/godot/game/GodotApp.java +++ b/platform/android/java/app/src/com/godot/game/GodotApp.java @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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/lib/AndroidManifest.xml b/platform/android/java/lib/AndroidManifest.xml index 517fc403b2..b133585f99 100644 --- a/platform/android/java/lib/AndroidManifest.xml +++ b/platform/android/java/lib/AndroidManifest.xml @@ -11,7 +11,7 @@ </application> <instrumentation - android:icon="@drawable/icon" + android:icon="@mipmap/icon" android:label="@string/godot_project_name_string" android:name=".GodotInstrumentation" android:targetPackage="org.godotengine.godot" /> diff --git a/platform/android/java/lib/build.gradle b/platform/android/java/lib/build.gradle index 13a14422ed..eb97484b9c 100644 --- a/platform/android/java/lib/build.gradle +++ b/platform/android/java/lib/build.gradle @@ -1,7 +1,7 @@ apply plugin: 'com.android.library' dependencies { - implementation "com.android.support:support-core-utils:28.0.0" + implementation libraries.supportCoreUtils } def pathToRootDir = "../../../../" diff --git a/platform/android/java/lib/res/drawable-nodpi/icon.png b/platform/android/java/lib/res/drawable-nodpi/icon.png Binary files differdeleted file mode 100644 index 6ad9b43117..0000000000 --- a/platform/android/java/lib/res/drawable-nodpi/icon.png +++ /dev/null diff --git a/platform/android/java/lib/res/mipmap-anydpi-v26/icon.xml b/platform/android/java/lib/res/mipmap-anydpi-v26/icon.xml new file mode 100644 index 0000000000..1ed4037035 --- /dev/null +++ b/platform/android/java/lib/res/mipmap-anydpi-v26/icon.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8"?> +<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android"> + <background android:drawable="@mipmap/icon_background"/> + <foreground android:drawable="@mipmap/icon_foreground"/> +</adaptive-icon>
\ No newline at end of file diff --git a/platform/android/java/lib/res/mipmap-hdpi/icon.png b/platform/android/java/lib/res/mipmap-hdpi/icon.png Binary files differnew file mode 100644 index 0000000000..cc6e113e89 --- /dev/null +++ b/platform/android/java/lib/res/mipmap-hdpi/icon.png diff --git a/platform/android/java/lib/res/mipmap-hdpi/icon_background.png b/platform/android/java/lib/res/mipmap-hdpi/icon_background.png Binary files differnew file mode 100644 index 0000000000..78445c0181 --- /dev/null +++ b/platform/android/java/lib/res/mipmap-hdpi/icon_background.png diff --git a/platform/android/java/lib/res/mipmap-hdpi/icon_foreground.png b/platform/android/java/lib/res/mipmap-hdpi/icon_foreground.png Binary files differnew file mode 100644 index 0000000000..75e409ff74 --- /dev/null +++ b/platform/android/java/lib/res/mipmap-hdpi/icon_foreground.png diff --git a/platform/android/java/lib/res/mipmap-mdpi/icon.png b/platform/android/java/lib/res/mipmap-mdpi/icon.png Binary files differnew file mode 100644 index 0000000000..e1968fe142 --- /dev/null +++ b/platform/android/java/lib/res/mipmap-mdpi/icon.png diff --git a/platform/android/java/lib/res/mipmap-mdpi/icon_background.png b/platform/android/java/lib/res/mipmap-mdpi/icon_background.png Binary files differnew file mode 100644 index 0000000000..5813f751ed --- /dev/null +++ b/platform/android/java/lib/res/mipmap-mdpi/icon_background.png diff --git a/platform/android/java/lib/res/mipmap-mdpi/icon_foreground.png b/platform/android/java/lib/res/mipmap-mdpi/icon_foreground.png Binary files differnew file mode 100644 index 0000000000..982b69be1e --- /dev/null +++ b/platform/android/java/lib/res/mipmap-mdpi/icon_foreground.png diff --git a/platform/android/java/lib/res/mipmap-xhdpi/icon.png b/platform/android/java/lib/res/mipmap-xhdpi/icon.png Binary files differnew file mode 100644 index 0000000000..9281d8da48 --- /dev/null +++ b/platform/android/java/lib/res/mipmap-xhdpi/icon.png diff --git a/platform/android/java/lib/res/mipmap-xhdpi/icon_background.png b/platform/android/java/lib/res/mipmap-xhdpi/icon_background.png Binary files differnew file mode 100644 index 0000000000..4269c822a7 --- /dev/null +++ b/platform/android/java/lib/res/mipmap-xhdpi/icon_background.png diff --git a/platform/android/java/lib/res/mipmap-xhdpi/icon_foreground.png b/platform/android/java/lib/res/mipmap-xhdpi/icon_foreground.png Binary files differnew file mode 100644 index 0000000000..726b267ad6 --- /dev/null +++ b/platform/android/java/lib/res/mipmap-xhdpi/icon_foreground.png diff --git a/platform/android/java/lib/res/mipmap-xxhdpi/icon.png b/platform/android/java/lib/res/mipmap-xxhdpi/icon.png Binary files differnew file mode 100644 index 0000000000..7a6b67d273 --- /dev/null +++ b/platform/android/java/lib/res/mipmap-xxhdpi/icon.png diff --git a/platform/android/java/lib/res/mipmap-xxhdpi/icon_background.png b/platform/android/java/lib/res/mipmap-xxhdpi/icon_background.png Binary files differnew file mode 100644 index 0000000000..5e8b518d17 --- /dev/null +++ b/platform/android/java/lib/res/mipmap-xxhdpi/icon_background.png diff --git a/platform/android/java/lib/res/mipmap-xxhdpi/icon_foreground.png b/platform/android/java/lib/res/mipmap-xxhdpi/icon_foreground.png Binary files differnew file mode 100644 index 0000000000..b0c727f74c --- /dev/null +++ b/platform/android/java/lib/res/mipmap-xxhdpi/icon_foreground.png diff --git a/platform/android/java/lib/res/mipmap-xxxhdpi/icon.png b/platform/android/java/lib/res/mipmap-xxxhdpi/icon.png Binary files differnew file mode 100644 index 0000000000..0881245802 --- /dev/null +++ b/platform/android/java/lib/res/mipmap-xxxhdpi/icon.png diff --git a/platform/android/java/lib/res/mipmap-xxxhdpi/icon_background.png b/platform/android/java/lib/res/mipmap-xxxhdpi/icon_background.png Binary files differnew file mode 100644 index 0000000000..004b6fd508 --- /dev/null +++ b/platform/android/java/lib/res/mipmap-xxxhdpi/icon_background.png diff --git a/platform/android/java/lib/res/mipmap-xxxhdpi/icon_foreground.png b/platform/android/java/lib/res/mipmap-xxxhdpi/icon_foreground.png Binary files differnew file mode 100644 index 0000000000..72e6f92b6e --- /dev/null +++ b/platform/android/java/lib/res/mipmap-xxxhdpi/icon_foreground.png diff --git a/platform/android/java/lib/res/mipmap/icon.png b/platform/android/java/lib/res/mipmap/icon.png Binary files differnew file mode 100644 index 0000000000..0881245802 --- /dev/null +++ b/platform/android/java/lib/res/mipmap/icon.png diff --git a/platform/android/java/lib/res/mipmap/icon_background.png b/platform/android/java/lib/res/mipmap/icon_background.png Binary files differnew file mode 100644 index 0000000000..5813f751ed --- /dev/null +++ b/platform/android/java/lib/res/mipmap/icon_background.png diff --git a/platform/android/java/lib/res/mipmap/icon_foreground.png b/platform/android/java/lib/res/mipmap/icon_foreground.png Binary files differnew file mode 100644 index 0000000000..982b69be1e --- /dev/null +++ b/platform/android/java/lib/res/mipmap/icon_foreground.png diff --git a/platform/android/java/lib/src/org/godotengine/godot/Dictionary.java b/platform/android/java/lib/src/org/godotengine/godot/Dictionary.java index 588d9ae646..594cae774b 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/Dictionary.java +++ b/platform/android/java/lib/src/org/godotengine/godot/Dictionary.java @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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/lib/src/org/godotengine/godot/Godot.java b/platform/android/java/lib/src/org/godotengine/godot/Godot.java index 4dae2dcc53..021214b627 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/Godot.java +++ b/platform/android/java/lib/src/org/godotengine/godot/Godot.java @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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,6 +96,7 @@ import java.util.Locale; import javax.microedition.khronos.opengles.GL10; import org.godotengine.godot.input.GodotEditText; import org.godotengine.godot.payments.PaymentsManager; +import org.godotengine.godot.utils.GodotNetUtils; import org.godotengine.godot.utils.PermissionsUtil; import org.godotengine.godot.xr.XRMode; @@ -243,6 +244,7 @@ public abstract class Godot extends Activity implements SensorEventListener, IDo private Sensor mGyroscope; public static GodotIO io; + public static GodotNetUtils netUtils; static SingletonBase[] singletons = new SingletonBase[MAX_SINGLETONS]; static int singleton_count = 0; @@ -285,8 +287,6 @@ public abstract class Godot extends Activity implements SensorEventListener, IDo */ @Keep private void onVideoInit() { - boolean use_gl3 = getGLESVersionCode() >= 0x00030000; - final FrameLayout layout = new FrameLayout(this); layout.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)); setContentView(layout); @@ -297,7 +297,7 @@ public abstract class Godot extends Activity implements SensorEventListener, IDo // ...add to FrameLayout layout.addView(edittext); - mView = new GodotView(this, xrMode, use_gl3, use_32_bits, use_debug_opengl); + mView = new GodotView(this, xrMode, use_32_bits, use_debug_opengl); layout.addView(mView, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)); edittext.setView(mView); io.setEdit(edittext); @@ -502,6 +502,7 @@ public abstract class Godot extends Activity implements SensorEventListener, IDo io = new GodotIO(this); io.unique_id = Secure.getString(getContentResolver(), Secure.ANDROID_ID); GodotLib.io = io; + netUtils = new GodotNetUtils(this); mSensorManager = (SensorManager)getSystemService(Context.SENSOR_SERVICE); mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_GAME); diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotDownloaderAlarmReceiver.java b/platform/android/java/lib/src/org/godotengine/godot/GodotDownloaderAlarmReceiver.java index e7e2a3f808..1fb242d0bc 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/GodotDownloaderAlarmReceiver.java +++ b/platform/android/java/lib/src/org/godotengine/godot/GodotDownloaderAlarmReceiver.java @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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/lib/src/org/godotengine/godot/GodotDownloaderService.java b/platform/android/java/lib/src/org/godotengine/godot/GodotDownloaderService.java index 8e10710c9f..7e74e8a80d 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/GodotDownloaderService.java +++ b/platform/android/java/lib/src/org/godotengine/godot/GodotDownloaderService.java @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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/lib/src/org/godotengine/godot/GodotIO.java b/platform/android/java/lib/src/org/godotengine/godot/GodotIO.java index 04566cf62c..68ce40ba10 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/GodotIO.java +++ b/platform/android/java/lib/src/org/godotengine/godot/GodotIO.java @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -491,9 +491,9 @@ public class GodotIO { return (int)(metrics.density * 160f); } - public void showKeyboard(String p_existing_text) { + public void showKeyboard(String p_existing_text, int p_max_input_length) { if (edit != null) - edit.showKeyboard(p_existing_text); + edit.showKeyboard(p_existing_text, p_max_input_length); //InputMethodManager inputMgr = (InputMethodManager)activity.getSystemService(Context.INPUT_METHOD_SERVICE); //inputMgr.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0); diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotInstrumentation.java b/platform/android/java/lib/src/org/godotengine/godot/GodotInstrumentation.java index 0466f380e8..965e616ef3 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/GodotInstrumentation.java +++ b/platform/android/java/lib/src/org/godotengine/godot/GodotInstrumentation.java @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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/lib/src/org/godotengine/godot/GodotLib.java b/platform/android/java/lib/src/org/godotengine/godot/GodotLib.java index 67dce172dc..e0b46673ba 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/GodotLib.java +++ b/platform/android/java/lib/src/org/godotengine/godot/GodotLib.java @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -100,6 +100,16 @@ public class GodotLib { public static native void hover(int type, int x, int y); /** + * Forward double_tap events from the main thread to the GL thread. + */ + public static native void doubletap(int x, int y); + + /** + * Forward scroll events from the main thread to the GL thread. + */ + public static native void scroll(int x, int y); + + /** * Forward accelerometer sensor events from the main thread to the GL thread. * @see android.hardware.SensorEventListener#onSensorChanged(SensorEvent) */ diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotPaymentV3.java b/platform/android/java/lib/src/org/godotengine/godot/GodotPaymentV3.java index 1432cd3a67..93265d509f 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/GodotPaymentV3.java +++ b/platform/android/java/lib/src/org/godotengine/godot/GodotPaymentV3.java @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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/lib/src/org/godotengine/godot/GodotRenderer.java b/platform/android/java/lib/src/org/godotengine/godot/GodotRenderer.java index 56ba88656e..26fa033f12 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/GodotRenderer.java +++ b/platform/android/java/lib/src/org/godotengine/godot/GodotRenderer.java @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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/lib/src/org/godotengine/godot/GodotView.java b/platform/android/java/lib/src/org/godotengine/godot/GodotView.java index 5511e5d782..8d3c2ae319 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/GodotView.java +++ b/platform/android/java/lib/src/org/godotengine/godot/GodotView.java @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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,8 +32,10 @@ package org.godotengine.godot; import android.annotation.SuppressLint; import android.graphics.PixelFormat; import android.opengl.GLSurfaceView; +import android.view.GestureDetector; import android.view.KeyEvent; import android.view.MotionEvent; +import org.godotengine.godot.input.GodotGestureHandler; import org.godotengine.godot.input.GodotInputHandler; import org.godotengine.godot.utils.GLUtils; import org.godotengine.godot.xr.XRMode; @@ -68,16 +70,17 @@ public class GodotView extends GLSurfaceView { private final Godot activity; private final GodotInputHandler inputHandler; + private final GestureDetector detector; private final GodotRenderer godotRenderer; - public GodotView(Godot activity, XRMode xrMode, boolean p_use_gl3, boolean p_use_32_bits, boolean p_use_debug_opengl) { + public GodotView(Godot activity, XRMode xrMode, boolean p_use_32_bits, boolean p_use_debug_opengl) { super(activity); - GLUtils.use_gl3 = p_use_gl3; GLUtils.use_32 = p_use_32_bits; GLUtils.use_debug_opengl = p_use_debug_opengl; this.activity = activity; this.inputHandler = new GodotInputHandler(this); + this.detector = new GestureDetector(activity, new GodotGestureHandler(this)); this.godotRenderer = new GodotRenderer(); init(xrMode, false, 16, 0); } @@ -90,6 +93,7 @@ public class GodotView extends GLSurfaceView { @Override public boolean onTouchEvent(MotionEvent event) { super.onTouchEvent(event); + this.detector.onTouchEvent(event); return activity.gotTouchEvent(event); } diff --git a/platform/android/java/lib/src/org/godotengine/godot/input/GodotEditText.java b/platform/android/java/lib/src/org/godotengine/godot/input/GodotEditText.java index 45b739baa0..e901b4b36d 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/input/GodotEditText.java +++ b/platform/android/java/lib/src/org/godotengine/godot/input/GodotEditText.java @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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,6 +32,7 @@ package org.godotengine.godot.input; import android.content.Context; import android.os.Handler; import android.os.Message; +import android.text.InputFilter; import android.util.AttributeSet; import android.view.KeyEvent; import android.view.inputmethod.EditorInfo; @@ -104,6 +105,7 @@ public class GodotEditText extends EditText { edit.append(text); edit.mInputWrapper.setOriginText(text); edit.addTextChangedListener(edit.mInputWrapper); + setMaxInputLength(edit, msg.arg1); final InputMethodManager imm = (InputMethodManager)mView.getContext().getSystemService(Context.INPUT_METHOD_SERVICE); imm.showSoftInput(edit, 0); } @@ -120,6 +122,16 @@ public class GodotEditText extends EditText { } } + private void setMaxInputLength(EditText p_edit_text, int p_max_input_length) { + if (p_max_input_length > 0) { + InputFilter[] filters = new InputFilter[1]; + filters[0] = new InputFilter.LengthFilter(p_max_input_length); + p_edit_text.setFilters(filters); + } else { + p_edit_text.setFilters(new InputFilter[] {}); + } + } + // =========================================================== // Getter & Setter // =========================================================== @@ -149,12 +161,13 @@ public class GodotEditText extends EditText { // =========================================================== // Methods // =========================================================== - public void showKeyboard(String p_existing_text) { + public void showKeyboard(String p_existing_text, int p_max_input_length) { this.mOriginText = p_existing_text; final Message msg = new Message(); msg.what = HANDLER_OPEN_IME_KEYBOARD; msg.obj = this; + msg.arg1 = p_max_input_length; sHandler.sendMessage(msg); } diff --git a/platform/android/java/lib/src/org/godotengine/godot/input/GodotGestureHandler.java b/platform/android/java/lib/src/org/godotengine/godot/input/GodotGestureHandler.java new file mode 100644 index 0000000000..1a38a9c3d2 --- /dev/null +++ b/platform/android/java/lib/src/org/godotengine/godot/input/GodotGestureHandler.java @@ -0,0 +1,106 @@ +/*************************************************************************/ +/* GodotGestureHandler.java */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +package org.godotengine.godot.input; + +import android.util.Log; +import android.view.GestureDetector; +import android.view.MotionEvent; +import org.godotengine.godot.GodotLib; +import org.godotengine.godot.GodotView; + +/** + * Handles gesture input related events for the {@link GodotView} view. + * https://developer.android.com/reference/android/view/GestureDetector.SimpleOnGestureListener + */ +public class GodotGestureHandler extends GestureDetector.SimpleOnGestureListener { + + private final GodotView godotView; + + public GodotGestureHandler(GodotView godotView) { + this.godotView = godotView; + } + + private void queueEvent(Runnable task) { + godotView.queueEvent(task); + } + + @Override + public boolean onDown(MotionEvent event) { + super.onDown(event); + //Log.i("GodotGesture", "onDown"); + return true; + } + + @Override + public boolean onSingleTapConfirmed(MotionEvent event) { + super.onSingleTapConfirmed(event); + return true; + } + + @Override + public void onLongPress(MotionEvent event) { + //Log.i("GodotGesture", "onLongPress"); + } + + @Override + public boolean onDoubleTap(MotionEvent event) { + //Log.i("GodotGesture", "onDoubleTap"); + final int x = Math.round(event.getX()); + final int y = Math.round(event.getY()); + queueEvent(new Runnable() { + @Override + public void run() { + GodotLib.doubletap(x, y); + } + }); + return true; + } + + @Override + public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { + //Log.i("GodotGesture", "onScroll"); + final int x = Math.round(distanceX); + final int y = Math.round(distanceY); + queueEvent(new Runnable() { + @Override + public void run() { + GodotLib.scroll(x, y); + } + }); + return true; + } + + @Override + public boolean onFling(MotionEvent event1, MotionEvent event2, float velocityX, float velocityY) { + //Log.i("GodotGesture", "onFling"); + return true; + } +} diff --git a/platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java b/platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java index 2756ca6c83..b2b88088e8 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java +++ b/platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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/lib/src/org/godotengine/godot/input/GodotTextInputWrapper.java b/platform/android/java/lib/src/org/godotengine/godot/input/GodotTextInputWrapper.java index 9b372c75e3..3a154f1bf3 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/input/GodotTextInputWrapper.java +++ b/platform/android/java/lib/src/org/godotengine/godot/input/GodotTextInputWrapper.java @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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/lib/src/org/godotengine/godot/input/Joystick.java b/platform/android/java/lib/src/org/godotengine/godot/input/Joystick.java index ff95bfb0c5..0c1bdb32aa 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/input/Joystick.java +++ b/platform/android/java/lib/src/org/godotengine/godot/input/Joystick.java @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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/lib/src/org/godotengine/godot/payments/ConsumeTask.java b/platform/android/java/lib/src/org/godotengine/godot/payments/ConsumeTask.java index 4c1050c948..95cc48f536 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/payments/ConsumeTask.java +++ b/platform/android/java/lib/src/org/godotengine/godot/payments/ConsumeTask.java @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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/lib/src/org/godotengine/godot/payments/HandlePurchaseTask.java b/platform/android/java/lib/src/org/godotengine/godot/payments/HandlePurchaseTask.java index 1a914967a2..23d693cc8c 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/payments/HandlePurchaseTask.java +++ b/platform/android/java/lib/src/org/godotengine/godot/payments/HandlePurchaseTask.java @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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/lib/src/org/godotengine/godot/payments/PaymentsCache.java b/platform/android/java/lib/src/org/godotengine/godot/payments/PaymentsCache.java index 8a2facbcfb..84a7eda6e0 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/payments/PaymentsCache.java +++ b/platform/android/java/lib/src/org/godotengine/godot/payments/PaymentsCache.java @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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/lib/src/org/godotengine/godot/payments/PaymentsManager.java b/platform/android/java/lib/src/org/godotengine/godot/payments/PaymentsManager.java index c079c55854..90b958266b 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/payments/PaymentsManager.java +++ b/platform/android/java/lib/src/org/godotengine/godot/payments/PaymentsManager.java @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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/lib/src/org/godotengine/godot/payments/PurchaseTask.java b/platform/android/java/lib/src/org/godotengine/godot/payments/PurchaseTask.java index 9adc85e521..09c9349124 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/payments/PurchaseTask.java +++ b/platform/android/java/lib/src/org/godotengine/godot/payments/PurchaseTask.java @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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/lib/src/org/godotengine/godot/payments/ReleaseAllConsumablesTask.java b/platform/android/java/lib/src/org/godotengine/godot/payments/ReleaseAllConsumablesTask.java index daca6ef5ae..a101780511 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/payments/ReleaseAllConsumablesTask.java +++ b/platform/android/java/lib/src/org/godotengine/godot/payments/ReleaseAllConsumablesTask.java @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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/lib/src/org/godotengine/godot/payments/ValidateTask.java b/platform/android/java/lib/src/org/godotengine/godot/payments/ValidateTask.java index 17a2a197ad..dbb6b8a783 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/payments/ValidateTask.java +++ b/platform/android/java/lib/src/org/godotengine/godot/payments/ValidateTask.java @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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/lib/src/org/godotengine/godot/utils/Crypt.java b/platform/android/java/lib/src/org/godotengine/godot/utils/Crypt.java index 4c551d1d21..bc0e565774 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/utils/Crypt.java +++ b/platform/android/java/lib/src/org/godotengine/godot/utils/Crypt.java @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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/lib/src/org/godotengine/godot/utils/CustomSSLSocketFactory.java b/platform/android/java/lib/src/org/godotengine/godot/utils/CustomSSLSocketFactory.java index b61007faa3..c78e8c1c66 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/utils/CustomSSLSocketFactory.java +++ b/platform/android/java/lib/src/org/godotengine/godot/utils/CustomSSLSocketFactory.java @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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/lib/src/org/godotengine/godot/utils/GLUtils.java b/platform/android/java/lib/src/org/godotengine/godot/utils/GLUtils.java index 6c95494f8b..9d29551f89 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/utils/GLUtils.java +++ b/platform/android/java/lib/src/org/godotengine/godot/utils/GLUtils.java @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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,7 +44,6 @@ public class GLUtils { public static final boolean DEBUG = false; - public static boolean use_gl3 = false; public static boolean use_32 = false; public static boolean use_debug_opengl = false; diff --git a/platform/uwp/power_uwp.cpp b/platform/android/java/lib/src/org/godotengine/godot/utils/GodotNetUtils.java index ba1311a1b1..011d426c7e 100644 --- a/platform/uwp/power_uwp.cpp +++ b/platform/android/java/lib/src/org/godotengine/godot/utils/GodotNetUtils.java @@ -1,12 +1,12 @@ /*************************************************************************/ -/* power_uwp.cpp */ +/* GodotNetUtils.java */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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,50 +28,56 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "power_uwp.h" +package org.godotengine.godot.utils; -PowerUWP::PowerUWP() : - nsecs_left(-1), - percent_left(-1), - power_state(OS::POWERSTATE_UNKNOWN) { -} +import android.content.Context; +import android.net.wifi.WifiManager; +import android.util.Log; +import org.godotengine.godot.Godot; -PowerUWP::~PowerUWP() { -} +/** + * This class handles Android-specific networking functions. + * For now, it only provides access to WifiManager.MulticastLock, which is needed on some devices + * to receive broadcast and multicast packets. + */ +public class GodotNetUtils { -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; -} + /* A single, reference counted, multicast lock, or null if permission CHANGE_WIFI_MULTICAST_STATE is missing */ + private WifiManager.MulticastLock multicastLock; -OS::PowerState PowerUWP::get_power_state() { - if (UpdatePowerInfo()) { - return power_state; - } else { - WARN_PRINT("Power management is not implemented on this platform, defaulting to POWERSTATE_UNKNOWN"); - return OS::POWERSTATE_UNKNOWN; + public GodotNetUtils(Godot p_activity) { + if (PermissionsUtil.hasManifestPermission(p_activity, "android.permission.CHANGE_WIFI_MULTICAST_STATE")) { + WifiManager wifi = (WifiManager)p_activity.getApplicationContext().getSystemService(Context.WIFI_SERVICE); + multicastLock = wifi.createMulticastLock("GodotMulticastLock"); + multicastLock.setReferenceCounted(true); + } } -} -int PowerUWP::get_power_seconds_left() { - if (UpdatePowerInfo()) { - return nsecs_left; - } else { - WARN_PRINT("Power management is not implemented on this platform, defaulting to -1"); - return -1; + /** + * Acquire the multicast lock. This is required on some devices to receive broadcast/multicast packets. + * This is done automatically by Godot when enabling broadcast or joining a multicast group on a socket. + */ + public void multicastLockAcquire() { + if (multicastLock == null) + return; + try { + multicastLock.acquire(); + } catch (RuntimeException e) { + Log.e("Godot", "Exception during multicast lock acquire: " + e); + } } -} -int PowerUWP::get_power_percent_left() { - if (UpdatePowerInfo()) { - return percent_left; - } else { - WARN_PRINT("Power management is not implemented on this platform, defaulting to -1"); - return -1; + /** + * Release the multicast lock. + * This is done automatically by Godot when the lock is no longer needed by a socket. + */ + public void multicastLockRelease() { + if (multicastLock == null) + return; + try { + multicastLock.release(); + } catch (RuntimeException e) { + Log.e("Godot", "Exception during multicast lock release: " + e); + } } } diff --git a/platform/android/java/lib/src/org/godotengine/godot/utils/HttpRequester.java b/platform/android/java/lib/src/org/godotengine/godot/utils/HttpRequester.java index 02ae753b3e..68f9a83597 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/utils/HttpRequester.java +++ b/platform/android/java/lib/src/org/godotengine/godot/utils/HttpRequester.java @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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/lib/src/org/godotengine/godot/utils/PermissionsUtil.java b/platform/android/java/lib/src/org/godotengine/godot/utils/PermissionsUtil.java index 2c4a444e5a..7cf32b00fe 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/utils/PermissionsUtil.java +++ b/platform/android/java/lib/src/org/godotengine/godot/utils/PermissionsUtil.java @@ -1,3 +1,33 @@ +/*************************************************************************/ +/* PermissionsUtil.java */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + package org.godotengine.godot.utils; import android.Manifest; @@ -71,7 +101,7 @@ public final class PermissionsUtil { return false; } - if (manifestPermissions == null || manifestPermissions.length == 0) + if (manifestPermissions.length == 0) return true; List<String> dangerousPermissions = new ArrayList<>(); @@ -111,8 +141,8 @@ public final class PermissionsUtil { e.printStackTrace(); return new String[0]; } - if (manifestPermissions == null || manifestPermissions.length == 0) - return new String[0]; + if (manifestPermissions.length == 0) + return manifestPermissions; List<String> dangerousPermissions = new ArrayList<>(); for (String manifestPermission : manifestPermissions) { @@ -132,6 +162,24 @@ public final class PermissionsUtil { } /** + * Check if the given permission is in the AndroidManifest.xml file. + * @param activity the caller activity for this method. + * @param permission the permession to look for in the manifest file. + * @return "true" if the permission is in the manifest file of the activity, "false" otherwise. + */ + public static boolean hasManifestPermission(Godot activity, String permission) { + try { + for (String p : getManifestPermissions(activity)) { + if (permission.equals(p)) + return true; + } + } catch (PackageManager.NameNotFoundException e) { + } + + return false; + } + + /** * Returns the permissions defined in the AndroidManifest.xml file. * @param activity the caller activity for this method. * @return manifest permissions list @@ -140,6 +188,8 @@ public final class PermissionsUtil { private static String[] getManifestPermissions(Godot activity) throws PackageManager.NameNotFoundException { PackageManager packageManager = activity.getPackageManager(); PackageInfo packageInfo = packageManager.getPackageInfo(activity.getPackageName(), PackageManager.GET_PERMISSIONS); + if (packageInfo.requestedPermissions == null) + return new String[0]; return packageInfo.requestedPermissions; } diff --git a/platform/android/java/lib/src/org/godotengine/godot/utils/RequestParams.java b/platform/android/java/lib/src/org/godotengine/godot/utils/RequestParams.java index b9fe0dd0c9..25fa10647d 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/utils/RequestParams.java +++ b/platform/android/java/lib/src/org/godotengine/godot/utils/RequestParams.java @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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/lib/src/org/godotengine/godot/xr/XRMode.java b/platform/android/java/lib/src/org/godotengine/godot/xr/XRMode.java index 5896b23ac3..982e43f9d1 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/xr/XRMode.java +++ b/platform/android/java/lib/src/org/godotengine/godot/xr/XRMode.java @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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/lib/src/org/godotengine/godot/xr/ovr/OvrConfigChooser.java b/platform/android/java/lib/src/org/godotengine/godot/xr/ovr/OvrConfigChooser.java index ff836a31ca..9209d6ccf2 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/xr/ovr/OvrConfigChooser.java +++ b/platform/android/java/lib/src/org/godotengine/godot/xr/ovr/OvrConfigChooser.java @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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/lib/src/org/godotengine/godot/xr/ovr/OvrContextFactory.java b/platform/android/java/lib/src/org/godotengine/godot/xr/ovr/OvrContextFactory.java index 5f6da8c672..36f4416df2 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/xr/ovr/OvrContextFactory.java +++ b/platform/android/java/lib/src/org/godotengine/godot/xr/ovr/OvrContextFactory.java @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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/lib/src/org/godotengine/godot/xr/ovr/OvrWindowSurfaceFactory.java b/platform/android/java/lib/src/org/godotengine/godot/xr/ovr/OvrWindowSurfaceFactory.java index f1e38c35d8..b2aa130f37 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/xr/ovr/OvrWindowSurfaceFactory.java +++ b/platform/android/java/lib/src/org/godotengine/godot/xr/ovr/OvrWindowSurfaceFactory.java @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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/lib/src/org/godotengine/godot/xr/regular/RegularConfigChooser.java b/platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularConfigChooser.java index 3836967f86..8409e37f8f 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularConfigChooser.java +++ b/platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularConfigChooser.java @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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 +45,8 @@ public class RegularConfigChooser implements GLSurfaceView.EGLConfigChooser { private int[] mValue = new int[1]; + // FIXME: Add support for Vulkan. + /* This EGL config specification is used to specify 2.0 rendering. * We use a minimum size of 4 bits for red/green/blue, but will * perform actual matching in chooseConfig() below. @@ -59,15 +61,6 @@ public class RegularConfigChooser implements GLSurfaceView.EGLConfigChooser { EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, EGL10.EGL_NONE }; - private static int[] s_configAttribs3 = { - EGL10.EGL_RED_SIZE, 4, - EGL10.EGL_GREEN_SIZE, 4, - EGL10.EGL_BLUE_SIZE, 4, - // EGL10.EGL_DEPTH_SIZE, 16, - // EGL10.EGL_STENCIL_SIZE, EGL10.EGL_DONT_CARE, - EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, //apparently there is no EGL_OPENGL_ES3_BIT - EGL10.EGL_NONE - }; public RegularConfigChooser(int r, int g, int b, int a, int depth, int stencil) { mRedSize = r; @@ -83,7 +76,7 @@ public class RegularConfigChooser implements GLSurfaceView.EGLConfigChooser { /* Get the number of minimally matching EGL configurations */ int[] num_config = new int[1]; - egl.eglChooseConfig(display, GLUtils.use_gl3 ? s_configAttribs3 : s_configAttribs2, null, 0, num_config); + egl.eglChooseConfig(display, s_configAttribs2, null, 0, num_config); int numConfigs = num_config[0]; @@ -94,7 +87,7 @@ public class RegularConfigChooser implements GLSurfaceView.EGLConfigChooser { /* Allocate then read the array of minimally matching EGL configs */ EGLConfig[] configs = new EGLConfig[numConfigs]; - egl.eglChooseConfig(display, GLUtils.use_gl3 ? s_configAttribs3 : s_configAttribs2, configs, numConfigs, num_config); + egl.eglChooseConfig(display, s_configAttribs2, configs, numConfigs, num_config); if (GLUtils.DEBUG) { GLUtils.printConfigs(egl, display, configs); diff --git a/platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularContextFactory.java b/platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularContextFactory.java index 4f1e9a696b..f2b4c95a2c 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularContextFactory.java +++ b/platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularContextFactory.java @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -52,24 +52,17 @@ public class RegularContextFactory implements GLSurfaceView.EGLContextFactory { public EGLContext createContext(EGL10 egl, EGLDisplay display, EGLConfig eglConfig) { String driver_name = GodotLib.getGlobal("rendering/quality/driver/driver_name"); - if (GLUtils.use_gl3 && !driver_name.equals("GLES3")) { - GLUtils.use_gl3 = false; - } - if (GLUtils.use_gl3) - Log.w(TAG, "creating OpenGL ES 3.0 context :"); - else - Log.w(TAG, "creating OpenGL ES 2.0 context :"); + // FIXME: Add support for Vulkan. + Log.w(TAG, "creating OpenGL ES 2.0 context :"); GLUtils.checkEglError(TAG, "Before eglCreateContext", egl); EGLContext context; if (GLUtils.use_debug_opengl) { int[] attrib_list2 = { EGL_CONTEXT_CLIENT_VERSION, 2, _EGL_CONTEXT_FLAGS_KHR, _EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR, EGL10.EGL_NONE }; - int[] attrib_list3 = { EGL_CONTEXT_CLIENT_VERSION, 3, _EGL_CONTEXT_FLAGS_KHR, _EGL_CONTEXT_OPENGL_DEBUG_BIT_KHR, EGL10.EGL_NONE }; - context = egl.eglCreateContext(display, eglConfig, EGL10.EGL_NO_CONTEXT, GLUtils.use_gl3 ? attrib_list3 : attrib_list2); + context = egl.eglCreateContext(display, eglConfig, EGL10.EGL_NO_CONTEXT, attrib_list2); } else { int[] attrib_list2 = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL10.EGL_NONE }; - int[] attrib_list3 = { EGL_CONTEXT_CLIENT_VERSION, 3, EGL10.EGL_NONE }; - context = egl.eglCreateContext(display, eglConfig, EGL10.EGL_NO_CONTEXT, GLUtils.use_gl3 ? attrib_list3 : attrib_list2); + context = egl.eglCreateContext(display, eglConfig, EGL10.EGL_NO_CONTEXT, attrib_list2); } GLUtils.checkEglError(TAG, "After eglCreateContext", egl); return context; diff --git a/platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularFallbackConfigChooser.java b/platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularFallbackConfigChooser.java index f5718ef2b3..71fcf06020 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularFallbackConfigChooser.java +++ b/platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularFallbackConfigChooser.java @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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 2bed1f0892..9e9b17fb99 100644 --- a/platform/android/java_class_wrapper.cpp +++ b/platform/android/java_class_wrapper.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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,11 +28,11 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "java_class_wrapper.h" +#include "api/java_class_wrapper.h" #include "string_android.h" #include "thread_jandroid.h" -bool JavaClass::_call_method(JavaObject *p_instance, const StringName &p_method, const Variant **p_args, int p_argcount, Variant::CallError &r_error, Variant &ret) { +bool JavaClass::_call_method(JavaObject *p_instance, const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error, Variant &ret) { Map<StringName, List<MethodInfo> >::Element *M = methods.find(p_method); if (!M) @@ -44,20 +44,20 @@ bool JavaClass::_call_method(JavaObject *p_instance, const StringName &p_method, for (List<MethodInfo>::Element *E = M->get().front(); E; E = E->next()) { if (!p_instance && !E->get()._static) { - r_error.error = Variant::CallError::CALL_ERROR_INSTANCE_IS_NULL; + r_error.error = Callable::CallError::CALL_ERROR_INSTANCE_IS_NULL; continue; } int pc = E->get().param_types.size(); if (pc > p_argcount) { - r_error.error = Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; + r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; r_error.argument = pc; continue; } if (pc < p_argcount) { - r_error.error = Variant::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS; + r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS; r_error.argument = pc; continue; } @@ -97,7 +97,7 @@ bool JavaClass::_call_method(JavaObject *p_instance, const StringName &p_method, case ARG_TYPE_DOUBLE: { if (!p_args[i]->is_num()) - arg_expected = Variant::REAL; + arg_expected = Variant::FLOAT; } break; case ARG_TYPE_STRING: { @@ -141,7 +141,7 @@ bool JavaClass::_call_method(JavaObject *p_instance, const StringName &p_method, } if (arg_expected != Variant::NIL) { - r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; r_error.argument = i; r_error.expected = arg_expected; valid = false; @@ -158,7 +158,7 @@ bool JavaClass::_call_method(JavaObject *p_instance, const StringName &p_method, if (!method) return true; //no version convinces - r_error.error = Variant::CallError::CALL_OK; + r_error.error = Callable::CallError::CALL_OK; jvalue *argv = NULL; @@ -405,7 +405,7 @@ bool JavaClass::_call_method(JavaObject *p_instance, const StringName &p_method, } } - r_error.error = Variant::CallError::CALL_OK; + r_error.error = Callable::CallError::CALL_OK; bool success = true; switch (method->return_type) { @@ -501,7 +501,7 @@ bool JavaClass::_call_method(JavaObject *p_instance, const StringName &p_method, if (!_convert_object_to_variant(env, obj, ret, method->return_type)) { ret = Variant(); - r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD; + r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; success = false; } env->DeleteLocalRef(obj); @@ -517,7 +517,7 @@ bool JavaClass::_call_method(JavaObject *p_instance, const StringName &p_method, return success; } -Variant JavaClass::call(const StringName &p_method, const Variant **p_args, int p_argcount, Variant::CallError &r_error) { +Variant JavaClass::call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) { Variant ret; bool found = _call_method(NULL, p_method, p_args, p_argcount, r_error, ret); @@ -533,7 +533,7 @@ JavaClass::JavaClass() { ///////////////////// -Variant JavaObject::call(const StringName &p_method, const Variant **p_args, int p_argcount, Variant::CallError &r_error) { +Variant JavaObject::call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) { return Variant(); } @@ -546,11 +546,6 @@ JavaObject::~JavaObject() { //////////////////// -void JavaClassWrapper::_bind_methods() { - - ClassDB::bind_method(D_METHOD("wrap", "name"), &JavaClassWrapper::wrap); -} - bool JavaClassWrapper::_get_type_sig(JNIEnv *env, jobject obj, uint32_t &sig, String &strsig) { jstring name2 = (jstring)env->CallObjectMethod(obj, Class_getName); diff --git a/platform/android/java_godot_io_wrapper.cpp b/platform/android/java_godot_io_wrapper.cpp index ade7c03d58..8d075f8e97 100644 --- a/platform/android/java_godot_io_wrapper.cpp +++ b/platform/android/java_godot_io_wrapper.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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 +53,7 @@ GodotIOJavaWrapper::GodotIOJavaWrapper(JNIEnv *p_env, jobject p_godot_io_instanc _get_model = p_env->GetMethodID(cls, "getModel", "()Ljava/lang/String;"); _get_screen_DPI = p_env->GetMethodID(cls, "getScreenDPI", "()I"); _get_unique_id = p_env->GetMethodID(cls, "getUniqueID", "()Ljava/lang/String;"); - _show_keyboard = p_env->GetMethodID(cls, "showKeyboard", "(Ljava/lang/String;)V"); + _show_keyboard = p_env->GetMethodID(cls, "showKeyboard", "(Ljava/lang/String;I)V"); _hide_keyboard = p_env->GetMethodID(cls, "hideKeyboard", "()V"); _set_screen_orientation = p_env->GetMethodID(cls, "setScreenOrientation", "(I)V"); _get_system_dir = p_env->GetMethodID(cls, "getSystemDir", "(I)Ljava/lang/String;"); @@ -135,11 +135,11 @@ bool GodotIOJavaWrapper::has_vk() { return (_show_keyboard != 0) && (_hide_keyboard != 0); } -void GodotIOJavaWrapper::show_vk(const String &p_existing) { +void GodotIOJavaWrapper::show_vk(const String &p_existing, int p_max_input_length) { if (_show_keyboard) { JNIEnv *env = ThreadAndroid::get_env(); jstring jStr = env->NewStringUTF(p_existing.utf8().get_data()); - env->CallVoidMethod(godot_io_instance, _show_keyboard, jStr); + env->CallVoidMethod(godot_io_instance, _show_keyboard, jStr, p_max_input_length); } } diff --git a/platform/android/java_godot_io_wrapper.h b/platform/android/java_godot_io_wrapper.h index 100e50fd66..7dfed52187 100644 --- a/platform/android/java_godot_io_wrapper.h +++ b/platform/android/java_godot_io_wrapper.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -73,7 +73,7 @@ public: int get_screen_dpi(); String get_unique_id(); bool has_vk(); - void show_vk(const String &p_existing); + void show_vk(const String &p_existing, int p_max_input_length); void hide_vk(); int get_vk_height(); void set_vk_height(int p_height); diff --git a/platform/android/java_godot_lib_jni.cpp b/platform/android/java_godot_lib_jni.cpp index a14e0a1960..900a452024 100644 --- a/platform/android/java_godot_lib_jni.cpp +++ b/platform/android/java_godot_lib_jni.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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 +33,7 @@ #include "java_godot_wrapper.h" #include "android/asset_manager_jni.h" +#include "api/java_class_wrapper.h" #include "audio_driver_jandroid.h" #include "core/engine.h" #include "core/os/keyboard.h" @@ -40,9 +41,9 @@ #include "dir_access_jandroid.h" #include "file_access_android.h" #include "file_access_jandroid.h" -#include "java_class_wrapper.h" #include "main/input_default.h" #include "main/main.h" +#include "net_socket_android.h" #include "os_android.h" #include "string_android.h" #include "thread_jandroid.h" @@ -98,7 +99,7 @@ jvalret _variant_to_jvalue(JNIEnv *env, Variant::Type p_type, const Variant *p_a v.val.i = *p_arg; }; } break; - case Variant::REAL: { + case Variant::FLOAT: { if (force_jobject) { @@ -122,9 +123,9 @@ jvalret _variant_to_jvalue(JNIEnv *env, Variant::Type p_type, const Variant *p_a v.val.l = jStr; v.obj = jStr; } break; - case Variant::POOL_STRING_ARRAY: { + case Variant::PACKED_STRING_ARRAY: { - PoolVector<String> sarray = *p_arg; + Vector<String> sarray = *p_arg; jobjectArray arr = env->NewObjectArray(sarray.size(), env->FindClass("java/lang/String"), env->NewStringUTF("")); for (int j = 0; j < sarray.size(); j++) { @@ -181,35 +182,39 @@ jvalret _variant_to_jvalue(JNIEnv *env, Variant::Type p_type, const Variant *p_a v.obj = jdict; } break; - case Variant::POOL_INT_ARRAY: { + case Variant::PACKED_INT32_ARRAY: { - PoolVector<int> array = *p_arg; + Vector<int> array = *p_arg; jintArray arr = env->NewIntArray(array.size()); - PoolVector<int>::Read r = array.read(); + const int *r = array.ptr(); env->SetIntArrayRegion(arr, 0, array.size(), r.ptr()); v.val.l = arr; v.obj = arr; } break; - case Variant::POOL_BYTE_ARRAY: { - PoolVector<uint8_t> array = *p_arg; + case Variant::PACKED_BYTE_ARRAY: { + Vector<uint8_t> array = *p_arg; jbyteArray arr = env->NewByteArray(array.size()); - PoolVector<uint8_t>::Read r = array.read(); + const uint8_t *r = array.ptr(); env->SetByteArrayRegion(arr, 0, array.size(), reinterpret_cast<const signed char *>(r.ptr())); v.val.l = arr; v.obj = arr; } break; - case Variant::POOL_REAL_ARRAY: { + case Variant::PACKED_FLOAT32_ARRAY: { - PoolVector<float> array = *p_arg; + Vector<float> array = *p_arg; jfloatArray arr = env->NewFloatArray(array.size()); - PoolVector<float>::Read r = array.read(); + const float *r = array.ptr(); env->SetFloatArrayRegion(arr, 0, array.size(), r.ptr()); v.val.l = arr; v.obj = arr; } break; +#ifndef _MSC_VER +#warning This is missing 64 bits arrays, I have no idea how to do it in JNI +#endif + default: { v.val.i = 0; @@ -254,7 +259,7 @@ Variant _jobject_to_variant(JNIEnv *env, jobject obj) { jobjectArray arr = (jobjectArray)obj; int stringCount = env->GetArrayLength(arr); - PoolVector<String> sarr; + Vector<String> sarr; for (int i = 0; i < stringCount; i++) { jstring string = (jstring)env->GetObjectArrayElement(arr, i); @@ -284,10 +289,10 @@ Variant _jobject_to_variant(JNIEnv *env, jobject obj) { jintArray arr = (jintArray)obj; int fCount = env->GetArrayLength(arr); - PoolVector<int> sarr; + Vector<int> sarr; sarr.resize(fCount); - PoolVector<int>::Write w = sarr.write(); + int *w = sarr.ptrw(); env->GetIntArrayRegion(arr, 0, fCount, w.ptr()); w.release(); return sarr; @@ -297,10 +302,10 @@ Variant _jobject_to_variant(JNIEnv *env, jobject obj) { jbyteArray arr = (jbyteArray)obj; int fCount = env->GetArrayLength(arr); - PoolVector<uint8_t> sarr; + Vector<uint8_t> sarr; sarr.resize(fCount); - PoolVector<uint8_t>::Write w = sarr.write(); + uint8_t *w = sarr.ptrw(); env->GetByteArrayRegion(arr, 0, fCount, reinterpret_cast<signed char *>(w.ptr())); w.release(); return sarr; @@ -318,10 +323,10 @@ Variant _jobject_to_variant(JNIEnv *env, jobject obj) { jdoubleArray arr = (jdoubleArray)obj; int fCount = env->GetArrayLength(arr); - PoolRealArray sarr; + PackedFloat32Array sarr; sarr.resize(fCount); - PoolRealArray::Write w = sarr.write(); + real_t *w = sarr.ptrw(); for (int i = 0; i < fCount; i++) { @@ -336,10 +341,10 @@ Variant _jobject_to_variant(JNIEnv *env, jobject obj) { jfloatArray arr = (jfloatArray)obj; int fCount = env->GetArrayLength(arr); - PoolRealArray sarr; + PackedFloat32Array sarr; sarr.resize(fCount); - PoolRealArray::Write w = sarr.write(); + real_t *w = sarr.ptrw(); for (int i = 0; i < fCount; i++) { @@ -373,7 +378,7 @@ Variant _jobject_to_variant(JNIEnv *env, jobject obj) { jmethodID get_keys = env->GetMethodID(oclass, "get_keys", "()[Ljava/lang/String;"); jobjectArray arr = (jobjectArray)env->CallObjectMethod(obj, get_keys); - PoolStringArray keys = _jobject_to_variant(env, arr); + PackedStringArray keys = _jobject_to_variant(env, arr); env->DeleteLocalRef(arr); jmethodID get_values = env->GetMethodID(oclass, "get_values", "()[Ljava/lang/Object;"); @@ -410,30 +415,30 @@ class JNISingleton : public Object { Map<StringName, MethodData> method_map; public: - virtual Variant call(const StringName &p_method, const Variant **p_args, int p_argcount, Variant::CallError &r_error) { + virtual Variant call(const StringName &p_method, const Variant **p_args, int p_argcount, Callable::CallError &r_error) { ERR_FAIL_COND_V(!instance, Variant()); - r_error.error = Variant::CallError::CALL_OK; + r_error.error = Callable::CallError::CALL_OK; Map<StringName, MethodData>::Element *E = method_map.find(p_method); if (!E) { - r_error.error = Variant::CallError::CALL_ERROR_INVALID_METHOD; + r_error.error = Callable::CallError::CALL_ERROR_INVALID_METHOD; return Variant(); } int ac = E->get().argtypes.size(); if (ac < p_argcount) { - r_error.error = Variant::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; + r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS; r_error.argument = ac; return Variant(); } if (ac > p_argcount) { - r_error.error = Variant::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS; + r_error.error = Callable::CallError::CALL_ERROR_TOO_MANY_ARGUMENTS; r_error.argument = ac; return Variant(); } @@ -442,7 +447,7 @@ public: if (!Variant::can_convert(p_args[i]->get_type(), E->get().argtypes[i])) { - r_error.error = Variant::CallError::CALL_ERROR_INVALID_ARGUMENT; + r_error.error = Callable::CallError::CALL_ERROR_INVALID_ARGUMENT; r_error.argument = i; r_error.expected = E->get().argtypes[i]; } @@ -486,7 +491,7 @@ public: ret = env->CallIntMethodA(instance, E->get().method, v); } break; - case Variant::REAL: { + case Variant::FLOAT: { ret = env->CallFloatMethodA(instance, E->get().method, v); } break; @@ -496,7 +501,7 @@ public: ret = jstring_to_string((jstring)o, env); env->DeleteLocalRef(o); } break; - case Variant::POOL_STRING_ARRAY: { + case Variant::PACKED_STRING_ARRAY: { jobjectArray arr = (jobjectArray)env->CallObjectMethodA(instance, E->get().method, v); @@ -504,35 +509,38 @@ public: env->DeleteLocalRef(arr); } break; - case Variant::POOL_INT_ARRAY: { + case Variant::PACKED_INT32_ARRAY: { jintArray arr = (jintArray)env->CallObjectMethodA(instance, E->get().method, v); int fCount = env->GetArrayLength(arr); - PoolVector<int> sarr; + Vector<int> sarr; sarr.resize(fCount); - PoolVector<int>::Write w = sarr.write(); + int *w = sarr.ptrw(); env->GetIntArrayRegion(arr, 0, fCount, w.ptr()); w.release(); ret = sarr; env->DeleteLocalRef(arr); } break; - case Variant::POOL_REAL_ARRAY: { + case Variant::PACKED_FLOAT32_ARRAY: { jfloatArray arr = (jfloatArray)env->CallObjectMethodA(instance, E->get().method, v); int fCount = env->GetArrayLength(arr); - PoolVector<float> sarr; + Vector<float> sarr; sarr.resize(fCount); - PoolVector<float>::Write w = sarr.write(); + float *w = sarr.ptrw(); env->GetFloatArrayRegion(arr, 0, fCount, w.ptr()); w.release(); ret = sarr; env->DeleteLocalRef(arr); } break; +#ifndef _MSC_VER +#warning This is missing 64 bits arrays, I have no idea how to do it in JNI +#endif case Variant::DICTIONARY: { jobject obj = env->CallObjectMethodA(instance, E->get().method, v); @@ -635,6 +643,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_initialize(JNIEnv *en DirAccessJAndroid::setup(godot_io_java->get_instance()); AudioDriverAndroid::setup(godot_io_java->get_instance()); + NetSocketAndroid::setup(godot_java->get_member_object("netUtils", "Lorg/godotengine/godot/utils/GodotNetUtils;", env)); os_android = new OS_Android(godot_java, godot_io_java, p_use_apk_expansion); @@ -737,7 +746,6 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_setup(JNIEnv *env, jo } java_class_wrapper = memnew(JavaClassWrapper(godot_java->get_activity())); - Engine::get_singleton()->add_singleton(Engine::Singleton("JavaClassWrapper", java_class_wrapper)); _initialize_java_modules(); } @@ -833,6 +841,20 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_hover(JNIEnv *env, jo os_android->process_hover(p_type, Point2(p_x, p_y)); } +JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_doubletap(JNIEnv *env, jobject obj, jint p_x, jint p_y) { + if (step == 0) + return; + + os_android->process_double_tap(Point2(p_x, p_y)); +} + +JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_scroll(JNIEnv *env, jobject obj, jint p_x, jint p_y) { + if (step == 0) + return; + + os_android->process_scroll(Point2(p_x, p_y)); +} + /* * Android Key codes. */ @@ -1231,13 +1253,13 @@ static Variant::Type get_jni_type(const String &p_type) { { "void", Variant::NIL }, { "boolean", Variant::BOOL }, { "int", Variant::INT }, - { "float", Variant::REAL }, - { "double", Variant::REAL }, + { "float", Variant::FLOAT }, + { "double", Variant::FLOAT }, { "java.lang.String", Variant::STRING }, - { "[I", Variant::POOL_INT_ARRAY }, - { "[B", Variant::POOL_BYTE_ARRAY }, - { "[F", Variant::POOL_REAL_ARRAY }, - { "[Ljava.lang.String;", Variant::POOL_STRING_ARRAY }, + { "[I", Variant::PACKED_INT32_ARRAY }, + { "[B", Variant::PACKED_BYTE_ARRAY }, + { "[F", Variant::PACKED_FLOAT32_ARRAY }, + { "[Ljava.lang.String;", Variant::PACKED_STRING_ARRAY }, { "org.godotengine.godot.Dictionary", Variant::DICTIONARY }, { NULL, Variant::NIL } }; @@ -1355,7 +1377,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_callobject(JNIEnv *en env->DeleteLocalRef(obj); }; - Variant::CallError err; + Callable::CallError err; obj->call(str_method, (const Variant **)vptr, count, err); // something diff --git a/platform/android/java_godot_lib_jni.h b/platform/android/java_godot_lib_jni.h index a564bbd4a1..71d4547f65 100644 --- a/platform/android/java_godot_lib_jni.h +++ b/platform/android/java_godot_lib_jni.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -46,6 +46,8 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_step(JNIEnv *env, job JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_back(JNIEnv *env, jobject obj); JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_touch(JNIEnv *env, jobject obj, jint ev, jint pointer, jint count, jintArray positions); JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_hover(JNIEnv *env, jobject obj, jint p_type, jint p_x, jint p_y); +JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_doubletap(JNIEnv *env, jobject obj, jint p_x, jint p_y); +JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_scroll(JNIEnv *env, jobject obj, jint p_x, jint p_y); JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_key(JNIEnv *env, jobject obj, jint p_scancode, jint p_unicode_char, jboolean p_pressed); JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joybutton(JNIEnv *env, jobject obj, jint p_device, jint p_button, jboolean p_pressed); JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_joyaxis(JNIEnv *env, jobject obj, jint p_device, jint p_axis, jfloat p_value); diff --git a/platform/android/java_godot_wrapper.cpp b/platform/android/java_godot_wrapper.cpp index e3e613d30b..9ac91b8ef6 100644 --- a/platform/android/java_godot_wrapper.cpp +++ b/platform/android/java_godot_wrapper.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -99,13 +99,6 @@ jobject GodotJavaWrapper::get_class_loader() { } } -void GodotJavaWrapper::gfx_init(bool gl2) { - // beats me what this once did, there was no code, - // but we're getting false if our GLES3 driver is initialised - // and true for our GLES2 driver - // Maybe we're supposed to communicate this back or store it? -} - void GodotJavaWrapper::on_video_init(JNIEnv *p_env) { if (_on_video_init) if (p_env == NULL) diff --git a/platform/android/java_godot_wrapper.h b/platform/android/java_godot_wrapper.h index d23ff273cb..f378b1ea38 100644 --- a/platform/android/java_godot_wrapper.h +++ b/platform/android/java_godot_wrapper.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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,7 +71,6 @@ public: jobject get_class_loader(); - void gfx_init(bool gl2); void on_video_init(JNIEnv *p_env = NULL); void restart(JNIEnv *p_env = NULL); void force_quit(JNIEnv *p_env = NULL); diff --git a/platform/android/net_socket_android.cpp b/platform/android/net_socket_android.cpp new file mode 100644 index 0000000000..320bdd3817 --- /dev/null +++ b/platform/android/net_socket_android.cpp @@ -0,0 +1,136 @@ +/*************************************************************************/ +/* net_socket_android.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "net_socket_android.h" + +#include "thread_jandroid.h" + +jobject NetSocketAndroid::net_utils = 0; +jclass NetSocketAndroid::cls = 0; +jmethodID NetSocketAndroid::_multicast_lock_acquire = 0; +jmethodID NetSocketAndroid::_multicast_lock_release = 0; + +void NetSocketAndroid::setup(jobject p_net_utils) { + + JNIEnv *env = ThreadAndroid::get_env(); + + net_utils = env->NewGlobalRef(p_net_utils); + + jclass c = env->GetObjectClass(net_utils); + cls = (jclass)env->NewGlobalRef(c); + + _multicast_lock_acquire = env->GetMethodID(cls, "multicastLockAcquire", "()V"); + _multicast_lock_release = env->GetMethodID(cls, "multicastLockRelease", "()V"); +} + +void NetSocketAndroid::multicast_lock_acquire() { + if (_multicast_lock_acquire) { + JNIEnv *env = ThreadAndroid::get_env(); + env->CallVoidMethod(net_utils, _multicast_lock_acquire); + } +} + +void NetSocketAndroid::multicast_lock_release() { + if (_multicast_lock_release) { + JNIEnv *env = ThreadAndroid::get_env(); + env->CallVoidMethod(net_utils, _multicast_lock_release); + } +} + +NetSocket *NetSocketAndroid::_create_func() { + return memnew(NetSocketAndroid); +} + +void NetSocketAndroid::make_default() { + _create = _create_func; +} + +NetSocketAndroid::NetSocketAndroid() : + wants_broadcast(false), + multicast_groups(0) { +} + +NetSocketAndroid::~NetSocketAndroid() { + close(); +} + +void NetSocketAndroid::close() { + NetSocketPosix::close(); + if (wants_broadcast) + multicast_lock_release(); + if (multicast_groups) + multicast_lock_release(); + wants_broadcast = false; + multicast_groups = 0; +} + +Error NetSocketAndroid::set_broadcasting_enabled(bool p_enabled) { + Error err = NetSocketPosix::set_broadcasting_enabled(p_enabled); + if (err != OK) + return err; + + if (p_enabled != wants_broadcast) { + if (p_enabled) { + multicast_lock_acquire(); + } else { + multicast_lock_release(); + } + + wants_broadcast = p_enabled; + } + + return OK; +} + +Error NetSocketAndroid::join_multicast_group(const IP_Address &p_multi_address, String p_if_name) { + Error err = NetSocketPosix::join_multicast_group(p_multi_address, p_if_name); + if (err != OK) + return err; + + if (!multicast_groups) + multicast_lock_acquire(); + multicast_groups++; + + return OK; +} + +Error NetSocketAndroid::leave_multicast_group(const IP_Address &p_multi_address, String p_if_name) { + Error err = NetSocketPosix::leave_multicast_group(p_multi_address, p_if_name); + if (err != OK) + return err; + + ERR_FAIL_COND_V(multicast_groups == 0, ERR_BUG); + + multicast_groups--; + if (!multicast_groups) + multicast_lock_release(); + + return OK; +} diff --git a/platform/android/net_socket_android.h b/platform/android/net_socket_android.h new file mode 100644 index 0000000000..4fc80d2de1 --- /dev/null +++ b/platform/android/net_socket_android.h @@ -0,0 +1,78 @@ +/*************************************************************************/ +/* net_socket_android.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef NET_SOCKET_ANDROID_H +#define NET_SOCKET_ANDROID_H + +#include "drivers/unix/net_socket_posix.h" + +#include <jni.h> + +/** + * Specialized NetSocket implementation for Android. + * + * Some devices requires Android-specific code to acquire a MulticastLock + * before sockets are allowed to receive broadcast and multicast packets. + * This implementation calls into Java code and automatically acquire/release + * the lock when broadcasting is enabled/disabled on a socket, or that socket + * joins/leaves a multicast group. + */ +class NetSocketAndroid : public NetSocketPosix { + +private: + static jobject net_utils; + static jclass cls; + static jmethodID _multicast_lock_acquire; + static jmethodID _multicast_lock_release; + + bool wants_broadcast; + int multicast_groups; + + static void multicast_lock_acquire(); + static void multicast_lock_release(); + +protected: + static NetSocket *_create_func(); + +public: + static void make_default(); + static void setup(jobject p_net_utils); + + virtual void close(); + + virtual Error set_broadcasting_enabled(bool p_enabled); + virtual Error join_multicast_group(const IP_Address &p_multi_address, String p_if_name); + virtual Error leave_multicast_group(const IP_Address &p_multi_address, String p_if_name); + + NetSocketAndroid(); + ~NetSocketAndroid(); +}; + +#endif diff --git a/platform/android/os_android.cpp b/platform/android/os_android.cpp index defee8f1f1..15e3ac48c7 100644 --- a/platform/android/os_android.cpp +++ b/platform/android/os_android.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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,7 +33,6 @@ #include "core/io/file_access_buffered_fa.h" #include "core/project_settings.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" @@ -43,6 +42,7 @@ #include "dir_access_jandroid.h" #include "file_access_jandroid.h" +#include "net_socket_android.h" #include <dlfcn.h> @@ -66,8 +66,6 @@ int OS_Android::get_video_driver_count() const { const char *OS_Android::get_video_driver_name(int p_driver) const { switch (p_driver) { - case VIDEO_DRIVER_GLES3: - return "GLES3"; case VIDEO_DRIVER_GLES2: return "GLES2"; } @@ -106,6 +104,8 @@ void OS_Android::initialize_core() { DirAccess::make_default<DirAccessJAndroid>(DirAccess::ACCESS_RESOURCES); DirAccess::make_default<DirAccessUnix>(DirAccess::ACCESS_USERDATA); DirAccess::make_default<DirAccessUnix>(DirAccess::ACCESS_FILESYSTEM); + + NetSocketAndroid::make_default(); } void OS_Android::set_opengl_extensions(const char *p_gl_extensions) { @@ -120,44 +120,21 @@ int OS_Android::get_current_video_driver() const { Error OS_Android::initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver) { - bool use_gl3 = godot_java->get_gles_version_code() >= 0x00030000; - use_gl3 = use_gl3 && (GLOBAL_GET("rendering/quality/driver/driver_name") == "GLES3"); bool gl_initialization_error = false; - while (true) { - if (use_gl3) { - if (RasterizerGLES3::is_viable() == OK) { - godot_java->gfx_init(false); - RasterizerGLES3::register_config(); - RasterizerGLES3::make_current(); - break; - } else { - if (GLOBAL_GET("rendering/quality/driver/fallback_to_gles2")) { - p_video_driver = VIDEO_DRIVER_GLES2; - use_gl3 = false; - continue; - } else { - gl_initialization_error = true; - break; - } - } - } else { - if (RasterizerGLES2::is_viable() == OK) { - godot_java->gfx_init(true); - RasterizerGLES2::register_config(); - RasterizerGLES2::make_current(); - break; - } else { - gl_initialization_error = true; - break; - } - } + // FIXME: Add Vulkan support. Readd fallback code from Vulkan to GLES2? + + if (RasterizerGLES2::is_viable() == OK) { + RasterizerGLES2::register_config(); + RasterizerGLES2::make_current(); + } else { + gl_initialization_error = true; } if (gl_initialization_error) { OS::get_singleton()->alert("Your device does not support any of the supported OpenGL versions.\n" "Please try updating your Android version.", - "Unable to initialize Video driver"); + "Unable to initialize video driver"); return ERR_UNAVAILABLE; } @@ -175,11 +152,6 @@ Error OS_Android::initialize(const VideoMode &p_desired, int p_video_driver, int input = memnew(InputDefault); input->set_fallback_mapping(godot_java->get_input_fallback_mapping()); - ///@TODO implement a subclass for Android and instantiate that instead - camera_server = memnew(CameraServer); - - //power_manager = memnew(PowerAndroid); - return OK; } @@ -196,8 +168,6 @@ void OS_Android::delete_main_loop() { void OS_Android::finalize() { - memdelete(camera_server); - memdelete(input); } @@ -504,6 +474,25 @@ void OS_Android::process_hover(int p_type, Point2 p_pos) { } } +void OS_Android::process_double_tap(Point2 p_pos) { + Ref<InputEventMouseButton> ev; + ev.instance(); + ev->set_position(p_pos); + ev->set_global_position(p_pos); + ev->set_pressed(false); + ev->set_doubleclick(true); + input->parse_input_event(ev); +} + +void OS_Android::process_scroll(Point2 p_pos) { + Ref<InputEventPanGesture> ev; + ev.instance(); + ev->set_position(p_pos); + ev->set_delta(p_pos - scroll_prev_pos); + input->parse_input_event(ev); + scroll_prev_pos = p_pos; +} + void OS_Android::process_accelerometer(const Vector3 &p_accelerometer) { input->set_accelerometer(p_accelerometer); @@ -541,10 +530,10 @@ int OS_Android::get_virtual_keyboard_height() const { // return 0; } -void OS_Android::show_virtual_keyboard(const String &p_existing_text, const Rect2 &p_screen_rect) { +void OS_Android::show_virtual_keyboard(const String &p_existing_text, const Rect2 &p_screen_rect, int p_max_input_length) { if (godot_io_java->has_vk()) { - godot_io_java->show_vk(p_existing_text); + godot_io_java->show_vk(p_existing_text, p_max_input_length); } else { ERR_PRINT("Virtual keyboard not available"); @@ -733,7 +722,6 @@ void OS_Android::vibrate_handheld(int p_duration_ms) { bool OS_Android::_check_internal_feature_support(const String &p_feature) { if (p_feature == "mobile") { - //TODO support etc2 only if GLES3 driver is selected return true; } #if defined(__aarch64__) diff --git a/platform/android/os_android.h b/platform/android/os_android.h index a290c0cedd..ec6ffe5438 100644 --- a/platform/android/os_android.h +++ b/platform/android/os_android.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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,9 +37,7 @@ #include "core/os/main_loop.h" #include "drivers/unix/os_unix.h" #include "main/input_default.h" -//#include "power_android.h" #include "servers/audio_server.h" -#include "servers/camera_server.h" #include "servers/visual/rasterizer.h" class GodotJavaWrapper; @@ -71,6 +69,7 @@ public: private: Vector<TouchPos> touch; Point2 hover_prev_pos; // needed to calculate the relative position on hover events + Point2 scroll_prev_pos; // needed to calculate the relative position on scroll events bool use_gl2; bool use_apk_expansion; @@ -79,8 +78,6 @@ private: VisualServer *visual_server; - CameraServer *camera_server; - mutable String data_dir_cache; //AudioDriverAndroid audio_driver_android; @@ -95,8 +92,6 @@ private: GodotJavaWrapper *godot_java; GodotIOJavaWrapper *godot_io_java; - //PowerAndroid *power_manager_func; - int video_driver_index; public: @@ -160,7 +155,7 @@ public: virtual bool has_touchscreen_ui_hint() const; virtual bool has_virtual_keyboard() const; - virtual void show_virtual_keyboard(const String &p_existing_text, const Rect2 &p_screen_rect = Rect2()); + virtual void show_virtual_keyboard(const String &p_existing_text, const Rect2 &p_screen_rect = Rect2(), int p_max_input_length = -1); virtual void hide_virtual_keyboard(); virtual int get_virtual_keyboard_height() const; @@ -190,6 +185,8 @@ public: void process_gyroscope(const Vector3 &p_gyroscope); void process_touch(int p_what, int p_pointer, const Vector<TouchPos> &p_points); void process_hover(int p_type, Point2 p_pos); + void process_double_tap(Point2 p_pos); + void process_scroll(Point2 p_pos); void process_joy_event(JoypadEvent p_event); void process_event(Ref<InputEvent> p_event); void init_video_mode(int p_video_width, int p_video_height); diff --git a/platform/android/platform_config.h b/platform/android/platform_config.h index ac58be8444..c5e896c4e1 100644 --- a/platform/android/platform_config.h +++ b/platform/android/platform_config.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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 deleted file mode 100644 index 4d2fbfbf1a..0000000000 --- a/platform/android/power_android.cpp +++ /dev/null @@ -1,255 +0,0 @@ -/*************************************************************************/ -/* power_android.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -/* -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; - (*env)->PopLocalFrame(env, NULL); - --s_active; - } -} - -static struct LocalReferenceHolder LocalReferenceHolder_Setup(const char *func) { - struct LocalReferenceHolder refholder; - refholder.m_env = NULL; - refholder.m_func = func; - return refholder; -} - -static bool LocalReferenceHolder_Init(struct LocalReferenceHolder *refholder, JNIEnv *env) { - const int capacity = 16; - if ((*env)->PushLocalFrame(env, capacity) < 0) { - return false; - } - ++s_active; - refholder->m_env = env; - return true; -} - -static SDL_bool LocalReferenceHolder_IsActive(void) { - return s_active > 0; -} - -ANativeWindow *Android_JNI_GetNativeWindow(void) { - ANativeWindow *anw; - jobject s; - JNIEnv *env = Android_JNI_GetEnv(); - - s = (*env)->CallStaticObjectMethod(env, mActivityClass, midGetNativeSurface); - anw = ANativeWindow_fromSurface(env, s); - (*env)->DeleteLocalRef(env, s); - - return anw; -} - -/* - * CODE CHUNK IMPORTED FROM SDL 2.0 - * returns 0 on success or -1 on error (others undefined then) - * returns truthy or falsy value in plugged, charged and battery - * returns the value in seconds and percent or -1 if not available - */ -int Android_JNI_GetPowerInfo(int *plugged, int *charged, int *battery, int *seconds, int *percent) { - env = Android_JNI_GetEnv(); - refs = LocalReferenceHolder_Setup(__FUNCTION__); - - if (!LocalReferenceHolder_Init(&refs, env)) { - LocalReferenceHolder_Cleanup(&refs); - return -1; - } - mid = (*env)->GetStaticMethodID(env, mActivityClass, "getContext", "()Landroid/content/Context;"); - context = (*env)->CallStaticObjectMethod(env, mActivityClass, mid); - action = (*env)->NewStringUTF(env, "android.intent.action.BATTERY_CHANGED"); - cls = (*env)->FindClass(env, "android/content/IntentFilter"); - mid = (*env)->GetMethodID(env, cls, "<init>", "(Ljava/lang/String;)V"); - filter = (*env)->NewObject(env, cls, mid, action); - (*env)->DeleteLocalRef(env, action); - mid = (*env)->GetMethodID(env, mActivityClass, "registerReceiver", "(Landroid/content/BroadcastReceiver;Landroid/content/IntentFilter;)Landroid/content/Intent;"); - intent = (*env)->CallObjectMethod(env, context, mid, NULL, filter); - (*env)->DeleteLocalRef(env, filter); - cls = (*env)->GetObjectClass(env, intent); - imid = (*env)->GetMethodID(env, cls, "getIntExtra", "(Ljava/lang/String;I)I"); -// Watch out for C89 scoping rules because of the macro -#define GET_INT_EXTRA(var, key) \ - int var; \ - iname = (*env)->NewStringUTF(env, key); \ - var = (*env)->CallIntMethod(env, intent, imid, iname, -1); \ - (*env)->DeleteLocalRef(env, iname); - bmid = (*env)->GetMethodID(env, cls, "getBooleanExtra", "(Ljava/lang/String;Z)Z"); -// Watch out for C89 scoping rules because of the macro -#define GET_BOOL_EXTRA(var, key) \ - int var; \ - bname = (*env)->NewStringUTF(env, key); \ - var = (*env)->CallBooleanMethod(env, intent, bmid, bname, JNI_FALSE); \ - (*env)->DeleteLocalRef(env, bname); - if (plugged) { - // Watch out for C89 scoping rules because of the macro - GET_INT_EXTRA(plug, "plugged") // == BatteryManager.EXTRA_PLUGGED (API 5) - if (plug == -1) { - LocalReferenceHolder_Cleanup(&refs); - return -1; - } - // 1 == BatteryManager.BATTERY_PLUGGED_AC - // 2 == BatteryManager.BATTERY_PLUGGED_USB - *plugged = (0 < plug) ? 1 : 0; - } - if (charged) { - // Watch out for C89 scoping rules because of the macro - GET_INT_EXTRA(status, "status") // == BatteryManager.EXTRA_STATUS (API 5) - if (status == -1) { - LocalReferenceHolder_Cleanup(&refs); - return -1; - } - // 5 == BatteryManager.BATTERY_STATUS_FULL - *charged = (status == 5) ? 1 : 0; - } - if (battery) { - GET_BOOL_EXTRA(present, "present") // == BatteryManager.EXTRA_PRESENT (API 5) - *battery = present ? 1 : 0; - } - if (seconds) { - *seconds = -1; // not possible - } - if (percent) { - int level; - int scale; - // Watch out for C89 scoping rules because of the macro - { - GET_INT_EXTRA(level_temp, "level") // == BatteryManager.EXTRA_LEVEL (API 5) - level = level_temp; - } - // Watch out for C89 scoping rules because of the macro - { - GET_INT_EXTRA(scale_temp, "scale") // == BatteryManager.EXTRA_SCALE (API 5) - scale = scale_temp; - } - if ((level == -1) || (scale == -1)) { - LocalReferenceHolder_Cleanup(&refs); - return -1; - } - *percent = level * 100 / scale; - } - (*env)->DeleteLocalRef(env, intent); - LocalReferenceHolder_Cleanup(&refs); - - return 0; -} - -bool PowerAndroid::GetPowerInfo_Android() { - int battery; - int plugged; - int charged; - - if (Android_JNI_GetPowerInfo(&plugged, &charged, &battery, &this->nsecs_left, &this->percent_left) != -1) { - if (plugged) { - if (charged) { - this->power_state = OS::POWERSTATE_CHARGED; - } else if (battery) { - this->power_state = OS::POWERSTATE_CHARGING; - } else { - this->power_state = OS::POWERSTATE_NO_BATTERY; - this->nsecs_left = -1; - this->percent_left = -1; - } - } else { - this->power_state = OS::POWERSTATE_ON_BATTERY; - } - } else { - this->power_state = OS::POWERSTATE_UNKNOWN; - this->nsecs_left = -1; - this->percent_left = -1; - } - - return true; -} - -OS::PowerState PowerAndroid::get_power_state() { - if (GetPowerInfo_Android()) { - return power_state; - } else { - WARN_PRINT("Power management is not implemented on this platform, defaulting to POWERSTATE_UNKNOWN"); - return OS::POWERSTATE_UNKNOWN; - } -} - -int PowerAndroid::get_power_seconds_left() { - if (GetPowerInfo_Android()) { - return nsecs_left; - } else { - WARN_PRINT("Power management is not implemented on this platform, defaulting to -1"); - return -1; - } -} - -int PowerAndroid::get_power_percent_left() { - if (GetPowerInfo_Android()) { - return percent_left; - } else { - WARN_PRINT("Power management is not implemented on this platform, defaulting to -1"); - return -1; - } -} - -PowerAndroid::PowerAndroid() : - nsecs_left(-1), - percent_left(-1), - power_state(OS::POWERSTATE_UNKNOWN) { -} - -PowerAndroid::~PowerAndroid() { -} diff --git a/platform/android/string_android.h b/platform/android/string_android.h index fe627a3e0c..51c488c8cc 100644 --- a/platform/android/string_android.h +++ b/platform/android/string_android.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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.cpp b/platform/android/thread_jandroid.cpp index 9df9e57b24..98b61ad755 100644 --- a/platform/android/thread_jandroid.cpp +++ b/platform/android/thread_jandroid.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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 0b6e1f4b4a..eb4725ae68 100644 --- a/platform/android/thread_jandroid.h +++ b/platform/android/thread_jandroid.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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.cpp b/platform/haiku/audio_driver_media_kit.cpp index 3c4e31da36..b7f6b57244 100644 --- a/platform/haiku/audio_driver_media_kit.cpp +++ b/platform/haiku/audio_driver_media_kit.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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 634438fd2a..06a362a89e 100644 --- a/platform/haiku/audio_driver_media_kit.h +++ b/platform/haiku/audio_driver_media_kit.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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 d73d893603..3c4d43ff71 100644 --- a/platform/haiku/context_gl_haiku.cpp +++ b/platform/haiku/context_gl_haiku.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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 8452f5fbfb..c5d258915d 100644 --- a/platform/haiku/context_gl_haiku.h +++ b/platform/haiku/context_gl_haiku.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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 2a3e165069..dd72294816 100644 --- a/platform/haiku/detect.py +++ b/platform/haiku/detect.py @@ -95,7 +95,7 @@ def configure(env): if not env['builtin_enet']: env.ParseConfig('pkg-config libenet --cflags --libs') - if not env['builtin_squish'] and env['tools']: + if not env['builtin_squish']: env.ParseConfig('pkg-config libsquish --cflags --libs') if not env['builtin_zstd']: diff --git a/platform/haiku/godot_haiku.cpp b/platform/haiku/godot_haiku.cpp index d772632d1c..0657f4c052 100644 --- a/platform/haiku/godot_haiku.cpp +++ b/platform/haiku/godot_haiku.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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 f548904547..82d9c093e1 100644 --- a/platform/haiku/haiku_application.cpp +++ b/platform/haiku/haiku_application.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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 d808c03863..2e04d921bf 100644 --- a/platform/haiku/haiku_application.h +++ b/platform/haiku/haiku_application.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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 c0dc1d2eee..3c2b7f8d10 100644 --- a/platform/haiku/haiku_direct_window.cpp +++ b/platform/haiku/haiku_direct_window.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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.h b/platform/haiku/haiku_direct_window.h index 77aa71c9e0..ccc9542f0e 100644 --- a/platform/haiku/haiku_direct_window.h +++ b/platform/haiku/haiku_direct_window.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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.cpp b/platform/haiku/haiku_gl_view.cpp index 56db7b1ffb..970a1276fd 100644 --- a/platform/haiku/haiku_gl_view.cpp +++ b/platform/haiku/haiku_gl_view.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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 cc31268c72..59e02d2367 100644 --- a/platform/haiku/haiku_gl_view.h +++ b/platform/haiku/haiku_gl_view.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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 486e9a3d17..692a1e5a78 100644 --- a/platform/haiku/key_mapping_haiku.cpp +++ b/platform/haiku/key_mapping_haiku.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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 a6a50659e0..a0e85e3390 100644 --- a/platform/haiku/key_mapping_haiku.h +++ b/platform/haiku/key_mapping_haiku.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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 9c07535c85..a082ba53f9 100644 --- a/platform/haiku/os_haiku.cpp +++ b/platform/haiku/os_haiku.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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,10 +28,9 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "drivers/gles3/rasterizer_gles3.h" - #include "os_haiku.h" +#include "drivers/gles2/rasterizer_gles2.h" #include "main/main.h" #include "servers/physics/physics_server_sw.h" #include "servers/visual/visual_server_raster.h" @@ -78,7 +77,7 @@ int OS_Haiku::get_video_driver_count() const { } const char *OS_Haiku::get_video_driver_name(int p_driver) const { - return "GLES3"; + return "GLES2"; } int OS_Haiku::get_current_video_driver() const { @@ -112,9 +111,9 @@ Error OS_Haiku::initialize(const VideoMode &p_desired, int p_video_driver, int p context_gl->initialize(); context_gl->make_current(); context_gl->set_use_vsync(current_video_mode.use_vsync); - RasterizerGLES3::register_config(); - RasterizerGLES3::make_current(); - + // FIXME: That's not how the rasterizer setup should happen. + RasterizerGLES2::register_config(); + RasterizerGLES2::make_current(); #endif visual_server = memnew(VisualServerRaster); @@ -133,8 +132,6 @@ Error OS_Haiku::initialize(const VideoMode &p_desired, int p_video_driver, int p window->Show(); visual_server->init(); - camera_server = memnew(CameraServer); - AudioDriverManager::initialize(p_audio_driver); return OK; @@ -150,8 +147,6 @@ void OS_Haiku::finalize() { visual_server->finish(); memdelete(visual_server); - memdelete(camera_server); - memdelete(input); #if defined(OPENGL_ENABLED) @@ -365,18 +360,3 @@ String OS_Haiku::get_cache_path() const { return get_config_path(); } } - -OS::PowerState OS_Haiku::get_power_state() { - WARN_PRINT("Power management is not implemented on this platform, defaulting to POWERSTATE_UNKNOWN"); - return OS::POWERSTATE_UNKNOWN; -} - -int OS_Haiku::get_power_seconds_left() { - WARN_PRINT("Power management is not implemented on this platform, defaulting to -1"); - return -1; -} - -int OS_Haiku::get_power_percent_left() { - WARN_PRINT("Power management is not implemented on this platform, defaulting to -1"); - return -1; -} diff --git a/platform/haiku/os_haiku.h b/platform/haiku/os_haiku.h index 70d78a1978..fc8cb77a91 100644 --- a/platform/haiku/os_haiku.h +++ b/platform/haiku/os_haiku.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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,7 +38,6 @@ #include "haiku_direct_window.h" #include "main/input_default.h" #include "servers/audio_server.h" -#include "servers/camera_server.h" #include "servers/visual_server.h" class OS_Haiku : public OS_Unix { @@ -50,7 +49,6 @@ private: VisualServer *visual_server; VideoMode current_video_mode; int video_driver_index; - CameraServer *camera_server; #ifdef MEDIA_KIT_ENABLED AudioDriverMediaKit driver_media_kit; @@ -115,10 +113,6 @@ public: virtual void get_fullscreen_mode_list(List<VideoMode> *p_list, int p_screen = 0) const; virtual String get_executable_path() const; - virtual OS::PowerState get_power_state(); - virtual int get_power_seconds_left(); - virtual int get_power_percent_left(); - virtual bool _check_internal_feature_support(const String &p_feature); virtual String get_config_path() const; diff --git a/platform/haiku/platform_config.h b/platform/haiku/platform_config.h index 3ce26136e8..f2d5418adf 100644 --- a/platform/haiku/platform_config.h +++ b/platform/haiku/platform_config.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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,5 +33,4 @@ // for ifaddrs.h needed in drivers/unix/ip_unix.cpp #define _BSD_SOURCE 1 -#define GLES3_INCLUDE_H "thirdparty/glad/glad/glad.h" #define GLES2_INCLUDE_H "thirdparty/glad/glad/glad.h" diff --git a/platform/iphone/SCsub b/platform/iphone/SCsub index 85ba56165b..1f82f51888 100644 --- a/platform/iphone/SCsub +++ b/platform/iphone/SCsub @@ -14,7 +14,7 @@ iphone_lib = [ 'in_app_store.mm', 'icloud.mm', 'ios.mm', - 'camera_ios.mm', + 'vulkan_context_iphone.mm', ] env_ios = env.Clone() diff --git a/platform/iphone/app_delegate.h b/platform/iphone/app_delegate.h index 4c43f10e89..6b3b7ad5bc 100644 --- a/platform/iphone/app_delegate.h +++ b/platform/iphone/app_delegate.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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,13 +28,20 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ +#if defined(OPENGL_ENABLED) #import "gl_view.h" +#endif #import "view_controller.h" #import <UIKit/UIKit.h> #import <CoreMotion/CoreMotion.h> +#if defined(OPENGL_ENABLED) @interface AppDelegate : NSObject <UIApplicationDelegate, GLViewDelegate> { +#endif +#if defined(VULKAN_ENABLED) +@interface AppDelegate : NSObject <UIApplicationDelegate> { +#endif //@property (strong, nonatomic) UIWindow *window; ViewController *view_controller; bool is_focus_out; diff --git a/platform/iphone/app_delegate.mm b/platform/iphone/app_delegate.mm index 3f1230faa8..acc3e5d4e0 100644 --- a/platform/iphone/app_delegate.mm +++ b/platform/iphone/app_delegate.mm @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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,7 +32,9 @@ #include "core/project_settings.h" #include "drivers/coreaudio/audio_driver_coreaudio.h" +#if defined(OPENGL_ENABLED) #import "gl_view.h" +#endif #include "main/main.h" #include "os_iphone.h" @@ -412,10 +414,12 @@ static void on_focus_in(ViewController *view_controller, bool *is_focus_out) { OS::VideoMode _get_video_mode() { int backingWidth; int backingHeight; +#if defined(OPENGL_ENABLED) glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_WIDTH_OES, &backingWidth); glGetRenderbufferParameterivOES(GL_RENDERBUFFER_OES, GL_RENDERBUFFER_HEIGHT_OES, &backingHeight); +#endif OS::VideoMode vm; vm.fullscreen = true; @@ -426,7 +430,7 @@ OS::VideoMode _get_video_mode() { }; static int frame_count = 0; -- (void)drawView:(GLView *)view; +- (void)drawView:(UIView *)view; { switch (frame_count) { @@ -634,6 +638,7 @@ static int frame_count = 0; return FALSE; }; +#if defined(OPENGL_ENABLED) // WARNING: We must *always* create the GLView after we have constructed the // OS with iphone_main. This allows the GLView to access project settings so // it can properly initialize the OpenGL context @@ -642,7 +647,7 @@ static int frame_count = 0; view_controller = [[ViewController alloc] init]; view_controller.view = glView; - window.rootViewController = view_controller; + _set_keep_screen_on(bool(GLOBAL_DEF("display/window/energy_saving/keep_screen_on", true)) ? YES : NO); glView.useCADisplayLink = @@ -650,6 +655,13 @@ static int frame_count = 0; printf("cadisaplylink: %d", glView.useCADisplayLink); glView.animationInterval = 1.0 / kRenderingFrequency; [glView startAnimation]; +#endif + +#if defined(VULKAN_ENABLED) + view_controller = [[ViewController alloc] init]; +#endif + + window.rootViewController = view_controller; // Show the window [window makeKeyAndVisible]; diff --git a/platform/iphone/camera_ios.mm b/platform/iphone/camera_ios.mm deleted file mode 100644 index ff84df66ff..0000000000 --- a/platform/iphone/camera_ios.mm +++ /dev/null @@ -1,436 +0,0 @@ -/*************************************************************************/ -/* camera_ios.mm */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -///@TODO this is a near duplicate of CameraOSX, we should find a way to combine those to minimise code duplication!!!! -// If you fix something here, make sure you fix it there as wel! - -#include "camera_ios.h" -#include "servers/camera/camera_feed.h" - -#import <AVFoundation/AVFoundation.h> -#import <UIKit/UIKit.h> - -////////////////////////////////////////////////////////////////////////// -// MyCaptureSession - This is a little helper class so we can capture our frames - -@interface MyCaptureSession : AVCaptureSession <AVCaptureVideoDataOutputSampleBufferDelegate> { - Ref<CameraFeed> feed; - size_t width[2]; - size_t height[2]; - PoolVector<uint8_t> img_data[2]; - - AVCaptureDeviceInput *input; - AVCaptureVideoDataOutput *output; -} - -@end - -@implementation MyCaptureSession - -- (id)initForFeed:(Ref<CameraFeed>)p_feed andDevice:(AVCaptureDevice *)p_device { - if (self = [super init]) { - NSError *error; - feed = p_feed; - width[0] = 0; - height[0] = 0; - width[1] = 0; - height[1] = 0; - - // prepare our device - [p_device lockForConfiguration:&error]; - - [p_device setFocusMode:AVCaptureFocusModeLocked]; - [p_device setExposureMode:AVCaptureExposureModeLocked]; - [p_device setWhiteBalanceMode:AVCaptureWhiteBalanceModeLocked]; - - [p_device unlockForConfiguration]; - - [self beginConfiguration]; - - // setup our capture - self.sessionPreset = AVCaptureSessionPreset1280x720; - - input = [AVCaptureDeviceInput deviceInputWithDevice:p_device error:&error]; - if (!input) { - print_line("Couldn't get input device for camera"); - } else { - [self addInput:input]; - } - - output = [AVCaptureVideoDataOutput new]; - if (!output) { - print_line("Couldn't get output device for camera"); - } else { - NSDictionary *settings = @{ (NSString *)kCVPixelBufferPixelFormatTypeKey : @(kCVPixelFormatType_420YpCbCr8BiPlanarFullRange) }; - output.videoSettings = settings; - - // discard if the data output queue is blocked (as we process the still image) - [output setAlwaysDiscardsLateVideoFrames:YES]; - - // now set ourselves as the delegate to receive new frames. Note that we're doing this on the main thread at the moment, we may need to change this.. - [output setSampleBufferDelegate:self queue:dispatch_get_main_queue()]; - - [self addOutput:output]; - } - - [self commitConfiguration]; - - // kick off our session.. - [self startRunning]; - }; - return self; -} - -- (void)cleanup { - // stop running - [self stopRunning]; - - // cleanup - [self beginConfiguration]; - - if (input) { - [self removeInput:input]; - // don't release this - input = nil; - } - - if (output) { - [self removeOutput:output]; - [output setSampleBufferDelegate:nil queue:NULL]; - [output release]; - output = nil; - } - - [self commitConfiguration]; -} - -- (void)dealloc { - // bye bye - [super dealloc]; -} - -- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection { - // This gets called every time our camera has a new image for us to process. - // May need to investigate in a way to throttle this if we get more images then we're rendering frames.. - - // For now, version 1, we're just doing the bare minimum to make this work... - - CVImageBufferRef pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer); - // int width = CVPixelBufferGetWidth(pixelBuffer); - // int height = CVPixelBufferGetHeight(pixelBuffer); - - // It says that we need to lock this on the documentation pages but it's not in the samples - // need to lock our base address so we can access our pixel buffers, better safe then sorry? - CVPixelBufferLockBaseAddress(pixelBuffer, kCVPixelBufferLock_ReadOnly); - - // get our buffers - unsigned char *dataY = (unsigned char *)CVPixelBufferGetBaseAddressOfPlane(pixelBuffer, 0); - unsigned char *dataCbCr = (unsigned char *)CVPixelBufferGetBaseAddressOfPlane(pixelBuffer, 1); - if (dataY == NULL) { - print_line("Couldn't access Y pixel buffer data"); - } else if (dataCbCr == NULL) { - print_line("Couldn't access CbCr pixel buffer data"); - } else { - UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation]; - Ref<Image> img[2]; - - { - // do Y - int new_width = CVPixelBufferGetWidthOfPlane(pixelBuffer, 0); - int new_height = CVPixelBufferGetHeightOfPlane(pixelBuffer, 0); - int _bytes_per_row = CVPixelBufferGetBytesPerRowOfPlane(pixelBuffer, 0); - - if ((width[0] != new_width) || (height[0] != new_height)) { - // printf("Camera Y plane %i, %i - %i\n", new_width, new_height, bytes_per_row); - - width[0] = new_width; - height[0] = new_height; - img_data[0].resize(new_width * new_height); - } - - PoolVector<uint8_t>::Write w = img_data[0].write(); - memcpy(w.ptr(), dataY, new_width * new_height); - - img[0].instance(); - img[0]->create(new_width, new_height, 0, Image::FORMAT_R8, img_data[0]); - } - - { - // do CbCr - int new_width = CVPixelBufferGetWidthOfPlane(pixelBuffer, 1); - int new_height = CVPixelBufferGetHeightOfPlane(pixelBuffer, 1); - int bytes_per_row = CVPixelBufferGetBytesPerRowOfPlane(pixelBuffer, 1); - - if ((width[1] != new_width) || (height[1] != new_height)) { - // printf("Camera CbCr plane %i, %i - %i\n", new_width, new_height, bytes_per_row); - - width[1] = new_width; - height[1] = new_height; - img_data[1].resize(2 * new_width * new_height); - } - - PoolVector<uint8_t>::Write w = img_data[1].write(); - memcpy(w.ptr(), dataCbCr, 2 * new_width * new_height); - - ///TODO GLES2 doesn't support FORMAT_RG8, need to do some form of conversion - img[1].instance(); - img[1]->create(new_width, new_height, 0, Image::FORMAT_RG8, img_data[1]); - } - - // set our texture... - feed->set_YCbCr_imgs(img[0], img[1]); - - // update our matrix to match the orientation, note, before changing anything - // here, be aware that the project orientation settings must match your xcode - // settings or this will go wrong! - Transform2D display_transform; - switch (orientation) { - case UIInterfaceOrientationPortrait: { - display_transform = Transform2D(0.0, -1.0, -1.0, 0.0, 1.0, 1.0); - } break; - case UIInterfaceOrientationLandscapeRight: { - display_transform = Transform2D(1.0, 0.0, 0.0, -1.0, 0.0, 1.0); - } break; - case UIInterfaceOrientationLandscapeLeft: { - display_transform = Transform2D(-1.0, 0.0, 0.0, 1.0, 1.0, 0.0); - } break; - default: { - display_transform = Transform2D(0.0, 1.0, 1.0, 0.0, 0.0, 0.0); - } break; - } - - //TODO: this is correct for the camera on the back, I have a feeling this needs to be inversed for the camera on the front! - feed->set_transform(display_transform); - } - - // and unlock - CVPixelBufferUnlockBaseAddress(pixelBuffer, kCVPixelBufferLock_ReadOnly); -} - -@end - -////////////////////////////////////////////////////////////////////////// -// CameraFeedIOS - Subclass for camera feeds in iOS - -class CameraFeedIOS : public CameraFeed { -private: - AVCaptureDevice *device; - MyCaptureSession *capture_session; - -public: - bool get_is_arkit() const; - AVCaptureDevice *get_device() const; - - CameraFeedIOS(); - ~CameraFeedIOS(); - - void set_device(AVCaptureDevice *p_device); - - bool activate_feed(); - void deactivate_feed(); -}; - -AVCaptureDevice *CameraFeedIOS::get_device() const { - return device; -}; - -CameraFeedIOS::CameraFeedIOS() { - capture_session = NULL; - device = NULL; - transform = Transform2D(1.0, 0.0, 0.0, 1.0, 0.0, 0.0); /* should re-orientate this based on device orientation */ -}; - -void CameraFeedIOS::set_device(AVCaptureDevice *p_device) { - device = p_device; - [device retain]; - - // get some info - NSString *device_name = p_device.localizedName; - name = device_name.UTF8String; - position = CameraFeed::FEED_UNSPECIFIED; - if ([p_device position] == AVCaptureDevicePositionBack) { - position = CameraFeed::FEED_BACK; - } else if ([p_device position] == AVCaptureDevicePositionFront) { - position = CameraFeed::FEED_FRONT; - }; -}; - -CameraFeedIOS::~CameraFeedIOS() { - if (capture_session != NULL) { - [capture_session release]; - capture_session = NULL; - }; - - if (device != NULL) { - [device release]; - device = NULL; - }; -}; - -bool CameraFeedIOS::activate_feed() { - if (capture_session) { - // already recording! - } else { - // start camera capture - capture_session = [[MyCaptureSession alloc] initForFeed:this andDevice:device]; - }; - - return true; -}; - -void CameraFeedIOS::deactivate_feed() { - // end camera capture if we have one - if (capture_session) { - [capture_session cleanup]; - [capture_session release]; - capture_session = NULL; - }; -}; - -////////////////////////////////////////////////////////////////////////// -// MyDeviceNotifications - This is a little helper class gets notifications -// when devices are connected/disconnected - -@interface MyDeviceNotifications : NSObject { - CameraIOS *camera_server; -} - -@end - -@implementation MyDeviceNotifications - -- (void)devices_changed:(NSNotification *)notification { - camera_server->update_feeds(); -} - -- (id)initForServer:(CameraIOS *)p_server { - if (self = [super init]) { - camera_server = p_server; - - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(devices_changed:) name:AVCaptureDeviceWasConnectedNotification object:nil]; - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(devices_changed:) name:AVCaptureDeviceWasDisconnectedNotification object:nil]; - }; - return self; -} - -- (void)dealloc { - // remove notifications - [[NSNotificationCenter defaultCenter] removeObserver:self name:AVCaptureDeviceWasConnectedNotification object:nil]; - [[NSNotificationCenter defaultCenter] removeObserver:self name:AVCaptureDeviceWasDisconnectedNotification object:nil]; - - [super dealloc]; -} - -@end - -MyDeviceNotifications *device_notifications = nil; - -////////////////////////////////////////////////////////////////////////// -// CameraIOS - Subclass for our camera server on iPhone - -void CameraIOS::update_feeds() { - // this way of doing things is deprecated but still works, - // rewrite to using AVCaptureDeviceDiscoverySession - - AVCaptureDeviceDiscoverySession *session = [AVCaptureDeviceDiscoverySession discoverySessionWithDeviceTypes:[NSArray arrayWithObjects:AVCaptureDeviceTypeBuiltInTelephotoCamera, AVCaptureDeviceTypeBuiltInDualCamera, AVCaptureDeviceTypeBuiltInTrueDepthCamera, AVCaptureDeviceTypeBuiltInWideAngleCamera] mediaType:AVMediaTypeVideo position:AVCaptureDevicePositionUnspecified]; - - // remove devices that are gone.. - for (int i = feeds.size() - 1; i >= 0; i--) { - Ref<CameraFeedIOS> feed(feeds[i]); - - if (feed.is_null()) { - // feed not managed by us - } else if (![session.devices containsObject:feed->get_device()]) { - // remove it from our array, this will also destroy it ;) - remove_feed(feed); - }; - }; - - // add new devices.. - for (AVCaptureDevice *device in session.devices) { - bool found = false; - - for (int i = 0; i < feeds.size() && !found; i++) { - Ref<CameraFeedIOS> feed(feeds[i]); - - if (feed.is_null()) { - // feed not managed by us - } else if (feed->get_device() == device) { - found = true; - }; - }; - - if (!found) { - Ref<CameraFeedIOS> newfeed; - newfeed.instance(); - newfeed->set_device(device); - add_feed(newfeed); - }; - }; -}; - -CameraIOS::CameraIOS() { - // check if we have our usage description - NSString *usage_desc = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"NSCameraUsageDescription"]; - if (usage_desc == NULL) { - // don't initialise if we don't get anything - print_line("No NSCameraUsageDescription key in pList, no access to cameras."); - return; - } else if (usage_desc.length == 0) { - // don't initialise if we don't get anything - print_line("Empty NSCameraUsageDescription key in pList, no access to cameras."); - return; - } - - // now we'll request access. - // If this is the first time the user will be prompted with the string (iOS will read it). - // Once a decision is made it is returned. If the user wants to change it later on they - // need to go into setting. - print_line("Requesting Camera permissions"); - - [AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo - completionHandler:^(BOOL granted) { - if (granted) { - print_line("Access to cameras granted!"); - - // Find available cameras we have at this time - update_feeds(); - - // should only have one of these.... - device_notifications = [[MyDeviceNotifications alloc] initForServer:this]; - } else { - print_line("No access to cameras!"); - } - }]; -}; - -CameraIOS::~CameraIOS() { - [device_notifications release]; -}; diff --git a/platform/iphone/detect.py b/platform/iphone/detect.py index f646b8b1d5..e01950c1db 100644 --- a/platform/iphone/detect.py +++ b/platform/iphone/detect.py @@ -23,6 +23,7 @@ def get_opts(): return [ ('IPHONEPATH', 'Path to iPhone toolchain', '/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain'), ('IPHONESDK', 'Path to the iPhone SDK', ''), + BoolVariable('use_static_mvk', 'Link MoltenVK statically as Level-0 driver (better portability) or use Vulkan ICD loader (enables validation layers)', False), BoolVariable('game_center', 'Support for game center', True), BoolVariable('store_kit', 'Support for in-app store', True), BoolVariable('icloud', 'Support for iCloud', True), @@ -149,7 +150,7 @@ def configure(env): '-framework', 'Foundation', '-framework', 'GameController', '-framework', 'MediaPlayer', - '-framework', 'OpenGLES', + '-framework', 'Metal', '-framework', 'QuartzCore', '-framework', 'Security', '-framework', 'SystemConfiguration', @@ -170,11 +171,18 @@ def configure(env): env.Append(CPPDEFINES=['ICLOUD_ENABLED']) env.Prepend(CPPPATH=['$IPHONESDK/usr/include', - '$IPHONESDK/System/Library/Frameworks/OpenGLES.framework/Headers', '$IPHONESDK/System/Library/Frameworks/AudioUnit.framework/Headers', ]) env['ENV']['CODESIGN_ALLOCATE'] = '/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/codesign_allocate' env.Prepend(CPPPATH=['#platform/iphone']) - env.Append(CPPDEFINES=['IPHONE_ENABLED', 'UNIX_ENABLED', 'GLES_ENABLED', 'COREAUDIO_ENABLED']) + env.Append(CPPDEFINES=['IPHONE_ENABLED', 'UNIX_ENABLED', 'COREAUDIO_ENABLED']) + + env.Append(CPPDEFINES=['VULKAN_ENABLED']) + env.Append(LINKFLAGS=['-framework', 'IOSurface']) + if (env['use_static_mvk']): + env.Append(LINKFLAGS=['-framework', 'MoltenVK']) + env['builtin_vulkan'] = False + elif not env['builtin_vulkan']: + env.Append(LIBS=['vulkan']) diff --git a/platform/iphone/export/export.cpp b/platform/iphone/export/export.cpp index baae13c53d..7cef2351e3 100644 --- a/platform/iphone/export/export.cpp +++ b/platform/iphone/export/export.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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,6 +29,7 @@ /*************************************************************************/ #include "export.h" +#include "core/io/image_loader.h" #include "core/io/marshalls.h" #include "core/io/resource_saver.h" #include "core/io/zip_io.h" @@ -39,6 +40,7 @@ #include "editor/editor_export.h" #include "editor/editor_node.h" #include "editor/editor_settings.h" +#include "main/splash.gen.h" #include "platform/iphone/logo.gen.h" #include "string.h" @@ -55,6 +57,7 @@ class EditorExportPlatformIOS : public EditorExportPlatform { typedef Error (*FileHandler)(String p_file, void *p_userdata); static Error _walk_dir_recursive(DirAccess *p_da, FileHandler p_handler, void *p_userdata); static Error _codesign(String p_file, void *p_userdata); + void _blend_and_rotate(Ref<Image> &p_dst, Ref<Image> &p_src, bool p_rot); struct IOSConfigData { String pkg_name; @@ -63,6 +66,10 @@ class EditorExportPlatformIOS : public EditorExportPlatform { String architectures; String linker_flags; String cpp_code; + String modules_buildfile; + String modules_fileref; + String modules_buildphase; + String modules_buildgrp; }; struct ExportArchitecture { @@ -110,54 +117,14 @@ class EditorExportPlatformIOS : public EditorExportPlatform { return false; } - int segments = 0; - bool first = true; for (int i = 0; i < pname.length(); i++) { CharType c = pname[i]; - if (first && c == '.') { - if (r_error) { - *r_error = TTR("Identifier segments must be of non-zero length."); - } - return false; - } - if (c == '.') { - segments++; - first = true; - continue; - } - if (!((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '-')) { + if (!((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '-' || c == '.')) { if (r_error) { *r_error = vformat(TTR("The character '%s' is not allowed in Identifier."), String::chr(c)); } return false; } - if (first && (c >= '0' && c <= '9')) { - if (r_error) { - *r_error = TTR("A digit cannot be the first character in a Identifier segment."); - } - return false; - } - if (first && c == '-') { - if (r_error) { - *r_error = vformat(TTR("The character '%s' cannot be the first character in a Identifier segment."), String::chr(c)); - } - return false; - } - first = false; - } - - if (segments == 0) { - if (r_error) { - *r_error = TTR("The Identifier must have at least one '.' separator."); - } - return false; - } - - if (first) { - if (r_error) { - *r_error = TTR("Identifier segments must be of non-zero length."); - } - return false; } return true; @@ -170,7 +137,7 @@ protected: public: virtual String get_name() const { return "iOS"; } virtual String get_os_name() const { return "iOS"; } - virtual Ref<Texture> get_logo() const { return logo; } + virtual Ref<Texture2D> get_logo() const { return logo; } virtual List<String> get_binary_extensions(const Ref<EditorExportPreset> &p_preset) const { List<String> list; @@ -178,6 +145,7 @@ public: return list; } virtual Error export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags = 0); + virtual void add_module_code(const Ref<EditorExportPreset> &p_preset, IOSConfigData &p_config_data, const String &p_name, const String &p_fid, const String &p_gid); virtual bool can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const; @@ -199,11 +167,9 @@ void EditorExportPlatformIOS::get_preset_features(const Ref<EditorExportPreset> String driver = ProjectSettings::get_singleton()->get("rendering/quality/driver/driver_name"); if (driver == "GLES2") { r_features->push_back("etc"); - } else if (driver == "GLES3") { + } else if (driver == "Vulkan") { + // FIXME: Review if this is correct. r_features->push_back("etc2"); - if (ProjectSettings::get_singleton()->get("rendering/quality/driver/fallback_to_gles2")) { - r_features->push_back("etc"); - } } Vector<String> architectures = _get_preset_architectures(p_preset); @@ -214,7 +180,7 @@ void EditorExportPlatformIOS::get_preset_features(const Ref<EditorExportPreset> Vector<EditorExportPlatformIOS::ExportArchitecture> EditorExportPlatformIOS::_get_supported_architectures() { Vector<ExportArchitecture> archs; - archs.push_back(ExportArchitecture("armv7", true)); + archs.push_back(ExportArchitecture("armv7", false)); // Disabled by default, not included in official templates. archs.push_back(ExportArchitecture("arm64", true)); return archs; } @@ -222,27 +188,30 @@ Vector<EditorExportPlatformIOS::ExportArchitecture> EditorExportPlatformIOS::_ge struct LoadingScreenInfo { const char *preset_key; const char *export_name; + int width; + int height; + bool rotate; }; static const LoadingScreenInfo loading_screen_infos[] = { - { "landscape_launch_screens/iphone_2436x1125", "Default-Landscape-X.png" }, - { "landscape_launch_screens/iphone_2208x1242", "Default-Landscape-736h@3x.png" }, - { "landscape_launch_screens/ipad_1024x768", "Default-Landscape.png" }, - { "landscape_launch_screens/ipad_2048x1536", "Default-Landscape@2x.png" }, - - { "portrait_launch_screens/iphone_640x960", "Default-480h@2x.png" }, - { "portrait_launch_screens/iphone_640x1136", "Default-568h@2x.png" }, - { "portrait_launch_screens/iphone_750x1334", "Default-667h@2x.png" }, - { "portrait_launch_screens/iphone_1125x2436", "Default-Portrait-X.png" }, - { "portrait_launch_screens/ipad_768x1024", "Default-Portrait.png" }, - { "portrait_launch_screens/ipad_1536x2048", "Default-Portrait@2x.png" }, - { "portrait_launch_screens/iphone_1242x2208", "Default-Portrait-736h@3x.png" } + { "landscape_launch_screens/iphone_2436x1125", "Default-Landscape-X.png", 2436, 1125, false }, + { "landscape_launch_screens/iphone_2208x1242", "Default-Landscape-736h@3x.png", 2208, 1242, false }, + { "landscape_launch_screens/ipad_1024x768", "Default-Landscape.png", 1024, 768, false }, + { "landscape_launch_screens/ipad_2048x1536", "Default-Landscape@2x.png", 2048, 1536, false }, + + { "portrait_launch_screens/iphone_640x960", "Default-480h@2x.png", 640, 960, true }, + { "portrait_launch_screens/iphone_640x1136", "Default-568h@2x.png", 640, 1136, true }, + { "portrait_launch_screens/iphone_750x1334", "Default-667h@2x.png", 750, 1334, true }, + { "portrait_launch_screens/iphone_1125x2436", "Default-Portrait-X.png", 1125, 2436, true }, + { "portrait_launch_screens/ipad_768x1024", "Default-Portrait.png", 768, 1024, true }, + { "portrait_launch_screens/ipad_1536x2048", "Default-Portrait@2x.png", 1536, 2048, true }, + { "portrait_launch_screens/iphone_1242x2208", "Default-Portrait-736h@3x.png", 1242, 2208, true } }; void EditorExportPlatformIOS::get_export_options(List<ExportOption> *r_options) { - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_package/debug", PROPERTY_HINT_GLOBAL_FILE, "*.zip"), "")); - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_package/release", PROPERTY_HINT_GLOBAL_FILE, "*.zip"), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_template/debug", PROPERTY_HINT_GLOBAL_FILE, "*.zip"), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_template/release", PROPERTY_HINT_GLOBAL_FILE, "*.zip"), "")); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/app_store_team_id"), "")); @@ -263,11 +232,16 @@ void EditorExportPlatformIOS::get_export_options(List<ExportOption> *r_options) r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/copyright"), "")); r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "capabilities/arkit"), false)); + r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "capabilities/camera"), false)); + r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "capabilities/access_wifi"), false)); r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "capabilities/game_center"), true)); r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "capabilities/in_app_purchases"), false)); r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "capabilities/push_notifications"), false)); + r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "user_data/accessible_from_files_app"), false)); + r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "user_data/accessible_from_itunes_sharing"), false)); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "privacy/camera_usage_description", PROPERTY_HINT_PLACEHOLDER_TEXT, "Provide a message if you need to use the camera"), "")); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "privacy/microphone_usage_description", PROPERTY_HINT_PLACEHOLDER_TEXT, "Provide a message if you need to use the microphone"), "")); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "privacy/photolibrary_usage_description", PROPERTY_HINT_PLACEHOLDER_TEXT, "Provide a message if you need access to the photo library"), "")); @@ -277,6 +251,8 @@ void EditorExportPlatformIOS::get_export_options(List<ExportOption> *r_options) r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "orientation/landscape_right"), true)); r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "orientation/portrait_upside_down"), true)); + r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "icons/generate_missing"), false)); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "required_icons/iphone_120x120", PROPERTY_HINT_FILE, "*.png"), "")); // Home screen on iPhone/iPod Touch with retina display r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "required_icons/ipad_76x76", PROPERTY_HINT_FILE, "*.png"), "")); // Home screen on iPad r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "required_icons/app_store_1024x1024", PROPERTY_HINT_FILE, "*.png"), "")); // App Store @@ -287,6 +263,8 @@ void EditorExportPlatformIOS::get_export_options(List<ExportOption> *r_options) r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "optional_icons/spotlight_40x40", PROPERTY_HINT_FILE, "*.png"), "")); // Spotlight r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "optional_icons/spotlight_80x80", PROPERTY_HINT_FILE, "*.png"), "")); // Spotlight on devices with retina display + r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "launch_screens/generate_missing"), false)); + for (uint64_t i = 0; i < sizeof(loading_screen_infos) / sizeof(loading_screen_infos[0]); ++i) { r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, loading_screen_infos[i].preset_key, PROPERTY_HINT_FILE, "*.png"), "")); } @@ -311,6 +289,14 @@ void EditorExportPlatformIOS::_fix_config_file(const Ref<EditorExportPreset> &p_ for (int i = 0; i < lines.size(); i++) { if (lines[i].find("$binary") != -1) { strnew += lines[i].replace("$binary", p_config.binary_name) + "\n"; + } else if (lines[i].find("$modules_buildfile") != -1) { + strnew += lines[i].replace("$modules_buildfile", p_config.modules_buildfile) + "\n"; + } else if (lines[i].find("$modules_fileref") != -1) { + strnew += lines[i].replace("$modules_fileref", p_config.modules_fileref) + "\n"; + } else if (lines[i].find("$modules_buildphase") != -1) { + strnew += lines[i].replace("$modules_buildphase", p_config.modules_buildphase) + "\n"; + } else if (lines[i].find("$modules_buildgrp") != -1) { + strnew += lines[i].replace("$modules_buildgrp", p_config.modules_buildgrp) + "\n"; } else if (lines[i].find("$name") != -1) { strnew += lines[i].replace("$name", p_config.pkg_name) + "\n"; } else if (lines[i].find("$info") != -1) { @@ -349,6 +335,10 @@ void EditorExportPlatformIOS::_fix_config_file(const Ref<EditorExportPreset> &p_ strnew += lines[i].replace("$linker_flags", p_config.linker_flags) + "\n"; } else if (lines[i].find("$cpp_code") != -1) { strnew += lines[i].replace("$cpp_code", p_config.cpp_code) + "\n"; + } else if (lines[i].find("$docs_in_place") != -1) { + strnew += lines[i].replace("$docs_in_place", ((bool)p_preset->get("user_data/accessible_from_files_app")) ? "<true/>" : "<false/>") + "\n"; + } else if (lines[i].find("$docs_sharing") != -1) { + strnew += lines[i].replace("$docs_sharing", ((bool)p_preset->get("user_data/accessible_from_itunes_sharing")) ? "<true/>" : "<false/>") + "\n"; } else if (lines[i].find("$access_wifi") != -1) { bool is_on = p_preset->get("capabilities/access_wifi"); strnew += lines[i].replace("$access_wifi", is_on ? "1" : "0") + "\n"; @@ -452,6 +442,36 @@ String EditorExportPlatformIOS::_get_cpp_code() { return result; } +void EditorExportPlatformIOS::_blend_and_rotate(Ref<Image> &p_dst, Ref<Image> &p_src, bool p_rot) { + + ERR_FAIL_COND(p_dst.is_null()); + ERR_FAIL_COND(p_src.is_null()); + + int sw = p_rot ? p_src->get_height() : p_src->get_width(); + int sh = p_rot ? p_src->get_width() : p_src->get_height(); + + int x_pos = (p_dst->get_width() - sw) / 2; + int y_pos = (p_dst->get_height() - sh) / 2; + + int xs = (x_pos >= 0) ? 0 : -x_pos; + int ys = (y_pos >= 0) ? 0 : -y_pos; + + if (sw + x_pos > p_dst->get_width()) sw = p_dst->get_width() - x_pos; + if (sh + y_pos > p_dst->get_height()) sh = p_dst->get_height() - y_pos; + + for (int y = ys; y < sh; y++) { + for (int x = xs; x < sw; x++) { + Color sc = p_rot ? p_src->get_pixel(p_src->get_width() - y - 1, x) : p_src->get_pixel(x, y); + Color dc = p_dst->get_pixel(x_pos + x, y_pos + y); + dc.r = (double)(sc.a * sc.r + dc.a * (1.0 - sc.a) * dc.r); + dc.g = (double)(sc.a * sc.g + dc.a * (1.0 - sc.a) * dc.g); + dc.b = (double)(sc.a * sc.b + dc.a * (1.0 - sc.a) * dc.b); + dc.a = (double)(sc.a + dc.a * (1.0 - sc.a)); + p_dst->set_pixel(x_pos + x, y_pos + y, dc); + } + } +} + struct IconInfo { const char *preset_key; const char *idiom; @@ -466,8 +486,8 @@ static const IconInfo icon_infos[] = { { "required_icons/iphone_120x120", "iphone", "Icon-120.png", "120", "2x", "60x60", true }, { "required_icons/iphone_120x120", "iphone", "Icon-120.png", "120", "3x", "40x40", true }, - { "required_icons/ipad_76x76", "ipad", "Icon-76.png", "76", "1x", "76x76", false }, - { "required_icons/app_store_1024x1024", "ios-marketing", "Icon-1024.png", "1024", "1x", "1024x1024", false }, + { "required_icons/ipad_76x76", "ipad", "Icon-76.png", "76", "1x", "76x76", true }, + { "required_icons/app_store_1024x1024", "ios-marketing", "Icon-1024.png", "1024", "1x", "1024x1024", true }, { "optional_icons/iphone_180x180", "iphone", "Icon-180.png", "180", "3x", "60x60", false }, @@ -491,20 +511,56 @@ Error EditorExportPlatformIOS::_export_icons(const Ref<EditorExportPreset> &p_pr for (uint64_t i = 0; i < (sizeof(icon_infos) / sizeof(icon_infos[0])); ++i) { IconInfo info = icon_infos[i]; + int side_size = String(info.actual_size_side).to_int(); String icon_path = p_preset->get(info.preset_key); if (icon_path.length() == 0) { - if (info.is_required) { - ERR_PRINT("Required icon is not specified in the preset"); + if ((bool)p_preset->get("icons/generate_missing")) { + // Resize main app icon + icon_path = ProjectSettings::get_singleton()->get("application/config/icon"); + Ref<Image> img = memnew(Image); + Error err = ImageLoader::load_image(icon_path, img); + if (err != OK) { + ERR_PRINT("Invalid icon (" + String(info.preset_key) + "): '" + icon_path + "'."); + return ERR_UNCONFIGURED; + } + img->resize(side_size, side_size); + err = img->save_png(p_iconset_dir + info.export_name); + if (err) { + String err_str = String("Failed to export icon(" + String(info.preset_key) + "): '" + icon_path + "'."); + ERR_PRINT(err_str.utf8().get_data()); + return err; + } + } else { + if (info.is_required) { + String err_str = String("Required icon (") + info.preset_key + ") is not specified in the preset."; + ERR_PRINT(err_str); + return ERR_UNCONFIGURED; + } else { + String err_str = String("Icon (") + info.preset_key + ") is not specified in the preset."; + WARN_PRINT(err_str); + } + continue; + } + } else { + // Load custom icon + Ref<Image> img = memnew(Image); + Error err = ImageLoader::load_image(icon_path, img); + if (err != OK) { + ERR_PRINT("Invalid icon (" + String(info.preset_key) + "): '" + icon_path + "'."); return ERR_UNCONFIGURED; } - continue; - } - Error err = da->copy(icon_path, p_iconset_dir + info.export_name); - if (err) { - memdelete(da); - String err_str = String("Failed to export icon: ") + icon_path; - ERR_PRINT(err_str.utf8().get_data()); - return err; + if (img->get_width() != side_size || img->get_height() != side_size) { + ERR_PRINT("Invalid icon size (" + String(info.preset_key) + "): '" + icon_path + "'."); + return ERR_UNCONFIGURED; + } + + err = da->copy(icon_path, p_iconset_dir + info.export_name); + if (err) { + memdelete(da); + String err_str = String("Failed to export icon(" + String(info.preset_key) + "): '" + icon_path + "'."); + ERR_PRINT(err_str.utf8().get_data()); + return err; + } } sizes += String(info.actual_size_side) + "\n"; if (i > 0) { @@ -543,13 +599,72 @@ Error EditorExportPlatformIOS::_export_loading_screens(const Ref<EditorExportPre LoadingScreenInfo info = loading_screen_infos[i]; String loading_screen_file = p_preset->get(info.preset_key); if (loading_screen_file.size() > 0) { - Error err = da->copy(loading_screen_file, p_dest_dir + info.export_name); + // Load custom loading screens + Ref<Image> img = memnew(Image); + Error err = ImageLoader::load_image(loading_screen_file, img); + if (err != OK) { + ERR_PRINT("Invalid loading screen (" + String(info.preset_key) + "): '" + loading_screen_file + "'."); + return ERR_UNCONFIGURED; + } + if (img->get_width() != info.width || img->get_height() != info.height) { + ERR_PRINT("Invalid loading screen size (" + String(info.preset_key) + "): '" + loading_screen_file + "'."); + return ERR_UNCONFIGURED; + } + err = da->copy(loading_screen_file, p_dest_dir + info.export_name); if (err) { memdelete(da); String err_str = String("Failed to export loading screen (") + info.preset_key + ") from path '" + loading_screen_file + "'."; ERR_PRINT(err_str.utf8().get_data()); return err; } + } else if ((bool)p_preset->get("launch_screens/generate_missing")) { + // Generate loading screen from the splash screen + Color boot_bg_color = ProjectSettings::get_singleton()->get("application/boot_splash/bg_color"); + String boot_logo_path = ProjectSettings::get_singleton()->get("application/boot_splash/image"); + bool boot_logo_scale = ProjectSettings::get_singleton()->get("application/boot_splash/fullsize"); + + Ref<Image> img = memnew(Image); + img->create(info.width, info.height, false, Image::FORMAT_RGBA8); + img->fill(boot_bg_color); + + Ref<Image> img_bs; + + if (boot_logo_path.length() > 0) { + img_bs = Ref<Image>(memnew(Image)); + ImageLoader::load_image(boot_logo_path, img_bs); + } + if (!img_bs.is_valid()) { + img_bs = Ref<Image>(memnew(Image(boot_splash_png))); + } + if (img_bs.is_valid()) { + float aspect_ratio = (float)img_bs->get_width() / (float)img_bs->get_height(); + if (info.rotate) { + if (boot_logo_scale) { + if (info.width * aspect_ratio <= info.height) { + img_bs->resize(info.width * aspect_ratio, info.width); + } else { + img_bs->resize(info.height, info.height / aspect_ratio); + } + } + } else { + if (boot_logo_scale) { + if (info.height * aspect_ratio <= info.width) { + img_bs->resize(info.height * aspect_ratio, info.height); + } else { + img_bs->resize(info.width, info.width / aspect_ratio); + } + } + } + _blend_and_rotate(img, img_bs, info.rotate); + } + Error err = img->save_png(p_dest_dir + info.export_name); + if (err) { + String err_str = String("Failed to export loading screen (") + info.preset_key + ") from splash screen."; + WARN_PRINT(err_str.utf8().get_data()); + } + } else { + String err_str = String("No loading screen (") + info.preset_key + ") specified."; + WARN_PRINT(err_str.utf8().get_data()); } } memdelete(da); @@ -837,6 +952,22 @@ Vector<String> EditorExportPlatformIOS::_get_preset_architectures(const Ref<Edit return enabled_archs; } +void EditorExportPlatformIOS::add_module_code(const Ref<EditorExportPreset> &p_preset, EditorExportPlatformIOS::IOSConfigData &p_config_data, const String &p_name, const String &p_fid, const String &p_gid) { + if ((bool)p_preset->get("capabilities/" + p_name)) { + //add module static library + print_line("ADDING MODULE: " + p_name); + + p_config_data.modules_buildfile += p_gid + " /* libgodot_" + p_name + "_module.a in Frameworks */ = {isa = PBXBuildFile; fileRef = " + p_fid + " /* libgodot_" + p_name + "_module.a */; };\n\t\t"; + p_config_data.modules_fileref += p_fid + " /* libgodot_" + p_name + "_module.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = godot_" + p_name + "_module ; path = \"libgodot_" + p_name + "_module.a\"; sourceTree = \"<group>\"; };\n\t\t"; + p_config_data.modules_buildphase += p_gid + " /* libgodot_" + p_name + "_module.a */,\n\t\t\t\t"; + p_config_data.modules_buildgrp += p_fid + " /* libgodot_" + p_name + "_module.a */,\n\t\t\t\t"; + } else { + //add stub function for disabled module + p_config_data.cpp_code += "void register_" + p_name + "_types() { /*stub*/ };\n"; + p_config_data.cpp_code += "void unregister_" + p_name + "_types() { /*stub*/ };\n"; + } +} + Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags) { ExportNotifier notifier(*this, p_preset, p_debug, p_path, p_flags); @@ -850,9 +981,9 @@ Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_p ERR_FAIL_COND_V_MSG(team_id.length() == 0, ERR_CANT_OPEN, "App Store Team ID not specified - cannot configure the project."); if (p_debug) - src_pkg_name = p_preset->get("custom_package/debug"); + src_pkg_name = p_preset->get("custom_template/debug"); else - src_pkg_name = p_preset->get("custom_package/release"); + src_pkg_name = p_preset->get("custom_template/release"); if (src_pkg_name == "") { String err; @@ -934,7 +1065,11 @@ Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_p _get_additional_plist_content(), String(" ").join(_get_preset_architectures(p_preset)), _get_linker_flags(), - _get_cpp_code() + _get_cpp_code(), + "", + "", + "", + "" }; DirAccess *tmp_app_path = DirAccess::create_for_path(dest_dir); @@ -949,6 +1084,10 @@ Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_p return ERR_CANT_OPEN; } + add_module_code(p_preset, config_data, "arkit", "F9B95E6E2391205500AF0000", "F9C95E812391205C00BF0000"); + add_module_code(p_preset, config_data, "camera", "F9B95E6E2391205500AF0001", "F9C95E812391205C00BF0001"); + + //export rest of the files int ret = unzGoToFirstFile(src_pkg_zip); Vector<uint8_t> project_file_data; while (ret == UNZ_OK) { @@ -988,6 +1127,20 @@ Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_p is_execute = true; #endif file = "godot_ios.a"; + } else if (file.begins_with("libgodot_arkit")) { + if ((bool)p_preset->get("capabilities/arkit") && file.ends_with(String(p_debug ? "debug" : "release") + ".fat.a")) { + file = "libgodot_arkit_module.a"; + } else { + ret = unzGoToNextFile(src_pkg_zip); + continue; //ignore! + } + } else if (file.begins_with("libgodot_camera")) { + if ((bool)p_preset->get("capabilities/camera") && file.ends_with(String(p_debug ? "debug" : "release") + ".fat.a")) { + file = "libgodot_camera_module.a"; + } else { + ret = unzGoToNextFile(src_pkg_zip); + continue; //ignore! + } } if (file == project_file) { project_file_data = data; @@ -1010,7 +1163,7 @@ Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_p print_line("Creating " + dir_name); Error dir_err = tmp_app_path->make_dir_recursive(dir_name); if (dir_err) { - ERR_PRINTS("Can't create '" + dir_name + "'."); + ERR_PRINT("Can't create '" + dir_name + "'."); unzClose(src_pkg_zip); memdelete(tmp_app_path); return ERR_CANT_CREATE; @@ -1020,7 +1173,7 @@ Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_p /* write the file */ FileAccess *f = FileAccess::open(file, FileAccess::WRITE); if (!f) { - ERR_PRINTS("Can't write '" + file + "'."); + ERR_PRINT("Can't write '" + file + "'."); unzClose(src_pkg_zip); memdelete(tmp_app_path); return ERR_CANT_CREATE; @@ -1044,7 +1197,7 @@ Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_p unzClose(src_pkg_zip); if (!found_library) { - ERR_PRINTS("Requested template library '" + library_to_use + "' not found. It might be missing from your template archive."); + ERR_PRINT("Requested template library '" + library_to_use + "' not found. It might be missing from your template archive."); memdelete(tmp_app_path); return ERR_FILE_NOT_FOUND; } @@ -1073,7 +1226,7 @@ Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_p String project_file_name = dest_dir + binary_name + ".xcodeproj/project.pbxproj"; FileAccess *f = FileAccess::open(project_file_name, FileAccess::WRITE); if (!f) { - ERR_PRINTS("Can't write '" + project_file_name + "'."); + ERR_PRINT("Can't write '" + project_file_name + "'."); return ERR_CANT_CREATE; }; f->store_buffer(project_file_data.ptr(), project_file_data.size()); @@ -1136,25 +1289,30 @@ Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_p bool EditorExportPlatformIOS::can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const { String err; - r_missing_templates = find_export_template("iphone.zip") == String(); + bool valid = false; - if (p_preset->get("custom_package/debug") != "") { - if (FileAccess::exists(p_preset->get("custom_package/debug"))) { - r_missing_templates = false; - } else { + // Look for export templates (first official, and if defined custom templates). + + bool dvalid = exists_export_template("iphone.zip", &err); + bool rvalid = dvalid; // Both in the same ZIP. + + if (p_preset->get("custom_template/debug") != "") { + dvalid = FileAccess::exists(p_preset->get("custom_template/debug")); + if (!dvalid) { err += TTR("Custom debug template not found.") + "\n"; } } - - if (p_preset->get("custom_package/release") != "") { - if (FileAccess::exists(p_preset->get("custom_package/release"))) { - r_missing_templates = false; - } else { + if (p_preset->get("custom_template/release") != "") { + rvalid = FileAccess::exists(p_preset->get("custom_template/release")); + if (!rvalid) { err += TTR("Custom release template not found.") + "\n"; } } - bool valid = !r_missing_templates; + valid = dvalid || rvalid; + r_missing_templates = !valid; + + // Validate the rest of the configuration. String team_id = p_preset->get("application/app_store_team_id"); if (team_id.length() == 0) { diff --git a/platform/iphone/export/export.h b/platform/iphone/export/export.h index 3da58def33..77b2a07bd1 100644 --- a/platform/iphone/export/export.h +++ b/platform/iphone/export/export.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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.h b/platform/iphone/game_center.h index 1a14968f02..d35cc4b87c 100644 --- a/platform/iphone/game_center.h +++ b/platform/iphone/game_center.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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 97d6f0c71b..99d539d4ff 100644 --- a/platform/iphone/game_center.mm +++ b/platform/iphone/game_center.mm @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -198,11 +198,11 @@ void GameCenter::request_achievement_descriptions() { ret["type"] = "achievement_descriptions"; if (error == nil) { ret["result"] = "ok"; - PoolStringArray names; - PoolStringArray titles; - PoolStringArray unachieved_descriptions; - PoolStringArray achieved_descriptions; - PoolIntArray maximum_points; + PackedStringArray names; + PackedStringArray titles; + PackedStringArray unachieved_descriptions; + PackedStringArray achieved_descriptions; + PackedInt32Array maximum_points; Array hidden; Array replayable; @@ -253,8 +253,8 @@ void GameCenter::request_achievements() { ret["type"] = "achievements"; if (error == nil) { ret["result"] = "ok"; - PoolStringArray names; - PoolRealArray percentages; + PackedStringArray names; + PackedFloat32Array percentages; for (int i = 0; i < [achievements count]; i++) { diff --git a/platform/iphone/gl_view.h b/platform/iphone/gl_view.h index e3c9d212f0..975aa4b70a 100644 --- a/platform/iphone/gl_view.h +++ b/platform/iphone/gl_view.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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 4e6b8e1ada..ede60a502d 100644 --- a/platform/iphone/gl_view.mm +++ b/platform/iphone/gl_view.mm @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -47,7 +47,6 @@ @end */ -bool gles3_available = true; int gl_view_base_fb; static String keyboard_text; static GLView *_instance = NULL; @@ -284,20 +283,11 @@ static void clear_touches() { kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat, nil]; - bool fallback_gl2 = false; - // Create a GL ES 3 context based on the gl driver from project settings - if (GLOBAL_GET("rendering/quality/driver/driver_name") == "GLES3") { - context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES3]; - NSLog(@"Setting up an OpenGL ES 3.0 context. Based on Project Settings \"rendering/quality/driver/driver_name\""); - if (!context && GLOBAL_GET("rendering/quality/driver/fallback_to_gles2")) { - gles3_available = false; - fallback_gl2 = true; - NSLog(@"Failed to create OpenGL ES 3.0 context. Falling back to OpenGL ES 2.0"); - } - } + + // FIXME: Add Vulkan support via MoltenVK. Add fallback code back? // Create GL ES 2 context - if (GLOBAL_GET("rendering/quality/driver/driver_name") == "GLES2" || fallback_gl2) { + if (GLOBAL_GET("rendering/quality/driver/driver_name") == "GLES2") { context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2]; NSLog(@"Setting up an OpenGL ES 2.0 context."); if (!context) { diff --git a/platform/iphone/godot_iphone.cpp b/platform/iphone/godot_iphone.cpp index 992da2818b..8c3eddc5f7 100644 --- a/platform/iphone/godot_iphone.cpp +++ b/platform/iphone/godot_iphone.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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 aa4e1d4582..401a6cbeb8 100644 --- a/platform/iphone/icloud.h +++ b/platform/iphone/icloud.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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 c60db3d661..251f78f2da 100644 --- a/platform/iphone/icloud.mm +++ b/platform/iphone/icloud.mm @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -80,13 +80,13 @@ Variant nsobject_to_variant(NSObject *object) { const char *str = [(NSString *)object UTF8String]; return String::utf8(str != NULL ? str : ""); } else if ([object isKindOfClass:[NSData class]]) { - PoolByteArray ret; + PackedByteArray ret; NSData *data = (NSData *)object; if ([data length] > 0) { ret.resize([data length]); { - PoolByteArray::Write w = ret.write(); - copymem(w.ptr(), [data bytes], [data length]); + // PackedByteArray::Write w = ret.write(); + copymem((void *)ret.ptr(), [data bytes], [data length]); } } return ret; @@ -184,10 +184,10 @@ NSObject *variant_to_nsobject(Variant v) { [result addObject:value]; } return result; - } 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()]; + } else if (v.get_type() == Variant::PACKED_BYTE_ARRAY) { + PackedByteArray arr = v; + // PackedByteArray::Read r = arr.read(); + NSData *result = [NSData dataWithBytes:arr.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()); @@ -315,7 +315,7 @@ ICloud::ICloud() { Dictionary ret; ret["type"] = "key_value_changed"; - //PoolStringArray result_keys; + //PackedStringArray result_keys; //Array result_values; Dictionary keyValues; String reason = ""; diff --git a/platform/iphone/in_app_store.h b/platform/iphone/in_app_store.h index 7ed699c4f1..493877a5a7 100644 --- a/platform/iphone/in_app_store.h +++ b/platform/iphone/in_app_store.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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 8eef430621..a8a887824f 100644 --- a/platform/iphone/in_app_store.mm +++ b/platform/iphone/in_app_store.mm @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -85,12 +85,12 @@ void InAppStore::_bind_methods() { Dictionary ret; ret["type"] = "product_info"; ret["result"] = "ok"; - PoolStringArray titles; - PoolStringArray descriptions; - PoolRealArray prices; - PoolStringArray ids; - PoolStringArray localized_prices; - PoolStringArray currency_codes; + PackedStringArray titles; + PackedStringArray descriptions; + PackedFloat32Array prices; + PackedStringArray ids; + PackedStringArray localized_prices; + PackedStringArray currency_codes; for (NSUInteger i = 0; i < [products count]; i++) { @@ -113,7 +113,7 @@ void InAppStore::_bind_methods() { ret["localized_prices"] = localized_prices; ret["currency_codes"] = currency_codes; - PoolStringArray invalid_ids; + PackedStringArray invalid_ids; for (NSString *ipid in response.invalidProductIdentifiers) { @@ -133,7 +133,7 @@ Error InAppStore::request_product_info(Variant p_params) { Dictionary params = p_params; ERR_FAIL_COND_V(!params.has("product_ids"), ERR_INVALID_PARAMETER); - PoolStringArray pids = params["product_ids"]; + PackedStringArray pids = params["product_ids"]; printf("************ request product info! %i\n", pids.size()); NSMutableArray *array = [[[NSMutableArray alloc] initWithCapacity:pids.size()] autorelease]; diff --git a/platform/iphone/ios.h b/platform/iphone/ios.h index ef45fc7ac3..1378fdbbc5 100644 --- a/platform/iphone/ios.h +++ b/platform/iphone/ios.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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/ios.mm b/platform/iphone/ios.mm index 6e986df493..2656f125b9 100644 --- a/platform/iphone/ios.mm +++ b/platform/iphone/ios.mm @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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/main.m b/platform/iphone/main.m index e9f009eabe..164db2a74b 100644 --- a/platform/iphone/main.m +++ b/platform/iphone/main.m @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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/os_iphone.cpp b/platform/iphone/os_iphone.cpp index 83b0660ef7..db203ff2b3 100644 --- a/platform/iphone/os_iphone.cpp +++ b/platform/iphone/os_iphone.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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,8 +32,16 @@ #include "os_iphone.h" +#if defined(OPENGL_ENABLED) #include "drivers/gles2/rasterizer_gles2.h" -#include "drivers/gles3/rasterizer_gles3.h" +#endif + +#if defined(VULKAN_ENABLED) +#include "servers/visual/rasterizer_rd/rasterizer_rd.h" +// #import <QuartzCore/CAMetalLayer.h> +#include <vulkan/vulkan_metal.h> +#endif + #include "servers/visual/visual_server_raster.h" #include "servers/visual/visual_server_wrap_mt.h" @@ -57,8 +65,6 @@ int OSIPhone::get_video_driver_count() const { const char *OSIPhone::get_video_driver_name(int p_driver) const { switch (p_driver) { - case VIDEO_DRIVER_GLES3: - return "GLES3"; case VIDEO_DRIVER_GLES2: return "GLES2"; } @@ -103,69 +109,50 @@ int OSIPhone::get_current_video_driver() const { return video_driver_index; } -extern bool gles3_available; // from gl_view.mm - Error OSIPhone::initialize(const VideoMode &p_desired, int p_video_driver, int p_audio_driver) { + video_driver_index = p_video_driver; - bool use_gl3 = GLOBAL_GET("rendering/quality/driver/driver_name") == "GLES3"; +#if defined(OPENGL_ENABLED) bool gl_initialization_error = false; - while (true) { - if (use_gl3) { - if (RasterizerGLES3::is_viable() == OK && gles3_available) { - RasterizerGLES3::register_config(); - RasterizerGLES3::make_current(); - break; - } else { - if (GLOBAL_GET("rendering/quality/driver/fallback_to_gles2")) { - p_video_driver = VIDEO_DRIVER_GLES2; - use_gl3 = false; - continue; - } else { - gl_initialization_error = true; - break; - } - } - } else { - if (RasterizerGLES2::is_viable() == OK) { - RasterizerGLES2::register_config(); - RasterizerGLES2::make_current(); - break; - } else { - gl_initialization_error = true; - break; - } - } + // FIXME: Add Vulkan support via MoltenVK. Add fallback code back? + + if (RasterizerGLES2::is_viable() == OK) { + RasterizerGLES2::register_config(); + RasterizerGLES2::make_current(); + } else { + gl_initialization_error = true; } if (gl_initialization_error) { OS::get_singleton()->alert("Your device does not support any of the supported OpenGL versions.", - "Unable to initialize Video driver"); + "Unable to initialize video driver"); return ERR_UNAVAILABLE; } +#endif - video_driver_index = p_video_driver; +#if defined(VULKAN_ENABLED) + RasterizerRD::make_current(); +#endif + + visual_server = memnew(VisualServerRaster); // FIXME: Reimplement threaded rendering 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); +#if defined(OPENGL_ENABLED) // reset this to what it should be, it will have been set to 0 after visual_server->init() is called - if (use_gl3) - RasterizerStorageGLES3::system_fbo = gl_view_base_fb; - else - RasterizerStorageGLES2::system_fbo = gl_view_base_fb; + RasterizerStorageGLES2::system_fbo = gl_view_base_fb; +#endif AudioDriverManager::initialize(p_audio_driver); input = memnew(InputDefault); - camera_server = memnew(CameraIOS); - #ifdef GAME_CENTER_ENABLED game_center = memnew(GameCenter); Engine::get_singleton()->add_singleton(Engine::Singleton("GameCenter", game_center)); @@ -358,19 +345,32 @@ void OSIPhone::delete_main_loop() { void OSIPhone::finalize() { - if (main_loop) // should not happen? - memdelete(main_loop); + delete_main_loop(); - if (camera_server) { - memdelete(camera_server); - camera_server = NULL; - } + memdelete(input); + memdelete(ios); + +#ifdef GAME_CENTER_ENABLED + memdelete(game_center); +#endif + +#ifdef STOREKIT_ENABLED + memdelete(store_kit); +#endif + +#ifdef ICLOUD_ENABLED + memdelete(icloud); +#endif visual_server->finish(); memdelete(visual_server); // memdelete(rasterizer); - memdelete(input); + // Free unhandled events before close + for (int i = 0; i < MAX_EVENTS; i++) { + event_queue[i].unref(); + }; + event_count = 0; }; void OSIPhone::set_mouse_show(bool p_show){}; @@ -454,9 +454,10 @@ bool OSIPhone::can_draw() const { }; int OSIPhone::set_base_framebuffer(int p_fb) { - +#if defined(OPENGL_ENABLED) // gl_view_base_fb has not been updated yet - RasterizerStorageGLES3::system_fbo = p_fb; + RasterizerStorageGLES2::system_fbo = p_fb; +#endif return 0; }; @@ -471,7 +472,7 @@ extern Error _shell_open(String p_uri); extern void _set_keep_screen_on(bool p_enabled); extern void _vibrate(); -void OSIPhone::show_virtual_keyboard(const String &p_existing_text, const Rect2 &p_screen_rect) { +void OSIPhone::show_virtual_keyboard(const String &p_existing_text, const Rect2 &p_screen_rect, int p_max_input_length) { _show_keyboard(p_existing_text); }; diff --git a/platform/iphone/os_iphone.h b/platform/iphone/os_iphone.h index 63799bbae8..f42679e754 100644 --- a/platform/iphone/os_iphone.h +++ b/platform/iphone/os_iphone.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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 +37,6 @@ #include "drivers/coreaudio/audio_driver_coreaudio.h" #include "drivers/unix/os_unix.h" -#include "camera_ios.h" #include "game_center.h" #include "icloud.h" #include "in_app_store.h" @@ -47,6 +46,11 @@ #include "servers/visual/rasterizer.h" #include "servers/visual_server.h" +#if defined(VULKAN_ENABLED) +#include "drivers/vulkan/rendering_device_vulkan.h" +#include "platform/iphone/vulkan_context_iphone.h" +#endif + class OSIPhone : public OS_Unix { private: @@ -62,8 +66,6 @@ private: AudioDriverCoreAudio audio_driver; - CameraServer *camera_server; - #ifdef GAME_CENTER_ENABLED GameCenter *game_center; #endif @@ -77,6 +79,10 @@ private: MainLoop *main_loop; +#if defined(VULKAN_ENABLED) + VulkanContextIPhone *context_vulkan; + RenderingDeviceVulkan *rendering_device_vulkan; +#endif VideoMode video_mode; virtual int get_video_driver_count() const; @@ -168,7 +174,7 @@ public: virtual bool can_draw() const; virtual bool has_virtual_keyboard() const; - virtual void show_virtual_keyboard(const String &p_existing_text, const Rect2 &p_screen_rect = Rect2()); + virtual void show_virtual_keyboard(const String &p_existing_text, const Rect2 &p_screen_rect = Rect2(), int p_max_input_length = -1); virtual void hide_virtual_keyboard(); virtual int get_virtual_keyboard_height() const; diff --git a/platform/iphone/platform_config.h b/platform/iphone/platform_config.h index 1884e03403..bc190ba956 100644 --- a/platform/iphone/platform_config.h +++ b/platform/iphone/platform_config.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -31,7 +31,6 @@ #include <alloca.h> #define GLES2_INCLUDE_H <ES2/gl.h> -#define GLES3_INCLUDE_H <ES3/gl.h> #define PLATFORM_REFCOUNT diff --git a/platform/iphone/platform_refcount.h b/platform/iphone/platform_refcount.h index 56fd4e6e81..9029418462 100644 --- a/platform/iphone/platform_refcount.h +++ b/platform/iphone/platform_refcount.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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/semaphore_iphone.cpp b/platform/iphone/semaphore_iphone.cpp index cc7dde72f7..0461f58c40 100644 --- a/platform/iphone/semaphore_iphone.cpp +++ b/platform/iphone/semaphore_iphone.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -91,7 +91,7 @@ int SemaphoreIphone::get() const { return 0; } -Semaphore *SemaphoreIphone::create_semaphore_iphone() { +SemaphoreOld *SemaphoreIphone::create_semaphore_iphone() { return memnew(SemaphoreIphone); } diff --git a/platform/iphone/semaphore_iphone.h b/platform/iphone/semaphore_iphone.h index 16658384e6..54ff3c17f9 100644 --- a/platform/iphone/semaphore_iphone.h +++ b/platform/iphone/semaphore_iphone.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -39,11 +39,11 @@ typedef struct cgsem cgsem_t; #include "core/os/semaphore.h" -class SemaphoreIphone : public Semaphore { +class SemaphoreIphone : public SemaphoreOld { mutable cgsem_t sem; - static Semaphore *create_semaphore_iphone(); + static SemaphoreOld *create_semaphore_iphone(); public: virtual Error wait(); diff --git a/platform/iphone/view_controller.h b/platform/iphone/view_controller.h index 68e3bc64fc..f6bbe11d97 100644 --- a/platform/iphone/view_controller.h +++ b/platform/iphone/view_controller.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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,4 +45,6 @@ - (BOOL)prefersStatusBarHidden; +- (BOOL)prefersHomeIndicatorAutoHidden; + @end diff --git a/platform/iphone/view_controller.mm b/platform/iphone/view_controller.mm index e52ad92bf2..465e38e45e 100644 --- a/platform/iphone/view_controller.mm +++ b/platform/iphone/view_controller.mm @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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,6 +32,8 @@ #include "os_iphone.h" +#include "core/project_settings.h" + extern "C" { int add_path(int, char **); @@ -129,6 +131,14 @@ int add_cmdline(int p_argc, char **p_args) { return YES; } +- (BOOL)prefersHomeIndicatorAutoHidden { + if (GLOBAL_GET("display/window/ios/hide_home_indicator")) { + return YES; + } else { + return NO; + } +} + #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 diff --git a/platform/windows/camera_win.h b/platform/iphone/vulkan_context_iphone.h index 22ce9aa43f..200057e14d 100644 --- a/platform/windows/camera_win.h +++ b/platform/iphone/vulkan_context_iphone.h @@ -1,12 +1,12 @@ /*************************************************************************/ -/* camera_win.h */ +/* vulkan_context_osx.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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,19 +28,21 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef CAMERAWIN_H -#define CAMERAWIN_H +#ifndef VULKAN_CONTEXT_IPHONE_H +#define VULKAN_CONTEXT_IPHONE_H -#include "servers/camera/camera_feed.h" -#include "servers/camera_server.h" +#include "drivers/vulkan/vulkan_context.h" +// #import <UIKit/UIKit.h> -class CameraWindows : public CameraServer { -private: - void add_active_cameras(); +class VulkanContextIPhone : public VulkanContext { + + virtual const char *_get_platform_surface_extension() const; public: - CameraWindows(); - ~CameraWindows(); + int window_create(void *p_window, int p_width, int p_height); + + VulkanContextIPhone(); + ~VulkanContextIPhone(); }; -#endif /* CAMERAWIN_H */ +#endif // VULKAN_CONTEXT_IPHONE_H diff --git a/platform/osx/power_osx.h b/platform/iphone/vulkan_context_iphone.mm index 40d0d40fd4..f49b85c097 100644 --- a/platform/osx/power_osx.h +++ b/platform/iphone/vulkan_context_iphone.mm @@ -1,12 +1,12 @@ /*************************************************************************/ -/* power_osx.h */ +/* vulkan_context_osx.mm */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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,32 +28,29 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef POWER_OSX_H -#define POWER_OSX_H +#include "vulkan_context_iphone.h" +#include <vulkan/vulkan_ios.h> -#include "core/os/file_access.h" -#include "core/os/os.h" -#include "dir_access_osx.h" +const char *VulkanContextIPhone::_get_platform_surface_extension() const { + return VK_MVK_IOS_SURFACE_EXTENSION_NAME; +} -#include <CoreFoundation/CoreFoundation.h> +int VulkanContextIPhone::window_create(void *p_window, int p_width, int p_height) { -class PowerOSX { + VkIOSSurfaceCreateInfoMVK createInfo; + createInfo.sType = VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK; + createInfo.pNext = NULL; + createInfo.flags = 0; + createInfo.pView = p_window; -private: - int nsecs_left; - int percent_left; - OS::PowerState power_state; - void checkps(CFDictionaryRef dict, bool *have_ac, bool *have_battery, bool *charging); - bool GetPowerInfo_MacOSX(/*PowerState * state, int *seconds, int *percent*/); - bool UpdatePowerInfo(); + VkSurfaceKHR surface; + VkResult err = vkCreateIOSSurfaceMVK(_get_instance(), &createInfo, NULL, &surface); + ERR_FAIL_COND_V(err, -1); + return _window_create(surface, p_width, p_height); +} -public: - PowerOSX(); - virtual ~PowerOSX(); +VulkanContextIPhone::VulkanContextIPhone() { +} - OS::PowerState get_power_state(); - int get_power_seconds_left(); - int get_power_percent_left(); -}; - -#endif // POWER_OSX_H +VulkanContextIPhone::~VulkanContextIPhone() { +} diff --git a/platform/javascript/api/api.cpp b/platform/javascript/api/api.cpp index 0832ae0360..88de13d771 100644 --- a/platform/javascript/api/api.cpp +++ b/platform/javascript/api/api.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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/api/api.h b/platform/javascript/api/api.h index 52d87528f6..164d679205 100644 --- a/platform/javascript/api/api.h +++ b/platform/javascript/api/api.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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/api/javascript_eval.h b/platform/javascript/api/javascript_eval.h index 49e460fffd..29229de8e3 100644 --- a/platform/javascript/api/javascript_eval.h +++ b/platform/javascript/api/javascript_eval.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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.cpp b/platform/javascript/audio_driver_javascript.cpp index b359699d3a..f1bc7c4382 100644 --- a/platform/javascript/audio_driver_javascript.cpp +++ b/platform/javascript/audio_driver_javascript.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -63,7 +63,7 @@ void AudioDriverJavaScript::mix_to_js() { void AudioDriverJavaScript::process_capture(float sample) { int32_t sample32 = int32_t(sample * 32768.f) * (1U << 16); - capture_buffer_write(sample32); + input_buffer_write(sample32); } Error AudioDriverJavaScript::init() { @@ -198,7 +198,7 @@ void AudioDriverJavaScript::finish() { Error AudioDriverJavaScript::capture_start() { - capture_buffer_init(buffer_length); + input_buffer_init(buffer_length); /* clang-format off */ EM_ASM({ @@ -245,6 +245,8 @@ Error AudioDriverJavaScript::capture_stop() { }); /* clang-format on */ + input_buffer.clear(); + return OK; } diff --git a/platform/javascript/audio_driver_javascript.h b/platform/javascript/audio_driver_javascript.h index 9dcba02c96..2bb97ba192 100644 --- a/platform/javascript/audio_driver_javascript.h +++ b/platform/javascript/audio_driver_javascript.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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 172072db3c..1766833364 100644 --- a/platform/javascript/detect.py +++ b/platform/javascript/detect.py @@ -24,6 +24,7 @@ def get_opts(): def get_flags(): return [ ('tools', False), + ('builtin_pcre2_with_jit', False), # Disabling the mbedtls module reduces file size. # The module has little use due to the limited networking functionality # in this platform. For the available networking methods, the browser @@ -124,8 +125,24 @@ def configure(env): ## Link flags + # We use IDBFS in javascript_main.cpp. Since Emscripten 1.39.1 it needs to + # be linked explicitly. + env.Append(LIBS=['idbfs.js']) + env.Append(LINKFLAGS=['-s', 'BINARYEN=1']) + # Only include the JavaScript support code for the web environment + # (i.e. exclude Node.js and other unused environments). + # This makes the JavaScript support code about 4 KB smaller. + env.Append(LINKFLAGS=['-s', 'ENVIRONMENT=web']) + + # This needs to be defined for Emscripten using 'fastcomp' (default pre-1.39.0) + # and undefined if using 'upstream'. And to make things simple, earlier + # Emscripten versions didn't include 'fastcomp' in their path, so we check + # against the presence of 'upstream' to conditionally add the flag. + if not "upstream" in em_config['EMSCRIPTEN_ROOT']: + env.Append(LINKFLAGS=['-s', 'BINARYEN_TRAP_MODE=\'clamp\'']) + # Allow increasing memory buffer size during runtime. This is efficient # when using WebAssembly (in comparison to asm.js) and works well for # us since we don't know requirements at compile-time. diff --git a/platform/javascript/dom_keys.inc b/platform/javascript/dom_keys.inc index bf99ea5d42..25e88f99d1 100644 --- a/platform/javascript/dom_keys.inc +++ b/platform/javascript/dom_keys.inc @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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/engine.js b/platform/javascript/engine.js index 1f78aa672d..227accadb0 100644 --- a/platform/javascript/engine.js +++ b/platform/javascript/engine.js @@ -134,12 +134,10 @@ this.startGame = function(execName, mainPack) { executableName = execName; - var mainArgs = [ '--main-pack', mainPack ]; + var mainArgs = [ '--main-pack', getPathLeaf(mainPack) ]; return Promise.all([ - // Load from directory, - this.init(getBasePath(mainPack)), - // ...but write to root where the engine expects it. + this.init(getBasePath(execName)), this.preloadFile(mainPack, getPathLeaf(mainPack)) ]).then( Function.prototype.apply.bind(synchronousStart, this, mainArgs) diff --git a/platform/javascript/export/export.cpp b/platform/javascript/export/export.cpp index f3e8d6911a..c44a0270ab 100644 --- a/platform/javascript/export/export.cpp +++ b/platform/javascript/export/export.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -86,17 +86,28 @@ public: ERR_FAIL_COND_MSG(req[0] != "GET" || req[2] != "HTTP/1.1", "Invalid method or HTTP version."); String filepath = EditorSettings::get_singleton()->get_cache_dir().plus_file("tmp_js_export"); - String basereq = "/tmp_js_export"; + const String basereq = "/tmp_js_export"; + String ctype = ""; if (req[1] == basereq + ".html") { filepath += ".html"; + ctype = "text/html"; } else if (req[1] == basereq + ".js") { filepath += ".js"; + ctype = "application/javascript"; } else if (req[1] == basereq + ".pck") { filepath += ".pck"; - } else if (req[1] == basereq + ".png") { - filepath += ".png"; + ctype = "application/octet-stream"; + } else if (req[1] == basereq + ".png" || req[1] == "/favicon.png") { + // Also allow serving the generated favicon for a smoother loading experience. + if (req[1] == "/favicon.png") { + filepath = EditorSettings::get_singleton()->get_cache_dir().plus_file("favicon.png"); + } else { + filepath += ".png"; + } + ctype = "image/png"; } else if (req[1] == basereq + ".wasm") { filepath += ".wasm"; + ctype = "application/wasm"; } else { String s = "HTTP/1.1 404 Not Found\r\n"; s += "Connection: Close\r\n"; @@ -109,10 +120,14 @@ public: ERR_FAIL_COND(!f); String s = "HTTP/1.1 200 OK\r\n"; s += "Connection: Close\r\n"; + s += "Content-Type: " + ctype + "\r\n"; s += "\r\n"; CharString cs = s.utf8(); Error err = connection->put_data((const uint8_t *)cs.get_data(), cs.size() - 1); - ERR_FAIL_COND(err != OK); + if (err != OK) { + memdelete(f); + ERR_FAIL(); + } while (true) { uint8_t bytes[4096]; @@ -121,8 +136,12 @@ public: break; } err = connection->put_data(bytes, read); - ERR_FAIL_COND(err != OK); + if (err != OK) { + memdelete(f); + ERR_FAIL(); + } } + memdelete(f); } void poll() { @@ -193,7 +212,7 @@ public: virtual String get_name() const; virtual String get_os_name() const; - virtual Ref<Texture> get_logo() const; + virtual Ref<Texture2D> get_logo() const; virtual bool can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const; virtual List<String> get_binary_extensions(const Ref<EditorExportPreset> &p_preset) const; @@ -205,7 +224,7 @@ public: virtual String get_option_tooltip(int p_index) const { return p_index ? TTR("Stop HTTP Server") : TTR("Run exported HTML in the system's default browser."); } virtual Ref<ImageTexture> get_option_icon(int p_index) const; virtual Error run(const Ref<EditorExportPreset> &p_preset, int p_option, int p_debug_flags); - virtual Ref<Texture> get_run_icon() const; + virtual Ref<Texture2D> get_run_icon() const; virtual void get_platform_features(List<String> *r_features) { @@ -252,11 +271,9 @@ void EditorExportPlatformJavaScript::get_preset_features(const Ref<EditorExportP String driver = ProjectSettings::get_singleton()->get("rendering/quality/driver/driver_name"); if (driver == "GLES2") { r_features->push_back("etc"); - } else if (driver == "GLES3") { + } else if (driver == "Vulkan") { + // FIXME: Review if this is correct. r_features->push_back("etc2"); - if (ProjectSettings::get_singleton()->get("rendering/quality/driver/fallback_to_gles2")) { - r_features->push_back("etc"); - } } } } @@ -281,39 +298,39 @@ String EditorExportPlatformJavaScript::get_os_name() const { return "HTML5"; } -Ref<Texture> EditorExportPlatformJavaScript::get_logo() const { +Ref<Texture2D> EditorExportPlatformJavaScript::get_logo() const { return logo; } bool EditorExportPlatformJavaScript::can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const { - bool valid = false; String err; + bool valid = false; + + // Look for export templates (first official, and if defined custom templates). - if (find_export_template(EXPORT_TEMPLATE_WEBASSEMBLY_RELEASE) != "") - valid = true; - else if (find_export_template(EXPORT_TEMPLATE_WEBASSEMBLY_DEBUG) != "") - valid = true; + bool dvalid = exists_export_template(EXPORT_TEMPLATE_WEBASSEMBLY_DEBUG, &err); + bool rvalid = exists_export_template(EXPORT_TEMPLATE_WEBASSEMBLY_RELEASE, &err); if (p_preset->get("custom_template/debug") != "") { - if (FileAccess::exists(p_preset->get("custom_template/debug"))) { - valid = true; - } else { + dvalid = FileAccess::exists(p_preset->get("custom_template/debug")); + if (!dvalid) { err += TTR("Custom debug template not found.") + "\n"; } } - if (p_preset->get("custom_template/release") != "") { - if (FileAccess::exists(p_preset->get("custom_template/release"))) { - valid = true; - } else { + rvalid = FileAccess::exists(p_preset->get("custom_template/release")); + if (!rvalid) { err += TTR("Custom release template not found.") + "\n"; } } + valid = dvalid || rvalid; r_missing_templates = !valid; + // Validate the rest of the configuration. + if (p_preset->get("vram_texture_compression/for_mobile")) { String etc_error = test_etc2(); if (etc_error != String()) { @@ -456,11 +473,10 @@ Error EditorExportPlatformJavaScript::export_project(const Ref<EditorExportPrese } Ref<Image> splash; - String splash_path = GLOBAL_GET("application/boot_splash/image"); - splash_path = splash_path.strip_edges(); + const String splash_path = String(GLOBAL_GET("application/boot_splash/image")).strip_edges(); if (!splash_path.empty()) { splash.instance(); - Error err = splash->load(splash_path); + const Error err = splash->load(splash_path); if (err) { EditorNode::get_singleton()->show_warning(TTR("Could not read boot splash image file:") + "\n" + splash_path + "\n" + TTR("Using default boot splash image.")); splash.unref(); @@ -469,11 +485,32 @@ Error EditorExportPlatformJavaScript::export_project(const Ref<EditorExportPrese if (splash.is_null()) { splash = Ref<Image>(memnew(Image(boot_splash_png))); } - String png_path = p_path.get_base_dir().plus_file(p_path.get_file().get_basename() + ".png"); - if (splash->save_png(png_path) != OK) { - EditorNode::get_singleton()->show_warning(TTR("Could not write file:") + "\n" + png_path); + const String splash_png_path = p_path.get_base_dir().plus_file(p_path.get_file().get_basename() + ".png"); + if (splash->save_png(splash_png_path) != OK) { + EditorNode::get_singleton()->show_warning(TTR("Could not write file:") + "\n" + splash_png_path); return ERR_FILE_CANT_WRITE; } + + // Save a favicon that can be accessed without waiting for the project to finish loading. + // This way, the favicon can be displayed immediately when loading the page. + Ref<Image> favicon; + const String favicon_path = String(GLOBAL_GET("application/config/icon")).strip_edges(); + if (!favicon_path.empty()) { + favicon.instance(); + const Error err = favicon->load(favicon_path); + if (err) { + favicon.unref(); + } + } + + if (favicon.is_valid()) { + const String favicon_png_path = p_path.get_base_dir().plus_file("favicon.png"); + if (favicon->save_png(favicon_png_path) != OK) { + EditorNode::get_singleton()->show_warning(TTR("Could not write file:") + "\n" + favicon_png_path); + return ERR_FILE_CANT_WRITE; + } + } + return OK; } @@ -522,9 +559,8 @@ Error EditorExportPlatformJavaScript::run(const Ref<EditorExportPreset> &p_prese return OK; } - String basepath = EditorSettings::get_singleton()->get_cache_dir().plus_file("tmp_js_export"); - String path = basepath + ".html"; - Error err = export_project(p_preset, true, path, p_debug_flags); + const String basepath = EditorSettings::get_singleton()->get_cache_dir().plus_file("tmp_js_export"); + Error err = export_project(p_preset, true, basepath + ".html", p_debug_flags); if (err != OK) { // Export generates several files, clean them up on failure. DirAccess::remove_file_or_error(basepath + ".html"); @@ -532,13 +568,14 @@ Error EditorExportPlatformJavaScript::run(const Ref<EditorExportPreset> &p_prese DirAccess::remove_file_or_error(basepath + ".pck"); DirAccess::remove_file_or_error(basepath + ".png"); DirAccess::remove_file_or_error(basepath + ".wasm"); + DirAccess::remove_file_or_error(EditorSettings::get_singleton()->get_cache_dir().plus_file("favicon.png")); return err; } - IP_Address bind_ip; - uint16_t bind_port = EDITOR_GET("export/web/http_port"); + const uint16_t bind_port = EDITOR_GET("export/web/http_port"); // Resolve host if needed. - String bind_host = EDITOR_GET("export/web/http_host"); + const String bind_host = EDITOR_GET("export/web/http_host"); + IP_Address bind_ip; if (bind_host.is_valid_ip_address()) { bind_ip = bind_host; } else { @@ -559,7 +596,7 @@ Error EditorExportPlatformJavaScript::run(const Ref<EditorExportPreset> &p_prese return OK; } -Ref<Texture> EditorExportPlatformJavaScript::get_run_icon() const { +Ref<Texture2D> EditorExportPlatformJavaScript::get_run_icon() const { return run_icon; } diff --git a/platform/javascript/export/export.h b/platform/javascript/export/export.h index 7ebbcd6f00..30c5c855d1 100644 --- a/platform/javascript/export/export.h +++ b/platform/javascript/export/export.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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/http_client.h.inc b/platform/javascript/http_client.h.inc index c034069ab2..03e2ce8b8a 100644 --- a/platform/javascript/http_client.h.inc +++ b/platform/javascript/http_client.h.inc @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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/http_client_javascript.cpp b/platform/javascript/http_client_javascript.cpp index e6e933811f..d7796cc4f4 100644 --- a/platform/javascript/http_client_javascript.cpp +++ b/platform/javascript/http_client_javascript.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -103,12 +103,12 @@ Error HTTPClient::prepare_request(Method p_method, const String &p_url, const Ve return OK; } -Error HTTPClient::request_raw(Method p_method, const String &p_url, const Vector<String> &p_headers, const PoolVector<uint8_t> &p_body) { +Error HTTPClient::request_raw(Method p_method, const String &p_url, const Vector<String> &p_headers, const Vector<uint8_t> &p_body) { Error err = prepare_request(p_method, p_url, p_headers); if (err != OK) return err; - PoolByteArray::Read read = p_body.read(); + const uint8_t *read = p_body.ptr(); godot_xhr_send_data(xhr_id, read.ptr(), p_body.size()); return OK; } @@ -173,18 +173,18 @@ int HTTPClient::get_response_body_length() const { return polled_response.size(); } -PoolByteArray HTTPClient::read_response_body_chunk() { +PackedByteArray HTTPClient::read_response_body_chunk() { - ERR_FAIL_COND_V(status != STATUS_BODY, PoolByteArray()); + ERR_FAIL_COND_V(status != STATUS_BODY, PackedByteArray()); int to_read = MIN(read_limit, polled_response.size() - response_read_offset); - PoolByteArray chunk; + PackedByteArray chunk; chunk.resize(to_read); - PoolByteArray::Write write = chunk.write(); - PoolByteArray::Read read = polled_response.read(); + uint8_t *write = chunk.ptrw(); + const uint8_t *read = polled_response.ptr(); memcpy(write.ptr(), read.ptr() + response_read_offset, to_read); - write = PoolByteArray::Write(); - read = PoolByteArray::Read(); + write = uint8_t * (); + read = const uint8_t * (); response_read_offset += to_read; if (response_read_offset == polled_response.size()) { @@ -211,6 +211,10 @@ void HTTPClient::set_read_chunk_size(int p_size) { read_limit = p_size; } +int HTTPClient::get_read_chunk_size() const { + return read_limit; +} + Error HTTPClient::poll() { switch (status) { @@ -259,23 +263,23 @@ Error HTTPClient::poll() { status = STATUS_BODY; - PoolByteArray bytes; + PackedByteArray bytes; int len = godot_xhr_get_response_headers_length(xhr_id); bytes.resize(len + 1); - PoolByteArray::Write write = bytes.write(); + uint8_t *write = bytes.ptrw(); godot_xhr_get_response_headers(xhr_id, reinterpret_cast<char *>(write.ptr()), len); write[len] = 0; - write = PoolByteArray::Write(); + write = uint8_t * (); - PoolByteArray::Read read = bytes.read(); + const uint8_t *read = bytes.ptr(); polled_response_header = String::utf8(reinterpret_cast<const char *>(read.ptr())); - read = PoolByteArray::Read(); + read = const uint8_t * (); polled_response.resize(godot_xhr_get_response_length(xhr_id)); - write = polled_response.write(); + write = polled_response.ptrw(); godot_xhr_get_response(xhr_id, write.ptr(), polled_response.size()); - write = PoolByteArray::Write(); + write = uint8_t * (); break; } diff --git a/platform/javascript/http_request.h b/platform/javascript/http_request.h index 4a596057da..57dc4f0d9f 100644 --- a/platform/javascript/http_request.h +++ b/platform/javascript/http_request.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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/http_request.js b/platform/javascript/http_request.js index 66dacfc3d4..f621689f9d 100644 --- a/platform/javascript/http_request.js +++ b/platform/javascript/http_request.js @@ -3,9 +3,10 @@ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ -/* http://www.godotengine.org */ +/* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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/id_handler.js b/platform/javascript/id_handler.js index 36ef5aa8ef..3851123ed1 100644 --- a/platform/javascript/id_handler.js +++ b/platform/javascript/id_handler.js @@ -3,9 +3,10 @@ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ -/* http://www.godotengine.org */ +/* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2018 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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.cpp b/platform/javascript/javascript_eval.cpp index dd3eba74e4..44cce28d57 100644 --- a/platform/javascript/javascript_eval.cpp +++ b/platform/javascript/javascript_eval.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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,7 +33,7 @@ #include "api/javascript_eval.h" #include "emscripten.h" -extern "C" EMSCRIPTEN_KEEPALIVE uint8_t *resize_poolbytearray_and_open_write(PoolByteArray *p_arr, PoolByteArray::Write *r_write, int p_len) { +extern "C" EMSCRIPTEN_KEEPALIVE uint8_t *resize_PackedByteArray_and_open_write(PackedByteArray *p_arr, uint8_t **r_write, int p_len) { p_arr->resize(p_len); *r_write = p_arr->write(); @@ -48,8 +48,8 @@ Variant JavaScript::eval(const String &p_code, bool p_use_global_exec_context) { char *s; } js_data; - PoolByteArray arr; - PoolByteArray::Write arr_write; + PackedByteArray arr; + uint8_t *arr_write; /* clang-format off */ Variant::Type return_type = static_cast<Variant::Type>(EM_ASM_INT({ @@ -81,7 +81,7 @@ Variant JavaScript::eval(const String &p_code, bool p_use_global_exec_context) { case 'number': setValue(PTR, eval_ret, 'double'); - return 3; // REAL + return 3; // FLOAT case 'string': var array_len = lengthBytesUTF8(eval_ret)+1; @@ -114,9 +114,9 @@ Variant JavaScript::eval(const String &p_code, bool p_use_global_exec_context) { eval_ret = new Uint8Array(eval_ret); } if (eval_ret instanceof Uint8Array) { - var bytes_ptr = ccall('resize_poolbytearray_and_open_write', 'number', ['number', 'number' ,'number'], [BYTEARRAY_PTR, BYTEARRAY_WRITE_PTR, eval_ret.length]); + var bytes_ptr = ccall('resize_PackedByteArray_and_open_write', 'number', ['number', 'number' ,'number'], [BYTEARRAY_PTR, BYTEARRAY_WRITE_PTR, eval_ret.length]); HEAPU8.set(eval_ret, bytes_ptr); - return 20; // POOL_BYTE_ARRAY + return 20; // PACKED_BYTE_ARRAY } break; } @@ -128,7 +128,7 @@ Variant JavaScript::eval(const String &p_code, bool p_use_global_exec_context) { switch (return_type) { case Variant::BOOL: return js_data.b; - case Variant::REAL: + case Variant::FLOAT: return js_data.d; case Variant::STRING: { String str = String::utf8(js_data.s); @@ -137,8 +137,8 @@ Variant JavaScript::eval(const String &p_code, bool p_use_global_exec_context) { /* clang-format on */ return str; } - case Variant::POOL_BYTE_ARRAY: - arr_write = PoolByteArray::Write(); + case Variant::PACKED_BYTE_ARRAY: + arr_write = uint8_t * (); return arr; default: return Variant(); diff --git a/platform/javascript/javascript_main.cpp b/platform/javascript/javascript_main.cpp index bdf9dfe18f..815bc7e456 100644 --- a/platform/javascript/javascript_main.cpp +++ b/platform/javascript/javascript_main.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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/os_javascript.cpp b/platform/javascript/os_javascript.cpp index 652f6a1ce1..5acdc5f602 100644 --- a/platform/javascript/os_javascript.cpp +++ b/platform/javascript/os_javascript.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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,7 +32,6 @@ #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 "main/main.h" @@ -49,6 +48,7 @@ #define DOM_BUTTON_RIGHT 2 #define DOM_BUTTON_XBUTTON1 3 #define DOM_BUTTON_XBUTTON2 4 +#define GODOT_CANVAS_SELECTOR "#canvas" // Window (canvas) @@ -70,18 +70,23 @@ static bool is_canvas_focused() { /* clang-format on */ } -static Point2 correct_canvas_position(int x, int y) { +static Point2 compute_position_in_canvas(int x, int y) { + int canvas_x = EM_ASM_INT({ + return document.getElementById('canvas').getBoundingClientRect().x; + }); + int canvas_y = EM_ASM_INT({ + return document.getElementById('canvas').getBoundingClientRect().y; + }); int canvas_width; int canvas_height; - emscripten_get_canvas_element_size(NULL, &canvas_width, &canvas_height); + emscripten_get_canvas_element_size(GODOT_CANVAS_SELECTOR, &canvas_width, &canvas_height); double element_width; double element_height; - emscripten_get_element_css_size(NULL, &element_width, &element_height); + emscripten_get_element_css_size(GODOT_CANVAS_SELECTOR, &element_width, &element_height); - x = (int)(canvas_width / element_width * x); - y = (int)(canvas_height / element_height * y); - return Point2(x, y); + return Point2((int)(canvas_width / element_width * (x - canvas_x)), + (int)(canvas_height / element_height * (y - canvas_y))); } static bool cursor_inside_canvas = true; @@ -135,14 +140,14 @@ void OS_JavaScript::set_window_size(const Size2 p_size) { emscripten_exit_soft_fullscreen(); window_maximized = false; } - emscripten_set_canvas_element_size(NULL, p_size.x, p_size.y); + emscripten_set_canvas_element_size(GODOT_CANVAS_SELECTOR, p_size.x, p_size.y); } } Size2 OS_JavaScript::get_window_size() const { int canvas[2]; - emscripten_get_canvas_element_size(NULL, canvas, canvas + 1); + emscripten_get_canvas_element_size(GODOT_CANVAS_SELECTOR, canvas, canvas + 1); return Size2(canvas[0], canvas[1]); } @@ -162,7 +167,7 @@ void OS_JavaScript::set_window_maximized(bool p_enabled) { strategy.canvasResolutionScaleMode = EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_STDDEF; strategy.filteringMode = EMSCRIPTEN_FULLSCREEN_FILTERING_DEFAULT; strategy.canvasResizedCallback = NULL; - emscripten_enter_soft_fullscreen(NULL, &strategy); + emscripten_enter_soft_fullscreen(GODOT_CANVAS_SELECTOR, &strategy); window_maximized = p_enabled; } } @@ -191,7 +196,7 @@ void OS_JavaScript::set_window_fullscreen(bool p_enabled) { strategy.canvasResolutionScaleMode = EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_STDDEF; strategy.filteringMode = EMSCRIPTEN_FULLSCREEN_FILTERING_DEFAULT; strategy.canvasResizedCallback = NULL; - EMSCRIPTEN_RESULT result = emscripten_request_fullscreen_strategy(NULL, false, &strategy); + EMSCRIPTEN_RESULT result = emscripten_request_fullscreen_strategy(GODOT_CANVAS_SELECTOR, false, &strategy); ERR_FAIL_COND_MSG(result == EMSCRIPTEN_RESULT_FAILED_NOT_DEFERRED, "Enabling fullscreen is only possible from an input callback for the HTML5 platform."); ERR_FAIL_COND_MSG(result != EMSCRIPTEN_RESULT_SUCCESS, "Enabling fullscreen is only possible from an input callback for the HTML5 platform."); // Not fullscreen yet, so prevent "windowed" canvas dimensions from @@ -214,6 +219,20 @@ void OS_JavaScript::get_fullscreen_mode_list(List<VideoMode> *p_list, int p_scre p_list->push_back(OS::VideoMode(screen.width, screen.height, true)); } +bool OS_JavaScript::get_window_per_pixel_transparency_enabled() const { + if (!is_layered_allowed()) { + return false; + } + return transparency_enabled; +} + +void OS_JavaScript::set_window_per_pixel_transparency_enabled(bool p_enabled) { + if (!is_layered_allowed()) { + return; + } + transparency_enabled = p_enabled; +} + // Keys template <typename T> @@ -298,9 +317,10 @@ EM_BOOL OS_JavaScript::mouse_button_callback(int p_event_type, const EmscriptenM Ref<InputEventMouseButton> ev; ev.instance(); ev->set_pressed(p_event_type == EMSCRIPTEN_EVENT_MOUSEDOWN); - ev->set_position(correct_canvas_position(p_event->canvasX, p_event->canvasY)); + ev->set_position(compute_position_in_canvas(p_event->clientX, p_event->clientY)); ev->set_global_position(ev->get_position()); dom2godot_mod(p_event, ev); + switch (p_event->button) { case DOM_BUTTON_LEFT: ev->set_button_index(BUTTON_LEFT); break; case DOM_BUTTON_MIDDLE: ev->set_button_index(BUTTON_MIDDLE); break; @@ -312,7 +332,7 @@ EM_BOOL OS_JavaScript::mouse_button_callback(int p_event_type, const EmscriptenM if (ev->is_pressed()) { - uint64_t diff = p_event->timestamp - os->last_click_ms; + double diff = emscripten_get_now() - os->last_click_ms; if (ev->get_button_index() == os->last_click_button_index) { @@ -362,7 +382,7 @@ EM_BOOL OS_JavaScript::mousemove_callback(int p_event_type, const EmscriptenMous OS_JavaScript *os = get_singleton(); int input_mask = os->input->get_mouse_button_mask(); - Point2 pos = correct_canvas_position(p_event->canvasX, p_event->canvasY); + Point2 pos = compute_position_in_canvas(p_event->clientX, p_event->clientY); // For motion outside the canvas, only read mouse movement if dragging // started inside the canvas; imitating desktop app behaviour. if (!cursor_inside_canvas && !input_mask) @@ -459,7 +479,7 @@ void OS_JavaScript::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_s cursors_cache.erase(p_shape); } - Ref<Texture> texture = p_cursor; + Ref<Texture2D> texture = p_cursor; Ref<AtlasTexture> atlas_texture = p_cursor; Ref<Image> image; Size2 texture_size; @@ -516,17 +536,17 @@ void OS_JavaScript::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_s png_meta.height = texture_size.height; png_meta.format = PNG_FORMAT_RGBA; - PoolByteArray png; + PackedByteArray png; size_t len; - PoolByteArray::Read r = image->get_data().read(); + const uint8_t *r = image->get_data().ptr(); ERR_FAIL_COND(!png_image_write_get_memory_size(png_meta, len, 0, r.ptr(), 0, NULL)); png.resize(len); - PoolByteArray::Write w = png.write(); + uint8_t *w = png.ptrw(); ERR_FAIL_COND(!png_image_write_to_memory(&png_meta, w.ptr(), &len, 0, r.ptr(), 0, NULL)); - w = PoolByteArray::Write(); + w = uint8_t * (); - r = png.read(); + r = png.ptr(); char *object_url; /* clang-format off */ @@ -543,7 +563,7 @@ void OS_JavaScript::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_s stringToUTF8(url, string_on_wasm_heap, length_bytes); }, r.ptr(), len, &object_url); /* clang-format on */ - r = PoolByteArray::Read(); + r = const uint8_t * (); String url = String::utf8(object_url) + "?" + itos(p_hotspot.x) + " " + itos(p_hotspot.y); @@ -696,7 +716,7 @@ EM_BOOL OS_JavaScript::touch_press_callback(int p_event_type, const EmscriptenTo if (!touch.isChanged) continue; ev->set_index(touch.identifier); - ev->set_position(correct_canvas_position(touch.canvasX, touch.canvasY)); + ev->set_position(compute_position_in_canvas(touch.clientX, touch.clientY)); os->touches[i] = ev->get_position(); ev->set_pressed(p_event_type == EMSCRIPTEN_EVENT_TOUCHSTART); @@ -721,7 +741,7 @@ EM_BOOL OS_JavaScript::touchmove_callback(int p_event_type, const EmscriptenTouc if (!touch.isChanged) continue; ev->set_index(touch.identifier); - ev->set_position(correct_canvas_position(touch.canvasX, touch.canvasY)); + ev->set_position(compute_position_in_canvas(touch.clientX, touch.clientY)); Point2 &prev = os->touches[i]; ev->set_relative(ev->get_position() - prev); prev = ev->get_position(); @@ -804,8 +824,6 @@ int OS_JavaScript::get_video_driver_count() const { const char *OS_JavaScript::get_video_driver_name(int p_driver) const { switch (p_driver) { - case VIDEO_DRIVER_GLES3: - return "GLES3"; case VIDEO_DRIVER_GLES2: return "GLES2"; } @@ -879,56 +897,32 @@ Error OS_JavaScript::initialize(const VideoMode &p_desired, int p_video_driver, EmscriptenWebGLContextAttributes attributes; emscripten_webgl_init_context_attributes(&attributes); - attributes.alpha = false; + attributes.alpha = GLOBAL_GET("display/window/per_pixel_transparency/allowed"); attributes.antialias = false; ERR_FAIL_INDEX_V(p_video_driver, VIDEO_DRIVER_MAX, ERR_INVALID_PARAMETER); - bool gles3 = true; - if (p_video_driver == VIDEO_DRIVER_GLES2) { - gles3 = false; + if (p_desired.layered) { + set_window_per_pixel_transparency_enabled(true); } bool gl_initialization_error = false; - while (true) { - if (gles3) { - if (RasterizerGLES3::is_viable() == OK) { - attributes.majorVersion = 2; - RasterizerGLES3::register_config(); - RasterizerGLES3::make_current(); - break; - } else { - if (GLOBAL_GET("rendering/quality/driver/fallback_to_gles2")) { - p_video_driver = VIDEO_DRIVER_GLES2; - gles3 = false; - continue; - } else { - gl_initialization_error = true; - break; - } - } - } else { - if (RasterizerGLES2::is_viable() == OK) { - attributes.majorVersion = 1; - RasterizerGLES2::register_config(); - RasterizerGLES2::make_current(); - break; - } else { - gl_initialization_error = true; - break; - } - } + if (RasterizerGLES2::is_viable() == OK) { + attributes.majorVersion = 1; + RasterizerGLES2::register_config(); + RasterizerGLES2::make_current(); + } else { + gl_initialization_error = true; } - EMSCRIPTEN_WEBGL_CONTEXT_HANDLE ctx = emscripten_webgl_create_context(NULL, &attributes); + EMSCRIPTEN_WEBGL_CONTEXT_HANDLE ctx = emscripten_webgl_create_context(GODOT_CANVAS_SELECTOR, &attributes); if (emscripten_webgl_make_context_current(ctx) != EMSCRIPTEN_RESULT_SUCCESS) { gl_initialization_error = true; } if (gl_initialization_error) { - OS::get_singleton()->alert("Your browser does not support any of the supported WebGL versions.\n" - "Please update your browser version.", - "Unable to initialize Video driver"); + OS::get_singleton()->alert("Your browser does not seem to support WebGL. Please update your browser version.", + "Unable to initialize video driver"); return ERR_UNAVAILABLE; } @@ -970,12 +964,10 @@ Error OS_JavaScript::initialize(const VideoMode &p_desired, int p_video_driver, VisualServer *visual_server = memnew(VisualServerRaster()); input = memnew(InputDefault); - camera_server = memnew(CameraServer); - EMSCRIPTEN_RESULT result; #define EM_CHECK(ev) \ if (result != EMSCRIPTEN_RESULT_SUCCESS) \ - ERR_PRINTS("Error while setting " #ev " callback: Code " + itos(result)) + ERR_PRINT("Error while setting " #ev " callback: Code " + itos(result)); #define SET_EM_CALLBACK(target, ev, cb) \ result = emscripten_set_##ev##_callback(target, NULL, true, &cb); \ EM_CHECK(ev) @@ -985,21 +977,21 @@ Error OS_JavaScript::initialize(const VideoMode &p_desired, int p_video_driver, // These callbacks from Emscripten's html5.h suffice to access most // JavaScript APIs. For APIs that are not (sufficiently) exposed, EM_ASM // is used below. - SET_EM_CALLBACK("#window", mousemove, mousemove_callback) - SET_EM_CALLBACK("#canvas", mousedown, mouse_button_callback) - SET_EM_CALLBACK("#window", mouseup, mouse_button_callback) - SET_EM_CALLBACK("#window", wheel, wheel_callback) - SET_EM_CALLBACK("#window", touchstart, touch_press_callback) - SET_EM_CALLBACK("#window", touchmove, touchmove_callback) - SET_EM_CALLBACK("#window", touchend, touch_press_callback) - SET_EM_CALLBACK("#window", touchcancel, touch_press_callback) - SET_EM_CALLBACK("#canvas", keydown, keydown_callback) - SET_EM_CALLBACK("#canvas", keypress, keypress_callback) - SET_EM_CALLBACK("#canvas", keyup, keyup_callback) - SET_EM_CALLBACK(NULL, fullscreenchange, fullscreen_change_callback) + SET_EM_CALLBACK(EMSCRIPTEN_EVENT_TARGET_WINDOW, mousemove, mousemove_callback) + SET_EM_CALLBACK(GODOT_CANVAS_SELECTOR, mousedown, mouse_button_callback) + SET_EM_CALLBACK(EMSCRIPTEN_EVENT_TARGET_WINDOW, mouseup, mouse_button_callback) + SET_EM_CALLBACK(EMSCRIPTEN_EVENT_TARGET_WINDOW, wheel, wheel_callback) + SET_EM_CALLBACK(EMSCRIPTEN_EVENT_TARGET_WINDOW, touchstart, touch_press_callback) + SET_EM_CALLBACK(EMSCRIPTEN_EVENT_TARGET_WINDOW, touchmove, touchmove_callback) + SET_EM_CALLBACK(EMSCRIPTEN_EVENT_TARGET_WINDOW, touchend, touch_press_callback) + SET_EM_CALLBACK(EMSCRIPTEN_EVENT_TARGET_WINDOW, touchcancel, touch_press_callback) + SET_EM_CALLBACK(GODOT_CANVAS_SELECTOR, keydown, keydown_callback) + SET_EM_CALLBACK(GODOT_CANVAS_SELECTOR, keypress, keypress_callback) + SET_EM_CALLBACK(GODOT_CANVAS_SELECTOR, keyup, keyup_callback) + SET_EM_CALLBACK(EMSCRIPTEN_EVENT_TARGET_DOCUMENT, fullscreenchange, fullscreen_change_callback) SET_EM_CALLBACK_NOTARGET(gamepadconnected, gamepad_change_callback) SET_EM_CALLBACK_NOTARGET(gamepaddisconnected, gamepad_change_callback) -#undef SET_EM_CALLBACK_NODATA +#undef SET_EM_CALLBACK_NOTARGET #undef SET_EM_CALLBACK #undef EM_CHECK @@ -1080,15 +1072,15 @@ bool OS_JavaScript::main_loop_iterate() { strategy.canvasResolutionScaleMode = EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_STDDEF; strategy.filteringMode = EMSCRIPTEN_FULLSCREEN_FILTERING_DEFAULT; strategy.canvasResizedCallback = NULL; - emscripten_enter_soft_fullscreen(NULL, &strategy); + emscripten_enter_soft_fullscreen(GODOT_CANVAS_SELECTOR, &strategy); } else { - emscripten_set_canvas_element_size(NULL, windowed_size.width, windowed_size.height); + emscripten_set_canvas_element_size(GODOT_CANVAS_SELECTOR, windowed_size.width, windowed_size.height); } just_exited_fullscreen = false; } int canvas[2]; - emscripten_get_canvas_element_size(NULL, canvas, canvas + 1); + emscripten_get_canvas_element_size(GODOT_CANVAS_SELECTOR, canvas, canvas + 1); video_mode.width = canvas[0]; video_mode.height = canvas[1]; if (!window_maximized && !video_mode.fullscreen && !just_exited_fullscreen && !entering_fullscreen) { @@ -1106,7 +1098,6 @@ void OS_JavaScript::delete_main_loop() { void OS_JavaScript::finalize() { - memdelete(camera_server); memdelete(input); } @@ -1187,17 +1178,17 @@ void OS_JavaScript::set_icon(const Ref<Image> &p_icon) { png_meta.height = icon->get_height(); png_meta.format = PNG_FORMAT_RGBA; - PoolByteArray png; + PackedByteArray png; size_t len; - PoolByteArray::Read r = icon->get_data().read(); + const uint8_t *r = icon->get_data().ptr(); ERR_FAIL_COND(!png_image_write_get_memory_size(png_meta, len, 0, r.ptr(), 0, NULL)); png.resize(len); - PoolByteArray::Write w = png.write(); + uint8_t *w = png.ptrw(); ERR_FAIL_COND(!png_image_write_to_memory(&png_meta, w.ptr(), &len, 0, r.ptr(), 0, NULL)); - w = PoolByteArray::Write(); + w = uint8_t * (); - r = png.read(); + r = png.ptr(); /* clang-format off */ EM_ASM_ARGS({ var PNG_PTR = $0; @@ -1253,24 +1244,6 @@ String OS_JavaScript::get_resource_dir() const { return "/"; } -OS::PowerState OS_JavaScript::get_power_state() { - - WARN_PRINT("Power management is not supported for the HTML5 platform, defaulting to POWERSTATE_UNKNOWN"); - return OS::POWERSTATE_UNKNOWN; -} - -int OS_JavaScript::get_power_seconds_left() { - - WARN_PRINT("Power management is not supported for the HTML5 platform, defaulting to -1"); - return -1; -} - -int OS_JavaScript::get_power_percent_left() { - - WARN_PRINT("Power management is not supported for the HTML5 platform, defaulting to -1"); - return -1; -} - void OS_JavaScript::file_access_close_callback(const String &p_file, int p_flags) { OS_JavaScript *os = get_singleton(); @@ -1311,6 +1284,7 @@ OS_JavaScript::OS_JavaScript(int p_argc, char *p_argv[]) { window_maximized = false; entering_fullscreen = false; just_exited_fullscreen = false; + transparency_enabled = false; main_loop = NULL; diff --git a/platform/javascript/os_javascript.h b/platform/javascript/os_javascript.h index 10676c49f7..5319ea121c 100644 --- a/platform/javascript/os_javascript.h +++ b/platform/javascript/os_javascript.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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 +35,6 @@ #include "drivers/unix/os_unix.h" #include "main/input_default.h" #include "servers/audio_server.h" -#include "servers/camera_server.h" #include "servers/visual/rasterizer.h" #include <emscripten/html5.h> @@ -47,6 +46,7 @@ class OS_JavaScript : public OS_Unix { bool window_maximized; bool entering_fullscreen; bool just_exited_fullscreen; + bool transparency_enabled; InputDefault *input; Ref<InputEventKey> deferred_key_event; @@ -56,7 +56,7 @@ class OS_JavaScript : public OS_Unix { Point2 touches[32]; Point2i last_click_pos; - uint64_t last_click_ms; + double last_click_ms; int last_click_button_index; MainLoop *main_loop; @@ -67,8 +67,6 @@ class OS_JavaScript : public OS_Unix { int64_t sync_wait_time; int64_t last_sync_check_time; - CameraServer *camera_server; - static EM_BOOL fullscreen_change_callback(int p_event_type, const EmscriptenFullscreenChangeEvent *p_event, void *p_user_data); static EM_BOOL keydown_callback(int p_event_type, const EmscriptenKeyboardEvent *p_event, void *p_user_data); @@ -126,6 +124,9 @@ public: virtual void set_mouse_mode(MouseMode p_mode); virtual MouseMode get_mouse_mode() const; + virtual bool get_window_per_pixel_transparency_enabled() const; + virtual void set_window_per_pixel_transparency_enabled(bool p_enabled); + virtual bool has_touchscreen_ui_hint() const; virtual bool is_joy_known(int p_device); @@ -144,7 +145,7 @@ public: void run_async(); bool main_loop_iterate(); - virtual Error execute(const String &p_path, const List<String> &p_arguments, bool p_blocking, ProcessID *r_child_id = NULL, String *r_pipe = NULL, int *r_exitcode = NULL, bool read_stderr = false, Mutex *p_pipe_mutex = NULL); + virtual Error execute(const String &p_path, const List<String> &p_arguments, bool p_blocking = true, ProcessID *r_child_id = NULL, String *r_pipe = NULL, int *r_exitcode = NULL, bool read_stderr = false, Mutex *p_pipe_mutex = NULL); virtual Error kill(const ProcessID &p_pid); virtual int get_process_id() const; @@ -159,10 +160,6 @@ public: virtual String get_resource_dir() const; virtual String get_user_data_dir() const; - virtual OS::PowerState get_power_state(); - virtual int get_power_seconds_left(); - virtual int get_power_percent_left(); - void set_idb_available(bool p_idb_available); virtual bool is_userfs_persistent() const; diff --git a/platform/javascript/platform_config.h b/platform/javascript/platform_config.h index baba6325b3..e2200376d3 100644 --- a/platform/javascript/platform_config.h +++ b/platform/javascript/platform_config.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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/SCsub b/platform/osx/SCsub index 9620863b96..d764ac4b50 100644 --- a/platform/osx/SCsub +++ b/platform/osx/SCsub @@ -12,8 +12,8 @@ files = [ 'semaphore_osx.cpp', 'dir_access_osx.mm', 'joypad_osx.cpp', - 'power_osx.cpp', - 'camera_osx.mm', + 'vulkan_context_osx.mm', + 'context_gl_osx.mm' ] prog = env.add_program('#bin/godot', files) diff --git a/platform/osx/camera_osx.mm b/platform/osx/camera_osx.mm deleted file mode 100644 index af09eec2eb..0000000000 --- a/platform/osx/camera_osx.mm +++ /dev/null @@ -1,362 +0,0 @@ -/*************************************************************************/ -/* camera_osx.mm */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -///@TODO this is a near duplicate of CameraIOS, we should find a way to combine those to minimise code duplication!!!! -// If you fix something here, make sure you fix it there as wel! - -#include "camera_osx.h" -#include "servers/camera/camera_feed.h" -#import <AVFoundation/AVFoundation.h> - -////////////////////////////////////////////////////////////////////////// -// MyCaptureSession - This is a little helper class so we can capture our frames - -@interface MyCaptureSession : AVCaptureSession <AVCaptureVideoDataOutputSampleBufferDelegate> { - Ref<CameraFeed> feed; - size_t width[2]; - size_t height[2]; - PoolVector<uint8_t> img_data[2]; - - AVCaptureDeviceInput *input; - AVCaptureVideoDataOutput *output; -} - -@end - -@implementation MyCaptureSession - -- (id)initForFeed:(Ref<CameraFeed>)p_feed andDevice:(AVCaptureDevice *)p_device { - if (self = [super init]) { - NSError *error; - feed = p_feed; - width[0] = 0; - height[0] = 0; - width[1] = 0; - height[1] = 0; - - [self beginConfiguration]; - - input = [AVCaptureDeviceInput deviceInputWithDevice:p_device error:&error]; - if (!input) { - print_line("Couldn't get input device for camera"); - } else { - [self addInput:input]; - } - - output = [AVCaptureVideoDataOutput new]; - if (!output) { - print_line("Couldn't get output device for camera"); - } else { - NSDictionary *settings = @{ (NSString *)kCVPixelBufferPixelFormatTypeKey : @(kCVPixelFormatType_420YpCbCr8BiPlanarFullRange) }; - output.videoSettings = settings; - - // discard if the data output queue is blocked (as we process the still image) - [output setAlwaysDiscardsLateVideoFrames:YES]; - - // now set ourselves as the delegate to receive new frames. - [output setSampleBufferDelegate:self queue:dispatch_get_main_queue()]; - - // this takes ownership - [self addOutput:output]; - } - - [self commitConfiguration]; - - // kick off our session.. - [self startRunning]; - }; - return self; -} - -- (void)cleanup { - // stop running - [self stopRunning]; - - // cleanup - [self beginConfiguration]; - - // remove input - if (input) { - [self removeInput:input]; - // don't release this - input = NULL; - } - - // free up our output - if (output) { - [self removeOutput:output]; - [output setSampleBufferDelegate:nil queue:NULL]; - [output release]; - output = NULL; - } - - [self commitConfiguration]; -} - -- (void)dealloc { - // bye bye - [super dealloc]; -} - -- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection { - // This gets called every time our camera has a new image for us to process. - // May need to investigate in a way to throttle this if we get more images then we're rendering frames.. - - // For now, version 1, we're just doing the bare minimum to make this work... - CVImageBufferRef pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer); - // int _width = CVPixelBufferGetWidth(pixelBuffer); - // int _height = CVPixelBufferGetHeight(pixelBuffer); - - // It says that we need to lock this on the documentation pages but it's not in the samples - // need to lock our base address so we can access our pixel buffers, better safe then sorry? - CVPixelBufferLockBaseAddress(pixelBuffer, kCVPixelBufferLock_ReadOnly); - - // get our buffers - unsigned char *dataY = (unsigned char *)CVPixelBufferGetBaseAddressOfPlane(pixelBuffer, 0); - unsigned char *dataCbCr = (unsigned char *)CVPixelBufferGetBaseAddressOfPlane(pixelBuffer, 1); - if (dataY == NULL) { - print_line("Couldn't access Y pixel buffer data"); - } else if (dataCbCr == NULL) { - print_line("Couldn't access CbCr pixel buffer data"); - } else { - Ref<Image> img[2]; - - { - // do Y - size_t new_width = CVPixelBufferGetWidthOfPlane(pixelBuffer, 0); - size_t new_height = CVPixelBufferGetHeightOfPlane(pixelBuffer, 0); - - if ((width[0] != new_width) || (height[0] != new_height)) { - width[0] = new_width; - height[0] = new_height; - img_data[0].resize(new_width * new_height); - } - - PoolVector<uint8_t>::Write w = img_data[0].write(); - memcpy(w.ptr(), dataY, new_width * new_height); - - img[0].instance(); - img[0]->create(new_width, new_height, 0, Image::FORMAT_R8, img_data[0]); - } - - { - // do CbCr - size_t new_width = CVPixelBufferGetWidthOfPlane(pixelBuffer, 1); - size_t new_height = CVPixelBufferGetHeightOfPlane(pixelBuffer, 1); - - if ((width[1] != new_width) || (height[1] != new_height)) { - width[1] = new_width; - height[1] = new_height; - img_data[1].resize(2 * new_width * new_height); - } - - PoolVector<uint8_t>::Write w = img_data[1].write(); - memcpy(w.ptr(), dataCbCr, 2 * new_width * new_height); - - ///TODO GLES2 doesn't support FORMAT_RG8, need to do some form of conversion - img[1].instance(); - img[1]->create(new_width, new_height, 0, Image::FORMAT_RG8, img_data[1]); - } - - // set our texture... - feed->set_YCbCr_imgs(img[0], img[1]); - } - - // and unlock - CVPixelBufferUnlockBaseAddress(pixelBuffer, kCVPixelBufferLock_ReadOnly); -} - -@end - -////////////////////////////////////////////////////////////////////////// -// CameraFeedOSX - Subclass for camera feeds in OSX - -class CameraFeedOSX : public CameraFeed { -private: - AVCaptureDevice *device; - MyCaptureSession *capture_session; - -public: - AVCaptureDevice *get_device() const; - - CameraFeedOSX(); - ~CameraFeedOSX(); - - void set_device(AVCaptureDevice *p_device); - - bool activate_feed(); - void deactivate_feed(); -}; - -AVCaptureDevice *CameraFeedOSX::get_device() const { - return device; -}; - -CameraFeedOSX::CameraFeedOSX() { - device = NULL; - capture_session = NULL; -}; - -void CameraFeedOSX::set_device(AVCaptureDevice *p_device) { - device = p_device; - [device retain]; - - // get some info - NSString *device_name = p_device.localizedName; - name = device_name.UTF8String; - position = CameraFeed::FEED_UNSPECIFIED; - if ([p_device position] == AVCaptureDevicePositionBack) { - position = CameraFeed::FEED_BACK; - } else if ([p_device position] == AVCaptureDevicePositionFront) { - position = CameraFeed::FEED_FRONT; - }; -}; - -CameraFeedOSX::~CameraFeedOSX() { - if (capture_session != NULL) { - [capture_session release]; - capture_session = NULL; - }; - - if (device != NULL) { - [device release]; - device = NULL; - }; -}; - -bool CameraFeedOSX::activate_feed() { - if (capture_session) { - // already recording! - } else { - // start camera capture - capture_session = [[MyCaptureSession alloc] initForFeed:this andDevice:device]; - }; - - return true; -}; - -void CameraFeedOSX::deactivate_feed() { - // end camera capture if we have one - if (capture_session) { - [capture_session cleanup]; - [capture_session release]; - capture_session = NULL; - }; -}; - -////////////////////////////////////////////////////////////////////////// -// MyDeviceNotifications - This is a little helper class gets notifications -// when devices are connected/disconnected - -@interface MyDeviceNotifications : NSObject { - CameraOSX *camera_server; -} - -@end - -@implementation MyDeviceNotifications - -- (void)devices_changed:(NSNotification *)notification { - camera_server->update_feeds(); -} - -- (id)initForServer:(CameraOSX *)p_server { - if (self = [super init]) { - camera_server = p_server; - - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(devices_changed:) name:AVCaptureDeviceWasConnectedNotification object:nil]; - [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(devices_changed:) name:AVCaptureDeviceWasDisconnectedNotification object:nil]; - }; - return self; -} - -- (void)dealloc { - // remove notifications - [[NSNotificationCenter defaultCenter] removeObserver:self name:AVCaptureDeviceWasConnectedNotification object:nil]; - [[NSNotificationCenter defaultCenter] removeObserver:self name:AVCaptureDeviceWasDisconnectedNotification object:nil]; - - [super dealloc]; -} - -@end - -MyDeviceNotifications *device_notifications = nil; - -////////////////////////////////////////////////////////////////////////// -// CameraOSX - Subclass for our camera server on OSX - -void CameraOSX::update_feeds() { - NSArray *devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo]; - - // remove devices that are gone.. - for (int i = feeds.size() - 1; i >= 0; i--) { - Ref<CameraFeedOSX> feed = (Ref<CameraFeedOSX>)feeds[i]; - - if (![devices containsObject:feed->get_device()]) { - // remove it from our array, this will also destroy it ;) - remove_feed(feed); - }; - }; - - // add new devices.. - for (AVCaptureDevice *device in devices) { - bool found = false; - for (int i = 0; i < feeds.size() && !found; i++) { - Ref<CameraFeedOSX> feed = (Ref<CameraFeedOSX>)feeds[i]; - if (feed->get_device() == device) { - found = true; - }; - }; - - if (!found) { - Ref<CameraFeedOSX> newfeed; - newfeed.instance(); - newfeed->set_device(device); - - // assume display camera so inverse - Transform2D transform = Transform2D(-1.0, 0.0, 0.0, -1.0, 1.0, 1.0); - newfeed->set_transform(transform); - - add_feed(newfeed); - }; - }; -}; - -CameraOSX::CameraOSX() { - // Find available cameras we have at this time - update_feeds(); - - // should only have one of these.... - device_notifications = [[MyDeviceNotifications alloc] initForServer:this]; -}; - -CameraOSX::~CameraOSX() { - [device_notifications release]; -}; diff --git a/platform/windows/power_windows.h b/platform/osx/context_gl_osx.h index ef75ce6271..6e73c2203a 100644 --- a/platform/windows/power_windows.h +++ b/platform/osx/context_gl_osx.h @@ -1,12 +1,12 @@ /*************************************************************************/ -/* power_windows.h */ +/* context_gl_osx.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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,31 +28,48 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef POWER_WINDOWS_H -#define POWER_WINDOWS_H +#ifndef CONTEXT_GL_OSX_H +#define CONTEXT_GL_OSX_H -#include "core/os/dir_access.h" -#include "core/os/file_access.h" +#if defined(OPENGL_ENABLED) || defined(GLES_ENABLED) + +#include "core/error_list.h" #include "core/os/os.h" -#include <windows.h> +#include <AppKit/AppKit.h> +#include <ApplicationServices/ApplicationServices.h> +#include <CoreVideo/CoreVideo.h> -class PowerWindows { +class ContextGL_OSX { -private: - int nsecs_left; - int percent_left; - OS::PowerState power_state; + bool opengl_3_context; + bool use_vsync; - bool GetPowerInfo_Windows(); + void *framework; + id window_view; + NSOpenGLPixelFormat *pixelFormat; + NSOpenGLContext *context; public: - PowerWindows(); - virtual ~PowerWindows(); + void release_current(); + + void make_current(); + void update(); + + void set_opacity(GLint p_opacity); + + int get_window_width(); + int get_window_height(); + void swap_buffers(); + + Error initialize(); + + void set_use_vsync(bool p_use); + bool is_using_vsync() const; - OS::PowerState get_power_state(); - int get_power_seconds_left(); - int get_power_percent_left(); + ContextGL_OSX(id p_view, bool p_opengl_3_context); + ~ContextGL_OSX(); }; -#endif // POWER_WINDOWS_H +#endif +#endif
\ No newline at end of file diff --git a/platform/osx/context_gl_osx.mm b/platform/osx/context_gl_osx.mm new file mode 100644 index 0000000000..91d1332d24 --- /dev/null +++ b/platform/osx/context_gl_osx.mm @@ -0,0 +1,172 @@ +/*************************************************************************/ +/* context_gl_osx.mm */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "context_gl_osx.h" + +#if defined(OPENGL_ENABLED) || defined(GLES_ENABLED) + +void ContextGL_OSX::release_current() { + + [NSOpenGLContext clearCurrentContext]; +} + +void ContextGL_OSX::make_current() { + + [context makeCurrentContext]; +} + +void ContextGL_OSX::update() { + + [context update]; +} + +void ContextGL_OSX::set_opacity(GLint p_opacity) { + + [context setValues:&p_opacity forParameter:NSOpenGLCPSurfaceOpacity]; +} + +int ContextGL_OSX::get_window_width() { + + return OS::get_singleton()->get_video_mode().width; +} + +int ContextGL_OSX::get_window_height() { + + return OS::get_singleton()->get_video_mode().height; +} + +void ContextGL_OSX::swap_buffers() { + + [context flushBuffer]; +} + +void ContextGL_OSX::set_use_vsync(bool p_use) { + + CGLContextObj ctx = CGLGetCurrentContext(); + if (ctx) { + GLint swapInterval = p_use ? 1 : 0; + CGLSetParameter(ctx, kCGLCPSwapInterval, &swapInterval); + use_vsync = p_use; + } +} + +bool ContextGL_OSX::is_using_vsync() const { + + return use_vsync; +} + +Error ContextGL_OSX::initialize() { + + framework = CFBundleGetBundleWithIdentifier(CFSTR("com.apple.opengl")); + ERR_FAIL_COND_V(!framework, ERR_CANT_CREATE); + + unsigned int attributeCount = 0; + + // OS X needs non-zero color size, so set reasonable values + int colorBits = 32; + + // 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); \ + } + + // Arbitrary array size here + NSOpenGLPixelFormatAttribute attributes[40]; + + ADD_ATTR(NSOpenGLPFADoubleBuffer); + ADD_ATTR(NSOpenGLPFAClosestPolicy); + + if (!opengl_3_context) { + ADD_ATTR2(NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersionLegacy); + } else { + //we now need OpenGL 3 or better, maybe even change this to 3_3Core ? + ADD_ATTR2(NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core); + } + + ADD_ATTR2(NSOpenGLPFAColorSize, colorBits); + + /* + 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->samples > 0) { + ADD_ATTR2(NSOpenGLPFASampleBuffers, 1); + ADD_ATTR2(NSOpenGLPFASamples, fbconfig->samples); + } +*/ + + // NOTE: All NSOpenGLPixelFormats on the relevant cards support sRGB + // framebuffer, so there's no need (and no way) to request it + + ADD_ATTR(0); + +#undef ADD_ATTR +#undef ADD_ATTR2 + + pixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:attributes]; + ERR_FAIL_COND_V(pixelFormat == nil, ERR_CANT_CREATE); + + context = [[NSOpenGLContext alloc] initWithFormat:pixelFormat shareContext:nil]; + + ERR_FAIL_COND_V(context == nil, ERR_CANT_CREATE); + + [context setView:window_view]; + + [context makeCurrentContext]; + + return OK; +} + +ContextGL_OSX::ContextGL_OSX(id p_view, bool p_opengl_3_context) { + + opengl_3_context = p_opengl_3_context; + window_view = p_view; + use_vsync = false; +} + +ContextGL_OSX::~ContextGL_OSX() {} + +#endif diff --git a/platform/osx/crash_handler_osx.h b/platform/osx/crash_handler_osx.h index 6a72ce8ae9..abd9812596 100644 --- a/platform/osx/crash_handler_osx.h +++ b/platform/osx/crash_handler_osx.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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/crash_handler_osx.mm b/platform/osx/crash_handler_osx.mm index 015859b3c0..5da0118686 100644 --- a/platform/osx/crash_handler_osx.mm +++ b/platform/osx/crash_handler_osx.mm @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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/detect.py b/platform/osx/detect.py index 7882253e7a..12ca5c10dc 100644 --- a/platform/osx/detect.py +++ b/platform/osx/detect.py @@ -1,5 +1,6 @@ import os import sys +import subprocess from methods import detect_darwin_sdk_path @@ -25,8 +26,12 @@ def get_opts(): return [ ('osxcross_sdk', 'OSXCross SDK version', 'darwin14'), ('MACOS_SDK_PATH', 'Path to the macOS SDK', ''), + BoolVariable('use_static_mvk', 'Link MoltenVK statically as Level-0 driver (better portability) or use Vulkan ICD loader (enables validation layers)', False), EnumVariable('debug_symbols', 'Add debugging symbols to release builds', 'yes', ('yes', 'no', 'full')), BoolVariable('separate_debug_symbols', 'Create a separate file containing debugging symbols', False), + BoolVariable('use_ubsan', 'Use LLVM/GCC compiler undefined behavior sanitizer (UBSAN)', False), + BoolVariable('use_asan', 'Use LLVM/GCC compiler address sanitizer (ASAN))', False), + BoolVariable('use_tsan', 'Use LLVM/GCC compiler thread sanitizer (TSAN))', False), ] @@ -122,6 +127,21 @@ def configure(env): env["CC"] = "clang" env["LINK"] = "clang++" + if env['use_ubsan'] or env['use_asan'] or env['use_tsan']: + env.extra_suffix += "s" + + if env['use_ubsan']: + env.Append(CCFLAGS=['-fsanitize=undefined']) + env.Append(LINKFLAGS=['-fsanitize=undefined']) + + if env['use_asan']: + env.Append(CCFLAGS=['-fsanitize=address']) + env.Append(LINKFLAGS=['-fsanitize=address']) + + if env['use_tsan']: + env.Append(CCFLAGS=['-fsanitize=thread']) + env.Append(LINKFLAGS=['-fsanitize=thread']) + ## Dependencies if env['builtin_libtheora']: @@ -130,9 +150,19 @@ def configure(env): ## Flags env.Prepend(CPPPATH=['#platform/osx']) - env.Append(CPPDEFINES=['OSX_ENABLED', 'UNIX_ENABLED', 'GLES_ENABLED', 'APPLE_STYLE_KEYS', 'COREAUDIO_ENABLED', 'COREMIDI_ENABLED']) - env.Append(LINKFLAGS=['-framework', 'Cocoa', '-framework', 'Carbon', '-framework', 'OpenGL', '-framework', 'AGL', '-framework', 'AudioUnit', '-framework', 'CoreAudio', '-framework', 'CoreMIDI', '-lz', '-framework', 'IOKit', '-framework', 'ForceFeedback', '-framework', 'AVFoundation', '-framework', 'CoreMedia', '-framework', 'CoreVideo']) - env.Append(LIBS=['pthread']) - - env.Append(CCFLAGS=['-mmacosx-version-min=10.9']) - env.Append(LINKFLAGS=['-mmacosx-version-min=10.9']) + env.Append(CPPDEFINES=['OSX_ENABLED', 'UNIX_ENABLED', 'APPLE_STYLE_KEYS', 'COREAUDIO_ENABLED', 'COREMIDI_ENABLED']) + env.Append(LINKFLAGS=['-framework', 'Cocoa', '-framework', 'Carbon', '-framework', 'AudioUnit', '-framework', 'CoreAudio', '-framework', 'CoreMIDI', '-framework', 'IOKit', '-framework', 'ForceFeedback', '-framework', 'CoreVideo', '-framework', 'AVFoundation', '-framework', 'CoreMedia']) + env.Append(LIBS=['pthread', 'z']) + + env.Append(CPPDEFINES=['VULKAN_ENABLED']) + env.Append(LINKFLAGS=['-framework', 'Metal', '-framework', 'QuartzCore', '-framework', 'IOSurface']) + if (env['use_static_mvk']): + env.Append(LINKFLAGS=['-framework', 'MoltenVK']) + env['builtin_vulkan'] = False + elif not env['builtin_vulkan']: + env.Append(LIBS=['vulkan']) + + #env.Append(CPPDEFINES=['GLES_ENABLED', 'OPENGL_ENABLED']) + + env.Append(CCFLAGS=['-mmacosx-version-min=10.12']) + env.Append(LINKFLAGS=['-mmacosx-version-min=10.12']) diff --git a/platform/osx/dir_access_osx.h b/platform/osx/dir_access_osx.h index c5951a570e..d61ee181f0 100644 --- a/platform/osx/dir_access_osx.h +++ b/platform/osx/dir_access_osx.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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 75f50aaa28..66ea380903 100644 --- a/platform/osx/dir_access_osx.mm +++ b/platform/osx/dir_access_osx.mm @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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/export/export.cpp b/platform/osx/export/export.cpp index 9226aea369..dbe52da912 100644 --- a/platform/osx/export/export.cpp +++ b/platform/osx/export/export.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -74,7 +74,7 @@ protected: public: virtual String get_name() const { return "Mac OSX"; } virtual String get_os_name() const { return "OSX"; } - virtual Ref<Texture> get_logo() const { return logo; } + virtual Ref<Texture2D> get_logo() const { return logo; } virtual List<String> get_binary_extensions(const Ref<EditorExportPreset> &p_preset) const { List<String> list; @@ -118,8 +118,8 @@ void EditorExportPlatformOSX::get_preset_features(const Ref<EditorExportPreset> 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, "custom_template/debug", PROPERTY_HINT_GLOBAL_FILE, "*.zip"), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "custom_template/release", PROPERTY_HINT_GLOBAL_FILE, "*.zip"), "")); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/name", PROPERTY_HINT_PLACEHOLDER_TEXT, "Game Name"), "")); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/info"), "Made with Godot Engine")); @@ -130,6 +130,8 @@ void EditorExportPlatformOSX::get_export_options(List<ExportOption> *r_options) 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::BOOL, "display/high_res"), false)); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "privacy/camera_usage_description", PROPERTY_HINT_PLACEHOLDER_TEXT, "Provide a message if you need to use the camera"), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "privacy/microphone_usage_description", PROPERTY_HINT_PLACEHOLDER_TEXT, "Provide a message if you need to use the microphone"), "")); #ifdef OSX_ENABLED r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "codesign/enable"), false)); @@ -137,7 +139,7 @@ void EditorExportPlatformOSX::get_export_options(List<ExportOption> *r_options) r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "codesign/timestamp"), true)); r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "codesign/hardened_runtime"), true)); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "codesign/entitlements", PROPERTY_HINT_GLOBAL_FILE, "*.plist"), "")); - r_options->push_back(ExportOption(PropertyInfo(Variant::POOL_STRING_ARRAY, "codesign/custom_options"), PoolStringArray())); + r_options->push_back(ExportOption(PropertyInfo(Variant::PACKED_STRING_ARRAY, "codesign/custom_options"), PackedStringArray())); #endif r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "texture_format/s3tc"), true)); @@ -145,7 +147,7 @@ void EditorExportPlatformOSX::get_export_options(List<ExportOption> *r_options) r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "texture_format/etc2"), false)); } -void _rgba8_to_packbits_encode(int p_ch, int p_size, PoolVector<uint8_t> &p_source, Vector<uint8_t> &p_dest) { +void _rgba8_to_packbits_encode(int p_ch, int p_size, Vector<uint8_t> &p_source, Vector<uint8_t> &p_dest) { int src_len = p_size * p_size; @@ -158,11 +160,11 @@ void _rgba8_to_packbits_encode(int p_ch, int p_size, PoolVector<uint8_t> &p_sour int i = 0; while (i < src_len) { - uint8_t cur = p_source.read()[i * 4 + p_ch]; + uint8_t cur = p_source.ptr()[i * 4 + p_ch]; if (i < src_len - 2) { - if ((p_source.read()[(i + 1) * 4 + p_ch] == cur) && (p_source.read()[(i + 2) * 4 + p_ch] == cur)) { + if ((p_source.ptr()[(i + 1) * 4 + p_ch] == cur) && (p_source.ptr()[(i + 2) * 4 + p_ch] == cur)) { if (buf_size > 0) { result.write[res_size++] = (uint8_t)(buf_size - 1); copymem(&result.write[res_size], &buf, buf_size); @@ -174,7 +176,7 @@ void _rgba8_to_packbits_encode(int p_ch, int p_size, PoolVector<uint8_t> &p_sour bool hit_lim = true; for (int j = 3; j <= lim; j++) { - if (p_source.read()[(i + j) * 4 + p_ch] != cur) { + if (p_source.ptr()[(i + j) * 4 + p_ch] != cur) { hit_lim = false; i = i + j - 1; result.write[res_size++] = (uint8_t)(j - 3 + 0x80); @@ -276,7 +278,7 @@ void EditorExportPlatformOSX::_make_icon(const Ref<Image> &p_icon, Vector<uint8_ DirAccess::remove_file_or_error(path); } else { - PoolVector<uint8_t> src_data = copy->get_data(); + Vector<uint8_t> src_data = copy->get_data(); //encode 24bit RGB RLE icon { @@ -300,7 +302,7 @@ void EditorExportPlatformOSX::_make_icon(const Ref<Image> &p_icon, Vector<uint8_ data.resize(data.size() + len + 8); for (int j = 0; j < len; j++) { - data.write[ofs + 8 + j] = src_data.read()[j * 4 + 3]; + data.write[ofs + 8 + j] = src_data.ptr()[j * 4 + 3]; } len += 8; len = BSWAP32(len); @@ -342,6 +344,12 @@ void EditorExportPlatformOSX::_fix_plist(const Ref<EditorExportPreset> &p_preset 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 if (lines[i].find("$camera_usage_description") != -1) { + String description = p_preset->get("privacy/camera_usage_description"); + strnew += lines[i].replace("$camera_usage_description", description) + "\n"; + } else if (lines[i].find("$microphone_usage_description") != -1) { + String description = p_preset->get("privacy/microphone_usage_description"); + strnew += lines[i].replace("$microphone_usage_description", description) + "\n"; } else { strnew += lines[i] + "\n"; } @@ -378,7 +386,7 @@ Error EditorExportPlatformOSX::_code_sign(const Ref<EditorExportPreset> &p_prese args.push_back(p_preset->get("codesign/entitlements")); } - PoolStringArray user_args = p_preset->get("codesign/custom_options"); + PackedStringArray user_args = p_preset->get("codesign/custom_options"); for (int i = 0; i < user_args.size(); i++) { String user_arg = user_args[i].strip_edges(); if (!user_arg.empty()) { @@ -451,9 +459,9 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p EditorProgress ep("export", "Exporting for OSX", 3, true); if (p_debug) - src_pkg_name = p_preset->get("custom_package/debug"); + src_pkg_name = p_preset->get("custom_template/debug"); else - src_pkg_name = p_preset->get("custom_package/release"); + src_pkg_name = p_preset->get("custom_template/release"); if (src_pkg_name == "") { String err; @@ -494,6 +502,8 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p else pkg_name = "Unnamed"; + String pkg_name_safe = OS::get_singleton()->get_safe_dir_name(pkg_name); + Error err = OK; String tmp_app_path_name = ""; zlib_filefunc_def io2 = io; @@ -501,12 +511,13 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p io2.opaque = &dst_f; zipFile dst_pkg_zip = NULL; + DirAccess *tmp_app_path = NULL; String export_format = use_dmg() && p_path.ends_with("dmg") ? "dmg" : "zip"; if (export_format == "dmg") { // We're on OSX so we can export to DMG, but first we create our application bundle tmp_app_path_name = EditorSettings::get_singleton()->get_cache_dir().plus_file(pkg_name + ".app"); print_line("Exporting to " + tmp_app_path_name); - DirAccess *tmp_app_path = DirAccess::create_for_path(tmp_app_path_name); + tmp_app_path = DirAccess::create_for_path(tmp_app_path_name); if (!tmp_app_path) { err = ERR_CANT_CREATE; } @@ -603,25 +614,45 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p } if (data.size() > 0) { + + if (file.find("/data.mono.osx.64.release_debug/") != -1) { + if (!p_debug) { + ret = unzGoToNextFile(src_pkg_zip); + continue; //skip + } + file = file.replace("/data.mono.osx.64.release_debug/", "/data_" + pkg_name_safe + "/"); + } + if (file.find("/data.mono.osx.64.release/") != -1) { + if (p_debug) { + ret = unzGoToNextFile(src_pkg_zip); + continue; //skip + } + file = file.replace("/data.mono.osx.64.release/", "/data_" + pkg_name_safe + "/"); + } + print_line("ADDING: " + file + " size: " + itos(data.size())); total_size += data.size(); if (export_format == "dmg") { // write it into our application bundle file = tmp_app_path_name.plus_file(file); - - // write the file, need to add chmod - FileAccess *f = FileAccess::open(file, FileAccess::WRITE); - if (f) { - f->store_buffer(data.ptr(), data.size()); - f->close(); - if (is_execute) { - // Chmod with 0755 if the file is executable - FileAccess::set_unix_permissions(file, 0755); + if (err == OK) { + err = tmp_app_path->make_dir_recursive(file.get_base_dir()); + } + if (err == OK) { + // write the file, need to add chmod + FileAccess *f = FileAccess::open(file, FileAccess::WRITE); + if (f) { + f->store_buffer(data.ptr(), data.size()); + f->close(); + if (is_execute) { + // Chmod with 0755 if the file is executable + FileAccess::set_unix_permissions(file, 0755); + } + memdelete(f); + } else { + err = ERR_CANT_CREATE; } - memdelete(f); - } else { - err = ERR_CANT_CREATE; } } else { // add it to our zip file @@ -661,7 +692,7 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p unzClose(src_pkg_zip); if (!found_binary) { - ERR_PRINTS("Requested template binary '" + binary_to_use + "' not found. It might be missing from your template archive."); + ERR_PRINT("Requested template binary '" + binary_to_use + "' not found. It might be missing from your template archive."); err = ERR_FILE_NOT_FOUND; } @@ -788,33 +819,32 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p bool EditorExportPlatformOSX::can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const { - bool valid = false; String err; + bool valid = false; - if (exists_export_template("osx.zip", &err)) { - valid = true; - } + // Look for export templates (first official, and if defined custom templates). - if (p_preset->get("custom_package/debug") != "") { - if (FileAccess::exists(p_preset->get("custom_package/debug"))) { - valid = true; - } else { + bool dvalid = exists_export_template("osx.zip", &err); + bool rvalid = dvalid; // Both in the same ZIP. + + if (p_preset->get("custom_template/debug") != "") { + dvalid = FileAccess::exists(p_preset->get("custom_template/debug")); + if (!dvalid) { err += TTR("Custom debug template not found.") + "\n"; } } - - if (p_preset->get("custom_package/release") != "") { - if (FileAccess::exists(p_preset->get("custom_package/release"))) { - valid = true; - } else { + if (p_preset->get("custom_template/release") != "") { + rvalid = FileAccess::exists(p_preset->get("custom_template/release")); + if (!rvalid) { err += TTR("Custom release template not found.") + "\n"; } } + valid = dvalid || rvalid; + r_missing_templates = !valid; + if (!err.empty()) r_error = err; - - r_missing_templates = !valid; return valid; } diff --git a/platform/osx/export/export.h b/platform/osx/export/export.h index 7e7e697488..7b8832cb01 100644 --- a/platform/osx/export/export.h +++ b/platform/osx/export/export.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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 79364314aa..eacd2b5cc6 100644 --- a/platform/osx/godot_main_osx.mm +++ b/platform/osx/godot_main_osx.mm @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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,6 +36,12 @@ #include <unistd.h> int main(int argc, char **argv) { + +#if defined(VULKAN_ENABLED) + //MoltenVK - enable full component swizzling support + setenv("MVK_CONFIG_FULL_IMAGE_VIEW_SWIZZLE", "1", 1); +#endif + int first_arg = 1; const char *dbg_arg = "-NSDocumentRevisionsDebugMode"; printf("arguments\n"); @@ -45,35 +51,6 @@ int main(int argc, char **argv) { printf("%i: %s\n", i, argv[i]); }; - 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); - memcpy(path, argv[0], len); - path[len] = 0; - - 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"); - 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); - } - } - #ifdef DEBUG_ENABLED // lets report the path we made current after all that char cwd[4096]; diff --git a/platform/osx/joypad_osx.cpp b/platform/osx/joypad_osx.cpp index 4edf347f61..13ece678f3 100644 --- a/platform/osx/joypad_osx.cpp +++ b/platform/osx/joypad_osx.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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/joypad_osx.h b/platform/osx/joypad_osx.h index 255a674f09..388251016b 100644 --- a/platform/osx/joypad_osx.h +++ b/platform/osx/joypad_osx.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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/os_osx.h b/platform/osx/os_osx.h index 09a871f26c..75a56bd82c 100644 --- a/platform/osx/os_osx.h +++ b/platform/osx/os_osx.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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,7 +33,6 @@ #define BitMap _QDBitMap // Suppress deprecated QuickDraw definition. -#include "camera_osx.h" #include "core/os/input.h" #include "crash_handler_osx.h" #include "drivers/coreaudio/audio_driver_coreaudio.h" @@ -41,12 +40,20 @@ #include "drivers/unix/os_unix.h" #include "joypad_osx.h" #include "main/input_default.h" -#include "power_osx.h" #include "servers/audio_server.h" #include "servers/visual/rasterizer.h" #include "servers/visual/visual_server_wrap_mt.h" #include "servers/visual_server.h" +#if defined(OPENGL_ENABLED) +#include "context_gl_osx.h" +#endif + +#if defined(VULKAN_ENABLED) +#include "drivers/vulkan/rendering_device_vulkan.h" +#include "platform/osx/vulkan_context_osx.h" +#endif + #include <AppKit/AppKit.h> #include <AppKit/NSCursor.h> #include <ApplicationServices/ApplicationServices.h> @@ -70,17 +77,11 @@ public: int key_event_pos; bool force_quit; - // rasterizer seems to no longer be given to visual server, its using GLES3 directly? - //Rasterizer *rasterizer; VisualServer *visual_server; - CameraServer *camera_server; - List<String> args; MainLoop *main_loop; - IP_Unix *ip_unix; - #ifdef COREAUDIO_ENABLED AudioDriverCoreAudio audio_driver; #endif @@ -98,7 +99,6 @@ public: void process_events(); void process_key_events(); - void *framework; // pthread_key_t current; bool mouse_grab; Point2 mouse_pos; @@ -109,13 +109,17 @@ public: id window_view; id autoreleasePool; id cursor; - NSOpenGLPixelFormat *pixelFormat; - NSOpenGLContext *context; + +#if defined(OPENGL_ENABLED) + ContextGL_OSX *context_gles2; +#endif + +#if defined(VULKAN_ENABLED) + VulkanContextOSX *context_vulkan; + RenderingDeviceVulkan *rendering_device_vulkan; +#endif bool layered_window; - bool waiting_for_vsync; - NSCondition *vsync_condition; - CVDisplayLinkRef displayLink; CursorShape cursor_shape; NSCursor *cursors[CURSOR_MAX]; @@ -127,6 +131,7 @@ public: bool maximized; bool zoomed; bool resizable; + bool window_focused; Size2 window_size; Rect2 restore_rect; @@ -141,8 +146,6 @@ public: Size2 min_size; Size2 max_size; - PowerOSX *power_manager; - CrashHandler crash_handler; float _mouse_scale(float p_scale) { @@ -228,6 +231,7 @@ public: virtual String get_config_path() const; virtual String get_data_path() const; virtual String get_cache_path() const; + virtual String get_bundle_resource_dir() const; virtual String get_godot_dir_name() const; virtual String get_system_dir(SystemDir p_dir) const; @@ -280,6 +284,7 @@ public: virtual bool is_window_maximized() const; virtual void set_window_always_on_top(bool p_enabled); virtual bool is_window_always_on_top() const; + virtual bool is_window_focused() const; virtual void request_attention(); virtual String get_joy_guid(int p_device) const; @@ -296,10 +301,6 @@ public: virtual String get_unique_id() const; - virtual OS::PowerState get_power_state(); - virtual int get_power_seconds_left(); - virtual int get_power_percent_left(); - virtual bool _check_internal_feature_support(const String &p_feature); virtual void _set_use_vsync(bool p_enable); diff --git a/platform/osx/os_osx.mm b/platform/osx/os_osx.mm index ba3ac9862e..f2e5f9369c 100644 --- a/platform/osx/os_osx.mm +++ b/platform/osx/os_osx.mm @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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,11 +34,19 @@ #include "core/print_string.h" #include "core/version_generated.gen.h" #include "dir_access_osx.h" + +#if defined(OPENGL_ENABLED) #include "drivers/gles2/rasterizer_gles2.h" -#include "drivers/gles3/rasterizer_gles3.h" +#endif + +#if defined(VULKAN_ENABLED) +#include "servers/visual/rasterizer_rd/rasterizer_rd.h" +#endif + #include "main/main.h" #include "semaphore_osx.h" #include "servers/visual/visual_server_raster.h" +#include "servers/visual/visual_server_wrap_mt.h" #include <mach-o/dyld.h> @@ -52,6 +60,9 @@ #include <os/log.h> #endif +#import <QuartzCore/CAMetalLayer.h> +#include <vulkan/vulkan_metal.h> + #include <dlfcn.h> #include <fcntl.h> #include <libproc.h> @@ -115,19 +126,18 @@ static Vector2 get_mouse_pos(NSPoint locationInWindow, CGFloat backingScaleFacto return Vector2(mouse_x, mouse_y); } -// DisplayLinkCallback is called from our DisplayLink OS thread informing us right before -// a screen update is required. We can use it to work around the broken vsync. -static CVReturn DisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeStamp *now, const CVTimeStamp *outputTime, CVOptionFlags flagsIn, CVOptionFlags *flagsOut, void *displayLinkContext) { - OS_OSX *os = (OS_OSX *)displayLinkContext; - - // Set flag so we know we can output our next frame and signal our conditional lock - // if we're not doing vsync this will be ignored - [os->vsync_condition lock]; - os->waiting_for_vsync = false; - [os->vsync_condition signal]; - [os->vsync_condition unlock]; - - return kCVReturnSuccess; +static NSCursor *cursorFromSelector(SEL selector, SEL fallback = nil) { + if ([NSCursor respondsToSelector:selector]) { + id object = [NSCursor performSelector:selector]; + if ([object isKindOfClass:[NSCursor class]]) { + return object; + } + } + if (fallback) { + // Fallback should be a reasonable default, no need to check. + return [NSCursor performSelector:fallback]; + } + return [NSCursor arrowCursor]; } @interface GodotApplication : NSApplication @@ -261,29 +271,6 @@ static CVReturn DisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeSt return NSTerminateCancel; } -- (void)applicationDidHide:(NSNotification *)notification { - /* - _Godotwindow* window; - for (window = _Godot.windowListHead; window; window = window->next) - _GodotInputWindowVisibility(window, GL_FALSE); -*/ -} - -- (void)applicationDidUnhide:(NSNotification *)notification { - /* - _Godotwindow* window; - - for (window = _Godot.windowListHead; window; window = window->next) { - if ([window_object isVisible]) - _GodotInputWindowVisibility(window, GL_TRUE); - } -*/ -} - -- (void)applicationDidChangeScreenParameters:(NSNotification *)notification { - //_GodotInputMonitorChange(); -} - - (void)showAbout:(id)sender { if (OS_OSX::singleton->get_main_loop()) OS_OSX::singleton->get_main_loop()->notification(MainLoop::NOTIFICATION_WM_ABOUT); @@ -295,6 +282,8 @@ static CVReturn DisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeSt //_Godotwindow* window; } +- (void)windowWillClose:(NSNotification *)notification; + @end @implementation GodotWindowDelegate @@ -307,6 +296,24 @@ static CVReturn DisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeSt return NO; } +- (void)windowWillClose:(NSNotification *)notification { +#if defined(VULKAN_ENABLED) + if (OS_OSX::singleton->video_driver_index == OS::VIDEO_DRIVER_VULKAN) { + + if (OS_OSX::singleton->rendering_device_vulkan) { + OS_OSX::singleton->rendering_device_vulkan->finalize(); + memdelete(OS_OSX::singleton->rendering_device_vulkan); + OS_OSX::singleton->rendering_device_vulkan = NULL; + } + + if (OS_OSX::singleton->context_vulkan) { + memdelete(OS_OSX::singleton->context_vulkan); + OS_OSX::singleton->context_vulkan = NULL; + } + } +#endif +} + - (void)windowDidEnterFullScreen:(NSNotification *)notification { OS_OSX::singleton->zoomed = true; @@ -337,11 +344,16 @@ static CVReturn DisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeSt NSWindow *window = (NSWindow *)[notification object]; CGFloat newBackingScaleFactor = [window backingScaleFactor]; CGFloat oldBackingScaleFactor = [[[notification userInfo] objectForKey:@"NSBackingPropertyOldScaleFactorKey"] doubleValue]; - if (OS_OSX::singleton->is_hidpi_allowed()) { - [OS_OSX::singleton->window_view setWantsBestResolutionOpenGLSurface:YES]; - } else { - [OS_OSX::singleton->window_view setWantsBestResolutionOpenGLSurface:NO]; + +#if defined(OPENGL_ENABLED) + if (OS_OSX::singleton->video_driver_index == OS::VIDEO_DRIVER_GLES2) { + if (OS_OSX::singleton->is_hidpi_allowed()) { + [OS_OSX::singleton->window_view setWantsBestResolutionOpenGLSurface:YES]; + } else { + [OS_OSX::singleton->window_view setWantsBestResolutionOpenGLSurface:NO]; + } } +#endif if (newBackingScaleFactor != oldBackingScaleFactor) { //Set new display scale and window size @@ -353,21 +365,27 @@ static CVReturn DisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeSt OS_OSX::singleton->window_size.width = fbRect.size.width * newDisplayScale; OS_OSX::singleton->window_size.height = fbRect.size.height * newDisplayScale; +#if defined(VULKAN_ENABLED) + if (OS_OSX::singleton->video_driver_index == OS::VIDEO_DRIVER_VULKAN) { + CALayer *layer = [OS_OSX::singleton->window_view layer]; + layer.contentsScale = OS_OSX::singleton->_display_scale(); + } +#endif //Update context if (OS_OSX::singleton->main_loop) { - [OS_OSX::singleton->context update]; - - //Force window resize ??? - NSRect frame = [OS_OSX::singleton->window_object frame]; - [OS_OSX::singleton->window_object setFrame:NSMakeRect(frame.origin.x, frame.origin.y, 1, 1) display:YES]; - [OS_OSX::singleton->window_object setFrame:frame display:YES]; + //Force window resize event + [self windowDidResize:notification]; } } } - (void)windowDidResize:(NSNotification *)notification { - [OS_OSX::singleton->context update]; +#if defined(OPENGL_ENABLED) + if (OS_OSX::singleton->video_driver_index == OS::VIDEO_DRIVER_GLES2) { + OS_OSX::singleton->context_gles2->update(); + } +#endif const NSRect contentRect = [OS_OSX::singleton->window_view frame]; const NSRect fbRect = contentRect; @@ -375,6 +393,14 @@ static CVReturn DisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeSt OS_OSX::singleton->window_size.width = fbRect.size.width * displayScale; OS_OSX::singleton->window_size.height = fbRect.size.height * displayScale; +#if defined(VULKAN_ENABLED) + if (OS_OSX::singleton->video_driver_index == OS::VIDEO_DRIVER_VULKAN) { + CALayer *layer = [OS_OSX::singleton->window_view layer]; + layer.contentsScale = OS_OSX::singleton->_display_scale(); + OS_OSX::singleton->context_vulkan->window_resize(0, OS_OSX::singleton->window_size.width, OS_OSX::singleton->window_size.height); + } +#endif + if (OS_OSX::singleton->main_loop) { Main::force_redraw(); //Event retrieval blocks until resize is over. Call Main::iteration() directly. @@ -382,15 +408,6 @@ static CVReturn DisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeSt Main::iteration(); } } - - /* - _GodotInputFramebufferSize(window, fbRect.size.width, fbRect.size.height); - _GodotInputWindowSize(window, contentRect.size.width, contentRect.size.height); - _GodotInputWindowDamage(window); - - if (window->cursorMode == Godot_CURSOR_DISABLED) - centerCursor(window); -*/ } - (void)windowDidMove:(NSNotification *)notification { @@ -398,23 +415,9 @@ static CVReturn DisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeSt if (OS_OSX::singleton->get_main_loop()) { OS_OSX::singleton->input->release_pressed_events(); } - - /* - [window->nsgl.context update]; - - int x, y; - _GodotPlatformGetWindowPos(window, &x, &y); - _GodotInputWindowPos(window, x, y); - - if (window->cursorMode == Godot_CURSOR_DISABLED) - centerCursor(window); -*/ } - (void)windowDidBecomeKey:(NSNotification *)notification { - //_GodotInputWindowFocus(window, GL_TRUE); - //_GodotPlatformSetCursorMode(window, window->cursorMode); - if (OS_OSX::singleton->get_main_loop()) { get_mouse_pos( [OS_OSX::singleton->window_object mouseLocationOutsideOfEventStream], @@ -423,25 +426,31 @@ static CVReturn DisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeSt OS_OSX::singleton->get_main_loop()->notification(MainLoop::NOTIFICATION_WM_FOCUS_IN); } + + OS_OSX::singleton->window_focused = true; } - (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); + + OS_OSX::singleton->window_focused = false; } - (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); + + OS_OSX::singleton->window_focused = false; }; - (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); + + OS_OSX::singleton->window_focused = true; }; @end @@ -452,8 +461,12 @@ static CVReturn DisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeSt bool imeInputEventInProgress; } - (void)cancelComposition; + +- (CALayer *)makeBackingLayer; + - (BOOL)wantsUpdateLayer; - (void)updateLayer; + @end @implementation GodotContentView @@ -464,12 +477,32 @@ static CVReturn DisplayLinkCallback(CVDisplayLinkRef displayLink, const CVTimeSt } } -- (BOOL)wantsUpdateLayer { - return YES; +- (CALayer *)makeBackingLayer { +#if defined(VULKAN_ENABLED) + if (OS_OSX::singleton->video_driver_index == OS::VIDEO_DRIVER_VULKAN) { + CALayer *layer = [[CAMetalLayer class] layer]; + layer.contentsScale = OS_OSX::singleton->_display_scale(); + return layer; + } +#endif + return [super makeBackingLayer]; } - (void)updateLayer { - [OS_OSX::singleton->context update]; +#if defined(VULKAN_ENABLED) + if (OS_OSX::singleton->video_driver_index == OS::VIDEO_DRIVER_VULKAN) { + [super updateLayer]; + } +#endif +#if defined(OPENGL_ENABLED) + if (OS_OSX::singleton->video_driver_index == OS::VIDEO_DRIVER_GLES2) { + OS_OSX::singleton->context_gles2->update(); + } +#endif +} + +- (BOOL)wantsUpdateLayer { + return YES; } - (id)init { @@ -495,7 +528,7 @@ static const NSRange kEmptyRange = { NSNotFound, 0 }; } - (NSRange)markedRange { - return (markedText.length > 0) ? NSMakeRange(0, markedText.length - 1) : kEmptyRange; + return NSMakeRange(0, markedText.length); } - (NSRange)selectedRange { @@ -508,6 +541,10 @@ static const NSRange kEmptyRange = { NSNotFound, 0 }; } else { [markedText initWithString:aString]; } + if (markedText.length == 0) { + [self unmarkText]; + return; + } if (OS_OSX::singleton->im_active) { imeInputEventInProgress = true; OS_OSX::singleton->im_text.parse_utf8([[markedText mutableString] UTF8String]); @@ -710,7 +747,7 @@ static void _mouseDownEvent(NSEvent *event, int index, int mask, bool pressed) { const Vector2 pos = get_mouse_pos([event locationInWindow], backingScaleFactor); mm->set_position(pos); mm->set_pressure([event pressure]); - if ([event subtype] == NSTabletPointEventSubtype) { + if ([event subtype] == NSEventSubtypeTabletPoint) { const NSPoint p = [event tilt]; mm->set_tilt(Vector2(p.x, p.y)); } @@ -1456,6 +1493,14 @@ Error OS_OSX::initialize(const VideoMode &p_desired, int p_video_driver, int p_a // Register to be notified on displays arrangement changes CGDisplayRegisterReconfigurationCallback(displays_arrangement_changed, NULL); + //!!!!!!!!!!!!!!!!!!!!!!!!!! + //TODO - do Vulkan and GLES2 support checks, driver selection and fallback + video_driver_index = p_video_driver; + print_verbose("Driver: " + String(get_video_driver_name(video_driver_index)) + " [" + itos(video_driver_index) + "]"); + //!!!!!!!!!!!!!!!!!!!!!!!!!! + + //Create window + window_delegate = [[GodotWindowDelegate alloc] init]; // Don't use accumulation buffer support; it's not accelerated @@ -1496,14 +1541,20 @@ Error OS_OSX::initialize(const VideoMode &p_desired, int p_video_driver, int p_a window_size.height = p_desired.height * displayScale; if (displayScale > 1.0) { - [window_view setWantsBestResolutionOpenGLSurface:YES]; - //if (current_videomode.resizable) +#if defined(OPENGL_ENABLED) + if (video_driver_index == VIDEO_DRIVER_GLES2) { + [window_view setWantsBestResolutionOpenGLSurface:YES]; + } +#endif [window_object setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary]; } else { - [window_view setWantsBestResolutionOpenGLSurface:NO]; +#if defined(OPENGL_ENABLED) + if (video_driver_index == VIDEO_DRIVER_GLES2) { + [window_view setWantsBestResolutionOpenGLSurface:NO]; + } +#endif } - //[window_object setTitle:[NSString stringWithUTF8String:"GodotEnginies"]]; [window_object setContentView:window_view]; [window_object setDelegate:window_delegate]; [window_object setAcceptsMouseMovedEvents:YES]; @@ -1511,86 +1562,51 @@ Error OS_OSX::initialize(const VideoMode &p_desired, int p_video_driver, int p_a [window_object setRestorable:NO]; - unsigned int attributeCount = 0; + // Init context and rendering device +#if defined(OPENGL_ENABLED) + if (video_driver_index == VIDEO_DRIVER_GLES2) { - // OS X needs non-zero color size, so set reasonable values - int colorBits = 32; + context_gles2 = memnew(ContextGL_OSX(window_view, false)); - // 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); \ - } - - // Arbitrary array size here - NSOpenGLPixelFormatAttribute attributes[40]; + if (context_gles2->initialize() != OK) { + memdelete(context_gles2); + context_gles2 = NULL; + ERR_FAIL_V(ERR_UNAVAILABLE); + } - ADD_ATTR(NSOpenGLPFADoubleBuffer); - ADD_ATTR(NSOpenGLPFAClosestPolicy); + context_gles2->set_use_vsync(p_desired.use_vsync); - if (p_video_driver == VIDEO_DRIVER_GLES2) { - ADD_ATTR2(NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersionLegacy); - } else { - //we now need OpenGL 3 or better, maybe even change this to 3_3Core ? - ADD_ATTR2(NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core); + if (RasterizerGLES2::is_viable() == OK) { + RasterizerGLES2::register_config(); + RasterizerGLES2::make_current(); + } else { + memdelete(context_gles2); + context_gles2 = NULL; + ERR_FAIL_V(ERR_UNAVAILABLE); + } } +#endif +#if defined(VULKAN_ENABLED) + if (video_driver_index == VIDEO_DRIVER_VULKAN) { + + context_vulkan = memnew(VulkanContextOSX); + if (context_vulkan->initialize() != OK) { + memdelete(context_vulkan); + context_vulkan = NULL; + ERR_FAIL_V(ERR_UNAVAILABLE); + } + if (context_vulkan->window_create(window_view, get_video_mode().width, get_video_mode().height) == -1) { + memdelete(context_vulkan); + context_vulkan = NULL; + ERR_FAIL_V(ERR_UNAVAILABLE); + } - ADD_ATTR2(NSOpenGLPFAColorSize, colorBits); - - /* - if (fbconfig->alphaBits > 0) - ADD_ATTR2(NSOpenGLPFAAlphaSize, fbconfig->alphaBits); -*/ - - ADD_ATTR2(NSOpenGLPFADepthSize, 24); - - ADD_ATTR2(NSOpenGLPFAStencilSize, 8); - - /* - if (fbconfig->stereo) - ADD_ATTR(NSOpenGLPFAStereo); -*/ + rendering_device_vulkan = memnew(RenderingDeviceVulkan); + rendering_device_vulkan->initialize(context_vulkan); - /* - if (fbconfig->samples > 0) { - ADD_ATTR2(NSOpenGLPFASampleBuffers, 1); - ADD_ATTR2(NSOpenGLPFASamples, fbconfig->samples); + RasterizerRD::make_current(); } -*/ - - // NOTE: All NSOpenGLPixelFormats on the relevant cards support sRGB - // framebuffer, so there's no need (and no way) to request it - - ADD_ATTR(0); - -#undef ADD_ATTR -#undef ADD_ATTR2 - - pixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:attributes]; - ERR_FAIL_COND_V(pixelFormat == nil, ERR_UNAVAILABLE); - - context = [[NSOpenGLContext alloc] initWithFormat:pixelFormat shareContext:nil]; - - ERR_FAIL_COND_V(context == nil, ERR_UNAVAILABLE); - - [context setView:window_view]; - - [context makeCurrentContext]; - - // setup our display link, this will inform us when a refresh is needed - CVDisplayLinkCreateWithActiveCGDisplays(&displayLink); - CVDisplayLinkSetOutputCallback(displayLink, &DisplayLinkCallback, this); - CVDisplayLinkSetCurrentCGDisplayFromOpenGLContext(displayLink, context.CGLContextObj, pixelFormat.CGLPixelFormatObj); - CVDisplayLinkStart(displayLink); - - // initialise a conditional lock object - vsync_condition = [[NSCondition alloc] init]; - - set_use_vsync(p_desired.use_vsync); +#endif [NSApp activateIgnoringOtherApps:YES]; @@ -1601,53 +1617,6 @@ Error OS_OSX::initialize(const VideoMode &p_desired, int p_video_driver, int p_a if (p_desired.fullscreen) zoomed = true; - /*** END OSX INITIALIZATION ***/ - - bool gles3 = true; - if (p_video_driver == VIDEO_DRIVER_GLES2) { - gles3 = false; - } - - bool editor = Engine::get_singleton()->is_editor_hint(); - bool gl_initialization_error = false; - - while (true) { - if (gles3) { - if (RasterizerGLES3::is_viable() == OK) { - RasterizerGLES3::register_config(); - RasterizerGLES3::make_current(); - break; - } else { - if (GLOBAL_GET("rendering/quality/driver/fallback_to_gles2") || editor) { - p_video_driver = VIDEO_DRIVER_GLES2; - gles3 = false; - continue; - } else { - gl_initialization_error = true; - break; - } - } - } else { - if (RasterizerGLES2::is_viable() == OK) { - RasterizerGLES2::register_config(); - RasterizerGLES2::make_current(); - break; - } else { - gl_initialization_error = true; - break; - } - } - } - - if (gl_initialization_error) { - OS::get_singleton()->alert("Your video card driver does not support any of the supported OpenGL versions.\n" - "Please update your drivers or if you have a very old or integrated GPU upgrade it.", - "Unable to initialize Video driver"); - return ERR_UNAVAILABLE; - } - - video_driver_index = p_video_driver; - 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)); @@ -1656,13 +1625,9 @@ Error OS_OSX::initialize(const VideoMode &p_desired, int p_video_driver, int p_a visual_server->init(); AudioDriverManager::initialize(p_audio_driver); - camera_server = memnew(CameraOSX); - input = memnew(InputDefault); joypad_osx = memnew(JoypadOSX); - power_manager = memnew(PowerOSX); - _ensure_user_data_dir(); restore_rect = Rect2(get_window_position(), get_window_size()); @@ -1682,28 +1647,25 @@ void OS_OSX::finalize() { midi_driver.close(); #endif - if (displayLink) { - CVDisplayLinkRelease(displayLink); +#if defined(OPENGL_ENABLED) + if (video_driver_index == VIDEO_DRIVER_GLES2) { + + if (context_gles2) + memdelete(context_gles2); } - [vsync_condition release]; +#endif CFNotificationCenterRemoveObserver(CFNotificationCenterGetDistributedCenter(), NULL, kTISNotifySelectedKeyboardInputSourceChanged, NULL); CGDisplayRemoveReconfigurationCallback(displays_arrangement_changed, NULL); delete_main_loop(); - if (camera_server) { - memdelete(camera_server); - camera_server = NULL; - } - memdelete(joypad_osx); memdelete(input); cursors_cache.clear(); visual_server->finish(); memdelete(visual_server); - //memdelete(rasterizer); } void OS_OSX::set_main_loop(MainLoop *p_main_loop) { @@ -1743,42 +1705,39 @@ public: case ERR_WARNING: if (NSAppKitVersionNumber >= NSAppKitVersionNumber10_12) { os_log_info(OS_LOG_DEFAULT, - "WARNING: %{public}s: %{public}s\nAt: %{public}s:%i.", - p_function, err_details, p_file, p_line); + "WARNING: %{public}s\nat: %{public}s (%{public}s:%i)", + err_details, p_function, p_file, p_line); } - logf_error("\E[1;33mWARNING: %s: \E[0m\E[1m%s\n", p_function, - err_details); - logf_error("\E[0;33m At: %s:%i.\E[0m\n", p_file, p_line); + logf_error("\E[1;33mWARNING:\E[0;93m %s\n", err_details); + logf_error("\E[0;90m at: %s (%s:%i)\E[0m\n", p_function, p_file, p_line); break; case ERR_SCRIPT: if (NSAppKitVersionNumber >= NSAppKitVersionNumber10_12) { os_log_error(OS_LOG_DEFAULT, - "SCRIPT ERROR: %{public}s: %{public}s\nAt: %{public}s:%i.", - p_function, err_details, p_file, p_line); + "SCRIPT ERROR: %{public}s\nat: %{public}s (%{public}s:%i)", + err_details, p_function, p_file, p_line); } - logf_error("\E[1;35mSCRIPT ERROR: %s: \E[0m\E[1m%s\n", p_function, - err_details); - logf_error("\E[0;35m At: %s:%i.\E[0m\n", p_file, p_line); + logf_error("\E[1;35mSCRIPT ERROR:\E[0;95m %s\n", err_details); + logf_error("\E[0;90m at: %s (%s:%i)\E[0m\n", p_function, p_file, p_line); break; case ERR_SHADER: if (NSAppKitVersionNumber >= NSAppKitVersionNumber10_12) { os_log_error(OS_LOG_DEFAULT, - "SHADER ERROR: %{public}s: %{public}s\nAt: %{public}s:%i.", - p_function, err_details, p_file, p_line); + "SHADER ERROR: %{public}s\nat: %{public}s (%{public}s:%i)", + err_details, p_function, p_file, p_line); } - logf_error("\E[1;36mSHADER ERROR: %s: \E[0m\E[1m%s\n", p_function, - err_details); - logf_error("\E[0;36m At: %s:%i.\E[0m\n", p_file, p_line); + logf_error("\E[1;36mSHADER ERROR:\E[0;96m %s\n", err_details); + logf_error("\E[0;90m at: %s (%s:%i)\E[0m\n", p_function, p_file, p_line); break; case ERR_ERROR: default: if (NSAppKitVersionNumber >= NSAppKitVersionNumber10_12) { os_log_error(OS_LOG_DEFAULT, - "ERROR: %{public}s: %{public}s\nAt: %{public}s:%i.", - p_function, err_details, p_file, p_line); + "ERROR: %{public}s\nat: %{public}s (%{public}s:%i)", + err_details, p_function, p_file, p_line); } - logf_error("\E[1;31mERROR: %s: \E[0m\E[1m%s\n", p_function, err_details); - logf_error("\E[0;31m At: %s:%i.\E[0m\n", p_file, p_line); + logf_error("\E[1;31mERROR:\E[0;91m %s\n", err_details); + logf_error("\E[0;90m at: %s (%s:%i)\E[0m\n", p_function, p_file, p_line); break; } } @@ -1798,7 +1757,7 @@ void OS_OSX::alert(const String &p_alert, const String &p_title) { [window addButtonWithTitle:@"OK"]; [window setMessageText:ns_title]; [window setInformativeText:ns_alert]; - [window setAlertStyle:NSWarningAlertStyle]; + [window setAlertStyle:NSAlertStyleWarning]; // Display it, then release [window runModal]; @@ -1846,15 +1805,15 @@ void OS_OSX::set_cursor_shape(CursorShape p_shape) { case CURSOR_BUSY: [[NSCursor arrowCursor] set]; break; case CURSOR_DRAG: [[NSCursor closedHandCursor] set]; break; case CURSOR_CAN_DROP: [[NSCursor openHandCursor] set]; break; - case CURSOR_FORBIDDEN: [[NSCursor arrowCursor] set]; break; - case CURSOR_VSIZE: [[NSCursor resizeUpDownCursor] set]; break; - case CURSOR_HSIZE: [[NSCursor resizeLeftRightCursor] set]; break; - case CURSOR_BDIAGSIZE: [[NSCursor arrowCursor] set]; break; - case CURSOR_FDIAGSIZE: [[NSCursor arrowCursor] set]; break; + case CURSOR_FORBIDDEN: [[NSCursor operationNotAllowedCursor] set]; break; + case CURSOR_VSIZE: [cursorFromSelector(@selector(_windowResizeNorthSouthCursor), @selector(resizeUpDownCursor)) set]; break; + case CURSOR_HSIZE: [cursorFromSelector(@selector(_windowResizeEastWestCursor), @selector(resizeLeftRightCursor)) set]; break; + case CURSOR_BDIAGSIZE: [cursorFromSelector(@selector(_windowResizeNorthEastSouthWestCursor)) set]; break; + case CURSOR_FDIAGSIZE: [cursorFromSelector(@selector(_windowResizeNorthWestSouthEastCursor)) set]; break; case CURSOR_MOVE: [[NSCursor arrowCursor] set]; break; case CURSOR_VSPLIT: [[NSCursor resizeUpDownCursor] set]; break; case CURSOR_HSPLIT: [[NSCursor resizeLeftRightCursor] set]; break; - case CURSOR_HELP: [[NSCursor arrowCursor] set]; break; + case CURSOR_HELP: [cursorFromSelector(@selector(_helpCursor)) set]; break; default: { }; } @@ -1883,7 +1842,7 @@ void OS_OSX::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, c cursors_cache.erase(p_shape); } - Ref<Texture> texture = p_cursor; + Ref<Texture2D> texture = p_cursor; Ref<AtlasTexture> atlas_texture = p_cursor; Ref<Image> image; Size2 texture_size; @@ -1933,12 +1892,7 @@ void OS_OSX::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, c uint8_t *pixels = [imgrep bitmapData]; int len = int(texture_size.width * texture_size.height); - PoolVector<uint8_t> data = image->get_data(); - PoolVector<uint8_t>::Read r = data.read(); - - image->lock(); - /* Premultiply the alpha channel */ for (int i = 0; i < len; i++) { int row_index = floor(i / texture_size.width) + atlas_rect.position.y; int column_index = (i % int(texture_size.width)) + atlas_rect.position.x; @@ -1957,8 +1911,6 @@ void OS_OSX::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, c pixels[i * 4 + 3] = alpha; } - image->unlock(); - NSImage *nsimage = [[NSImage alloc] initWithSize:NSMakeSize(texture_size.width, texture_size.height)]; [nsimage addRepresentation:imgrep]; @@ -2093,8 +2045,7 @@ void OS_OSX::set_icon(const Ref<Image> &p_icon) { uint8_t *pixels = [imgrep bitmapData]; int len = img->get_width() * img->get_height(); - PoolVector<uint8_t> data = img->get_data(); - PoolVector<uint8_t>::Read r = data.read(); + const uint8_t *r = img->get_data().ptr(); /* Premultiply the alpha channel */ for (int i = 0; i < len; i++) { @@ -2148,6 +2099,19 @@ String OS_OSX::get_cache_path() const { } } +String OS_OSX::get_bundle_resource_dir() const { + + NSBundle *main = [NSBundle mainBundle]; + NSString *resourcePath = [main resourcePath]; + + char *utfs = strdup([resourcePath UTF8String]); + String ret; + ret.parse_utf8(utfs); + free(utfs); + + return ret; +} + // Get properly capitalized engine name for system paths String OS_OSX::get_godot_dir_name() const { @@ -2237,13 +2201,19 @@ String OS_OSX::get_clipboard() const { } void OS_OSX::release_rendering_thread() { - - [NSOpenGLContext clearCurrentContext]; +#if defined(OPENGL_ENABLED) + if (video_driver_index == VIDEO_DRIVER_GLES2) { + context_gles2->release_current(); + } +#endif } void OS_OSX::make_rendering_thread() { - - [context makeCurrentContext]; +#if defined(OPENGL_ENABLED) + if (video_driver_index == VIDEO_DRIVER_GLES2) { + context_gles2->make_current(); + } +#endif } Error OS_OSX::shell_open(String p_uri) { @@ -2253,24 +2223,21 @@ Error OS_OSX::shell_open(String p_uri) { } String OS_OSX::get_locale() const { - NSString *locale_code = [[NSLocale currentLocale] localeIdentifier]; + NSString *locale_code = [[NSLocale preferredLanguages] objectAtIndex:0]; return [locale_code UTF8String]; } void OS_OSX::swap_buffers() { - if (is_vsync_enabled()) { - // Wait until our DisplayLink callback unsets our flag... - [vsync_condition lock]; - while (waiting_for_vsync) - [vsync_condition wait]; - - // Make sure we wait again next frame around - waiting_for_vsync = true; - - [vsync_condition unlock]; +#if defined(OPENGL_ENABLED) + if (video_driver_index == VIDEO_DRIVER_GLES2) { + context_gles2->swap_buffers(); } - - [context flushBuffer]; +#endif +#if defined(VULKAN_ENABLED) + if (video_driver_index == VIDEO_DRIVER_VULKAN) { + context_vulkan->swap_buffers(); + } +#endif } void OS_OSX::wm_minimized(bool p_minimized) { @@ -2659,6 +2626,10 @@ bool OS_OSX::is_window_always_on_top() const { return [window_object level] == NSFloatingWindowLevel; } +bool OS_OSX::is_window_focused() const { + return window_focused; +} + void OS_OSX::request_attention() { [NSApp requestUserAttention:NSCriticalRequest]; @@ -2676,21 +2647,31 @@ void OS_OSX::set_window_per_pixel_transparency_enabled(bool p_enabled) { if (layered_window != p_enabled) { if (p_enabled) { set_borderless_window(true); - GLint opacity = 0; [window_object setBackgroundColor:[NSColor clearColor]]; [window_object setOpaque:NO]; [window_object setHasShadow:NO]; - [context setValues:&opacity forParameter:NSOpenGLCPSurfaceOpacity]; +#if defined(OPENGL_ENABLED) + if (video_driver_index == VIDEO_DRIVER_GLES2) { + context_gles2->set_opacity(0); + } +#endif layered_window = true; } else { - GLint opacity = 1; [window_object setBackgroundColor:[NSColor colorWithCalibratedWhite:1 alpha:1]]; [window_object setOpaque:YES]; [window_object setHasShadow:YES]; - [context setValues:&opacity forParameter:NSOpenGLCPSurfaceOpacity]; +#if defined(OPENGL_ENABLED) + if (video_driver_index == VIDEO_DRIVER_GLES2) { + context_gles2->set_opacity(1); + } +#endif layered_window = false; } - [context update]; +#if defined(OPENGL_ENABLED) + if (video_driver_index == VIDEO_DRIVER_GLES2) { + context_gles2->update(); + } +#endif NSRect frame = [window_object frame]; [window_object setFrame:NSMakeRect(frame.origin.x, frame.origin.y, 1, 1) display:YES]; [window_object setFrame:frame display:YES]; @@ -2945,7 +2926,7 @@ void OS_OSX::run() { quit = true; } } @catch (NSException *exception) { - ERR_PRINTS("NSException: " + String([exception reason].UTF8String)); + ERR_PRINT("NSException: " + String([exception reason].UTF8String)); } }; @@ -2983,25 +2964,13 @@ String OS_OSX::get_joy_guid(int p_device) const { return input->get_joy_guid_remapped(p_device); } -OS::PowerState OS_OSX::get_power_state() { - return power_manager->get_power_state(); -} - -int OS_OSX::get_power_seconds_left() { - return power_manager->get_power_seconds_left(); -} - -int OS_OSX::get_power_percent_left() { - return power_manager->get_power_percent_left(); -} - Error OS_OSX::move_to_trash(const String &p_path) { NSFileManager *fm = [NSFileManager defaultManager]; NSURL *url = [NSURL fileURLWithPath:@(p_path.utf8().get_data())]; NSError *err; if (![fm trashItemAtURL:url resultingItemURL:nil error:&err]) { - ERR_PRINTS("trashItemAtURL error: " + String(err.localizedDescription.UTF8String)); + ERR_PRINT("trashItemAtURL error: " + String(err.localizedDescription.UTF8String)); return FAILED; } @@ -3009,20 +2978,12 @@ Error OS_OSX::move_to_trash(const String &p_path) { } void OS_OSX::_set_use_vsync(bool p_enable) { - // CGLCPSwapInterval broke in OSX 10.14 and it seems Apple is not interested in fixing - // it as OpenGL is now deprecated and Metal solves this differently. - // Following SDLs example we're working around this using DisplayLink - // When vsync is enabled we set a flag "waiting_for_vsync" to true. - // This flag is set to false when DisplayLink informs us our display is about to refresh. - - /* CGLContextObj ctx = CGLGetCurrentContext(); - if (ctx) { - GLint swapInterval = p_enable ? 1 : 0; - CGLSetParameter(ctx, kCGLCPSwapInterval, &swapInterval); - }*/ - - ///TODO Maybe pause/unpause display link? - waiting_for_vsync = p_enable; +#if defined(OPENGL_ENABLED) + if (video_driver_index == VIDEO_DRIVER_GLES2) { + if (context_gles2) + context_gles2->set_use_vsync(p_enable); + } +#endif } OS_OSX *OS_OSX::singleton = NULL; @@ -3044,16 +3005,6 @@ 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; - } -*/ - - framework = CFBundleGetBundleWithIdentifier(CFSTR("com.apple.opengl")); - ERR_FAIL_COND(!framework); - // Implicitly create shared NSApplication instance [GodotApplication sharedApplication]; @@ -3120,6 +3071,7 @@ OS_OSX::OS_OSX() { window_size = Vector2(1024, 600); zoomed = false; resizable = false; + window_focused = true; Vector<Logger *> loggers; loggers.push_back(memnew(OSXTerminalLogger)); diff --git a/platform/osx/platform_config.h b/platform/osx/platform_config.h index ddb533cb79..155f37ed55 100644 --- a/platform/osx/platform_config.h +++ b/platform/osx/platform_config.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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 +30,5 @@ #include <alloca.h> -#define GLES3_INCLUDE_H "thirdparty/glad/glad/glad.h" #define GLES2_INCLUDE_H "thirdparty/glad/glad/glad.h" #define PTHREAD_RENAME_SELF diff --git a/platform/osx/power_osx.cpp b/platform/osx/power_osx.cpp deleted file mode 100644 index 04d423d8c5..0000000000 --- a/platform/osx/power_osx.cpp +++ /dev/null @@ -1,252 +0,0 @@ -/*************************************************************************/ -/* power_osx.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -/* -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> -#include <IOKit/ps/IOPSKeys.h> -#include <IOKit/ps/IOPowerSources.h> - -// CODE CHUNK IMPORTED FROM SDL 2.0 - -/* CoreFoundation is so verbose... */ -#define STRMATCH(a, b) (CFStringCompare(a, b, 0) == kCFCompareEqualTo) -#define GETVAL(k, v) \ - CFDictionaryGetValueIfPresent(dict, CFSTR(k), (const void **)v) - -/* Note that AC power sources also include a laptop battery it is charging. */ -void PowerOSX::checkps(CFDictionaryRef dict, bool *have_ac, bool *have_battery, bool *charging) { - CFStringRef strval; /* don't CFRelease() this. */ - CFBooleanRef bval; - CFNumberRef numval; - bool charge = false; - bool choose = false; - bool is_ac = false; - int secs = -1; - int maxpct = -1; - int pct = -1; - - if ((GETVAL(kIOPSIsPresentKey, &bval)) && (bval == kCFBooleanFalse)) { - return; /* nothing to see here. */ - } - - if (!GETVAL(kIOPSPowerSourceStateKey, &strval)) { - return; - } - - if (STRMATCH(strval, CFSTR(kIOPSACPowerValue))) { - is_ac = *have_ac = true; - } else if (!STRMATCH(strval, CFSTR(kIOPSBatteryPowerValue))) { - return; /* not a battery? */ - } - - if ((GETVAL(kIOPSIsChargingKey, &bval)) && (bval == kCFBooleanTrue)) { - charge = true; - } - - if (GETVAL(kIOPSMaxCapacityKey, &numval)) { - SInt32 val = -1; - CFNumberGetValue(numval, kCFNumberSInt32Type, &val); - if (val > 0) { - *have_battery = true; - maxpct = (int)val; - } - } - - if (GETVAL(kIOPSMaxCapacityKey, &numval)) { - SInt32 val = -1; - CFNumberGetValue(numval, kCFNumberSInt32Type, &val); - if (val > 0) { - *have_battery = true; - maxpct = (int)val; - } - } - - if (GETVAL(kIOPSTimeToEmptyKey, &numval)) { - SInt32 val = -1; - CFNumberGetValue(numval, kCFNumberSInt32Type, &val); - - /* Mac OS X reports 0 minutes until empty if you're plugged in. :( */ - if ((val == 0) && (is_ac)) { - val = -1; /* !!! FIXME: calc from timeToFull and capacity? */ - } - - secs = (int)val; - if (secs > 0) { - secs *= 60; /* value is in minutes, so convert to seconds. */ - } - } - - if (GETVAL(kIOPSCurrentCapacityKey, &numval)) { - SInt32 val = -1; - CFNumberGetValue(numval, kCFNumberSInt32Type, &val); - pct = (int)val; - } - - if ((pct > 0) && (maxpct > 0)) { - pct = (int)((((double)pct) / ((double)maxpct)) * 100.0); - } - - if (pct > 100) { - pct = 100; - } - - /* - * We pick the battery that claims to have the most minutes left. - * (failing a report of minutes, we'll take the highest percent.) - */ - if ((secs < 0) && (nsecs_left < 0)) { - if ((pct < 0) && (percent_left < 0)) { - choose = true; /* at least we know there's a battery. */ - } - if (pct > percent_left) { - choose = true; - } - } else if (secs > nsecs_left) { - choose = true; - } - - if (choose) { - nsecs_left = secs; - percent_left = pct; - *charging = charge; - } -} - -#undef GETVAL -#undef STRMATCH - -// CODE CHUNK IMPORTED FROM SDL 2.0 -bool PowerOSX::GetPowerInfo_MacOSX() { - CFTypeRef blob = IOPSCopyPowerSourcesInfo(); - - nsecs_left = -1; - percent_left = -1; - power_state = OS::POWERSTATE_UNKNOWN; - - if (blob != NULL) { - CFArrayRef list = IOPSCopyPowerSourcesList(blob); - if (list != NULL) { - /* don't CFRelease() the list items, or dictionaries! */ - bool have_ac = false; - bool have_battery = false; - bool charging = false; - const CFIndex total = CFArrayGetCount(list); - CFIndex i; - for (i = 0; i < total; i++) { - CFTypeRef ps = (CFTypeRef)CFArrayGetValueAtIndex(list, i); - CFDictionaryRef dict = IOPSGetPowerSourceDescription(blob, ps); - if (dict != NULL) { - checkps(dict, &have_ac, &have_battery, &charging); - } - } - - if (!have_battery) { - power_state = OS::POWERSTATE_NO_BATTERY; - } else if (charging) { - power_state = OS::POWERSTATE_CHARGING; - } else if (have_ac) { - power_state = OS::POWERSTATE_CHARGED; - } else { - power_state = OS::POWERSTATE_ON_BATTERY; - } - - CFRelease(list); - } - CFRelease(blob); - } - - return true; /* always the definitive answer on Mac OS X. */ -} - -bool PowerOSX::UpdatePowerInfo() { - if (GetPowerInfo_MacOSX()) { - return true; - } - return false; -} - -OS::PowerState PowerOSX::get_power_state() { - if (UpdatePowerInfo()) { - return power_state; - } else { - return OS::POWERSTATE_UNKNOWN; - } -} - -int PowerOSX::get_power_seconds_left() { - if (UpdatePowerInfo()) { - return nsecs_left; - } else { - return -1; - } -} - -int PowerOSX::get_power_percent_left() { - if (UpdatePowerInfo()) { - return percent_left; - } else { - return -1; - } -} - -PowerOSX::PowerOSX() : - nsecs_left(-1), - percent_left(-1), - power_state(OS::POWERSTATE_UNKNOWN) { -} - -PowerOSX::~PowerOSX() { -} diff --git a/platform/osx/semaphore_osx.cpp b/platform/osx/semaphore_osx.cpp index fe7d19bd9e..e4e5991637 100644 --- a/platform/osx/semaphore_osx.cpp +++ b/platform/osx/semaphore_osx.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -86,7 +86,7 @@ int SemaphoreOSX::get() const { return 0; } -Semaphore *SemaphoreOSX::create_semaphore_osx() { +SemaphoreOld *SemaphoreOSX::create_semaphore_osx() { return memnew(SemaphoreOSX); } diff --git a/platform/osx/semaphore_osx.h b/platform/osx/semaphore_osx.h index c8e7c45227..9aa2b47bc8 100644 --- a/platform/osx/semaphore_osx.h +++ b/platform/osx/semaphore_osx.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -39,11 +39,11 @@ typedef struct cgsem cgsem_t; #include "core/os/semaphore.h" -class SemaphoreOSX : public Semaphore { +class SemaphoreOSX : public SemaphoreOld { mutable cgsem_t sem; - static Semaphore *create_semaphore_osx(); + static SemaphoreOld *create_semaphore_osx(); public: virtual Error wait(); diff --git a/platform/iphone/power_iphone.h b/platform/osx/vulkan_context_osx.h index d7d4bf4a69..619e91d1f6 100644 --- a/platform/iphone/power_iphone.h +++ b/platform/osx/vulkan_context_osx.h @@ -1,12 +1,12 @@ /*************************************************************************/ -/* power_iphone.h */ +/* vulkan_context_osx.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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,26 +28,21 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef POWER_IPHONE_H -#define POWER_IPHONE_H +#ifndef VULKAN_DEVICE_OSX_H +#define VULKAN_DEVICE_OSX_H -#include <os/os.h> +#include "drivers/vulkan/vulkan_context.h" +#include <AppKit/AppKit.h> -class PowerIphone { -private: - int nsecs_left; - int percent_left; - OS::PowerState power_state; +class VulkanContextOSX : public VulkanContext { - bool UpdatePowerInfo(); + virtual const char *_get_platform_surface_extension() const; public: - PowerIphone(); - virtual ~PowerIphone(); + int window_create(id p_window, int p_width, int p_height); - OS::PowerState get_power_state(); - int get_power_seconds_left(); - int get_power_percent_left(); + VulkanContextOSX(); + ~VulkanContextOSX(); }; -#endif // POWER_IPHONE_H +#endif // VULKAN_DEVICE_OSX_H diff --git a/platform/iphone/power_iphone.cpp b/platform/osx/vulkan_context_osx.mm index e2631b7822..c132bd334a 100644 --- a/platform/iphone/power_iphone.cpp +++ b/platform/osx/vulkan_context_osx.mm @@ -1,12 +1,12 @@ /*************************************************************************/ -/* power_iphone.cpp */ +/* vulkan_context_osx.mm */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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,43 +28,29 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "power_iphone.h" +#include "vulkan_context_osx.h" +#include <vulkan/vulkan_macos.h> -bool PowerIphone::UpdatePowerInfo() { - return false; +const char *VulkanContextOSX::_get_platform_surface_extension() const { + return VK_MVK_MACOS_SURFACE_EXTENSION_NAME; } -OS::PowerState PowerIphone::get_power_state() { - if (UpdatePowerInfo()) { - return power_state; - } else { - return OS::POWERSTATE_UNKNOWN; - } -} +int VulkanContextOSX::window_create(id p_window, int p_width, int p_height) { -int PowerIphone::get_power_seconds_left() { - if (UpdatePowerInfo()) { - return nsecs_left; - } else { - return -1; - } -} + VkMacOSSurfaceCreateInfoMVK createInfo; + createInfo.sType = VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK; + createInfo.pNext = NULL; + createInfo.flags = 0; + createInfo.pView = p_window; -int PowerIphone::get_power_percent_left() { - if (UpdatePowerInfo()) { - return percent_left; - } else { - return -1; - } + VkSurfaceKHR surface; + VkResult err = vkCreateMacOSSurfaceMVK(_get_instance(), &createInfo, NULL, &surface); + ERR_FAIL_COND_V(err, -1); + return _window_create(surface, p_width, p_height); } -PowerIphone::PowerIphone() : - nsecs_left(-1), - percent_left(-1), - power_state(OS::POWERSTATE_UNKNOWN) { - // TODO Auto-generated constructor stub +VulkanContextOSX::VulkanContextOSX() { } -PowerIphone::~PowerIphone() { - // TODO Auto-generated destructor stub +VulkanContextOSX::~VulkanContextOSX() { } diff --git a/platform/register_platform_apis.h b/platform/register_platform_apis.h index 10876bacc7..6b962f5d91 100644 --- a/platform/register_platform_apis.h +++ b/platform/register_platform_apis.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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/SCsub b/platform/server/SCsub index f977275595..e8538f03a6 100644 --- a/platform/server/SCsub +++ b/platform/server/SCsub @@ -10,10 +10,8 @@ common_server = [\ if sys.platform == "darwin": common_server.append("#platform/osx/crash_handler_osx.mm") - common_server.append("#platform/osx/power_osx.cpp") common_server.append("#platform/osx/semaphore_osx.cpp") else: common_server.append("#platform/x11/crash_handler_x11.cpp") - common_server.append("#platform/x11/power_x11.cpp") prog = env.add_program('#bin/godot_server', ['godot_server.cpp'] + common_server) diff --git a/platform/server/detect.py b/platform/server/detect.py index b6028c20e3..d82df77957 100644 --- a/platform/server/detect.py +++ b/platform/server/detect.py @@ -162,7 +162,7 @@ def configure(env): if not env['builtin_enet']: env.ParseConfig('pkg-config libenet --cflags --libs') - if not env['builtin_squish'] and env['tools']: + if not env['builtin_squish']: env.ParseConfig('pkg-config libsquish --cflags --libs') if not env['builtin_zstd']: diff --git a/platform/server/godot_server.cpp b/platform/server/godot_server.cpp index 91bd96ac31..df49bfaebf 100644 --- a/platform/server/godot_server.cpp +++ b/platform/server/godot_server.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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 87dc6421ac..8a66332ff1 100644 --- a/platform/server/os_server.cpp +++ b/platform/server/os_server.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -31,7 +31,6 @@ #include "os_server.h" #include "core/print_string.h" -#include "drivers/dummy/audio_driver_dummy.h" #include "drivers/dummy/rasterizer_dummy.h" #include "drivers/dummy/texture_loader_dummy.h" #include "servers/visual/visual_server_raster.h" @@ -88,18 +87,10 @@ Error OS_Server::initialize(const VideoMode &p_desired, int p_video_driver, int visual_server = memnew(VisualServerRaster); visual_server->init(); - camera_server = memnew(CameraServer); - AudioDriverManager::initialize(p_audio_driver); input = memnew(InputDefault); -#ifdef __APPLE__ - power_manager = memnew(PowerOSX); -#else - power_manager = memnew(PowerX11); -#endif - _ensure_user_data_dir(); resource_loader_dummy.instance(); @@ -119,10 +110,6 @@ void OS_Server::finalize() { memdelete(input); - memdelete(camera_server); - - memdelete(power_manager); - ResourceLoader::remove_resource_format_loader(resource_loader_dummy); resource_loader_dummy.unref(); @@ -202,18 +189,6 @@ String OS_Server::get_name() const { void OS_Server::move_window_to_foreground() { } -OS::PowerState OS_Server::get_power_state() { - return power_manager->get_power_state(); -} - -int OS_Server::get_power_seconds_left() { - return power_manager->get_power_seconds_left(); -} - -int OS_Server::get_power_percent_left() { - return power_manager->get_power_percent_left(); -} - bool OS_Server::_check_internal_feature_support(const String &p_feature) { return p_feature == "pc"; } diff --git a/platform/server/os_server.h b/platform/server/os_server.h index b8119288ff..7584293722 100644 --- a/platform/server/os_server.h +++ b/platform/server/os_server.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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,11 +36,9 @@ #include "main/input_default.h" #ifdef __APPLE__ #include "platform/osx/crash_handler_osx.h" -#include "platform/osx/power_osx.h" #include "platform/osx/semaphore_osx.h" #else #include "platform/x11/crash_handler_x11.h" -#include "platform/x11/power_x11.h" #endif #include "servers/audio_server.h" #include "servers/visual/rasterizer.h" @@ -58,20 +56,12 @@ class OS_Server : public OS_Unix { bool grab; virtual void delete_main_loop(); - IP_Unix *ip_unix; bool force_quit; InputDefault *input; -#ifdef __APPLE__ - PowerOSX *power_manager; -#else - PowerX11 *power_manager; -#endif - CrashHandler crash_handler; - CameraServer *camera_server; int video_driver_index; @@ -114,9 +104,6 @@ public: void run(); - virtual OS::PowerState get_power_state(); - virtual int get_power_seconds_left(); - virtual int get_power_percent_left(); virtual bool _check_internal_feature_support(const String &p_feature); virtual String get_config_path() const; diff --git a/platform/server/platform_config.h b/platform/server/platform_config.h index bedbff0b80..bdff93f02b 100644 --- a/platform/server/platform_config.h +++ b/platform/server/platform_config.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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 c14290f0c4..620d8c3c3a 100644 --- a/platform/uwp/SCsub +++ b/platform/uwp/SCsub @@ -7,7 +7,6 @@ files = [ '#platform/windows/key_mapping_windows.cpp', '#platform/windows/windows_terminal_logger.cpp', 'joypad_uwp.cpp', - 'power_uwp.cpp', 'context_egl_uwp.cpp', 'app.cpp', 'os_uwp.cpp', diff --git a/platform/uwp/app.cpp b/platform/uwp/app.cpp index 4f2ee0237a..a47fe96c1b 100644 --- a/platform/uwp/app.cpp +++ b/platform/uwp/app.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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/app.h b/platform/uwp/app.h index 0bd996d483..b7265ad086 100644 --- a/platform/uwp/app.h +++ b/platform/uwp/app.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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,7 +34,6 @@ #include <wrl.h> -// ANGLE doesn't provide a specific lib for GLES3, so we keep using GLES2 #include "GLES2/gl2.h" #include "os_uwp.h" diff --git a/platform/uwp/context_egl_uwp.cpp b/platform/uwp/context_egl_uwp.cpp index 061c54687c..7ac9489bb4 100644 --- a/platform/uwp/context_egl_uwp.cpp +++ b/platform/uwp/context_egl_uwp.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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/context_egl_uwp.h b/platform/uwp/context_egl_uwp.h index 0c62fe7456..fa61cf50c6 100644 --- a/platform/uwp/context_egl_uwp.h +++ b/platform/uwp/context_egl_uwp.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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,7 +45,7 @@ class ContextEGL_UWP { public: enum Driver { GLES_2_0, - GLES_3_0, + VULKAN, // FIXME: Add Vulkan support. }; private: diff --git a/platform/uwp/detect.py b/platform/uwp/detect.py index 7da93eafae..000bd18e7d 100644 --- a/platform/uwp/detect.py +++ b/platform/uwp/detect.py @@ -34,6 +34,7 @@ def get_flags(): return [ ('tools', False), ('xaudio2', True), + ('builtin_pcre2_with_jit', False), ] diff --git a/platform/uwp/export/export.cpp b/platform/uwp/export/export.cpp index 557699cf37..533293387d 100644 --- a/platform/uwp/export/export.cpp +++ b/platform/uwp/export/export.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -517,7 +517,7 @@ Error AppxPackager::add_file(String p_file_name, const uint8_t *p_buffer, size_t int total_out_before = strm.total_out; int err = deflate(&strm, Z_FULL_FLUSH); - ERR_FAIL_COND_V(err >= 0, ERR_BUG); // Negative means bug + ERR_FAIL_COND_V(err < 0, ERR_BUG); // Negative means bug bh.compressed_size = strm.total_out - total_out_before; @@ -1004,7 +1004,7 @@ public: return list; } - virtual Ref<Texture> get_logo() const { + virtual Ref<Texture2D> get_logo() const { return logo; } @@ -1090,15 +1090,14 @@ public: } virtual bool can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const { + String err; - bool valid = true; - Platform arch = (Platform)(int)(p_preset->get("architecture/target")); + bool valid = false; - String custom_debug_binary = p_preset->get("custom_template/debug"); - String custom_release_binary = p_preset->get("custom_template/release"); + // Look for export templates (first official, and if defined custom templates). + Platform arch = (Platform)(int)(p_preset->get("architecture/target")); String platform_infix; - switch (arch) { case EditorExportPlatformUWP::ARM: { platform_infix = "arm"; @@ -1111,38 +1110,26 @@ public: } break; } - if (!exists_export_template("uwp_" + platform_infix + "_debug.zip", &err) || !exists_export_template("uwp_" + platform_infix + "_release.zip", &err)) { - valid = false; - r_missing_templates = true; - } + bool dvalid = exists_export_template("uwp_" + platform_infix + "_debug.zip", &err); + bool rvalid = exists_export_template("uwp_" + platform_infix + "_release.zip", &err); - if (!valid && custom_debug_binary == "" && custom_release_binary == "") { - if (!err.empty()) { - r_error = err; + if (p_preset->get("custom_template/debug") != "") { + dvalid = FileAccess::exists(p_preset->get("custom_template/debug")); + if (!dvalid) { + err += TTR("Custom debug template not found.") + "\n"; } - return valid; } - - bool dvalid = true; - bool rvalid = true; - - if (!FileAccess::exists(custom_debug_binary)) { - dvalid = false; - err += TTR("Custom debug template not found.") + "\n"; - } - - if (!FileAccess::exists(custom_release_binary)) { - rvalid = false; - err += TTR("Custom release template not found.") + "\n"; + if (p_preset->get("custom_template/release") != "") { + rvalid = FileAccess::exists(p_preset->get("custom_template/release")); + if (!rvalid) { + err += TTR("Custom release template not found.") + "\n"; + } } - if (dvalid || rvalid) - valid = true; + valid = dvalid || rvalid; + r_missing_templates = !valid; - if (!valid) { - r_error = err; - return valid; - } + // Validate the rest of the configuration. if (!_valid_resource_name(p_preset->get("package/short_name"))) { valid = false; @@ -1189,7 +1176,7 @@ public: err += TTR("Invalid square 71x71 logo image dimensions (should be 71x71).") + "\n"; } - if (!p_preset->get("images/square150x150_logo").is_zero() && !_valid_image((Object::cast_to<StreamTexture>((Object *)p_preset->get("images/square150x150_logo"))), 150, 0)) { + if (!p_preset->get("images/square150x150_logo").is_zero() && !_valid_image((Object::cast_to<StreamTexture>((Object *)p_preset->get("images/square150x150_logo"))), 150, 150)) { valid = false; err += TTR("Invalid square 150x150 logo image dimensions (should be 150x150).") + "\n"; } @@ -1410,7 +1397,7 @@ public: } if (!FileAccess::exists(signtool_path)) { - ERR_PRINTS("Could not find signtool executable at " + signtool_path + ", aborting."); + ERR_PRINT("Could not find signtool executable at " + signtool_path + ", aborting."); return ERR_FILE_NOT_FOUND; } @@ -1431,12 +1418,12 @@ public: } if (!FileAccess::exists(cert_path)) { - ERR_PRINTS("Could not find certificate file at " + cert_path + ", aborting."); + ERR_PRINT("Could not find certificate file at " + cert_path + ", aborting."); return ERR_FILE_NOT_FOUND; } if (cert_alg < 0 || cert_alg > 2) { - ERR_PRINTS("Invalid certificate algorithm " + itos(cert_alg) + ", aborting."); + ERR_PRINT("Invalid certificate algorithm " + itos(cert_alg) + ", aborting."); return ERR_INVALID_DATA; } diff --git a/platform/uwp/export/export.h b/platform/uwp/export/export.h index e4839eeda2..ce03bc0aeb 100644 --- a/platform/uwp/export/export.h +++ b/platform/uwp/export/export.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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 0899c7592c..90df6fe5d7 100644 --- a/platform/uwp/joypad_uwp.cpp +++ b/platform/uwp/joypad_uwp.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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.h b/platform/uwp/joypad_uwp.h index 31fc9bcd11..f2a721f3dd 100644 --- a/platform/uwp/joypad_uwp.h +++ b/platform/uwp/joypad_uwp.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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/os_uwp.cpp b/platform/uwp/os_uwp.cpp index 60f2290355..3cd7a02a94 100644 --- a/platform/uwp/os_uwp.cpp +++ b/platform/uwp/os_uwp.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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,7 +36,6 @@ #include "core/io/marshalls.h" #include "core/project_settings.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" @@ -186,71 +185,33 @@ Error OS_UWP::initialize(const VideoMode &p_desired, int p_video_driver, int p_a main_loop = NULL; outside = true; + // FIXME: Hardcoded for now, add Vulkan support. + p_video_driver = VIDEO_DRIVER_GLES2; ContextEGL_UWP::Driver opengl_api_type = ContextEGL_UWP::GLES_2_0; - if (p_video_driver == VIDEO_DRIVER_GLES2) { - opengl_api_type = ContextEGL_UWP::GLES_2_0; - } - bool gl_initialization_error = false; - gl_context = NULL; - while (!gl_context) { - gl_context = memnew(ContextEGL_UWP(window, opengl_api_type)); - - if (gl_context->initialize() != OK) { - memdelete(gl_context); - gl_context = NULL; - - if (GLOBAL_GET("rendering/quality/driver/fallback_to_gles2")) { - if (p_video_driver == VIDEO_DRIVER_GLES2) { - gl_initialization_error = true; - break; - } - - p_video_driver = VIDEO_DRIVER_GLES2; - opengl_api_type = ContextEGL_UWP::GLES_2_0; - } else { - gl_initialization_error = true; - break; - } - } - } + gl_context = memnew(ContextEGL_UWP(window, opengl_api_type)); - while (true) { - if (opengl_api_type == ContextEGL_UWP::GLES_3_0) { - if (RasterizerGLES3::is_viable() == OK) { - RasterizerGLES3::register_config(); - RasterizerGLES3::make_current(); - break; - } else { - if (GLOBAL_GET("rendering/quality/driver/fallback_to_gles2")) { - p_video_driver = VIDEO_DRIVER_GLES2; - opengl_api_type = ContextEGL_UWP::GLES_2_0; - continue; - } else { - gl_initialization_error = true; - break; - } - } - } + if (gl_context->initialize() != OK) { + memdelete(gl_context); + gl_context = NULL; + gl_initialization_error = true; + } - if (opengl_api_type == ContextEGL_UWP::GLES_2_0) { - if (RasterizerGLES2::is_viable() == OK) { - RasterizerGLES2::register_config(); - RasterizerGLES2::make_current(); - break; - } else { - gl_initialization_error = true; - break; - } + if (opengl_api_type == ContextEGL_UWP::GLES_2_0) { + if (RasterizerGLES2::is_viable() == OK) { + RasterizerGLES2::register_config(); + RasterizerGLES2::make_current(); + } else { + gl_initialization_error = true; } } if (gl_initialization_error) { OS::get_singleton()->alert("Your video card driver does not support any of the supported OpenGL versions.\n" "Please update your drivers or if you have a very old or integrated GPU upgrade it.", - "Unable to initialize Video driver"); + "Unable to initialize video driver"); return ERR_UNAVAILABLE; } @@ -303,9 +264,6 @@ Error OS_UWP::initialize(const VideoMode &p_desired, int p_video_driver, int p_a visual_server->init(); - ///@TODO implement a subclass for UWP and instantiate that instead - camera_server = memnew(CameraServer); - input = memnew(InputDefault); joypad = ref new JoypadUWP(input); @@ -313,8 +271,6 @@ Error OS_UWP::initialize(const VideoMode &p_desired, int p_video_driver, int p_a AudioDriverManager::initialize(p_audio_driver); - power_manager = memnew(PowerUWP); - managed_object->update_clipboard(); Clipboard::ContentChanged += ref new EventHandler<Platform::Object ^>(managed_object, &ManagedType::on_clipboard_changed); @@ -404,8 +360,6 @@ void OS_UWP::finalize() { memdelete(input); - memdelete(camera_server); - joypad = nullptr; } @@ -806,7 +760,7 @@ bool OS_UWP::has_virtual_keyboard() const { return UIViewSettings::GetForCurrentView()->UserInteractionMode == UserInteractionMode::Touch; } -void OS_UWP::show_virtual_keyboard(const String &p_existing_text, const Rect2 &p_screen_rect) { +void OS_UWP::show_virtual_keyboard(const String &p_existing_text, const Rect2 &p_screen_rect, int p_max_input_length) { InputPane ^ pane = InputPane::GetForCurrentView(); pane->TryShow(); @@ -898,18 +852,6 @@ bool OS_UWP::_check_internal_feature_support(const String &p_feature) { return p_feature == "pc"; } -OS::PowerState OS_UWP::get_power_state() { - return power_manager->get_power_state(); -} - -int OS_UWP::get_power_seconds_left() { - return power_manager->get_power_seconds_left(); -} - -int OS_UWP::get_power_percent_left() { - return power_manager->get_power_percent_left(); -} - OS_UWP::OS_UWP() { key_event_pos = 0; diff --git a/platform/uwp/os_uwp.h b/platform/uwp/os_uwp.h index 370cab6a9b..32b899c0da 100644 --- a/platform/uwp/os_uwp.h +++ b/platform/uwp/os_uwp.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -39,9 +39,7 @@ #include "drivers/xaudio2/audio_driver_xaudio2.h" #include "joypad_uwp.h" #include "main/input_default.h" -#include "power_uwp.h" #include "servers/audio_server.h" -#include "servers/camera_server.h" #include "servers/visual/rasterizer.h" #include "servers/visual_server.h" @@ -93,8 +91,6 @@ private: VisualServer *visual_server; int pressrc; - CameraServer *camera_server; - ContextEGL_UWP *gl_context; Windows::UI::Core::CoreWindow ^ window; @@ -105,8 +101,6 @@ private: AudioDriverXAudio2 audio_driver; - PowerUWP *power_manager; - MouseMode mouse_mode; bool alt_mem; bool gr_mem; @@ -208,7 +202,7 @@ public: virtual void delay_usec(uint32_t p_usec) const; virtual uint64_t get_ticks_usec() const; - virtual Error execute(const String &p_path, const List<String> &p_arguments, bool p_blocking, ProcessID *r_child_id = NULL, String *r_pipe = NULL, int *r_exitcode = NULL, bool read_stderr = false, Mutex *p_pipe_mutex = NULL); + virtual Error execute(const String &p_path, const List<String> &p_arguments, bool p_blocking = true, ProcessID *r_child_id = NULL, String *r_pipe = NULL, int *r_exitcode = NULL, bool read_stderr = false, Mutex *p_pipe_mutex = NULL); virtual Error kill(const ProcessID &p_pid); virtual bool has_environment(const String &p_var) const; @@ -242,7 +236,7 @@ public: virtual bool has_touchscreen_ui_hint() const; virtual bool has_virtual_keyboard() const; - virtual void show_virtual_keyboard(const String &p_existing_text, const Rect2 &p_screen_rect = Rect2()); + virtual void show_virtual_keyboard(const String &p_existing_text, const Rect2 &p_screen_rect = Rect2(), int p_max_input_length = -1); virtual void hide_virtual_keyboard(); virtual Error open_dynamic_library(const String p_path, void *&p_library_handle, bool p_also_set_library_path = false); @@ -257,10 +251,6 @@ public: void input_event(const Ref<InputEvent> &p_event); - virtual OS::PowerState get_power_state(); - virtual int get_power_seconds_left(); - virtual int get_power_percent_left(); - void queue_key_event(KeyEvent &p_event); OS_UWP(); diff --git a/platform/uwp/platform_config.h b/platform/uwp/platform_config.h index 311a41454d..09a16614e0 100644 --- a/platform/uwp/platform_config.h +++ b/platform/uwp/platform_config.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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.cpp b/platform/uwp/thread_uwp.cpp index 0e4e138aa6..9dc20a74e8 100644 --- a/platform/uwp/thread_uwp.cpp +++ b/platform/uwp/thread_uwp.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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 e29b45a903..a2d367ae2f 100644 --- a/platform/uwp/thread_uwp.h +++ b/platform/uwp/thread_uwp.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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/SCsub b/platform/windows/SCsub index 8426ccbb89..8e94c7b35d 100644 --- a/platform/windows/SCsub +++ b/platform/windows/SCsub @@ -8,14 +8,13 @@ import platform_windows_builders common_win = [ "godot_windows.cpp", - "camera_win.cpp", - "context_gl_windows.cpp", "crash_handler_windows.cpp", "os_windows.cpp", "key_mapping_windows.cpp", "joypad_windows.cpp", - "power_windows.cpp", - "windows_terminal_logger.cpp" + "windows_terminal_logger.cpp", + "vulkan_context_win.cpp", + "context_gl_windows.cpp" ] res_file = 'godot_res.rc' diff --git a/platform/windows/camera_win.cpp b/platform/windows/camera_win.cpp deleted file mode 100644 index 10787d0d0a..0000000000 --- a/platform/windows/camera_win.cpp +++ /dev/null @@ -1,98 +0,0 @@ -/*************************************************************************/ -/* camera_win.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#include "camera_win.h" - -///@TODO sorry guys, I got about 80% through implementing this using DirectShow only -// to find out Microsoft deprecated half the API and its replacement is as confusing -// as they could make it. Joey suggested looking into libuvc which offers a more direct -// route to webcams over USB and this is very promising but it wouldn't compile on -// windows for me...I've gutted the classes I implemented DirectShow in just to have -// a skeleton for someone to work on, mail me for more details or if you want a copy.... - -////////////////////////////////////////////////////////////////////////// -// CameraFeedWindows - Subclass for our camera feed on windows - -/// @TODO need to implement this - -class CameraFeedWindows : public CameraFeed { -private: -protected: -public: - CameraFeedWindows(); - virtual ~CameraFeedWindows(); - - bool activate_feed(); - void deactivate_feed(); -}; - -CameraFeedWindows::CameraFeedWindows(){ - ///@TODO implement this, should store information about our available camera -}; - -CameraFeedWindows::~CameraFeedWindows() { - // make sure we stop recording if we are! - if (is_active()) { - deactivate_feed(); - }; - - ///@TODO free up anything used by this -}; - -bool CameraFeedWindows::activate_feed() { - ///@TODO this should activate our camera and start the process of capturing frames - - return true; -}; - -///@TODO we should probably have a callback method here that is being called by the -// camera API which provides frames and call back into the CameraServer to update our texture - -void CameraFeedWindows::deactivate_feed(){ - ///@TODO this should deactivate our camera and stop the process of capturing frames -}; - -////////////////////////////////////////////////////////////////////////// -// CameraWindows - Subclass for our camera server on windows - -void CameraWindows::add_active_cameras(){ - ///@TODO scan through any active cameras and create CameraFeedWindows objects for them -}; - -CameraWindows::CameraWindows() { - // Find cameras active right now - add_active_cameras(); - - // need to add something that will react to devices being connected/removed... -}; - -CameraWindows::~CameraWindows(){ - -}; diff --git a/platform/windows/context_gl_windows.cpp b/platform/windows/context_gl_windows.cpp index e715999378..ad62e3a306 100644 --- a/platform/windows/context_gl_windows.cpp +++ b/platform/windows/context_gl_windows.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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,6 +34,8 @@ #include "context_gl_windows.h" +#include <dwmapi.h> + #define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091 #define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092 #define WGL_CONTEXT_FLAGS_ARB 0x2094 @@ -41,6 +43,11 @@ #define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126 #define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001 +#if defined(__GNUC__) +// Workaround GCC warning from -Wcast-function-type. +#define wglGetProcAddress (void *)wglGetProcAddress +#endif + typedef HGLRC(APIENTRY *PFNWGLCREATECONTEXTATTRIBSARBPROC)(HDC, HGLRC, const int *); void ContextGL_Windows::release_current() { @@ -63,16 +70,52 @@ int ContextGL_Windows::get_window_height() { return OS::get_singleton()->get_video_mode().height; } +bool ContextGL_Windows::should_vsync_via_compositor() { + + if (OS::get_singleton()->is_window_fullscreen() || !OS::get_singleton()->is_vsync_via_compositor_enabled()) { + return false; + } + + // Note: All Windows versions supported by Godot have a compositor. + // It can be disabled on earlier Windows versions. + BOOL dwm_enabled; + + if (SUCCEEDED(DwmIsCompositionEnabled(&dwm_enabled))) { + return dwm_enabled; + } + + return false; +} + void ContextGL_Windows::swap_buffers() { SwapBuffers(hDC); + + if (use_vsync) { + bool vsync_via_compositor_now = should_vsync_via_compositor(); + + if (vsync_via_compositor_now && wglGetSwapIntervalEXT() == 0) { + DwmFlush(); + } + + if (vsync_via_compositor_now != vsync_via_compositor) { + // The previous frame had a different operating mode than this + // frame. Set the 'vsync_via_compositor' member variable and the + // OpenGL swap interval to their proper values. + set_use_vsync(true); + } + } } void ContextGL_Windows::set_use_vsync(bool p_use) { + vsync_via_compositor = p_use && should_vsync_via_compositor(); + if (wglSwapIntervalEXT) { - wglSwapIntervalEXT(p_use ? 1 : 0); + int swap_interval = (p_use && !vsync_via_compositor) ? 1 : 0; + wglSwapIntervalEXT(swap_interval); } + use_vsync = p_use; } @@ -167,6 +210,7 @@ Error ContextGL_Windows::initialize() { } wglSwapIntervalEXT = (PFNWGLSWAPINTERVALEXTPROC)wglGetProcAddress("wglSwapIntervalEXT"); + wglGetSwapIntervalEXT = (PFNWGLGETSWAPINTERVALEXTPROC)wglGetProcAddress("wglGetSwapIntervalEXT"); //glWrapperInit(wrapper_get_proc_address); return OK; @@ -177,6 +221,7 @@ ContextGL_Windows::ContextGL_Windows(HWND hwnd, bool p_opengl_3_context) { opengl_3_context = p_opengl_3_context; hWnd = hwnd; use_vsync = false; + vsync_via_compositor = false; } ContextGL_Windows::~ContextGL_Windows() { diff --git a/platform/windows/context_gl_windows.h b/platform/windows/context_gl_windows.h index d23fba50e1..280c5a1e3c 100644 --- a/platform/windows/context_gl_windows.h +++ b/platform/windows/context_gl_windows.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -41,6 +41,7 @@ #include <windows.h> typedef bool(APIENTRY *PFNWGLSWAPINTERVALEXTPROC)(int interval); +typedef int(APIENTRY *PFNWGLGETSWAPINTERVALEXTPROC)(void); class ContextGL_Windows { @@ -50,8 +51,12 @@ class ContextGL_Windows { HWND hWnd; bool opengl_3_context; bool use_vsync; + bool vsync_via_compositor; PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT; + PFNWGLGETSWAPINTERVALEXTPROC wglGetSwapIntervalEXT; + + static bool should_vsync_via_compositor(); public: void release_current(); diff --git a/platform/windows/crash_handler_windows.cpp b/platform/windows/crash_handler_windows.cpp index 0716ee67f4..6145751e00 100644 --- a/platform/windows/crash_handler_windows.cpp +++ b/platform/windows/crash_handler_windows.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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/crash_handler_windows.h b/platform/windows/crash_handler_windows.h index eba72beb7e..adc548073c 100644 --- a/platform/windows/crash_handler_windows.h +++ b/platform/windows/crash_handler_windows.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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 9a2b2bcb98..3ab0d38a6a 100644 --- a/platform/windows/detect.py +++ b/platform/windows/detect.py @@ -151,14 +151,14 @@ def setup_msvc_auto(env): env['bits'] = '64' else: env['bits'] = '32' - print(" Found MSVC version %s, arch %s, bits=%s" % (env['MSVC_VERSION'], env['TARGET_ARCH'], env['bits'])) + print("Found MSVC version %s, arch %s, bits=%s" % (env['MSVC_VERSION'], env['TARGET_ARCH'], env['bits'])) if env['TARGET_ARCH'] in ('amd64', 'x86_64'): env["x86_libtheora_opt_vc"] = False def setup_mingw(env): """Set up env for use with mingw""" # Nothing to do here - print("Using Mingw") + print("Using MinGW") pass def configure_msvc(env, manual_msvc_config): @@ -207,7 +207,7 @@ def configure_msvc(env, manual_msvc_config): else: print("Missing environment variable: WindowsSdkDir") - env.AppendUnique(CPPDEFINES = ['WINDOWS_ENABLED', 'OPENGL_ENABLED', + env.AppendUnique(CPPDEFINES = ['WINDOWS_ENABLED', 'WASAPI_ENABLED', 'WINMIDI_ENABLED', 'TYPED_METHOD_BIND', 'WIN32', 'MSVC', @@ -219,9 +219,20 @@ def configure_msvc(env, manual_msvc_config): ## Libs - LIBS = ['winmm', 'opengl32', 'dsound', 'kernel32', 'ole32', 'oleaut32', + LIBS = ['winmm', 'dsound', 'kernel32', 'ole32', 'oleaut32', 'user32', 'gdi32', 'IPHLPAPI', 'Shlwapi', 'wsock32', 'Ws2_32', - 'shell32', 'advapi32', 'dinput8', 'dxguid', 'imm32', 'bcrypt','Avrt'] + 'shell32', 'advapi32', 'dinput8', 'dxguid', 'imm32', 'bcrypt', 'Avrt', + 'dwmapi'] + + env.AppendUnique(CPPDEFINES=['VULKAN_ENABLED']) + if not env['builtin_vulkan']: + LIBS += ['vulkan'] + else: + LIBS += ['cfgmgr32'] + + #env.AppendUnique(CPPDEFINES = ['OPENGL_ENABLED']) + LIBS += ['opengl32'] + env.Append(LINKFLAGS=[p + env["LIBSUFFIX"] for p in LIBS]) if manual_msvc_config: @@ -292,9 +303,7 @@ def configure_mingw(env): ## Compiler configuration - if (os.name == "nt"): - env['ENV']['TMP'] = os.environ['TMP'] # way to go scons, you can be so stupid sometimes - else: + if os.name != "nt": env["PROGSUFFIX"] = env["PROGSUFFIX"] + ".exe" # for linux cross-compilation if (env["bits"] == "default"): @@ -346,9 +355,20 @@ def configure_mingw(env): ## Compile flags env.Append(CCFLAGS=['-mwindows']) - env.Append(CPPDEFINES=['WINDOWS_ENABLED', 'OPENGL_ENABLED', 'WASAPI_ENABLED', 'WINMIDI_ENABLED']) + + env.Append(CPPDEFINES=['WINDOWS_ENABLED', 'WASAPI_ENABLED', 'WINMIDI_ENABLED']) env.Append(CPPDEFINES=[('WINVER', env['target_win_version']), ('_WIN32_WINNT', env['target_win_version'])]) - env.Append(LIBS=['mingw32', 'opengl32', 'dsound', 'ole32', 'd3d9', 'winmm', 'gdi32', 'iphlpapi', 'shlwapi', 'wsock32', 'ws2_32', 'kernel32', 'oleaut32', 'dinput8', 'dxguid', 'ksuser', 'imm32', 'bcrypt', 'avrt', 'uuid']) + env.Append(LIBS=['mingw32', 'dsound', 'ole32', 'd3d9', 'winmm', 'gdi32', 'iphlpapi', 'shlwapi', 'wsock32', 'ws2_32', 'kernel32', 'oleaut32', 'dinput8', 'dxguid', 'ksuser', 'imm32', 'bcrypt', 'avrt', 'uuid', 'dwmapi']) + + env.Append(CPPDEFINES=['VULKAN_ENABLED']) + if not env['builtin_vulkan']: + env.Append(LIBS=['vulkan']) + else: + env.Append(LIBS=['cfgmgr32']) + + ## TODO !!! Reenable when OpenGLES Rendering Device is implemented !!! + #env.Append(CPPDEFINES=['OPENGL_ENABLED']) + env.Append(LIBS=['opengl32']) env.Append(CPPDEFINES=['MINGW_ENABLED', ('MINGW_HAS_SECURE_API', 1)]) diff --git a/platform/windows/export/export.cpp b/platform/windows/export/export.cpp index 3abb05b494..78a3fc8f79 100644 --- a/platform/windows/export/export.cpp +++ b/platform/windows/export/export.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -39,6 +39,7 @@ static Error fixup_embedded_pck(const String &p_path, int64_t p_embedded_start, class EditorExportPlatformWindows : public EditorExportPlatformPC { + void _rcedit_add_data(const Ref<EditorExportPreset> &p_preset, const String &p_path); Error _code_sign(const Ref<EditorExportPreset> &p_preset, const String &p_path); public: @@ -62,15 +63,50 @@ Error EditorExportPlatformWindows::export_project(const Ref<EditorExportPreset> return err; } + _rcedit_add_data(p_preset, p_path); + + if (p_preset->get("codesign/enable") && err == OK) { + err = _code_sign(p_preset, p_path); + } + + return err; +} + +void EditorExportPlatformWindows::get_export_options(List<ExportOption> *r_options) { + EditorExportPlatformPC::get_export_options(r_options); + + r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "codesign/enable"), false)); +#ifdef WINDOWS_ENABLED + r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "codesign/identity_type", PROPERTY_HINT_ENUM, "Select automatically,Use PKCS12 file (specify *.PFX/*.P12 file),Use certificate store (specify SHA1 hash)"), 0)); +#endif + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "codesign/identity", PROPERTY_HINT_GLOBAL_FILE, "*.pfx,*.p12"), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "codesign/password"), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "codesign/timestamp"), true)); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "codesign/timestamp_server_url"), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "codesign/digest_algorithm", PROPERTY_HINT_ENUM, "SHA1,SHA256"), 1)); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "codesign/description"), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::PACKED_STRING_ARRAY, "codesign/custom_options"), PackedStringArray())); + + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/icon", PROPERTY_HINT_FILE, "*.ico"), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/file_version", PROPERTY_HINT_PLACEHOLDER_TEXT, "1.0.0"), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/product_version", PROPERTY_HINT_PLACEHOLDER_TEXT, "1.0.0"), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/company_name", PROPERTY_HINT_PLACEHOLDER_TEXT, "Company Name"), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/product_name", PROPERTY_HINT_PLACEHOLDER_TEXT, "Game Name"), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/file_description"), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/copyright"), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/trademarks"), "")); +} + +void EditorExportPlatformWindows::_rcedit_add_data(const Ref<EditorExportPreset> &p_preset, const String &p_path) { String rcedit_path = EditorSettings::get_singleton()->get("export/windows/rcedit"); if (rcedit_path == String()) { - return OK; + return; } if (!FileAccess::exists(rcedit_path)) { - ERR_PRINTS("Could not find rcedit executable at " + rcedit_path + ", aborting."); - return ERR_FILE_NOT_FOUND; + ERR_PRINT("Could not find rcedit executable at " + rcedit_path + ", no icon or app information data will be included."); + return; } #ifndef WINDOWS_ENABLED @@ -78,8 +114,8 @@ Error EditorExportPlatformWindows::export_project(const Ref<EditorExportPreset> String wine_path = EditorSettings::get_singleton()->get("export/windows/wine"); if (wine_path != String() && !FileAccess::exists(wine_path)) { - ERR_PRINTS("Could not find wine executable at " + wine_path + ", aborting."); - return ERR_FILE_NOT_FOUND; + ERR_PRINT("Could not find wine executable at " + wine_path + ", no icon or app information data will be included."); + return; } if (wine_path == String()) { @@ -144,37 +180,6 @@ Error EditorExportPlatformWindows::export_project(const Ref<EditorExportPreset> args.push_front(rcedit_path); OS::get_singleton()->execute(wine_path, args, true); #endif - - if (p_preset->get("codesign/enable") && err == OK) { - err = _code_sign(p_preset, p_path); - } - - return err; -} - -void EditorExportPlatformWindows::get_export_options(List<ExportOption> *r_options) { - EditorExportPlatformPC::get_export_options(r_options); - - r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "codesign/enable"), false)); -#ifdef WINDOWS_ENABLED - r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "codesign/identity_type", PROPERTY_HINT_ENUM, "Select automatically,Use PKCS12 file (specify *.PFX/*.P12 file),Use certificate store (specify SHA1 hash)"), 0)); -#endif - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "codesign/identity", PROPERTY_HINT_GLOBAL_FILE, "*.pfx,*.p12"), "")); - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "codesign/password"), "")); - r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "codesign/timestamp"), true)); - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "codesign/timestamp_server_url"), "")); - r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "codesign/digest_algorithm", PROPERTY_HINT_ENUM, "SHA1,SHA256"), 1)); - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "codesign/description"), "")); - r_options->push_back(ExportOption(PropertyInfo(Variant::POOL_STRING_ARRAY, "codesign/custom_options"), PoolStringArray())); - - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/icon", PROPERTY_HINT_FILE, "*.ico"), "")); - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/file_version", PROPERTY_HINT_PLACEHOLDER_TEXT, "1.0.0"), "")); - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/product_version", PROPERTY_HINT_PLACEHOLDER_TEXT, "1.0.0"), "")); - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/company_name", PROPERTY_HINT_PLACEHOLDER_TEXT, "Company Name"), "")); - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/product_name", PROPERTY_HINT_PLACEHOLDER_TEXT, "Game Name"), "")); - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/file_description"), "")); - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/copyright"), "")); - r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "application/trademarks"), "")); } Error EditorExportPlatformWindows::_code_sign(const Ref<EditorExportPreset> &p_preset, const String &p_path) { @@ -183,7 +188,7 @@ Error EditorExportPlatformWindows::_code_sign(const Ref<EditorExportPreset> &p_p #ifdef WINDOWS_ENABLED String signtool_path = EditorSettings::get_singleton()->get("export/windows/signtool"); if (signtool_path != String() && !FileAccess::exists(signtool_path)) { - ERR_PRINTS("Could not find signtool executable at " + signtool_path + ", aborting."); + ERR_PRINT("Could not find signtool executable at " + signtool_path + ", aborting."); return ERR_FILE_NOT_FOUND; } if (signtool_path == String()) { @@ -192,7 +197,7 @@ Error EditorExportPlatformWindows::_code_sign(const Ref<EditorExportPreset> &p_p #else String signtool_path = EditorSettings::get_singleton()->get("export/windows/osslsigncode"); if (signtool_path != String() && !FileAccess::exists(signtool_path)) { - ERR_PRINTS("Could not find osslsigncode executable at " + signtool_path + ", aborting."); + ERR_PRINT("Could not find osslsigncode executable at " + signtool_path + ", aborting."); return ERR_FILE_NOT_FOUND; } if (signtool_path == String()) { @@ -292,7 +297,7 @@ Error EditorExportPlatformWindows::_code_sign(const Ref<EditorExportPreset> &p_p } //user options - PoolStringArray user_args = p_preset->get("codesign/custom_options"); + PackedStringArray user_args = p_preset->get("codesign/custom_options"); for (int i = 0; i < user_args.size(); i++) { String user_arg = user_args[i].strip_edges(); if (!user_arg.empty()) { diff --git a/platform/windows/export/export.h b/platform/windows/export/export.h index e3431797b4..d669192831 100644 --- a/platform/windows/export/export.h +++ b/platform/windows/export/export.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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_res.rc b/platform/windows/godot_res.rc index 1fa8957f15..0593c8b069 100644 --- a/platform/windows/godot_res.rc +++ b/platform/windows/godot_res.rc @@ -4,10 +4,6 @@ #define _MKSTR(m_x) _STR(m_x) #endif -#ifndef VERSION_PATCH -#define VERSION_PATCH 0 -#endif - GODOT_ICON ICON platform/windows/godot.ico 1 VERSIONINFO diff --git a/platform/windows/godot_windows.cpp b/platform/windows/godot_windows.cpp index 11bfea6922..dcc12b7649 100644 --- a/platform/windows/godot_windows.cpp +++ b/platform/windows/godot_windows.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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_windows.cpp b/platform/windows/joypad_windows.cpp index 53ce342e8c..49432435b9 100644 --- a/platform/windows/joypad_windows.cpp +++ b/platform/windows/joypad_windows.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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,6 +37,11 @@ #define __builtin_bswap32 _byteswap_ulong #endif +#if defined(__GNUC__) +// Workaround GCC warning from -Wcast-function-type. +#define GetProcAddress (void *)GetProcAddress +#endif + DWORD WINAPI _xinput_get_state(DWORD dwUserIndex, XINPUT_STATE *pState) { return ERROR_DEVICE_NOT_CONNECTED; } diff --git a/platform/windows/joypad_windows.h b/platform/windows/joypad_windows.h index 4af5d9bd6a..ab85bc60ac 100644 --- a/platform/windows/joypad_windows.h +++ b/platform/windows/joypad_windows.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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_windows.cpp b/platform/windows/key_mapping_windows.cpp index 01bbb072bb..c76b31ca9c 100644 --- a/platform/windows/key_mapping_windows.cpp +++ b/platform/windows/key_mapping_windows.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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_windows.h b/platform/windows/key_mapping_windows.h index dbb8c20f1e..0f9bdecde1 100644 --- a/platform/windows/key_mapping_windows.h +++ b/platform/windows/key_mapping_windows.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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 f12893a8dc..f81bab13a4 100644 --- a/platform/windows/lang_table.h +++ b/platform/windows/lang_table.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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 429657f332..716a637993 100755..100644 --- a/platform/windows/os_windows.cpp +++ b/platform/windows/os_windows.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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,9 +34,17 @@ #include "os_windows.h" #include "core/io/marshalls.h" +#include "core/script_language.h" #include "core/version_generated.gen.h" + +#if defined(OPENGL_ENABLED) #include "drivers/gles2/rasterizer_gles2.h" -#include "drivers/gles3/rasterizer_gles3.h" +#endif + +#if defined(VULKAN_ENABLED) +#include "servers/visual/rasterizer_rd/rasterizer_rd.h" +#endif + #include "drivers/windows/dir_access_windows.h" #include "drivers/windows/file_access_windows.h" #include "drivers/windows/mutex_windows.h" @@ -74,6 +82,11 @@ __declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1; #define WM_POINTERUPDATE 0x0245 #endif +#if defined(__GNUC__) +// Workaround GCC warning from -Wcast-function-type. +#define GetProcAddress (void *)GetProcAddress +#endif + typedef struct { int count; int screen; @@ -352,12 +365,14 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) if (LOWORD(wParam) == WA_ACTIVE || LOWORD(wParam) == WA_CLICKACTIVE) { main_loop->notification(MainLoop::NOTIFICATION_WM_FOCUS_IN); + window_focused = true; alt_mem = false; control_mem = false; shift_mem = false; } else { // WM_INACTIVE input->release_pressed_events(); main_loop->notification(MainLoop::NOTIFICATION_WM_FOCUS_OUT); + window_focused = false; alt_mem = false; }; @@ -694,7 +709,7 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) break; } } - FALLTHROUGH; + [[fallthrough]]; case WM_MBUTTONDOWN: case WM_MBUTTONUP: case WM_RBUTTONDOWN: @@ -886,6 +901,11 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) preserve_window_size = false; set_window_size(Size2(video_mode.width, video_mode.height)); } +#if defined(VULKAN_ENABLED) + if (video_driver_index == VIDEO_DRIVER_VULKAN) { + context_vulkan->window_resize(0, video_mode.width, video_mode.height); + } +#endif } if (wParam == SIZE_MAXIMIZED) { @@ -964,7 +984,7 @@ LRESULT OS_Windows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) if (wParam==VK_WIN) TODO wtf is this? meta_mem=uMsg==WM_KEYDOWN; */ - FALLTHROUGH; + [[fallthrough]]; } case WM_CHAR: { @@ -1409,77 +1429,58 @@ Error OS_Windows::initialize(const VideoMode &p_desired, int p_video_driver, int SetWindowPos(hWnd, video_mode.always_on_top ? HWND_TOPMOST : HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); } -#if defined(OPENGL_ENABLED) - - bool gles3_context = true; - if (p_video_driver == VIDEO_DRIVER_GLES2) { - gles3_context = false; - } - - bool editor = Engine::get_singleton()->is_editor_hint(); - bool gl_initialization_error = false; - - gl_context = NULL; - while (!gl_context) { - gl_context = memnew(ContextGL_Windows(hWnd, gles3_context)); + //!!!!!!!!!!!!!!!!!!!!!!!!!! + //TODO - do Vulkan and GLES2 support checks, driver selection and fallback + video_driver_index = p_video_driver; + print_verbose("Driver: " + String(get_video_driver_name(video_driver_index)) + " [" + itos(video_driver_index) + "]"); + //!!!!!!!!!!!!!!!!!!!!!!!!!! - if (gl_context->initialize() != OK) { - memdelete(gl_context); - gl_context = NULL; + // Init context and rendering device +#if defined(OPENGL_ENABLED) + if (video_driver_index == VIDEO_DRIVER_GLES2) { - if (GLOBAL_GET("rendering/quality/driver/fallback_to_gles2") || editor) { - if (p_video_driver == VIDEO_DRIVER_GLES2) { - gl_initialization_error = true; - break; - } + context_gles2 = memnew(ContextGL_Windows(hWnd, false)); - p_video_driver = VIDEO_DRIVER_GLES2; - gles3_context = false; - } else { - gl_initialization_error = true; - break; - } + if (context_gles2->initialize() != OK) { + memdelete(context_gles2); + context_gles2 = NULL; + ERR_FAIL_V(ERR_UNAVAILABLE); } - } - while (true) { - if (gles3_context) { - if (RasterizerGLES3::is_viable() == OK) { - RasterizerGLES3::register_config(); - RasterizerGLES3::make_current(); - break; - } else { - if (GLOBAL_GET("rendering/quality/driver/fallback_to_gles2") || editor) { - p_video_driver = VIDEO_DRIVER_GLES2; - gles3_context = false; - continue; - } else { - gl_initialization_error = true; - break; - } - } + context_gles2->set_use_vsync(video_mode.use_vsync); + set_vsync_via_compositor(video_mode.vsync_via_compositor); + + if (RasterizerGLES2::is_viable() == OK) { + RasterizerGLES2::register_config(); + RasterizerGLES2::make_current(); } else { - if (RasterizerGLES2::is_viable() == OK) { - RasterizerGLES2::register_config(); - RasterizerGLES2::make_current(); - break; - } else { - gl_initialization_error = true; - break; - } + memdelete(context_gles2); + context_gles2 = NULL; + ERR_FAIL_V(ERR_UNAVAILABLE); } } +#endif +#if defined(VULKAN_ENABLED) + if (video_driver_index == VIDEO_DRIVER_VULKAN) { + + context_vulkan = memnew(VulkanContextWindows); + if (context_vulkan->initialize() != OK) { + memdelete(context_vulkan); + context_vulkan = NULL; + ERR_FAIL_V(ERR_UNAVAILABLE); + } + if (context_vulkan->window_create(hWnd, hInstance, get_video_mode().width, get_video_mode().height) == -1) { + memdelete(context_vulkan); + context_vulkan = NULL; + ERR_FAIL_V(ERR_UNAVAILABLE); + } - if (gl_initialization_error) { - OS::get_singleton()->alert("Your video card driver does not support any of the supported OpenGL versions.\n" - "Please update your drivers or if you have a very old or integrated GPU upgrade it.", - "Unable to initialize Video driver"); - return ERR_UNAVAILABLE; - } - - video_driver_index = p_video_driver; + //temporary + rendering_device_vulkan = memnew(RenderingDeviceVulkan); + rendering_device_vulkan->initialize(context_vulkan); - gl_context->set_use_vsync(video_mode.use_vsync); + RasterizerRD::make_current(); + } #endif visual_server = memnew(VisualServerRaster); @@ -1492,10 +1493,6 @@ Error OS_Windows::initialize(const VideoMode &p_desired, int p_video_driver, int input = memnew(InputDefault); joypad = memnew(JoypadWindows(input, &hWnd)); - power_manager = memnew(PowerWindows); - - camera_server = memnew(CameraWindows); - AudioDriverManager::initialize(p_audio_driver); TRACKMOUSEEVENT tme; @@ -1649,15 +1646,30 @@ void OS_Windows::finalize() { memdelete(joypad); memdelete(input); - memdelete(camera_server); touch_state.clear(); cursors_cache.clear(); visual_server->finish(); memdelete(visual_server); -#ifdef OPENGL_ENABLED - if (gl_context) - memdelete(gl_context); + +#if defined(OPENGL_ENABLED) + if (video_driver_index == VIDEO_DRIVER_GLES2) { + + if (context_gles2) + memdelete(context_gles2); + } +#endif +#if defined(VULKAN_ENABLED) + if (video_driver_index == VIDEO_DRIVER_VULKAN) { + + if (rendering_device_vulkan) { + rendering_device_vulkan->finalize(); + memdelete(rendering_device_vulkan); + } + + if (context_vulkan) + memdelete(context_vulkan); + } #endif if (user_proc) { @@ -1959,6 +1971,11 @@ void OS_Windows::set_window_size(const Size2 p_size) { video_mode.width = w; video_mode.height = h; +#if defined(VULKAN_ENABLED) + if (video_driver_index == VIDEO_DRIVER_VULKAN) { + context_vulkan->window_resize(0, video_mode.width, video_mode.height); + } +#endif if (video_mode.fullscreen) { return; @@ -2097,6 +2114,11 @@ bool OS_Windows::is_window_always_on_top() const { return video_mode.always_on_top; } +bool OS_Windows::is_window_focused() const { + + return window_focused; +} + void OS_Windows::set_console_visible(bool p_enabled) { if (console_visible == p_enabled) return; @@ -2507,7 +2529,7 @@ void OS_Windows::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shap cursors_cache.erase(p_shape); } - Ref<Texture> texture = p_cursor; + Ref<Texture2D> texture = p_cursor; Ref<AtlasTexture> atlas_texture = p_cursor; Ref<Image> image; Size2 texture_size; @@ -2546,7 +2568,6 @@ void OS_Windows::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shap // Create the BITMAP with alpha channel COLORREF *buffer = (COLORREF *)memalloc(sizeof(COLORREF) * image_size); - image->lock(); for (UINT index = 0; index < image_size; index++) { int row_index = floor(index / texture_size.width) + atlas_rect.position.y; int column_index = (index % int(texture_size.width)) + atlas_rect.position.x; @@ -2558,7 +2579,6 @@ void OS_Windows::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shap *(buffer + index) = image->get_pixel(column_index, row_index).to_argb32(); } - image->unlock(); // Using 4 channels, so 4 * 8 bits HBITMAP bitmap = CreateBitmap(texture_size.width, texture_size.height, 1, 4 * 8, buffer); @@ -2844,7 +2864,7 @@ void OS_Windows::set_native_icon(const String &p_filename) { ERR_FAIL_COND_MSG(big_icon_index == -1, "No valid icons found!"); if (small_icon_index == -1) { - WARN_PRINTS("No small icon found, reusing " + itos(big_icon_width) + "x" + itos(big_icon_width) + " @" + itos(big_icon_cc) + " icon!"); + WARN_PRINT("No small icon found, reusing " + itos(big_icon_width) + "x" + itos(big_icon_width) + " @" + itos(big_icon_cc) + " icon!"); small_icon_index = big_icon_index; small_icon_cc = big_icon_cc; } @@ -2913,7 +2933,7 @@ void OS_Windows::set_icon(const Ref<Image> &p_icon) { encode_uint32(0, &icon_bmp[36]); uint8_t *wr = &icon_bmp[40]; - PoolVector<uint8_t>::Read r = icon->get_data().read(); + const uint8_t *r = icon->get_data().ptr(); for (int i = 0; i < h; i++) { @@ -3111,18 +3131,32 @@ OS::LatinKeyboardVariant OS_Windows::get_latin_keyboard_variant() const { } void OS_Windows::release_rendering_thread() { - - gl_context->release_current(); +#if defined(OPENGL_ENABLED) + if (video_driver_index == VIDEO_DRIVER_GLES2) { + context_gles2->release_current(); + } +#endif } void OS_Windows::make_rendering_thread() { - - gl_context->make_current(); +#if defined(OPENGL_ENABLED) + if (video_driver_index == VIDEO_DRIVER_GLES2) { + context_gles2->make_current(); + } +#endif } void OS_Windows::swap_buffers() { - - gl_context->swap_buffers(); +#if defined(OPENGL_ENABLED) + if (video_driver_index == VIDEO_DRIVER_GLES2) { + context_gles2->swap_buffers(); + } +#endif +#if defined(VULKAN_ENABLED) + if (video_driver_index == VIDEO_DRIVER_VULKAN) { + context_vulkan->swap_buffers(); + } +#endif } void OS_Windows::force_process_input() { @@ -3289,29 +3323,12 @@ String OS_Windows::get_joy_guid(int p_device) const { } void OS_Windows::_set_use_vsync(bool p_enable) { - - if (gl_context) - gl_context->set_use_vsync(p_enable); -} -/* -bool OS_Windows::is_vsync_enabled() const { - - if (gl_context) - return gl_context->is_using_vsync(); - - return true; -}*/ - -OS::PowerState OS_Windows::get_power_state() { - return power_manager->get_power_state(); -} - -int OS_Windows::get_power_seconds_left() { - return power_manager->get_power_seconds_left(); -} - -int OS_Windows::get_power_percent_left() { - return power_manager->get_power_percent_left(); +#if defined(OPENGL_ENABLED) + if (video_driver_index == VIDEO_DRIVER_GLES2) { + if (context_gles2) + context_gles2->set_use_vsync(p_enable); + } +#endif } bool OS_Windows::_check_internal_feature_support(const String &p_feature) { @@ -3353,7 +3370,7 @@ Error OS_Windows::move_to_trash(const String &p_path) { delete[] from; if (ret) { - ERR_PRINTS("SHFileOperation error: " + itos(ret)); + ERR_PRINT("SHFileOperation error: " + itos(ret)); return FAILED; } @@ -3374,6 +3391,7 @@ OS_Windows::OS_Windows(HINSTANCE _hInstance) { meta_mem = false; minimized = false; was_maximized = false; + window_focused = true; console_visible = IsWindowVisible(GetConsoleWindow()); //Note: Functions for pen input, available on Windows 8+ diff --git a/platform/windows/os_windows.h b/platform/windows/os_windows.h index ce279fb033..6c3769c98c 100644 --- a/platform/windows/os_windows.h +++ b/platform/windows/os_windows.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -31,8 +31,6 @@ #ifndef OS_WINDOWS_H #define OS_WINDOWS_H -#include "camera_win.h" -#include "context_gl_windows.h" #include "core/os/input.h" #include "core/os/os.h" #include "core/project_settings.h" @@ -42,7 +40,6 @@ #include "drivers/winmidi/midi_driver_winmidi.h" #include "key_mapping_windows.h" #include "main/input_default.h" -#include "power_windows.h" #include "servers/audio_server.h" #include "servers/visual/rasterizer.h" #include "servers/visual_server.h" @@ -50,6 +47,15 @@ #include "drivers/xaudio2/audio_driver_xaudio2.h" #endif +#if defined(OPENGL_ENABLED) +#include "context_gl_windows.h" +#endif + +#if defined(VULKAN_ENABLED) +#include "drivers/vulkan/rendering_device_vulkan.h" +#include "platform/windows/vulkan_context_win.h" +#endif + #include <fcntl.h> #include <io.h> #include <stdio.h> @@ -171,11 +177,17 @@ class OS_Windows : public OS { bool outside; int old_x, old_y; Point2i center; + #if defined(OPENGL_ENABLED) - ContextGL_Windows *gl_context; + ContextGL_Windows *context_gles2; +#endif + +#if defined(VULKAN_ENABLED) + VulkanContextWindows *context_vulkan; + RenderingDeviceVulkan *rendering_device_vulkan; #endif + VisualServer *visual_server; - CameraWindows *camera_server; int pressrc; HINSTANCE hInstance; // Holds The Instance Of The Application HWND hWnd; @@ -226,8 +238,6 @@ class OS_Windows : public OS { JoypadWindows *joypad; Map<int, Vector2> touch_state; - PowerWindows *power_manager; - int video_driver_index; #ifdef WASAPI_ENABLED AudioDriverWASAPI driver_wasapi; @@ -276,6 +286,7 @@ protected: bool maximized; bool minimized; bool borderless; + bool window_focused; bool console_visible; bool was_maximized; @@ -324,6 +335,7 @@ public: virtual bool is_window_maximized() const; virtual void set_window_always_on_top(bool p_enabled); virtual bool is_window_always_on_top() const; + virtual bool is_window_focused() const; virtual void set_console_visible(bool p_enabled); virtual bool is_console_visible() const; virtual void request_attention(); @@ -359,7 +371,7 @@ public: virtual void delay_usec(uint32_t p_usec) const; virtual uint64_t get_ticks_usec() const; - virtual Error execute(const String &p_path, const List<String> &p_arguments, bool p_blocking, ProcessID *r_child_id = NULL, String *r_pipe = NULL, int *r_exitcode = NULL, bool read_stderr = false, Mutex *p_pipe_mutex = NULL); + virtual Error execute(const String &p_path, const List<String> &p_arguments, bool p_blocking = true, ProcessID *r_child_id = NULL, String *r_pipe = NULL, int *r_exitcode = NULL, bool read_stderr = false, Mutex *p_pipe_mutex = NULL); virtual Error kill(const ProcessID &p_pid); virtual int get_process_id() const; @@ -418,10 +430,6 @@ public: virtual void _set_use_vsync(bool p_enable); //virtual bool is_vsync_enabled() const; - virtual OS::PowerState get_power_state(); - virtual int get_power_seconds_left(); - virtual int get_power_percent_left(); - virtual bool _check_internal_feature_support(const String &p_feature); void disable_crash_handler(); diff --git a/platform/windows/platform_config.h b/platform/windows/platform_config.h index 8a4aab5c36..290decac5f 100644 --- a/platform/windows/platform_config.h +++ b/platform/windows/platform_config.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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,8 +29,5 @@ /*************************************************************************/ #include <malloc.h> -//#else -//#include <alloca.h> -//#endif -#define GLES3_INCLUDE_H "thirdparty/glad/glad/glad.h" + #define GLES2_INCLUDE_H "thirdparty/glad/glad/glad.h" diff --git a/platform/windows/power_windows.cpp b/platform/windows/power_windows.cpp deleted file mode 100644 index 0efd88c216..0000000000 --- a/platform/windows/power_windows.cpp +++ /dev/null @@ -1,131 +0,0 @@ -/*************************************************************************/ -/* power_windows.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -/* -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 - -bool PowerWindows::GetPowerInfo_Windows() { - SYSTEM_POWER_STATUS status; - bool need_details = FALSE; - - /* This API should exist back to Win95. */ - if (!GetSystemPowerStatus(&status)) { - /* !!! FIXME: push GetLastError() into GetError() */ - power_state = OS::POWERSTATE_UNKNOWN; - } else if (status.BatteryFlag == 0xFF) { /* unknown state */ - power_state = OS::POWERSTATE_UNKNOWN; - } else if (status.BatteryFlag & (1 << 7)) { /* no battery */ - power_state = OS::POWERSTATE_NO_BATTERY; - } else if (status.BatteryFlag & (1 << 3)) { /* charging */ - power_state = OS::POWERSTATE_CHARGING; - need_details = TRUE; - } else if (status.ACLineStatus == 1) { - power_state = OS::POWERSTATE_CHARGED; /* on AC, not charging. */ - need_details = TRUE; - } else { - power_state = OS::POWERSTATE_ON_BATTERY; /* not on AC. */ - need_details = TRUE; - } - - percent_left = -1; - nsecs_left = -1; - if (need_details) { - const int pct = (int)status.BatteryLifePercent; - const int secs = (int)status.BatteryLifeTime; - - if (pct != 255) { /* 255 == unknown */ - percent_left = (pct > 100) ? 100 : pct; /* clamp between 0%, 100% */ - } - if (secs != (int)0xFFFFFFFF) { /* ((DWORD)-1) == unknown */ - nsecs_left = secs; - } - } - - return TRUE; /* always the definitive answer on Windows. */ -} - -OS::PowerState PowerWindows::get_power_state() { - if (GetPowerInfo_Windows()) { - return power_state; - } else { - return OS::POWERSTATE_UNKNOWN; - } -} - -int PowerWindows::get_power_seconds_left() { - if (GetPowerInfo_Windows()) { - return nsecs_left; - } else { - return -1; - } -} - -int PowerWindows::get_power_percent_left() { - if (GetPowerInfo_Windows()) { - return percent_left; - } else { - return -1; - } -} - -PowerWindows::PowerWindows() : - nsecs_left(-1), - percent_left(-1), - power_state(OS::POWERSTATE_UNKNOWN) { -} - -PowerWindows::~PowerWindows() { -} diff --git a/platform/windows/vulkan_context_win.cpp b/platform/windows/vulkan_context_win.cpp new file mode 100644 index 0000000000..20e1b46682 --- /dev/null +++ b/platform/windows/vulkan_context_win.cpp @@ -0,0 +1,57 @@ +/*************************************************************************/ +/* vulkan_context_win.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "vulkan_context_win.h" +#include <vulkan/vulkan_win32.h> + +const char *VulkanContextWindows::_get_platform_surface_extension() const { + return VK_KHR_WIN32_SURFACE_EXTENSION_NAME; +} + +int VulkanContextWindows::window_create(HWND p_window, HINSTANCE p_instance, int p_width, int p_height) { + + VkWin32SurfaceCreateInfoKHR createInfo; + createInfo.sType = VK_STRUCTURE_TYPE_WIN32_SURFACE_CREATE_INFO_KHR; + createInfo.pNext = NULL; + createInfo.flags = 0; + createInfo.hinstance = p_instance; + createInfo.hwnd = p_window; + + VkSurfaceKHR surface; + VkResult err = vkCreateWin32SurfaceKHR(_get_instance(), &createInfo, NULL, &surface); + ERR_FAIL_COND_V(err, -1); + return _window_create(surface, p_width, p_height); +} + +VulkanContextWindows::VulkanContextWindows() { +} + +VulkanContextWindows::~VulkanContextWindows() { +} diff --git a/platform/uwp/power_uwp.h b/platform/windows/vulkan_context_win.h index cc19904a62..1289f2a299 100644 --- a/platform/uwp/power_uwp.h +++ b/platform/windows/vulkan_context_win.h @@ -1,12 +1,12 @@ /*************************************************************************/ -/* power_uwp.h */ +/* vulkan_context_win.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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,29 +28,21 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef POWER_UWP_H -#define POWER_UWP_H +#ifndef VULKAN_DEVICE_WIN_H +#define VULKAN_DEVICE_WIN_H -#include "core/os/dir_access.h" -#include "core/os/file_access.h" -#include "core/os/os.h" +#include "drivers/vulkan/vulkan_context.h" +#include <windows.h> -class PowerUWP { +class VulkanContextWindows : public VulkanContext { -private: - int nsecs_left; - int percent_left; - OS::PowerState power_state; - - bool UpdatePowerInfo(); + virtual const char *_get_platform_surface_extension() const; public: - PowerUWP(); - virtual ~PowerUWP(); + int window_create(HWND p_window, HINSTANCE p_instance, int p_width, int p_height); - OS::PowerState get_power_state(); - int get_power_seconds_left(); - int get_power_percent_left(); + VulkanContextWindows(); + ~VulkanContextWindows(); }; -#endif // POWER_UWP_H +#endif // VULKAN_DEVICE_WIN_H diff --git a/platform/windows/windows_terminal_logger.cpp b/platform/windows/windows_terminal_logger.cpp index adbdafb07e..520b654b94 100644 --- a/platform/windows/windows_terminal_logger.cpp +++ b/platform/windows/windows_terminal_logger.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -85,7 +85,6 @@ void WindowsTerminalLogger::log_error(const char *p_function, const char *p_file CONSOLE_SCREEN_BUFFER_INFO sbi; //original GetConsoleScreenBufferInfo(hCon, &sbi); - WORD current_fg = sbi.wAttributes & (FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY); WORD current_bg = sbi.wAttributes & (BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE | BACKGROUND_INTENSITY); uint32_t basecol = 0; @@ -98,53 +97,34 @@ void WindowsTerminalLogger::log_error(const char *p_function, const char *p_file basecol |= current_bg; - if (p_rationale && p_rationale[0]) { - - SetConsoleTextAttribute(hCon, basecol | FOREGROUND_INTENSITY); - switch (p_type) { - case ERR_ERROR: logf("ERROR: "); break; - case ERR_WARNING: logf("WARNING: "); break; - case ERR_SCRIPT: logf("SCRIPT ERROR: "); break; - case ERR_SHADER: logf("SHADER ERROR: "); break; - } - - SetConsoleTextAttribute(hCon, current_fg | current_bg | FOREGROUND_INTENSITY); - logf("%s\n", p_rationale); + SetConsoleTextAttribute(hCon, basecol | FOREGROUND_INTENSITY); + switch (p_type) { + case ERR_ERROR: logf("ERROR:"); break; + case ERR_WARNING: logf("WARNING:"); break; + case ERR_SCRIPT: logf("SCRIPT ERROR:"); break; + case ERR_SHADER: logf("SHADER ERROR:"); break; + } - SetConsoleTextAttribute(hCon, basecol); - switch (p_type) { - case ERR_ERROR: logf(" At: "); break; - case ERR_WARNING: logf(" At: "); break; - case ERR_SCRIPT: logf(" At: "); break; - case ERR_SHADER: logf(" At: "); break; - } + SetConsoleTextAttribute(hCon, basecol); + if (p_rationale && p_rationale[0]) { + logf(" %s\n", p_rationale); + } else { + logf(" %s\n", p_code); + } - SetConsoleTextAttribute(hCon, current_fg | current_bg); - logf("%s:%i\n", p_file, p_line); + // `FOREGROUND_INTENSITY` alone results in gray text. + SetConsoleTextAttribute(hCon, FOREGROUND_INTENSITY); + switch (p_type) { + case ERR_ERROR: logf(" at: "); break; + case ERR_WARNING: logf(" at: "); break; + case ERR_SCRIPT: logf(" at: "); break; + case ERR_SHADER: logf(" at: "); break; + } + if (p_rationale && p_rationale[0]) { + logf("(%s:%i)\n", p_file, p_line); } else { - - SetConsoleTextAttribute(hCon, basecol | FOREGROUND_INTENSITY); - switch (p_type) { - case ERR_ERROR: logf("ERROR: %s: ", p_function); break; - case ERR_WARNING: logf("WARNING: %s: ", p_function); break; - case ERR_SCRIPT: logf("SCRIPT ERROR: %s: ", p_function); break; - case ERR_SHADER: logf("SCRIPT ERROR: %s: ", p_function); break; - } - - SetConsoleTextAttribute(hCon, current_fg | current_bg | FOREGROUND_INTENSITY); - logf("%s\n", p_code); - - SetConsoleTextAttribute(hCon, basecol); - switch (p_type) { - case ERR_ERROR: logf(" At: "); break; - case ERR_WARNING: logf(" At: "); break; - case ERR_SCRIPT: logf(" At: "); break; - case ERR_SHADER: logf(" At: "); break; - } - - SetConsoleTextAttribute(hCon, current_fg | current_bg); - logf("%s:%i\n", p_file, p_line); + logf("%s (%s:%i)\n", p_function, p_file, p_line); } SetConsoleTextAttribute(hCon, sbi.wAttributes); diff --git a/platform/windows/windows_terminal_logger.h b/platform/windows/windows_terminal_logger.h index 475e1f25ab..d4443a707d 100644 --- a/platform/windows/windows_terminal_logger.h +++ b/platform/windows/windows_terminal_logger.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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/SCsub b/platform/x11/SCsub index 3d5aa15208..2268e4cc3d 100644 --- a/platform/x11/SCsub +++ b/platform/x11/SCsub @@ -7,11 +7,11 @@ import platform_x11_builders common_x11 = [ "context_gl_x11.cpp", + "vulkan_context_x11.cpp", "crash_handler_x11.cpp", "os_x11.cpp", "key_mapping_x11.cpp", "joypad_linux.cpp", - "power_x11.cpp", "detect_prime.cpp" ] diff --git a/platform/x11/context_gl_x11.cpp b/platform/x11/context_gl_x11.cpp index d70b947fcc..5442af3bef 100644 --- a/platform/x11/context_gl_x11.cpp +++ b/platform/x11/context_gl_x11.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -166,29 +166,11 @@ Error ContextGL_X11::initialize() { int (*oldHandler)(Display *, XErrorEvent *) = XSetErrorHandler(&ctxErrorHandler); switch (context_type) { - case OLDSTYLE: { - - p->glx_context = glXCreateContext(x11_display, vi, 0, GL_TRUE); - ERR_FAIL_COND_V(!p->glx_context, ERR_UNCONFIGURED); - } break; case GLES_2_0_COMPATIBLE: { p->glx_context = glXCreateNewContext(x11_display, fbconfig, GLX_RGBA_TYPE, 0, true); ERR_FAIL_COND_V(!p->glx_context, ERR_UNCONFIGURED); } break; - case GLES_3_0_COMPATIBLE: { - - static int context_attribs[] = { - GLX_CONTEXT_MAJOR_VERSION_ARB, 3, - GLX_CONTEXT_MINOR_VERSION_ARB, 3, - GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB, - GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB /*|GLX_CONTEXT_DEBUG_BIT_ARB*/, - None - }; - - p->glx_context = glXCreateContextAttribsARB(x11_display, fbconfig, NULL, true, context_attribs); - ERR_FAIL_COND_V(ctxErrorOccurred || !p->glx_context, ERR_UNCONFIGURED); - } break; } swa.colormap = XCreateColormap(x11_display, RootWindow(x11_display, vi->screen), vi->visual, AllocNone); diff --git a/platform/x11/context_gl_x11.h b/platform/x11/context_gl_x11.h index 095ce2154b..2c0643c95a 100644 --- a/platform/x11/context_gl_x11.h +++ b/platform/x11/context_gl_x11.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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,15 +45,12 @@ class ContextGL_X11 { public: enum ContextType { - OLDSTYLE, GLES_2_0_COMPATIBLE, - GLES_3_0_COMPATIBLE }; private: ContextGL_X11_Private *p; OS::VideoMode default_video_mode; - //::Colormap x11_colormap; ::Display *x11_display; ::Window &x11_window; bool double_buffer; diff --git a/platform/x11/crash_handler_x11.cpp b/platform/x11/crash_handler_x11.cpp index ca7251078f..19c8f71d0e 100644 --- a/platform/x11/crash_handler_x11.cpp +++ b/platform/x11/crash_handler_x11.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -107,7 +107,7 @@ static void handle_crash(int sig) { output.erase(output.length() - 1, 1); } - fprintf(stderr, "[%ld] %s (%ls)\n", i, fname, output.c_str()); + fprintf(stderr, "[%ld] %s (%ls)\n", (long int)i, fname, output.c_str()); } free(strings); diff --git a/platform/x11/crash_handler_x11.h b/platform/x11/crash_handler_x11.h index d0664aef85..98620cc789 100644 --- a/platform/x11/crash_handler_x11.h +++ b/platform/x11/crash_handler_x11.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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 b8ff97279d..b5b7895da9 100644 --- a/platform/x11/detect.py +++ b/platform/x11/detect.py @@ -171,7 +171,7 @@ def configure(env): else: env.Append(CCFLAGS=['-flto']) env.Append(LINKFLAGS=['-flto']) - + if not env['use_llvm']: env['RANLIB'] = 'gcc-ranlib' env['AR'] = 'gcc-ar' @@ -179,18 +179,10 @@ def configure(env): env.Append(CCFLAGS=['-pipe']) env.Append(LINKFLAGS=['-pipe']) - # Check for gcc version >= 6 before adding -no-pie - if using_gcc(env): - version = get_compiler_version(env) - if version != None and version[0] >= '6': - env.Append(CCFLAGS=['-fpie']) - env.Append(LINKFLAGS=['-no-pie']) - # Do the same for clang should be fine with Clang 4 and higher - if using_clang(env): - version = get_compiler_version(env) - if version != None and version[0] >= '4': - env.Append(CCFLAGS=['-fpie']) - env.Append(LINKFLAGS=['-no-pie']) + # -fpie and -no-pie is supported on GCC 6+ and Clang 4+, both below our + # minimal requirements. + env.Append(CCFLAGS=['-fpie']) + env.Append(LINKFLAGS=['-no-pie']) ## Dependencies @@ -232,7 +224,7 @@ def configure(env): if not env['builtin_enet']: env.ParseConfig('pkg-config libenet --cflags --libs') - if not env['builtin_squish'] and env['tools']: + if not env['builtin_squish']: env.ParseConfig('pkg-config libsquish --cflags --libs') if not env['builtin_zstd']: @@ -318,8 +310,19 @@ def configure(env): env.ParseConfig('pkg-config zlib --cflags --libs') env.Prepend(CPPPATH=['#platform/x11']) - env.Append(CPPDEFINES=['X11_ENABLED', 'UNIX_ENABLED', 'OPENGL_ENABLED', 'GLES_ENABLED']) - env.Append(LIBS=['GL', 'pthread']) + env.Append(CPPDEFINES=['X11_ENABLED', 'UNIX_ENABLED']) + + env.Append(CPPDEFINES=['VULKAN_ENABLED']) + if not env['builtin_vulkan']: + env.ParseConfig('pkg-config vulkan --cflags --libs') + if not env['builtin_glslang']: + # No pkgconfig file for glslang so far + env.Append(LIBS=['glslang', 'SPIRV']) + + #env.Append(CPPDEFINES=['OPENGL_ENABLED']) + env.Append(LIBS=['GL']) + + env.Append(LIBS=['pthread']) if (platform.system() == "Linux"): env.Append(LIBS=['dl']) @@ -329,9 +332,19 @@ def configure(env): if env["execinfo"]: env.Append(LIBS=['execinfo']) - + if not env['tools']: - env.Append(LINKFLAGS=['-T', 'platform/x11/pck_embed.ld']) + import subprocess + import re + linker_version_str = subprocess.check_output([env.subst(env["LINK"]), '-Wl,--version']).decode("utf-8") + gnu_ld_version = re.search('^GNU ld [^$]*(\d+\.\d+)$', linker_version_str, re.MULTILINE) + if not gnu_ld_version: + print("Warning: Creating template binaries enabled for PCK embedding is currently only supported with GNU ld") + else: + if float(gnu_ld_version.group(1)) >= 2.30: + env.Append(LINKFLAGS=['-T', 'platform/x11/pck_embed.ld']) + else: + env.Append(LINKFLAGS=['-T', 'platform/x11/pck_embed.legacy.ld']) ## Cross-compilation diff --git a/platform/x11/detect_prime.cpp b/platform/x11/detect_prime.cpp index 26008feade..98a51ff27c 100644 --- a/platform/x11/detect_prime.cpp +++ b/platform/x11/detect_prime.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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_prime.h b/platform/x11/detect_prime.h index 13bcf6fc38..df636449f4 100644 --- a/platform/x11/detect_prime.h +++ b/platform/x11/detect_prime.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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/export/export.cpp b/platform/x11/export/export.cpp index 6e66173463..1c0c6ec096 100644 --- a/platform/x11/export/export.cpp +++ b/platform/x11/export/export.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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/export/export.h b/platform/x11/export/export.h index 61b9a77524..d94ea114a8 100644 --- a/platform/x11/export/export.h +++ b/platform/x11/export/export.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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 755ef7a84f..77b74184ad 100644 --- a/platform/x11/godot_x11.cpp +++ b/platform/x11/godot_x11.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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 4242952374..a64a25aeee 100644 --- a/platform/x11/joypad_linux.cpp +++ b/platform/x11/joypad_linux.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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.h b/platform/x11/joypad_linux.h index b5904ce90b..e5638899bf 100644 --- a/platform/x11/joypad_linux.h +++ b/platform/x11/joypad_linux.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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.cpp b/platform/x11/key_mapping_x11.cpp index 9b5dfa4793..54e1e1d357 100644 --- a/platform/x11/key_mapping_x11.cpp +++ b/platform/x11/key_mapping_x11.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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 4e25d6a6ed..e99bf1694b 100644 --- a/platform/x11/key_mapping_x11.h +++ b/platform/x11/key_mapping_x11.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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 54d3759cc5..36e9681f5f 100644 --- a/platform/x11/os_x11.cpp +++ b/platform/x11/os_x11.cpp @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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,10 +33,17 @@ #include "core/os/dir_access.h" #include "core/print_string.h" -#include "drivers/gles2/rasterizer_gles2.h" -#include "drivers/gles3/rasterizer_gles3.h" #include "errno.h" #include "key_mapping_x11.h" + +#if defined(OPENGL_ENABLED) +#include "drivers/gles2/rasterizer_gles2.h" +#endif + +#if defined(VULKAN_ENABLED) +#include "servers/visual/rasterizer_rd/rasterizer_rd.h" +#endif + #include "servers/visual/visual_server_raster.h" #include "servers/visual/visual_server_wrap_mt.h" @@ -230,137 +237,131 @@ Error OS_X11::initialize(const VideoMode &p_desired, int p_video_driver, int p_a XFree(imvalret); } -/* - char* windowid = getenv("GODOT_WINDOWID"); - if (windowid) { - - //freopen("/home/punto/stdout", "w", stdout); - //reopen("/home/punto/stderr", "w", stderr); - x11_window = atol(windowid); - - XWindowAttributes xwa; - XGetWindowAttributes(x11_display,x11_window,&xwa); - - current_videomode.width = xwa.width; - current_videomode.height = xwa.height; - }; - */ - -// maybe contextgl wants to be in charge of creating the window -#if defined(OPENGL_ENABLED) - if (getenv("DRI_PRIME") == NULL) { - int use_prime = -1; + //!!!!!!!!!!!!!!!!!!!!!!!!!! + //TODO - do Vulkan and GLES2 support checks, driver selection and fallback + video_driver_index = p_video_driver; +#ifndef _MSC_VER +#warning Forcing vulkan video driver because OpenGL not implemented yet +#endif + video_driver_index = VIDEO_DRIVER_VULKAN; - if (getenv("PRIMUS_DISPLAY") || - getenv("PRIMUS_libGLd") || - getenv("PRIMUS_libGLa") || - getenv("PRIMUS_libGL") || - getenv("PRIMUS_LOAD_GLOBAL") || - getenv("BUMBLEBEE_SOCKET")) { + print_verbose("Driver: " + String(get_video_driver_name(video_driver_index)) + " [" + itos(video_driver_index) + "]"); + //!!!!!!!!!!!!!!!!!!!!!!!!!! - print_verbose("Optirun/primusrun detected. Skipping GPU detection"); - use_prime = 0; - } + //Create window - if (getenv("LD_LIBRARY_PATH")) { - String ld_library_path(getenv("LD_LIBRARY_PATH")); - Vector<String> libraries = ld_library_path.split(":"); + long visualMask = VisualScreenMask; + int numberOfVisuals; + XVisualInfo vInfoTemplate = {}; + vInfoTemplate.screen = DefaultScreen(x11_display); + XVisualInfo *visualInfo = XGetVisualInfo(x11_display, visualMask, &vInfoTemplate, &numberOfVisuals); - for (int i = 0; i < libraries.size(); ++i) { - if (FileAccess::exists(libraries[i] + "/libGL.so.1") || - FileAccess::exists(libraries[i] + "/libGL.so")) { + Colormap colormap = XCreateColormap(x11_display, RootWindow(x11_display, vInfoTemplate.screen), visualInfo->visual, AllocNone); - print_verbose("Custom libGL override detected. Skipping GPU detection"); - use_prime = 0; - } - } - } + XSetWindowAttributes windowAttributes = {}; + windowAttributes.colormap = colormap; + windowAttributes.background_pixel = 0xFFFFFFFF; + windowAttributes.border_pixel = 0; + windowAttributes.event_mask = KeyPressMask | KeyReleaseMask | StructureNotifyMask | ExposureMask; - if (use_prime == -1) { - print_verbose("Detecting GPUs, set DRI_PRIME in the environment to override GPU detection logic."); - use_prime = detect_prime(); - } + unsigned long valuemask = CWBorderPixel | CWColormap | CWEventMask; + x11_window = XCreateWindow(x11_display, RootWindow(x11_display, visualInfo->screen), 0, 0, OS::get_singleton()->get_video_mode().width, OS::get_singleton()->get_video_mode().height, 0, visualInfo->depth, InputOutput, visualInfo->visual, valuemask, &windowAttributes); - if (use_prime) { - print_line("Found discrete GPU, setting DRI_PRIME=1 to use it."); - print_line("Note: Set DRI_PRIME=0 in the environment to disable Godot from using the discrete GPU."); - setenv("DRI_PRIME", "1", 1); - } - } + //set_class_hint(x11_display, x11_window); + XMapWindow(x11_display, x11_window); + XFlush(x11_display); - ContextGL_X11::ContextType opengl_api_type = ContextGL_X11::GLES_3_0_COMPATIBLE; + XSync(x11_display, False); + //XSetErrorHandler(oldHandler); - if (p_video_driver == VIDEO_DRIVER_GLES2) { - opengl_api_type = ContextGL_X11::GLES_2_0_COMPATIBLE; - } + XFree(visualInfo); - bool editor = Engine::get_singleton()->is_editor_hint(); - bool gl_initialization_error = false; + // Init context and rendering device +#if defined(OPENGL_ENABLED) + if (video_driver_index == VIDEO_DRIVER_GLES2) { + if (getenv("DRI_PRIME") == NULL) { + int use_prime = -1; + + if (getenv("PRIMUS_DISPLAY") || + getenv("PRIMUS_libGLd") || + getenv("PRIMUS_libGLa") || + getenv("PRIMUS_libGL") || + getenv("PRIMUS_LOAD_GLOBAL") || + getenv("BUMBLEBEE_SOCKET")) { + + print_verbose("Optirun/primusrun detected. Skipping GPU detection"); + use_prime = 0; + } - context_gl = NULL; - while (!context_gl) { - context_gl = memnew(ContextGL_X11(x11_display, x11_window, current_videomode, opengl_api_type)); + if (getenv("LD_LIBRARY_PATH")) { + String ld_library_path(getenv("LD_LIBRARY_PATH")); + Vector<String> libraries = ld_library_path.split(":"); - if (context_gl->initialize() != OK) { - memdelete(context_gl); - context_gl = NULL; + for (int i = 0; i < libraries.size(); ++i) { + if (FileAccess::exists(libraries[i] + "/libGL.so.1") || + FileAccess::exists(libraries[i] + "/libGL.so")) { - if (GLOBAL_GET("rendering/quality/driver/fallback_to_gles2") || editor) { - if (p_video_driver == VIDEO_DRIVER_GLES2) { - gl_initialization_error = true; - break; + print_verbose("Custom libGL override detected. Skipping GPU detection"); + use_prime = 0; + } } + } - p_video_driver = VIDEO_DRIVER_GLES2; - opengl_api_type = ContextGL_X11::GLES_2_0_COMPATIBLE; - } else { - gl_initialization_error = true; - break; + if (use_prime == -1) { + print_verbose("Detecting GPUs, set DRI_PRIME in the environment to override GPU detection logic."); + use_prime = detect_prime(); } - } - } - while (true) { - if (opengl_api_type == ContextGL_X11::GLES_3_0_COMPATIBLE) { - if (RasterizerGLES3::is_viable() == OK) { - RasterizerGLES3::register_config(); - RasterizerGLES3::make_current(); - break; - } else { - if (GLOBAL_GET("rendering/quality/driver/fallback_to_gles2") || editor) { - p_video_driver = VIDEO_DRIVER_GLES2; - opengl_api_type = ContextGL_X11::GLES_2_0_COMPATIBLE; - continue; - } else { - gl_initialization_error = true; - break; - } + if (use_prime) { + print_line("Found discrete GPU, setting DRI_PRIME=1 to use it."); + print_line("Note: Set DRI_PRIME=0 in the environment to disable Godot from using the discrete GPU."); + setenv("DRI_PRIME", "1", 1); } } - if (opengl_api_type == ContextGL_X11::GLES_2_0_COMPATIBLE) { - if (RasterizerGLES2::is_viable() == OK) { - RasterizerGLES2::register_config(); - RasterizerGLES2::make_current(); - break; - } else { - gl_initialization_error = true; - break; - } + ContextGL_X11::ContextType opengl_api_type = ContextGL_X11::GLES_2_0_COMPATIBLE; + + context_gles2 = memnew(ContextGL_X11(x11_display, x11_window, current_videomode, opengl_api_type)); + + if (context_gles2->initialize() != OK) { + memdelete(context_gles2); + context_gles2 = NULL; + ERR_FAIL_V(ERR_UNAVAILABLE); } - } - if (gl_initialization_error) { - OS::get_singleton()->alert("Your video card driver does not support any of the supported OpenGL versions.\n" - "Please update your drivers or if you have a very old or integrated GPU upgrade it.", - "Unable to initialize Video driver"); - return ERR_UNAVAILABLE; + context_gles2->set_use_vsync(current_videomode.use_vsync); + + if (RasterizerGLES2::is_viable() == OK) { + RasterizerGLES2::register_config(); + RasterizerGLES2::make_current(); + } else { + memdelete(context_gles2); + context_gles2 = NULL; + ERR_FAIL_V(ERR_UNAVAILABLE); + } } +#endif +#if defined(VULKAN_ENABLED) + if (video_driver_index == VIDEO_DRIVER_VULKAN) { - video_driver_index = p_video_driver; + context_vulkan = memnew(VulkanContextX11); + if (context_vulkan->initialize() != OK) { + memdelete(context_vulkan); + context_vulkan = NULL; + ERR_FAIL_V(ERR_UNAVAILABLE); + } + if (context_vulkan->window_create(x11_window, x11_display, get_video_mode().width, get_video_mode().height) == -1) { + memdelete(context_vulkan); + context_vulkan = NULL; + ERR_FAIL_V(ERR_UNAVAILABLE); + } - context_gl->set_use_vsync(current_videomode.use_vsync); + //temporary + rendering_device_vulkan = memnew(RenderingDeviceVulkan); + rendering_device_vulkan->initialize(context_vulkan); + RasterizerRD::make_current(); + } #endif visual_server = memnew(VisualServerRaster); @@ -526,19 +527,73 @@ Error OS_X11::initialize(const VideoMode &p_desired, int p_video_driver, int p_a "watch", "left_ptr_watch", "fleur", - "hand1", - "X_cursor", - "sb_v_double_arrow", - "sb_h_double_arrow", + "dnd-move", + "crossed_circle", + "v_double_arrow", + "h_double_arrow", "size_bdiag", "size_fdiag", - "hand1", - "sb_v_double_arrow", - "sb_h_double_arrow", + "move", + "row_resize", + "col_resize", "question_arrow" }; img[i] = XcursorLibraryLoadImage(cursor_file[i], cursor_theme, cursor_size); + if (!img[i]) { + const char *fallback = NULL; + + switch (i) { + case CURSOR_POINTING_HAND: + fallback = "pointer"; + break; + case CURSOR_CROSS: + fallback = "crosshair"; + break; + case CURSOR_WAIT: + fallback = "wait"; + break; + case CURSOR_BUSY: + fallback = "progress"; + break; + case CURSOR_DRAG: + fallback = "grabbing"; + break; + case CURSOR_CAN_DROP: + fallback = "hand1"; + break; + case CURSOR_FORBIDDEN: + fallback = "forbidden"; + break; + case CURSOR_VSIZE: + fallback = "ns-resize"; + break; + case CURSOR_HSIZE: + fallback = "ew-resize"; + break; + case CURSOR_BDIAGSIZE: + fallback = "fd_double_arrow"; + break; + case CURSOR_FDIAGSIZE: + fallback = "bd_double_arrow"; + break; + case CURSOR_MOVE: + img[i] = img[CURSOR_DRAG]; + break; + case CURSOR_VSPLIT: + fallback = "sb_v_double_arrow"; + break; + case CURSOR_HSPLIT: + fallback = "sb_h_double_arrow"; + break; + case CURSOR_HELP: + fallback = "help"; + break; + } + if (fallback != NULL) { + img[i] = XcursorLibraryLoadImage(fallback, cursor_theme, cursor_size); + } + } if (img[i]) { cursors[i] = XcursorImageLoadCursor(x11_display, img[i]); } else { @@ -596,9 +651,6 @@ Error OS_X11::initialize(const VideoMode &p_desired, int p_video_driver, int p_a AudioDriverManager::initialize(p_audio_driver); - ///@TODO implement a subclass for Linux and instantiate that instead - camera_server = memnew(CameraServer); - input = memnew(InputDefault); window_has_focus = true; // Set focus to true at init @@ -607,8 +659,6 @@ Error OS_X11::initialize(const VideoMode &p_desired, int p_video_driver, int p_a #endif _ensure_user_data_dir(); - power_manager = memnew(PowerX11); - if (p_desired.layered) { set_window_per_pixel_transparency_enabled(true); } @@ -672,14 +722,8 @@ bool OS_X11::refresh_device_info() { int range_max_x = 0; int range_max_y = 0; int pressure_resolution = 0; - int pressure_min = 0; - int pressure_max = 0; int tilt_resolution_x = 0; int tilt_resolution_y = 0; - int tilt_range_min_x = 0; - int tilt_range_min_y = 0; - int tilt_range_max_x = 0; - int tilt_range_max_y = 0; for (int j = 0; j < dev->num_classes; j++) { #ifdef TOUCH_ENABLED if (dev->classes[j]->type == XITouchClass && ((XITouchClassInfo *)dev->classes[j])->mode == XIDirectTouch) { @@ -700,17 +744,14 @@ bool OS_X11::refresh_device_info() { range_max_y = class_info->max; absolute_mode = true; } else if (class_info->number == VALUATOR_PRESSURE && class_info->mode == XIModeAbsolute) { - pressure_resolution = class_info->resolution; - pressure_min = class_info->min; - pressure_max = class_info->max; + pressure_resolution = (class_info->max - class_info->min); + if (pressure_resolution == 0) pressure_resolution = 1; } else if (class_info->number == VALUATOR_TILTX && class_info->mode == XIModeAbsolute) { - tilt_resolution_x = class_info->resolution; - tilt_range_min_x = class_info->min; - tilt_range_max_x = class_info->max; + tilt_resolution_x = (class_info->max - class_info->min); + if (tilt_resolution_x == 0) tilt_resolution_x = 1; } else if (class_info->number == VALUATOR_TILTY && class_info->mode == XIModeAbsolute) { - tilt_resolution_y = class_info->resolution; - tilt_range_min_y = class_info->min; - tilt_range_max_y = class_info->max; + tilt_resolution_y = (class_info->max - class_info->min); + if (tilt_resolution_y == 0) tilt_resolution_y = 1; } } } @@ -731,15 +772,6 @@ bool OS_X11::refresh_device_info() { print_verbose("XInput: Absolute pointing device: " + String(dev->name)); } - if (pressure_resolution <= 0) { - pressure_resolution = (pressure_max - pressure_min); - } - if (tilt_resolution_x <= 0) { - tilt_resolution_x = (tilt_range_max_x - tilt_range_min_x); - } - if (tilt_resolution_y <= 0) { - tilt_resolution_y = (tilt_range_max_y - tilt_range_min_y); - } xi.pressure = 0; xi.pen_devices[dev->deviceid] = Vector3(pressure_resolution, tilt_resolution_x, tilt_resolution_y); } @@ -832,14 +864,29 @@ void OS_X11::finalize() { memdelete(input); - memdelete(camera_server); - cursors_cache.clear(); visual_server->finish(); memdelete(visual_server); - //memdelete(rasterizer); - memdelete(power_manager); +#if defined(OPENGL_ENABLED) + if (video_driver_index == VIDEO_DRIVER_GLES2) { + + if (context_gles2) + memdelete(context_gles2); + } +#endif +#if defined(VULKAN_ENABLED) + if (video_driver_index == VIDEO_DRIVER_VULKAN) { + + if (rendering_device_vulkan) { + rendering_device_vulkan->finalize(); + memdelete(rendering_device_vulkan); + } + + if (context_vulkan) + memdelete(context_vulkan); + } +#endif if (xrandr_handle) dlclose(xrandr_handle); @@ -847,9 +894,6 @@ void OS_X11::finalize() { XUnmapWindow(x11_display, x11_window); XDestroyWindow(x11_display, x11_window); -#if defined(OPENGL_ENABLED) - memdelete(context_gl); -#endif for (int i = 0; i < CURSOR_MAX; i++) { if (cursors[i] != None) XFreeCursor(x11_display, cursors[i]); @@ -1434,11 +1478,15 @@ void OS_X11::set_window_fullscreen(bool p_enabled) { set_window_maximized(true); } set_wm_fullscreen(p_enabled); - if (!p_enabled && !current_videomode.always_on_top) { + if (!p_enabled && current_videomode.always_on_top) { // Restore set_window_maximized(false); } - + if (!p_enabled) { + set_window_position(last_position_before_fs); + } else { + last_position_before_fs = get_window_position(); + } current_videomode.fullscreen = p_enabled; } @@ -1689,6 +1737,10 @@ bool OS_X11::is_window_always_on_top() const { return current_videomode.always_on_top; } +bool OS_X11::is_window_focused() const { + return window_focused; +} + void OS_X11::set_borderless_window(bool p_borderless) { if (get_borderless_window() == p_borderless) @@ -2001,11 +2053,6 @@ void OS_X11::handle_key_event(XKeyEvent *p_event, bool p_echo) { if (last_is_pressed) { k->set_echo(true); } - } else { - //ignore - if (!last_is_pressed) { - return; - } } //printf("key: %x\n",k->get_scancode()); @@ -2088,6 +2135,12 @@ void OS_X11::_window_changed(XEvent *event) { current_videomode.width = event->xconfigure.width; current_videomode.height = event->xconfigure.height; + +#if defined(VULKAN_ENABLED) + if (video_driver_index == VIDEO_DRIVER_VULKAN) { + context_vulkan->window_resize(0, current_videomode.width, current_videomode.height); + } +#endif } void OS_X11::process_xevents() { @@ -2281,6 +2334,8 @@ void OS_X11::process_xevents() { minimized = false; window_has_focus = true; main_loop->notification(MainLoop::NOTIFICATION_WM_FOCUS_IN); + window_focused = true; + if (mouse_mode_grab) { // Show and update the cursor if confined and the window regained focus. if (mouse_mode == MOUSE_MODE_CONFINED) @@ -2308,6 +2363,7 @@ void OS_X11::process_xevents() { window_has_focus = false; input->release_pressed_events(); main_loop->notification(MainLoop::NOTIFICATION_WM_FOCUS_OUT); + window_focused = false; if (mouse_mode_grab) { //dear X11, I try, I really try, but you never work, you do whathever you want. @@ -2973,7 +3029,7 @@ void OS_X11::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, c cursors_cache.erase(p_shape); } - Ref<Texture> texture = p_cursor; + Ref<Texture2D> texture = p_cursor; Ref<AtlasTexture> atlas_texture = p_cursor; Ref<Image> image; Size2 texture_size; @@ -3020,8 +3076,6 @@ void OS_X11::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, c // allocate memory to contain the whole file cursor_image->pixels = (XcursorPixel *)memalloc(size); - image->lock(); - for (XcursorPixel index = 0; index < image_size; index++) { int row_index = floor(index / texture_size.width) + atlas_rect.position.y; int column_index = (index % int(texture_size.width)) + atlas_rect.position.x; @@ -3034,8 +3088,6 @@ void OS_X11::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, c *(cursor_image->pixels + index) = image->get_pixel(column_index, row_index).to_argb32(); } - image->unlock(); - ERR_FAIL_COND(cursor_image->pixels == NULL); // Save it for a further usage @@ -3069,24 +3121,33 @@ void OS_X11::set_custom_mouse_cursor(const RES &p_cursor, CursorShape p_shape, c } void OS_X11::release_rendering_thread() { - #if defined(OPENGL_ENABLED) - context_gl->release_current(); + if (video_driver_index == VIDEO_DRIVER_GLES2) { + context_gles2->release_current(); + } #endif } void OS_X11::make_rendering_thread() { - #if defined(OPENGL_ENABLED) - context_gl->make_current(); + if (video_driver_index == VIDEO_DRIVER_GLES2) { + context_gles2->make_current(); + } #endif } void OS_X11::swap_buffers() { - #if defined(OPENGL_ENABLED) - context_gl->swap_buffers(); + if (video_driver_index == VIDEO_DRIVER_GLES2) { + context_gles2->swap_buffers(); + } #endif + /* not needed for now +#if defined(VULKAN_ENABLED) + if (video_driver_index == VIDEO_DRIVER_VULKAN) { + context_vulkan->swap_buffers(); + } +#endif*/ } void OS_X11::alert(const String &p_alert, const String &p_title) { @@ -3204,10 +3265,10 @@ void OS_X11::set_icon(const Ref<Image> &p_icon) { pd.write[0] = w; pd.write[1] = h; - PoolVector<uint8_t>::Read r = img->get_data().read(); + const uint8_t *r = img->get_data().ptr(); long *wr = &pd.write[2]; - uint8_t const *pr = r.ptr(); + uint8_t const *pr = r; for (int i = 0; i < w * h; i++) { long v = 0; @@ -3274,19 +3335,13 @@ String OS_X11::get_joy_guid(int p_device) const { void OS_X11::_set_use_vsync(bool p_enable) { #if defined(OPENGL_ENABLED) - if (context_gl) - context_gl->set_use_vsync(p_enable); + if (video_driver_index == VIDEO_DRIVER_GLES2) { + if (context_gles2) + context_gles2->set_use_vsync(p_enable); + } #endif } -/* -bool OS_X11::is_vsync_enabled() const { - - if (context_gl) - return context_gl->is_using_vsync(); - return true; -} -*/ void OS_X11::set_context(int p_context) { XClassHint *classHint = XAllocClassHint(); @@ -3326,18 +3381,6 @@ void OS_X11::set_context(int p_context) { } } -OS::PowerState OS_X11::get_power_state() { - return power_manager->get_power_state(); -} - -int OS_X11::get_power_seconds_left() { - return power_manager->get_power_seconds_left(); -} - -int OS_X11::get_power_percent_left() { - return power_manager->get_power_percent_left(); -} - void OS_X11::disable_crash_handler() { crash_handler.disable(); } @@ -3405,7 +3448,7 @@ Error OS_X11::move_to_trash(const String &p_path) { // Issue an error if none of the previous locations is appropriate for the trash can. if (trash_can == "") { - ERR_PRINTS("move_to_trash: Could not determine the trash can location"); + ERR_PRINT("move_to_trash: Could not determine the trash can location"); return FAILED; } @@ -3416,7 +3459,7 @@ Error OS_X11::move_to_trash(const String &p_path) { // Issue an error if trash can is not created proprely. if (err != OK) { - ERR_PRINTS("move_to_trash: Could not create the trash can \"" + trash_can + "\""); + ERR_PRINT("move_to_trash: Could not create the trash can \"" + trash_can + "\""); return err; } @@ -3430,7 +3473,7 @@ Error OS_X11::move_to_trash(const String &p_path) { // Issue an error if "mv" failed to move the given resource to the trash can. if (err != OK || retval != 0) { - ERR_PRINTS("move_to_trash: Could not move the resource \"" + p_path + "\" to the trash can \"" + trash_can + "\""); + ERR_PRINT("move_to_trash: Could not move the resource \"" + p_path + "\" to the trash can \"" + trash_can + "\""); return FAILED; } @@ -3502,6 +3545,8 @@ OS_X11::OS_X11() { xi.last_relative_time = 0; layered_window = false; minimized = false; + window_focused = true; xim_style = 0L; mouse_mode = MOUSE_MODE_VISIBLE; + last_position_before_fs = Vector2(); } diff --git a/platform/x11/os_x11.h b/platform/x11/os_x11.h index a5576f4402..55d24d64a3 100644 --- a/platform/x11/os_x11.h +++ b/platform/x11/os_x11.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -31,7 +31,6 @@ #ifndef OS_X11_H #define OS_X11_H -#include "context_gl_x11.h" #include "core/os/input.h" #include "crash_handler_x11.h" #include "drivers/alsa/audio_driver_alsa.h" @@ -40,12 +39,18 @@ #include "drivers/unix/os_unix.h" #include "joypad_linux.h" #include "main/input_default.h" -#include "power_x11.h" #include "servers/audio_server.h" -#include "servers/camera_server.h" #include "servers/visual/rasterizer.h" #include "servers/visual_server.h" -//#include "servers/visual/visual_server_wrap_mt.h" + +#if defined(OPENGL_ENABLED) +#include "context_gl_x11.h" +#endif + +#if defined(VULKAN_ENABLED) +#include "drivers/vulkan/rendering_device_vulkan.h" +#include "platform/x11/vulkan_context_x11.h" +#endif #include <X11/Xcursor/Xcursor.h> #include <X11/Xlib.h> @@ -93,8 +98,13 @@ class OS_X11 : public OS_Unix { int xdnd_version; #if defined(OPENGL_ENABLED) - ContextGL_X11 *context_gl; + ContextGL_X11 *context_gles2; +#endif +#if defined(VULKAN_ENABLED) + VulkanContextX11 *context_vulkan; + RenderingDeviceVulkan *rendering_device_vulkan; #endif + //Rasterizer *rasterizer; VisualServer *visual_server; VideoMode current_videomode; @@ -116,6 +126,7 @@ class OS_X11 : public OS_Unix { // IME bool im_active; Vector2 im_position; + Vector2 last_position_before_fs; Size2 min_size; Size2 max_size; @@ -150,8 +161,6 @@ class OS_X11 : public OS_Unix { void get_key_modifier_state(unsigned int p_x11_state, Ref<InputEventWithModifiers> state); void flush_mouse_motion(); - CameraServer *camera_server; - MouseMode mouse_mode; Point2i center; @@ -190,14 +199,13 @@ class OS_X11 : public OS_Unix { AudioDriverPulseAudio driver_pulseaudio; #endif - PowerX11 *power_manager; - bool layered_window; CrashHandler crash_handler; int video_driver_index; bool maximized; + bool window_focused; //void set_wm_border(bool p_enabled); void set_wm_fullscreen(bool p_enabled); void set_wm_above(bool p_enabled); @@ -287,6 +295,7 @@ public: virtual bool is_window_maximized() const; virtual void set_window_always_on_top(bool p_enabled); virtual bool is_window_always_on_top() const; + virtual bool is_window_focused() const; virtual void request_attention(); virtual void set_borderless_window(bool p_borderless); @@ -311,10 +320,6 @@ public: virtual void _set_use_vsync(bool p_enable); //virtual bool is_vsync_enabled() const; - virtual OS::PowerState get_power_state(); - virtual int get_power_seconds_left(); - virtual int get_power_percent_left(); - virtual bool _check_internal_feature_support(const String &p_feature); virtual void force_process_input(); diff --git a/platform/x11/pck_embed.ld b/platform/x11/pck_embed.ld index fe09144d88..57a1994043 100644 --- a/platform/x11/pck_embed.ld +++ b/platform/x11/pck_embed.ld @@ -1,9 +1,9 @@ SECTIONS { /* Add a zero-sized section; the exporter will patch it to enclose the data appended to the executable (embedded PCK) */ - pck 0 (NOLOAD) : + pck 0 (INFO) : { - /* Just some content to avoid the linker discarding the section */ + /* binutils >= 2.30 allow it being zero-sized, but needs something between the braces to keep the section */ . = ALIGN(8); } } diff --git a/platform/x11/pck_embed.legacy.ld b/platform/x11/pck_embed.legacy.ld new file mode 100644 index 0000000000..a23013ba7a --- /dev/null +++ b/platform/x11/pck_embed.legacy.ld @@ -0,0 +1,10 @@ +SECTIONS +{ + /* The exporter will patch this section to enclose the data appended to the executable (embedded PCK) */ + pck 0 (INFO) : AT ( ADDR (.rodata) + SIZEOF (.rodata) ) + { + /* binutils < 2.30 need some actual content for the linker not to discard the section */ + BYTE(0); + } +} +INSERT AFTER .rodata; diff --git a/platform/x11/platform_config.h b/platform/x11/platform_config.h index 9e6011ddf7..ac30519132 100644 --- a/platform/x11/platform_config.h +++ b/platform/x11/platform_config.h @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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,5 +36,4 @@ #define PTHREAD_BSD_SET_NAME #endif -#define GLES3_INCLUDE_H "thirdparty/glad/glad/glad.h" #define GLES2_INCLUDE_H "thirdparty/glad/glad/glad.h" diff --git a/platform/x11/power_x11.cpp b/platform/x11/power_x11.cpp deleted file mode 100644 index c33c77e16b..0000000000 --- a/platform/x11/power_x11.cpp +++ /dev/null @@ -1,577 +0,0 @@ -/*************************************************************************/ -/* power_x11.cpp */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -/* -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> -#include <unistd.h> - -#include "core/error_macros.h" -#include <dirent.h> -#include <fcntl.h> -#include <sys/stat.h> -#include <sys/types.h> - -// CODE CHUNK IMPORTED FROM SDL 2.0 - -static const char *proc_apm_path = "/proc/apm"; -static const char *proc_acpi_battery_path = "/proc/acpi/battery"; -static const char *proc_acpi_ac_adapter_path = "/proc/acpi/ac_adapter"; -static const char *sys_class_power_supply_path = "/sys/class/power_supply"; - -FileAccessRef PowerX11::open_power_file(const char *base, const char *node, const char *key) { - String path = String(base) + String("/") + String(node) + String("/") + String(key); - FileAccessRef f = FileAccess::open(path, FileAccess::READ); - return f; -} - -bool PowerX11::read_power_file(const char *base, const char *node, const char *key, char *buf, size_t buflen) { - ssize_t br = 0; - FileAccessRef fd = open_power_file(base, node, key); - if (!fd) { - return false; - } - br = fd->get_buffer(reinterpret_cast<uint8_t *>(buf), buflen - 1); - fd->close(); - if (br < 0) { - return false; - } - buf[br] = '\0'; // null-terminate the string - return true; -} - -bool PowerX11::make_proc_acpi_key_val(char **_ptr, char **_key, char **_val) { - char *ptr = *_ptr; - - while (*ptr == ' ') { - ptr++; /* skip whitespace. */ - } - - if (*ptr == '\0') { - return false; /* EOF. */ - } - - *_key = ptr; - - while ((*ptr != ':') && (*ptr != '\0')) { - ptr++; - } - - if (*ptr == '\0') { - return false; /* (unexpected) EOF. */ - } - - *(ptr++) = '\0'; /* terminate the key. */ - - while (*ptr == ' ') { - ptr++; /* skip whitespace. */ - } - - if (*ptr == '\0') { - return false; /* (unexpected) EOF. */ - } - - *_val = ptr; - - while ((*ptr != '\n') && (*ptr != '\0')) { - ptr++; - } - - if (*ptr != '\0') { - *(ptr++) = '\0'; /* terminate the value. */ - } - - *_ptr = ptr; /* store for next time. */ - return true; -} - -void PowerX11::check_proc_acpi_battery(const char *node, bool *have_battery, bool *charging) { - const char *base = proc_acpi_battery_path; - char info[1024]; - char state[1024]; - char *ptr = NULL; - char *key = NULL; - char *val = NULL; - bool charge = false; - bool choose = false; - int maximum = -1; - int remaining = -1; - int secs = -1; - int pct = -1; - - if (!read_power_file(base, node, "state", state, sizeof(state))) { - return; - } else { - if (!read_power_file(base, node, "info", info, sizeof(info))) - return; - } - - ptr = &state[0]; - while (make_proc_acpi_key_val(&ptr, &key, &val)) { - if (String(key) == "present") { - if (String(val) == "yes") { - *have_battery = true; - } - } else if (String(key) == "charging state") { - /* !!! FIXME: what exactly _does_ charging/discharging mean? */ - if (String(val) == "charging/discharging") { - charge = true; - } else if (String(val) == "charging") { - charge = true; - } - } else if (String(key) == "remaining capacity") { - String sval = val; - const int cvt = sval.to_int(); - remaining = cvt; - } - } - - ptr = &info[0]; - while (make_proc_acpi_key_val(&ptr, &key, &val)) { - if (String(key) == "design capacity") { - String sval = val; - const int cvt = sval.to_int(); - maximum = cvt; - } - } - - if ((maximum >= 0) && (remaining >= 0)) { - pct = (int)((((float)remaining) / ((float)maximum)) * 100.0f); - if (pct < 0) { - pct = 0; - } else if (pct > 100) { - pct = 100; - } - } - - /* !!! FIXME: calculate (secs). */ - - /* - * We pick the battery that claims to have the most minutes left. - * (failing a report of minutes, we'll take the highest percent.) - */ - // -- GODOT start -- - //if ((secs < 0) && (this->nsecs_left < 0)) { - if (this->nsecs_left < 0) { - // -- GODOT end -- - if ((pct < 0) && (this->percent_left < 0)) { - choose = true; /* at least we know there's a battery. */ - } - if (pct > this->percent_left) { - choose = true; - } - } else if (secs > this->nsecs_left) { - choose = true; - } - - if (choose) { - this->nsecs_left = secs; - this->percent_left = pct; - *charging = charge; - } -} - -void PowerX11::check_proc_acpi_ac_adapter(const char *node, bool *have_ac) { - const char *base = proc_acpi_ac_adapter_path; - char state[256]; - char *ptr = NULL; - char *key = NULL; - char *val = NULL; - - if (!read_power_file(base, node, "state", state, sizeof(state))) { - return; - } - - ptr = &state[0]; - while (make_proc_acpi_key_val(&ptr, &key, &val)) { - String skey = key; - if (skey == "state") { - String sval = val; - if (sval == "on-line") { - *have_ac = true; - } - } - } -} - -bool PowerX11::GetPowerInfo_Linux_proc_acpi() { - String node; - DirAccess *dirp = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); - bool have_battery = false; - bool have_ac = false; - bool charging = false; - - this->nsecs_left = -1; - this->percent_left = -1; - this->power_state = OS::POWERSTATE_UNKNOWN; - - dirp->change_dir(proc_acpi_battery_path); - Error err = dirp->list_dir_begin(); - - if (err != OK) { - return false; /* can't use this interface. */ - } else { - node = dirp->get_next(); - while (node != "") { - check_proc_acpi_battery(node.utf8().get_data(), &have_battery, &charging /*, seconds, percent*/); - node = dirp->get_next(); - } - } - dirp->change_dir(proc_acpi_ac_adapter_path); - err = dirp->list_dir_begin(); - if (err != OK) { - return false; /* can't use this interface. */ - } else { - node = dirp->get_next(); - while (node != "") { - check_proc_acpi_ac_adapter(node.utf8().get_data(), &have_ac); - node = dirp->get_next(); - } - } - - if (!have_battery) { - this->power_state = OS::POWERSTATE_NO_BATTERY; - } else if (charging) { - this->power_state = OS::POWERSTATE_CHARGING; - } else if (have_ac) { - this->power_state = OS::POWERSTATE_CHARGED; - } else { - this->power_state = OS::POWERSTATE_ON_BATTERY; - } - - memdelete(dirp); - return true; /* definitive answer. */ -} - -bool PowerX11::next_string(char **_ptr, char **_str) { - char *ptr = *_ptr; - char *str = *_str; - - while (*ptr == ' ') { /* skip any spaces... */ - ptr++; - } - - if (*ptr == '\0') { - return false; - } - - str = ptr; - while ((*ptr != ' ') && (*ptr != '\n') && (*ptr != '\0')) - ptr++; - - if (*ptr != '\0') - *(ptr++) = '\0'; - - *_str = str; - *_ptr = ptr; - return true; -} - -bool PowerX11::int_string(char *str, int *val) { - String sval = str; - *val = sval.to_int(); - return (*str != '\0'); -} - -/* http://lxr.linux.no/linux+v2.6.29/drivers/char/apm-emulation.c */ -bool PowerX11::GetPowerInfo_Linux_proc_apm() { - bool need_details = false; - int ac_status = 0; - int battery_status = 0; - int battery_flag = 0; - int battery_percent = 0; - int battery_time = 0; - FileAccessRef fd = FileAccess::open(proc_apm_path, FileAccess::READ); - char buf[128]; - char *ptr = &buf[0]; - char *str = NULL; - ssize_t br; - - if (!fd) { - return false; /* can't use this interface. */ - } - - br = fd->get_buffer(reinterpret_cast<uint8_t *>(buf), sizeof(buf) - 1); - fd->close(); - - if (br < 0) { - return false; - } - - buf[br] = '\0'; /* null-terminate the string. */ - if (!next_string(&ptr, &str)) { /* driver version */ - return false; - } - if (!next_string(&ptr, &str)) { /* BIOS version */ - return false; - } - if (!next_string(&ptr, &str)) { /* APM flags */ - return false; - } - - if (!next_string(&ptr, &str)) { /* AC line status */ - return false; - } else if (!int_string(str, &ac_status)) { - return false; - } - - if (!next_string(&ptr, &str)) { /* battery status */ - return false; - } else if (!int_string(str, &battery_status)) { - return false; - } - if (!next_string(&ptr, &str)) { /* battery flag */ - return false; - } else if (!int_string(str, &battery_flag)) { - return false; - } - if (!next_string(&ptr, &str)) { /* remaining battery life percent */ - return false; - } - String sstr = str; - if (sstr[sstr.length() - 1] == '%') { - sstr[sstr.length() - 1] = '\0'; - } - if (!int_string(str, &battery_percent)) { - return false; - } - - if (!next_string(&ptr, &str)) { /* remaining battery life time */ - return false; - } else if (!int_string(str, &battery_time)) { - return false; - } - - if (!next_string(&ptr, &str)) { /* remaining battery life time units */ - return false; - } else if (String(str) == "min") { - battery_time *= 60; - } - - if (battery_flag == 0xFF) { /* unknown state */ - this->power_state = OS::POWERSTATE_UNKNOWN; - } else if (battery_flag & (1 << 7)) { /* no battery */ - this->power_state = OS::POWERSTATE_NO_BATTERY; - } else if (battery_flag & (1 << 3)) { /* charging */ - this->power_state = OS::POWERSTATE_CHARGING; - need_details = true; - } else if (ac_status == 1) { - this->power_state = OS::POWERSTATE_CHARGED; /* on AC, not charging. */ - need_details = true; - } else { - this->power_state = OS::POWERSTATE_ON_BATTERY; - need_details = true; - } - - this->percent_left = -1; - this->nsecs_left = -1; - if (need_details) { - const int pct = battery_percent; - const int secs = battery_time; - - if (pct >= 0) { /* -1 == unknown */ - this->percent_left = (pct > 100) ? 100 : pct; /* clamp between 0%, 100% */ - } - if (secs >= 0) { /* -1 == unknown */ - this->nsecs_left = secs; - } - } - - return true; -} - -/* !!! FIXME: implement d-bus queries to org.freedesktop.UPower. */ - -bool PowerX11::GetPowerInfo_Linux_sys_class_power_supply(/*PowerState *state, int *seconds, int *percent*/) { - const char *base = sys_class_power_supply_path; - String name; - - DirAccess *dirp = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); - dirp->change_dir(base); - Error err = dirp->list_dir_begin(); - - if (err != OK) { - return false; - } - - this->power_state = OS::POWERSTATE_NO_BATTERY; /* assume we're just plugged in. */ - this->nsecs_left = -1; - this->percent_left = -1; - - name = dirp->get_next(); - - while (name != "") { - bool choose = false; - char str[64]; - OS::PowerState st; - int secs; - int pct; - - if ((name == ".") || (name == "..")) { - name = dirp->get_next(); - continue; //skip these, of course. - } else { - if (!read_power_file(base, name.utf8().get_data(), "type", str, sizeof(str))) { - name = dirp->get_next(); - continue; // Don't know _what_ we're looking at. Give up on it. - } else { - if (String(str) != "Battery\n") { - name = dirp->get_next(); - continue; // we don't care about UPS and such. - } - } - } - - /* some drivers don't offer this, so if it's not explicitly reported assume it's present. */ - if (read_power_file(base, name.utf8().get_data(), "present", str, sizeof(str)) && (String(str) == "0\n")) { - st = OS::POWERSTATE_NO_BATTERY; - } else if (!read_power_file(base, name.utf8().get_data(), "status", str, sizeof(str))) { - st = OS::POWERSTATE_UNKNOWN; /* uh oh */ - } else if (String(str) == "Charging\n") { - st = OS::POWERSTATE_CHARGING; - } else if (String(str) == "Discharging\n") { - st = OS::POWERSTATE_ON_BATTERY; - } else if ((String(str) == "Full\n") || (String(str) == "Not charging\n")) { - st = OS::POWERSTATE_CHARGED; - } else { - st = OS::POWERSTATE_UNKNOWN; /* uh oh */ - } - - if (!read_power_file(base, name.utf8().get_data(), "capacity", str, sizeof(str))) { - pct = -1; - } else { - pct = String(str).to_int(); - pct = (pct > 100) ? 100 : pct; /* clamp between 0%, 100% */ - } - - if (!read_power_file(base, name.utf8().get_data(), "time_to_empty_now", str, sizeof(str))) { - secs = -1; - } else { - secs = String(str).to_int(); - secs = (secs <= 0) ? -1 : secs; /* 0 == unknown */ - } - - /* - * We pick the battery that claims to have the most minutes left. - * (failing a report of minutes, we'll take the highest percent.) - */ - if ((secs < 0) && (this->nsecs_left < 0)) { - if ((pct < 0) && (this->percent_left < 0)) { - choose = true; /* at least we know there's a battery. */ - } else if (pct > this->percent_left) { - choose = true; - } - } else if (secs > this->nsecs_left) { - choose = true; - } - - if (choose) { - this->nsecs_left = secs; - this->percent_left = pct; - this->power_state = st; - } - - name = dirp->get_next(); - } - - memdelete(dirp); - return true; /* don't look any further*/ -} - -bool PowerX11::UpdatePowerInfo() { - if (GetPowerInfo_Linux_sys_class_power_supply()) { // try method 1 - return true; - } - if (GetPowerInfo_Linux_proc_acpi()) { // try further - return true; - } - if (GetPowerInfo_Linux_proc_apm()) { // try even further - return true; - } - return false; -} - -PowerX11::PowerX11() : - nsecs_left(-1), - percent_left(-1), - power_state(OS::POWERSTATE_UNKNOWN) { -} - -PowerX11::~PowerX11() { -} - -OS::PowerState PowerX11::get_power_state() { - if (UpdatePowerInfo()) { - return power_state; - } else { - return OS::POWERSTATE_UNKNOWN; - } -} - -int PowerX11::get_power_seconds_left() { - if (UpdatePowerInfo()) { - return nsecs_left; - } else { - return -1; - } -} - -int PowerX11::get_power_percent_left() { - if (UpdatePowerInfo()) { - return percent_left; - } else { - return -1; - } -} diff --git a/platform/x11/power_x11.h b/platform/x11/power_x11.h deleted file mode 100644 index 469e3910f4..0000000000 --- a/platform/x11/power_x11.h +++ /dev/null @@ -1,66 +0,0 @@ -/*************************************************************************/ -/* power_x11.h */ -/*************************************************************************/ -/* This file is part of: */ -/* GODOT ENGINE */ -/* https://godotengine.org */ -/*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ -/* */ -/* Permission is hereby granted, free of charge, to any person obtaining */ -/* a copy of this software and associated documentation files (the */ -/* "Software"), to deal in the Software without restriction, including */ -/* without limitation the rights to use, copy, modify, merge, publish, */ -/* distribute, sublicense, and/or sell copies of the Software, and to */ -/* permit persons to whom the Software is furnished to do so, subject to */ -/* the following conditions: */ -/* */ -/* The above copyright notice and this permission notice shall be */ -/* included in all copies or substantial portions of the Software. */ -/* */ -/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ -/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ -/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ -/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ -/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ -/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ -/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/*************************************************************************/ - -#ifndef POWER_X11_H -#define POWER_X11_H - -#include "core/os/dir_access.h" -#include "core/os/file_access.h" -#include "core/os/os.h" - -class PowerX11 { - -private: - int nsecs_left; - int percent_left; - OS::PowerState power_state; - - FileAccessRef open_power_file(const char *base, const char *node, const char *key); - bool read_power_file(const char *base, const char *node, const char *key, char *buf, size_t buflen); - bool make_proc_acpi_key_val(char **_ptr, char **_key, char **_val); - void check_proc_acpi_battery(const char *node, bool *have_battery, bool *charging); - void check_proc_acpi_ac_adapter(const char *node, bool *have_ac); - bool GetPowerInfo_Linux_proc_acpi(); - bool next_string(char **_ptr, char **_str); - bool int_string(char *str, int *val); - bool GetPowerInfo_Linux_proc_apm(); - bool GetPowerInfo_Linux_sys_class_power_supply(); - bool UpdatePowerInfo(); - -public: - PowerX11(); - virtual ~PowerX11(); - - OS::PowerState get_power_state(); - int get_power_seconds_left(); - int get_power_percent_left(); -}; - -#endif // POWER_X11_H diff --git a/platform/x11/vulkan_context_x11.cpp b/platform/x11/vulkan_context_x11.cpp new file mode 100644 index 0000000000..602dbc77a2 --- /dev/null +++ b/platform/x11/vulkan_context_x11.cpp @@ -0,0 +1,57 @@ +/*************************************************************************/ +/* vulkan_context_x11.cpp */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "vulkan_context_x11.h" +#include <vulkan/vulkan_xlib.h> + +const char *VulkanContextX11::_get_platform_surface_extension() const { + return VK_KHR_XLIB_SURFACE_EXTENSION_NAME; +} + +int VulkanContextX11::window_create(::Window p_window, Display *p_display, int p_width, int p_height) { + + VkXlibSurfaceCreateInfoKHR createInfo; + createInfo.sType = VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR; + createInfo.pNext = NULL; + createInfo.flags = 0; + createInfo.dpy = p_display; + createInfo.window = p_window; + + VkSurfaceKHR surface; + VkResult err = vkCreateXlibSurfaceKHR(_get_instance(), &createInfo, NULL, &surface); + ERR_FAIL_COND_V(err, -1); + return _window_create(surface, p_width, p_height); +} + +VulkanContextX11::VulkanContextX11() { +} + +VulkanContextX11::~VulkanContextX11() { +} diff --git a/platform/osx/camera_osx.h b/platform/x11/vulkan_context_x11.h index 80ca3759ba..573f994ea6 100644 --- a/platform/osx/camera_osx.h +++ b/platform/x11/vulkan_context_x11.h @@ -1,12 +1,12 @@ /*************************************************************************/ -/* camera_osx.h */ +/* vulkan_context_x11.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (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,20 +28,21 @@ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef CAMERAOSX_H -#define CAMERAOSX_H +#ifndef VULKAN_DEVICE_X11_H +#define VULKAN_DEVICE_X11_H -///@TODO this is a near duplicate of CameraIOS, we should find a way to combine those to minimise code duplication!!!! -// If you fix something here, make sure you fix it there as wel! +#include "drivers/vulkan/vulkan_context.h" +#include <X11/Xlib.h> -#include "servers/camera_server.h" +class VulkanContextX11 : public VulkanContext { + + virtual const char *_get_platform_surface_extension() const; -class CameraOSX : public CameraServer { public: - CameraOSX(); - ~CameraOSX(); + int window_create(::Window p_window, Display *p_display, int p_width, int p_height); - void update_feeds(); + VulkanContextX11(); + ~VulkanContextX11(); }; -#endif /* CAMERAOSX_H */
\ No newline at end of file +#endif // VULKAN_DEVICE_X11_H |