diff options
Diffstat (limited to 'platform')
30 files changed, 347 insertions, 194 deletions
diff --git a/platform/android/detect.py b/platform/android/detect.py index 6f98dab2cc..3319d5890c 100644 --- a/platform/android/detect.py +++ b/platform/android/detect.py @@ -152,7 +152,7 @@ def configure(env): abi_subpath = "i686-linux-android" arch_subpath = "x86" env["x86_libtheora_opt_gcc"] = True - if env["android_arch"] == "x86_64": + elif env["android_arch"] == "x86_64": if get_platform(env["ndk_platform"]) < 21: print( "WARNING: android_arch=x86_64 is not supported by ndk_platform lower than android-21; setting" diff --git a/platform/android/dir_access_jandroid.cpp b/platform/android/dir_access_jandroid.cpp index 0eeee8215d..d2726b8652 100644 --- a/platform/android/dir_access_jandroid.cpp +++ b/platform/android/dir_access_jandroid.cpp @@ -102,7 +102,7 @@ String DirAccessJAndroid::get_drive(int p_drive) { Error DirAccessJAndroid::change_dir(String p_dir) { JNIEnv *env = get_jni_env(); - if (p_dir == "" || p_dir == "." || (p_dir == ".." && current_dir == "")) + if (p_dir.is_empty() || p_dir == "." || (p_dir == ".." && current_dir.is_empty())) return OK; String new_dir; @@ -114,7 +114,7 @@ Error DirAccessJAndroid::change_dir(String p_dir) { new_dir = p_dir.substr(1, p_dir.length()); else if (p_dir.begins_with("res://")) new_dir = p_dir.substr(6, p_dir.length()); - else if (current_dir == "") + else if (current_dir.is_empty()) new_dir = p_dir; else new_dir = current_dir.plus_file(p_dir); @@ -141,7 +141,7 @@ String DirAccessJAndroid::get_current_dir(bool p_include_drive) { bool DirAccessJAndroid::file_exists(String p_file) { String sd; - if (current_dir == "") + if (current_dir.is_empty()) sd = p_file; else sd = current_dir.plus_file(p_file); @@ -158,7 +158,7 @@ bool DirAccessJAndroid::dir_exists(String p_dir) { String sd; - if (current_dir == "") + if (current_dir.is_empty()) sd = p_dir; else { if (p_dir.is_relative_path()) diff --git a/platform/android/display_server_android.h b/platform/android/display_server_android.h index 669a1c80e4..5b987ad70e 100644 --- a/platform/android/display_server_android.h +++ b/platform/android/display_server_android.h @@ -70,8 +70,8 @@ class DisplayServerAndroid : public DisplayServer { CursorShape cursor_shape = CursorShape::CURSOR_ARROW; #if defined(VULKAN_ENABLED) - VulkanContextAndroid *context_vulkan; - RenderingDeviceVulkan *rendering_device_vulkan; + VulkanContextAndroid *context_vulkan = nullptr; + RenderingDeviceVulkan *rendering_device_vulkan = nullptr; #endif ObjectID window_attached_instance_id; diff --git a/platform/android/export/export_plugin.cpp b/platform/android/export/export_plugin.cpp index c5d3cbd966..70b36f2350 100644 --- a/platform/android/export/export_plugin.cpp +++ b/platform/android/export/export_plugin.cpp @@ -224,6 +224,10 @@ static const int EXPORT_FORMAT_AAB = 1; static const char *APK_ASSETS_DIRECTORY = "res://android/build/assets"; static const char *AAB_ASSETS_DIRECTORY = "res://android/build/assetPacks/installTime/src/main/assets"; +static const int DEFAULT_MIN_SDK_VERSION = 19; // Should match the value in 'platform/android/java/app/config.gradle#minSdk' +static const int DEFAULT_TARGET_SDK_VERSION = 30; // Should match the value in 'platform/android/java/app/config.gradle#targetSdk' +const String SDK_VERSION_RANGE = vformat("%s,%s,1", DEFAULT_MIN_SDK_VERSION, DEFAULT_TARGET_SDK_VERSION); + void EditorExportPlatformAndroid::_check_for_changes_poll_thread(void *ud) { EditorExportPlatformAndroid *ea = (EditorExportPlatformAndroid *)ud; @@ -303,7 +307,7 @@ void EditorExportPlatformAndroid::_check_for_changes_poll_thread(void *ud) { } } - if (d.description == "") { + if (d.description.is_empty()) { //in the oven, request! args.clear(); args.push_back("-s"); @@ -352,7 +356,7 @@ void EditorExportPlatformAndroid::_check_for_changes_poll_thread(void *ud) { } d.name = vendor + " " + device; - if (device == String()) { + if (device.is_empty()) { continue; } } @@ -390,13 +394,13 @@ void EditorExportPlatformAndroid::_check_for_changes_poll_thread(void *ud) { String EditorExportPlatformAndroid::get_project_name(const String &p_name) const { String aname; - if (p_name != "") { + if (!p_name.is_empty()) { aname = p_name; } else { aname = ProjectSettings::get_singleton()->get("application/config/name"); } - if (aname == "") { + if (aname.is_empty()) { aname = VERSION_NAME; } @@ -420,7 +424,7 @@ String EditorExportPlatformAndroid::get_package_name(const String &p_package) co first = false; } } - if (name == "") { + if (name.is_empty()) { name = "noname"; } @@ -577,7 +581,7 @@ Vector<String> EditorExportPlatformAndroid::list_gdap_files(const String &p_path da->list_dir_begin(); while (true) { String file = da->get_next(); - if (file == "") { + if (file.is_empty()) { break; } @@ -832,10 +836,13 @@ void EditorExportPlatformAndroid::_fix_manifest(const Ref<EditorExportPreset> &p bool screen_support_xlarge = p_preset->get("screen/support_xlarge"); int xr_mode_index = p_preset->get("xr_features/xr_mode"); + int hand_tracking_index = p_preset->get("xr_features/hand_tracking"); + int hand_tracking_frequency_index = p_preset->get("xr_features/hand_tracking_frequency"); bool backup_allowed = p_preset->get("user_data_backup/allow"); bool classify_as_game = p_preset->get("package/classify_as_game"); bool retain_data_on_uninstall = p_preset->get("package/retain_data_on_uninstall"); + bool exclude_from_recents = p_preset->get("package/exclude_from_recents"); Vector<String> perms; // Write permissions into the perms variable. @@ -949,6 +956,10 @@ void EditorExportPlatformAndroid::_fix_manifest(const Ref<EditorExportPreset> &p encode_uint32(screen_orientation, &p_manifest.write[iofs + 16]); } + if (tname == "activity" && attrname == "excludeFromRecents") { + encode_uint32(exclude_from_recents, &p_manifest.write[iofs + 16]); + } + if (tname == "supports-screens") { if (attrname == "smallScreens") { encode_uint32(screen_support_small ? 0xFFFFFFFF : 0, &p_manifest.write[iofs + 16]); @@ -978,6 +989,18 @@ void EditorExportPlatformAndroid::_fix_manifest(const Ref<EditorExportPreset> &p } } + if (tname == "meta-data" && attrname == "name" && value == "xr_hand_tracking_metadata_name") { + if (xr_mode_index == XR_MODE_OPENXR && hand_tracking_index > XR_HAND_TRACKING_NONE) { + string_table.write[attr_value] = "com.oculus.handtracking.frequency"; + } + } + + if (tname == "meta-data" && attrname == "value" && value == "xr_hand_tracking_metadata_value") { + if (xr_mode_index == XR_MODE_OPENXR && hand_tracking_index > XR_HAND_TRACKING_NONE) { + string_table.write[attr_value] = (hand_tracking_frequency_index == XR_HAND_TRACKING_FREQUENCY_LOW ? "LOW" : "HIGH"); + } + } + iofs += 20; } @@ -999,7 +1022,6 @@ void EditorExportPlatformAndroid::_fix_manifest(const Ref<EditorExportPreset> &p 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 > XR_HAND_TRACKING_NONE) { feature_names.push_back("oculus.software.handtracking"); feature_required_list.push_back(hand_tracking_index == XR_HAND_TRACKING_REQUIRED); @@ -1679,11 +1701,15 @@ void EditorExportPlatformAndroid::get_export_options(List<ExportOption> *r_optio 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")); + r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "version/min_sdk", PROPERTY_HINT_RANGE, SDK_VERSION_RANGE), DEFAULT_MIN_SDK_VERSION)); + r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "version/target_sdk", PROPERTY_HINT_RANGE, SDK_VERSION_RANGE), DEFAULT_TARGET_SDK_VERSION)); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "package/unique_name", PROPERTY_HINT_PLACEHOLDER_TEXT, "ext.domain.name"), "org.godotengine.$genname")); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "package/name", PROPERTY_HINT_PLACEHOLDER_TEXT, "Game Name [default if blank]"), "")); r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "package/signed"), true)); r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "package/classify_as_game"), true)); r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "package/retain_data_on_uninstall"), false)); + r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "package/exclude_from_recents"), false)); 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"), "")); @@ -1691,9 +1717,10 @@ void EditorExportPlatformAndroid::get_export_options(List<ExportOption> *r_optio r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "graphics/opengl_debug"), false)); - r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "xr_features/xr_mode", PROPERTY_HINT_ENUM, "Regular,OpenXR"), 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::INT, "xr_features/passthrough", PROPERTY_HINT_ENUM, "None,Optional,Required"), 0)); + r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "xr_features/xr_mode", PROPERTY_HINT_ENUM, "Regular,OpenXR"), XR_MODE_REGULAR)); + r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "xr_features/hand_tracking", PROPERTY_HINT_ENUM, "None,Optional,Required"), XR_HAND_TRACKING_NONE)); + r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "xr_features/hand_tracking_frequency", PROPERTY_HINT_ENUM, "Low,High"), XR_HAND_TRACKING_FREQUENCY_LOW)); + r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "xr_features/passthrough", PROPERTY_HINT_ENUM, "None,Optional,Required"), XR_PASSTHROUGH_NONE)); r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "screen/immersive_mode"), true)); r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "screen/support_small"), true)); @@ -2002,10 +2029,11 @@ String EditorExportPlatformAndroid::get_apksigner_path() { bool EditorExportPlatformAndroid::can_export(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates) const { String err; bool valid = false; + const bool custom_build_enabled = p_preset->get("custom_template/use_custom_build"); // Look for export templates (first official, and if defined custom templates). - if (!bool(p_preset->get("custom_template/use_custom_build"))) { + if (!custom_build_enabled) { String template_err; bool dvalid = false; bool rvalid = false; @@ -2080,7 +2108,7 @@ bool EditorExportPlatformAndroid::can_export(const Ref<EditorExportPreset> &p_pr } String sdk_path = EditorSettings::get_singleton()->get("export/android/android_sdk_path"); - if (sdk_path == "") { + if (sdk_path.is_empty()) { err += TTR("A valid Android SDK path is required in Editor Settings.") + "\n"; valid = false; } else { @@ -2127,7 +2155,7 @@ bool EditorExportPlatformAndroid::can_export(const Ref<EditorExportPreset> &p_pr if (apk_expansion) { String apk_expansion_pkey = p_preset->get("apk_expansion/public_key"); - if (apk_expansion_pkey == "") { + if (apk_expansion_pkey.is_empty()) { valid = false; err += TTR("Invalid public key for APK expansion.") + "\n"; @@ -2143,14 +2171,13 @@ bool EditorExportPlatformAndroid::can_export(const Ref<EditorExportPreset> &p_pr } String etc_error = test_etc2(); - if (etc_error != String()) { + if (!etc_error.is_empty()) { valid = false; err += etc_error; } // Ensure that `Use Custom Build` is enabled if a plugin is selected. String enabled_plugins_names = PluginConfigAndroid::get_plugins_names(get_enabled_plugins(p_preset)); - bool custom_build_enabled = p_preset->get("custom_template/use_custom_build"); if (!enabled_plugins_names.is_empty() && !custom_build_enabled) { valid = false; err += TTR("\"Use Custom Build\" must be enabled to use the plugins."); @@ -2176,12 +2203,34 @@ bool EditorExportPlatformAndroid::can_export(const Ref<EditorExportPreset> &p_pr } if (int(p_preset->get("custom_template/export_format")) == EXPORT_FORMAT_AAB && - !bool(p_preset->get("custom_template/use_custom_build"))) { + !custom_build_enabled) { valid = false; err += TTR("\"Export AAB\" is only valid when \"Use Custom Build\" is enabled."); err += "\n"; } + // Check the min sdk version + int min_sdk_version = p_preset->get("version/min_sdk"); + if (min_sdk_version != DEFAULT_MIN_SDK_VERSION && !custom_build_enabled) { + valid = false; + err += TTR("Changing the \"Min Sdk\" is only valid when \"Use Custom Build\" is enabled."); + err += "\n"; + } + + // Check the target sdk version + int target_sdk_version = p_preset->get("version/target_sdk"); + if (target_sdk_version != DEFAULT_TARGET_SDK_VERSION && !custom_build_enabled) { + valid = false; + err += TTR("Changing the \"Target Sdk\" is only valid when \"Use Custom Build\" is enabled."); + err += "\n"; + } + + if (target_sdk_version < min_sdk_version) { + valid = false; + err += TTR("\"Target Sdk\" version must be greater or equal to \"Min Sdk\" version."); + err += "\n"; + } + r_error = err; return valid; } @@ -2559,6 +2608,8 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP String package_name = get_package_name(p_preset->get("package/unique_name")); String version_code = itos(p_preset->get("version/code")); String version_name = p_preset->get("version/name"); + String min_sdk_version = itos(p_preset->get("version/min_sdk")); + String target_sdk_version = itos(p_preset->get("version/target_sdk")); String enabled_abi_string = String("|").join(enabled_abis); String sign_flag = should_sign ? "true" : "false"; String zipalign_flag = "true"; @@ -2588,6 +2639,8 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP cmdline.push_back("-Pexport_package_name=" + package_name); // argument to specify the package name. cmdline.push_back("-Pexport_version_code=" + version_code); // argument to specify the version code. cmdline.push_back("-Pexport_version_name=" + version_name); // argument to specify the version name. + cmdline.push_back("-Pexport_version_min_sdk=" + min_sdk_version); // argument to specify the min sdk. + cmdline.push_back("-Pexport_version_target_sdk=" + target_sdk_version); // argument to specify the target sdk. cmdline.push_back("-Pexport_enabled_abis=" + enabled_abi_string); // argument to specify enabled ABIs. cmdline.push_back("-Pplugins_local_binaries=" + local_plugins_binaries); // argument to specify the list of plugins local dependencies. cmdline.push_back("-Pplugins_remote_binaries=" + remote_plugins_binaries); // argument to specify the list of plugins remote dependencies. @@ -2680,13 +2733,13 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP src_apk = p_preset->get("custom_template/release"); } src_apk = src_apk.strip_edges(); - if (src_apk == "") { + if (src_apk.is_empty()) { if (p_debug) { src_apk = find_export_template("android_debug.apk"); } else { src_apk = find_export_template("android_release.apk"); } - if (src_apk == "") { + if (src_apk.is_empty()) { EditorNode::add_io_error(vformat(TTR("Package not found: %s"), src_apk)); return ERR_FILE_NOT_FOUND; } diff --git a/platform/android/export/gradle_export_util.cpp b/platform/android/export/gradle_export_util.cpp index 658c0ecd0a..27c84baa44 100644 --- a/platform/android/export/gradle_export_util.cpp +++ b/platform/android/export/gradle_export_util.cpp @@ -161,7 +161,7 @@ Error _create_project_name_strings_files(const Ref<EditorExportPreset> &p_preset da->list_dir_begin(); while (true) { String file = da->get_next(); - if (file == "") { + if (file.is_empty()) { break; } if (!file.begins_with("values-")) { @@ -252,8 +252,10 @@ String _get_activity_tag(const Ref<EditorExportPreset> &p_preset) { String orientation = _get_android_orientation_label(DisplayServer::ScreenOrientation(int(GLOBAL_GET("display/window/handheld/orientation")))); String manifest_activity_text = vformat( " <activity android:name=\"com.godot.game.GodotApp\" " - "tools:replace=\"android:screenOrientation\" " + "tools:replace=\"android:screenOrientation,android:excludeFromRecents\" " + "android:excludeFromRecents=\"%s\" " "android:screenOrientation=\"%s\">\n", + bool_to_string(p_preset->get("package/exclude_from_recents")), orientation); if (uses_xr) { manifest_activity_text += " <meta-data tools:node=\"replace\" android:name=\"com.oculus.vr.focusaware\" android:value=\"true\" />\n"; @@ -275,7 +277,9 @@ String _get_application_tag(const Ref<EditorExportPreset> &p_preset, bool p_has_ " android:hasFragileUserData=\"%s\"\n" " android:requestLegacyExternalStorage=\"%s\"\n" " tools:replace=\"android:allowBackup,android:isGame,android:hasFragileUserData,android:requestLegacyExternalStorage\"\n" - " tools:ignore=\"GoogleAppIndexingWarning\">\n\n", + " tools:ignore=\"GoogleAppIndexingWarning\">\n\n" + " <meta-data tools:node=\"remove\" android:name=\"xr_mode_metadata_name\" />\n" + " <meta-data tools:node=\"remove\" android:name=\"xr_hand_tracking_metadata_name\" />\n", bool_to_string(p_preset->get("user_data_backup/allow")), bool_to_string(p_preset->get("package/classify_as_game")), bool_to_string(p_preset->get("package/retain_data_on_uninstall")), @@ -283,6 +287,15 @@ String _get_application_tag(const Ref<EditorExportPreset> &p_preset, bool p_has_ if (uses_xr) { manifest_application_text += " <meta-data tools:node=\"replace\" android:name=\"com.samsung.android.vr.application.mode\" android:value=\"vr_only\" />\n"; + + bool hand_tracking_enabled = (int)(p_preset->get("xr_features/hand_tracking")) > XR_HAND_TRACKING_NONE; + if (hand_tracking_enabled) { + int hand_tracking_frequency_index = p_preset->get("xr_features/hand_tracking_frequency"); + String hand_tracking_frequency = hand_tracking_frequency_index == XR_HAND_TRACKING_FREQUENCY_LOW ? "LOW" : "HIGH"; + manifest_application_text += vformat( + " <meta-data tools:node=\"replace\" android:name=\"com.oculus.handtracking.frequency\" android:value=\"%s\" />\n", + hand_tracking_frequency); + } } manifest_application_text += _get_activity_tag(p_preset); manifest_application_text += " </application>\n"; diff --git a/platform/android/export/gradle_export_util.h b/platform/android/export/gradle_export_util.h index db05c7534c..3c440f3e29 100644 --- a/platform/android/export/gradle_export_util.h +++ b/platform/android/export/gradle_export_util.h @@ -54,6 +54,10 @@ static const int XR_HAND_TRACKING_NONE = 0; static const int XR_HAND_TRACKING_OPTIONAL = 1; static const int XR_HAND_TRACKING_REQUIRED = 2; +// Supported XR hand tracking frequencies. +static const int XR_HAND_TRACKING_FREQUENCY_LOW = 0; +static const int XR_HAND_TRACKING_FREQUENCY_HIGH = 1; + // Supported XR passthrough modes. static const int XR_PASSTHROUGH_NONE = 0; static const int XR_PASSTHROUGH_OPTIONAL = 1; diff --git a/platform/android/java/app/AndroidManifest.xml b/platform/android/java/app/AndroidManifest.xml index 9ae6367b42..3924aacccd 100644 --- a/platform/android/java/app/AndroidManifest.xml +++ b/platform/android/java/app/AndroidManifest.xml @@ -38,11 +38,19 @@ android:name="xr_mode_metadata_name" android:value="xr_mode_metadata_value" /> + <!-- XR hand tracking metadata --> + <!-- This is modified by the exporter based on the selected xr mode. DO NOT CHANGE the values here. --> + <!-- Removed at export time if the xr mode is not VR or hand tracking is disabled. --> + <meta-data + android:name="xr_hand_tracking_metadata_name" + android:value="xr_hand_tracking_metadata_value"/> + <activity android:name=".GodotApp" android:label="@string/godot_project_name_string" android:theme="@style/GodotAppSplashTheme" android:launchMode="singleTask" + android:excludeFromRecents="false" android:screenOrientation="landscape" android:configChanges="orientation|keyboardHidden|screenSize|smallestScreenSize|density|keyboard|navigation|screenLayout|uiMode" android:resizeableActivity="false" diff --git a/platform/android/java/app/build.gradle b/platform/android/java/app/build.gradle index a391a3ca9a..5d1a9d7b99 100644 --- a/platform/android/java/app/build.gradle +++ b/platform/android/java/app/build.gradle @@ -91,8 +91,8 @@ android { applicationId getExportPackageName() versionCode getExportVersionCode() versionName getExportVersionName() - minSdkVersion versions.minSdk - targetSdkVersion versions.targetSdk + minSdkVersion getExportMinSdkVersion() + targetSdkVersion getExportTargetSdkVersion() } lintOptions { diff --git a/platform/android/java/app/config.gradle b/platform/android/java/app/config.gradle index 2a2850df0f..32e03998da 100644 --- a/platform/android/java/app/config.gradle +++ b/platform/android/java/app/config.gradle @@ -1,8 +1,8 @@ ext.versions = [ androidGradlePlugin: '7.0.3', compileSdk : 30, - minSdk : 19, // Also update 'platform/android/java/lib/AndroidManifest.xml#minSdkVersion' value - targetSdk : 30, // Also update 'platform/android/java/lib/AndroidManifest.xml#targetSdkVersion' value + minSdk : 19, // Also update 'platform/android/java/lib/AndroidManifest.xml#minSdkVersion' & 'platform/android/export/export_plugin.cpp#DEFAULT_MIN_SDK_VERSION' + targetSdk : 30, // Also update 'platform/android/java/lib/AndroidManifest.xml#targetSdkVersion' & 'platform/android/export/export_plugin.cpp#DEFAULT_TARGET_SDK_VERSION' buildTools : '30.0.3', kotlinVersion : '1.5.10', fragmentVersion : '1.3.6', @@ -48,6 +48,30 @@ ext.getExportVersionName = { -> return versionName } +ext.getExportMinSdkVersion = { -> + String minSdkVersion = project.hasProperty("export_version_min_sdk") ? project.property("export_version_min_sdk") : "" + if (minSdkVersion == null || minSdkVersion.isEmpty()) { + minSdkVersion = "$versions.minSdk" + } + try { + return Integer.parseInt(minSdkVersion) + } catch (NumberFormatException ignored) { + return versions.minSdk + } +} + +ext.getExportTargetSdkVersion = { -> + String targetSdkVersion = project.hasProperty("export_version_target_sdk") ? project.property("export_version_target_sdk") : "" + if (targetSdkVersion == null || targetSdkVersion.isEmpty()) { + targetSdkVersion = "$versions.targetSdk" + } + try { + return Integer.parseInt(targetSdkVersion) + } catch (NumberFormatException ignored) { + return versions.targetSdk + } +} + ext.getGodotEditorVersion = { -> String editorVersion = project.hasProperty("godot_editor_version") ? project.property("godot_editor_version") : "" if (editorVersion == null || editorVersion.isEmpty()) { 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 17ff3c75c0..2fecf2e6ba 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/Godot.java +++ b/platform/android/java/lib/src/org/godotengine/godot/Godot.java @@ -727,45 +727,78 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC }); } - @Override - public void onSensorChanged(SensorEvent event) { + public float[] getRotatedValues(float values[]) { + if (values == null || values.length != 3) { + return values; + } + Display display = ((WindowManager)getActivity().getSystemService(WINDOW_SERVICE)).getDefaultDisplay(); int displayRotation = display.getRotation(); - float[] adjustedValues = new float[3]; - final int[][] axisSwap = { - { 1, -1, 0, 1 }, // ROTATION_0 - { -1, -1, 1, 0 }, // ROTATION_90 - { -1, 1, 0, 1 }, // ROTATION_180 - { 1, 1, 1, 0 } - }; // ROTATION_270 + float[] rotatedValues = new float[3]; + switch (displayRotation) { + case Surface.ROTATION_0: + rotatedValues[0] = values[0]; + rotatedValues[1] = values[1]; + rotatedValues[2] = values[2]; + break; + case Surface.ROTATION_90: + rotatedValues[0] = -values[1]; + rotatedValues[1] = values[0]; + rotatedValues[2] = values[2]; + break; + case Surface.ROTATION_180: + rotatedValues[0] = -values[0]; + rotatedValues[1] = -values[1]; + rotatedValues[2] = values[2]; + break; + case Surface.ROTATION_270: + rotatedValues[0] = values[1]; + rotatedValues[1] = -values[0]; + rotatedValues[2] = values[2]; + break; + } - final int[] as = axisSwap[displayRotation]; - adjustedValues[0] = (float)as[0] * event.values[as[2]]; - adjustedValues[1] = (float)as[1] * event.values[as[3]]; - adjustedValues[2] = event.values[2]; + return rotatedValues; + } - final float x = adjustedValues[0]; - final float y = adjustedValues[1]; - final float z = adjustedValues[2]; + @Override + public void onSensorChanged(SensorEvent event) { + if (mRenderView == null) { + return; + } final int typeOfSensor = event.sensor.getType(); - if (mRenderView != null) { - mRenderView.queueOnRenderThread(() -> { - if (typeOfSensor == Sensor.TYPE_ACCELEROMETER) { - GodotLib.accelerometer(-x, y, -z); - } - if (typeOfSensor == Sensor.TYPE_GRAVITY) { - GodotLib.gravity(-x, y, -z); - } - if (typeOfSensor == Sensor.TYPE_MAGNETIC_FIELD) { - GodotLib.magnetometer(-x, y, -z); - } - if (typeOfSensor == Sensor.TYPE_GYROSCOPE) { - GodotLib.gyroscope(x, -y, z); - } - }); + switch (typeOfSensor) { + case Sensor.TYPE_ACCELEROMETER: { + float[] rotatedValues = getRotatedValues(event.values); + mRenderView.queueOnRenderThread(() -> { + GodotLib.accelerometer(-rotatedValues[0], -rotatedValues[1], -rotatedValues[2]); + }); + break; + } + case Sensor.TYPE_GRAVITY: { + float[] rotatedValues = getRotatedValues(event.values); + mRenderView.queueOnRenderThread(() -> { + GodotLib.gravity(-rotatedValues[0], -rotatedValues[1], -rotatedValues[2]); + }); + break; + } + case Sensor.TYPE_MAGNETIC_FIELD: { + float[] rotatedValues = getRotatedValues(event.values); + mRenderView.queueOnRenderThread(() -> { + GodotLib.magnetometer(-rotatedValues[0], -rotatedValues[1], -rotatedValues[2]); + }); + break; + } + case Sensor.TYPE_GYROSCOPE: { + float[] rotatedValues = getRotatedValues(event.values); + mRenderView.queueOnRenderThread(() -> { + GodotLib.gyroscope(rotatedValues[0], rotatedValues[1], rotatedValues[2]); + }); + break; + } } } diff --git a/platform/android/os_android.cpp b/platform/android/os_android.cpp index 0e5e10bc0a..ffd69a56b9 100644 --- a/platform/android/os_android.cpp +++ b/platform/android/os_android.cpp @@ -198,7 +198,7 @@ String OS_Android::get_resource_dir() const { String OS_Android::get_locale() const { String locale = godot_io_java->get_locale(); - if (locale != "") { + if (!locale.is_empty()) { return locale; } @@ -207,7 +207,7 @@ String OS_Android::get_locale() const { String OS_Android::get_model_name() const { String model = godot_io_java->get_model(); - if (model != "") + if (!model.is_empty()) return model; return OS_Unix::get_model_name(); @@ -218,11 +218,11 @@ String OS_Android::get_data_path() const { } String OS_Android::get_user_data_dir() const { - if (data_dir_cache != String()) + if (!data_dir_cache.is_empty()) return data_dir_cache; String data_dir = godot_io_java->get_user_data_dir(); - if (data_dir != "") { + if (!data_dir.is_empty()) { data_dir_cache = _remove_symlink(data_dir); return data_dir_cache; } @@ -230,11 +230,11 @@ String OS_Android::get_user_data_dir() const { } String OS_Android::get_cache_path() const { - if (cache_dir_cache != String()) + if (!cache_dir_cache.is_empty()) return cache_dir_cache; String cache_dir = godot_io_java->get_cache_dir(); - if (cache_dir != "") { + if (!cache_dir.is_empty()) { cache_dir_cache = _remove_symlink(cache_dir); return cache_dir_cache; } @@ -243,7 +243,7 @@ String OS_Android::get_cache_path() const { String OS_Android::get_unique_id() const { String unique_id = godot_io_java->get_unique_id(); - if (unique_id != "") + if (!unique_id.is_empty()) return unique_id; return OS::get_unique_id(); diff --git a/platform/iphone/display_server_iphone.h b/platform/iphone/display_server_iphone.h index 5cfcc1765c..5ed03cc06e 100644 --- a/platform/iphone/display_server_iphone.h +++ b/platform/iphone/display_server_iphone.h @@ -54,8 +54,8 @@ class DisplayServerIPhone : public DisplayServer { _THREAD_SAFE_CLASS_ #if defined(VULKAN_ENABLED) - VulkanContextIPhone *context_vulkan; - RenderingDeviceVulkan *rendering_device_vulkan; + VulkanContextIPhone *context_vulkan = nullptr; + RenderingDeviceVulkan *rendering_device_vulkan = nullptr; #endif DisplayServer::ScreenOrientation screen_orientation; diff --git a/platform/iphone/display_server_iphone.mm b/platform/iphone/display_server_iphone.mm index b746c60d4e..6a01ca1b13 100644 --- a/platform/iphone/display_server_iphone.mm +++ b/platform/iphone/display_server_iphone.mm @@ -54,6 +54,8 @@ DisplayServerIPhone::DisplayServerIPhone(const String &p_rendering_driver, Windo #if defined(GLES3_ENABLED) // FIXME: Add support for both OpenGL and Vulkan when OpenGL is implemented // again, + // Note that we should be checking "opengl3" as the driver, might never enable this seeing OpenGL is deprecated on iOS + // We are hardcoding the rendering_driver to "vulkan" down below if (rendering_driver == "opengl_es") { bool gl_initialization_error = false; @@ -131,18 +133,16 @@ DisplayServerIPhone::DisplayServerIPhone(const String &p_rendering_driver, Windo DisplayServerIPhone::~DisplayServerIPhone() { #if defined(VULKAN_ENABLED) - if (rendering_driver == "vulkan") { - if (rendering_device_vulkan) { - rendering_device_vulkan->finalize(); - memdelete(rendering_device_vulkan); - rendering_device_vulkan = nullptr; - } + if (rendering_device_vulkan) { + rendering_device_vulkan->finalize(); + memdelete(rendering_device_vulkan); + rendering_device_vulkan = nullptr; + } - if (context_vulkan) { - context_vulkan->window_destroy(MAIN_WINDOW_ID); - memdelete(context_vulkan); - context_vulkan = nullptr; - } + if (context_vulkan) { + context_vulkan->window_destroy(MAIN_WINDOW_ID); + memdelete(context_vulkan); + context_vulkan = nullptr; } #endif } @@ -565,10 +565,8 @@ void DisplayServerIPhone::resize_window(CGSize viewSize) { Size2i size = Size2i(viewSize.width, viewSize.height) * screen_get_max_scale(); #if defined(VULKAN_ENABLED) - if (rendering_driver == "vulkan") { - if (context_vulkan) { - context_vulkan->window_resize(MAIN_WINDOW_ID, size.x, size.y); - } + if (context_vulkan) { + context_vulkan->window_resize(MAIN_WINDOW_ID, size.x, size.y); } #endif diff --git a/platform/iphone/export/export_plugin.cpp b/platform/iphone/export/export_plugin.cpp index 0abd255c7c..247b456b26 100644 --- a/platform/iphone/export/export_plugin.cpp +++ b/platform/iphone/export/export_plugin.cpp @@ -1363,10 +1363,10 @@ Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_p src_pkg_name = p_preset->get("custom_template/release"); } - if (src_pkg_name == "") { + if (src_pkg_name.is_empty()) { String err; src_pkg_name = find_export_template("iphone.zip", &err); - if (src_pkg_name == "") { + if (src_pkg_name.is_empty()) { EditorNode::add_io_error(err); return ERR_FILE_NOT_FOUND; } @@ -1767,7 +1767,7 @@ bool EditorExportPlatformIOS::can_export(const Ref<EditorExportPreset> &p_preset } String etc_error = test_etc2_or_pvrtc(); - if (etc_error != String()) { + if (!etc_error.is_empty()) { valid = false; err += etc_error; } diff --git a/platform/javascript/export/export_plugin.cpp b/platform/javascript/export/export_plugin.cpp index 018dd3b664..9733435584 100644 --- a/platform/javascript/export/export_plugin.cpp +++ b/platform/javascript/export/export_plugin.cpp @@ -380,7 +380,7 @@ bool EditorExportPlatformJavaScript::can_export(const Ref<EditorExportPreset> &p if (p_preset->get("vram_texture_compression/for_mobile")) { String etc_error = test_etc2(); - if (etc_error != String()) { + if (!etc_error.is_empty()) { valid = false; err += etc_error; } @@ -415,7 +415,7 @@ Error EditorExportPlatformJavaScript::export_project(const Ref<EditorExportPrese // Find the correct template String template_path = p_debug ? custom_debug : custom_release; template_path = template_path.strip_edges(); - if (template_path == String()) { + if (template_path.is_empty()) { ExportMode mode = (ExportMode)(int)p_preset->get("variant/export_type"); template_path = find_export_template(_get_template_name(mode, p_debug)); } @@ -424,7 +424,7 @@ Error EditorExportPlatformJavaScript::export_project(const Ref<EditorExportPrese return ERR_FILE_BAD_PATH; } - if (template_path != String() && !FileAccess::exists(template_path)) { + if (!template_path.is_empty() && !FileAccess::exists(template_path)) { EditorNode::get_singleton()->show_warning(TTR("Template file not found:") + "\n" + template_path); return ERR_FILE_NOT_FOUND; } diff --git a/platform/linuxbsd/detect.py b/platform/linuxbsd/detect.py index 07e16a982b..ab643b254a 100644 --- a/platform/linuxbsd/detect.py +++ b/platform/linuxbsd/detect.py @@ -161,7 +161,7 @@ def configure(env): env.Append(LINKFLAGS=["-ftest-coverage", "-fprofile-arcs"]) if env["use_ubsan"] or env["use_asan"] or env["use_lsan"] or env["use_tsan"] or env["use_msan"]: - env.extra_suffix += "s" + env.extra_suffix += ".san" if env["use_ubsan"]: env.Append( diff --git a/platform/linuxbsd/detect_prime_x11.cpp b/platform/linuxbsd/detect_prime_x11.cpp index c775546f15..5bcfc44f12 100644 --- a/platform/linuxbsd/detect_prime_x11.cpp +++ b/platform/linuxbsd/detect_prime_x11.cpp @@ -91,7 +91,7 @@ void create_context() { }; int fbcount; - GLXFBConfig fbconfig = 0; + GLXFBConfig fbconfig = nullptr; XVisualInfo *vi = nullptr; XSetWindowAttributes swa; @@ -100,8 +100,9 @@ void create_context() { unsigned long valuemask = CWBorderPixel | CWColormap | CWEventMask; GLXFBConfig *fbc = glXChooseFBConfig(x11_display, DefaultScreen(x11_display), visual_attribs, &fbcount); - if (!fbc) + if (!fbc) { exit(1); + } vi = glXGetVisualFromFBConfig(x11_display, fbc[0]); @@ -120,8 +121,9 @@ void create_context() { swa.colormap = XCreateColormap(x11_display, RootWindow(x11_display, vi->screen), vi->visual, AllocNone); x11_window = XCreateWindow(x11_display, RootWindow(x11_display, vi->screen), 0, 0, 10, 10, 0, vi->depth, InputOutput, vi->visual, valuemask, &swa); - if (!x11_window) + if (!x11_window) { exit(1); + } glXMakeCurrent(x11_display, x11_window, glx_context); XFree(vi); @@ -179,8 +181,9 @@ int detect_prime() { close(fdset[0]); - if (i) + if (i) { setenv("DRI_PRIME", "1", 1); + } create_context(); const char *vendor = (const char *)glGetString(GL_VENDOR); diff --git a/platform/linuxbsd/display_server_x11.cpp b/platform/linuxbsd/display_server_x11.cpp index 74ec8b652f..247665e313 100644 --- a/platform/linuxbsd/display_server_x11.cpp +++ b/platform/linuxbsd/display_server_x11.cpp @@ -1150,7 +1150,7 @@ void DisplayServerX11::delete_sub_window(WindowID p_id) { } #ifdef VULKAN_ENABLED - if (rendering_driver == "vulkan") { + if (context_vulkan) { context_vulkan->window_destroy(p_id); } #endif @@ -2927,7 +2927,7 @@ void DisplayServerX11::_window_changed(XEvent *event) { wd.size = new_rect.size; #if defined(VULKAN_ENABLED) - if (rendering_driver == "vulkan") { + if (context_vulkan) { context_vulkan->window_resize(window_id, wd.size.width, wd.size.height); } #endif @@ -4672,12 +4672,12 @@ DisplayServerX11::~DisplayServerX11() { //destroy all windows for (KeyValue<WindowID, WindowData> &E : windows) { #ifdef VULKAN_ENABLED - if (rendering_driver == "vulkan") { + if (context_vulkan) { context_vulkan->window_destroy(E.key); } #endif #ifdef GLES3_ENABLED - if (rendering_driver == "opengl3") { + if (gl_manager) { gl_manager->window_destroy(E.key); } #endif @@ -4693,15 +4693,15 @@ DisplayServerX11::~DisplayServerX11() { //destroy drivers #if defined(VULKAN_ENABLED) - if (rendering_driver == "vulkan") { - if (rendering_device_vulkan) { - rendering_device_vulkan->finalize(); - memdelete(rendering_device_vulkan); - } + if (rendering_device_vulkan) { + rendering_device_vulkan->finalize(); + memdelete(rendering_device_vulkan); + rendering_device_vulkan = nullptr; + } - if (context_vulkan) { - memdelete(context_vulkan); - } + if (context_vulkan) { + memdelete(context_vulkan); + context_vulkan = nullptr; } #endif diff --git a/platform/linuxbsd/os_linuxbsd.cpp b/platform/linuxbsd/os_linuxbsd.cpp index 69474c6dec..c39b5cb784 100644 --- a/platform/linuxbsd/os_linuxbsd.cpp +++ b/platform/linuxbsd/os_linuxbsd.cpp @@ -419,7 +419,7 @@ Error OS_LinuxBSD::move_to_trash(const String &p_path) { String mnt = get_mountpoint(p_path); // If there is a directory "[Mountpoint]/.Trash-[UID], use it as the trash can. - if (mnt != "") { + if (!mnt.is_empty()) { String path(mnt + "/.Trash-" + itos(getuid())); struct stat s; if (!stat(path.utf8().get_data(), &s)) { @@ -428,7 +428,7 @@ Error OS_LinuxBSD::move_to_trash(const String &p_path) { } // Otherwise, if ${XDG_DATA_HOME} is defined, use "${XDG_DATA_HOME}/Trash" as the trash can. - if (trash_path == "") { + if (trash_path.is_empty()) { char *dhome = getenv("XDG_DATA_HOME"); if (dhome) { trash_path = String(dhome) + "/Trash"; @@ -436,7 +436,7 @@ Error OS_LinuxBSD::move_to_trash(const String &p_path) { } // Otherwise, if ${HOME} is defined, use "${HOME}/.local/share/Trash" as the trash can. - if (trash_path == "") { + if (trash_path.is_empty()) { char *home = getenv("HOME"); if (home) { trash_path = String(home) + "/.local/share/Trash"; @@ -444,7 +444,7 @@ Error OS_LinuxBSD::move_to_trash(const String &p_path) { } // Issue an error if none of the previous locations is appropriate for the trash can. - ERR_FAIL_COND_V_MSG(trash_path == "", FAILED, "Could not determine the trash can location"); + ERR_FAIL_COND_V_MSG(trash_path.is_empty(), FAILED, "Could not determine the trash can location"); // Create needed directories for decided trash can location. { diff --git a/platform/osx/detect.py b/platform/osx/detect.py index f5c7731395..c67791b340 100644 --- a/platform/osx/detect.py +++ b/platform/osx/detect.py @@ -124,7 +124,7 @@ def configure(env): env["AS"] = basecmd + "as" if env["use_ubsan"] or env["use_asan"] or env["use_tsan"]: - env.extra_suffix += "s" + env.extra_suffix += ".san" if env["use_ubsan"]: env.Append( diff --git a/platform/osx/display_server_osx.mm b/platform/osx/display_server_osx.mm index fec5c98a99..7cd51611b3 100644 --- a/platform/osx/display_server_osx.mm +++ b/platform/osx/display_server_osx.mm @@ -167,12 +167,12 @@ static NSCursor *_cursorFromSelector(SEL selector, SEL fallback = nil) { } #if defined(GLES3_ENABLED) - if (DS_OSX->rendering_driver == "opengl3") { + if (DS_OSX->gl_manager) { DS_OSX->gl_manager->window_destroy(window_id); } #endif #ifdef VULKAN_ENABLED - if (DS_OSX->rendering_driver == "vulkan") { + if (DS_OSX->context_vulkan) { DS_OSX->context_vulkan->window_destroy(window_id); } #endif @@ -272,12 +272,12 @@ static NSCursor *_cursorFromSelector(SEL selector, SEL fallback = nil) { } #if defined(GLES3_ENABLED) - if (DS_OSX->rendering_driver == "opengl3") { + if (DS_OSX->gl_manager) { DS_OSX->gl_manager->window_resize(window_id, wd.size.width, wd.size.height); } #endif #if defined(VULKAN_ENABLED) - if (DS_OSX->rendering_driver == "vulkan") { + if (DS_OSX->context_vulkan) { DS_OSX->context_vulkan->window_resize(window_id, wd.size.width, wd.size.height); } #endif @@ -403,7 +403,7 @@ static NSCursor *_cursorFromSelector(SEL selector, SEL fallback = nil) { - (CALayer *)makeBackingLayer { #if defined(VULKAN_ENABLED) - if (DS_OSX->rendering_driver == "vulkan") { + if (DS_OSX->context_vulkan) { CALayer *layer = [[CAMetalLayer class] layer]; return layer; } @@ -413,12 +413,12 @@ static NSCursor *_cursorFromSelector(SEL selector, SEL fallback = nil) { - (void)updateLayer { #if defined(GLES3_ENABLED) - if (DS_OSX->rendering_driver == "opengl3") { + if (DS_OSX->gl_manager) { DS_OSX->gl_manager->window_update(window_id); } #endif #if defined(VULKAN_ENABLED) - if (DS_OSX->rendering_driver == "vulkan") { + if (DS_OSX->context_vulkan) { [super updateLayer]; } #endif @@ -2577,12 +2577,12 @@ void DisplayServerOSX::_set_window_per_pixel_transparency_enabled(bool p_enabled [layer setOpaque:NO]; } #if defined(VULKAN_ENABLED) - if (rendering_driver == "vulkan") { + if (context_vulkan) { //TODO - implement transparency for Vulkan } #endif #if defined(GLES3_ENABLED) - if (rendering_driver == "opengl3") { + if (gl_manager) { //TODO - reimplement OpenGLES } #endif @@ -2596,24 +2596,24 @@ void DisplayServerOSX::_set_window_per_pixel_transparency_enabled(bool p_enabled [layer setOpaque:YES]; } #if defined(VULKAN_ENABLED) - if (rendering_driver == "vulkan") { + if (context_vulkan) { //TODO - implement transparency for Vulkan } #endif #if defined(GLES3_ENABLED) - if (rendering_driver == "opengl3") { + if (gl_manager) { //TODO - reimplement OpenGLES } #endif wd.layered_window = false; } #if defined(GLES3_ENABLED) - if (rendering_driver == "opengl3") { + if (gl_manager) { //TODO - reimplement OpenGLES } #endif #if defined(VULKAN_ENABLED) - if (rendering_driver == "vulkan") { + if (context_vulkan) { //TODO - implement transparency for Vulkan } #endif @@ -3451,12 +3451,12 @@ void DisplayServerOSX::set_icon(const Ref<Image> &p_icon) { void DisplayServerOSX::window_set_vsync_mode(DisplayServer::VSyncMode p_vsync_mode, WindowID p_window) { _THREAD_SAFE_METHOD_ #if defined(GLES3_ENABLED) - if (rendering_driver == "opengl3") { + if (gl_manager) { gl_manager->swap_buffers(); } #endif #if defined(VULKAN_ENABLED) - if (rendering_driver == "vulkan") { + if (context_vulkan) { context_vulkan->set_vsync_mode(p_window, p_vsync_mode); } #endif @@ -3465,12 +3465,12 @@ void DisplayServerOSX::window_set_vsync_mode(DisplayServer::VSyncMode p_vsync_mo DisplayServer::VSyncMode DisplayServerOSX::window_get_vsync_mode(WindowID p_window) const { _THREAD_SAFE_METHOD_ #if defined(GLES3_ENABLED) - if (rendering_driver == "opengl3") { + if (gl_manager) { return (gl_manager->is_using_vsync() ? DisplayServer::VSyncMode::VSYNC_ENABLED : DisplayServer::VSyncMode::VSYNC_DISABLED); } #endif #if defined(VULKAN_ENABLED) - if (rendering_driver == "vulkan") { + if (context_vulkan) { return context_vulkan->get_vsync_mode(p_window); } #endif @@ -3586,19 +3586,15 @@ DisplayServerOSX::WindowID DisplayServerOSX::_create_window(WindowMode p_mode, V } #if defined(VULKAN_ENABLED) - if (rendering_driver == "vulkan") { - if (context_vulkan) { - Error err = context_vulkan->window_create(window_id_counter, p_vsync_mode, wd.window_view, p_rect.size.width, p_rect.size.height); - ERR_FAIL_COND_V_MSG(err != OK, INVALID_WINDOW_ID, "Can't create a Vulkan context"); - } + if (context_vulkan) { + Error err = context_vulkan->window_create(window_id_counter, p_vsync_mode, wd.window_view, p_rect.size.width, p_rect.size.height); + ERR_FAIL_COND_V_MSG(err != OK, INVALID_WINDOW_ID, "Can't create a Vulkan context"); } #endif #if defined(GLES3_ENABLED) - if (rendering_driver == "opengl3") { - if (gl_manager) { - Error err = gl_manager->window_create(window_id_counter, wd.window_view, p_rect.size.width, p_rect.size.height); - ERR_FAIL_COND_V_MSG(err != OK, INVALID_WINDOW_ID, "Can't create an OpenGL context"); - } + if (gl_manager) { + Error err = gl_manager->window_create(window_id_counter, wd.window_view, p_rect.size.width, p_rect.size.height); + ERR_FAIL_COND_V_MSG(err != OK, INVALID_WINDOW_ID, "Can't create an OpenGL context"); } #endif id = window_id_counter++; @@ -3618,12 +3614,12 @@ DisplayServerOSX::WindowID DisplayServerOSX::_create_window(WindowMode p_mode, V } #if defined(GLES3_ENABLED) - if (rendering_driver == "opengl3") { + if (gl_manager) { gl_manager->window_resize(id, wd.size.width, wd.size.height); } #endif #if defined(VULKAN_ENABLED) - if (rendering_driver == "vulkan") { + if (context_vulkan) { context_vulkan->window_resize(id, wd.size.width, wd.size.height); } #endif diff --git a/platform/osx/export/export_plugin.cpp b/platform/osx/export/export_plugin.cpp index 36a2e5e205..8126510245 100644 --- a/platform/osx/export/export_plugin.cpp +++ b/platform/osx/export/export_plugin.cpp @@ -481,10 +481,10 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p src_pkg_name = p_preset->get("custom_template/release"); } - if (src_pkg_name == "") { + if (src_pkg_name.is_empty()) { String err; src_pkg_name = find_export_template("osx.zip", &err); - if (src_pkg_name == "") { + if (src_pkg_name.is_empty()) { EditorNode::add_io_error(err); return ERR_FILE_NOT_FOUND; } @@ -607,7 +607,7 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p iconpath = ProjectSettings::get_singleton()->get("application/config/icon"); } - if (iconpath != "") { + if (!iconpath.is_empty()) { if (iconpath.get_extension() == "icns") { FileAccess *icon = FileAccess::open(iconpath, FileAccess::READ); if (icon) { @@ -695,7 +695,7 @@ Error EditorExportPlatformOSX::export_project(const Ref<EditorExportPreset> &p_p String ent_path = p_preset->get("codesign/entitlements/custom_file"); String hlp_ent_path = EditorPaths::get_singleton()->get_cache_dir().plus_file(pkg_name + "_helper.entitlements"); - if (sign_enabled && (ent_path == "")) { + if (sign_enabled && (ent_path.is_empty())) { ent_path = EditorPaths::get_singleton()->get_cache_dir().plus_file(pkg_name + ".entitlements"); FileAccess *ent_f = FileAccess::open(ent_path, FileAccess::WRITE); diff --git a/platform/uwp/export/export_plugin.cpp b/platform/uwp/export/export_plugin.cpp index 192814efe4..31a6889543 100644 --- a/platform/uwp/export/export_plugin.cpp +++ b/platform/uwp/export/export_plugin.cpp @@ -257,7 +257,7 @@ Error EditorExportPlatformUWP::export_project(const Ref<EditorExportPreset> &p_p Platform arch = (Platform)(int)p_preset->get("architecture/target"); - if (src_appx == "") { + if (src_appx.is_empty()) { String err, infix; switch (arch) { case ARM: { @@ -275,7 +275,7 @@ Error EditorExportPlatformUWP::export_project(const Ref<EditorExportPreset> &p_p } else { src_appx = find_export_template("uwp" + infix + "release.zip", &err); } - if (src_appx == "") { + if (src_appx.is_empty()) { EditorNode::add_io_error(err); return ERR_FILE_NOT_FOUND; } @@ -431,7 +431,7 @@ Error EditorExportPlatformUWP::export_project(const Ref<EditorExportPreset> &p_p #ifdef WINDOWS_ENABLED // Sign with signtool String signtool_path = EditorSettings::get_singleton()->get("export/uwp/signtool"); - if (signtool_path == String()) { + if (signtool_path.is_empty()) { return OK; } @@ -452,7 +452,7 @@ Error EditorExportPlatformUWP::export_project(const Ref<EditorExportPreset> &p_p cert_alg = p_preset->get("signing/algorithm"); } - if (cert_path == String()) { + if (cert_path.is_empty()) { return OK; // Certificate missing, don't try to sign } diff --git a/platform/windows/detect.py b/platform/windows/detect.py index aaaa50e729..e9ecc99ef5 100644 --- a/platform/windows/detect.py +++ b/platform/windows/detect.py @@ -308,7 +308,7 @@ def configure_msvc(env, manual_msvc_config): # Sanitizers if env["use_asan"]: - env.extra_suffix += ".s" + env.extra_suffix += ".san" env.Append(LINKFLAGS=["/INFERASANLIBS"]) env.Append(CCFLAGS=["/fsanitize=address"]) diff --git a/platform/windows/display_server_windows.cpp b/platform/windows/display_server_windows.cpp index 9fe15366f4..899cf5dfad 100644 --- a/platform/windows/display_server_windows.cpp +++ b/platform/windows/display_server_windows.cpp @@ -538,12 +538,12 @@ void DisplayServerWindows::delete_sub_window(WindowID p_window) { } #ifdef VULKAN_ENABLED - if (rendering_driver == "vulkan") { + if (context_vulkan) { context_vulkan->window_destroy(p_window); } #endif #ifdef GLES3_ENABLED - if (rendering_driver == "opengl3") { + if (gl_manager) { gl_manager->window_destroy(p_window); } #endif @@ -828,12 +828,12 @@ void DisplayServerWindows::window_set_size(const Size2i p_size, WindowID p_windo wd.height = h; #if defined(VULKAN_ENABLED) - if (rendering_driver == "vulkan") { + if (context_vulkan) { context_vulkan->window_resize(p_window, w, h); } #endif #if defined(GLES3_ENABLED) - if (rendering_driver == "opengl3") { + if (gl_manager) { gl_manager->window_resize(p_window, w, h); } #endif @@ -1204,8 +1204,11 @@ void DisplayServerWindows::console_set_visible(bool p_enabled) { if (console_visible == p_enabled) { return; } - ShowWindow(GetConsoleWindow(), p_enabled ? SW_SHOW : SW_HIDE); - console_visible = p_enabled; + if (!((OS_Windows *)OS::get_singleton())->_is_win11_terminal()) { + // GetConsoleWindow is not supported by the Windows Terminal. + ShowWindow(GetConsoleWindow(), p_enabled ? SW_SHOW : SW_HIDE); + console_visible = p_enabled; + } } bool DisplayServerWindows::is_console_visible() const { @@ -1565,7 +1568,7 @@ String DisplayServerWindows::keyboard_get_layout_name(int p_index) const { GetKeyboardLayoutList(layout_count, layouts); String ret = _get_full_layout_name_from_registry(layouts[p_index]); // Try reading full name from Windows registry, fallback to locale name if failed (e.g. on Wine). - if (ret == String()) { + if (ret.is_empty()) { WCHAR buf[LOCALE_NAME_MAX_LENGTH]; memset(buf, 0, LOCALE_NAME_MAX_LENGTH * sizeof(WCHAR)); LCIDToLocaleName(MAKELCID(LOWORD(layouts[p_index]), SORT_DEFAULT), buf, LOCALE_NAME_MAX_LENGTH, 0); @@ -2643,7 +2646,7 @@ LRESULT DisplayServerWindows::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARA windows[window_id].height = window_h; #if defined(VULKAN_ENABLED) - if ((rendering_driver == "vulkan") && window_created) { + if (context_vulkan && window_created) { context_vulkan->window_resize(window_id, windows[window_id].width, windows[window_id].height); } #endif @@ -3105,7 +3108,7 @@ DisplayServer::WindowID DisplayServerWindows::_create_window(WindowMode p_mode, } #ifdef VULKAN_ENABLED - if (rendering_driver == "vulkan") { + if (context_vulkan) { if (context_vulkan->window_create(id, p_vsync_mode, wd.hWnd, hInstance, WindowRect.right - WindowRect.left, WindowRect.bottom - WindowRect.top) == -1) { memdelete(context_vulkan); context_vulkan = nullptr; @@ -3116,7 +3119,7 @@ DisplayServer::WindowID DisplayServerWindows::_create_window(WindowMode p_mode, #endif #ifdef GLES3_ENABLED - if (rendering_driver == "opengl3") { + if (gl_manager) { Error err = gl_manager->window_create(id, wd.hWnd, hInstance, WindowRect.right - WindowRect.left, WindowRect.bottom - WindowRect.top); ERR_FAIL_COND_V_MSG(err != OK, INVALID_WINDOW_ID, "Failed to create an OpenGL window."); } @@ -3455,7 +3458,7 @@ DisplayServerWindows::~DisplayServerWindows() { if (windows.has(MAIN_WINDOW_ID)) { #ifdef VULKAN_ENABLED - if (rendering_driver == "vulkan") { + if (context_vulkan) { context_vulkan->window_destroy(MAIN_WINDOW_ID); } #endif @@ -3467,14 +3470,15 @@ DisplayServerWindows::~DisplayServerWindows() { } #if defined(VULKAN_ENABLED) - if (rendering_driver == "vulkan") { - if (rendering_device_vulkan) { - rendering_device_vulkan->finalize(); - memdelete(rendering_device_vulkan); - } + if (rendering_device_vulkan) { + rendering_device_vulkan->finalize(); + memdelete(rendering_device_vulkan); + rendering_device_vulkan = nullptr; + } - if (context_vulkan) - memdelete(context_vulkan); + if (context_vulkan) { + memdelete(context_vulkan); + context_vulkan = nullptr; } #endif diff --git a/platform/windows/display_server_windows.h b/platform/windows/display_server_windows.h index a59f8ebb44..fec449ebce 100644 --- a/platform/windows/display_server_windows.h +++ b/platform/windows/display_server_windows.h @@ -305,12 +305,12 @@ class DisplayServerWindows : public DisplayServer { Point2i center; #if defined(GLES3_ENABLED) - GLManager_Windows *gl_manager; + GLManager_Windows *gl_manager = nullptr; #endif #if defined(VULKAN_ENABLED) - VulkanContextWindows *context_vulkan; - RenderingDeviceVulkan *rendering_device_vulkan; + VulkanContextWindows *context_vulkan = nullptr; + RenderingDeviceVulkan *rendering_device_vulkan = nullptr; #endif Map<int, Vector2> touch_state; diff --git a/platform/windows/export/export_plugin.cpp b/platform/windows/export/export_plugin.cpp index 165e86c066..5a1cdb0962 100644 --- a/platform/windows/export/export_plugin.cpp +++ b/platform/windows/export/export_plugin.cpp @@ -82,7 +82,7 @@ void EditorExportPlatformWindows::get_export_options(List<ExportOption> *r_optio 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()) { + if (rcedit_path.is_empty()) { return; } @@ -95,12 +95,12 @@ void EditorExportPlatformWindows::_rcedit_add_data(const Ref<EditorExportPreset> // On non-Windows we need WINE to run rcedit String wine_path = EditorSettings::get_singleton()->get("export/windows/wine"); - if (wine_path != String() && !FileAccess::exists(wine_path)) { + if (!wine_path.is_empty() && !FileAccess::exists(wine_path)) { ERR_PRINT("Could not find wine executable at " + wine_path + ", no icon or app information data will be included."); return; } - if (wine_path == String()) { + if (wine_path.is_empty()) { wine_path = "wine"; // try to run wine from PATH } #endif @@ -117,39 +117,39 @@ void EditorExportPlatformWindows::_rcedit_add_data(const Ref<EditorExportPreset> List<String> args; args.push_back(p_path); - if (icon_path != String()) { + if (!icon_path.is_empty()) { args.push_back("--set-icon"); args.push_back(icon_path); } - if (file_verion != String()) { + if (!file_verion.is_empty()) { args.push_back("--set-file-version"); args.push_back(file_verion); } - if (product_version != String()) { + if (!product_version.is_empty()) { args.push_back("--set-product-version"); args.push_back(product_version); } - if (company_name != String()) { + if (!company_name.is_empty()) { args.push_back("--set-version-string"); args.push_back("CompanyName"); args.push_back(company_name); } - if (product_name != String()) { + if (!product_name.is_empty()) { args.push_back("--set-version-string"); args.push_back("ProductName"); args.push_back(product_name); } - if (file_description != String()) { + if (!file_description.is_empty()) { args.push_back("--set-version-string"); args.push_back("FileDescription"); args.push_back(file_description); } - if (copyright != String()) { + if (!copyright.is_empty()) { args.push_back("--set-version-string"); args.push_back("LegalCopyright"); args.push_back(copyright); } - if (trademarks != String()) { + if (!trademarks.is_empty()) { args.push_back("--set-version-string"); args.push_back("LegalTrademarks"); args.push_back(trademarks); @@ -169,20 +169,20 @@ 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)) { + if (!signtool_path.is_empty() && !FileAccess::exists(signtool_path)) { ERR_PRINT("Could not find signtool executable at " + signtool_path + ", aborting."); return ERR_FILE_NOT_FOUND; } - if (signtool_path == String()) { + if (signtool_path.is_empty()) { signtool_path = "signtool"; // try to run signtool from PATH } #else String signtool_path = EditorSettings::get_singleton()->get("export/windows/osslsigncode"); - if (signtool_path != String() && !FileAccess::exists(signtool_path)) { + if (!signtool_path.is_empty() && !FileAccess::exists(signtool_path)) { ERR_PRINT("Could not find osslsigncode executable at " + signtool_path + ", aborting."); return ERR_FILE_NOT_FOUND; } - if (signtool_path == String()) { + if (signtool_path.is_empty()) { signtool_path = "osslsigncode"; // try to run signtool from PATH } #endif diff --git a/platform/windows/joypad_windows.cpp b/platform/windows/joypad_windows.cpp index 1d3761ee83..f76749ec54 100644 --- a/platform/windows/joypad_windows.cpp +++ b/platform/windows/joypad_windows.cpp @@ -97,11 +97,13 @@ bool JoypadWindows::have_device(const GUID &p_guid) { // adapted from SDL2, works a lot better than the MSDN version bool JoypadWindows::is_xinput_device(const GUID *p_guid) { - static GUID IID_ValveStreamingGamepad = { MAKELONG(0x28DE, 0x11FF), 0x0000, 0x0000, { 0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44 } }; + static GUID IID_ValveStreamingGamepad = { MAKELONG(0x28DE, 0x11FF), 0x28DE, 0x0000, { 0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44 } }; static GUID IID_X360WiredGamepad = { MAKELONG(0x045E, 0x02A1), 0x0000, 0x0000, { 0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44 } }; static GUID IID_X360WirelessGamepad = { MAKELONG(0x045E, 0x028E), 0x0000, 0x0000, { 0x00, 0x00, 0x50, 0x49, 0x44, 0x56, 0x49, 0x44 } }; - if (p_guid == &IID_ValveStreamingGamepad || p_guid == &IID_X360WiredGamepad || p_guid == &IID_X360WirelessGamepad) + if (memcmp(p_guid, &IID_ValveStreamingGamepad, sizeof(*p_guid)) == 0 || + memcmp(p_guid, &IID_X360WiredGamepad, sizeof(*p_guid)) == 0 || + memcmp(p_guid, &IID_X360WirelessGamepad, sizeof(*p_guid)) == 0) return true; PRAWINPUTDEVICELIST dev_list = nullptr; diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp index 6a0a4790fc..bb6a077a5d 100644 --- a/platform/windows/os_windows.cpp +++ b/platform/windows/os_windows.cpp @@ -467,6 +467,16 @@ Error OS_Windows::execute(const String &p_path, const List<String> &p_arguments, return OK; }; +bool OS_Windows::_is_win11_terminal() const { + HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE); + DWORD dwMode = 0; + if (GetConsoleMode(hStdOut, &dwMode)) { + return ((dwMode & ENABLE_VIRTUAL_TERMINAL_PROCESSING) == ENABLE_VIRTUAL_TERMINAL_PROCESSING); + } else { + return false; + } +} + Error OS_Windows::create_process(const String &p_path, const List<String> &p_arguments, ProcessID *r_child_id) { String path = p_path.replace("/", "\\"); String command = _quote_command_line_argument(path); @@ -484,6 +494,10 @@ Error OS_Windows::create_process(const String &p_path, const List<String> &p_arg #ifndef DEBUG_ENABLED dwCreationFlags |= CREATE_NO_WINDOW; #endif + if (p_path == get_executable_path() && GetConsoleWindow() != nullptr && _is_win11_terminal()) { + // Open a new terminal as a workaround for Windows Terminal bug. + dwCreationFlags |= CREATE_NEW_CONSOLE; + } int ret = CreateProcessW(nullptr, (LPWSTR)(command.utf16().ptrw()), nullptr, nullptr, false, dwCreationFlags, nullptr, nullptr, si_w, &pi.pi); ERR_FAIL_COND_V_MSG(ret == 0, ERR_CANT_FORK, "Could not create child process: " + command); @@ -606,7 +620,7 @@ String OS_Windows::get_locale() const { wl++; } - if (neutral != "") + if (!neutral.is_empty()) return String(neutral).replace("-", "_"); return "en"; @@ -757,11 +771,11 @@ String OS_Windows::get_system_dir(SystemDir p_dir, bool p_shared_storage) const String OS_Windows::get_user_data_dir() const { String appname = get_safe_dir_name(ProjectSettings::get_singleton()->get("application/config/name")); - if (appname != "") { + if (!appname.is_empty()) { bool use_custom_dir = ProjectSettings::get_singleton()->get("application/config/use_custom_user_dir"); if (use_custom_dir) { String custom_dir = get_safe_dir_name(ProjectSettings::get_singleton()->get("application/config/custom_user_dir_name"), true); - if (custom_dir == "") { + if (custom_dir.is_empty()) { custom_dir = appname; } return get_data_path().plus_file(custom_dir).replace("\\", "/"); diff --git a/platform/windows/os_windows.h b/platform/windows/os_windows.h index 1342d95575..086f63eb3e 100644 --- a/platform/windows/os_windows.h +++ b/platform/windows/os_windows.h @@ -157,6 +157,7 @@ public: void run(); + bool _is_win11_terminal() const; virtual bool _check_internal_feature_support(const String &p_feature) override; virtual void disable_crash_handler() override; |