feat: updated engine version to 4.4-rc1

This commit is contained in:
Sara 2025-02-23 14:38:14 +01:00
parent ee00efde1f
commit 21ba8e33af
5459 changed files with 1128836 additions and 198305 deletions

View file

@ -1,4 +1,5 @@
#!/usr/bin/env python
from misc.utility.scons_hints import *
Import("env")
@ -67,7 +68,6 @@ ios_lib = [
"ios.mm",
"rendering_context_driver_vulkan_ios.mm",
"display_server_ios.mm",
"joypad_ios.mm",
"godot_view.mm",
"tts_ios.mm",
"display_layer.mm",

View file

@ -2,7 +2,8 @@ import os
import sys
from typing import TYPE_CHECKING
from methods import detect_darwin_sdk_path, print_error
from methods import detect_darwin_sdk_path, print_error, print_warning
from platform_methods import validate_arch
if TYPE_CHECKING:
from SCons.Script.SConscript import SConsEnvironment
@ -51,7 +52,8 @@ def get_flags():
"arch": "arm64",
"target": "template_debug",
"use_volk": False,
"supported": ["mono"],
"metal": True,
"supported": ["metal", "mono"],
"builtin_pcre2_with_jit": False,
}
@ -59,12 +61,7 @@ def get_flags():
def configure(env: "SConsEnvironment"):
# Validate arch.
supported_arches = ["x86_64", "arm64"]
if env["arch"] not in supported_arches:
print_error(
'Unsupported CPU architecture "%s" for iOS. Supported architectures are: %s.'
% (env["arch"], ", ".join(supported_arches))
)
sys.exit(255)
validate_arch(env["arch"], get_name(), supported_arches)
## LTO
@ -133,7 +130,7 @@ def configure(env: "SConsEnvironment"):
elif env["arch"] == "arm64":
env.Append(
CCFLAGS=(
"-fobjc-arc -arch arm64 -fmessage-length=0 -fno-strict-aliasing"
"-fobjc-arc -arch arm64 -fmessage-length=0"
" -fdiagnostics-print-source-range-info -fdiagnostics-show-category=id -fdiagnostics-parseable-fixits"
" -fpascal-strings -fblocks -fvisibility=hidden -MMD -MT dependencies"
" -isysroot $IOS_SDK_PATH".split()
@ -154,11 +151,31 @@ def configure(env: "SConsEnvironment"):
env.Prepend(CPPPATH=["#platform/ios"])
env.Append(CPPDEFINES=["IOS_ENABLED", "UNIX_ENABLED", "COREAUDIO_ENABLED"])
if env["metal"] and env["ios_simulator"]:
print_warning("iOS simulator does not support the Metal rendering driver")
env["metal"] = False
if env["metal"]:
env.AppendUnique(CPPDEFINES=["METAL_ENABLED", "RD_ENABLED"])
env.Prepend(
CPPPATH=[
"$IOS_SDK_PATH/System/Library/Frameworks/Metal.framework/Headers",
"$IOS_SDK_PATH/System/Library/Frameworks/MetalFX.framework/Headers",
"$IOS_SDK_PATH/System/Library/Frameworks/QuartzCore.framework/Headers",
]
)
env.Prepend(CPPPATH=["#thirdparty/spirv-cross"])
if env["vulkan"] and env["ios_simulator"]:
print_warning("iOS simulator does not support the Vulkan rendering driver")
env["vulkan"] = False
if env["vulkan"]:
env.Append(CPPDEFINES=["VULKAN_ENABLED", "RD_ENABLED"])
env.AppendUnique(CPPDEFINES=["VULKAN_ENABLED", "RD_ENABLED"])
if env["opengl3"]:
env.Append(CPPDEFINES=["GLES3_ENABLED", "GLES_SILENCE_DEPRECATION"])
env.Append(CCFLAGS=["-Wno-module-import-in-extern-c"])
env.Prepend(
CPPPATH=[
"$IOS_SDK_PATH/System/Library/Frameworks/OpenGLES.framework/Headers",

View file

@ -41,12 +41,12 @@
#if defined(VULKAN_ENABLED)
#import "rendering_context_driver_vulkan_ios.h"
#ifdef USE_VOLK
#include <volk.h>
#else
#include <vulkan/vulkan.h>
#endif
#include "drivers/vulkan/godot_vulkan.h"
#endif // VULKAN_ENABLED
#if defined(METAL_ENABLED)
#include "drivers/metal/rendering_context_driver_metal.h"
#endif // METAL_ENABLED
#endif // RD_ENABLED
#if defined(GLES3_ENABLED)
@ -84,7 +84,7 @@ class DisplayServerIOS : public DisplayServer {
void perform_event(const Ref<InputEvent> &p_event);
DisplayServerIOS(const String &p_rendering_driver, DisplayServer::WindowMode p_mode, DisplayServer::VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, int p_screen, Context p_context, Error &r_error);
DisplayServerIOS(const String &p_rendering_driver, DisplayServer::WindowMode p_mode, DisplayServer::VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, int p_screen, Context p_context, int64_t p_parent_window, Error &r_error);
~DisplayServerIOS();
public:
@ -93,7 +93,7 @@ public:
static DisplayServerIOS *get_singleton();
static void register_ios_driver();
static DisplayServer *create_func(const String &p_rendering_driver, WindowMode p_mode, DisplayServer::VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, int p_screen, Context p_context, Error &r_error);
static DisplayServer *create_func(const String &p_rendering_driver, WindowMode p_mode, DisplayServer::VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, int p_screen, Context p_context, int64_t p_parent_window, Error &r_error);
static Vector<String> get_rendering_drivers_func();
// MARK: - Events
@ -224,6 +224,7 @@ public:
void virtual_keyboard_set_height(int height);
virtual int virtual_keyboard_get_height() const override;
virtual bool has_hardware_keyboard() const override;
virtual void clipboard_set(const String &p_text) override;
virtual String clipboard_get() const override;

View file

@ -45,13 +45,15 @@
#import <sys/utsname.h>
#import <GameController/GameController.h>
static const float kDisplayServerIOSAcceleration = 1.f;
DisplayServerIOS *DisplayServerIOS::get_singleton() {
return (DisplayServerIOS *)DisplayServer::get_singleton();
}
DisplayServerIOS::DisplayServerIOS(const String &p_rendering_driver, WindowMode p_mode, DisplayServer::VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, int p_screen, Context p_context, Error &r_error) {
DisplayServerIOS::DisplayServerIOS(const String &p_rendering_driver, WindowMode p_mode, DisplayServer::VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, int p_screen, Context p_context, int64_t p_parent_window, Error &r_error) {
KeyMappingIOS::initialize();
rendering_driver = p_rendering_driver;
@ -72,6 +74,13 @@ DisplayServerIOS::DisplayServerIOS(const String &p_rendering_driver, WindowMode
union {
#ifdef VULKAN_ENABLED
RenderingContextDriverVulkanIOS::WindowPlatformData vulkan;
#endif
#ifdef METAL_ENABLED
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunguarded-availability"
// Eliminate "RenderingContextDriverMetal is only available on iOS 14.0 or newer".
RenderingContextDriverMetal::WindowPlatformData metal;
#pragma clang diagnostic pop
#endif
} wpd;
@ -85,16 +94,41 @@ DisplayServerIOS::DisplayServerIOS(const String &p_rendering_driver, WindowMode
rendering_context = memnew(RenderingContextDriverVulkanIOS);
}
#endif
if (rendering_context) {
if (rendering_context->initialize() != OK) {
ERR_PRINT(vformat("Failed to initialize %s context", rendering_driver));
memdelete(rendering_context);
rendering_context = nullptr;
#ifdef METAL_ENABLED
if (rendering_driver == "metal") {
if (@available(iOS 14.0, *)) {
layer = [AppDelegate.viewController.godotView initializeRenderingForDriver:@"metal"];
wpd.metal.layer = (CAMetalLayer *)layer;
rendering_context = memnew(RenderingContextDriverMetal);
} else {
OS::get_singleton()->alert("Metal is only supported on iOS 14.0 and later.");
r_error = ERR_UNAVAILABLE;
return;
}
}
#endif
if (rendering_context) {
if (rendering_context->initialize() != OK) {
memdelete(rendering_context);
rendering_context = nullptr;
#if defined(GLES3_ENABLED)
bool fallback_to_opengl3 = GLOBAL_GET("rendering/rendering_device/fallback_to_opengl3");
if (fallback_to_opengl3 && rendering_driver != "opengl3") {
WARN_PRINT("Your device seem not to support MoltenVK or Metal, switching to OpenGL 3.");
rendering_driver = "opengl3";
OS::get_singleton()->set_current_rendering_method("gl_compatibility");
OS::get_singleton()->set_current_rendering_driver_name(rendering_driver);
} else
#endif
{
ERR_PRINT(vformat("Failed to initialize %s context", rendering_driver));
r_error = ERR_UNAVAILABLE;
return;
}
}
}
if (rendering_context) {
if (rendering_context->window_create(MAIN_WINDOW_ID, &wpd) != OK) {
ERR_PRINT(vformat("Failed to create %s window.", rendering_driver));
memdelete(rendering_context);
@ -162,8 +196,8 @@ DisplayServerIOS::~DisplayServerIOS() {
#endif
}
DisplayServer *DisplayServerIOS::create_func(const String &p_rendering_driver, WindowMode p_mode, DisplayServer::VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, int p_screen, Context p_context, Error &r_error) {
return memnew(DisplayServerIOS(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_position, p_resolution, p_screen, p_context, r_error));
DisplayServer *DisplayServerIOS::create_func(const String &p_rendering_driver, WindowMode p_mode, DisplayServer::VSyncMode p_vsync_mode, uint32_t p_flags, const Vector2i *p_position, const Vector2i &p_resolution, int p_screen, Context p_context, int64_t p_parent_window, Error &r_error) {
return memnew(DisplayServerIOS(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_position, p_resolution, p_screen, p_context, p_parent_window, r_error));
}
Vector<String> DisplayServerIOS::get_rendering_drivers_func() {
@ -172,6 +206,11 @@ Vector<String> DisplayServerIOS::get_rendering_drivers_func() {
#if defined(VULKAN_ENABLED)
drivers.push_back("vulkan");
#endif
#if defined(METAL_ENABLED)
if (@available(ios 14.0, *)) {
drivers.push_back("metal");
}
#endif
#if defined(GLES3_ENABLED)
drivers.push_back("opengl3");
#endif
@ -331,6 +370,8 @@ bool DisplayServerIOS::has_feature(Feature p_feature) const {
// case FEATURE_NATIVE_DIALOG:
// case FEATURE_NATIVE_DIALOG_INPUT:
// case FEATURE_NATIVE_DIALOG_FILE:
// case FEATURE_NATIVE_DIALOG_FILE_EXTRA:
// case FEATURE_NATIVE_DIALOG_FILE_MIME:
// case FEATURE_NATIVE_ICON:
// case FEATURE_WINDOW_TRANSPARENCY:
case FEATURE_CLIPBOARD:
@ -724,6 +765,14 @@ int DisplayServerIOS::virtual_keyboard_get_height() const {
return virtual_keyboard_height;
}
bool DisplayServerIOS::has_hardware_keyboard() const {
if (@available(iOS 14.0, *)) {
return [GCKeyboard coalescedKeyboard];
} else {
return false;
}
}
void DisplayServerIOS::clipboard_set(const String &p_text) {
[UIPasteboard generalPasteboard].string = [NSString stringWithUTF8String:p_text.utf8()];
}

View file

@ -41,15 +41,20 @@
<member name="application/export_project_only" type="bool" setter="" getter="">
If [code]true[/code], exports iOS project files without building an XCArchive or [code].ipa[/code] file. If [code]false[/code], exports iOS project files and builds an XCArchive and [code].ipa[/code] file at the same time. When combining Godot with Fastlane or other build pipelines, you may want to set this to [code]true[/code].
</member>
<member name="application/generate_simulator_library_if_missing" type="bool" setter="" getter="">
If [code]true[/code], and ARM64 simulator library is missing from the export template, it is automatically generated from ARM64 device library.
</member>
<member name="application/icon_interpolation" type="int" setter="" getter="">
Interpolation method used to resize application icon.
</member>
<member name="application/min_ios_version" type="String" setter="" getter="">
Minimum version of iOS required for this application to run in the [code]major.minor.patch[/code] or [code]major.minor[/code] format, can only contain numeric characters ([code]0-9[/code]) and periods ([code].[/code]).
</member>
<member name="application/provisioning_profile_specifier_debug" type="String" setter="" getter="">
Name of the provisioning profile. Sets XCode PROVISIONING_PROFILE_SPECIFIER for debug. [url=https://developer.apple.com/documentation/xcode/build-settings-reference#Provisioning-Profile]Used for manual provisioning[/url].
Can be overridden with the environment variable [code]GODOT_IOS_PROFILE_SPECIFIER_DEBUG[/code].
</member>
<member name="application/provisioning_profile_specifier_release" type="String" setter="" getter="">
Name of the provisioning profile. Sets XCode PROVISIONING_PROFILE_SPECIFIER for release. [url=https://developer.apple.com/documentation/xcode/build-settings-reference#Provisioning-Profile]Used for manual provisioning[/url].
Can be overridden with the environment variable [code]GODOT_IOS_PROFILE_SPECIFIER_RELEASE[/code].
</member>
<member name="application/provisioning_profile_uuid_debug" type="String" setter="" getter="">
UUID of the provisioning profile. If left empty, Xcode will download or create a provisioning profile automatically. See [url=https://developer.apple.com/help/account/manage-profiles/edit-download-or-delete-profiles]Edit, download, or delete provisioning profiles[/url].
Can be overridden with the environment variable [code]GODOT_IOS_PROVISIONING_PROFILE_UUID_DEBUG[/code].
@ -76,6 +81,9 @@
<member name="capabilities/access_wifi" type="bool" setter="" getter="">
If [code]true[/code], networking features related to Wi-Fi access are enabled. See [url=https://developer.apple.com/support/required-device-capabilities/]Required Device Capabilities[/url].
</member>
<member name="capabilities/additional" type="PackedStringArray" setter="" getter="">
Additional data added to the [code]UIRequiredDeviceCapabilities[/code] array of the [code]Info.plist[/code] file.
</member>
<member name="capabilities/performance_a12" type="bool" setter="" getter="">
Requires the graphics performance and features of the A12 Bionic and later chips (devices supporting all Vulkan renderer features).
Enabling this option limits supported devices to: iPhone XS, iPhone XR, iPad Mini (5th gen.), iPad Air (3rd gen.), iPad (8th gen) and newer.
@ -84,51 +92,181 @@
Requires the graphics performance and features of the A17 Pro and later chips.
Enabling this option limits supported devices to: iPhone 15 Pro and newer.
</member>
<member name="capabilities/push_notifications" type="bool" setter="" getter="">
If [code]true[/code], push notifications are enabled. See [url=https://developer.apple.com/support/required-device-capabilities/]Required Device Capabilities[/url].
</member>
<member name="custom_template/debug" type="String" setter="" getter="">
Path to the custom export template. If left empty, default template is used.
</member>
<member name="custom_template/release" type="String" setter="" getter="">
Path to the custom export template. If left empty, default template is used.
</member>
<member name="entitlements/additional" type="String" setter="" getter="">
Additional data added to the root [code]&lt;dict&gt;[/code] section of the [url=https://developer.apple.com/documentation/bundleresources/entitlements].entitlements[/url] file. The value should be an XML section with pairs of key-value elements, for example:
[codeblock lang=text]
&lt;key&gt;key_name&lt;/key&gt;
&lt;string&gt;value&lt;/string&gt;
[/codeblock]
</member>
<member name="entitlements/game_center" type="bool" setter="" getter="">
Enable to allow access to Game Center features. [url=https://developer.apple.com/documentation/bundleresources/entitlements/com_apple_developer_game-center]com.apple.developer.game-center[/url].
</member>
<member name="entitlements/increased_memory_limit" type="bool" setter="" getter="">
Enable if app may perform better with a higher memory limit. [url=https://developer.apple.com/documentation/bundleresources/entitlements/com_apple_developer_kernel_increased-memory-limit]com.apple.developer.kernel.increased-memory-limit[/url].
</member>
<member name="entitlements/push_notifications" type="String" setter="" getter="">
Environment for Apple Push Notification service. See [url=https://developer.apple.com/documentation/bundleresources/entitlements/aps-environment]aps-environment[/url].
</member>
<member name="icons/app_store_1024x1024" type="String" setter="" getter="">
App Store application icon file. If left empty, it will fallback to [member ProjectSettings.application/config/icon]. See [url=https://developer.apple.com/design/human-interface-guidelines/foundations/app-icons]App icons[/url].
</member>
<member name="icons/ipad_76x76" type="String" setter="" getter="">
Home screen application icon file on iPad (1x DPI). If left empty, it will fallback to [member ProjectSettings.application/config/icon]. See [url=https://developer.apple.com/design/human-interface-guidelines/foundations/app-icons]App icons[/url].
<member name="icons/app_store_1024x1024_dark" type="String" setter="" getter="">
App Store application icon file, dark version. See [url=https://developer.apple.com/design/human-interface-guidelines/foundations/app-icons]App icons[/url].
</member>
<member name="icons/app_store_1024x1024_tinted" type="String" setter="" getter="">
App Store application icon file, tinted version. See [url=https://developer.apple.com/design/human-interface-guidelines/foundations/app-icons]App icons[/url].
</member>
<member name="icons/icon_1024x1024" type="String" setter="" getter="">
Base application icon used to generate other icons. If left empty, it will fallback to [member ProjectSettings.application/config/icon]. See [url=https://developer.apple.com/design/human-interface-guidelines/foundations/app-icons]App icons[/url].
</member>
<member name="icons/icon_1024x1024_dark" type="String" setter="" getter="">
Base application icon used to generate other icons, dark version. See [url=https://developer.apple.com/design/human-interface-guidelines/foundations/app-icons]App icons[/url].
</member>
<member name="icons/icon_1024x1024_tinted" type="String" setter="" getter="">
Base application icon used to generate other icons, tinted version. See [url=https://developer.apple.com/design/human-interface-guidelines/foundations/app-icons]App icons[/url].
</member>
<member name="icons/ios_128x128" type="String" setter="" getter="">
iOS application 64x64 icon file (2x DPI). If left empty, it will fallback to [member ProjectSettings.application/config/icon]. See [url=https://developer.apple.com/design/human-interface-guidelines/foundations/app-icons]App icons[/url].
</member>
<member name="icons/ios_128x128_dark" type="String" setter="" getter="">
iOS application 64x64 icon file (2x DPI), dark version. See [url=https://developer.apple.com/design/human-interface-guidelines/foundations/app-icons]App icons[/url].
</member>
<member name="icons/ios_128x128_tinted" type="String" setter="" getter="">
iOS application 64x64 icon file (2x DPI), tinted version. See [url=https://developer.apple.com/design/human-interface-guidelines/foundations/app-icons]App icons[/url].
</member>
<member name="icons/ios_136x136" type="String" setter="" getter="">
iOS application 68x68 icon file (2x DPI). If left empty, it will fallback to [member ProjectSettings.application/config/icon]. See [url=https://developer.apple.com/design/human-interface-guidelines/foundations/app-icons]App icons[/url].
</member>
<member name="icons/ios_136x136_dark" type="String" setter="" getter="">
iOS application 68x68 icon file (2x DPI), dark version. See [url=https://developer.apple.com/design/human-interface-guidelines/foundations/app-icons]App icons[/url].
</member>
<member name="icons/ios_136x136_tinted" type="String" setter="" getter="">
iOS application 68x68 icon file (2x DPI), tinted version. See [url=https://developer.apple.com/design/human-interface-guidelines/foundations/app-icons]App icons[/url].
</member>
<member name="icons/ios_192x192" type="String" setter="" getter="">
iOS application 64x64 icon file (3x DPI). If left empty, it will fallback to [member ProjectSettings.application/config/icon]. See [url=https://developer.apple.com/design/human-interface-guidelines/foundations/app-icons]App icons[/url].
</member>
<member name="icons/ios_192x192_dark" type="String" setter="" getter="">
iOS application 64x64 icon file (3x DPI), dark version. See [url=https://developer.apple.com/design/human-interface-guidelines/foundations/app-icons]App icons[/url].
</member>
<member name="icons/ios_192x192_tinted" type="String" setter="" getter="">
iOS application 64x64 icon file (3x DPI), tinted version. See [url=https://developer.apple.com/design/human-interface-guidelines/foundations/app-icons]App icons[/url].
</member>
<member name="icons/ipad_152x152" type="String" setter="" getter="">
Home screen application icon file on iPad (2x DPI). If left empty, it will fallback to [member ProjectSettings.application/config/icon]. See [url=https://developer.apple.com/design/human-interface-guidelines/foundations/app-icons]App icons[/url].
</member>
<member name="icons/ipad_152x152_dark" type="String" setter="" getter="">
Home screen application icon file on iPad (2x DPI), dark version. See [url=https://developer.apple.com/design/human-interface-guidelines/foundations/app-icons]App icons[/url].
</member>
<member name="icons/ipad_152x152_tinted" type="String" setter="" getter="">
Home screen application icon file on iPad (2x DPI), tinted version. See [url=https://developer.apple.com/design/human-interface-guidelines/foundations/app-icons]App icons[/url].
</member>
<member name="icons/ipad_167x167" type="String" setter="" getter="">
Home screen application icon file on iPad (3x DPI). If left empty, it will fallback to [member ProjectSettings.application/config/icon]. See [url=https://developer.apple.com/design/human-interface-guidelines/foundations/app-icons]App icons[/url].
</member>
<member name="icons/ipad_167x167_dark" type="String" setter="" getter="">
Home screen application icon file on iPad (3x DPI), dark version. See [url=https://developer.apple.com/design/human-interface-guidelines/foundations/app-icons]App icons[/url].
</member>
<member name="icons/ipad_167x167_tinted" type="String" setter="" getter="">
Home screen application icon file on iPad (3x DPI), tinted version. See [url=https://developer.apple.com/design/human-interface-guidelines/foundations/app-icons]App icons[/url].
</member>
<member name="icons/iphone_120x120" type="String" setter="" getter="">
Home screen application icon file on iPhone (2x DPI). If left empty, it will fallback to [member ProjectSettings.application/config/icon]. See [url=https://developer.apple.com/design/human-interface-guidelines/foundations/app-icons]App icons[/url].
</member>
<member name="icons/iphone_120x120_dark" type="String" setter="" getter="">
Home screen application icon file on iPhone (2x DPI), dark version. See [url=https://developer.apple.com/design/human-interface-guidelines/foundations/app-icons]App icons[/url].
</member>
<member name="icons/iphone_120x120_tinted" type="String" setter="" getter="">
Home screen application icon file on iPhone (2x DPI), tinted version. See [url=https://developer.apple.com/design/human-interface-guidelines/foundations/app-icons]App icons[/url].
</member>
<member name="icons/iphone_180x180" type="String" setter="" getter="">
Home screen application icon file on iPhone (3x DPI). If left empty, it will fallback to [member ProjectSettings.application/config/icon]. See [url=https://developer.apple.com/design/human-interface-guidelines/foundations/app-icons]App icons[/url].
</member>
<member name="icons/iphone_180x180_dark" type="String" setter="" getter="">
Home screen application icon file on iPhone (3x DPI), dark version. See [url=https://developer.apple.com/design/human-interface-guidelines/foundations/app-icons]App icons[/url].
</member>
<member name="icons/iphone_180x180_tinted" type="String" setter="" getter="">
Home screen application icon file on iPhone (3x DPI), tinted version. See [url=https://developer.apple.com/design/human-interface-guidelines/foundations/app-icons]App icons[/url].
</member>
<member name="icons/notification_40x40" type="String" setter="" getter="">
Notification icon file on iPad and iPhone (2x DPI). If left empty, it will fallback to [member ProjectSettings.application/config/icon]. See [url=https://developer.apple.com/design/human-interface-guidelines/foundations/app-icons]App icons[/url].
</member>
<member name="icons/notification_40x40_dark" type="String" setter="" getter="">
Notification icon file on iPad and iPhone (2x DPI), dark version. See [url=https://developer.apple.com/design/human-interface-guidelines/foundations/app-icons]App icons[/url].
</member>
<member name="icons/notification_40x40_tinted" type="String" setter="" getter="">
Notification icon file on iPad and iPhone (2x DPI), tinted version. See [url=https://developer.apple.com/design/human-interface-guidelines/foundations/app-icons]App icons[/url].
</member>
<member name="icons/notification_60x60" type="String" setter="" getter="">
Notification icon file on iPhone (3x DPI). If left empty, it will fallback to [member ProjectSettings.application/config/icon]. See [url=https://developer.apple.com/design/human-interface-guidelines/foundations/app-icons]App icons[/url].
</member>
<member name="icons/notification_60x60_dark" type="String" setter="" getter="">
Notification icon file on iPhone (3x DPI), dark version. See [url=https://developer.apple.com/design/human-interface-guidelines/foundations/app-icons]App icons[/url].
</member>
<member name="icons/notification_60x60_tinted" type="String" setter="" getter="">
Notification icon file on iPhone (3x DPI), tinted version. See [url=https://developer.apple.com/design/human-interface-guidelines/foundations/app-icons]App icons[/url].
</member>
<member name="icons/notification_76x76" type="String" setter="" getter="">
Notification icon file on iPad and iPhone (2x DPI). If left empty, it will fallback to [member ProjectSettings.application/config/icon]. See [url=https://developer.apple.com/design/human-interface-guidelines/foundations/app-icons]App icons[/url].
</member>
<member name="icons/notification_76x76_dark" type="String" setter="" getter="">
Notification icon file on iPad and iPhone (2x DPI), dark version. See [url=https://developer.apple.com/design/human-interface-guidelines/foundations/app-icons]App icons[/url].
</member>
<member name="icons/notification_76x76_tinted" type="String" setter="" getter="">
Notification icon file on iPad and iPhone (2x DPI), tinted version. See [url=https://developer.apple.com/design/human-interface-guidelines/foundations/app-icons]App icons[/url].
</member>
<member name="icons/notification_114x114" type="String" setter="" getter="">
Notification icon file on iPad and iPhone (3x DPI). If left empty, it will fallback to [member ProjectSettings.application/config/icon]. See [url=https://developer.apple.com/design/human-interface-guidelines/foundations/app-icons]App icons[/url].
</member>
<member name="icons/notification_114x114_dark" type="String" setter="" getter="">
Notification icon file on iPad and iPhone (3x DPI), dark version. See [url=https://developer.apple.com/design/human-interface-guidelines/foundations/app-icons]App icons[/url].
</member>
<member name="icons/notification_114x114_tinted" type="String" setter="" getter="">
Notification icon file on iPad and iPhone (3x DPI), tinted version. See [url=https://developer.apple.com/design/human-interface-guidelines/foundations/app-icons]App icons[/url].
</member>
<member name="icons/settings_58x58" type="String" setter="" getter="">
Application settings icon file on iPad and iPhone (2x DPI). If left empty, it will fallback to [member ProjectSettings.application/config/icon]. See [url=https://developer.apple.com/design/human-interface-guidelines/foundations/app-icons]App icons[/url].
</member>
<member name="icons/settings_58x58_dark" type="String" setter="" getter="">
Application settings icon file on iPad and iPhone (2x DPI), dark version. See [url=https://developer.apple.com/design/human-interface-guidelines/foundations/app-icons]App icons[/url].
</member>
<member name="icons/settings_58x58_tinted" type="String" setter="" getter="">
Application settings icon file on iPad and iPhone (2x DPI), tinted version. See [url=https://developer.apple.com/design/human-interface-guidelines/foundations/app-icons]App icons[/url].
</member>
<member name="icons/settings_87x87" type="String" setter="" getter="">
Application settings icon file on iPhone (3x DPI). If left empty, it will fallback to [member ProjectSettings.application/config/icon]. See [url=https://developer.apple.com/design/human-interface-guidelines/foundations/app-icons]App icons[/url].
</member>
<member name="icons/spotlight_40x40" type="String" setter="" getter="">
Spotlight icon file on iPad (1x DPI). If left empty, it will fallback to [member ProjectSettings.application/config/icon]. See [url=https://developer.apple.com/design/human-interface-guidelines/foundations/app-icons]App icons[/url].
<member name="icons/settings_87x87_dark" type="String" setter="" getter="">
Application settings icon file on iPhone (3x DPI), dark version. See [url=https://developer.apple.com/design/human-interface-guidelines/foundations/app-icons]App icons[/url].
</member>
<member name="icons/settings_87x87_tinted" type="String" setter="" getter="">
Application settings icon file on iPhone (3x DPI), tinted version. See [url=https://developer.apple.com/design/human-interface-guidelines/foundations/app-icons]App icons[/url].
</member>
<member name="icons/spotlight_80x80" type="String" setter="" getter="">
Spotlight icon file on iPad and iPhone (2x DPI). If left empty, it will fallback to [member ProjectSettings.application/config/icon]. See [url=https://developer.apple.com/design/human-interface-guidelines/foundations/app-icons]App icons[/url].
</member>
<member name="icons/spotlight_80x80_dark" type="String" setter="" getter="">
Spotlight icon file on iPad and iPhone (2x DPI), dark version. See [url=https://developer.apple.com/design/human-interface-guidelines/foundations/app-icons]App icons[/url].
</member>
<member name="icons/spotlight_80x80_tinted" type="String" setter="" getter="">
Spotlight icon file on iPad and iPhone (2x DPI), tinted version. See [url=https://developer.apple.com/design/human-interface-guidelines/foundations/app-icons]App icons[/url].
</member>
<member name="icons/spotlight_120x120" type="String" setter="" getter="">
Spotlight icon file on iPad and iPhone (3x DPI). If left empty, it will fallback to [member ProjectSettings.application/config/icon]. See [url=https://developer.apple.com/design/human-interface-guidelines/foundations/app-icons]App icons[/url].
</member>
<member name="icons/spotlight_120x120_dark" type="String" setter="" getter="">
Spotlight icon file on iPad and iPhone (3x DPI), dark version. See [url=https://developer.apple.com/design/human-interface-guidelines/foundations/app-icons]App icons[/url].
</member>
<member name="icons/spotlight_120x120_tinted" type="String" setter="" getter="">
Spotlight icon file on iPad and iPhone (3x DPI), tinted version. See [url=https://developer.apple.com/design/human-interface-guidelines/foundations/app-icons]App icons[/url].
</member>
<member name="privacy/active_keyboard_access_reasons" type="int" setter="" getter="">
The reasons your app use active keyboard API. See [url=https://developer.apple.com/documentation/bundleresources/privacy_manifest_files/describing_use_of_required_reason_api]Describing use of required reason API[/url].
</member>

View file

@ -39,6 +39,7 @@ void register_ios_exporter_types() {
}
void register_ios_exporter() {
// TODO: Move to editor_settings.cpp
#ifdef MACOS_ENABLED
EDITOR_DEF("export/ios/ios_deploy", "");
EditorSettings::get_singleton()->add_property_hint(PropertyInfo(Variant::STRING, "export/ios/ios_deploy", PROPERTY_HINT_GLOBAL_FILE, "*"));

File diff suppressed because it is too large Load diff

View file

@ -54,6 +54,8 @@
// of these is set, they will override the values set in the credentials file.
const String ENV_IOS_PROFILE_UUID_DEBUG = "GODOT_IOS_PROVISIONING_PROFILE_UUID_DEBUG";
const String ENV_IOS_PROFILE_UUID_RELEASE = "GODOT_IOS_PROVISIONING_PROFILE_UUID_RELEASE";
const String ENV_IOS_PROFILE_SPECIFIER_DEBUG = "GODOT_IOS_PROFILE_SPECIFIER_DEBUG";
const String ENV_IOS_PROFILE_SPECIFIER_RELEASE = "GODOT_IOS_PROFILE_SPECIFIER_RELEASE";
class EditorExportPlatformIOS : public EditorExportPlatform {
GDCLASS(EditorExportPlatformIOS, EditorExportPlatform);
@ -68,7 +70,6 @@ class EditorExportPlatformIOS : public EditorExportPlatform {
struct Device {
String id;
String name;
bool simulator = false;
bool wifi = false;
bool use_ios_deploy = false;
};
@ -135,8 +136,6 @@ class EditorExportPlatformIOS : public EditorExportPlatform {
Vector<ExportArchitecture> _get_supported_architectures() const;
Vector<String> _get_preset_architectures(const Ref<EditorExportPreset> &p_preset) const;
bool _archive_has_arm64(const String &p_path, uint32_t *r_cputype = nullptr, uint32_t *r_cpusubtype = nullptr) const;
int _archive_convert_to_simulator(const String &p_path) const;
void _check_xcframework_content(const String &p_path, int &r_total_libs, int &r_static_libs, int &r_dylibs, int &r_frameworks) const;
Error _convert_to_framework(const String &p_source, const String &p_destination, const String &p_id) const;
@ -146,7 +145,7 @@ class EditorExportPlatformIOS : public EditorExportPlatform {
Error _export_additional_assets(const Ref<EditorExportPreset> &p_preset, const String &p_out_dir, const Vector<SharedObject> &p_libraries, Vector<IOSExportAsset> &r_exported_assets);
Error _export_ios_plugins(const Ref<EditorExportPreset> &p_preset, IOSConfigData &p_config_data, const String &dest_dir, Vector<IOSExportAsset> &r_exported_assets, bool p_debug);
Error _export_project_helper(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags, bool p_simulator, bool p_oneclick);
Error _export_project_helper(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, BitField<EditorExportPlatform::DebugFlags> p_flags, bool p_oneclick);
bool is_package_name_valid(const String &p_package, String *r_error = nullptr) const;
@ -169,7 +168,7 @@ public:
virtual Ref<ImageTexture> get_option_icon(int p_index) const override;
virtual String get_option_label(int p_index) const override;
virtual String get_option_tooltip(int p_index) const override;
virtual Error run(const Ref<EditorExportPreset> &p_preset, int p_device, int p_debug_flags) override;
virtual Error run(const Ref<EditorExportPreset> &p_preset, int p_device, BitField<EditorExportPlatform::DebugFlags> p_debug_flags) override;
virtual bool poll_export() override {
bool dc = devices_changed.is_set();
@ -202,7 +201,9 @@ public:
return list;
}
virtual Error export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags = 0) override;
virtual HashMap<String, Variant> get_custom_project_settings(const Ref<EditorExportPreset> &p_preset) const override;
virtual Error export_project(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, BitField<EditorExportPlatform::DebugFlags> p_flags = 0) override;
virtual bool has_valid_export_configuration(const Ref<EditorExportPreset> &p_preset, String &r_error, bool &r_missing_templates, bool p_debug = false) const override;
virtual bool has_valid_project_configuration(const Ref<EditorExportPreset> &p_preset, String &r_error) const override;

View file

@ -169,7 +169,7 @@ uint64_t PluginConfigIOS::get_plugin_modification_time(const PluginConfigIOS &pl
PluginConfigIOS PluginConfigIOS::load_plugin_config(Ref<ConfigFile> config_file, const String &path) {
PluginConfigIOS plugin_config = {};
if (!config_file.is_valid()) {
if (config_file.is_null()) {
return plugin_config;
}

View file

@ -32,7 +32,7 @@
typedef NSObject<UIApplicationDelegate> ApplicationDelegateService;
@interface GodotApplicalitionDelegate : NSObject <UIApplicationDelegate>
@interface GodotApplicationDelegate : NSObject <UIApplicationDelegate>
@property(class, readonly, strong) NSArray<ApplicationDelegateService *> *services;

View file

@ -32,11 +32,11 @@
#import "app_delegate.h"
@interface GodotApplicalitionDelegate ()
@interface GodotApplicationDelegate ()
@end
@implementation GodotApplicalitionDelegate
@implementation GodotApplicationDelegate
static NSMutableArray<ApplicationDelegateService *> *services = nil;

View file

@ -71,7 +71,7 @@ static const float earth_gravity = 9.80665;
CALayer<DisplayLayer> *layer;
if ([driverName isEqualToString:@"vulkan"]) {
if ([driverName isEqualToString:@"vulkan"] || [driverName isEqualToString:@"metal"]) {
#if defined(TARGET_OS_SIMULATOR) && TARGET_OS_SIMULATOR
if (@available(iOS 13, *)) {
layer = [GodotMetalLayer layer];
@ -441,6 +441,9 @@ static const float earth_gravity = 9.80665;
UIInterfaceOrientation interfaceOrientation = UIInterfaceOrientationUnknown;
#if __IPHONE_OS_VERSION_MAX_ALLOWED < 140000
interfaceOrientation = [[UIApplication sharedApplication] statusBarOrientation];
#else
if (@available(iOS 13, *)) {
interfaceOrientation = [UIApplication sharedApplication].delegate.window.windowScene.interfaceOrientation;
#if !defined(TARGET_OS_SIMULATOR) || !TARGET_OS_SIMULATOR
@ -448,6 +451,7 @@ static const float earth_gravity = 9.80665;
interfaceOrientation = [[UIApplication sharedApplication] statusBarOrientation];
#endif
}
#endif
switch (interfaceOrientation) {
case UIInterfaceOrientationLandscapeLeft: {

View file

@ -42,7 +42,7 @@ void iOS::_bind_methods() {
ClassDB::bind_method(D_METHOD("supports_haptic_engine"), &iOS::supports_haptic_engine);
ClassDB::bind_method(D_METHOD("start_haptic_engine"), &iOS::start_haptic_engine);
ClassDB::bind_method(D_METHOD("stop_haptic_engine"), &iOS::stop_haptic_engine);
};
}
bool iOS::supports_haptic_engine() {
if (@available(iOS 13, *)) {
@ -191,7 +191,7 @@ String iOS::get_model() const {
String iOS::get_rate_url(int p_app_id) const {
String app_url_path = "itms-apps://itunes.apple.com/app/idAPP_ID";
String ret = app_url_path.replace("APP_ID", String::num(p_app_id));
String ret = app_url_path.replace("APP_ID", String::num_int64(p_app_id));
print_verbose(vformat("Returning rate url %s", ret));
return ret;

View file

@ -1,50 +0,0 @@
/**************************************************************************/
/* joypad_ios.h */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#import <GameController/GameController.h>
@interface JoypadIOSObserver : NSObject
- (void)startObserving;
- (void)startProcessing;
- (void)finishObserving;
@end
class JoypadIOS {
private:
JoypadIOSObserver *observer;
public:
JoypadIOS();
~JoypadIOS();
void start_processing();
};

View file

@ -1,362 +0,0 @@
/**************************************************************************/
/* joypad_ios.mm */
/**************************************************************************/
/* This file is part of: */
/* GODOT ENGINE */
/* https://godotengine.org */
/**************************************************************************/
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
/* "Software"), to deal in the Software without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of the Software, and to */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions: */
/* */
/* The above copyright notice and this permission notice shall be */
/* included in all copies or substantial portions of the Software. */
/* */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/
#import "joypad_ios.h"
#import "godot_view.h"
#import "os_ios.h"
#include "core/config/project_settings.h"
#import "drivers/coreaudio/audio_driver_coreaudio.h"
#include "main/main.h"
JoypadIOS::JoypadIOS() {
observer = [[JoypadIOSObserver alloc] init];
[observer startObserving];
}
JoypadIOS::~JoypadIOS() {
if (observer) {
[observer finishObserving];
observer = nil;
}
}
void JoypadIOS::start_processing() {
if (observer) {
[observer startProcessing];
}
}
@interface JoypadIOSObserver ()
@property(assign, nonatomic) BOOL isObserving;
@property(assign, nonatomic) BOOL isProcessing;
@property(strong, nonatomic) NSMutableDictionary *connectedJoypads;
@property(strong, nonatomic) NSMutableArray *joypadsQueue;
@end
@implementation JoypadIOSObserver
- (instancetype)init {
self = [super init];
if (self) {
[self godot_commonInit];
}
return self;
}
- (void)godot_commonInit {
self.isObserving = NO;
self.isProcessing = NO;
}
- (void)startProcessing {
self.isProcessing = YES;
for (GCController *controller in self.joypadsQueue) {
[self addiOSJoypad:controller];
}
[self.joypadsQueue removeAllObjects];
}
- (void)startObserving {
if (self.isObserving) {
return;
}
self.isObserving = YES;
self.connectedJoypads = [NSMutableDictionary dictionary];
self.joypadsQueue = [NSMutableArray array];
// get told when controllers connect, this will be called right away for
// already connected controllers
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(controllerWasConnected:)
name:GCControllerDidConnectNotification
object:nil];
// get told when controllers disconnect
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(controllerWasDisconnected:)
name:GCControllerDidDisconnectNotification
object:nil];
}
- (void)finishObserving {
if (self.isObserving) {
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
self.isObserving = NO;
self.isProcessing = NO;
self.connectedJoypads = nil;
self.joypadsQueue = nil;
}
- (void)dealloc {
[self finishObserving];
}
- (int)getJoyIdForController:(GCController *)controller {
NSArray *keys = [self.connectedJoypads allKeysForObject:controller];
for (NSNumber *key in keys) {
int joy_id = [key intValue];
return joy_id;
}
return -1;
}
- (void)addiOSJoypad:(GCController *)controller {
// get a new id for our controller
int joy_id = Input::get_singleton()->get_unused_joy_id();
if (joy_id == -1) {
print_verbose("Couldn't retrieve new joy ID.");
return;
}
// assign our player index
if (controller.playerIndex == GCControllerPlayerIndexUnset) {
controller.playerIndex = [self getFreePlayerIndex];
}
// tell Godot about our new controller
Input::get_singleton()->joy_connection_changed(joy_id, true, String::utf8([controller.vendorName UTF8String]));
// add it to our dictionary, this will retain our controllers
[self.connectedJoypads setObject:controller forKey:[NSNumber numberWithInt:joy_id]];
// set our input handler
[self setControllerInputHandler:controller];
}
- (void)controllerWasConnected:(NSNotification *)notification {
// get our controller
GCController *controller = (GCController *)notification.object;
if (!controller) {
print_verbose("Couldn't retrieve new controller.");
return;
}
if ([[self.connectedJoypads allKeysForObject:controller] count] > 0) {
print_verbose("Controller is already registered.");
} else if (!self.isProcessing) {
[self.joypadsQueue addObject:controller];
} else {
[self addiOSJoypad:controller];
}
}
- (void)controllerWasDisconnected:(NSNotification *)notification {
// find our joystick, there should be only one in our dictionary
GCController *controller = (GCController *)notification.object;
if (!controller) {
return;
}
NSArray *keys = [self.connectedJoypads allKeysForObject:controller];
for (NSNumber *key in keys) {
// tell Godot this joystick is no longer there
int joy_id = [key intValue];
Input::get_singleton()->joy_connection_changed(joy_id, false, "");
// and remove it from our dictionary
[self.connectedJoypads removeObjectForKey:key];
}
}
- (GCControllerPlayerIndex)getFreePlayerIndex {
bool have_player_1 = false;
bool have_player_2 = false;
bool have_player_3 = false;
bool have_player_4 = false;
if (self.connectedJoypads == nil) {
NSArray *keys = [self.connectedJoypads allKeys];
for (NSNumber *key in keys) {
GCController *controller = [self.connectedJoypads objectForKey:key];
if (controller.playerIndex == GCControllerPlayerIndex1) {
have_player_1 = true;
} else if (controller.playerIndex == GCControllerPlayerIndex2) {
have_player_2 = true;
} else if (controller.playerIndex == GCControllerPlayerIndex3) {
have_player_3 = true;
} else if (controller.playerIndex == GCControllerPlayerIndex4) {
have_player_4 = true;
}
}
}
if (!have_player_1) {
return GCControllerPlayerIndex1;
} else if (!have_player_2) {
return GCControllerPlayerIndex2;
} else if (!have_player_3) {
return GCControllerPlayerIndex3;
} else if (!have_player_4) {
return GCControllerPlayerIndex4;
} else {
return GCControllerPlayerIndexUnset;
}
}
- (void)setControllerInputHandler:(GCController *)controller {
// Hook in the callback handler for the correct gamepad profile.
// This is a bit of a weird design choice on Apples part.
// You need to select the most capable gamepad profile for the
// gamepad attached.
if (controller.extendedGamepad != nil) {
// The extended gamepad profile has all the input you could possibly find on
// a gamepad but will only be active if your gamepad actually has all of
// these...
_weakify(self);
_weakify(controller);
controller.extendedGamepad.valueChangedHandler = ^(GCExtendedGamepad *gamepad, GCControllerElement *element) {
_strongify(self);
_strongify(controller);
int joy_id = [self getJoyIdForController:controller];
if (element == gamepad.buttonA) {
Input::get_singleton()->joy_button(joy_id, JoyButton::A,
gamepad.buttonA.isPressed);
} else if (element == gamepad.buttonB) {
Input::get_singleton()->joy_button(joy_id, JoyButton::B,
gamepad.buttonB.isPressed);
} else if (element == gamepad.buttonX) {
Input::get_singleton()->joy_button(joy_id, JoyButton::X,
gamepad.buttonX.isPressed);
} else if (element == gamepad.buttonY) {
Input::get_singleton()->joy_button(joy_id, JoyButton::Y,
gamepad.buttonY.isPressed);
} else if (element == gamepad.leftShoulder) {
Input::get_singleton()->joy_button(joy_id, JoyButton::LEFT_SHOULDER,
gamepad.leftShoulder.isPressed);
} else if (element == gamepad.rightShoulder) {
Input::get_singleton()->joy_button(joy_id, JoyButton::RIGHT_SHOULDER,
gamepad.rightShoulder.isPressed);
} else if (element == gamepad.dpad) {
Input::get_singleton()->joy_button(joy_id, JoyButton::DPAD_UP,
gamepad.dpad.up.isPressed);
Input::get_singleton()->joy_button(joy_id, JoyButton::DPAD_DOWN,
gamepad.dpad.down.isPressed);
Input::get_singleton()->joy_button(joy_id, JoyButton::DPAD_LEFT,
gamepad.dpad.left.isPressed);
Input::get_singleton()->joy_button(joy_id, JoyButton::DPAD_RIGHT,
gamepad.dpad.right.isPressed);
}
if (element == gamepad.leftThumbstick) {
float value = gamepad.leftThumbstick.xAxis.value;
Input::get_singleton()->joy_axis(joy_id, JoyAxis::LEFT_X, value);
value = -gamepad.leftThumbstick.yAxis.value;
Input::get_singleton()->joy_axis(joy_id, JoyAxis::LEFT_Y, value);
} else if (element == gamepad.rightThumbstick) {
float value = gamepad.rightThumbstick.xAxis.value;
Input::get_singleton()->joy_axis(joy_id, JoyAxis::RIGHT_X, value);
value = -gamepad.rightThumbstick.yAxis.value;
Input::get_singleton()->joy_axis(joy_id, JoyAxis::RIGHT_Y, value);
} else if (element == gamepad.leftTrigger) {
float value = gamepad.leftTrigger.value;
Input::get_singleton()->joy_axis(joy_id, JoyAxis::TRIGGER_LEFT, value);
} else if (element == gamepad.rightTrigger) {
float value = gamepad.rightTrigger.value;
Input::get_singleton()->joy_axis(joy_id, JoyAxis::TRIGGER_RIGHT, value);
}
if (@available(iOS 13, *)) {
// iOS uses 'buttonOptions' and 'buttonMenu' names for BACK and START joy buttons.
if (element == gamepad.buttonOptions) {
Input::get_singleton()->joy_button(joy_id, JoyButton::BACK,
gamepad.buttonOptions.isPressed);
} else if (element == gamepad.buttonMenu) {
Input::get_singleton()->joy_button(joy_id, JoyButton::START,
gamepad.buttonMenu.isPressed);
}
}
if (@available(iOS 14, *)) {
// iOS uses 'buttonHome' for the GUIDE joy button.
if (element == gamepad.buttonHome) {
Input::get_singleton()->joy_button(joy_id, JoyButton::GUIDE,
gamepad.buttonHome.isPressed);
}
}
};
} else if (controller.microGamepad != nil) {
// micro gamepads were added in OS 9 and feature just 2 buttons and a d-pad
_weakify(self);
_weakify(controller);
controller.microGamepad.valueChangedHandler = ^(GCMicroGamepad *gamepad, GCControllerElement *element) {
_strongify(self);
_strongify(controller);
int joy_id = [self getJoyIdForController:controller];
if (element == gamepad.buttonA) {
Input::get_singleton()->joy_button(joy_id, JoyButton::A,
gamepad.buttonA.isPressed);
} else if (element == gamepad.buttonX) {
Input::get_singleton()->joy_button(joy_id, JoyButton::X,
gamepad.buttonX.isPressed);
} else if (element == gamepad.dpad) {
Input::get_singleton()->joy_button(joy_id, JoyButton::DPAD_UP,
gamepad.dpad.up.isPressed);
Input::get_singleton()->joy_button(joy_id, JoyButton::DPAD_DOWN,
gamepad.dpad.down.isPressed);
Input::get_singleton()->joy_button(joy_id, JoyButton::DPAD_LEFT, gamepad.dpad.left.isPressed);
Input::get_singleton()->joy_button(joy_id, JoyButton::DPAD_RIGHT, gamepad.dpad.right.isPressed);
}
};
}
///@TODO need to add support for controller.motion which gives us access to
/// the orientation of the device (if supported)
///@TODO need to add support for controllerPausedHandler which should be a
/// toggle
}
@end

View file

@ -184,7 +184,7 @@
NSInteger skip = 0;
if (substringToDelete != nil) {
for (NSInteger i = 0; i < MIN([substringToDelete length], [substringToEnter length]); i++) {
for (NSUInteger i = 0; i < MIN([substringToDelete length], [substringToEnter length]); i++) {
if ([substringToDelete characterAtIndex:i] == [substringToEnter characterAtIndex:i]) {
skip++;
} else {

View file

@ -46,7 +46,7 @@ int main(int argc, char *argv[]) {
gargv = argv;
@autoreleasepool {
NSString *className = NSStringFromClass([GodotApplicalitionDelegate class]);
NSString *className = NSStringFromClass([GodotApplicationDelegate class]);
UIApplicationMain(argc, argv, nil, className);
}
return 0;

View file

@ -34,8 +34,8 @@
#ifdef IOS_ENABLED
#import "ios.h"
#import "joypad_ios.h"
#import "drivers/apple/joypad_apple.h"
#import "drivers/coreaudio/audio_driver_coreaudio.h"
#include "drivers/unix/os_unix.h"
#include "servers/audio_server.h"
@ -58,15 +58,14 @@ private:
iOS *ios = nullptr;
JoypadIOS *joypad_ios = nullptr;
JoypadApple *joypad_apple = nullptr;
MainLoop *main_loop = nullptr;
virtual void initialize_core() override;
virtual void initialize() override;
virtual void initialize_joypads() override {
}
virtual void initialize_joypads() override;
virtual void set_main_loop(MainLoop *p_main_loop) override;
virtual MainLoop *get_main_loop() const override;
@ -114,9 +113,10 @@ public:
virtual Error shell_open(const String &p_uri) override;
virtual String get_user_data_dir() const override;
virtual String get_user_data_dir(const String &p_user_dir) const override;
virtual String get_cache_path() const override;
virtual String get_temp_path() const override;
virtual String get_locale() const override;
@ -132,6 +132,8 @@ public:
void on_enter_background();
void on_exit_background();
virtual Rect2 calculate_boot_screen_rect(const Size2 &p_window_size, const Size2 &p_imgrect_size) const override;
};
#endif // IOS_ENABLED

View file

@ -56,11 +56,7 @@
#import <QuartzCore/CAMetalLayer.h>
#if defined(VULKAN_ENABLED)
#ifdef USE_VOLK
#include <volk.h>
#else
#include <vulkan/vulkan.h>
#endif
#include "drivers/vulkan/godot_vulkan.h"
#endif // VULKAN_ENABLED
#endif
@ -90,6 +86,46 @@ void register_dynamic_symbol(char *name, void *address) {
OS_IOS::dynamic_symbol_lookup_table[String(name)] = address;
}
Rect2 fit_keep_aspect_centered(const Vector2 &p_container, const Vector2 &p_rect) {
real_t available_ratio = p_container.width / p_container.height;
real_t fit_ratio = p_rect.width / p_rect.height;
Rect2 result;
if (fit_ratio < available_ratio) {
// Fit height - we'll have horizontal gaps
result.size.height = p_container.height;
result.size.width = p_container.height * fit_ratio;
result.position.y = 0;
result.position.x = (p_container.width - result.size.width) * 0.5f;
} else {
// Fit width - we'll have vertical gaps
result.size.width = p_container.width;
result.size.height = p_container.width / fit_ratio;
result.position.x = 0;
result.position.y = (p_container.height - result.size.height) * 0.5f;
}
return result;
}
Rect2 fit_keep_aspect_covered(const Vector2 &p_container, const Vector2 &p_rect) {
real_t available_ratio = p_container.width / p_container.height;
real_t fit_ratio = p_rect.width / p_rect.height;
Rect2 result;
if (fit_ratio < available_ratio) {
// Need to scale up to fit width, and crop height
result.size.width = p_container.width;
result.size.height = p_container.width / fit_ratio;
result.position.x = 0;
result.position.y = (p_container.height - result.size.height) * 0.5f;
} else {
// Need to scale up to fit height, and crop width
result.size.width = p_container.height * fit_ratio;
result.size.height = p_container.height;
result.position.x = (p_container.width - result.size.width) * 0.5f;
result.position.y = 0;
}
return result;
}
OS_IOS *OS_IOS::get_singleton() {
return (OS_IOS *)OS::get_singleton();
}
@ -130,16 +166,18 @@ void OS_IOS::initialize() {
initialize_core();
}
void OS_IOS::initialize_joypads() {
joypad_apple = memnew(JoypadApple);
}
void OS_IOS::initialize_modules() {
ios = memnew(iOS);
Engine::get_singleton()->add_singleton(Engine::Singleton("iOS", ios));
joypad_ios = memnew(JoypadIOS);
}
void OS_IOS::deinitialize_modules() {
if (joypad_ios) {
memdelete(joypad_ios);
if (joypad_apple) {
memdelete(joypad_apple);
}
if (ios) {
@ -173,6 +211,8 @@ bool OS_IOS::iterate() {
DisplayServer::get_singleton()->process_events();
}
joypad_apple->process_joypads();
return Main::iteration();
}
@ -180,10 +220,6 @@ void OS_IOS::start() {
if (Main::start() == EXIT_SUCCESS) {
main_loop->initialize();
}
if (joypad_ios) {
joypad_ios->start_processing();
}
}
void OS_IOS::finalize() {
@ -318,7 +354,7 @@ Error OS_IOS::shell_open(const String &p_uri) {
return OK;
}
String OS_IOS::get_user_data_dir() const {
String OS_IOS::get_user_data_dir(const String &p_user_dir) const {
static String ret;
if (ret.is_empty()) {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
@ -340,11 +376,24 @@ String OS_IOS::get_cache_path() const {
return ret;
}
String OS_IOS::get_locale() const {
NSString *preferedLanguage = [NSLocale preferredLanguages].firstObject;
String OS_IOS::get_temp_path() const {
static String ret;
if (ret.is_empty()) {
NSURL *url = [NSURL fileURLWithPath:NSTemporaryDirectory()
isDirectory:YES];
if (url) {
ret = String::utf8([url.path UTF8String]);
ret = ret.trim_prefix("file://");
}
}
return ret;
}
if (preferedLanguage) {
return String::utf8([preferedLanguage UTF8String]).replace("-", "_");
String OS_IOS::get_locale() const {
NSString *preferredLanguage = [NSLocale preferredLanguages].firstObject;
if (preferredLanguage) {
return String::utf8([preferredLanguage UTF8String]).replace("-", "_");
}
NSString *localeIdentifier = [[NSLocale currentLocale] localeIdentifier];
@ -651,4 +700,21 @@ void OS_IOS::on_exit_background() {
}
}
Rect2 OS_IOS::calculate_boot_screen_rect(const Size2 &p_window_size, const Size2 &p_imgrect_size) const {
String scalemodestr = GLOBAL_GET("ios/launch_screen_image_mode");
if (scalemodestr == "scaleAspectFit") {
return fit_keep_aspect_centered(p_window_size, p_imgrect_size);
} else if (scalemodestr == "scaleAspectFill") {
return fit_keep_aspect_covered(p_window_size, p_imgrect_size);
} else if (scalemodestr == "scaleToFill") {
return Rect2(Point2(), p_window_size);
} else if (scalemodestr == "center") {
return OS_Unix::calculate_boot_screen_rect(p_window_size, p_imgrect_size);
} else {
WARN_PRINT(vformat("Boot screen scale mode mismatch between iOS and Godot: %s not supported", scalemodestr));
return OS_Unix::calculate_boot_screen_rect(p_window_size, p_imgrect_size);
}
}
#endif // IOS_ENABLED

View file

@ -50,7 +50,7 @@ RenderingContextDriver::SurfaceID RenderingContextDriverVulkanIOS::surface_creat
create_info.pLayer = *wpd->layer_ptr;
VkSurfaceKHR vk_surface = VK_NULL_HANDLE;
VkResult err = vkCreateMetalSurfaceEXT(instance_get(), &create_info, nullptr, &vk_surface);
VkResult err = vkCreateMetalSurfaceEXT(instance_get(), &create_info, get_allocation_callbacks(VK_OBJECT_TYPE_SURFACE_KHR), &vk_surface);
ERR_FAIL_COND_V(err != VK_SUCCESS, SurfaceID());
Surface *surface = memnew(Surface);