You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-11-10 13:00:37 +00:00
Merge pull request #105628 from rsanchezsaez/apple/ios-visionos-4.5
Native visionOS platform support
This commit is contained in:
@@ -647,7 +647,11 @@ if env["scu_build"]:
|
|||||||
# are actually handled to change compile options, etc.
|
# are actually handled to change compile options, etc.
|
||||||
detect.configure(env)
|
detect.configure(env)
|
||||||
|
|
||||||
print(f'Building for platform "{env["platform"]}", architecture "{env["arch"]}", target "{env["target"]}".')
|
platform_string = env["platform"]
|
||||||
|
if env.get("simulator"):
|
||||||
|
platform_string += " (simulator)"
|
||||||
|
print(f'Building for platform "{platform_string}", architecture "{env["arch"]}", target "{env["target"]}".')
|
||||||
|
|
||||||
if env.dev_build:
|
if env.dev_build:
|
||||||
print_info("Developer build, with debug optimization level and debug symbols (unless overridden).")
|
print_info("Developer build, with debug optimization level and debug symbols (unless overridden).")
|
||||||
|
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ def make_default_controller_mappings(target, source, env):
|
|||||||
"Windows": "WINDOWS",
|
"Windows": "WINDOWS",
|
||||||
"Mac OS X": "MACOS",
|
"Mac OS X": "MACOS",
|
||||||
"Android": "ANDROID",
|
"Android": "ANDROID",
|
||||||
"iOS": "IOS",
|
"iOS": "APPLE_EMBEDDED",
|
||||||
"Web": "WEB",
|
"Web": "WEB",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -585,7 +585,7 @@ bool OS::has_feature(const String &p_feature) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(IOS_SIMULATOR)
|
#if defined(IOS_SIMULATOR) || defined(VISIONOS_SIMULATOR)
|
||||||
if (p_feature == "simulator") {
|
if (p_feature == "simulator") {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
13
doc/classes/EditorExportPlatformAppleEmbedded.xml
Normal file
13
doc/classes/EditorExportPlatformAppleEmbedded.xml
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
<class name="EditorExportPlatformAppleEmbedded" inherits="EditorExportPlatform" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
|
||||||
|
<brief_description>
|
||||||
|
Base class for the Apple embedded platform exporters (iOS and visionOS).
|
||||||
|
</brief_description>
|
||||||
|
<description>
|
||||||
|
The base class for Apple embedded platform exporters. These include iOS and visionOS, but not macOS. See the classes inheriting from this one for more details.
|
||||||
|
</description>
|
||||||
|
<tutorials>
|
||||||
|
<link title="Exporting for iOS">$DOCS_URL/tutorials/export/exporting_for_ios.html</link>
|
||||||
|
<link title="iOS plugins documentation index">$DOCS_URL/tutorials/platform/ios/index.html</link>
|
||||||
|
</tutorials>
|
||||||
|
</class>
|
||||||
@@ -4,7 +4,7 @@
|
|||||||
Base class for the desktop platform exporter (Windows and Linux/BSD).
|
Base class for the desktop platform exporter (Windows and Linux/BSD).
|
||||||
</brief_description>
|
</brief_description>
|
||||||
<description>
|
<description>
|
||||||
The base class for the desktop platform exporters. These include Windows and Linux/BSD, but not macOS. See the classes inheriting this one for more details.
|
The base class for the desktop platform exporters. These include Windows and Linux/BSD, but not macOS. See the classes inheriting from this one for more details.
|
||||||
</description>
|
</description>
|
||||||
<tutorials>
|
<tutorials>
|
||||||
<link title="Exporting for Windows">$DOCS_URL/tutorials/export/exporting_for_windows.html</link>
|
<link title="Exporting for Windows">$DOCS_URL/tutorials/export/exporting_for_windows.html</link>
|
||||||
|
|||||||
@@ -251,6 +251,57 @@
|
|||||||
If no modifications are needed, then an empty [PackedByteArray] should be returned.
|
If no modifications are needed, then an empty [PackedByteArray] should be returned.
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
|
<method name="add_apple_embedded_platform_bundle_file">
|
||||||
|
<return type="void" />
|
||||||
|
<param index="0" name="path" type="String" />
|
||||||
|
<description>
|
||||||
|
Adds an Apple embedded platform bundle file from the given [param path] to the exported project.
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
|
<method name="add_apple_embedded_platform_cpp_code">
|
||||||
|
<return type="void" />
|
||||||
|
<param index="0" name="code" type="String" />
|
||||||
|
<description>
|
||||||
|
Adds C++ code to the Apple embedded platform export. The final code is created from the code appended by each active export plugin.
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
|
<method name="add_apple_embedded_platform_embedded_framework">
|
||||||
|
<return type="void" />
|
||||||
|
<param index="0" name="path" type="String" />
|
||||||
|
<description>
|
||||||
|
Adds a dynamic library (*.dylib, *.framework) to the Linking Phase in the Apple embedded platform's Xcode project and embeds it into the resulting binary.
|
||||||
|
[b]Note:[/b] For static libraries (*.a), this works in the same way as [method add_apple_embedded_platform_framework].
|
||||||
|
[b]Note:[/b] This method should not be used for System libraries as they are already present on the device.
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
|
<method name="add_apple_embedded_platform_framework">
|
||||||
|
<return type="void" />
|
||||||
|
<param index="0" name="path" type="String" />
|
||||||
|
<description>
|
||||||
|
Adds a static library (*.a) or a dynamic library (*.dylib, *.framework) to the Linking Phase to the Apple embedded platform's Xcode project.
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
|
<method name="add_apple_embedded_platform_linker_flags">
|
||||||
|
<return type="void" />
|
||||||
|
<param index="0" name="flags" type="String" />
|
||||||
|
<description>
|
||||||
|
Adds linker flags for the Apple embedded platform export.
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
|
<method name="add_apple_embedded_platform_plist_content">
|
||||||
|
<return type="void" />
|
||||||
|
<param index="0" name="plist_content" type="String" />
|
||||||
|
<description>
|
||||||
|
Adds additional fields to the Apple embedded platform's project Info.plist file.
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
|
<method name="add_apple_embedded_platform_project_static_lib">
|
||||||
|
<return type="void" />
|
||||||
|
<param index="0" name="path" type="String" />
|
||||||
|
<description>
|
||||||
|
Adds a static library from the given [param path] to the Apple embedded platform project.
|
||||||
|
</description>
|
||||||
|
</method>
|
||||||
<method name="add_file">
|
<method name="add_file">
|
||||||
<return type="void" />
|
<return type="void" />
|
||||||
<param index="0" name="path" type="String" />
|
<param index="0" name="path" type="String" />
|
||||||
@@ -262,55 +313,55 @@
|
|||||||
[param file] will not be imported, so consider using [method _customize_resource] to remap imported resources.
|
[param file] will not be imported, so consider using [method _customize_resource] to remap imported resources.
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="add_ios_bundle_file">
|
<method name="add_ios_bundle_file" deprecated="Use [method add_apple_embedded_platform_bundle_file] instead.">
|
||||||
<return type="void" />
|
<return type="void" />
|
||||||
<param index="0" name="path" type="String" />
|
<param index="0" name="path" type="String" />
|
||||||
<description>
|
<description>
|
||||||
Adds an iOS bundle file from the given [param path] to the exported project.
|
Adds an iOS bundle file from the given [param path] to the exported project.
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="add_ios_cpp_code">
|
<method name="add_ios_cpp_code" deprecated="Use [method add_apple_embedded_platform_cpp_code] instead.">
|
||||||
<return type="void" />
|
<return type="void" />
|
||||||
<param index="0" name="code" type="String" />
|
<param index="0" name="code" type="String" />
|
||||||
<description>
|
<description>
|
||||||
Adds a C++ code to the iOS export. The final code is created from the code appended by each active export plugin.
|
Adds C++ code to the iOS export. The final code is created from the code appended by each active export plugin.
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="add_ios_embedded_framework">
|
<method name="add_ios_embedded_framework" deprecated="Use [method add_apple_embedded_platform_embedded_framework] instead.">
|
||||||
<return type="void" />
|
<return type="void" />
|
||||||
<param index="0" name="path" type="String" />
|
<param index="0" name="path" type="String" />
|
||||||
<description>
|
<description>
|
||||||
Adds a dynamic library (*.dylib, *.framework) to Linking Phase in iOS's Xcode project and embeds it into resulting binary.
|
Adds a dynamic library (*.dylib, *.framework) to Linking Phase in iOS's Xcode project and embeds it into resulting binary.
|
||||||
[b]Note:[/b] For static libraries (*.a) works in same way as [method add_ios_framework].
|
[b]Note:[/b] For static libraries (*.a), this works the in same way as [method add_apple_embedded_platform_framework].
|
||||||
[b]Note:[/b] This method should not be used for System libraries as they are already present on the device.
|
[b]Note:[/b] This method should not be used for System libraries as they are already present on the device.
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="add_ios_framework">
|
<method name="add_ios_framework" deprecated="Use [method add_apple_embedded_platform_framework] instead.">
|
||||||
<return type="void" />
|
<return type="void" />
|
||||||
<param index="0" name="path" type="String" />
|
<param index="0" name="path" type="String" />
|
||||||
<description>
|
<description>
|
||||||
Adds a static library (*.a) or dynamic library (*.dylib, *.framework) to Linking Phase in iOS's Xcode project.
|
Adds a static library (*.a) or a dynamic library (*.dylib, *.framework) to the Linking Phase to the iOS Xcode project.
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="add_ios_linker_flags">
|
<method name="add_ios_linker_flags" deprecated="Use [method add_apple_embedded_platform_linker_flags] instead.">
|
||||||
<return type="void" />
|
<return type="void" />
|
||||||
<param index="0" name="flags" type="String" />
|
<param index="0" name="flags" type="String" />
|
||||||
<description>
|
<description>
|
||||||
Adds linker flags for the iOS export.
|
Adds linker flags for the iOS export.
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="add_ios_plist_content">
|
<method name="add_ios_plist_content" deprecated="Use [method add_apple_embedded_platform_plist_content] instead.">
|
||||||
<return type="void" />
|
<return type="void" />
|
||||||
<param index="0" name="plist_content" type="String" />
|
<param index="0" name="plist_content" type="String" />
|
||||||
<description>
|
<description>
|
||||||
Adds content for iOS Property List files.
|
Adds additional fields to the iOS project Info.plist file.
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="add_ios_project_static_lib">
|
<method name="add_ios_project_static_lib" deprecated="Use [method add_apple_embedded_platform_project_static_lib] instead.">
|
||||||
<return type="void" />
|
<return type="void" />
|
||||||
<param index="0" name="path" type="String" />
|
<param index="0" name="path" type="String" />
|
||||||
<description>
|
<description>
|
||||||
Adds a static lib from the given [param path] to the iOS project.
|
Adds a static library from the given [param path] to the iOS project.
|
||||||
</description>
|
</description>
|
||||||
</method>
|
</method>
|
||||||
<method name="add_macos_plugin_file">
|
<method name="add_macos_plugin_file">
|
||||||
|
|||||||
@@ -900,6 +900,9 @@
|
|||||||
<member name="display/display_server/driver.macos" type="String" setter="" getter="">
|
<member name="display/display_server/driver.macos" type="String" setter="" getter="">
|
||||||
MacOS override for [member display/display_server/driver].
|
MacOS override for [member display/display_server/driver].
|
||||||
</member>
|
</member>
|
||||||
|
<member name="display/display_server/driver.visionos" type="String" setter="" getter="">
|
||||||
|
visionOS override for [member display/display_server/driver].
|
||||||
|
</member>
|
||||||
<member name="display/display_server/driver.windows" type="String" setter="" getter="">
|
<member name="display/display_server/driver.windows" type="String" setter="" getter="">
|
||||||
Windows override for [member display/display_server/driver].
|
Windows override for [member display/display_server/driver].
|
||||||
</member>
|
</member>
|
||||||
@@ -3163,6 +3166,11 @@
|
|||||||
- [code]metal[/code] (default), Metal from native drivers, only supported on Apple Silicon Macs. On Intel Macs, it will automatically fall back to [code]vulkan[/code] as Metal support is not implemented.
|
- [code]metal[/code] (default), Metal from native drivers, only supported on Apple Silicon Macs. On Intel Macs, it will automatically fall back to [code]vulkan[/code] as Metal support is not implemented.
|
||||||
- [code]vulkan[/code], Vulkan over Metal via MoltenVK, supported on both Apple Silicon and Intel Macs.
|
- [code]vulkan[/code], Vulkan over Metal via MoltenVK, supported on both Apple Silicon and Intel Macs.
|
||||||
</member>
|
</member>
|
||||||
|
<member name="rendering/rendering_device/driver.visionos" type="String" setter="" getter="" default=""metal"">
|
||||||
|
visionOS override for [member rendering/rendering_device/driver].
|
||||||
|
Only one option is supported:
|
||||||
|
- [code]metal[/code] (default), Metal from native drivers.
|
||||||
|
</member>
|
||||||
<member name="rendering/rendering_device/driver.windows" type="String" setter="" getter="" default=""vulkan"">
|
<member name="rendering/rendering_device/driver.windows" type="String" setter="" getter="" default=""vulkan"">
|
||||||
Windows override for [member rendering/rendering_device/driver].
|
Windows override for [member rendering/rendering_device/driver].
|
||||||
Two options are supported:
|
Two options are supported:
|
||||||
|
|||||||
@@ -14,8 +14,6 @@ SConscript("windows/SCsub")
|
|||||||
|
|
||||||
# Sounds drivers
|
# Sounds drivers
|
||||||
SConscript("alsa/SCsub")
|
SConscript("alsa/SCsub")
|
||||||
if env["platform"] == "ios" or env["platform"] == "macos":
|
|
||||||
SConscript("coreaudio/SCsub")
|
|
||||||
SConscript("pulseaudio/SCsub")
|
SConscript("pulseaudio/SCsub")
|
||||||
if env["platform"] == "windows":
|
if env["platform"] == "windows":
|
||||||
SConscript("wasapi/SCsub")
|
SConscript("wasapi/SCsub")
|
||||||
@@ -28,8 +26,11 @@ if env["xaudio2"]:
|
|||||||
SConscript("xaudio2/SCsub")
|
SConscript("xaudio2/SCsub")
|
||||||
|
|
||||||
# Shared Apple platform drivers
|
# Shared Apple platform drivers
|
||||||
if env["platform"] in ["macos", "ios"]:
|
if env["platform"] in ["macos", "ios", "visionos"]:
|
||||||
SConscript("apple/SCsub")
|
SConscript("apple/SCsub")
|
||||||
|
SConscript("coreaudio/SCsub")
|
||||||
|
if env["platform"] in ["ios", "visionos"]:
|
||||||
|
SConscript("apple_embedded/SCsub")
|
||||||
|
|
||||||
# Accessibility
|
# Accessibility
|
||||||
if env["accesskit"] and env["platform"] in ["macos", "windows", "linuxbsd"]:
|
if env["accesskit"] and env["platform"] in ["macos", "windows", "linuxbsd"]:
|
||||||
@@ -37,7 +38,7 @@ if env["accesskit"] and env["platform"] in ["macos", "windows", "linuxbsd"]:
|
|||||||
|
|
||||||
# Midi drivers
|
# Midi drivers
|
||||||
SConscript("alsamidi/SCsub")
|
SConscript("alsamidi/SCsub")
|
||||||
if env["platform"] in ["macos", "ios"]:
|
if env["platform"] in ["macos"]:
|
||||||
SConscript("coremidi/SCsub")
|
SConscript("coremidi/SCsub")
|
||||||
SConscript("winmidi/SCsub")
|
SConscript("winmidi/SCsub")
|
||||||
|
|
||||||
|
|||||||
16
drivers/apple_embedded/SCsub
Normal file
16
drivers/apple_embedded/SCsub
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
from misc.utility.scons_hints import *
|
||||||
|
|
||||||
|
Import("env")
|
||||||
|
|
||||||
|
env_apple_embedded = env.Clone()
|
||||||
|
|
||||||
|
# Enable module support
|
||||||
|
env_apple_embedded.Append(CCFLAGS=["-fmodules", "-fcxx-modules"])
|
||||||
|
|
||||||
|
# Use bundled Vulkan headers
|
||||||
|
vulkan_dir = "#thirdparty/vulkan"
|
||||||
|
env_apple_embedded.Prepend(CPPPATH=[vulkan_dir, vulkan_dir + "/include"])
|
||||||
|
|
||||||
|
# Driver source files
|
||||||
|
env_apple_embedded.add_source_files(env.drivers_sources, "*.mm")
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
/* app_delegate.h */
|
/* app_delegate_service.h */
|
||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
/* This file is part of: */
|
/* This file is part of: */
|
||||||
/* GODOT ENGINE */
|
/* GODOT ENGINE */
|
||||||
@@ -32,18 +32,11 @@
|
|||||||
|
|
||||||
#import <UIKit/UIKit.h>
|
#import <UIKit/UIKit.h>
|
||||||
|
|
||||||
@class ViewController;
|
@class GDTViewController;
|
||||||
|
|
||||||
// FIXME: Add support for both OpenGL and Vulkan when OpenGL is implemented again,
|
@interface GDTAppDelegateService : NSObject <UIApplicationDelegate>
|
||||||
// so it can't be done with compilation time branching.
|
|
||||||
//#if defined(GLES3_ENABLED)
|
|
||||||
//@interface AppDelegate : NSObject <UIApplicationDelegate, GLViewDelegate> {
|
|
||||||
//#endif
|
|
||||||
//#if defined(VULKAN_ENABLED)
|
|
||||||
@interface AppDelegate : NSObject <UIApplicationDelegate>
|
|
||||||
//#endif
|
|
||||||
|
|
||||||
@property(strong, nonatomic) UIWindow *window;
|
@property(strong, nonatomic) UIWindow *window;
|
||||||
@property(strong, class, readonly, nonatomic) ViewController *viewController;
|
@property(strong, class, readonly, nonatomic) GDTViewController *viewController;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
/* app_delegate.mm */
|
/* app_delegate_service.mm */
|
||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
/* This file is part of: */
|
/* This file is part of: */
|
||||||
/* GODOT ENGINE */
|
/* GODOT ENGINE */
|
||||||
@@ -28,10 +28,10 @@
|
|||||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
|
|
||||||
#import "app_delegate.h"
|
#import "app_delegate_service.h"
|
||||||
|
|
||||||
#import "godot_view.h"
|
#import "godot_view_apple_embedded.h"
|
||||||
#import "os_ios.h"
|
#import "os_apple_embedded.h"
|
||||||
#import "view_controller.h"
|
#import "view_controller.h"
|
||||||
|
|
||||||
#include "core/config/project_settings.h"
|
#include "core/config/project_settings.h"
|
||||||
@@ -46,10 +46,10 @@
|
|||||||
extern int gargc;
|
extern int gargc;
|
||||||
extern char **gargv;
|
extern char **gargv;
|
||||||
|
|
||||||
extern int ios_main(int, char **);
|
extern int apple_embedded_main(int, char **);
|
||||||
extern void ios_finish();
|
extern void apple_embedded_finish();
|
||||||
|
|
||||||
@implementation AppDelegate
|
@implementation GDTAppDelegateService
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
SESSION_CATEGORY_AMBIENT,
|
SESSION_CATEGORY_AMBIENT,
|
||||||
@@ -60,9 +60,9 @@ enum {
|
|||||||
SESSION_CATEGORY_SOLO_AMBIENT
|
SESSION_CATEGORY_SOLO_AMBIENT
|
||||||
};
|
};
|
||||||
|
|
||||||
static ViewController *mainViewController = nil;
|
static GDTViewController *mainViewController = nil;
|
||||||
|
|
||||||
+ (ViewController *)viewController {
|
+ (GDTViewController *)viewController {
|
||||||
return mainViewController;
|
return mainViewController;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -71,12 +71,15 @@ static ViewController *mainViewController = nil;
|
|||||||
// TODO: logo screen is not displayed while shaders are compiling
|
// TODO: logo screen is not displayed while shaders are compiling
|
||||||
// DummyViewController(Splash/LoadingViewController) -> setup -> GodotViewController
|
// DummyViewController(Splash/LoadingViewController) -> setup -> GodotViewController
|
||||||
|
|
||||||
CGRect windowBounds = [[UIScreen mainScreen] bounds];
|
#if !defined(VISIONOS_ENABLED)
|
||||||
|
|
||||||
// Create a full-screen window
|
// Create a full-screen window
|
||||||
|
CGRect windowBounds = [[UIScreen mainScreen] bounds];
|
||||||
self.window = [[UIWindow alloc] initWithFrame:windowBounds];
|
self.window = [[UIWindow alloc] initWithFrame:windowBounds];
|
||||||
|
#else
|
||||||
|
self.window = [[UIWindow alloc] init];
|
||||||
|
#endif
|
||||||
|
|
||||||
int err = ios_main(gargc, gargv);
|
int err = apple_embedded_main(gargc, gargv);
|
||||||
|
|
||||||
if (err != 0) {
|
if (err != 0) {
|
||||||
// bail, things did not go very well for us, should probably output a message on screen with our error code...
|
// bail, things did not go very well for us, should probably output a message on screen with our error code...
|
||||||
@@ -84,7 +87,7 @@ static ViewController *mainViewController = nil;
|
|||||||
return NO;
|
return NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
ViewController *viewController = [[ViewController alloc] init];
|
GDTViewController *viewController = [[GDTViewController alloc] init];
|
||||||
viewController.godotView.useCADisplayLink = bool(GLOBAL_DEF("display.iOS/use_cadisplaylink", true)) ? YES : NO;
|
viewController.godotView.useCADisplayLink = bool(GLOBAL_DEF("display.iOS/use_cadisplaylink", true)) ? YES : NO;
|
||||||
viewController.godotView.renderingInterval = 1.0 / kRenderingFrequency;
|
viewController.godotView.renderingInterval = 1.0 / kRenderingFrequency;
|
||||||
|
|
||||||
@@ -135,10 +138,10 @@ static ViewController *mainViewController = nil;
|
|||||||
if ([notification.name isEqualToString:AVAudioSessionInterruptionNotification]) {
|
if ([notification.name isEqualToString:AVAudioSessionInterruptionNotification]) {
|
||||||
if ([[notification.userInfo valueForKey:AVAudioSessionInterruptionTypeKey] isEqualToNumber:[NSNumber numberWithInt:AVAudioSessionInterruptionTypeBegan]]) {
|
if ([[notification.userInfo valueForKey:AVAudioSessionInterruptionTypeKey] isEqualToNumber:[NSNumber numberWithInt:AVAudioSessionInterruptionTypeBegan]]) {
|
||||||
NSLog(@"Audio interruption began");
|
NSLog(@"Audio interruption began");
|
||||||
OS_IOS::get_singleton()->on_focus_out();
|
OS_AppleEmbedded::get_singleton()->on_focus_out();
|
||||||
} else if ([[notification.userInfo valueForKey:AVAudioSessionInterruptionTypeKey] isEqualToNumber:[NSNumber numberWithInt:AVAudioSessionInterruptionTypeEnded]]) {
|
} else if ([[notification.userInfo valueForKey:AVAudioSessionInterruptionTypeKey] isEqualToNumber:[NSNumber numberWithInt:AVAudioSessionInterruptionTypeEnded]]) {
|
||||||
NSLog(@"Audio interruption ended");
|
NSLog(@"Audio interruption ended");
|
||||||
OS_IOS::get_singleton()->on_focus_in();
|
OS_AppleEmbedded::get_singleton()->on_focus_in();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -150,7 +153,7 @@ static ViewController *mainViewController = nil;
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (void)applicationWillTerminate:(UIApplication *)application {
|
- (void)applicationWillTerminate:(UIApplication *)application {
|
||||||
ios_finish();
|
apple_embedded_finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
// When application goes to background (e.g. user switches to another app or presses Home),
|
// When application goes to background (e.g. user switches to another app or presses Home),
|
||||||
@@ -164,19 +167,19 @@ static ViewController *mainViewController = nil;
|
|||||||
// notification panel by swiping from the upper part of the screen.
|
// notification panel by swiping from the upper part of the screen.
|
||||||
|
|
||||||
- (void)applicationWillResignActive:(UIApplication *)application {
|
- (void)applicationWillResignActive:(UIApplication *)application {
|
||||||
OS_IOS::get_singleton()->on_focus_out();
|
OS_AppleEmbedded::get_singleton()->on_focus_out();
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)applicationDidBecomeActive:(UIApplication *)application {
|
- (void)applicationDidBecomeActive:(UIApplication *)application {
|
||||||
OS_IOS::get_singleton()->on_focus_in();
|
OS_AppleEmbedded::get_singleton()->on_focus_in();
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)applicationDidEnterBackground:(UIApplication *)application {
|
- (void)applicationDidEnterBackground:(UIApplication *)application {
|
||||||
OS_IOS::get_singleton()->on_enter_background();
|
OS_AppleEmbedded::get_singleton()->on_enter_background();
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)applicationWillEnterForeground:(UIApplication *)application {
|
- (void)applicationWillEnterForeground:(UIApplication *)application {
|
||||||
OS_IOS::get_singleton()->on_exit_background();
|
OS_AppleEmbedded::get_singleton()->on_exit_background();
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)dealloc {
|
- (void)dealloc {
|
||||||
59
drivers/apple_embedded/apple_embedded.h
Normal file
59
drivers/apple_embedded/apple_embedded.h
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
/**************************************************************************/
|
||||||
|
/* apple_embedded.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. */
|
||||||
|
/**************************************************************************/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "core/object/class_db.h"
|
||||||
|
|
||||||
|
#import <CoreHaptics/CoreHaptics.h>
|
||||||
|
|
||||||
|
class AppleEmbedded : public Object {
|
||||||
|
GDCLASS(AppleEmbedded, Object);
|
||||||
|
|
||||||
|
static void _bind_methods();
|
||||||
|
|
||||||
|
private:
|
||||||
|
CHHapticEngine *haptic_engine API_AVAILABLE(ios(13)) = nullptr;
|
||||||
|
|
||||||
|
CHHapticEngine *get_haptic_engine_instance() API_AVAILABLE(ios(13));
|
||||||
|
void start_haptic_engine();
|
||||||
|
void stop_haptic_engine();
|
||||||
|
|
||||||
|
public:
|
||||||
|
static void alert(const char *p_alert, const char *p_title);
|
||||||
|
|
||||||
|
bool supports_haptic_engine();
|
||||||
|
void vibrate_haptic_engine(float p_duration_seconds, float p_amplitude);
|
||||||
|
|
||||||
|
String get_model() const;
|
||||||
|
String get_rate_url(int p_app_id) const;
|
||||||
|
|
||||||
|
AppleEmbedded();
|
||||||
|
};
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
/* ios.mm */
|
/* apple_embedded.mm */
|
||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
/* This file is part of: */
|
/* This file is part of: */
|
||||||
/* GODOT ENGINE */
|
/* GODOT ENGINE */
|
||||||
@@ -28,23 +28,23 @@
|
|||||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
|
|
||||||
#import "ios.h"
|
#import "apple_embedded.h"
|
||||||
|
|
||||||
#import "app_delegate.h"
|
#import "app_delegate_service.h"
|
||||||
#import "view_controller.h"
|
#import "view_controller.h"
|
||||||
|
|
||||||
#import <CoreHaptics/CoreHaptics.h>
|
#import <CoreHaptics/CoreHaptics.h>
|
||||||
#import <UIKit/UIKit.h>
|
#import <UIKit/UIKit.h>
|
||||||
#include <sys/sysctl.h>
|
#include <sys/sysctl.h>
|
||||||
|
|
||||||
void iOS::_bind_methods() {
|
void AppleEmbedded::_bind_methods() {
|
||||||
ClassDB::bind_method(D_METHOD("get_rate_url", "app_id"), &iOS::get_rate_url);
|
ClassDB::bind_method(D_METHOD("get_rate_url", "app_id"), &AppleEmbedded::get_rate_url);
|
||||||
ClassDB::bind_method(D_METHOD("supports_haptic_engine"), &iOS::supports_haptic_engine);
|
ClassDB::bind_method(D_METHOD("supports_haptic_engine"), &AppleEmbedded::supports_haptic_engine);
|
||||||
ClassDB::bind_method(D_METHOD("start_haptic_engine"), &iOS::start_haptic_engine);
|
ClassDB::bind_method(D_METHOD("start_haptic_engine"), &AppleEmbedded::start_haptic_engine);
|
||||||
ClassDB::bind_method(D_METHOD("stop_haptic_engine"), &iOS::stop_haptic_engine);
|
ClassDB::bind_method(D_METHOD("stop_haptic_engine"), &AppleEmbedded::stop_haptic_engine);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool iOS::supports_haptic_engine() {
|
bool AppleEmbedded::supports_haptic_engine() {
|
||||||
if (@available(iOS 13, *)) {
|
if (@available(iOS 13, *)) {
|
||||||
id<CHHapticDeviceCapability> capabilities = [CHHapticEngine capabilitiesForHardware];
|
id<CHHapticDeviceCapability> capabilities = [CHHapticEngine capabilitiesForHardware];
|
||||||
return capabilities.supportsHaptics;
|
return capabilities.supportsHaptics;
|
||||||
@@ -53,7 +53,7 @@ bool iOS::supports_haptic_engine() {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
CHHapticEngine *iOS::get_haptic_engine_instance() API_AVAILABLE(ios(13)) {
|
CHHapticEngine *AppleEmbedded::get_haptic_engine_instance() API_AVAILABLE(ios(13)) {
|
||||||
if (haptic_engine == nullptr) {
|
if (haptic_engine == nullptr) {
|
||||||
NSError *error = nullptr;
|
NSError *error = nullptr;
|
||||||
haptic_engine = [[CHHapticEngine alloc] initAndReturnError:&error];
|
haptic_engine = [[CHHapticEngine alloc] initAndReturnError:&error];
|
||||||
@@ -69,7 +69,7 @@ CHHapticEngine *iOS::get_haptic_engine_instance() API_AVAILABLE(ios(13)) {
|
|||||||
return haptic_engine;
|
return haptic_engine;
|
||||||
}
|
}
|
||||||
|
|
||||||
void iOS::vibrate_haptic_engine(float p_duration_seconds, float p_amplitude) API_AVAILABLE(ios(13)) {
|
void AppleEmbedded::vibrate_haptic_engine(float p_duration_seconds, float p_amplitude) API_AVAILABLE(ios(13)) {
|
||||||
if (@available(iOS 13, *)) { // We need the @available check every time to make the compiler happy...
|
if (@available(iOS 13, *)) { // We need the @available check every time to make the compiler happy...
|
||||||
if (supports_haptic_engine()) {
|
if (supports_haptic_engine()) {
|
||||||
CHHapticEngine *cur_haptic_engine = get_haptic_engine_instance();
|
CHHapticEngine *cur_haptic_engine = get_haptic_engine_instance();
|
||||||
@@ -117,10 +117,10 @@ void iOS::vibrate_haptic_engine(float p_duration_seconds, float p_amplitude) API
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
NSLog(@"Haptic engine is not supported in this version of iOS");
|
NSLog(@"Haptic engine is not supported");
|
||||||
}
|
}
|
||||||
|
|
||||||
void iOS::start_haptic_engine() {
|
void AppleEmbedded::start_haptic_engine() {
|
||||||
if (@available(iOS 13, *)) {
|
if (@available(iOS 13, *)) {
|
||||||
if (supports_haptic_engine()) {
|
if (supports_haptic_engine()) {
|
||||||
CHHapticEngine *cur_haptic_engine = get_haptic_engine_instance();
|
CHHapticEngine *cur_haptic_engine = get_haptic_engine_instance();
|
||||||
@@ -136,10 +136,10 @@ void iOS::start_haptic_engine() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
NSLog(@"Haptic engine is not supported in this version of iOS");
|
NSLog(@"Haptic engine is not supported");
|
||||||
}
|
}
|
||||||
|
|
||||||
void iOS::stop_haptic_engine() {
|
void AppleEmbedded::stop_haptic_engine() {
|
||||||
if (@available(iOS 13, *)) {
|
if (@available(iOS 13, *)) {
|
||||||
if (supports_haptic_engine()) {
|
if (supports_haptic_engine()) {
|
||||||
CHHapticEngine *cur_haptic_engine = get_haptic_engine_instance();
|
CHHapticEngine *cur_haptic_engine = get_haptic_engine_instance();
|
||||||
@@ -155,10 +155,10 @@ void iOS::stop_haptic_engine() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
NSLog(@"Haptic engine is not supported in this version of iOS");
|
NSLog(@"Haptic engine is not supported");
|
||||||
}
|
}
|
||||||
|
|
||||||
void iOS::alert(const char *p_alert, const char *p_title) {
|
void AppleEmbedded::alert(const char *p_alert, const char *p_title) {
|
||||||
NSString *title = [NSString stringWithUTF8String:p_title];
|
NSString *title = [NSString stringWithUTF8String:p_title];
|
||||||
NSString *message = [NSString stringWithUTF8String:p_alert];
|
NSString *message = [NSString stringWithUTF8String:p_alert];
|
||||||
|
|
||||||
@@ -170,10 +170,10 @@ void iOS::alert(const char *p_alert, const char *p_title) {
|
|||||||
|
|
||||||
[alert addAction:button];
|
[alert addAction:button];
|
||||||
|
|
||||||
[AppDelegate.viewController presentViewController:alert animated:YES completion:nil];
|
[GDTAppDelegateService.viewController presentViewController:alert animated:YES completion:nil];
|
||||||
}
|
}
|
||||||
|
|
||||||
String iOS::get_model() const {
|
String AppleEmbedded::get_model() const {
|
||||||
// [[UIDevice currentDevice] model] only returns "iPad" or "iPhone".
|
// [[UIDevice currentDevice] model] only returns "iPad" or "iPhone".
|
||||||
size_t size;
|
size_t size;
|
||||||
sysctlbyname("hw.machine", nullptr, &size, nullptr, 0);
|
sysctlbyname("hw.machine", nullptr, &size, nullptr, 0);
|
||||||
@@ -188,7 +188,7 @@ String iOS::get_model() const {
|
|||||||
return String::utf8(str != nullptr ? str : "");
|
return String::utf8(str != nullptr ? str : "");
|
||||||
}
|
}
|
||||||
|
|
||||||
String iOS::get_rate_url(int p_app_id) const {
|
String AppleEmbedded::get_rate_url(int p_app_id) const {
|
||||||
String app_url_path = "itms-apps://itunes.apple.com/app/idAPP_ID";
|
String app_url_path = "itms-apps://itunes.apple.com/app/idAPP_ID";
|
||||||
|
|
||||||
String ret = app_url_path.replace("APP_ID", String::num_int64(p_app_id));
|
String ret = app_url_path.replace("APP_ID", String::num_int64(p_app_id));
|
||||||
@@ -197,4 +197,4 @@ String iOS::get_rate_url(int p_app_id) const {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
iOS::iOS() {}
|
AppleEmbedded::AppleEmbedded() {}
|
||||||
42
drivers/apple_embedded/display_layer_apple_embedded.h
Normal file
42
drivers/apple_embedded/display_layer_apple_embedded.h
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
/**************************************************************************/
|
||||||
|
/* display_layer_apple_embedded.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. */
|
||||||
|
/**************************************************************************/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#import <QuartzCore/CAMetalLayer.h>
|
||||||
|
|
||||||
|
@protocol GDTDisplayLayer <NSObject>
|
||||||
|
|
||||||
|
- (void)startRenderDisplayLayer;
|
||||||
|
- (void)stopRenderDisplayLayer;
|
||||||
|
- (void)initializeDisplayLayer;
|
||||||
|
- (void)layoutDisplayLayer;
|
||||||
|
|
||||||
|
@end
|
||||||
233
drivers/apple_embedded/display_server_apple_embedded.h
Normal file
233
drivers/apple_embedded/display_server_apple_embedded.h
Normal file
@@ -0,0 +1,233 @@
|
|||||||
|
/**************************************************************************/
|
||||||
|
/* display_server_apple_embedded.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. */
|
||||||
|
/**************************************************************************/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "core/input/input.h"
|
||||||
|
#include "servers/display_server.h"
|
||||||
|
|
||||||
|
#if defined(RD_ENABLED)
|
||||||
|
#include "servers/rendering/renderer_rd/renderer_compositor_rd.h"
|
||||||
|
#include "servers/rendering/rendering_device.h"
|
||||||
|
|
||||||
|
#if defined(VULKAN_ENABLED)
|
||||||
|
#import "rendering_context_driver_vulkan_apple_embedded.h"
|
||||||
|
|
||||||
|
#include "drivers/vulkan/godot_vulkan.h"
|
||||||
|
#endif // VULKAN_ENABLED
|
||||||
|
|
||||||
|
#if defined(METAL_ENABLED)
|
||||||
|
#import "drivers/metal/rendering_context_driver_metal.h"
|
||||||
|
#endif // METAL_ENABLED
|
||||||
|
#endif // RD_ENABLED
|
||||||
|
|
||||||
|
#if defined(GLES3_ENABLED)
|
||||||
|
#include "drivers/gles3/rasterizer_gles3.h"
|
||||||
|
#endif // GLES3_ENABLED
|
||||||
|
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
#import <QuartzCore/CAMetalLayer.h>
|
||||||
|
|
||||||
|
class DisplayServerAppleEmbedded : public DisplayServer {
|
||||||
|
GDSOFTCLASS(DisplayServerAppleEmbedded, DisplayServer);
|
||||||
|
|
||||||
|
_THREAD_SAFE_CLASS_
|
||||||
|
|
||||||
|
#if defined(RD_ENABLED)
|
||||||
|
RenderingContextDriver *rendering_context = nullptr;
|
||||||
|
RenderingDevice *rendering_device = nullptr;
|
||||||
|
#endif
|
||||||
|
NativeMenu *native_menu = nullptr;
|
||||||
|
|
||||||
|
id tts = nullptr;
|
||||||
|
|
||||||
|
DisplayServer::ScreenOrientation screen_orientation;
|
||||||
|
|
||||||
|
ObjectID window_attached_instance_id;
|
||||||
|
|
||||||
|
Callable window_event_callback;
|
||||||
|
Callable window_resize_callback;
|
||||||
|
Callable input_event_callback;
|
||||||
|
Callable input_text_callback;
|
||||||
|
|
||||||
|
Callable system_theme_changed;
|
||||||
|
|
||||||
|
int virtual_keyboard_height = 0;
|
||||||
|
|
||||||
|
void perform_event(const Ref<InputEvent> &p_event);
|
||||||
|
|
||||||
|
void initialize_tts() const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
DisplayServerAppleEmbedded(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);
|
||||||
|
~DisplayServerAppleEmbedded();
|
||||||
|
|
||||||
|
public:
|
||||||
|
String rendering_driver;
|
||||||
|
|
||||||
|
static DisplayServerAppleEmbedded *get_singleton();
|
||||||
|
|
||||||
|
static Vector<String> get_rendering_drivers_func();
|
||||||
|
|
||||||
|
// MARK: - Events
|
||||||
|
|
||||||
|
virtual void process_events() override;
|
||||||
|
|
||||||
|
virtual void window_set_rect_changed_callback(const Callable &p_callable, WindowID p_window = MAIN_WINDOW_ID) override;
|
||||||
|
virtual void window_set_window_event_callback(const Callable &p_callable, WindowID p_window = MAIN_WINDOW_ID) override;
|
||||||
|
virtual void window_set_input_event_callback(const Callable &p_callable, WindowID p_window = MAIN_WINDOW_ID) override;
|
||||||
|
virtual void window_set_input_text_callback(const Callable &p_callable, WindowID p_window = MAIN_WINDOW_ID) override;
|
||||||
|
virtual void window_set_drop_files_callback(const Callable &p_callable, WindowID p_window = MAIN_WINDOW_ID) override;
|
||||||
|
|
||||||
|
static void _dispatch_input_events(const Ref<InputEvent> &p_event);
|
||||||
|
void send_input_event(const Ref<InputEvent> &p_event) const;
|
||||||
|
void send_input_text(const String &p_text) const;
|
||||||
|
void send_window_event(DisplayServer::WindowEvent p_event) const;
|
||||||
|
void _window_callback(const Callable &p_callable, const Variant &p_arg) const;
|
||||||
|
|
||||||
|
void emit_system_theme_changed();
|
||||||
|
|
||||||
|
// MARK: - Input
|
||||||
|
|
||||||
|
// MARK: Touches and Apple Pencil
|
||||||
|
|
||||||
|
void touch_press(int p_idx, int p_x, int p_y, bool p_pressed, bool p_double_click);
|
||||||
|
void touch_drag(int p_idx, int p_prev_x, int p_prev_y, int p_x, int p_y, float p_pressure, Vector2 p_tilt);
|
||||||
|
void touches_canceled(int p_idx);
|
||||||
|
|
||||||
|
// MARK: Keyboard
|
||||||
|
|
||||||
|
void key(Key p_key, char32_t p_char, Key p_unshifted, Key p_physical, NSInteger p_modifier, bool p_pressed, KeyLocation p_location);
|
||||||
|
bool is_keyboard_active() const;
|
||||||
|
|
||||||
|
// MARK: Motion
|
||||||
|
|
||||||
|
void update_gravity(const Vector3 &p_gravity);
|
||||||
|
void update_accelerometer(const Vector3 &p_accelerometer);
|
||||||
|
void update_magnetometer(const Vector3 &p_magnetometer);
|
||||||
|
void update_gyroscope(const Vector3 &p_gyroscope);
|
||||||
|
|
||||||
|
// MARK: -
|
||||||
|
|
||||||
|
virtual bool has_feature(Feature p_feature) const override;
|
||||||
|
|
||||||
|
virtual bool tts_is_speaking() const override;
|
||||||
|
virtual bool tts_is_paused() const override;
|
||||||
|
virtual TypedArray<Dictionary> tts_get_voices() const override;
|
||||||
|
|
||||||
|
virtual void tts_speak(const String &p_text, const String &p_voice, int p_volume = 50, float p_pitch = 1.f, float p_rate = 1.f, int p_utterance_id = 0, bool p_interrupt = false) override;
|
||||||
|
virtual void tts_pause() override;
|
||||||
|
virtual void tts_resume() override;
|
||||||
|
virtual void tts_stop() override;
|
||||||
|
|
||||||
|
virtual bool is_dark_mode_supported() const override;
|
||||||
|
virtual bool is_dark_mode() const override;
|
||||||
|
virtual void set_system_theme_change_callback(const Callable &p_callable) override;
|
||||||
|
|
||||||
|
virtual Rect2i get_display_safe_area() const override;
|
||||||
|
|
||||||
|
virtual int get_screen_count() const override;
|
||||||
|
virtual int get_primary_screen() const override;
|
||||||
|
virtual Point2i screen_get_position(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
|
||||||
|
virtual Size2i screen_get_size(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
|
||||||
|
virtual Rect2i screen_get_usable_rect(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
|
||||||
|
|
||||||
|
virtual Vector<DisplayServer::WindowID> get_window_list() const override;
|
||||||
|
|
||||||
|
virtual WindowID get_window_at_screen_position(const Point2i &p_position) const override;
|
||||||
|
|
||||||
|
virtual int64_t window_get_native_handle(HandleType p_handle_type, WindowID p_window = MAIN_WINDOW_ID) const override;
|
||||||
|
|
||||||
|
virtual void window_attach_instance_id(ObjectID p_instance, WindowID p_window = MAIN_WINDOW_ID) override;
|
||||||
|
virtual ObjectID window_get_attached_instance_id(WindowID p_window = MAIN_WINDOW_ID) const override;
|
||||||
|
|
||||||
|
virtual void window_set_title(const String &p_title, WindowID p_window = MAIN_WINDOW_ID) override;
|
||||||
|
|
||||||
|
virtual int window_get_current_screen(WindowID p_window = MAIN_WINDOW_ID) const override;
|
||||||
|
virtual void window_set_current_screen(int p_screen, WindowID p_window = MAIN_WINDOW_ID) override;
|
||||||
|
|
||||||
|
virtual Point2i window_get_position(WindowID p_window = MAIN_WINDOW_ID) const override;
|
||||||
|
virtual Point2i window_get_position_with_decorations(WindowID p_window = MAIN_WINDOW_ID) const override;
|
||||||
|
virtual void window_set_position(const Point2i &p_position, WindowID p_window = MAIN_WINDOW_ID) override;
|
||||||
|
|
||||||
|
virtual void window_set_transient(WindowID p_window, WindowID p_parent) override;
|
||||||
|
|
||||||
|
virtual void window_set_max_size(const Size2i p_size, WindowID p_window = MAIN_WINDOW_ID) override;
|
||||||
|
virtual Size2i window_get_max_size(WindowID p_window = MAIN_WINDOW_ID) const override;
|
||||||
|
|
||||||
|
virtual void window_set_min_size(const Size2i p_size, WindowID p_window = MAIN_WINDOW_ID) override;
|
||||||
|
virtual Size2i window_get_min_size(WindowID p_window = MAIN_WINDOW_ID) const override;
|
||||||
|
|
||||||
|
virtual void window_set_size(const Size2i p_size, WindowID p_window = MAIN_WINDOW_ID) override;
|
||||||
|
virtual Size2i window_get_size(WindowID p_window = MAIN_WINDOW_ID) const override;
|
||||||
|
virtual Size2i window_get_size_with_decorations(WindowID p_window = MAIN_WINDOW_ID) const override;
|
||||||
|
|
||||||
|
virtual void window_set_mode(WindowMode p_mode, WindowID p_window = MAIN_WINDOW_ID) override;
|
||||||
|
virtual WindowMode window_get_mode(WindowID p_window = MAIN_WINDOW_ID) const override;
|
||||||
|
|
||||||
|
virtual bool window_is_maximize_allowed(WindowID p_window = MAIN_WINDOW_ID) const override;
|
||||||
|
|
||||||
|
virtual void window_set_flag(WindowFlags p_flag, bool p_enabled, WindowID p_window = MAIN_WINDOW_ID) override;
|
||||||
|
virtual bool window_get_flag(WindowFlags p_flag, WindowID p_window = MAIN_WINDOW_ID) const override;
|
||||||
|
|
||||||
|
virtual void window_request_attention(WindowID p_window = MAIN_WINDOW_ID) override;
|
||||||
|
virtual void window_move_to_foreground(WindowID p_window = MAIN_WINDOW_ID) override;
|
||||||
|
virtual bool window_is_focused(WindowID p_window = MAIN_WINDOW_ID) const override;
|
||||||
|
|
||||||
|
virtual float screen_get_max_scale() const override;
|
||||||
|
|
||||||
|
virtual void screen_set_orientation(DisplayServer::ScreenOrientation p_orientation, int p_screen) override;
|
||||||
|
virtual DisplayServer::ScreenOrientation screen_get_orientation(int p_screen) const override;
|
||||||
|
|
||||||
|
virtual bool window_can_draw(WindowID p_window = MAIN_WINDOW_ID) const override;
|
||||||
|
|
||||||
|
virtual bool can_any_window_draw() const override;
|
||||||
|
|
||||||
|
virtual void window_set_vsync_mode(DisplayServer::VSyncMode p_vsync_mode, WindowID p_window = MAIN_WINDOW_ID) override;
|
||||||
|
virtual DisplayServer::VSyncMode window_get_vsync_mode(WindowID p_vsync_mode) const override;
|
||||||
|
|
||||||
|
virtual bool is_touchscreen_available() const override;
|
||||||
|
|
||||||
|
virtual void virtual_keyboard_show(const String &p_existing_text, const Rect2 &p_screen_rect, VirtualKeyboardType p_type, int p_max_length, int p_cursor_start, int p_cursor_end) override;
|
||||||
|
virtual void virtual_keyboard_hide() override;
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
virtual void screen_set_keep_on(bool p_enable) override;
|
||||||
|
virtual bool screen_is_kept_on() const override;
|
||||||
|
|
||||||
|
void resize_window(CGSize size);
|
||||||
|
virtual void swap_buffers() override {}
|
||||||
|
};
|
||||||
794
drivers/apple_embedded/display_server_apple_embedded.mm
Normal file
794
drivers/apple_embedded/display_server_apple_embedded.mm
Normal file
@@ -0,0 +1,794 @@
|
|||||||
|
/**************************************************************************/
|
||||||
|
/* display_server_apple_embedded.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 "display_server_apple_embedded.h"
|
||||||
|
|
||||||
|
#import "app_delegate_service.h"
|
||||||
|
#import "apple_embedded.h"
|
||||||
|
#import "godot_view_apple_embedded.h"
|
||||||
|
#import "key_mapping_apple_embedded.h"
|
||||||
|
#import "keyboard_input_view.h"
|
||||||
|
#import "os_apple_embedded.h"
|
||||||
|
#import "tts_apple_embedded.h"
|
||||||
|
#import "view_controller.h"
|
||||||
|
|
||||||
|
#include "core/config/project_settings.h"
|
||||||
|
#include "core/io/file_access_pack.h"
|
||||||
|
|
||||||
|
#import <GameController/GameController.h>
|
||||||
|
|
||||||
|
static const float kDisplayServerIOSAcceleration = 1.f;
|
||||||
|
|
||||||
|
DisplayServerAppleEmbedded *DisplayServerAppleEmbedded::get_singleton() {
|
||||||
|
return (DisplayServerAppleEmbedded *)DisplayServer::get_singleton();
|
||||||
|
}
|
||||||
|
|
||||||
|
DisplayServerAppleEmbedded::DisplayServerAppleEmbedded(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) {
|
||||||
|
KeyMappingAppleEmbedded::initialize();
|
||||||
|
|
||||||
|
rendering_driver = p_rendering_driver;
|
||||||
|
|
||||||
|
// Init TTS
|
||||||
|
bool tts_enabled = GLOBAL_GET("audio/general/text_to_speech");
|
||||||
|
if (tts_enabled) {
|
||||||
|
initialize_tts();
|
||||||
|
}
|
||||||
|
native_menu = memnew(NativeMenu);
|
||||||
|
|
||||||
|
bool has_made_render_compositor_current = false;
|
||||||
|
|
||||||
|
#if defined(RD_ENABLED)
|
||||||
|
rendering_context = nullptr;
|
||||||
|
rendering_device = nullptr;
|
||||||
|
|
||||||
|
CALayer *layer = nullptr;
|
||||||
|
|
||||||
|
union {
|
||||||
|
#ifdef VULKAN_ENABLED
|
||||||
|
RenderingContextDriverVulkanAppleEmbedded::WindowPlatformData vulkan;
|
||||||
|
#endif
|
||||||
|
#ifdef METAL_ENABLED
|
||||||
|
GODOT_CLANG_WARNING_PUSH_AND_IGNORE("-Wunguarded-availability")
|
||||||
|
// Eliminate "RenderingContextDriverMetal is only available on iOS 14.0 or newer".
|
||||||
|
RenderingContextDriverMetal::WindowPlatformData metal;
|
||||||
|
GODOT_CLANG_WARNING_POP
|
||||||
|
#endif
|
||||||
|
} wpd;
|
||||||
|
|
||||||
|
#if defined(VULKAN_ENABLED)
|
||||||
|
if (rendering_driver == "vulkan") {
|
||||||
|
layer = [GDTAppDelegateService.viewController.godotView initializeRenderingForDriver:@"vulkan"];
|
||||||
|
if (!layer) {
|
||||||
|
ERR_FAIL_MSG("Failed to create iOS Vulkan rendering layer.");
|
||||||
|
}
|
||||||
|
wpd.vulkan.layer_ptr = (CAMetalLayer *const *)&layer;
|
||||||
|
rendering_context = memnew(RenderingContextDriverVulkanAppleEmbedded);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef METAL_ENABLED
|
||||||
|
if (rendering_driver == "metal") {
|
||||||
|
if (@available(iOS 14.0, *)) {
|
||||||
|
layer = [GDTAppDelegateService.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);
|
||||||
|
rendering_context = nullptr;
|
||||||
|
r_error = ERR_UNAVAILABLE;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Size2i size = Size2i(layer.bounds.size.width, layer.bounds.size.height) * screen_get_max_scale();
|
||||||
|
rendering_context->window_set_size(MAIN_WINDOW_ID, size.width, size.height);
|
||||||
|
rendering_context->window_set_vsync_mode(MAIN_WINDOW_ID, p_vsync_mode);
|
||||||
|
|
||||||
|
rendering_device = memnew(RenderingDevice);
|
||||||
|
if (rendering_device->initialize(rendering_context, MAIN_WINDOW_ID) != OK) {
|
||||||
|
rendering_device = nullptr;
|
||||||
|
memdelete(rendering_context);
|
||||||
|
rendering_context = nullptr;
|
||||||
|
r_error = ERR_UNAVAILABLE;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
rendering_device->screen_create(MAIN_WINDOW_ID);
|
||||||
|
|
||||||
|
RendererCompositorRD::make_current();
|
||||||
|
has_made_render_compositor_current = true;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(GLES3_ENABLED)
|
||||||
|
if (rendering_driver == "opengl3") {
|
||||||
|
CALayer *layer = [GDTAppDelegateService.viewController.godotView initializeRenderingForDriver:@"opengl3"];
|
||||||
|
|
||||||
|
if (!layer) {
|
||||||
|
ERR_FAIL_MSG("Failed to create iOS OpenGLES rendering layer.");
|
||||||
|
}
|
||||||
|
|
||||||
|
RasterizerGLES3::make_current(false);
|
||||||
|
has_made_render_compositor_current = true;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ERR_FAIL_COND_MSG(!has_made_render_compositor_current, vformat("Failed to make RendererCompositor current for rendering driver %s", rendering_driver));
|
||||||
|
|
||||||
|
bool keep_screen_on = bool(GLOBAL_GET("display/window/energy_saving/keep_screen_on"));
|
||||||
|
screen_set_keep_on(keep_screen_on);
|
||||||
|
|
||||||
|
Input::get_singleton()->set_event_dispatch_function(_dispatch_input_events);
|
||||||
|
|
||||||
|
r_error = OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
DisplayServerAppleEmbedded::~DisplayServerAppleEmbedded() {
|
||||||
|
if (native_menu) {
|
||||||
|
memdelete(native_menu);
|
||||||
|
native_menu = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(RD_ENABLED)
|
||||||
|
if (rendering_device) {
|
||||||
|
rendering_device->screen_free(MAIN_WINDOW_ID);
|
||||||
|
memdelete(rendering_device);
|
||||||
|
rendering_device = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rendering_context) {
|
||||||
|
rendering_context->window_destroy(MAIN_WINDOW_ID);
|
||||||
|
memdelete(rendering_context);
|
||||||
|
rendering_context = nullptr;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector<String> DisplayServerAppleEmbedded::get_rendering_drivers_func() {
|
||||||
|
Vector<String> drivers;
|
||||||
|
|
||||||
|
#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
|
||||||
|
|
||||||
|
return drivers;
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: Events
|
||||||
|
|
||||||
|
void DisplayServerAppleEmbedded::window_set_rect_changed_callback(const Callable &p_callable, WindowID p_window) {
|
||||||
|
window_resize_callback = p_callable;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DisplayServerAppleEmbedded::window_set_window_event_callback(const Callable &p_callable, WindowID p_window) {
|
||||||
|
window_event_callback = p_callable;
|
||||||
|
}
|
||||||
|
void DisplayServerAppleEmbedded::window_set_input_event_callback(const Callable &p_callable, WindowID p_window) {
|
||||||
|
input_event_callback = p_callable;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DisplayServerAppleEmbedded::window_set_input_text_callback(const Callable &p_callable, WindowID p_window) {
|
||||||
|
input_text_callback = p_callable;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DisplayServerAppleEmbedded::window_set_drop_files_callback(const Callable &p_callable, WindowID p_window) {
|
||||||
|
// Probably not supported for iOS
|
||||||
|
}
|
||||||
|
|
||||||
|
void DisplayServerAppleEmbedded::process_events() {
|
||||||
|
Input::get_singleton()->flush_buffered_events();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DisplayServerAppleEmbedded::_dispatch_input_events(const Ref<InputEvent> &p_event) {
|
||||||
|
DisplayServerAppleEmbedded::get_singleton()->send_input_event(p_event);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DisplayServerAppleEmbedded::send_input_event(const Ref<InputEvent> &p_event) const {
|
||||||
|
_window_callback(input_event_callback, p_event);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DisplayServerAppleEmbedded::send_input_text(const String &p_text) const {
|
||||||
|
_window_callback(input_text_callback, p_text);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DisplayServerAppleEmbedded::send_window_event(DisplayServer::WindowEvent p_event) const {
|
||||||
|
_window_callback(window_event_callback, int(p_event));
|
||||||
|
}
|
||||||
|
|
||||||
|
void DisplayServerAppleEmbedded::_window_callback(const Callable &p_callable, const Variant &p_arg) const {
|
||||||
|
if (p_callable.is_valid()) {
|
||||||
|
p_callable.call(p_arg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Input
|
||||||
|
|
||||||
|
// MARK: Touches
|
||||||
|
|
||||||
|
void DisplayServerAppleEmbedded::touch_press(int p_idx, int p_x, int p_y, bool p_pressed, bool p_double_click) {
|
||||||
|
Ref<InputEventScreenTouch> ev;
|
||||||
|
ev.instantiate();
|
||||||
|
|
||||||
|
ev->set_index(p_idx);
|
||||||
|
ev->set_pressed(p_pressed);
|
||||||
|
ev->set_position(Vector2(p_x, p_y));
|
||||||
|
ev->set_double_tap(p_double_click);
|
||||||
|
perform_event(ev);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DisplayServerAppleEmbedded::touch_drag(int p_idx, int p_prev_x, int p_prev_y, int p_x, int p_y, float p_pressure, Vector2 p_tilt) {
|
||||||
|
Ref<InputEventScreenDrag> ev;
|
||||||
|
ev.instantiate();
|
||||||
|
ev->set_index(p_idx);
|
||||||
|
ev->set_pressure(p_pressure);
|
||||||
|
ev->set_tilt(p_tilt);
|
||||||
|
ev->set_position(Vector2(p_x, p_y));
|
||||||
|
ev->set_relative(Vector2(p_x - p_prev_x, p_y - p_prev_y));
|
||||||
|
ev->set_relative_screen_position(ev->get_relative());
|
||||||
|
perform_event(ev);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DisplayServerAppleEmbedded::perform_event(const Ref<InputEvent> &p_event) {
|
||||||
|
Input::get_singleton()->parse_input_event(p_event);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DisplayServerAppleEmbedded::touches_canceled(int p_idx) {
|
||||||
|
touch_press(p_idx, -1, -1, false, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: Keyboard
|
||||||
|
|
||||||
|
void DisplayServerAppleEmbedded::key(Key p_key, char32_t p_char, Key p_unshifted, Key p_physical, NSInteger p_modifier, bool p_pressed, KeyLocation p_location) {
|
||||||
|
Ref<InputEventKey> ev;
|
||||||
|
ev.instantiate();
|
||||||
|
ev->set_echo(false);
|
||||||
|
ev->set_pressed(p_pressed);
|
||||||
|
ev->set_keycode(fix_keycode(p_char, p_key));
|
||||||
|
if (@available(iOS 13.4, *)) {
|
||||||
|
if (p_key != Key::SHIFT) {
|
||||||
|
ev->set_shift_pressed(p_modifier & UIKeyModifierShift);
|
||||||
|
}
|
||||||
|
if (p_key != Key::CTRL) {
|
||||||
|
ev->set_ctrl_pressed(p_modifier & UIKeyModifierControl);
|
||||||
|
}
|
||||||
|
if (p_key != Key::ALT) {
|
||||||
|
ev->set_alt_pressed(p_modifier & UIKeyModifierAlternate);
|
||||||
|
}
|
||||||
|
if (p_key != Key::META) {
|
||||||
|
ev->set_meta_pressed(p_modifier & UIKeyModifierCommand);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ev->set_key_label(p_unshifted);
|
||||||
|
ev->set_physical_keycode(p_physical);
|
||||||
|
ev->set_unicode(fix_unicode(p_char));
|
||||||
|
ev->set_location(p_location);
|
||||||
|
perform_event(ev);
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: Motion
|
||||||
|
|
||||||
|
void DisplayServerAppleEmbedded::update_gravity(const Vector3 &p_gravity) {
|
||||||
|
Input::get_singleton()->set_gravity(p_gravity);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DisplayServerAppleEmbedded::update_accelerometer(const Vector3 &p_accelerometer) {
|
||||||
|
Input::get_singleton()->set_accelerometer(p_accelerometer / kDisplayServerIOSAcceleration);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DisplayServerAppleEmbedded::update_magnetometer(const Vector3 &p_magnetometer) {
|
||||||
|
Input::get_singleton()->set_magnetometer(p_magnetometer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DisplayServerAppleEmbedded::update_gyroscope(const Vector3 &p_gyroscope) {
|
||||||
|
Input::get_singleton()->set_gyroscope(p_gyroscope);
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: -
|
||||||
|
|
||||||
|
bool DisplayServerAppleEmbedded::has_feature(Feature p_feature) const {
|
||||||
|
switch (p_feature) {
|
||||||
|
#ifndef DISABLE_DEPRECATED
|
||||||
|
case FEATURE_GLOBAL_MENU: {
|
||||||
|
return (native_menu && native_menu->has_feature(NativeMenu::FEATURE_GLOBAL_MENU));
|
||||||
|
} break;
|
||||||
|
#endif
|
||||||
|
// case FEATURE_CURSOR_SHAPE:
|
||||||
|
// case FEATURE_CUSTOM_CURSOR_SHAPE:
|
||||||
|
// case FEATURE_HIDPI:
|
||||||
|
// case FEATURE_ICON:
|
||||||
|
// case FEATURE_IME:
|
||||||
|
// case FEATURE_MOUSE:
|
||||||
|
// case FEATURE_MOUSE_WARP:
|
||||||
|
// 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:
|
||||||
|
case FEATURE_KEEP_SCREEN_ON:
|
||||||
|
case FEATURE_ORIENTATION:
|
||||||
|
case FEATURE_TOUCHSCREEN:
|
||||||
|
case FEATURE_VIRTUAL_KEYBOARD:
|
||||||
|
case FEATURE_TEXT_TO_SPEECH:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DisplayServerAppleEmbedded::initialize_tts() const {
|
||||||
|
const_cast<DisplayServerAppleEmbedded *>(this)->tts = [[GDTTTS alloc] init];
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DisplayServerAppleEmbedded::tts_is_speaking() const {
|
||||||
|
if (unlikely(!tts)) {
|
||||||
|
initialize_tts();
|
||||||
|
}
|
||||||
|
ERR_FAIL_NULL_V(tts, false);
|
||||||
|
return [tts isSpeaking];
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DisplayServerAppleEmbedded::tts_is_paused() const {
|
||||||
|
if (unlikely(!tts)) {
|
||||||
|
initialize_tts();
|
||||||
|
}
|
||||||
|
ERR_FAIL_NULL_V(tts, false);
|
||||||
|
return [tts isPaused];
|
||||||
|
}
|
||||||
|
|
||||||
|
TypedArray<Dictionary> DisplayServerAppleEmbedded::tts_get_voices() const {
|
||||||
|
if (unlikely(!tts)) {
|
||||||
|
initialize_tts();
|
||||||
|
}
|
||||||
|
ERR_FAIL_NULL_V(tts, TypedArray<Dictionary>());
|
||||||
|
return [tts getVoices];
|
||||||
|
}
|
||||||
|
|
||||||
|
void DisplayServerAppleEmbedded::tts_speak(const String &p_text, const String &p_voice, int p_volume, float p_pitch, float p_rate, int p_utterance_id, bool p_interrupt) {
|
||||||
|
if (unlikely(!tts)) {
|
||||||
|
initialize_tts();
|
||||||
|
}
|
||||||
|
ERR_FAIL_NULL(tts);
|
||||||
|
[tts speak:p_text voice:p_voice volume:p_volume pitch:p_pitch rate:p_rate utterance_id:p_utterance_id interrupt:p_interrupt];
|
||||||
|
}
|
||||||
|
|
||||||
|
void DisplayServerAppleEmbedded::tts_pause() {
|
||||||
|
if (unlikely(!tts)) {
|
||||||
|
initialize_tts();
|
||||||
|
}
|
||||||
|
ERR_FAIL_NULL(tts);
|
||||||
|
[tts pauseSpeaking];
|
||||||
|
}
|
||||||
|
|
||||||
|
void DisplayServerAppleEmbedded::tts_resume() {
|
||||||
|
if (unlikely(!tts)) {
|
||||||
|
initialize_tts();
|
||||||
|
}
|
||||||
|
ERR_FAIL_NULL(tts);
|
||||||
|
[tts resumeSpeaking];
|
||||||
|
}
|
||||||
|
|
||||||
|
void DisplayServerAppleEmbedded::tts_stop() {
|
||||||
|
if (unlikely(!tts)) {
|
||||||
|
initialize_tts();
|
||||||
|
}
|
||||||
|
ERR_FAIL_NULL(tts);
|
||||||
|
[tts stopSpeaking];
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DisplayServerAppleEmbedded::is_dark_mode_supported() const {
|
||||||
|
if (@available(iOS 13.0, *)) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DisplayServerAppleEmbedded::is_dark_mode() const {
|
||||||
|
if (@available(iOS 13.0, *)) {
|
||||||
|
return [UITraitCollection currentTraitCollection].userInterfaceStyle == UIUserInterfaceStyleDark;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DisplayServerAppleEmbedded::set_system_theme_change_callback(const Callable &p_callable) {
|
||||||
|
system_theme_changed = p_callable;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DisplayServerAppleEmbedded::emit_system_theme_changed() {
|
||||||
|
if (system_theme_changed.is_valid()) {
|
||||||
|
Variant ret;
|
||||||
|
Callable::CallError ce;
|
||||||
|
system_theme_changed.callp(nullptr, 0, ret, ce);
|
||||||
|
if (ce.error != Callable::CallError::CALL_OK) {
|
||||||
|
ERR_PRINT(vformat("Failed to execute system theme changed callback: %s.", Variant::get_callable_error_text(system_theme_changed, nullptr, 0, ce)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rect2i DisplayServerAppleEmbedded::get_display_safe_area() const {
|
||||||
|
UIEdgeInsets insets = UIEdgeInsetsZero;
|
||||||
|
UIView *view = GDTAppDelegateService.viewController.godotView;
|
||||||
|
if ([view respondsToSelector:@selector(safeAreaInsets)]) {
|
||||||
|
insets = [view safeAreaInsets];
|
||||||
|
}
|
||||||
|
float scale = screen_get_scale();
|
||||||
|
Size2i insets_position = Size2i(insets.left, insets.top) * scale;
|
||||||
|
Size2i insets_size = Size2i(insets.left + insets.right, insets.top + insets.bottom) * scale;
|
||||||
|
return Rect2i(screen_get_position() + insets_position, screen_get_size() - insets_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
int DisplayServerAppleEmbedded::get_screen_count() const {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int DisplayServerAppleEmbedded::get_primary_screen() const {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Point2i DisplayServerAppleEmbedded::screen_get_position(int p_screen) const {
|
||||||
|
return Size2i();
|
||||||
|
}
|
||||||
|
|
||||||
|
Size2i DisplayServerAppleEmbedded::screen_get_size(int p_screen) const {
|
||||||
|
CALayer *layer = GDTAppDelegateService.viewController.godotView.renderingLayer;
|
||||||
|
|
||||||
|
if (!layer) {
|
||||||
|
return Size2i();
|
||||||
|
}
|
||||||
|
|
||||||
|
return Size2i(layer.bounds.size.width, layer.bounds.size.height) * screen_get_scale(p_screen);
|
||||||
|
}
|
||||||
|
|
||||||
|
Rect2i DisplayServerAppleEmbedded::screen_get_usable_rect(int p_screen) const {
|
||||||
|
return Rect2i(screen_get_position(p_screen), screen_get_size(p_screen));
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector<DisplayServer::WindowID> DisplayServerAppleEmbedded::get_window_list() const {
|
||||||
|
Vector<DisplayServer::WindowID> list;
|
||||||
|
list.push_back(MAIN_WINDOW_ID);
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
DisplayServer::WindowID DisplayServerAppleEmbedded::get_window_at_screen_position(const Point2i &p_position) const {
|
||||||
|
return MAIN_WINDOW_ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
int64_t DisplayServerAppleEmbedded::window_get_native_handle(HandleType p_handle_type, WindowID p_window) const {
|
||||||
|
ERR_FAIL_COND_V(p_window != MAIN_WINDOW_ID, 0);
|
||||||
|
switch (p_handle_type) {
|
||||||
|
case DISPLAY_HANDLE: {
|
||||||
|
return 0; // Not supported.
|
||||||
|
}
|
||||||
|
case WINDOW_HANDLE: {
|
||||||
|
return (int64_t)GDTAppDelegateService.viewController;
|
||||||
|
}
|
||||||
|
case WINDOW_VIEW: {
|
||||||
|
return (int64_t)GDTAppDelegateService.viewController.godotView;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DisplayServerAppleEmbedded::window_attach_instance_id(ObjectID p_instance, WindowID p_window) {
|
||||||
|
window_attached_instance_id = p_instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
ObjectID DisplayServerAppleEmbedded::window_get_attached_instance_id(WindowID p_window) const {
|
||||||
|
return window_attached_instance_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DisplayServerAppleEmbedded::window_set_title(const String &p_title, WindowID p_window) {
|
||||||
|
// Probably not supported for iOS
|
||||||
|
}
|
||||||
|
|
||||||
|
int DisplayServerAppleEmbedded::window_get_current_screen(WindowID p_window) const {
|
||||||
|
return SCREEN_OF_MAIN_WINDOW;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DisplayServerAppleEmbedded::window_set_current_screen(int p_screen, WindowID p_window) {
|
||||||
|
// Probably not supported for iOS
|
||||||
|
}
|
||||||
|
|
||||||
|
Point2i DisplayServerAppleEmbedded::window_get_position(WindowID p_window) const {
|
||||||
|
return Point2i();
|
||||||
|
}
|
||||||
|
|
||||||
|
Point2i DisplayServerAppleEmbedded::window_get_position_with_decorations(WindowID p_window) const {
|
||||||
|
return Point2i();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DisplayServerAppleEmbedded::window_set_position(const Point2i &p_position, WindowID p_window) {
|
||||||
|
// Probably not supported for single window iOS app
|
||||||
|
}
|
||||||
|
|
||||||
|
void DisplayServerAppleEmbedded::window_set_transient(WindowID p_window, WindowID p_parent) {
|
||||||
|
// Probably not supported for iOS
|
||||||
|
}
|
||||||
|
|
||||||
|
void DisplayServerAppleEmbedded::window_set_max_size(const Size2i p_size, WindowID p_window) {
|
||||||
|
// Probably not supported for iOS
|
||||||
|
}
|
||||||
|
|
||||||
|
Size2i DisplayServerAppleEmbedded::window_get_max_size(WindowID p_window) const {
|
||||||
|
return Size2i();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DisplayServerAppleEmbedded::window_set_min_size(const Size2i p_size, WindowID p_window) {
|
||||||
|
// Probably not supported for iOS
|
||||||
|
}
|
||||||
|
|
||||||
|
Size2i DisplayServerAppleEmbedded::window_get_min_size(WindowID p_window) const {
|
||||||
|
return Size2i();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DisplayServerAppleEmbedded::window_set_size(const Size2i p_size, WindowID p_window) {
|
||||||
|
// Probably not supported for iOS
|
||||||
|
}
|
||||||
|
|
||||||
|
Size2i DisplayServerAppleEmbedded::window_get_size(WindowID p_window) const {
|
||||||
|
id<UIApplicationDelegate> appDelegate = [[UIApplication sharedApplication] delegate];
|
||||||
|
CGRect windowBounds = appDelegate.window.bounds;
|
||||||
|
return Size2i(windowBounds.size.width, windowBounds.size.height) * screen_get_max_scale();
|
||||||
|
}
|
||||||
|
|
||||||
|
Size2i DisplayServerAppleEmbedded::window_get_size_with_decorations(WindowID p_window) const {
|
||||||
|
return window_get_size(p_window);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DisplayServerAppleEmbedded::window_set_mode(WindowMode p_mode, WindowID p_window) {
|
||||||
|
// Probably not supported for iOS
|
||||||
|
}
|
||||||
|
|
||||||
|
DisplayServer::WindowMode DisplayServerAppleEmbedded::window_get_mode(WindowID p_window) const {
|
||||||
|
return WindowMode::WINDOW_MODE_FULLSCREEN;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DisplayServerAppleEmbedded::window_is_maximize_allowed(WindowID p_window) const {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DisplayServerAppleEmbedded::window_set_flag(WindowFlags p_flag, bool p_enabled, WindowID p_window) {
|
||||||
|
// Probably not supported for iOS
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DisplayServerAppleEmbedded::window_get_flag(WindowFlags p_flag, WindowID p_window) const {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DisplayServerAppleEmbedded::window_request_attention(WindowID p_window) {
|
||||||
|
// Probably not supported for iOS
|
||||||
|
}
|
||||||
|
|
||||||
|
void DisplayServerAppleEmbedded::window_move_to_foreground(WindowID p_window) {
|
||||||
|
// Probably not supported for iOS
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DisplayServerAppleEmbedded::window_is_focused(WindowID p_window) const {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
float DisplayServerAppleEmbedded::screen_get_max_scale() const {
|
||||||
|
return screen_get_scale(SCREEN_OF_MAIN_WINDOW);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DisplayServerAppleEmbedded::screen_set_orientation(DisplayServer::ScreenOrientation p_orientation, int p_screen) {
|
||||||
|
screen_orientation = p_orientation;
|
||||||
|
if (@available(iOS 16.0, *)) {
|
||||||
|
[GDTAppDelegateService.viewController setNeedsUpdateOfSupportedInterfaceOrientations];
|
||||||
|
}
|
||||||
|
#if !defined(VISIONOS_ENABLED)
|
||||||
|
else {
|
||||||
|
[UIViewController attemptRotationToDeviceOrientation];
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
DisplayServer::ScreenOrientation DisplayServerAppleEmbedded::screen_get_orientation(int p_screen) const {
|
||||||
|
return screen_orientation;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DisplayServerAppleEmbedded::window_can_draw(WindowID p_window) const {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DisplayServerAppleEmbedded::can_any_window_draw() const {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DisplayServerAppleEmbedded::is_touchscreen_available() const {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
_FORCE_INLINE_ int _convert_utf32_offset_to_utf16(const String &p_existing_text, int p_pos) {
|
||||||
|
int limit = p_pos;
|
||||||
|
for (int i = 0; i < MIN(p_existing_text.length(), p_pos); i++) {
|
||||||
|
if (p_existing_text[i] > 0xffff) {
|
||||||
|
limit++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return limit;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DisplayServerAppleEmbedded::virtual_keyboard_show(const String &p_existing_text, const Rect2 &p_screen_rect, VirtualKeyboardType p_type, int p_max_length, int p_cursor_start, int p_cursor_end) {
|
||||||
|
NSString *existingString = [[NSString alloc] initWithUTF8String:p_existing_text.utf8().get_data()];
|
||||||
|
|
||||||
|
GDTAppDelegateService.viewController.keyboardView.keyboardType = UIKeyboardTypeDefault;
|
||||||
|
GDTAppDelegateService.viewController.keyboardView.textContentType = nil;
|
||||||
|
switch (p_type) {
|
||||||
|
case KEYBOARD_TYPE_DEFAULT: {
|
||||||
|
GDTAppDelegateService.viewController.keyboardView.keyboardType = UIKeyboardTypeDefault;
|
||||||
|
} break;
|
||||||
|
case KEYBOARD_TYPE_MULTILINE: {
|
||||||
|
GDTAppDelegateService.viewController.keyboardView.keyboardType = UIKeyboardTypeDefault;
|
||||||
|
} break;
|
||||||
|
case KEYBOARD_TYPE_NUMBER: {
|
||||||
|
GDTAppDelegateService.viewController.keyboardView.keyboardType = UIKeyboardTypeNumberPad;
|
||||||
|
} break;
|
||||||
|
case KEYBOARD_TYPE_NUMBER_DECIMAL: {
|
||||||
|
GDTAppDelegateService.viewController.keyboardView.keyboardType = UIKeyboardTypeDecimalPad;
|
||||||
|
} break;
|
||||||
|
case KEYBOARD_TYPE_PHONE: {
|
||||||
|
GDTAppDelegateService.viewController.keyboardView.keyboardType = UIKeyboardTypePhonePad;
|
||||||
|
GDTAppDelegateService.viewController.keyboardView.textContentType = UITextContentTypeTelephoneNumber;
|
||||||
|
} break;
|
||||||
|
case KEYBOARD_TYPE_EMAIL_ADDRESS: {
|
||||||
|
GDTAppDelegateService.viewController.keyboardView.keyboardType = UIKeyboardTypeEmailAddress;
|
||||||
|
GDTAppDelegateService.viewController.keyboardView.textContentType = UITextContentTypeEmailAddress;
|
||||||
|
} break;
|
||||||
|
case KEYBOARD_TYPE_PASSWORD: {
|
||||||
|
GDTAppDelegateService.viewController.keyboardView.keyboardType = UIKeyboardTypeDefault;
|
||||||
|
GDTAppDelegateService.viewController.keyboardView.textContentType = UITextContentTypePassword;
|
||||||
|
} break;
|
||||||
|
case KEYBOARD_TYPE_URL: {
|
||||||
|
GDTAppDelegateService.viewController.keyboardView.keyboardType = UIKeyboardTypeWebSearch;
|
||||||
|
GDTAppDelegateService.viewController.keyboardView.textContentType = UITextContentTypeURL;
|
||||||
|
} break;
|
||||||
|
}
|
||||||
|
|
||||||
|
[GDTAppDelegateService.viewController.keyboardView
|
||||||
|
becomeFirstResponderWithString:existingString
|
||||||
|
cursorStart:_convert_utf32_offset_to_utf16(p_existing_text, p_cursor_start)
|
||||||
|
cursorEnd:_convert_utf32_offset_to_utf16(p_existing_text, p_cursor_end)];
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DisplayServerAppleEmbedded::is_keyboard_active() const {
|
||||||
|
return [GDTAppDelegateService.viewController.keyboardView isFirstResponder];
|
||||||
|
}
|
||||||
|
|
||||||
|
void DisplayServerAppleEmbedded::virtual_keyboard_hide() {
|
||||||
|
[GDTAppDelegateService.viewController.keyboardView resignFirstResponder];
|
||||||
|
}
|
||||||
|
|
||||||
|
void DisplayServerAppleEmbedded::virtual_keyboard_set_height(int height) {
|
||||||
|
virtual_keyboard_height = height * screen_get_max_scale();
|
||||||
|
}
|
||||||
|
|
||||||
|
int DisplayServerAppleEmbedded::virtual_keyboard_get_height() const {
|
||||||
|
return virtual_keyboard_height;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DisplayServerAppleEmbedded::has_hardware_keyboard() const {
|
||||||
|
if (@available(iOS 14.0, *)) {
|
||||||
|
return [GCKeyboard coalescedKeyboard];
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DisplayServerAppleEmbedded::clipboard_set(const String &p_text) {
|
||||||
|
[UIPasteboard generalPasteboard].string = [NSString stringWithUTF8String:p_text.utf8().get_data()];
|
||||||
|
}
|
||||||
|
|
||||||
|
String DisplayServerAppleEmbedded::clipboard_get() const {
|
||||||
|
NSString *text = [UIPasteboard generalPasteboard].string;
|
||||||
|
|
||||||
|
return String::utf8([text UTF8String]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DisplayServerAppleEmbedded::screen_set_keep_on(bool p_enable) {
|
||||||
|
[UIApplication sharedApplication].idleTimerDisabled = p_enable;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DisplayServerAppleEmbedded::screen_is_kept_on() const {
|
||||||
|
return [UIApplication sharedApplication].idleTimerDisabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DisplayServerAppleEmbedded::resize_window(CGSize viewSize) {
|
||||||
|
Size2i size = Size2i(viewSize.width, viewSize.height) * screen_get_max_scale();
|
||||||
|
|
||||||
|
#if defined(RD_ENABLED)
|
||||||
|
if (rendering_context) {
|
||||||
|
rendering_context->window_set_size(MAIN_WINDOW_ID, size.x, size.y);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
Variant resize_rect = Rect2i(Point2i(), size);
|
||||||
|
_window_callback(window_resize_callback, resize_rect);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DisplayServerAppleEmbedded::window_set_vsync_mode(DisplayServer::VSyncMode p_vsync_mode, WindowID p_window) {
|
||||||
|
_THREAD_SAFE_METHOD_
|
||||||
|
#if defined(RD_ENABLED)
|
||||||
|
if (rendering_context) {
|
||||||
|
rendering_context->window_set_vsync_mode(p_window, p_vsync_mode);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
DisplayServer::VSyncMode DisplayServerAppleEmbedded::window_get_vsync_mode(WindowID p_window) const {
|
||||||
|
_THREAD_SAFE_METHOD_
|
||||||
|
#if defined(RD_ENABLED)
|
||||||
|
if (rendering_context) {
|
||||||
|
return rendering_context->window_get_vsync_mode(p_window);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return DisplayServer::VSYNC_ENABLED;
|
||||||
|
}
|
||||||
@@ -32,12 +32,12 @@
|
|||||||
|
|
||||||
#import <UIKit/UIKit.h>
|
#import <UIKit/UIKit.h>
|
||||||
|
|
||||||
typedef NSObject<UIApplicationDelegate> ApplicationDelegateService;
|
typedef NSObject<UIApplicationDelegate> GDTAppDelegateServiceProtocol;
|
||||||
|
|
||||||
@interface GodotApplicationDelegate : NSObject <UIApplicationDelegate>
|
@interface GDTApplicationDelegate : NSObject <UIApplicationDelegate>
|
||||||
|
|
||||||
@property(class, readonly, strong) NSArray<ApplicationDelegateService *> *services;
|
@property(class, readonly, strong) NSArray<GDTAppDelegateServiceProtocol *> *services;
|
||||||
|
|
||||||
+ (void)addService:(ApplicationDelegateService *)service;
|
+ (void)addService:(GDTAppDelegateServiceProtocol *)service;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
/* godot_app_delegate.m */
|
/* godot_app_delegate.mm */
|
||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
/* This file is part of: */
|
/* This file is part of: */
|
||||||
/* GODOT ENGINE */
|
/* GODOT ENGINE */
|
||||||
@@ -30,26 +30,22 @@
|
|||||||
|
|
||||||
#import "godot_app_delegate.h"
|
#import "godot_app_delegate.h"
|
||||||
|
|
||||||
#import "app_delegate.h"
|
#import "app_delegate_service.h"
|
||||||
|
|
||||||
@interface GodotApplicationDelegate ()
|
@implementation GDTApplicationDelegate
|
||||||
|
|
||||||
@end
|
static NSMutableArray<GDTAppDelegateServiceProtocol *> *services = nil;
|
||||||
|
|
||||||
@implementation GodotApplicationDelegate
|
+ (NSArray<GDTAppDelegateServiceProtocol *> *)services {
|
||||||
|
|
||||||
static NSMutableArray<ApplicationDelegateService *> *services = nil;
|
|
||||||
|
|
||||||
+ (NSArray<ApplicationDelegateService *> *)services {
|
|
||||||
return services;
|
return services;
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (void)load {
|
+ (void)load {
|
||||||
services = [NSMutableArray new];
|
services = [NSMutableArray new];
|
||||||
[services addObject:[AppDelegate new]];
|
[services addObject:[GDTAppDelegateService new]];
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (void)addService:(ApplicationDelegateService *)service {
|
+ (void)addService:(GDTAppDelegateServiceProtocol *)service {
|
||||||
if (!services || !service) {
|
if (!services || !service) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -63,7 +59,7 @@ static NSMutableArray<ApplicationDelegateService *> *services = nil;
|
|||||||
- (UIWindow *)window {
|
- (UIWindow *)window {
|
||||||
UIWindow *result = nil;
|
UIWindow *result = nil;
|
||||||
|
|
||||||
for (ApplicationDelegateService *service in services) {
|
for (GDTAppDelegateServiceProtocol *service in services) {
|
||||||
if (![service respondsToSelector:_cmd]) {
|
if (![service respondsToSelector:_cmd]) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -83,7 +79,7 @@ static NSMutableArray<ApplicationDelegateService *> *services = nil;
|
|||||||
- (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary<UIApplicationLaunchOptionsKey, id> *)launchOptions {
|
- (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary<UIApplicationLaunchOptionsKey, id> *)launchOptions {
|
||||||
BOOL result = NO;
|
BOOL result = NO;
|
||||||
|
|
||||||
for (ApplicationDelegateService *service in services) {
|
for (GDTAppDelegateServiceProtocol *service in services) {
|
||||||
if (![service respondsToSelector:_cmd]) {
|
if (![service respondsToSelector:_cmd]) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -99,7 +95,7 @@ static NSMutableArray<ApplicationDelegateService *> *services = nil;
|
|||||||
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary<UIApplicationLaunchOptionsKey, id> *)launchOptions {
|
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary<UIApplicationLaunchOptionsKey, id> *)launchOptions {
|
||||||
BOOL result = NO;
|
BOOL result = NO;
|
||||||
|
|
||||||
for (ApplicationDelegateService *service in services) {
|
for (GDTAppDelegateServiceProtocol *service in services) {
|
||||||
if (![service respondsToSelector:_cmd]) {
|
if (![service respondsToSelector:_cmd]) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -125,7 +121,7 @@ static NSMutableArray<ApplicationDelegateService *> *services = nil;
|
|||||||
// MARK: Life-Cycle
|
// MARK: Life-Cycle
|
||||||
|
|
||||||
- (void)applicationDidBecomeActive:(UIApplication *)application {
|
- (void)applicationDidBecomeActive:(UIApplication *)application {
|
||||||
for (ApplicationDelegateService *service in services) {
|
for (GDTAppDelegateServiceProtocol *service in services) {
|
||||||
if (![service respondsToSelector:_cmd]) {
|
if (![service respondsToSelector:_cmd]) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -135,7 +131,7 @@ static NSMutableArray<ApplicationDelegateService *> *services = nil;
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (void)applicationWillResignActive:(UIApplication *)application {
|
- (void)applicationWillResignActive:(UIApplication *)application {
|
||||||
for (ApplicationDelegateService *service in services) {
|
for (GDTAppDelegateServiceProtocol *service in services) {
|
||||||
if (![service respondsToSelector:_cmd]) {
|
if (![service respondsToSelector:_cmd]) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -145,7 +141,7 @@ static NSMutableArray<ApplicationDelegateService *> *services = nil;
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (void)applicationDidEnterBackground:(UIApplication *)application {
|
- (void)applicationDidEnterBackground:(UIApplication *)application {
|
||||||
for (ApplicationDelegateService *service in services) {
|
for (GDTAppDelegateServiceProtocol *service in services) {
|
||||||
if (![service respondsToSelector:_cmd]) {
|
if (![service respondsToSelector:_cmd]) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -155,7 +151,7 @@ static NSMutableArray<ApplicationDelegateService *> *services = nil;
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (void)applicationWillEnterForeground:(UIApplication *)application {
|
- (void)applicationWillEnterForeground:(UIApplication *)application {
|
||||||
for (ApplicationDelegateService *service in services) {
|
for (GDTAppDelegateServiceProtocol *service in services) {
|
||||||
if (![service respondsToSelector:_cmd]) {
|
if (![service respondsToSelector:_cmd]) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -165,7 +161,7 @@ static NSMutableArray<ApplicationDelegateService *> *services = nil;
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (void)applicationWillTerminate:(UIApplication *)application {
|
- (void)applicationWillTerminate:(UIApplication *)application {
|
||||||
for (ApplicationDelegateService *service in services) {
|
for (GDTAppDelegateServiceProtocol *service in services) {
|
||||||
if (![service respondsToSelector:_cmd]) {
|
if (![service respondsToSelector:_cmd]) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -177,7 +173,7 @@ static NSMutableArray<ApplicationDelegateService *> *services = nil;
|
|||||||
// MARK: Environment Changes
|
// MARK: Environment Changes
|
||||||
|
|
||||||
- (void)applicationProtectedDataDidBecomeAvailable:(UIApplication *)application {
|
- (void)applicationProtectedDataDidBecomeAvailable:(UIApplication *)application {
|
||||||
for (ApplicationDelegateService *service in services) {
|
for (GDTAppDelegateServiceProtocol *service in services) {
|
||||||
if (![service respondsToSelector:_cmd]) {
|
if (![service respondsToSelector:_cmd]) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -187,7 +183,7 @@ static NSMutableArray<ApplicationDelegateService *> *services = nil;
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (void)applicationProtectedDataWillBecomeUnavailable:(UIApplication *)application {
|
- (void)applicationProtectedDataWillBecomeUnavailable:(UIApplication *)application {
|
||||||
for (ApplicationDelegateService *service in services) {
|
for (GDTAppDelegateServiceProtocol *service in services) {
|
||||||
if (![service respondsToSelector:_cmd]) {
|
if (![service respondsToSelector:_cmd]) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -197,7 +193,7 @@ static NSMutableArray<ApplicationDelegateService *> *services = nil;
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application {
|
- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application {
|
||||||
for (ApplicationDelegateService *service in services) {
|
for (GDTAppDelegateServiceProtocol *service in services) {
|
||||||
if (![service respondsToSelector:_cmd]) {
|
if (![service respondsToSelector:_cmd]) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -207,7 +203,7 @@ static NSMutableArray<ApplicationDelegateService *> *services = nil;
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (void)applicationSignificantTimeChange:(UIApplication *)application {
|
- (void)applicationSignificantTimeChange:(UIApplication *)application {
|
||||||
for (ApplicationDelegateService *service in services) {
|
for (GDTAppDelegateServiceProtocol *service in services) {
|
||||||
if (![service respondsToSelector:_cmd]) {
|
if (![service respondsToSelector:_cmd]) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -221,7 +217,7 @@ static NSMutableArray<ApplicationDelegateService *> *services = nil;
|
|||||||
- (BOOL)application:(UIApplication *)application shouldSaveSecureApplicationState:(NSCoder *)coder API_AVAILABLE(ios(13.2)) {
|
- (BOOL)application:(UIApplication *)application shouldSaveSecureApplicationState:(NSCoder *)coder API_AVAILABLE(ios(13.2)) {
|
||||||
BOOL result = NO;
|
BOOL result = NO;
|
||||||
|
|
||||||
for (ApplicationDelegateService *service in services) {
|
for (GDTAppDelegateServiceProtocol *service in services) {
|
||||||
if (![service respondsToSelector:_cmd]) {
|
if (![service respondsToSelector:_cmd]) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -237,7 +233,7 @@ static NSMutableArray<ApplicationDelegateService *> *services = nil;
|
|||||||
- (BOOL)application:(UIApplication *)application shouldRestoreSecureApplicationState:(NSCoder *)coder API_AVAILABLE(ios(13.2)) {
|
- (BOOL)application:(UIApplication *)application shouldRestoreSecureApplicationState:(NSCoder *)coder API_AVAILABLE(ios(13.2)) {
|
||||||
BOOL result = NO;
|
BOOL result = NO;
|
||||||
|
|
||||||
for (ApplicationDelegateService *service in services) {
|
for (GDTAppDelegateServiceProtocol *service in services) {
|
||||||
if (![service respondsToSelector:_cmd]) {
|
if (![service respondsToSelector:_cmd]) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -251,7 +247,7 @@ static NSMutableArray<ApplicationDelegateService *> *services = nil;
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (UIViewController *)application:(UIApplication *)application viewControllerWithRestorationIdentifierPath:(NSArray<NSString *> *)identifierComponents coder:(NSCoder *)coder {
|
- (UIViewController *)application:(UIApplication *)application viewControllerWithRestorationIdentifierPath:(NSArray<NSString *> *)identifierComponents coder:(NSCoder *)coder {
|
||||||
for (ApplicationDelegateService *service in services) {
|
for (GDTAppDelegateServiceProtocol *service in services) {
|
||||||
if (![service respondsToSelector:_cmd]) {
|
if (![service respondsToSelector:_cmd]) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -267,7 +263,7 @@ static NSMutableArray<ApplicationDelegateService *> *services = nil;
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (void)application:(UIApplication *)application willEncodeRestorableStateWithCoder:(NSCoder *)coder {
|
- (void)application:(UIApplication *)application willEncodeRestorableStateWithCoder:(NSCoder *)coder {
|
||||||
for (ApplicationDelegateService *service in services) {
|
for (GDTAppDelegateServiceProtocol *service in services) {
|
||||||
if (![service respondsToSelector:_cmd]) {
|
if (![service respondsToSelector:_cmd]) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -277,7 +273,7 @@ static NSMutableArray<ApplicationDelegateService *> *services = nil;
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (void)application:(UIApplication *)application didDecodeRestorableStateWithCoder:(NSCoder *)coder {
|
- (void)application:(UIApplication *)application didDecodeRestorableStateWithCoder:(NSCoder *)coder {
|
||||||
for (ApplicationDelegateService *service in services) {
|
for (GDTAppDelegateServiceProtocol *service in services) {
|
||||||
if (![service respondsToSelector:_cmd]) {
|
if (![service respondsToSelector:_cmd]) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -289,7 +285,7 @@ static NSMutableArray<ApplicationDelegateService *> *services = nil;
|
|||||||
// MARK: Download Data in Background
|
// MARK: Download Data in Background
|
||||||
|
|
||||||
- (void)application:(UIApplication *)application handleEventsForBackgroundURLSession:(NSString *)identifier completionHandler:(void (^)(void))completionHandler {
|
- (void)application:(UIApplication *)application handleEventsForBackgroundURLSession:(NSString *)identifier completionHandler:(void (^)(void))completionHandler {
|
||||||
for (ApplicationDelegateService *service in services) {
|
for (GDTAppDelegateServiceProtocol *service in services) {
|
||||||
if (![service respondsToSelector:_cmd]) {
|
if (![service respondsToSelector:_cmd]) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -309,7 +305,7 @@ static NSMutableArray<ApplicationDelegateService *> *services = nil;
|
|||||||
- (BOOL)application:(UIApplication *)application willContinueUserActivityWithType:(NSString *)userActivityType {
|
- (BOOL)application:(UIApplication *)application willContinueUserActivityWithType:(NSString *)userActivityType {
|
||||||
BOOL result = NO;
|
BOOL result = NO;
|
||||||
|
|
||||||
for (ApplicationDelegateService *service in services) {
|
for (GDTAppDelegateServiceProtocol *service in services) {
|
||||||
if (![service respondsToSelector:_cmd]) {
|
if (![service respondsToSelector:_cmd]) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -325,7 +321,7 @@ static NSMutableArray<ApplicationDelegateService *> *services = nil;
|
|||||||
- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray<id<UIUserActivityRestoring>> *restorableObjects))restorationHandler {
|
- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray<id<UIUserActivityRestoring>> *restorableObjects))restorationHandler {
|
||||||
BOOL result = NO;
|
BOOL result = NO;
|
||||||
|
|
||||||
for (ApplicationDelegateService *service in services) {
|
for (GDTAppDelegateServiceProtocol *service in services) {
|
||||||
if (![service respondsToSelector:_cmd]) {
|
if (![service respondsToSelector:_cmd]) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -339,7 +335,7 @@ static NSMutableArray<ApplicationDelegateService *> *services = nil;
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (void)application:(UIApplication *)application didUpdateUserActivity:(NSUserActivity *)userActivity {
|
- (void)application:(UIApplication *)application didUpdateUserActivity:(NSUserActivity *)userActivity {
|
||||||
for (ApplicationDelegateService *service in services) {
|
for (GDTAppDelegateServiceProtocol *service in services) {
|
||||||
if (![service respondsToSelector:_cmd]) {
|
if (![service respondsToSelector:_cmd]) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -349,7 +345,7 @@ static NSMutableArray<ApplicationDelegateService *> *services = nil;
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (void)application:(UIApplication *)application didFailToContinueUserActivityWithType:(NSString *)userActivityType error:(NSError *)error {
|
- (void)application:(UIApplication *)application didFailToContinueUserActivityWithType:(NSString *)userActivityType error:(NSError *)error {
|
||||||
for (ApplicationDelegateService *service in services) {
|
for (GDTAppDelegateServiceProtocol *service in services) {
|
||||||
if (![service respondsToSelector:_cmd]) {
|
if (![service respondsToSelector:_cmd]) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -359,7 +355,7 @@ static NSMutableArray<ApplicationDelegateService *> *services = nil;
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (void)application:(UIApplication *)application performActionForShortcutItem:(UIApplicationShortcutItem *)shortcutItem completionHandler:(void (^)(BOOL succeeded))completionHandler {
|
- (void)application:(UIApplication *)application performActionForShortcutItem:(UIApplicationShortcutItem *)shortcutItem completionHandler:(void (^)(BOOL succeeded))completionHandler {
|
||||||
for (ApplicationDelegateService *service in services) {
|
for (GDTAppDelegateServiceProtocol *service in services) {
|
||||||
if (![service respondsToSelector:_cmd]) {
|
if (![service respondsToSelector:_cmd]) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -371,7 +367,7 @@ static NSMutableArray<ApplicationDelegateService *> *services = nil;
|
|||||||
// MARK: WatchKit
|
// MARK: WatchKit
|
||||||
|
|
||||||
- (void)application:(UIApplication *)application handleWatchKitExtensionRequest:(NSDictionary *)userInfo reply:(void (^)(NSDictionary *replyInfo))reply {
|
- (void)application:(UIApplication *)application handleWatchKitExtensionRequest:(NSDictionary *)userInfo reply:(void (^)(NSDictionary *replyInfo))reply {
|
||||||
for (ApplicationDelegateService *service in services) {
|
for (GDTAppDelegateServiceProtocol *service in services) {
|
||||||
if (![service respondsToSelector:_cmd]) {
|
if (![service respondsToSelector:_cmd]) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -383,7 +379,7 @@ static NSMutableArray<ApplicationDelegateService *> *services = nil;
|
|||||||
// MARK: HealthKit
|
// MARK: HealthKit
|
||||||
|
|
||||||
- (void)applicationShouldRequestHealthAuthorization:(UIApplication *)application {
|
- (void)applicationShouldRequestHealthAuthorization:(UIApplication *)application {
|
||||||
for (ApplicationDelegateService *service in services) {
|
for (GDTAppDelegateServiceProtocol *service in services) {
|
||||||
if (![service respondsToSelector:_cmd]) {
|
if (![service respondsToSelector:_cmd]) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -395,7 +391,7 @@ static NSMutableArray<ApplicationDelegateService *> *services = nil;
|
|||||||
// MARK: Opening an URL
|
// MARK: Opening an URL
|
||||||
|
|
||||||
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey, id> *)options {
|
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey, id> *)options {
|
||||||
for (ApplicationDelegateService *service in services) {
|
for (GDTAppDelegateServiceProtocol *service in services) {
|
||||||
if (![service respondsToSelector:_cmd]) {
|
if (![service respondsToSelector:_cmd]) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -413,7 +409,7 @@ static NSMutableArray<ApplicationDelegateService *> *services = nil;
|
|||||||
- (BOOL)application:(UIApplication *)application shouldAllowExtensionPointIdentifier:(UIApplicationExtensionPointIdentifier)extensionPointIdentifier {
|
- (BOOL)application:(UIApplication *)application shouldAllowExtensionPointIdentifier:(UIApplicationExtensionPointIdentifier)extensionPointIdentifier {
|
||||||
BOOL result = NO;
|
BOOL result = NO;
|
||||||
|
|
||||||
for (ApplicationDelegateService *service in services) {
|
for (GDTAppDelegateServiceProtocol *service in services) {
|
||||||
if (![service respondsToSelector:_cmd]) {
|
if (![service respondsToSelector:_cmd]) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -429,7 +425,7 @@ static NSMutableArray<ApplicationDelegateService *> *services = nil;
|
|||||||
// MARK: SiriKit
|
// MARK: SiriKit
|
||||||
|
|
||||||
- (id)application:(UIApplication *)application handlerForIntent:(INIntent *)intent API_AVAILABLE(ios(14.0)) {
|
- (id)application:(UIApplication *)application handlerForIntent:(INIntent *)intent API_AVAILABLE(ios(14.0)) {
|
||||||
for (ApplicationDelegateService *service in services) {
|
for (GDTAppDelegateServiceProtocol *service in services) {
|
||||||
if (![service respondsToSelector:_cmd]) {
|
if (![service respondsToSelector:_cmd]) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -447,7 +443,7 @@ static NSMutableArray<ApplicationDelegateService *> *services = nil;
|
|||||||
// MARK: CloudKit
|
// MARK: CloudKit
|
||||||
|
|
||||||
- (void)application:(UIApplication *)application userDidAcceptCloudKitShareWithMetadata:(CKShareMetadata *)cloudKitShareMetadata {
|
- (void)application:(UIApplication *)application userDidAcceptCloudKitShareWithMetadata:(CKShareMetadata *)cloudKitShareMetadata {
|
||||||
for (ApplicationDelegateService *service in services) {
|
for (GDTAppDelegateServiceProtocol *service in services) {
|
||||||
if (![service respondsToSelector:_cmd]) {
|
if (![service respondsToSelector:_cmd]) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
/* godot_view.h */
|
/* godot_view_apple_embedded.h */
|
||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
/* This file is part of: */
|
/* This file is part of: */
|
||||||
/* GODOT ENGINE */
|
/* GODOT ENGINE */
|
||||||
@@ -34,31 +34,39 @@
|
|||||||
|
|
||||||
class String;
|
class String;
|
||||||
|
|
||||||
@class GodotView;
|
@class GDTView;
|
||||||
@protocol DisplayLayer;
|
@protocol GDTDisplayLayer;
|
||||||
@protocol GodotViewRendererProtocol;
|
@protocol GDTViewRendererProtocol;
|
||||||
|
|
||||||
@protocol GodotViewDelegate
|
@protocol GDTViewDelegate
|
||||||
|
|
||||||
- (BOOL)godotViewFinishedSetup:(GodotView *)view;
|
- (BOOL)godotViewFinishedSetup:(GDTView *)view;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@interface GodotView : UIView
|
@interface GDTView : UIView
|
||||||
|
|
||||||
@property(assign, nonatomic) id<GodotViewRendererProtocol> renderer;
|
@property(assign, nonatomic) id<GDTViewRendererProtocol> renderer;
|
||||||
@property(assign, nonatomic) id<GodotViewDelegate> delegate;
|
@property(assign, nonatomic) id<GDTViewDelegate> delegate;
|
||||||
|
|
||||||
@property(assign, readonly, nonatomic) BOOL isActive;
|
@property(assign, readonly, nonatomic) BOOL isActive;
|
||||||
|
|
||||||
@property(assign, nonatomic) BOOL useCADisplayLink;
|
@property(assign, nonatomic) BOOL useCADisplayLink;
|
||||||
@property(strong, readonly, nonatomic) CALayer<DisplayLayer> *renderingLayer;
|
@property(strong, readonly, nonatomic) CALayer<GDTDisplayLayer> *renderingLayer;
|
||||||
@property(assign, readonly, nonatomic) BOOL canRender;
|
@property(assign, readonly, nonatomic) BOOL canRender;
|
||||||
|
|
||||||
@property(assign, nonatomic) NSTimeInterval renderingInterval;
|
@property(assign, nonatomic) NSTimeInterval renderingInterval;
|
||||||
|
|
||||||
- (CALayer<DisplayLayer> *)initializeRenderingForDriver:(NSString *)driverName;
|
// Can be extended by subclasses
|
||||||
|
- (void)godot_commonInit;
|
||||||
|
|
||||||
|
// Implemented in subclasses
|
||||||
|
- (CALayer<GDTDisplayLayer> *)initializeRenderingForDriver:(NSString *)driverName;
|
||||||
|
|
||||||
- (void)stopRendering;
|
- (void)stopRendering;
|
||||||
- (void)startRendering;
|
- (void)startRendering;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
// Implemented in subclasses
|
||||||
|
extern GDTView *GDTViewCreate();
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
/* godot_view.mm */
|
/* godot_view_apple_embedded.mm */
|
||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
/* This file is part of: */
|
/* This file is part of: */
|
||||||
/* GODOT ENGINE */
|
/* GODOT ENGINE */
|
||||||
@@ -28,10 +28,10 @@
|
|||||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
|
|
||||||
#import "godot_view.h"
|
#import "godot_view_apple_embedded.h"
|
||||||
|
|
||||||
#import "display_layer.h"
|
#import "display_layer_apple_embedded.h"
|
||||||
#import "display_server_ios.h"
|
#import "display_server_apple_embedded.h"
|
||||||
#import "godot_view_renderer.h"
|
#import "godot_view_renderer.h"
|
||||||
|
|
||||||
#include "core/config/project_settings.h"
|
#include "core/config/project_settings.h"
|
||||||
@@ -43,7 +43,7 @@
|
|||||||
static const int max_touches = 32;
|
static const int max_touches = 32;
|
||||||
static const float earth_gravity = 9.80665;
|
static const float earth_gravity = 9.80665;
|
||||||
|
|
||||||
@interface GodotView () {
|
@interface GDTView () {
|
||||||
UITouch *godot_touches[max_touches];
|
UITouch *godot_touches[max_touches];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -56,48 +56,17 @@ static const float earth_gravity = 9.80665;
|
|||||||
// Only used if CADisplayLink is not
|
// Only used if CADisplayLink is not
|
||||||
@property(strong, nonatomic) NSTimer *animationTimer;
|
@property(strong, nonatomic) NSTimer *animationTimer;
|
||||||
|
|
||||||
@property(strong, nonatomic) CALayer<DisplayLayer> *renderingLayer;
|
@property(strong, nonatomic) CALayer<GDTDisplayLayer> *renderingLayer;
|
||||||
|
|
||||||
@property(strong, nonatomic) CMMotionManager *motionManager;
|
@property(strong, nonatomic) CMMotionManager *motionManager;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation GodotView
|
@implementation GDTView
|
||||||
|
|
||||||
- (CALayer<DisplayLayer> *)initializeRenderingForDriver:(NSString *)driverName {
|
// Implemented in subclasses
|
||||||
if (self.renderingLayer) {
|
- (CALayer<GDTDisplayLayer> *)initializeRenderingForDriver:(NSString *)driverName {
|
||||||
return self.renderingLayer;
|
|
||||||
}
|
|
||||||
|
|
||||||
CALayer<DisplayLayer> *layer;
|
|
||||||
|
|
||||||
if ([driverName isEqualToString:@"vulkan"] || [driverName isEqualToString:@"metal"]) {
|
|
||||||
#if defined(TARGET_OS_SIMULATOR) && TARGET_OS_SIMULATOR
|
|
||||||
if (@available(iOS 13, *)) {
|
|
||||||
layer = [GodotMetalLayer layer];
|
|
||||||
} else {
|
|
||||||
return nil;
|
return nil;
|
||||||
}
|
|
||||||
#else
|
|
||||||
layer = [GodotMetalLayer layer];
|
|
||||||
#endif
|
|
||||||
} else if ([driverName isEqualToString:@"opengl3"]) {
|
|
||||||
GODOT_CLANG_WARNING_PUSH_AND_IGNORE("-Wdeprecated-declarations") // OpenGL is deprecated in iOS 12.0.
|
|
||||||
layer = [GodotOpenGLLayer layer];
|
|
||||||
GODOT_CLANG_WARNING_POP
|
|
||||||
} else {
|
|
||||||
return nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
layer.frame = self.bounds;
|
|
||||||
layer.contentsScale = self.contentScaleFactor;
|
|
||||||
|
|
||||||
[self.layer addSublayer:layer];
|
|
||||||
self.renderingLayer = layer;
|
|
||||||
|
|
||||||
[layer initializeDisplayLayer];
|
|
||||||
|
|
||||||
return self.renderingLayer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (instancetype)initWithCoder:(NSCoder *)coder {
|
- (instancetype)initWithCoder:(NSCoder *)coder {
|
||||||
@@ -148,7 +117,13 @@ static const float earth_gravity = 9.80665;
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (void)godot_commonInit {
|
- (void)godot_commonInit {
|
||||||
|
#if !defined(VISIONOS_ENABLED)
|
||||||
self.contentScaleFactor = [UIScreen mainScreen].scale;
|
self.contentScaleFactor = [UIScreen mainScreen].scale;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (@available(iOS 17.0, *)) {
|
||||||
|
[self registerForTraitChanges:@[ [UITraitUserInterfaceStyle class] ] withTarget:self action:@selector(traitCollectionDidChangeWithView:previousTraitCollection:)];
|
||||||
|
}
|
||||||
|
|
||||||
[self initTouches];
|
[self initTouches];
|
||||||
|
|
||||||
@@ -167,7 +142,7 @@ static const float earth_gravity = 9.80665;
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (void)system_theme_changed {
|
- (void)system_theme_changed {
|
||||||
DisplayServerIOS *ds = (DisplayServerIOS *)DisplayServer::get_singleton();
|
DisplayServerAppleEmbedded *ds = (DisplayServerAppleEmbedded *)DisplayServer::get_singleton();
|
||||||
if (ds) {
|
if (ds) {
|
||||||
ds->emit_system_theme_changed();
|
ds->emit_system_theme_changed();
|
||||||
}
|
}
|
||||||
@@ -175,8 +150,16 @@ static const float earth_gravity = 9.80665;
|
|||||||
|
|
||||||
- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection {
|
- (void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection {
|
||||||
if (@available(iOS 13.0, *)) {
|
if (@available(iOS 13.0, *)) {
|
||||||
|
#if !defined(VISIONOS_ENABLED)
|
||||||
[super traitCollectionDidChange:previousTraitCollection];
|
[super traitCollectionDidChange:previousTraitCollection];
|
||||||
|
#endif
|
||||||
|
[self traitCollectionDidChangeWithView:self
|
||||||
|
previousTraitCollection:previousTraitCollection];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)traitCollectionDidChangeWithView:(UIView *)view previousTraitCollection:(UITraitCollection *)previousTraitCollection {
|
||||||
|
if (@available(iOS 13.0, *)) {
|
||||||
if ([UITraitCollection currentTraitCollection].userInterfaceStyle != previousTraitCollection.userInterfaceStyle) {
|
if ([UITraitCollection currentTraitCollection].userInterfaceStyle != previousTraitCollection.userInterfaceStyle) {
|
||||||
[self system_theme_changed];
|
[self system_theme_changed];
|
||||||
}
|
}
|
||||||
@@ -293,8 +276,8 @@ static const float earth_gravity = 9.80665;
|
|||||||
self.renderingLayer.frame = self.bounds;
|
self.renderingLayer.frame = self.bounds;
|
||||||
[self.renderingLayer layoutDisplayLayer];
|
[self.renderingLayer layoutDisplayLayer];
|
||||||
|
|
||||||
if (DisplayServerIOS::get_singleton()) {
|
if (DisplayServerAppleEmbedded::get_singleton()) {
|
||||||
DisplayServerIOS::get_singleton()->resize_window(self.bounds.size);
|
DisplayServerAppleEmbedded::get_singleton()->resize_window(self.bounds.size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -357,7 +340,7 @@ static const float earth_gravity = 9.80665;
|
|||||||
int tid = [self getTouchIDForTouch:touch];
|
int tid = [self getTouchIDForTouch:touch];
|
||||||
ERR_FAIL_COND(tid == -1);
|
ERR_FAIL_COND(tid == -1);
|
||||||
CGPoint touchPoint = [touch locationInView:self];
|
CGPoint touchPoint = [touch locationInView:self];
|
||||||
DisplayServerIOS::get_singleton()->touch_press(tid, touchPoint.x * self.contentScaleFactor, touchPoint.y * self.contentScaleFactor, true, touch.tapCount > 1);
|
DisplayServerAppleEmbedded::get_singleton()->touch_press(tid, touchPoint.x * self.contentScaleFactor, touchPoint.y * self.contentScaleFactor, true, touch.tapCount > 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -369,7 +352,7 @@ static const float earth_gravity = 9.80665;
|
|||||||
CGPoint prev_point = [touch previousLocationInView:self];
|
CGPoint prev_point = [touch previousLocationInView:self];
|
||||||
CGFloat alt = [touch altitudeAngle];
|
CGFloat alt = [touch altitudeAngle];
|
||||||
CGVector azim = [touch azimuthUnitVectorInView:self];
|
CGVector azim = [touch azimuthUnitVectorInView:self];
|
||||||
DisplayServerIOS::get_singleton()->touch_drag(tid, prev_point.x * self.contentScaleFactor, prev_point.y * self.contentScaleFactor, touchPoint.x * self.contentScaleFactor, touchPoint.y * self.contentScaleFactor, [touch force] / [touch maximumPossibleForce], Vector2(azim.dx, azim.dy) * Math::cos(alt));
|
DisplayServerAppleEmbedded::get_singleton()->touch_drag(tid, prev_point.x * self.contentScaleFactor, prev_point.y * self.contentScaleFactor, touchPoint.x * self.contentScaleFactor, touchPoint.y * self.contentScaleFactor, [touch force] / [touch maximumPossibleForce], Vector2(azim.dx, azim.dy) * Math::cos(alt));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -379,7 +362,7 @@ static const float earth_gravity = 9.80665;
|
|||||||
ERR_FAIL_COND(tid == -1);
|
ERR_FAIL_COND(tid == -1);
|
||||||
[self removeTouch:touch];
|
[self removeTouch:touch];
|
||||||
CGPoint touchPoint = [touch locationInView:self];
|
CGPoint touchPoint = [touch locationInView:self];
|
||||||
DisplayServerIOS::get_singleton()->touch_press(tid, touchPoint.x * self.contentScaleFactor, touchPoint.y * self.contentScaleFactor, false, false);
|
DisplayServerAppleEmbedded::get_singleton()->touch_press(tid, touchPoint.x * self.contentScaleFactor, touchPoint.y * self.contentScaleFactor, false, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -387,7 +370,7 @@ static const float earth_gravity = 9.80665;
|
|||||||
for (UITouch *touch in touches) {
|
for (UITouch *touch in touches) {
|
||||||
int tid = [self getTouchIDForTouch:touch];
|
int tid = [self getTouchIDForTouch:touch];
|
||||||
ERR_FAIL_COND(tid == -1);
|
ERR_FAIL_COND(tid == -1);
|
||||||
DisplayServerIOS::get_singleton()->touches_canceled(tid);
|
DisplayServerAppleEmbedded::get_singleton()->touches_canceled(tid);
|
||||||
}
|
}
|
||||||
[self clearTouches];
|
[self clearTouches];
|
||||||
}
|
}
|
||||||
@@ -440,6 +423,7 @@ static const float earth_gravity = 9.80665;
|
|||||||
|
|
||||||
UIInterfaceOrientation interfaceOrientation = UIInterfaceOrientationUnknown;
|
UIInterfaceOrientation interfaceOrientation = UIInterfaceOrientationUnknown;
|
||||||
|
|
||||||
|
#if !defined(VISIONOS_ENABLED)
|
||||||
#if __IPHONE_OS_VERSION_MAX_ALLOWED < 140000
|
#if __IPHONE_OS_VERSION_MAX_ALLOWED < 140000
|
||||||
interfaceOrientation = [[UIApplication sharedApplication] statusBarOrientation];
|
interfaceOrientation = [[UIApplication sharedApplication] statusBarOrientation];
|
||||||
#else
|
#else
|
||||||
@@ -451,31 +435,34 @@ static const float earth_gravity = 9.80665;
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#else
|
||||||
|
interfaceOrientation = [UIApplication sharedApplication].delegate.window.windowScene.interfaceOrientation;
|
||||||
|
#endif
|
||||||
|
|
||||||
switch (interfaceOrientation) {
|
switch (interfaceOrientation) {
|
||||||
case UIInterfaceOrientationLandscapeLeft: {
|
case UIInterfaceOrientationLandscapeLeft: {
|
||||||
DisplayServerIOS::get_singleton()->update_gravity(Vector3(gravity.x, gravity.y, gravity.z).rotated(Vector3(0, 0, 1), -Math::PI * 0.5));
|
DisplayServerAppleEmbedded::get_singleton()->update_gravity(Vector3(gravity.x, gravity.y, gravity.z).rotated(Vector3(0, 0, 1), -Math::PI * 0.5));
|
||||||
DisplayServerIOS::get_singleton()->update_accelerometer(Vector3(acceleration.x + gravity.x, acceleration.y + gravity.y, acceleration.z + gravity.z).rotated(Vector3(0, 0, 1), -Math::PI * 0.5));
|
DisplayServerAppleEmbedded::get_singleton()->update_accelerometer(Vector3(acceleration.x + gravity.x, acceleration.y + gravity.y, acceleration.z + gravity.z).rotated(Vector3(0, 0, 1), -Math::PI * 0.5));
|
||||||
DisplayServerIOS::get_singleton()->update_magnetometer(Vector3(magnetic.x, magnetic.y, magnetic.z).rotated(Vector3(0, 0, 1), -Math::PI * 0.5));
|
DisplayServerAppleEmbedded::get_singleton()->update_magnetometer(Vector3(magnetic.x, magnetic.y, magnetic.z).rotated(Vector3(0, 0, 1), -Math::PI * 0.5));
|
||||||
DisplayServerIOS::get_singleton()->update_gyroscope(Vector3(rotation.x, rotation.y, rotation.z).rotated(Vector3(0, 0, 1), -Math::PI * 0.5));
|
DisplayServerAppleEmbedded::get_singleton()->update_gyroscope(Vector3(rotation.x, rotation.y, rotation.z).rotated(Vector3(0, 0, 1), -Math::PI * 0.5));
|
||||||
} break;
|
} break;
|
||||||
case UIInterfaceOrientationLandscapeRight: {
|
case UIInterfaceOrientationLandscapeRight: {
|
||||||
DisplayServerIOS::get_singleton()->update_gravity(Vector3(gravity.x, gravity.y, gravity.z).rotated(Vector3(0, 0, 1), Math::PI * 0.5));
|
DisplayServerAppleEmbedded::get_singleton()->update_gravity(Vector3(gravity.x, gravity.y, gravity.z).rotated(Vector3(0, 0, 1), Math::PI * 0.5));
|
||||||
DisplayServerIOS::get_singleton()->update_accelerometer(Vector3(acceleration.x + gravity.x, acceleration.y + gravity.y, acceleration.z + gravity.z).rotated(Vector3(0, 0, 1), Math::PI * 0.5));
|
DisplayServerAppleEmbedded::get_singleton()->update_accelerometer(Vector3(acceleration.x + gravity.x, acceleration.y + gravity.y, acceleration.z + gravity.z).rotated(Vector3(0, 0, 1), Math::PI * 0.5));
|
||||||
DisplayServerIOS::get_singleton()->update_magnetometer(Vector3(magnetic.x, magnetic.y, magnetic.z).rotated(Vector3(0, 0, 1), Math::PI * 0.5));
|
DisplayServerAppleEmbedded::get_singleton()->update_magnetometer(Vector3(magnetic.x, magnetic.y, magnetic.z).rotated(Vector3(0, 0, 1), Math::PI * 0.5));
|
||||||
DisplayServerIOS::get_singleton()->update_gyroscope(Vector3(rotation.x, rotation.y, rotation.z).rotated(Vector3(0, 0, 1), Math::PI * 0.5));
|
DisplayServerAppleEmbedded::get_singleton()->update_gyroscope(Vector3(rotation.x, rotation.y, rotation.z).rotated(Vector3(0, 0, 1), Math::PI * 0.5));
|
||||||
} break;
|
} break;
|
||||||
case UIInterfaceOrientationPortraitUpsideDown: {
|
case UIInterfaceOrientationPortraitUpsideDown: {
|
||||||
DisplayServerIOS::get_singleton()->update_gravity(Vector3(gravity.x, gravity.y, gravity.z).rotated(Vector3(0, 0, 1), Math::PI));
|
DisplayServerAppleEmbedded::get_singleton()->update_gravity(Vector3(gravity.x, gravity.y, gravity.z).rotated(Vector3(0, 0, 1), Math::PI));
|
||||||
DisplayServerIOS::get_singleton()->update_accelerometer(Vector3(acceleration.x + gravity.x, acceleration.y + gravity.y, acceleration.z + gravity.z).rotated(Vector3(0, 0, 1), Math::PI));
|
DisplayServerAppleEmbedded::get_singleton()->update_accelerometer(Vector3(acceleration.x + gravity.x, acceleration.y + gravity.y, acceleration.z + gravity.z).rotated(Vector3(0, 0, 1), Math::PI));
|
||||||
DisplayServerIOS::get_singleton()->update_magnetometer(Vector3(magnetic.x, magnetic.y, magnetic.z).rotated(Vector3(0, 0, 1), Math::PI));
|
DisplayServerAppleEmbedded::get_singleton()->update_magnetometer(Vector3(magnetic.x, magnetic.y, magnetic.z).rotated(Vector3(0, 0, 1), Math::PI));
|
||||||
DisplayServerIOS::get_singleton()->update_gyroscope(Vector3(rotation.x, rotation.y, rotation.z).rotated(Vector3(0, 0, 1), Math::PI));
|
DisplayServerAppleEmbedded::get_singleton()->update_gyroscope(Vector3(rotation.x, rotation.y, rotation.z).rotated(Vector3(0, 0, 1), Math::PI));
|
||||||
} break;
|
} break;
|
||||||
default: { // assume portrait
|
default: { // assume portrait
|
||||||
DisplayServerIOS::get_singleton()->update_gravity(Vector3(gravity.x, gravity.y, gravity.z));
|
DisplayServerAppleEmbedded::get_singleton()->update_gravity(Vector3(gravity.x, gravity.y, gravity.z));
|
||||||
DisplayServerIOS::get_singleton()->update_accelerometer(Vector3(acceleration.x + gravity.x, acceleration.y + gravity.y, acceleration.z + gravity.z));
|
DisplayServerAppleEmbedded::get_singleton()->update_accelerometer(Vector3(acceleration.x + gravity.x, acceleration.y + gravity.y, acceleration.z + gravity.z));
|
||||||
DisplayServerIOS::get_singleton()->update_magnetometer(Vector3(magnetic.x, magnetic.y, magnetic.z));
|
DisplayServerAppleEmbedded::get_singleton()->update_magnetometer(Vector3(magnetic.x, magnetic.y, magnetic.z));
|
||||||
DisplayServerIOS::get_singleton()->update_gyroscope(Vector3(rotation.x, rotation.y, rotation.z));
|
DisplayServerAppleEmbedded::get_singleton()->update_gyroscope(Vector3(rotation.x, rotation.y, rotation.z));
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -32,7 +32,7 @@
|
|||||||
|
|
||||||
#import <UIKit/UIKit.h>
|
#import <UIKit/UIKit.h>
|
||||||
|
|
||||||
@protocol GodotViewRendererProtocol <NSObject>
|
@protocol GDTViewRendererProtocol <NSObject>
|
||||||
|
|
||||||
@property(assign, readonly, nonatomic) BOOL hasFinishedSetup;
|
@property(assign, readonly, nonatomic) BOOL hasFinishedSetup;
|
||||||
|
|
||||||
@@ -41,6 +41,6 @@
|
|||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@interface GodotViewRenderer : NSObject <GodotViewRendererProtocol>
|
@interface GDTViewRenderer : NSObject <GDTViewRendererProtocol>
|
||||||
|
|
||||||
@end
|
@end
|
||||||
@@ -30,8 +30,8 @@
|
|||||||
|
|
||||||
#import "godot_view_renderer.h"
|
#import "godot_view_renderer.h"
|
||||||
|
|
||||||
#import "display_server_ios.h"
|
#import "display_server_apple_embedded.h"
|
||||||
#import "os_ios.h"
|
#import "os_apple_embedded.h"
|
||||||
|
|
||||||
#include "core/config/project_settings.h"
|
#include "core/config/project_settings.h"
|
||||||
#include "core/os/keyboard.h"
|
#include "core/os/keyboard.h"
|
||||||
@@ -44,7 +44,7 @@
|
|||||||
#import <QuartzCore/QuartzCore.h>
|
#import <QuartzCore/QuartzCore.h>
|
||||||
#import <UIKit/UIKit.h>
|
#import <UIKit/UIKit.h>
|
||||||
|
|
||||||
@interface GodotViewRenderer ()
|
@interface GDTViewRenderer ()
|
||||||
|
|
||||||
@property(assign, nonatomic) BOOL hasFinishedProjectDataSetup;
|
@property(assign, nonatomic) BOOL hasFinishedProjectDataSetup;
|
||||||
@property(assign, nonatomic) BOOL hasStartedMain;
|
@property(assign, nonatomic) BOOL hasStartedMain;
|
||||||
@@ -52,7 +52,7 @@
|
|||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation GodotViewRenderer
|
@implementation GDTViewRenderer
|
||||||
|
|
||||||
- (BOOL)setupView:(UIView *)view {
|
- (BOOL)setupView:(UIView *)view {
|
||||||
if (self.hasFinishedSetup) {
|
if (self.hasFinishedSetup) {
|
||||||
@@ -70,7 +70,7 @@
|
|||||||
|
|
||||||
if (!self.hasStartedMain) {
|
if (!self.hasStartedMain) {
|
||||||
self.hasStartedMain = YES;
|
self.hasStartedMain = YES;
|
||||||
OS_IOS::get_singleton()->start();
|
OS_AppleEmbedded::get_singleton()->start();
|
||||||
return YES;
|
return YES;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -109,11 +109,11 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (void)renderOnView:(UIView *)view {
|
- (void)renderOnView:(UIView *)view {
|
||||||
if (!OS_IOS::get_singleton()) {
|
if (!OS_AppleEmbedded::get_singleton()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
OS_IOS::get_singleton()->iterate();
|
OS_AppleEmbedded::get_singleton()->iterate();
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
/* key_mapping_ios.h */
|
/* key_mapping_apple_embedded.h */
|
||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
/* This file is part of: */
|
/* This file is part of: */
|
||||||
/* GODOT ENGINE */
|
/* GODOT ENGINE */
|
||||||
@@ -34,8 +34,8 @@
|
|||||||
|
|
||||||
#import <UIKit/UIKit.h>
|
#import <UIKit/UIKit.h>
|
||||||
|
|
||||||
class KeyMappingIOS {
|
class KeyMappingAppleEmbedded {
|
||||||
KeyMappingIOS() {}
|
KeyMappingAppleEmbedded() {}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static void initialize();
|
static void initialize();
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
/* key_mapping_ios.mm */
|
/* key_mapping_apple_embedded.mm */
|
||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
/* This file is part of: */
|
/* This file is part of: */
|
||||||
/* GODOT ENGINE */
|
/* GODOT ENGINE */
|
||||||
@@ -28,7 +28,7 @@
|
|||||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
|
|
||||||
#import "key_mapping_ios.h"
|
#import "key_mapping_apple_embedded.h"
|
||||||
|
|
||||||
#include "core/templates/hash_map.h"
|
#include "core/templates/hash_map.h"
|
||||||
|
|
||||||
@@ -40,7 +40,7 @@ struct HashMapHasherKeys {
|
|||||||
HashMap<CFIndex, Key, HashMapHasherKeys> keyusage_map;
|
HashMap<CFIndex, Key, HashMapHasherKeys> keyusage_map;
|
||||||
HashMap<CFIndex, KeyLocation, HashMapHasherKeys> location_map;
|
HashMap<CFIndex, KeyLocation, HashMapHasherKeys> location_map;
|
||||||
|
|
||||||
void KeyMappingIOS::initialize() {
|
void KeyMappingAppleEmbedded::initialize() {
|
||||||
if (@available(iOS 13.4, *)) {
|
if (@available(iOS 13.4, *)) {
|
||||||
keyusage_map[UIKeyboardHIDUsageKeyboardA] = Key::A;
|
keyusage_map[UIKeyboardHIDUsageKeyboardA] = Key::A;
|
||||||
keyusage_map[UIKeyboardHIDUsageKeyboardB] = Key::B;
|
keyusage_map[UIKeyboardHIDUsageKeyboardB] = Key::B;
|
||||||
@@ -185,7 +185,7 @@ void KeyMappingIOS::initialize() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Key KeyMappingIOS::remap_key(CFIndex p_keycode) {
|
Key KeyMappingAppleEmbedded::remap_key(CFIndex p_keycode) {
|
||||||
if (@available(iOS 13.4, *)) {
|
if (@available(iOS 13.4, *)) {
|
||||||
const Key *key = keyusage_map.getptr(p_keycode);
|
const Key *key = keyusage_map.getptr(p_keycode);
|
||||||
if (key) {
|
if (key) {
|
||||||
@@ -195,7 +195,7 @@ Key KeyMappingIOS::remap_key(CFIndex p_keycode) {
|
|||||||
return Key::NONE;
|
return Key::NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
KeyLocation KeyMappingIOS::key_location(CFIndex p_keycode) {
|
KeyLocation KeyMappingAppleEmbedded::key_location(CFIndex p_keycode) {
|
||||||
if (@available(iOS 13.4, *)) {
|
if (@available(iOS 13.4, *)) {
|
||||||
const KeyLocation *location = location_map.getptr(p_keycode);
|
const KeyLocation *location = location_map.getptr(p_keycode);
|
||||||
if (location) {
|
if (location) {
|
||||||
@@ -32,7 +32,7 @@
|
|||||||
|
|
||||||
#import <UIKit/UIKit.h>
|
#import <UIKit/UIKit.h>
|
||||||
|
|
||||||
@interface GodotKeyboardInputView : UITextView
|
@interface GDTKeyboardInputView : UITextView
|
||||||
|
|
||||||
- (BOOL)becomeFirstResponderWithString:(NSString *)existingString cursorStart:(NSInteger)start cursorEnd:(NSInteger)end;
|
- (BOOL)becomeFirstResponderWithString:(NSString *)existingString cursorStart:(NSInteger)start cursorEnd:(NSInteger)end;
|
||||||
|
|
||||||
@@ -30,19 +30,19 @@
|
|||||||
|
|
||||||
#import "keyboard_input_view.h"
|
#import "keyboard_input_view.h"
|
||||||
|
|
||||||
#import "display_server_ios.h"
|
#import "display_server_apple_embedded.h"
|
||||||
#import "os_ios.h"
|
#import "os_apple_embedded.h"
|
||||||
|
|
||||||
#include "core/os/keyboard.h"
|
#include "core/os/keyboard.h"
|
||||||
|
|
||||||
@interface GodotKeyboardInputView () <UITextViewDelegate>
|
@interface GDTKeyboardInputView () <UITextViewDelegate>
|
||||||
|
|
||||||
@property(nonatomic, copy) NSString *previousText;
|
@property(nonatomic, copy) NSString *previousText;
|
||||||
@property(nonatomic, assign) NSRange previousSelectedRange;
|
@property(nonatomic, assign) NSRange previousSelectedRange;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation GodotKeyboardInputView
|
@implementation GDTKeyboardInputView
|
||||||
|
|
||||||
- (instancetype)initWithCoder:(NSCoder *)coder {
|
- (instancetype)initWithCoder:(NSCoder *)coder {
|
||||||
self = [super initWithCoder:coder];
|
self = [super initWithCoder:coder];
|
||||||
@@ -116,8 +116,8 @@
|
|||||||
|
|
||||||
- (void)deleteText:(NSInteger)charactersToDelete {
|
- (void)deleteText:(NSInteger)charactersToDelete {
|
||||||
for (int i = 0; i < charactersToDelete; i++) {
|
for (int i = 0; i < charactersToDelete; i++) {
|
||||||
DisplayServerIOS::get_singleton()->key(Key::BACKSPACE, 0, Key::BACKSPACE, Key::NONE, 0, true, KeyLocation::UNSPECIFIED);
|
DisplayServerAppleEmbedded::get_singleton()->key(Key::BACKSPACE, 0, Key::BACKSPACE, Key::NONE, 0, true, KeyLocation::UNSPECIFIED);
|
||||||
DisplayServerIOS::get_singleton()->key(Key::BACKSPACE, 0, Key::BACKSPACE, Key::NONE, 0, false, KeyLocation::UNSPECIFIED);
|
DisplayServerAppleEmbedded::get_singleton()->key(Key::BACKSPACE, 0, Key::BACKSPACE, Key::NONE, 0, false, KeyLocation::UNSPECIFIED);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -136,8 +136,8 @@
|
|||||||
key = Key::SPACE;
|
key = Key::SPACE;
|
||||||
}
|
}
|
||||||
|
|
||||||
DisplayServerIOS::get_singleton()->key(key, character, key, Key::NONE, 0, true, KeyLocation::UNSPECIFIED);
|
DisplayServerAppleEmbedded::get_singleton()->key(key, character, key, Key::NONE, 0, true, KeyLocation::UNSPECIFIED);
|
||||||
DisplayServerIOS::get_singleton()->key(key, character, key, Key::NONE, 0, false, KeyLocation::UNSPECIFIED);
|
DisplayServerAppleEmbedded::get_singleton()->key(key, character, key, Key::NONE, 0, false, KeyLocation::UNSPECIFIED);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
35
drivers/apple_embedded/main_utilities.h
Normal file
35
drivers/apple_embedded/main_utilities.h
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
/**************************************************************************/
|
||||||
|
/* main_utilities.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. */
|
||||||
|
/**************************************************************************/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
void change_to_launch_dir(char **p_args);
|
||||||
|
|
||||||
|
int process_args(int p_argc, char **p_args, char **r_args);
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
/* godot_ios.mm */
|
/* main_utilities.mm */
|
||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
/* This file is part of: */
|
/* This file is part of: */
|
||||||
/* GODOT ENGINE */
|
/* GODOT ENGINE */
|
||||||
@@ -28,15 +28,29 @@
|
|||||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
|
|
||||||
#import "os_ios.h"
|
|
||||||
|
|
||||||
#include "core/string/ustring.h"
|
#include "core/string/ustring.h"
|
||||||
#include "main/main.h"
|
|
||||||
|
#import <UIKit/UIKit.h>
|
||||||
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
|
||||||
static OS_IOS *os = nullptr;
|
void change_to_launch_dir(char **p_args) {
|
||||||
|
size_t len = strlen(p_args[0]);
|
||||||
|
|
||||||
|
while (len--) {
|
||||||
|
if (p_args[0][len] == '/') {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (len >= 0) {
|
||||||
|
char path[512];
|
||||||
|
memcpy(path, p_args[0], len > sizeof(path) ? sizeof(path) : len);
|
||||||
|
path[len] = 0;
|
||||||
|
chdir(path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int add_path(int p_argc, char **p_args) {
|
int add_path(int p_argc, char **p_args) {
|
||||||
NSString *str = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"godot_path"];
|
NSString *str = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"godot_path"];
|
||||||
@@ -70,50 +84,12 @@ int add_cmdline(int p_argc, char **p_args) {
|
|||||||
return p_argc;
|
return p_argc;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ios_main(int argc, char **argv) {
|
int process_args(int p_argc, char **p_args, char **r_args) {
|
||||||
size_t len = strlen(argv[0]);
|
for (int i = 0; i < p_argc; i++) {
|
||||||
|
r_args[i] = p_args[i];
|
||||||
while (len--) {
|
|
||||||
if (argv[0][len] == '/') {
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
r_args[p_argc] = nullptr;
|
||||||
|
p_argc = add_path(p_argc, r_args);
|
||||||
if (len >= 0) {
|
p_argc = add_cmdline(p_argc, r_args);
|
||||||
char path[512];
|
return p_argc;
|
||||||
memcpy(path, argv[0], len > sizeof(path) ? sizeof(path) : len);
|
|
||||||
path[len] = 0;
|
|
||||||
chdir(path);
|
|
||||||
}
|
|
||||||
|
|
||||||
os = new OS_IOS();
|
|
||||||
|
|
||||||
// We must override main when testing is enabled
|
|
||||||
TEST_MAIN_OVERRIDE
|
|
||||||
|
|
||||||
char *fargv[64];
|
|
||||||
for (int i = 0; i < argc; i++) {
|
|
||||||
fargv[i] = argv[i];
|
|
||||||
}
|
|
||||||
fargv[argc] = nullptr;
|
|
||||||
argc = add_path(argc, fargv);
|
|
||||||
argc = add_cmdline(argc, fargv);
|
|
||||||
|
|
||||||
Error err = Main::setup(fargv[0], argc - 1, &fargv[1], false);
|
|
||||||
|
|
||||||
if (err != OK) {
|
|
||||||
if (err == ERR_HELP) { // Returned by --help and --version, so success.
|
|
||||||
return EXIT_SUCCESS;
|
|
||||||
}
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
os->initialize_modules();
|
|
||||||
|
|
||||||
return os->get_exit_code();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ios_finish() {
|
|
||||||
Main::cleanup();
|
|
||||||
delete os;
|
|
||||||
}
|
}
|
||||||
137
drivers/apple_embedded/os_apple_embedded.h
Normal file
137
drivers/apple_embedded/os_apple_embedded.h
Normal file
@@ -0,0 +1,137 @@
|
|||||||
|
/**************************************************************************/
|
||||||
|
/* os_apple_embedded.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. */
|
||||||
|
/**************************************************************************/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifdef APPLE_EMBEDDED_ENABLED
|
||||||
|
|
||||||
|
#import "apple_embedded.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"
|
||||||
|
#include "servers/rendering/renderer_compositor.h"
|
||||||
|
|
||||||
|
#if defined(RD_ENABLED)
|
||||||
|
#include "servers/rendering/rendering_device.h"
|
||||||
|
|
||||||
|
#if defined(VULKAN_ENABLED)
|
||||||
|
#import "rendering_context_driver_vulkan_apple_embedded.h"
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
class OS_AppleEmbedded : public OS_Unix {
|
||||||
|
private:
|
||||||
|
static HashMap<String, void *> dynamic_symbol_lookup_table;
|
||||||
|
friend void register_dynamic_symbol(char *name, void *address);
|
||||||
|
|
||||||
|
AudioDriverCoreAudio audio_driver;
|
||||||
|
|
||||||
|
AppleEmbedded *apple_embedded = 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 set_main_loop(MainLoop *p_main_loop) override;
|
||||||
|
virtual MainLoop *get_main_loop() const override;
|
||||||
|
|
||||||
|
virtual void delete_main_loop() override;
|
||||||
|
|
||||||
|
virtual void finalize() override;
|
||||||
|
|
||||||
|
bool is_focused = false;
|
||||||
|
|
||||||
|
CGFloat _weight_to_ct(int p_weight) const;
|
||||||
|
CGFloat _stretch_to_ct(int p_stretch) const;
|
||||||
|
String _get_default_fontname(const String &p_font_name) const;
|
||||||
|
|
||||||
|
static _FORCE_INLINE_ String get_framework_executable(const String &p_path);
|
||||||
|
|
||||||
|
void deinitialize_modules();
|
||||||
|
|
||||||
|
public:
|
||||||
|
static OS_AppleEmbedded *get_singleton();
|
||||||
|
|
||||||
|
OS_AppleEmbedded();
|
||||||
|
~OS_AppleEmbedded();
|
||||||
|
|
||||||
|
void initialize_modules();
|
||||||
|
|
||||||
|
bool iterate();
|
||||||
|
|
||||||
|
void start();
|
||||||
|
|
||||||
|
virtual void alert(const String &p_alert, const String &p_title = "ALERT!") override;
|
||||||
|
|
||||||
|
virtual Vector<String> get_system_fonts() const override;
|
||||||
|
virtual Vector<String> get_system_font_path_for_text(const String &p_font_name, const String &p_text, const String &p_locale = String(), const String &p_script = String(), int p_weight = 400, int p_stretch = 100, bool p_italic = false) const override;
|
||||||
|
virtual String get_system_font_path(const String &p_font_name, int p_weight = 400, int p_stretch = 100, bool p_italic = false) const override;
|
||||||
|
|
||||||
|
virtual Error open_dynamic_library(const String &p_path, void *&p_library_handle, GDExtensionData *p_data = nullptr) override;
|
||||||
|
virtual Error close_dynamic_library(void *p_library_handle) override;
|
||||||
|
virtual Error get_dynamic_library_symbol_handle(void *p_library_handle, const String &p_name, void *&p_symbol_handle, bool p_optional = false) override;
|
||||||
|
|
||||||
|
virtual String get_distribution_name() const override;
|
||||||
|
virtual String get_version() const override;
|
||||||
|
virtual String get_model_name() const override;
|
||||||
|
|
||||||
|
virtual Error shell_open(const String &p_uri) 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;
|
||||||
|
|
||||||
|
virtual String get_unique_id() const override;
|
||||||
|
virtual String get_processor_name() const override;
|
||||||
|
|
||||||
|
virtual void vibrate_handheld(int p_duration_ms = 500, float p_amplitude = -1.0) override;
|
||||||
|
|
||||||
|
virtual bool _check_internal_feature_support(const String &p_feature) override;
|
||||||
|
|
||||||
|
void on_focus_out();
|
||||||
|
void on_focus_in();
|
||||||
|
|
||||||
|
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 // APPLE_EMBEDDED_ENABLED
|
||||||
717
drivers/apple_embedded/os_apple_embedded.mm
Normal file
717
drivers/apple_embedded/os_apple_embedded.mm
Normal file
@@ -0,0 +1,717 @@
|
|||||||
|
/**************************************************************************/
|
||||||
|
/* os_apple_embedded.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 "os_apple_embedded.h"
|
||||||
|
|
||||||
|
#ifdef APPLE_EMBEDDED_ENABLED
|
||||||
|
|
||||||
|
#import "app_delegate_service.h"
|
||||||
|
#import "display_server_apple_embedded.h"
|
||||||
|
#import "godot_view_apple_embedded.h"
|
||||||
|
#import "terminal_logger_apple_embedded.h"
|
||||||
|
#import "view_controller.h"
|
||||||
|
|
||||||
|
#include "core/config/project_settings.h"
|
||||||
|
#include "core/io/dir_access.h"
|
||||||
|
#include "core/io/file_access.h"
|
||||||
|
#include "core/io/file_access_pack.h"
|
||||||
|
#include "drivers/unix/syslog_logger.h"
|
||||||
|
#include "main/main.h"
|
||||||
|
|
||||||
|
#import <AudioToolbox/AudioServices.h>
|
||||||
|
#import <CoreText/CoreText.h>
|
||||||
|
#import <UIKit/UIKit.h>
|
||||||
|
#import <dlfcn.h>
|
||||||
|
#include <sys/sysctl.h>
|
||||||
|
|
||||||
|
#if defined(RD_ENABLED)
|
||||||
|
#include "servers/rendering/renderer_rd/renderer_compositor_rd.h"
|
||||||
|
#import <QuartzCore/CAMetalLayer.h>
|
||||||
|
|
||||||
|
#if defined(VULKAN_ENABLED)
|
||||||
|
#include "drivers/vulkan/godot_vulkan.h"
|
||||||
|
#endif // VULKAN_ENABLED
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Initialization order between compilation units is not guaranteed,
|
||||||
|
// so we use this as a hack to ensure certain code is called before
|
||||||
|
// everything else, but after all units are initialized.
|
||||||
|
typedef void (*init_callback)();
|
||||||
|
static init_callback *apple_init_callbacks = nullptr;
|
||||||
|
static int apple_embedded_platform_init_callbacks_count = 0;
|
||||||
|
static int apple_embedded_platform_init_callbacks_capacity = 0;
|
||||||
|
HashMap<String, void *> OS_AppleEmbedded::dynamic_symbol_lookup_table;
|
||||||
|
|
||||||
|
void add_apple_embedded_platform_init_callback(init_callback cb) {
|
||||||
|
if (apple_embedded_platform_init_callbacks_count == apple_embedded_platform_init_callbacks_capacity) {
|
||||||
|
void *new_ptr = realloc(apple_init_callbacks, sizeof(cb) * (apple_embedded_platform_init_callbacks_capacity + 32));
|
||||||
|
if (new_ptr) {
|
||||||
|
apple_init_callbacks = (init_callback *)(new_ptr);
|
||||||
|
apple_embedded_platform_init_callbacks_capacity += 32;
|
||||||
|
} else {
|
||||||
|
ERR_FAIL_MSG("Unable to allocate memory for extension callbacks.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
apple_init_callbacks[apple_embedded_platform_init_callbacks_count++] = cb;
|
||||||
|
}
|
||||||
|
|
||||||
|
void register_dynamic_symbol(char *name, void *address) {
|
||||||
|
OS_AppleEmbedded::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_AppleEmbedded *OS_AppleEmbedded::get_singleton() {
|
||||||
|
return (OS_AppleEmbedded *)OS::get_singleton();
|
||||||
|
}
|
||||||
|
|
||||||
|
OS_AppleEmbedded::OS_AppleEmbedded() {
|
||||||
|
for (int i = 0; i < apple_embedded_platform_init_callbacks_count; ++i) {
|
||||||
|
apple_init_callbacks[i]();
|
||||||
|
}
|
||||||
|
free(apple_init_callbacks);
|
||||||
|
apple_init_callbacks = nullptr;
|
||||||
|
apple_embedded_platform_init_callbacks_count = 0;
|
||||||
|
apple_embedded_platform_init_callbacks_capacity = 0;
|
||||||
|
|
||||||
|
main_loop = nullptr;
|
||||||
|
|
||||||
|
Vector<Logger *> loggers;
|
||||||
|
loggers.push_back(memnew(TerminalLoggerAppleEmbedded));
|
||||||
|
_set_logger(memnew(CompositeLogger(loggers)));
|
||||||
|
|
||||||
|
AudioDriverManager::add_driver(&audio_driver);
|
||||||
|
}
|
||||||
|
|
||||||
|
OS_AppleEmbedded::~OS_AppleEmbedded() {}
|
||||||
|
|
||||||
|
void OS_AppleEmbedded::alert(const String &p_alert, const String &p_title) {
|
||||||
|
const CharString utf8_alert = p_alert.utf8();
|
||||||
|
const CharString utf8_title = p_title.utf8();
|
||||||
|
AppleEmbedded::alert(utf8_alert.get_data(), utf8_title.get_data());
|
||||||
|
}
|
||||||
|
|
||||||
|
void OS_AppleEmbedded::initialize_core() {
|
||||||
|
OS_Unix::initialize_core();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OS_AppleEmbedded::initialize() {
|
||||||
|
initialize_core();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OS_AppleEmbedded::initialize_joypads() {
|
||||||
|
joypad_apple = memnew(JoypadApple);
|
||||||
|
}
|
||||||
|
|
||||||
|
void OS_AppleEmbedded::initialize_modules() {
|
||||||
|
apple_embedded = memnew(AppleEmbedded);
|
||||||
|
Engine::get_singleton()->add_singleton(Engine::Singleton("AppleEmbedded", apple_embedded));
|
||||||
|
}
|
||||||
|
|
||||||
|
void OS_AppleEmbedded::deinitialize_modules() {
|
||||||
|
if (joypad_apple) {
|
||||||
|
memdelete(joypad_apple);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (apple_embedded) {
|
||||||
|
memdelete(apple_embedded);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void OS_AppleEmbedded::set_main_loop(MainLoop *p_main_loop) {
|
||||||
|
main_loop = p_main_loop;
|
||||||
|
}
|
||||||
|
|
||||||
|
MainLoop *OS_AppleEmbedded::get_main_loop() const {
|
||||||
|
return main_loop;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OS_AppleEmbedded::delete_main_loop() {
|
||||||
|
if (main_loop) {
|
||||||
|
main_loop->finalize();
|
||||||
|
memdelete(main_loop);
|
||||||
|
}
|
||||||
|
|
||||||
|
main_loop = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool OS_AppleEmbedded::iterate() {
|
||||||
|
if (!main_loop) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (DisplayServer::get_singleton()) {
|
||||||
|
DisplayServer::get_singleton()->process_events();
|
||||||
|
}
|
||||||
|
|
||||||
|
joypad_apple->process_joypads();
|
||||||
|
|
||||||
|
return Main::iteration();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OS_AppleEmbedded::start() {
|
||||||
|
if (Main::start() == EXIT_SUCCESS) {
|
||||||
|
main_loop->initialize();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void OS_AppleEmbedded::finalize() {
|
||||||
|
deinitialize_modules();
|
||||||
|
|
||||||
|
// Already gets called
|
||||||
|
//delete_main_loop();
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: Dynamic Libraries
|
||||||
|
|
||||||
|
_FORCE_INLINE_ String OS_AppleEmbedded::get_framework_executable(const String &p_path) {
|
||||||
|
Ref<DirAccess> da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
|
||||||
|
|
||||||
|
// Read framework bundle to get executable name.
|
||||||
|
NSURL *url = [NSURL fileURLWithPath:@(p_path.utf8().get_data())];
|
||||||
|
NSBundle *bundle = [NSBundle bundleWithURL:url];
|
||||||
|
if (bundle) {
|
||||||
|
String exe_path = String::utf8([[bundle executablePath] UTF8String]);
|
||||||
|
if (da->file_exists(exe_path)) {
|
||||||
|
return exe_path;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try default executable name (invalid framework).
|
||||||
|
if (da->dir_exists(p_path) && da->file_exists(p_path.path_join(p_path.get_file().get_basename()))) {
|
||||||
|
return p_path.path_join(p_path.get_file().get_basename());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Not a framework, try loading as .dylib.
|
||||||
|
return p_path;
|
||||||
|
}
|
||||||
|
|
||||||
|
Error OS_AppleEmbedded::open_dynamic_library(const String &p_path, void *&p_library_handle, GDExtensionData *p_data) {
|
||||||
|
if (p_path.length() == 0) {
|
||||||
|
// Static xcframework.
|
||||||
|
p_library_handle = RTLD_SELF;
|
||||||
|
|
||||||
|
if (p_data != nullptr && p_data->r_resolved_path != nullptr) {
|
||||||
|
*p_data->r_resolved_path = p_path;
|
||||||
|
}
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
String path = get_framework_executable(p_path);
|
||||||
|
|
||||||
|
if (!FileAccess::exists(path)) {
|
||||||
|
// Load .dylib or framework from within the executable path.
|
||||||
|
path = get_framework_executable(get_executable_path().get_base_dir().path_join(p_path.get_file()));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!FileAccess::exists(path)) {
|
||||||
|
// Load .dylib converted to framework from within the executable path.
|
||||||
|
path = get_framework_executable(get_executable_path().get_base_dir().path_join(p_path.get_file().get_basename() + ".framework"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!FileAccess::exists(path)) {
|
||||||
|
// Load .dylib or framework from a standard iOS location.
|
||||||
|
path = get_framework_executable(get_executable_path().get_base_dir().path_join("Frameworks").path_join(p_path.get_file()));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!FileAccess::exists(path)) {
|
||||||
|
// Load .dylib converted to framework from a standard iOS location.
|
||||||
|
path = get_framework_executable(get_executable_path().get_base_dir().path_join("Frameworks").path_join(p_path.get_file().get_basename() + ".framework"));
|
||||||
|
}
|
||||||
|
|
||||||
|
ERR_FAIL_COND_V(!FileAccess::exists(path), ERR_FILE_NOT_FOUND);
|
||||||
|
|
||||||
|
p_library_handle = dlopen(path.utf8().get_data(), RTLD_NOW);
|
||||||
|
ERR_FAIL_NULL_V_MSG(p_library_handle, ERR_CANT_OPEN, vformat("Can't open dynamic library: %s. Error: %s.", p_path, dlerror()));
|
||||||
|
|
||||||
|
if (p_data != nullptr && p_data->r_resolved_path != nullptr) {
|
||||||
|
*p_data->r_resolved_path = path;
|
||||||
|
}
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
Error OS_AppleEmbedded::close_dynamic_library(void *p_library_handle) {
|
||||||
|
if (p_library_handle == RTLD_SELF) {
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
return OS_Unix::close_dynamic_library(p_library_handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
Error OS_AppleEmbedded::get_dynamic_library_symbol_handle(void *p_library_handle, const String &p_name, void *&p_symbol_handle, bool p_optional) {
|
||||||
|
if (p_library_handle == RTLD_SELF) {
|
||||||
|
void **ptr = OS_AppleEmbedded::dynamic_symbol_lookup_table.getptr(p_name);
|
||||||
|
if (ptr) {
|
||||||
|
p_symbol_handle = *ptr;
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return OS_Unix::get_dynamic_library_symbol_handle(p_library_handle, p_name, p_symbol_handle, p_optional);
|
||||||
|
}
|
||||||
|
|
||||||
|
String OS_AppleEmbedded::get_distribution_name() const {
|
||||||
|
return get_name();
|
||||||
|
}
|
||||||
|
|
||||||
|
String OS_AppleEmbedded::get_version() const {
|
||||||
|
NSOperatingSystemVersion ver = [NSProcessInfo processInfo].operatingSystemVersion;
|
||||||
|
return vformat("%d.%d.%d", (int64_t)ver.majorVersion, (int64_t)ver.minorVersion, (int64_t)ver.patchVersion);
|
||||||
|
}
|
||||||
|
|
||||||
|
String OS_AppleEmbedded::get_model_name() const {
|
||||||
|
String model = apple_embedded->get_model();
|
||||||
|
if (model != "") {
|
||||||
|
return model;
|
||||||
|
}
|
||||||
|
|
||||||
|
return OS_Unix::get_model_name();
|
||||||
|
}
|
||||||
|
|
||||||
|
Error OS_AppleEmbedded::shell_open(const String &p_uri) {
|
||||||
|
NSString *urlPath = [[NSString alloc] initWithUTF8String:p_uri.utf8().get_data()];
|
||||||
|
NSURL *url = [NSURL URLWithString:urlPath];
|
||||||
|
|
||||||
|
if (![[UIApplication sharedApplication] canOpenURL:url]) {
|
||||||
|
return ERR_CANT_OPEN;
|
||||||
|
}
|
||||||
|
|
||||||
|
print_verbose(vformat("Opening URL %s", p_uri));
|
||||||
|
|
||||||
|
[[UIApplication sharedApplication] openURL:url options:@{} completionHandler:nil];
|
||||||
|
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
String OS_AppleEmbedded::get_user_data_dir(const String &p_user_dir) const {
|
||||||
|
static String ret;
|
||||||
|
if (ret.is_empty()) {
|
||||||
|
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
|
||||||
|
if (paths && [paths count] >= 1) {
|
||||||
|
ret.append_utf8([[paths firstObject] UTF8String]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
String OS_AppleEmbedded::get_cache_path() const {
|
||||||
|
static String ret;
|
||||||
|
if (ret.is_empty()) {
|
||||||
|
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
|
||||||
|
if (paths && [paths count] >= 1) {
|
||||||
|
ret.append_utf8([[paths firstObject] UTF8String]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
String OS_AppleEmbedded::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;
|
||||||
|
}
|
||||||
|
|
||||||
|
String OS_AppleEmbedded::get_locale() const {
|
||||||
|
NSString *preferredLanguage = [NSLocale preferredLanguages].firstObject;
|
||||||
|
|
||||||
|
if (preferredLanguage) {
|
||||||
|
return String::utf8([preferredLanguage UTF8String]).replace_char('-', '_');
|
||||||
|
}
|
||||||
|
|
||||||
|
NSString *localeIdentifier = [[NSLocale currentLocale] localeIdentifier];
|
||||||
|
return String::utf8([localeIdentifier UTF8String]).replace_char('-', '_');
|
||||||
|
}
|
||||||
|
|
||||||
|
String OS_AppleEmbedded::get_unique_id() const {
|
||||||
|
NSString *uuid = [UIDevice currentDevice].identifierForVendor.UUIDString;
|
||||||
|
return String::utf8([uuid UTF8String]);
|
||||||
|
}
|
||||||
|
|
||||||
|
String OS_AppleEmbedded::get_processor_name() const {
|
||||||
|
char buffer[256];
|
||||||
|
size_t buffer_len = 256;
|
||||||
|
if (sysctlbyname("machdep.cpu.brand_string", &buffer, &buffer_len, nullptr, 0) == 0) {
|
||||||
|
return String::utf8(buffer, buffer_len);
|
||||||
|
}
|
||||||
|
ERR_FAIL_V_MSG("", String("Couldn't get the CPU model name. Returning an empty string."));
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector<String> OS_AppleEmbedded::get_system_fonts() const {
|
||||||
|
HashSet<String> font_names;
|
||||||
|
CFArrayRef fonts = CTFontManagerCopyAvailableFontFamilyNames();
|
||||||
|
if (fonts) {
|
||||||
|
for (CFIndex i = 0; i < CFArrayGetCount(fonts); i++) {
|
||||||
|
CFStringRef cf_name = (CFStringRef)CFArrayGetValueAtIndex(fonts, i);
|
||||||
|
if (cf_name && (CFStringGetLength(cf_name) > 0) && (CFStringCompare(cf_name, CFSTR("LastResort"), kCFCompareCaseInsensitive) != kCFCompareEqualTo) && (CFStringGetCharacterAtIndex(cf_name, 0) != '.')) {
|
||||||
|
NSString *ns_name = (__bridge NSString *)cf_name;
|
||||||
|
font_names.insert(String::utf8([ns_name UTF8String]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CFRelease(fonts);
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector<String> ret;
|
||||||
|
for (const String &E : font_names) {
|
||||||
|
ret.push_back(E);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
String OS_AppleEmbedded::_get_default_fontname(const String &p_font_name) const {
|
||||||
|
String font_name = p_font_name;
|
||||||
|
if (font_name.to_lower() == "sans-serif") {
|
||||||
|
font_name = "Helvetica";
|
||||||
|
} else if (font_name.to_lower() == "serif") {
|
||||||
|
font_name = "Times";
|
||||||
|
} else if (font_name.to_lower() == "monospace") {
|
||||||
|
font_name = "Courier";
|
||||||
|
} else if (font_name.to_lower() == "fantasy") {
|
||||||
|
font_name = "Papyrus";
|
||||||
|
} else if (font_name.to_lower() == "cursive") {
|
||||||
|
font_name = "Apple Chancery";
|
||||||
|
};
|
||||||
|
return font_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
CGFloat OS_AppleEmbedded::_weight_to_ct(int p_weight) const {
|
||||||
|
if (p_weight < 150) {
|
||||||
|
return -0.80;
|
||||||
|
} else if (p_weight < 250) {
|
||||||
|
return -0.60;
|
||||||
|
} else if (p_weight < 350) {
|
||||||
|
return -0.40;
|
||||||
|
} else if (p_weight < 450) {
|
||||||
|
return 0.0;
|
||||||
|
} else if (p_weight < 550) {
|
||||||
|
return 0.23;
|
||||||
|
} else if (p_weight < 650) {
|
||||||
|
return 0.30;
|
||||||
|
} else if (p_weight < 750) {
|
||||||
|
return 0.40;
|
||||||
|
} else if (p_weight < 850) {
|
||||||
|
return 0.56;
|
||||||
|
} else if (p_weight < 925) {
|
||||||
|
return 0.62;
|
||||||
|
} else {
|
||||||
|
return 1.00;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CGFloat OS_AppleEmbedded::_stretch_to_ct(int p_stretch) const {
|
||||||
|
if (p_stretch < 56) {
|
||||||
|
return -0.5;
|
||||||
|
} else if (p_stretch < 69) {
|
||||||
|
return -0.37;
|
||||||
|
} else if (p_stretch < 81) {
|
||||||
|
return -0.25;
|
||||||
|
} else if (p_stretch < 93) {
|
||||||
|
return -0.13;
|
||||||
|
} else if (p_stretch < 106) {
|
||||||
|
return 0.0;
|
||||||
|
} else if (p_stretch < 137) {
|
||||||
|
return 0.13;
|
||||||
|
} else if (p_stretch < 144) {
|
||||||
|
return 0.25;
|
||||||
|
} else if (p_stretch < 162) {
|
||||||
|
return 0.37;
|
||||||
|
} else {
|
||||||
|
return 0.5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector<String> OS_AppleEmbedded::get_system_font_path_for_text(const String &p_font_name, const String &p_text, const String &p_locale, const String &p_script, int p_weight, int p_stretch, bool p_italic) const {
|
||||||
|
Vector<String> ret;
|
||||||
|
String font_name = _get_default_fontname(p_font_name);
|
||||||
|
|
||||||
|
CFStringRef name = CFStringCreateWithCString(kCFAllocatorDefault, font_name.utf8().get_data(), kCFStringEncodingUTF8);
|
||||||
|
CTFontSymbolicTraits traits = 0;
|
||||||
|
if (p_weight >= 700) {
|
||||||
|
traits |= kCTFontBoldTrait;
|
||||||
|
}
|
||||||
|
if (p_italic) {
|
||||||
|
traits |= kCTFontItalicTrait;
|
||||||
|
}
|
||||||
|
if (p_stretch < 100) {
|
||||||
|
traits |= kCTFontCondensedTrait;
|
||||||
|
} else if (p_stretch > 100) {
|
||||||
|
traits |= kCTFontExpandedTrait;
|
||||||
|
}
|
||||||
|
|
||||||
|
CFNumberRef sym_traits = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &traits);
|
||||||
|
CFMutableDictionaryRef traits_dict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, nullptr, nullptr);
|
||||||
|
CFDictionaryAddValue(traits_dict, kCTFontSymbolicTrait, sym_traits);
|
||||||
|
|
||||||
|
CGFloat weight = _weight_to_ct(p_weight);
|
||||||
|
CFNumberRef font_weight = CFNumberCreate(kCFAllocatorDefault, kCFNumberCGFloatType, &weight);
|
||||||
|
CFDictionaryAddValue(traits_dict, kCTFontWeightTrait, font_weight);
|
||||||
|
|
||||||
|
CGFloat stretch = _stretch_to_ct(p_stretch);
|
||||||
|
CFNumberRef font_stretch = CFNumberCreate(kCFAllocatorDefault, kCFNumberCGFloatType, &stretch);
|
||||||
|
CFDictionaryAddValue(traits_dict, kCTFontWidthTrait, font_stretch);
|
||||||
|
|
||||||
|
CFMutableDictionaryRef attributes = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, nullptr, nullptr);
|
||||||
|
CFDictionaryAddValue(attributes, kCTFontFamilyNameAttribute, name);
|
||||||
|
CFDictionaryAddValue(attributes, kCTFontTraitsAttribute, traits_dict);
|
||||||
|
|
||||||
|
CTFontDescriptorRef font = CTFontDescriptorCreateWithAttributes(attributes);
|
||||||
|
if (font) {
|
||||||
|
CTFontRef family = CTFontCreateWithFontDescriptor(font, 0, nullptr);
|
||||||
|
if (family) {
|
||||||
|
CFStringRef string = CFStringCreateWithCString(kCFAllocatorDefault, p_text.utf8().get_data(), kCFStringEncodingUTF8);
|
||||||
|
CFRange range = CFRangeMake(0, CFStringGetLength(string));
|
||||||
|
CTFontRef fallback_family = CTFontCreateForString(family, string, range);
|
||||||
|
if (fallback_family) {
|
||||||
|
CTFontDescriptorRef fallback_font = CTFontCopyFontDescriptor(fallback_family);
|
||||||
|
if (fallback_font) {
|
||||||
|
CFURLRef url = (CFURLRef)CTFontDescriptorCopyAttribute(fallback_font, kCTFontURLAttribute);
|
||||||
|
if (url) {
|
||||||
|
NSString *font_path = [NSString stringWithString:[(__bridge NSURL *)url path]];
|
||||||
|
ret.push_back(String::utf8([font_path UTF8String]));
|
||||||
|
CFRelease(url);
|
||||||
|
}
|
||||||
|
CFRelease(fallback_font);
|
||||||
|
}
|
||||||
|
CFRelease(fallback_family);
|
||||||
|
}
|
||||||
|
CFRelease(string);
|
||||||
|
CFRelease(family);
|
||||||
|
}
|
||||||
|
CFRelease(font);
|
||||||
|
}
|
||||||
|
|
||||||
|
CFRelease(attributes);
|
||||||
|
CFRelease(traits_dict);
|
||||||
|
CFRelease(sym_traits);
|
||||||
|
CFRelease(font_stretch);
|
||||||
|
CFRelease(font_weight);
|
||||||
|
CFRelease(name);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
String OS_AppleEmbedded::get_system_font_path(const String &p_font_name, int p_weight, int p_stretch, bool p_italic) const {
|
||||||
|
String ret;
|
||||||
|
String font_name = _get_default_fontname(p_font_name);
|
||||||
|
|
||||||
|
CFStringRef name = CFStringCreateWithCString(kCFAllocatorDefault, font_name.utf8().get_data(), kCFStringEncodingUTF8);
|
||||||
|
|
||||||
|
CTFontSymbolicTraits traits = 0;
|
||||||
|
if (p_weight >= 700) {
|
||||||
|
traits |= kCTFontBoldTrait;
|
||||||
|
}
|
||||||
|
if (p_italic) {
|
||||||
|
traits |= kCTFontItalicTrait;
|
||||||
|
}
|
||||||
|
if (p_stretch < 100) {
|
||||||
|
traits |= kCTFontCondensedTrait;
|
||||||
|
} else if (p_stretch > 100) {
|
||||||
|
traits |= kCTFontExpandedTrait;
|
||||||
|
}
|
||||||
|
|
||||||
|
CFNumberRef sym_traits = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &traits);
|
||||||
|
CFMutableDictionaryRef traits_dict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, nullptr, nullptr);
|
||||||
|
CFDictionaryAddValue(traits_dict, kCTFontSymbolicTrait, sym_traits);
|
||||||
|
|
||||||
|
CGFloat weight = _weight_to_ct(p_weight);
|
||||||
|
CFNumberRef font_weight = CFNumberCreate(kCFAllocatorDefault, kCFNumberCGFloatType, &weight);
|
||||||
|
CFDictionaryAddValue(traits_dict, kCTFontWeightTrait, font_weight);
|
||||||
|
|
||||||
|
CGFloat stretch = _stretch_to_ct(p_stretch);
|
||||||
|
CFNumberRef font_stretch = CFNumberCreate(kCFAllocatorDefault, kCFNumberCGFloatType, &stretch);
|
||||||
|
CFDictionaryAddValue(traits_dict, kCTFontWidthTrait, font_stretch);
|
||||||
|
|
||||||
|
CFMutableDictionaryRef attributes = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, nullptr, nullptr);
|
||||||
|
CFDictionaryAddValue(attributes, kCTFontFamilyNameAttribute, name);
|
||||||
|
CFDictionaryAddValue(attributes, kCTFontTraitsAttribute, traits_dict);
|
||||||
|
|
||||||
|
CTFontDescriptorRef font = CTFontDescriptorCreateWithAttributes(attributes);
|
||||||
|
if (font) {
|
||||||
|
CFURLRef url = (CFURLRef)CTFontDescriptorCopyAttribute(font, kCTFontURLAttribute);
|
||||||
|
if (url) {
|
||||||
|
NSString *font_path = [NSString stringWithString:[(__bridge NSURL *)url path]];
|
||||||
|
ret = String::utf8([font_path UTF8String]);
|
||||||
|
CFRelease(url);
|
||||||
|
}
|
||||||
|
CFRelease(font);
|
||||||
|
}
|
||||||
|
|
||||||
|
CFRelease(attributes);
|
||||||
|
CFRelease(traits_dict);
|
||||||
|
CFRelease(sym_traits);
|
||||||
|
CFRelease(font_stretch);
|
||||||
|
CFRelease(font_weight);
|
||||||
|
CFRelease(name);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OS_AppleEmbedded::vibrate_handheld(int p_duration_ms, float p_amplitude) {
|
||||||
|
if (apple_embedded->supports_haptic_engine()) {
|
||||||
|
if (p_amplitude > 0.0) {
|
||||||
|
p_amplitude = CLAMP(p_amplitude, 0.0, 1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
apple_embedded->vibrate_haptic_engine((float)p_duration_ms / 1000.f, p_amplitude);
|
||||||
|
} else {
|
||||||
|
// iOS <13 does not support duration for vibration
|
||||||
|
AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool OS_AppleEmbedded::_check_internal_feature_support(const String &p_feature) {
|
||||||
|
if (p_feature == "system_fonts") {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (p_feature == "mobile") {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OS_AppleEmbedded::on_focus_out() {
|
||||||
|
if (is_focused) {
|
||||||
|
is_focused = false;
|
||||||
|
|
||||||
|
if (DisplayServerAppleEmbedded::get_singleton()) {
|
||||||
|
DisplayServerAppleEmbedded::get_singleton()->send_window_event(DisplayServer::WINDOW_EVENT_FOCUS_OUT);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (OS::get_singleton()->get_main_loop()) {
|
||||||
|
OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_APPLICATION_FOCUS_OUT);
|
||||||
|
}
|
||||||
|
|
||||||
|
[GDTAppDelegateService.viewController.godotView stopRendering];
|
||||||
|
|
||||||
|
audio_driver.stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void OS_AppleEmbedded::on_focus_in() {
|
||||||
|
if (!is_focused) {
|
||||||
|
is_focused = true;
|
||||||
|
|
||||||
|
if (DisplayServerAppleEmbedded::get_singleton()) {
|
||||||
|
DisplayServerAppleEmbedded::get_singleton()->send_window_event(DisplayServer::WINDOW_EVENT_FOCUS_IN);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (OS::get_singleton()->get_main_loop()) {
|
||||||
|
OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_APPLICATION_FOCUS_IN);
|
||||||
|
}
|
||||||
|
|
||||||
|
[GDTAppDelegateService.viewController.godotView startRendering];
|
||||||
|
|
||||||
|
audio_driver.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void OS_AppleEmbedded::on_enter_background() {
|
||||||
|
// Do not check for is_focused, because on_focus_out will always be fired first by applicationWillResignActive.
|
||||||
|
|
||||||
|
if (OS::get_singleton()->get_main_loop()) {
|
||||||
|
OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_APPLICATION_PAUSED);
|
||||||
|
}
|
||||||
|
|
||||||
|
on_focus_out();
|
||||||
|
}
|
||||||
|
|
||||||
|
void OS_AppleEmbedded::on_exit_background() {
|
||||||
|
if (!is_focused) {
|
||||||
|
on_focus_in();
|
||||||
|
|
||||||
|
if (OS::get_singleton()->get_main_loop()) {
|
||||||
|
OS::get_singleton()->get_main_loop()->notification(MainLoop::NOTIFICATION_APPLICATION_RESUMED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rect2 OS_AppleEmbedded::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 // APPLE_EMBEDDED_ENABLED
|
||||||
44
drivers/apple_embedded/platform_config.h
Normal file
44
drivers/apple_embedded/platform_config.h
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
/**************************************************************************/
|
||||||
|
/* platform_config.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. */
|
||||||
|
/**************************************************************************/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <alloca.h>
|
||||||
|
|
||||||
|
#define PLATFORM_THREAD_OVERRIDE
|
||||||
|
|
||||||
|
#define PTHREAD_RENAME_SELF
|
||||||
|
|
||||||
|
#define _weakify(var) __weak typeof(var) GDWeak_##var = var;
|
||||||
|
#define _strongify(var) \
|
||||||
|
_Pragma("clang diagnostic push") \
|
||||||
|
_Pragma("clang diagnostic ignored \"-Wshadow\"") \
|
||||||
|
__strong typeof(var) var = GDWeak_##var; \
|
||||||
|
_Pragma("clang diagnostic pop")
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
/* rendering_context_driver_vulkan_ios.h */
|
/* rendering_context_driver_vulkan_apple_embedded.h */
|
||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
/* This file is part of: */
|
/* This file is part of: */
|
||||||
/* GODOT ENGINE */
|
/* GODOT ENGINE */
|
||||||
@@ -36,7 +36,7 @@
|
|||||||
|
|
||||||
#import <QuartzCore/CAMetalLayer.h>
|
#import <QuartzCore/CAMetalLayer.h>
|
||||||
|
|
||||||
class RenderingContextDriverVulkanIOS : public RenderingContextDriverVulkan {
|
class RenderingContextDriverVulkanAppleEmbedded : public RenderingContextDriverVulkan {
|
||||||
private:
|
private:
|
||||||
virtual const char *_get_platform_surface_extension() const override final;
|
virtual const char *_get_platform_surface_extension() const override final;
|
||||||
|
|
||||||
@@ -48,8 +48,8 @@ public:
|
|||||||
CAMetalLayer *const *layer_ptr;
|
CAMetalLayer *const *layer_ptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
RenderingContextDriverVulkanIOS();
|
RenderingContextDriverVulkanAppleEmbedded();
|
||||||
~RenderingContextDriverVulkanIOS();
|
~RenderingContextDriverVulkanAppleEmbedded();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // VULKAN_ENABLED
|
#endif // VULKAN_ENABLED
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
/* rendering_context_driver_vulkan_ios.mm */
|
/* rendering_context_driver_vulkan_apple_embedded.mm */
|
||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
/* This file is part of: */
|
/* This file is part of: */
|
||||||
/* GODOT ENGINE */
|
/* GODOT ENGINE */
|
||||||
@@ -28,7 +28,7 @@
|
|||||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
|
|
||||||
#import "rendering_context_driver_vulkan_ios.h"
|
#import "rendering_context_driver_vulkan_apple_embedded.h"
|
||||||
|
|
||||||
#ifdef VULKAN_ENABLED
|
#ifdef VULKAN_ENABLED
|
||||||
|
|
||||||
@@ -38,11 +38,11 @@
|
|||||||
#include <vulkan/vulkan_metal.h>
|
#include <vulkan/vulkan_metal.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const char *RenderingContextDriverVulkanIOS::_get_platform_surface_extension() const {
|
const char *RenderingContextDriverVulkanAppleEmbedded::_get_platform_surface_extension() const {
|
||||||
return VK_EXT_METAL_SURFACE_EXTENSION_NAME;
|
return VK_EXT_METAL_SURFACE_EXTENSION_NAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
RenderingContextDriver::SurfaceID RenderingContextDriverVulkanIOS::surface_create(const void *p_platform_data) {
|
RenderingContextDriver::SurfaceID RenderingContextDriverVulkanAppleEmbedded::surface_create(const void *p_platform_data) {
|
||||||
const WindowPlatformData *wpd = (const WindowPlatformData *)(p_platform_data);
|
const WindowPlatformData *wpd = (const WindowPlatformData *)(p_platform_data);
|
||||||
|
|
||||||
VkMetalSurfaceCreateInfoEXT create_info = {};
|
VkMetalSurfaceCreateInfoEXT create_info = {};
|
||||||
@@ -58,11 +58,11 @@ RenderingContextDriver::SurfaceID RenderingContextDriverVulkanIOS::surface_creat
|
|||||||
return SurfaceID(surface);
|
return SurfaceID(surface);
|
||||||
}
|
}
|
||||||
|
|
||||||
RenderingContextDriverVulkanIOS::RenderingContextDriverVulkanIOS() {
|
RenderingContextDriverVulkanAppleEmbedded::RenderingContextDriverVulkanAppleEmbedded() {
|
||||||
// Does nothing.
|
// Does nothing.
|
||||||
}
|
}
|
||||||
|
|
||||||
RenderingContextDriverVulkanIOS::~RenderingContextDriverVulkanIOS() {
|
RenderingContextDriverVulkanAppleEmbedded::~RenderingContextDriverVulkanAppleEmbedded() {
|
||||||
// Does nothing.
|
// Does nothing.
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
/* ios_terminal_logger.h */
|
/* terminal_logger_apple_embedded.h */
|
||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
/* This file is part of: */
|
/* This file is part of: */
|
||||||
/* GODOT ENGINE */
|
/* GODOT ENGINE */
|
||||||
@@ -30,13 +30,13 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#ifdef IOS_ENABLED
|
#ifdef APPLE_EMBEDDED_ENABLED
|
||||||
|
|
||||||
#include "core/io/logger.h"
|
#include "core/io/logger.h"
|
||||||
|
|
||||||
class IOSTerminalLogger : public StdLogger {
|
class TerminalLoggerAppleEmbedded : public StdLogger {
|
||||||
public:
|
public:
|
||||||
virtual void log_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, bool p_editor_notify = false, ErrorType p_type = ERR_ERROR, const Vector<Ref<ScriptBacktrace>> &p_script_backtraces = {}) override;
|
virtual void log_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, bool p_editor_notify = false, ErrorType p_type = ERR_ERROR, const Vector<Ref<ScriptBacktrace>> &p_script_backtraces = {}) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // IOS_ENABLED
|
#endif // APPLE_EMBEDDED_ENABLED
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
/* ios_terminal_logger.mm */
|
/* terminal_logger_apple_embedded.mm */
|
||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
/* This file is part of: */
|
/* This file is part of: */
|
||||||
/* GODOT ENGINE */
|
/* GODOT ENGINE */
|
||||||
@@ -28,13 +28,13 @@
|
|||||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
|
|
||||||
#import "ios_terminal_logger.h"
|
#import "terminal_logger_apple_embedded.h"
|
||||||
|
|
||||||
#ifdef IOS_ENABLED
|
#ifdef APPLE_EMBEDDED_ENABLED
|
||||||
|
|
||||||
#import <os/log.h>
|
#import <os/log.h>
|
||||||
|
|
||||||
void IOSTerminalLogger::log_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, bool p_editor_notify, ErrorType p_type, const Vector<Ref<ScriptBacktrace>> &p_script_backtraces) {
|
void TerminalLoggerAppleEmbedded::log_error(const char *p_function, const char *p_file, int p_line, const char *p_code, const char *p_rationale, bool p_editor_notify, ErrorType p_type, const Vector<Ref<ScriptBacktrace>> &p_script_backtraces) {
|
||||||
if (!should_log(true)) {
|
if (!should_log(true)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -77,4 +77,4 @@ void IOSTerminalLogger::log_error(const char *p_function, const char *p_file, in
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // IOS_ENABLED
|
#endif // APPLE_EMBEDDED_ENABLED
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
/* tts_ios.h */
|
/* tts_apple_embedded.h */
|
||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
/* This file is part of: */
|
/* This file is part of: */
|
||||||
/* GODOT ENGINE */
|
/* GODOT ENGINE */
|
||||||
@@ -42,7 +42,7 @@
|
|||||||
#import <AVFoundation/AVFoundation.h>
|
#import <AVFoundation/AVFoundation.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@interface TTS_IOS : NSObject <AVSpeechSynthesizerDelegate> {
|
@interface GDTTTS : NSObject <AVSpeechSynthesizerDelegate> {
|
||||||
bool speaking;
|
bool speaking;
|
||||||
HashMap<id, int> ids;
|
HashMap<id, int> ids;
|
||||||
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
/* tts_ios.mm */
|
/* tts_apple_embedded.mm */
|
||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
/* This file is part of: */
|
/* This file is part of: */
|
||||||
/* GODOT ENGINE */
|
/* GODOT ENGINE */
|
||||||
@@ -28,9 +28,9 @@
|
|||||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
|
|
||||||
#import "tts_ios.h"
|
#import "tts_apple_embedded.h"
|
||||||
|
|
||||||
@implementation TTS_IOS
|
@implementation GDTTTS
|
||||||
|
|
||||||
- (id)init {
|
- (id)init {
|
||||||
self = [super init];
|
self = [super init];
|
||||||
@@ -32,13 +32,12 @@
|
|||||||
|
|
||||||
#import <UIKit/UIKit.h>
|
#import <UIKit/UIKit.h>
|
||||||
|
|
||||||
@class GodotView;
|
@class GDTView;
|
||||||
@class GodotNativeVideoView;
|
@class GDTKeyboardInputView;
|
||||||
@class GodotKeyboardInputView;
|
|
||||||
|
|
||||||
@interface ViewController : UIViewController
|
@interface GDTViewController : UIViewController
|
||||||
|
|
||||||
@property(nonatomic, readonly, strong) GodotView *godotView;
|
@property(nonatomic, readonly, strong) GDTView *godotView;
|
||||||
@property(nonatomic, readonly, strong) GodotKeyboardInputView *keyboardView;
|
@property(nonatomic, readonly, strong) GDTKeyboardInputView *keyboardView;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
@@ -30,44 +30,44 @@
|
|||||||
|
|
||||||
#import "view_controller.h"
|
#import "view_controller.h"
|
||||||
|
|
||||||
#import "display_server_ios.h"
|
#import "display_server_apple_embedded.h"
|
||||||
#import "godot_view.h"
|
#import "godot_view_apple_embedded.h"
|
||||||
#import "godot_view_renderer.h"
|
#import "godot_view_renderer.h"
|
||||||
#import "key_mapping_ios.h"
|
#import "key_mapping_apple_embedded.h"
|
||||||
#import "keyboard_input_view.h"
|
#import "keyboard_input_view.h"
|
||||||
#import "os_ios.h"
|
#import "os_apple_embedded.h"
|
||||||
|
|
||||||
#include "core/config/project_settings.h"
|
#include "core/config/project_settings.h"
|
||||||
|
|
||||||
#import <AVFoundation/AVFoundation.h>
|
#import <AVFoundation/AVFoundation.h>
|
||||||
#import <GameController/GameController.h>
|
#import <GameController/GameController.h>
|
||||||
|
|
||||||
@interface ViewController () <GodotViewDelegate>
|
@interface GDTViewController () <GDTViewDelegate>
|
||||||
|
|
||||||
@property(strong, nonatomic) GodotViewRenderer *renderer;
|
@property(strong, nonatomic) GDTViewRenderer *renderer;
|
||||||
@property(strong, nonatomic) GodotKeyboardInputView *keyboardView;
|
@property(strong, nonatomic) GDTKeyboardInputView *keyboardView;
|
||||||
|
|
||||||
@property(strong, nonatomic) UIView *godotLoadingOverlay;
|
@property(strong, nonatomic) UIView *godotLoadingOverlay;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation ViewController
|
@implementation GDTViewController
|
||||||
|
|
||||||
- (GodotView *)godotView {
|
- (GDTView *)godotView {
|
||||||
return (GodotView *)self.view;
|
return (GDTView *)self.view;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)pressesBegan:(NSSet<UIPress *> *)presses withEvent:(UIPressesEvent *)event {
|
- (void)pressesBegan:(NSSet<UIPress *> *)presses withEvent:(UIPressesEvent *)event {
|
||||||
[super pressesBegan:presses withEvent:event];
|
[super pressesBegan:presses withEvent:event];
|
||||||
|
|
||||||
if (!DisplayServerIOS::get_singleton() || DisplayServerIOS::get_singleton()->is_keyboard_active()) {
|
if (!DisplayServerAppleEmbedded::get_singleton() || DisplayServerAppleEmbedded::get_singleton()->is_keyboard_active()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (@available(iOS 13.4, *)) {
|
if (@available(iOS 13.4, *)) {
|
||||||
for (UIPress *press in presses) {
|
for (UIPress *press in presses) {
|
||||||
String u32lbl = String::utf8([press.key.charactersIgnoringModifiers UTF8String]);
|
String u32lbl = String::utf8([press.key.charactersIgnoringModifiers UTF8String]);
|
||||||
String u32text = String::utf8([press.key.characters UTF8String]);
|
String u32text = String::utf8([press.key.characters UTF8String]);
|
||||||
Key key = KeyMappingIOS::remap_key(press.key.keyCode);
|
Key key = KeyMappingAppleEmbedded::remap_key(press.key.keyCode);
|
||||||
|
|
||||||
if (press.key.keyCode == 0 && u32text.is_empty() && u32lbl.is_empty()) {
|
if (press.key.keyCode == 0 && u32text.is_empty() && u32lbl.is_empty()) {
|
||||||
continue;
|
continue;
|
||||||
@@ -78,15 +78,15 @@
|
|||||||
us = u32lbl[0];
|
us = u32lbl[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
KeyLocation location = KeyMappingIOS::key_location(press.key.keyCode);
|
KeyLocation location = KeyMappingAppleEmbedded::key_location(press.key.keyCode);
|
||||||
|
|
||||||
if (!u32text.is_empty() && !u32text.begins_with("UIKey")) {
|
if (!u32text.is_empty() && !u32text.begins_with("UIKey")) {
|
||||||
for (int i = 0; i < u32text.length(); i++) {
|
for (int i = 0; i < u32text.length(); i++) {
|
||||||
const char32_t c = u32text[i];
|
const char32_t c = u32text[i];
|
||||||
DisplayServerIOS::get_singleton()->key(fix_keycode(us, key), c, fix_key_label(us, key), key, press.key.modifierFlags, true, location);
|
DisplayServerAppleEmbedded::get_singleton()->key(fix_keycode(us, key), c, fix_key_label(us, key), key, press.key.modifierFlags, true, location);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
DisplayServerIOS::get_singleton()->key(fix_keycode(us, key), 0, fix_key_label(us, key), key, press.key.modifierFlags, true, location);
|
DisplayServerAppleEmbedded::get_singleton()->key(fix_keycode(us, key), 0, fix_key_label(us, key), key, press.key.modifierFlags, true, location);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -95,13 +95,13 @@
|
|||||||
- (void)pressesEnded:(NSSet<UIPress *> *)presses withEvent:(UIPressesEvent *)event {
|
- (void)pressesEnded:(NSSet<UIPress *> *)presses withEvent:(UIPressesEvent *)event {
|
||||||
[super pressesEnded:presses withEvent:event];
|
[super pressesEnded:presses withEvent:event];
|
||||||
|
|
||||||
if (!DisplayServerIOS::get_singleton() || DisplayServerIOS::get_singleton()->is_keyboard_active()) {
|
if (!DisplayServerAppleEmbedded::get_singleton() || DisplayServerAppleEmbedded::get_singleton()->is_keyboard_active()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (@available(iOS 13.4, *)) {
|
if (@available(iOS 13.4, *)) {
|
||||||
for (UIPress *press in presses) {
|
for (UIPress *press in presses) {
|
||||||
String u32lbl = String::utf8([press.key.charactersIgnoringModifiers UTF8String]);
|
String u32lbl = String::utf8([press.key.charactersIgnoringModifiers UTF8String]);
|
||||||
Key key = KeyMappingIOS::remap_key(press.key.keyCode);
|
Key key = KeyMappingAppleEmbedded::remap_key(press.key.keyCode);
|
||||||
|
|
||||||
if (press.key.keyCode == 0 && u32lbl.is_empty()) {
|
if (press.key.keyCode == 0 && u32lbl.is_empty()) {
|
||||||
continue;
|
continue;
|
||||||
@@ -112,16 +112,16 @@
|
|||||||
us = u32lbl[0];
|
us = u32lbl[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
KeyLocation location = KeyMappingIOS::key_location(press.key.keyCode);
|
KeyLocation location = KeyMappingAppleEmbedded::key_location(press.key.keyCode);
|
||||||
|
|
||||||
DisplayServerIOS::get_singleton()->key(fix_keycode(us, key), 0, fix_key_label(us, key), key, press.key.modifierFlags, false, location);
|
DisplayServerAppleEmbedded::get_singleton()->key(fix_keycode(us, key), 0, fix_key_label(us, key), key, press.key.modifierFlags, false, location);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)loadView {
|
- (void)loadView {
|
||||||
GodotView *view = [[GodotView alloc] init];
|
GDTView *view = GDTViewCreate();
|
||||||
GodotViewRenderer *renderer = [[GodotViewRenderer alloc] init];
|
GDTViewRenderer *renderer = [[GDTViewRenderer alloc] init];
|
||||||
|
|
||||||
self.renderer = renderer;
|
self.renderer = renderer;
|
||||||
self.view = view;
|
self.view = view;
|
||||||
@@ -170,7 +170,7 @@
|
|||||||
|
|
||||||
- (void)observeKeyboard {
|
- (void)observeKeyboard {
|
||||||
print_verbose("Setting up keyboard input view.");
|
print_verbose("Setting up keyboard input view.");
|
||||||
self.keyboardView = [GodotKeyboardInputView new];
|
self.keyboardView = [GDTKeyboardInputView new];
|
||||||
[self.view addSubview:self.keyboardView];
|
[self.view addSubview:self.keyboardView];
|
||||||
|
|
||||||
print_verbose("Adding observer for keyboard show/hide.");
|
print_verbose("Adding observer for keyboard show/hide.");
|
||||||
@@ -187,6 +187,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (void)displayLoadingOverlay {
|
- (void)displayLoadingOverlay {
|
||||||
|
#if !defined(VISIONOS_ENABLED)
|
||||||
NSBundle *bundle = [NSBundle mainBundle];
|
NSBundle *bundle = [NSBundle mainBundle];
|
||||||
NSString *storyboardName = @"Launch Screen";
|
NSString *storyboardName = @"Launch Screen";
|
||||||
|
|
||||||
@@ -202,9 +203,10 @@
|
|||||||
self.godotLoadingOverlay.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
|
self.godotLoadingOverlay.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
|
||||||
|
|
||||||
[self.view addSubview:self.godotLoadingOverlay];
|
[self.view addSubview:self.godotLoadingOverlay];
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL)godotViewFinishedSetup:(GodotView *)view {
|
- (BOOL)godotViewFinishedSetup:(GDTView *)view {
|
||||||
[self.godotLoadingOverlay removeFromSuperview];
|
[self.godotLoadingOverlay removeFromSuperview];
|
||||||
self.godotLoadingOverlay = nil;
|
self.godotLoadingOverlay = nil;
|
||||||
|
|
||||||
@@ -235,11 +237,11 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL)shouldAutorotate {
|
- (BOOL)shouldAutorotate {
|
||||||
if (!DisplayServerIOS::get_singleton()) {
|
if (!DisplayServerAppleEmbedded::get_singleton()) {
|
||||||
return NO;
|
return NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (DisplayServerIOS::get_singleton()->screen_get_orientation(DisplayServer::SCREEN_OF_MAIN_WINDOW)) {
|
switch (DisplayServerAppleEmbedded::get_singleton()->screen_get_orientation(DisplayServer::SCREEN_OF_MAIN_WINDOW)) {
|
||||||
case DisplayServer::SCREEN_SENSOR:
|
case DisplayServer::SCREEN_SENSOR:
|
||||||
case DisplayServer::SCREEN_SENSOR_LANDSCAPE:
|
case DisplayServer::SCREEN_SENSOR_LANDSCAPE:
|
||||||
case DisplayServer::SCREEN_SENSOR_PORTRAIT:
|
case DisplayServer::SCREEN_SENSOR_PORTRAIT:
|
||||||
@@ -250,11 +252,11 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
|
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
|
||||||
if (!DisplayServerIOS::get_singleton()) {
|
if (!DisplayServerAppleEmbedded::get_singleton()) {
|
||||||
return UIInterfaceOrientationMaskAll;
|
return UIInterfaceOrientationMaskAll;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (DisplayServerIOS::get_singleton()->screen_get_orientation(DisplayServer::SCREEN_OF_MAIN_WINDOW)) {
|
switch (DisplayServerAppleEmbedded::get_singleton()->screen_get_orientation(DisplayServer::SCREEN_OF_MAIN_WINDOW)) {
|
||||||
case DisplayServer::SCREEN_PORTRAIT:
|
case DisplayServer::SCREEN_PORTRAIT:
|
||||||
return UIInterfaceOrientationMaskPortrait;
|
return UIInterfaceOrientationMaskPortrait;
|
||||||
case DisplayServer::SCREEN_REVERSE_LANDSCAPE:
|
case DisplayServer::SCREEN_REVERSE_LANDSCAPE:
|
||||||
@@ -305,14 +307,14 @@
|
|||||||
CGRect rawFrame = [value CGRectValue];
|
CGRect rawFrame = [value CGRectValue];
|
||||||
CGRect keyboardFrame = [self.view convertRect:rawFrame fromView:nil];
|
CGRect keyboardFrame = [self.view convertRect:rawFrame fromView:nil];
|
||||||
|
|
||||||
if (DisplayServerIOS::get_singleton()) {
|
if (DisplayServerAppleEmbedded::get_singleton()) {
|
||||||
DisplayServerIOS::get_singleton()->virtual_keyboard_set_height(keyboardFrame.size.height);
|
DisplayServerAppleEmbedded::get_singleton()->virtual_keyboard_set_height(keyboardFrame.size.height);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)keyboardHidden:(NSNotification *)notification {
|
- (void)keyboardHidden:(NSNotification *)notification {
|
||||||
if (DisplayServerIOS::get_singleton()) {
|
if (DisplayServerAppleEmbedded::get_singleton()) {
|
||||||
DisplayServerIOS::get_singleton()->virtual_keyboard_set_height(0);
|
DisplayServerAppleEmbedded::get_singleton()->virtual_keyboard_set_height(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -34,7 +34,6 @@
|
|||||||
|
|
||||||
#include "core/string/print_string.h"
|
#include "core/string/print_string.h"
|
||||||
|
|
||||||
#import <CoreAudio/HostTime.h>
|
|
||||||
#import <CoreServices/CoreServices.h>
|
#import <CoreServices/CoreServices.h>
|
||||||
|
|
||||||
Mutex MIDIDriverCoreMidi::mutex;
|
Mutex MIDIDriverCoreMidi::mutex;
|
||||||
|
|||||||
@@ -39,6 +39,9 @@ if "-std=gnu++17" in env_metal["CXXFLAGS"]:
|
|||||||
env_metal["CXXFLAGS"].remove("-std=gnu++17")
|
env_metal["CXXFLAGS"].remove("-std=gnu++17")
|
||||||
env_metal.Append(CXXFLAGS=["-std=c++20"])
|
env_metal.Append(CXXFLAGS=["-std=c++20"])
|
||||||
|
|
||||||
|
# Enable module support
|
||||||
|
env_metal.Append(CCFLAGS=["-fmodules", "-fcxx-modules"])
|
||||||
|
|
||||||
# Driver source files
|
# Driver source files
|
||||||
|
|
||||||
driver_obj = []
|
driver_obj = []
|
||||||
|
|||||||
@@ -50,6 +50,8 @@
|
|||||||
|
|
||||||
#import "metal_device_properties.h"
|
#import "metal_device_properties.h"
|
||||||
|
|
||||||
|
#include "servers/rendering/renderer_rd/effects/metal_fx.h"
|
||||||
|
|
||||||
#import <Metal/Metal.h>
|
#import <Metal/Metal.h>
|
||||||
#import <MetalFX/MetalFX.h>
|
#import <MetalFX/MetalFX.h>
|
||||||
#import <spirv_cross.hpp>
|
#import <spirv_cross.hpp>
|
||||||
@@ -63,7 +65,7 @@
|
|||||||
#define MTLGPUFamilyApple9 (MTLGPUFamily)1009
|
#define MTLGPUFamilyApple9 (MTLGPUFamily)1009
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
API_AVAILABLE(macos(11.0), ios(14.0), tvos(14.0))
|
API_AVAILABLE(macos(11.0), ios(14.0), tvos(14.0), visionos(1.0))
|
||||||
MTLGPUFamily &operator--(MTLGPUFamily &p_family) {
|
MTLGPUFamily &operator--(MTLGPUFamily &p_family) {
|
||||||
p_family = static_cast<MTLGPUFamily>(static_cast<int>(p_family) - 1);
|
p_family = static_cast<MTLGPUFamily>(static_cast<int>(p_family) - 1);
|
||||||
if (p_family < MTLGPUFamilyApple1) {
|
if (p_family < MTLGPUFamilyApple1) {
|
||||||
@@ -126,7 +128,11 @@ void MetalDeviceProperties::init_features(id<MTLDevice> p_device) {
|
|||||||
|
|
||||||
if (@available(macOS 13.0, iOS 16.0, tvOS 16.0, *)) {
|
if (@available(macOS 13.0, iOS 16.0, tvOS 16.0, *)) {
|
||||||
features.metal_fx_spatial = [MTLFXSpatialScalerDescriptor supportsDevice:p_device];
|
features.metal_fx_spatial = [MTLFXSpatialScalerDescriptor supportsDevice:p_device];
|
||||||
|
#ifdef METAL_MFXTEMPORAL_ENABLED
|
||||||
features.metal_fx_temporal = [MTLFXTemporalScalerDescriptor supportsDevice:p_device];
|
features.metal_fx_temporal = [MTLFXTemporalScalerDescriptor supportsDevice:p_device];
|
||||||
|
#else
|
||||||
|
features.metal_fx_temporal = false;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
MTLCompileOptions *opts = [MTLCompileOptions new];
|
MTLCompileOptions *opts = [MTLCompileOptions new];
|
||||||
@@ -136,7 +142,7 @@ void MetalDeviceProperties::init_features(id<MTLDevice> p_device) {
|
|||||||
features.mslVersion = SPIRV_CROSS_NAMESPACE::CompilerMSL::Options::make_msl_version(m_maj, m_min)
|
features.mslVersion = SPIRV_CROSS_NAMESPACE::CompilerMSL::Options::make_msl_version(m_maj, m_min)
|
||||||
|
|
||||||
switch (features.mslVersionEnum) {
|
switch (features.mslVersionEnum) {
|
||||||
#if __MAC_OS_X_VERSION_MAX_ALLOWED >= 150000 || __IPHONE_OS_VERSION_MAX_ALLOWED >= 180000 || __TV_OS_VERSION_MAX_ALLOWED >= 180000
|
#if __MAC_OS_X_VERSION_MAX_ALLOWED >= 150000 || __IPHONE_OS_VERSION_MAX_ALLOWED >= 180000 || __TV_OS_VERSION_MAX_ALLOWED >= 180000 || __VISION_OS_VERSION_MAX_ALLOWED >= 20000
|
||||||
case MTLLanguageVersion3_2:
|
case MTLLanguageVersion3_2:
|
||||||
setMSLVersion(3, 2);
|
setMSLVersion(3, 2);
|
||||||
break;
|
break;
|
||||||
@@ -170,7 +176,7 @@ void MetalDeviceProperties::init_features(id<MTLDevice> p_device) {
|
|||||||
case MTLLanguageVersion1_1:
|
case MTLLanguageVersion1_1:
|
||||||
setMSLVersion(1, 1);
|
setMSLVersion(1, 1);
|
||||||
break;
|
break;
|
||||||
#if TARGET_OS_IPHONE && !TARGET_OS_MACCATALYST
|
#if TARGET_OS_IPHONE && !TARGET_OS_MACCATALYST && !TARGET_OS_VISION
|
||||||
case MTLLanguageVersion1_0:
|
case MTLLanguageVersion1_0:
|
||||||
setMSLVersion(1, 0);
|
setMSLVersion(1, 0);
|
||||||
break;
|
break;
|
||||||
@@ -324,6 +330,7 @@ void MetalDeviceProperties::init_limits(id<MTLDevice> p_device) {
|
|||||||
|
|
||||||
limits.maxDrawIndexedIndexValue = std::numeric_limits<uint32_t>::max() - 1;
|
limits.maxDrawIndexedIndexValue = std::numeric_limits<uint32_t>::max() - 1;
|
||||||
|
|
||||||
|
#ifdef METAL_MFXTEMPORAL_ENABLED
|
||||||
if (@available(macOS 14.0, iOS 17.0, tvOS 17.0, *)) {
|
if (@available(macOS 14.0, iOS 17.0, tvOS 17.0, *)) {
|
||||||
limits.temporalScalerInputContentMinScale = (double)[MTLFXTemporalScalerDescriptor supportedInputContentMinScaleForDevice:p_device];
|
limits.temporalScalerInputContentMinScale = (double)[MTLFXTemporalScalerDescriptor supportedInputContentMinScaleForDevice:p_device];
|
||||||
limits.temporalScalerInputContentMaxScale = (double)[MTLFXTemporalScalerDescriptor supportedInputContentMaxScaleForDevice:p_device];
|
limits.temporalScalerInputContentMaxScale = (double)[MTLFXTemporalScalerDescriptor supportedInputContentMaxScaleForDevice:p_device];
|
||||||
@@ -332,6 +339,11 @@ void MetalDeviceProperties::init_limits(id<MTLDevice> p_device) {
|
|||||||
limits.temporalScalerInputContentMinScale = 1.0;
|
limits.temporalScalerInputContentMinScale = 1.0;
|
||||||
limits.temporalScalerInputContentMaxScale = 3.0;
|
limits.temporalScalerInputContentMaxScale = 3.0;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
// Defaults taken from macOS 14+
|
||||||
|
limits.temporalScalerInputContentMinScale = 1.0;
|
||||||
|
limits.temporalScalerInputContentMaxScale = 3.0;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
MetalDeviceProperties::MetalDeviceProperties(id<MTLDevice> p_device) {
|
MetalDeviceProperties::MetalDeviceProperties(id<MTLDevice> p_device) {
|
||||||
|
|||||||
@@ -114,6 +114,9 @@ bool PixelFormats::isSupportedOrSubstitutable(DataFormat p_format) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool PixelFormats::isPVRTCFormat(MTLPixelFormat p_format) {
|
bool PixelFormats::isPVRTCFormat(MTLPixelFormat p_format) {
|
||||||
|
#if defined(VISIONOS_ENABLED)
|
||||||
|
return false;
|
||||||
|
#else
|
||||||
switch (p_format) {
|
switch (p_format) {
|
||||||
case MTLPixelFormatPVRTC_RGBA_2BPP:
|
case MTLPixelFormatPVRTC_RGBA_2BPP:
|
||||||
case MTLPixelFormatPVRTC_RGBA_2BPP_sRGB:
|
case MTLPixelFormatPVRTC_RGBA_2BPP_sRGB:
|
||||||
@@ -127,6 +130,7 @@ bool PixelFormats::isPVRTCFormat(MTLPixelFormat p_format) {
|
|||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
MTLFormatType PixelFormats::getFormatType(DataFormat p_format) {
|
MTLFormatType PixelFormats::getFormatType(DataFormat p_format) {
|
||||||
@@ -668,11 +672,13 @@ void PixelFormats::initMTLPixelFormatCapabilities() {
|
|||||||
addMTLPixelFormatDesc(RGBA32Sint, Color128, RWC);
|
addMTLPixelFormatDesc(RGBA32Sint, Color128, RWC);
|
||||||
addMTLPixelFormatDesc(RGBA32Float, Color128, All);
|
addMTLPixelFormatDesc(RGBA32Float, Color128, All);
|
||||||
|
|
||||||
|
#if !defined(VISIONOS_ENABLED)
|
||||||
// Compressed pixel formats
|
// Compressed pixel formats
|
||||||
addMTLPixelFormatDesc(PVRTC_RGBA_2BPP, PVRTC_RGBA_2BPP, RF);
|
addMTLPixelFormatDesc(PVRTC_RGBA_2BPP, PVRTC_RGBA_2BPP, RF);
|
||||||
addMTLPixelFormatDescSRGB(PVRTC_RGBA_2BPP_sRGB, PVRTC_RGBA_2BPP, RF, PVRTC_RGBA_2BPP);
|
addMTLPixelFormatDescSRGB(PVRTC_RGBA_2BPP_sRGB, PVRTC_RGBA_2BPP, RF, PVRTC_RGBA_2BPP);
|
||||||
addMTLPixelFormatDesc(PVRTC_RGBA_4BPP, PVRTC_RGBA_4BPP, RF);
|
addMTLPixelFormatDesc(PVRTC_RGBA_4BPP, PVRTC_RGBA_4BPP, RF);
|
||||||
addMTLPixelFormatDescSRGB(PVRTC_RGBA_4BPP_sRGB, PVRTC_RGBA_4BPP, RF, PVRTC_RGBA_4BPP);
|
addMTLPixelFormatDescSRGB(PVRTC_RGBA_4BPP_sRGB, PVRTC_RGBA_4BPP, RF, PVRTC_RGBA_4BPP);
|
||||||
|
#endif
|
||||||
|
|
||||||
addMTLPixelFormatDesc(ETC2_RGB8, ETC2_RGB8, RF);
|
addMTLPixelFormatDesc(ETC2_RGB8, ETC2_RGB8, RF);
|
||||||
addMTLPixelFormatDescSRGB(ETC2_RGB8_sRGB, ETC2_RGB8, RF, ETC2_RGB8);
|
addMTLPixelFormatDescSRGB(ETC2_RGB8_sRGB, ETC2_RGB8, RF, ETC2_RGB8);
|
||||||
|
|||||||
@@ -290,7 +290,11 @@ RDD::TextureID RenderingDeviceDriverMetal::texture_create(const TextureFormat &p
|
|||||||
// Usage.
|
// Usage.
|
||||||
|
|
||||||
MTLResourceOptions options = 0;
|
MTLResourceOptions options = 0;
|
||||||
|
#if defined(VISIONOS_ENABLED)
|
||||||
|
const bool supports_memoryless = true;
|
||||||
|
#else
|
||||||
const bool supports_memoryless = (*device_properties).features.highestFamily >= MTLGPUFamilyApple2 && (*device_properties).features.highestFamily < MTLGPUFamilyMac1;
|
const bool supports_memoryless = (*device_properties).features.highestFamily >= MTLGPUFamilyApple2 && (*device_properties).features.highestFamily < MTLGPUFamilyMac1;
|
||||||
|
#endif
|
||||||
if (supports_memoryless && p_format.usage_bits & TEXTURE_USAGE_TRANSIENT_BIT) {
|
if (supports_memoryless && p_format.usage_bits & TEXTURE_USAGE_TRANSIENT_BIT) {
|
||||||
options = MTLResourceStorageModeMemoryless | MTLResourceHazardTrackingModeTracked;
|
options = MTLResourceStorageModeMemoryless | MTLResourceHazardTrackingModeTracked;
|
||||||
desc.storageMode = MTLStorageModeMemoryless;
|
desc.storageMode = MTLStorageModeMemoryless;
|
||||||
@@ -2493,7 +2497,11 @@ RDD::ShaderID RenderingDeviceDriverMetal::shader_create_from_bytecode(const Vect
|
|||||||
cd->name = binary_data.shader_name;
|
cd->name = binary_data.shader_name;
|
||||||
cd->stage = shader_data.stage;
|
cd->stage = shader_data.stage;
|
||||||
options.preserveInvariance = shader_data.is_position_invariant;
|
options.preserveInvariance = shader_data.is_position_invariant;
|
||||||
|
#if defined(VISIONOS_ENABLED)
|
||||||
|
options.mathMode = MTLMathModeFast;
|
||||||
|
#else
|
||||||
options.fastMathEnabled = YES;
|
options.fastMathEnabled = YES;
|
||||||
|
#endif
|
||||||
MDLibrary *library = [MDLibrary newLibraryWithCacheEntry:cd
|
MDLibrary *library = [MDLibrary newLibraryWithCacheEntry:cd
|
||||||
device:device
|
device:device
|
||||||
source:source
|
source:source
|
||||||
@@ -4184,8 +4192,8 @@ Error RenderingDeviceDriverMetal::initialize(uint32_t p_device_index, uint32_t p
|
|||||||
error_string += "- No support for image cube arrays.\n";
|
error_string += "- No support for image cube arrays.\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(IOS_ENABLED)
|
#if defined(APPLE_EMBEDDED_ENABLED)
|
||||||
// iOS platform ports currently don't exit themselves when this method returns `ERR_CANT_CREATE`.
|
// Apple Embedded platforms exports currently don't exit themselves when this method returns `ERR_CANT_CREATE`.
|
||||||
OS::get_singleton()->alert(error_string + "\nClick OK to exit (black screen will be visible).");
|
OS::get_singleton()->alert(error_string + "\nClick OK to exit (black screen will be visible).");
|
||||||
#else
|
#else
|
||||||
OS::get_singleton()->alert(error_string + "\nClick OK to exit.");
|
OS::get_singleton()->alert(error_string + "\nClick OK to exit.");
|
||||||
|
|||||||
2757
editor/export/editor_export_platform_apple_embedded.cpp
Normal file
2757
editor/export/editor_export_platform_apple_embedded.cpp
Normal file
File diff suppressed because it is too large
Load Diff
319
editor/export/editor_export_platform_apple_embedded.h
Normal file
319
editor/export/editor_export_platform_apple_embedded.h
Normal file
@@ -0,0 +1,319 @@
|
|||||||
|
/**************************************************************************/
|
||||||
|
/* editor_export_platform_apple_embedded.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. */
|
||||||
|
/**************************************************************************/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "plugin_config_apple_embedded.h"
|
||||||
|
|
||||||
|
#include "core/config/project_settings.h"
|
||||||
|
#include "core/io/file_access.h"
|
||||||
|
#include "core/io/image_loader.h"
|
||||||
|
#include "core/io/marshalls.h"
|
||||||
|
#include "core/io/resource_saver.h"
|
||||||
|
#include "core/io/zip_io.h"
|
||||||
|
#include "core/os/os.h"
|
||||||
|
#include "core/templates/safe_refcount.h"
|
||||||
|
#include "editor/editor_settings.h"
|
||||||
|
#include "editor/export/editor_export_platform.h"
|
||||||
|
#include "main/splash.gen.h"
|
||||||
|
#include "scene/resources/image_texture.h"
|
||||||
|
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
// Optional environment variables for defining confidential information. If any
|
||||||
|
// of these is set, they will override the values set in the credentials file.
|
||||||
|
const String ENV_APPLE_PLATFORM_PROFILE_UUID_DEBUG = "GODOT_APPLE_PLATFORM_PROVISIONING_PROFILE_UUID_DEBUG";
|
||||||
|
const String ENV_APPLE_PLATFORM_PROFILE_UUID_RELEASE = "GODOT_APPLE_PLATFORM_PROVISIONING_PROFILE_UUID_RELEASE";
|
||||||
|
const String ENV_APPLE_PLATFORM_PROFILE_SPECIFIER_DEBUG = "GODOT_APPLE_PLATFORM_PROFILE_SPECIFIER_DEBUG";
|
||||||
|
const String ENV_APPLE_PLATFORM_PROFILE_SPECIFIER_RELEASE = "GODOT_APPLE_PLATFORM_PROFILE_SPECIFIER_RELEASE";
|
||||||
|
|
||||||
|
static const String storyboard_image_scale_mode[] = {
|
||||||
|
"center",
|
||||||
|
"scaleAspectFit",
|
||||||
|
"scaleAspectFill",
|
||||||
|
"scaleToFill",
|
||||||
|
};
|
||||||
|
|
||||||
|
class EditorExportPlatformAppleEmbedded : public EditorExportPlatform {
|
||||||
|
GDCLASS(EditorExportPlatformAppleEmbedded, EditorExportPlatform);
|
||||||
|
|
||||||
|
Ref<ImageTexture> logo;
|
||||||
|
Ref<ImageTexture> run_icon;
|
||||||
|
|
||||||
|
// Plugins
|
||||||
|
mutable SafeFlag plugins_changed;
|
||||||
|
SafeFlag devices_changed;
|
||||||
|
|
||||||
|
struct Device {
|
||||||
|
String id;
|
||||||
|
String name;
|
||||||
|
bool wifi = false;
|
||||||
|
bool use_ios_deploy = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
Vector<Device> devices;
|
||||||
|
Mutex device_lock;
|
||||||
|
|
||||||
|
Mutex plugins_lock;
|
||||||
|
mutable Vector<PluginConfigAppleEmbedded> plugins;
|
||||||
|
#ifdef MACOS_ENABLED
|
||||||
|
Thread check_for_changes_thread;
|
||||||
|
SafeFlag quit_request;
|
||||||
|
SafeFlag has_runnable_preset;
|
||||||
|
|
||||||
|
static bool _check_xcode_install();
|
||||||
|
static void _check_for_changes_poll_thread(void *ud);
|
||||||
|
void _update_preset_status();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef Error (*FileHandler)(String p_file, void *p_userdata);
|
||||||
|
static Error _walk_dir_recursive(Ref<DirAccess> &p_da, FileHandler p_handler, void *p_userdata);
|
||||||
|
static Error _codesign(String p_file, void *p_userdata);
|
||||||
|
|
||||||
|
struct AppleEmbeddedConfigData {
|
||||||
|
String pkg_name;
|
||||||
|
String binary_name;
|
||||||
|
String plist_content;
|
||||||
|
String architectures;
|
||||||
|
String linker_flags;
|
||||||
|
String cpp_code;
|
||||||
|
String modules_buildfile;
|
||||||
|
String modules_fileref;
|
||||||
|
String modules_buildphase;
|
||||||
|
String modules_buildgrp;
|
||||||
|
Vector<String> capabilities;
|
||||||
|
bool use_swift_runtime;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ExportArchitecture {
|
||||||
|
String name;
|
||||||
|
bool is_default = false;
|
||||||
|
|
||||||
|
ExportArchitecture() {}
|
||||||
|
|
||||||
|
ExportArchitecture(String p_name, bool p_is_default) {
|
||||||
|
name = p_name;
|
||||||
|
is_default = p_is_default;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct AppleEmbeddedExportAsset {
|
||||||
|
String exported_path;
|
||||||
|
bool is_framework = false; // framework is anything linked to the binary, otherwise it's a resource
|
||||||
|
bool should_embed = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
String _get_additional_plist_content();
|
||||||
|
String _get_linker_flags();
|
||||||
|
String _get_cpp_code();
|
||||||
|
void _fix_config_file(const Ref<EditorExportPreset> &p_preset, Vector<uint8_t> &pfile, const AppleEmbeddedConfigData &p_config, bool p_debug);
|
||||||
|
|
||||||
|
Vector<ExportArchitecture> _get_supported_architectures() const;
|
||||||
|
Vector<String> _get_preset_architectures(const Ref<EditorExportPreset> &p_preset) 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;
|
||||||
|
|
||||||
|
void _add_assets_to_project(const String &p_out_dir, const Ref<EditorExportPreset> &p_preset, Vector<uint8_t> &p_project_data, const Vector<AppleEmbeddedExportAsset> &p_additional_assets);
|
||||||
|
Error _export_additional_assets(const Ref<EditorExportPreset> &p_preset, const String &p_out_dir, const Vector<String> &p_assets, bool p_is_framework, bool p_should_embed, Vector<AppleEmbeddedExportAsset> &r_exported_assets);
|
||||||
|
Error _copy_asset(const Ref<EditorExportPreset> &p_preset, const String &p_out_dir, const String &p_asset, const String *p_custom_file_name, bool p_is_framework, bool p_should_embed, Vector<AppleEmbeddedExportAsset> &r_exported_assets);
|
||||||
|
Error _export_additional_assets(const Ref<EditorExportPreset> &p_preset, const String &p_out_dir, const Vector<SharedObject> &p_libraries, Vector<AppleEmbeddedExportAsset> &r_exported_assets);
|
||||||
|
Error _export_apple_embedded_plugins(const Ref<EditorExportPreset> &p_preset, AppleEmbeddedConfigData &p_config_data, const String &dest_dir, Vector<AppleEmbeddedExportAsset> &r_exported_assets, bool p_debug);
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
struct IconInfo {
|
||||||
|
const char *preset_key;
|
||||||
|
const char *idiom;
|
||||||
|
const char *export_name;
|
||||||
|
const char *actual_size_side;
|
||||||
|
const char *scale;
|
||||||
|
const char *unscaled_size;
|
||||||
|
bool force_opaque;
|
||||||
|
};
|
||||||
|
|
||||||
|
void _blend_and_rotate(Ref<Image> &p_dst, Ref<Image> &p_src, bool p_rot);
|
||||||
|
|
||||||
|
virtual Error _export_loading_screen_file(const Ref<EditorExportPreset> &p_preset, const String &p_dest_dir) { return OK; }
|
||||||
|
virtual Error _export_icons(const Ref<EditorExportPreset> &p_preset, const String &p_iconset_dir) { return OK; }
|
||||||
|
|
||||||
|
virtual String get_platform_name() const = 0;
|
||||||
|
virtual String get_sdk_name() const = 0;
|
||||||
|
virtual String get_minimum_deployment_target() const = 0;
|
||||||
|
|
||||||
|
virtual void get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) const override;
|
||||||
|
virtual void get_export_options(List<ExportOption> *r_options) const override;
|
||||||
|
virtual bool get_export_option_visibility(const EditorExportPreset *p_preset, const String &p_option) const override;
|
||||||
|
virtual String get_export_option_warning(const EditorExportPreset *p_preset, const StringName &p_name) const override;
|
||||||
|
|
||||||
|
virtual Vector<IconInfo> get_icon_infos() const = 0;
|
||||||
|
|
||||||
|
void _notification(int p_what);
|
||||||
|
|
||||||
|
virtual void get_platform_features(List<String> *r_features) const override {
|
||||||
|
r_features->push_back("mobile");
|
||||||
|
r_features->push_back("apple_embedded");
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual Ref<Texture2D> get_logo() const override { return logo; }
|
||||||
|
virtual Ref<Texture2D> get_run_icon() const override { return run_icon; }
|
||||||
|
|
||||||
|
virtual int get_options_count() const override;
|
||||||
|
virtual String get_options_tooltip() const override;
|
||||||
|
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, BitField<EditorExportPlatform::DebugFlags> p_debug_flags) override;
|
||||||
|
|
||||||
|
virtual bool poll_export() override {
|
||||||
|
bool dc = devices_changed.is_set();
|
||||||
|
if (dc) {
|
||||||
|
// don't clear unless we're reporting true, to avoid race
|
||||||
|
devices_changed.clear();
|
||||||
|
}
|
||||||
|
return dc;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool should_update_export_options() override {
|
||||||
|
bool export_options_changed = plugins_changed.is_set();
|
||||||
|
if (export_options_changed) {
|
||||||
|
// don't clear unless we're reporting true, to avoid race
|
||||||
|
plugins_changed.clear();
|
||||||
|
}
|
||||||
|
return export_options_changed;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual List<String> get_binary_extensions(const Ref<EditorExportPreset> &p_preset) const override {
|
||||||
|
List<String> list;
|
||||||
|
if (p_preset.is_valid()) {
|
||||||
|
bool project_only = p_preset->get("application/export_project_only");
|
||||||
|
if (project_only) {
|
||||||
|
list.push_back("xcodeproj");
|
||||||
|
} else {
|
||||||
|
list.push_back("ipa");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
virtual void resolve_platform_feature_priorities(const Ref<EditorExportPreset> &p_preset, HashSet<String> &p_features) override {
|
||||||
|
}
|
||||||
|
|
||||||
|
EditorExportPlatformAppleEmbedded(const char *p_platform_logo_svg, const char *p_run_icon_svg);
|
||||||
|
~EditorExportPlatformAppleEmbedded();
|
||||||
|
|
||||||
|
/// List the gdip files in the directory specified by the p_path parameter.
|
||||||
|
static Vector<String> list_plugin_config_files(const String &p_path, bool p_check_directories) {
|
||||||
|
Vector<String> dir_files;
|
||||||
|
Ref<DirAccess> da = DirAccess::open(p_path);
|
||||||
|
if (da.is_valid()) {
|
||||||
|
da->list_dir_begin();
|
||||||
|
while (true) {
|
||||||
|
String file = da->get_next();
|
||||||
|
if (file.is_empty()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (file == "." || file == "..") {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (da->current_is_hidden()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (da->current_is_dir()) {
|
||||||
|
if (p_check_directories) {
|
||||||
|
Vector<String> directory_files = list_plugin_config_files(p_path.path_join(file), false);
|
||||||
|
for (int i = 0; i < directory_files.size(); ++i) {
|
||||||
|
dir_files.push_back(file.path_join(directory_files[i]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (file.ends_with(PluginConfigAppleEmbedded::PLUGIN_CONFIG_EXT)) {
|
||||||
|
dir_files.push_back(file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
da->list_dir_end();
|
||||||
|
}
|
||||||
|
|
||||||
|
return dir_files;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Vector<PluginConfigAppleEmbedded> get_plugins(const String &p_platform_name) {
|
||||||
|
Vector<PluginConfigAppleEmbedded> loaded_plugins;
|
||||||
|
|
||||||
|
String plugins_dir = ProjectSettings::get_singleton()->get_resource_path().path_join(p_platform_name + "/plugins");
|
||||||
|
|
||||||
|
if (DirAccess::exists(plugins_dir)) {
|
||||||
|
Vector<String> plugins_filenames = list_plugin_config_files(plugins_dir, true);
|
||||||
|
|
||||||
|
if (!plugins_filenames.is_empty()) {
|
||||||
|
Ref<ConfigFile> config_file;
|
||||||
|
for (int i = 0; i < plugins_filenames.size(); i++) {
|
||||||
|
PluginConfigAppleEmbedded config = PluginConfigAppleEmbedded::load_plugin_config(config_file, plugins_dir.path_join(plugins_filenames[i]));
|
||||||
|
if (config.valid_config) {
|
||||||
|
loaded_plugins.push_back(config);
|
||||||
|
} else {
|
||||||
|
print_error("Invalid plugin config file " + plugins_filenames[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return loaded_plugins;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Vector<PluginConfigAppleEmbedded> get_enabled_plugins(const String &p_platform_name, const Ref<EditorExportPreset> &p_presets) {
|
||||||
|
Vector<PluginConfigAppleEmbedded> enabled_plugins;
|
||||||
|
Vector<PluginConfigAppleEmbedded> all_plugins = get_plugins(p_platform_name);
|
||||||
|
for (int i = 0; i < all_plugins.size(); i++) {
|
||||||
|
PluginConfigAppleEmbedded plugin = all_plugins[i];
|
||||||
|
bool enabled = p_presets->get("plugins/" + plugin.name);
|
||||||
|
if (enabled) {
|
||||||
|
enabled_plugins.push_back(plugin);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return enabled_plugins;
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -67,55 +67,55 @@ void EditorExportPlugin::_add_shared_object(const SharedObject &p_shared_object)
|
|||||||
shared_objects.push_back(p_shared_object);
|
shared_objects.push_back(p_shared_object);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EditorExportPlugin::add_ios_framework(const String &p_path) {
|
void EditorExportPlugin::add_apple_embedded_platform_framework(const String &p_path) {
|
||||||
ios_frameworks.push_back(p_path);
|
apple_embedded_platform_frameworks.push_back(p_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EditorExportPlugin::add_ios_embedded_framework(const String &p_path) {
|
void EditorExportPlugin::add_apple_embedded_platform_embedded_framework(const String &p_path) {
|
||||||
ios_embedded_frameworks.push_back(p_path);
|
apple_embedded_platform_embedded_frameworks.push_back(p_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector<String> EditorExportPlugin::get_ios_frameworks() const {
|
Vector<String> EditorExportPlugin::get_apple_embedded_platform_frameworks() const {
|
||||||
return ios_frameworks;
|
return apple_embedded_platform_frameworks;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector<String> EditorExportPlugin::get_ios_embedded_frameworks() const {
|
Vector<String> EditorExportPlugin::get_apple_embedded_platform_embedded_frameworks() const {
|
||||||
return ios_embedded_frameworks;
|
return apple_embedded_platform_embedded_frameworks;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EditorExportPlugin::add_ios_plist_content(const String &p_plist_content) {
|
void EditorExportPlugin::add_apple_embedded_platform_plist_content(const String &p_plist_content) {
|
||||||
ios_plist_content += p_plist_content + "\n";
|
apple_embedded_platform_plist_content += p_plist_content + "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
String EditorExportPlugin::get_ios_plist_content() const {
|
String EditorExportPlugin::get_apple_embedded_platform_plist_content() const {
|
||||||
return ios_plist_content;
|
return apple_embedded_platform_plist_content;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EditorExportPlugin::add_ios_linker_flags(const String &p_flags) {
|
void EditorExportPlugin::add_apple_embedded_platform_linker_flags(const String &p_flags) {
|
||||||
if (ios_linker_flags.length() > 0) {
|
if (apple_embedded_platform_linker_flags.length() > 0) {
|
||||||
ios_linker_flags += ' ';
|
apple_embedded_platform_linker_flags += ' ';
|
||||||
}
|
}
|
||||||
ios_linker_flags += p_flags;
|
apple_embedded_platform_linker_flags += p_flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
String EditorExportPlugin::get_ios_linker_flags() const {
|
String EditorExportPlugin::get_apple_embedded_platform_linker_flags() const {
|
||||||
return ios_linker_flags;
|
return apple_embedded_platform_linker_flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EditorExportPlugin::add_ios_bundle_file(const String &p_path) {
|
void EditorExportPlugin::add_apple_embedded_platform_bundle_file(const String &p_path) {
|
||||||
ios_bundle_files.push_back(p_path);
|
apple_embedded_platform_bundle_files.push_back(p_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector<String> EditorExportPlugin::get_ios_bundle_files() const {
|
Vector<String> EditorExportPlugin::get_apple_embedded_platform_bundle_files() const {
|
||||||
return ios_bundle_files;
|
return apple_embedded_platform_bundle_files;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EditorExportPlugin::add_ios_cpp_code(const String &p_code) {
|
void EditorExportPlugin::add_apple_embedded_platform_cpp_code(const String &p_code) {
|
||||||
ios_cpp_code += p_code;
|
apple_embedded_platform_cpp_code += p_code;
|
||||||
}
|
}
|
||||||
|
|
||||||
String EditorExportPlugin::get_ios_cpp_code() const {
|
String EditorExportPlugin::get_apple_embedded_platform_cpp_code() const {
|
||||||
return ios_cpp_code;
|
return apple_embedded_platform_cpp_code;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EditorExportPlugin::add_macos_plugin_file(const String &p_path) {
|
void EditorExportPlugin::add_macos_plugin_file(const String &p_path) {
|
||||||
@@ -126,12 +126,12 @@ const Vector<String> &EditorExportPlugin::get_macos_plugin_files() const {
|
|||||||
return macos_plugin_files;
|
return macos_plugin_files;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EditorExportPlugin::add_ios_project_static_lib(const String &p_path) {
|
void EditorExportPlugin::add_apple_embedded_platform_project_static_lib(const String &p_path) {
|
||||||
ios_project_static_libs.push_back(p_path);
|
apple_embedded_platform_project_static_libs.push_back(p_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector<String> EditorExportPlugin::get_ios_project_static_libs() const {
|
Vector<String> EditorExportPlugin::get_apple_embedded_platform_project_static_libs() const {
|
||||||
return ios_project_static_libs;
|
return apple_embedded_platform_project_static_libs;
|
||||||
}
|
}
|
||||||
|
|
||||||
Variant EditorExportPlugin::get_option(const StringName &p_name) const {
|
Variant EditorExportPlugin::get_option(const StringName &p_name) const {
|
||||||
@@ -328,14 +328,26 @@ void EditorExportPlugin::skip() {
|
|||||||
|
|
||||||
void EditorExportPlugin::_bind_methods() {
|
void EditorExportPlugin::_bind_methods() {
|
||||||
ClassDB::bind_method(D_METHOD("add_shared_object", "path", "tags", "target"), &EditorExportPlugin::add_shared_object);
|
ClassDB::bind_method(D_METHOD("add_shared_object", "path", "tags", "target"), &EditorExportPlugin::add_shared_object);
|
||||||
ClassDB::bind_method(D_METHOD("add_ios_project_static_lib", "path"), &EditorExportPlugin::add_ios_project_static_lib);
|
|
||||||
ClassDB::bind_method(D_METHOD("add_file", "path", "file", "remap"), &EditorExportPlugin::add_file);
|
ClassDB::bind_method(D_METHOD("add_file", "path", "file", "remap"), &EditorExportPlugin::add_file);
|
||||||
ClassDB::bind_method(D_METHOD("add_ios_framework", "path"), &EditorExportPlugin::add_ios_framework);
|
|
||||||
ClassDB::bind_method(D_METHOD("add_ios_embedded_framework", "path"), &EditorExportPlugin::add_ios_embedded_framework);
|
ClassDB::bind_method(D_METHOD("add_apple_embedded_platform_project_static_lib", "path"), &EditorExportPlugin::add_apple_embedded_platform_project_static_lib);
|
||||||
ClassDB::bind_method(D_METHOD("add_ios_plist_content", "plist_content"), &EditorExportPlugin::add_ios_plist_content);
|
ClassDB::bind_method(D_METHOD("add_apple_embedded_platform_framework", "path"), &EditorExportPlugin::add_apple_embedded_platform_framework);
|
||||||
ClassDB::bind_method(D_METHOD("add_ios_linker_flags", "flags"), &EditorExportPlugin::add_ios_linker_flags);
|
ClassDB::bind_method(D_METHOD("add_apple_embedded_platform_embedded_framework", "path"), &EditorExportPlugin::add_apple_embedded_platform_embedded_framework);
|
||||||
ClassDB::bind_method(D_METHOD("add_ios_bundle_file", "path"), &EditorExportPlugin::add_ios_bundle_file);
|
ClassDB::bind_method(D_METHOD("add_apple_embedded_platform_plist_content", "plist_content"), &EditorExportPlugin::add_apple_embedded_platform_plist_content);
|
||||||
ClassDB::bind_method(D_METHOD("add_ios_cpp_code", "code"), &EditorExportPlugin::add_ios_cpp_code);
|
ClassDB::bind_method(D_METHOD("add_apple_embedded_platform_linker_flags", "flags"), &EditorExportPlugin::add_apple_embedded_platform_linker_flags);
|
||||||
|
ClassDB::bind_method(D_METHOD("add_apple_embedded_platform_bundle_file", "path"), &EditorExportPlugin::add_apple_embedded_platform_bundle_file);
|
||||||
|
ClassDB::bind_method(D_METHOD("add_apple_embedded_platform_cpp_code", "code"), &EditorExportPlugin::add_apple_embedded_platform_cpp_code);
|
||||||
|
|
||||||
|
#ifndef DISABLE_DEPRECATED
|
||||||
|
ClassDB::bind_method(D_METHOD("add_ios_project_static_lib", "path"), &EditorExportPlugin::add_apple_embedded_platform_project_static_lib);
|
||||||
|
ClassDB::bind_method(D_METHOD("add_ios_framework", "path"), &EditorExportPlugin::add_apple_embedded_platform_framework);
|
||||||
|
ClassDB::bind_method(D_METHOD("add_ios_embedded_framework", "path"), &EditorExportPlugin::add_apple_embedded_platform_embedded_framework);
|
||||||
|
ClassDB::bind_method(D_METHOD("add_ios_plist_content", "plist_content"), &EditorExportPlugin::add_apple_embedded_platform_plist_content);
|
||||||
|
ClassDB::bind_method(D_METHOD("add_ios_linker_flags", "flags"), &EditorExportPlugin::add_apple_embedded_platform_linker_flags);
|
||||||
|
ClassDB::bind_method(D_METHOD("add_ios_bundle_file", "path"), &EditorExportPlugin::add_apple_embedded_platform_bundle_file);
|
||||||
|
ClassDB::bind_method(D_METHOD("add_ios_cpp_code", "code"), &EditorExportPlugin::add_apple_embedded_platform_cpp_code);
|
||||||
|
#endif
|
||||||
|
|
||||||
ClassDB::bind_method(D_METHOD("add_macos_plugin_file", "path"), &EditorExportPlugin::add_macos_plugin_file);
|
ClassDB::bind_method(D_METHOD("add_macos_plugin_file", "path"), &EditorExportPlugin::add_macos_plugin_file);
|
||||||
ClassDB::bind_method(D_METHOD("skip"), &EditorExportPlugin::skip);
|
ClassDB::bind_method(D_METHOD("skip"), &EditorExportPlugin::skip);
|
||||||
ClassDB::bind_method(D_METHOD("get_option", "name"), &EditorExportPlugin::get_option);
|
ClassDB::bind_method(D_METHOD("get_option", "name"), &EditorExportPlugin::get_option);
|
||||||
|
|||||||
@@ -53,13 +53,13 @@ class EditorExportPlugin : public RefCounted {
|
|||||||
Vector<ExtraFile> extra_files;
|
Vector<ExtraFile> extra_files;
|
||||||
bool skipped = false;
|
bool skipped = false;
|
||||||
|
|
||||||
Vector<String> ios_frameworks;
|
Vector<String> apple_embedded_platform_frameworks;
|
||||||
Vector<String> ios_embedded_frameworks;
|
Vector<String> apple_embedded_platform_embedded_frameworks;
|
||||||
Vector<String> ios_project_static_libs;
|
Vector<String> apple_embedded_platform_project_static_libs;
|
||||||
String ios_plist_content;
|
String apple_embedded_platform_plist_content;
|
||||||
String ios_linker_flags;
|
String apple_embedded_platform_linker_flags;
|
||||||
Vector<String> ios_bundle_files;
|
Vector<String> apple_embedded_platform_bundle_files;
|
||||||
String ios_cpp_code;
|
String apple_embedded_platform_cpp_code;
|
||||||
|
|
||||||
Vector<String> macos_plugin_files;
|
Vector<String> macos_plugin_files;
|
||||||
|
|
||||||
@@ -70,12 +70,12 @@ class EditorExportPlugin : public RefCounted {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_FORCE_INLINE_ void _export_end_clear() {
|
_FORCE_INLINE_ void _export_end_clear() {
|
||||||
ios_frameworks.clear();
|
apple_embedded_platform_frameworks.clear();
|
||||||
ios_embedded_frameworks.clear();
|
apple_embedded_platform_embedded_frameworks.clear();
|
||||||
ios_bundle_files.clear();
|
apple_embedded_platform_bundle_files.clear();
|
||||||
ios_plist_content = "";
|
apple_embedded_platform_plist_content = "";
|
||||||
ios_linker_flags = "";
|
apple_embedded_platform_linker_flags = "";
|
||||||
ios_cpp_code = "";
|
apple_embedded_platform_cpp_code = "";
|
||||||
macos_plugin_files.clear();
|
macos_plugin_files.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -95,13 +95,13 @@ protected:
|
|||||||
void add_shared_object(const String &p_path, const Vector<String> &tags, const String &p_target = String());
|
void add_shared_object(const String &p_path, const Vector<String> &tags, const String &p_target = String());
|
||||||
void _add_shared_object(const SharedObject &p_shared_object);
|
void _add_shared_object(const SharedObject &p_shared_object);
|
||||||
|
|
||||||
void add_ios_framework(const String &p_path);
|
void add_apple_embedded_platform_framework(const String &p_path);
|
||||||
void add_ios_embedded_framework(const String &p_path);
|
void add_apple_embedded_platform_embedded_framework(const String &p_path);
|
||||||
void add_ios_project_static_lib(const String &p_path);
|
void add_apple_embedded_platform_project_static_lib(const String &p_path);
|
||||||
void add_ios_plist_content(const String &p_plist_content);
|
void add_apple_embedded_platform_plist_content(const String &p_plist_content);
|
||||||
void add_ios_linker_flags(const String &p_flags);
|
void add_apple_embedded_platform_linker_flags(const String &p_flags);
|
||||||
void add_ios_bundle_file(const String &p_path);
|
void add_apple_embedded_platform_bundle_file(const String &p_path);
|
||||||
void add_ios_cpp_code(const String &p_code);
|
void add_apple_embedded_platform_cpp_code(const String &p_code);
|
||||||
void add_macos_plugin_file(const String &p_path);
|
void add_macos_plugin_file(const String &p_path);
|
||||||
|
|
||||||
void skip();
|
void skip();
|
||||||
@@ -177,13 +177,13 @@ public:
|
|||||||
virtual String get_android_manifest_element_contents(const Ref<EditorExportPlatform> &p_export_platform, bool p_debug) const;
|
virtual String get_android_manifest_element_contents(const Ref<EditorExportPlatform> &p_export_platform, bool p_debug) const;
|
||||||
virtual PackedByteArray update_android_prebuilt_manifest(const Ref<EditorExportPlatform> &p_export_platform, const PackedByteArray &p_manifest_data) const;
|
virtual PackedByteArray update_android_prebuilt_manifest(const Ref<EditorExportPlatform> &p_export_platform, const PackedByteArray &p_manifest_data) const;
|
||||||
|
|
||||||
Vector<String> get_ios_frameworks() const;
|
Vector<String> get_apple_embedded_platform_frameworks() const;
|
||||||
Vector<String> get_ios_embedded_frameworks() const;
|
Vector<String> get_apple_embedded_platform_embedded_frameworks() const;
|
||||||
Vector<String> get_ios_project_static_libs() const;
|
Vector<String> get_apple_embedded_platform_project_static_libs() const;
|
||||||
String get_ios_plist_content() const;
|
String get_apple_embedded_platform_plist_content() const;
|
||||||
String get_ios_linker_flags() const;
|
String get_apple_embedded_platform_linker_flags() const;
|
||||||
Vector<String> get_ios_bundle_files() const;
|
Vector<String> get_apple_embedded_platform_bundle_files() const;
|
||||||
String get_ios_cpp_code() const;
|
String get_apple_embedded_platform_cpp_code() const;
|
||||||
const Vector<String> &get_macos_plugin_files() const;
|
const Vector<String> &get_macos_plugin_files() const;
|
||||||
Variant get_option(const StringName &p_name) const;
|
Variant get_option(const StringName &p_name) const;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -111,6 +111,8 @@ public:
|
|||||||
PLATFORM_TVOSSIMULATOR = 8,
|
PLATFORM_TVOSSIMULATOR = 8,
|
||||||
PLATFORM_WATCHOSSIMULATOR = 9,
|
PLATFORM_WATCHOSSIMULATOR = 9,
|
||||||
PLATFORM_DRIVERKIT = 10,
|
PLATFORM_DRIVERKIT = 10,
|
||||||
|
PLATFORM_VISIONOS = 11,
|
||||||
|
PLATFORM_VISIONOSSIMULATOR = 12,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct LoadCommandHeader {
|
struct LoadCommandHeader {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
/* godot_plugin_config.cpp */
|
/* plugin_config_apple_embedded.cpp */
|
||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
/* This file is part of: */
|
/* This file is part of: */
|
||||||
/* GODOT ENGINE */
|
/* GODOT ENGINE */
|
||||||
@@ -28,13 +28,13 @@
|
|||||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
|
|
||||||
#include "godot_plugin_config.h"
|
#include "plugin_config_apple_embedded.h"
|
||||||
|
|
||||||
#include "core/config/project_settings.h"
|
#include "core/config/project_settings.h"
|
||||||
#include "core/io/dir_access.h"
|
#include "core/io/dir_access.h"
|
||||||
#include "core/io/file_access.h"
|
#include "core/io/file_access.h"
|
||||||
|
|
||||||
String PluginConfigIOS::resolve_local_dependency_path(String plugin_config_dir, String dependency_path) {
|
String PluginConfigAppleEmbedded::resolve_local_dependency_path(String plugin_config_dir, String dependency_path) {
|
||||||
String absolute_path;
|
String absolute_path;
|
||||||
|
|
||||||
if (dependency_path.is_empty()) {
|
if (dependency_path.is_empty()) {
|
||||||
@@ -51,7 +51,7 @@ String PluginConfigIOS::resolve_local_dependency_path(String plugin_config_dir,
|
|||||||
return absolute_path.replace(res_path, "res://");
|
return absolute_path.replace(res_path, "res://");
|
||||||
}
|
}
|
||||||
|
|
||||||
String PluginConfigIOS::resolve_system_dependency_path(String dependency_path) {
|
String PluginConfigAppleEmbedded::resolve_system_dependency_path(String dependency_path) {
|
||||||
String absolute_path;
|
String absolute_path;
|
||||||
|
|
||||||
if (dependency_path.is_empty()) {
|
if (dependency_path.is_empty()) {
|
||||||
@@ -67,7 +67,7 @@ String PluginConfigIOS::resolve_system_dependency_path(String dependency_path) {
|
|||||||
return system_path.path_join(dependency_path);
|
return system_path.path_join(dependency_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector<String> PluginConfigIOS::resolve_local_dependencies(String plugin_config_dir, Vector<String> p_paths) {
|
Vector<String> PluginConfigAppleEmbedded::resolve_local_dependencies(String plugin_config_dir, Vector<String> p_paths) {
|
||||||
Vector<String> paths;
|
Vector<String> paths;
|
||||||
|
|
||||||
for (int i = 0; i < p_paths.size(); i++) {
|
for (int i = 0; i < p_paths.size(); i++) {
|
||||||
@@ -83,7 +83,7 @@ Vector<String> PluginConfigIOS::resolve_local_dependencies(String plugin_config_
|
|||||||
return paths;
|
return paths;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector<String> PluginConfigIOS::resolve_system_dependencies(Vector<String> p_paths) {
|
Vector<String> PluginConfigAppleEmbedded::resolve_system_dependencies(Vector<String> p_paths) {
|
||||||
Vector<String> paths;
|
Vector<String> paths;
|
||||||
|
|
||||||
for (int i = 0; i < p_paths.size(); i++) {
|
for (int i = 0; i < p_paths.size(); i++) {
|
||||||
@@ -99,7 +99,7 @@ Vector<String> PluginConfigIOS::resolve_system_dependencies(Vector<String> p_pat
|
|||||||
return paths;
|
return paths;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PluginConfigIOS::validate_plugin(PluginConfigIOS &plugin_config) {
|
bool PluginConfigAppleEmbedded::validate_plugin(PluginConfigAppleEmbedded &plugin_config) {
|
||||||
bool valid_name = !plugin_config.name.is_empty();
|
bool valid_name = !plugin_config.name.is_empty();
|
||||||
bool valid_binary_name = !plugin_config.binary.is_empty();
|
bool valid_binary_name = !plugin_config.binary.is_empty();
|
||||||
bool valid_initialize = !plugin_config.initialization_method.is_empty();
|
bool valid_initialize = !plugin_config.initialization_method.is_empty();
|
||||||
@@ -134,7 +134,7 @@ bool PluginConfigIOS::validate_plugin(PluginConfigIOS &plugin_config) {
|
|||||||
return plugin_config.valid_config;
|
return plugin_config.valid_config;
|
||||||
}
|
}
|
||||||
|
|
||||||
String PluginConfigIOS::get_plugin_main_binary(PluginConfigIOS &plugin_config, bool p_debug) {
|
String PluginConfigAppleEmbedded::get_plugin_main_binary(PluginConfigAppleEmbedded &plugin_config, bool p_debug) {
|
||||||
if (!plugin_config.supports_targets) {
|
if (!plugin_config.supports_targets) {
|
||||||
return plugin_config.binary;
|
return plugin_config.binary;
|
||||||
}
|
}
|
||||||
@@ -147,7 +147,7 @@ String PluginConfigIOS::get_plugin_main_binary(PluginConfigIOS &plugin_config, b
|
|||||||
return plugin_binary_dir.path_join(plugin_file);
|
return plugin_binary_dir.path_join(plugin_file);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t PluginConfigIOS::get_plugin_modification_time(const PluginConfigIOS &plugin_config, const String &config_path) {
|
uint64_t PluginConfigAppleEmbedded::get_plugin_modification_time(const PluginConfigAppleEmbedded &plugin_config, const String &config_path) {
|
||||||
uint64_t last_updated = FileAccess::get_modified_time(config_path);
|
uint64_t last_updated = FileAccess::get_modified_time(config_path);
|
||||||
|
|
||||||
if (!plugin_config.supports_targets) {
|
if (!plugin_config.supports_targets) {
|
||||||
@@ -166,8 +166,8 @@ uint64_t PluginConfigIOS::get_plugin_modification_time(const PluginConfigIOS &pl
|
|||||||
return last_updated;
|
return last_updated;
|
||||||
}
|
}
|
||||||
|
|
||||||
PluginConfigIOS PluginConfigIOS::load_plugin_config(Ref<ConfigFile> config_file, const String &path) {
|
PluginConfigAppleEmbedded PluginConfigAppleEmbedded::load_plugin_config(Ref<ConfigFile> config_file, const String &path) {
|
||||||
PluginConfigIOS plugin_config = {};
|
PluginConfigAppleEmbedded plugin_config = {};
|
||||||
|
|
||||||
if (config_file.is_null()) {
|
if (config_file.is_null()) {
|
||||||
return plugin_config;
|
return plugin_config;
|
||||||
@@ -183,19 +183,19 @@ PluginConfigIOS PluginConfigIOS::load_plugin_config(Ref<ConfigFile> config_file,
|
|||||||
|
|
||||||
String config_base_dir = path.get_base_dir();
|
String config_base_dir = path.get_base_dir();
|
||||||
|
|
||||||
plugin_config.name = config_file->get_value(PluginConfigIOS::CONFIG_SECTION, PluginConfigIOS::CONFIG_NAME_KEY, String());
|
plugin_config.name = config_file->get_value(PluginConfigAppleEmbedded::CONFIG_SECTION, PluginConfigAppleEmbedded::CONFIG_NAME_KEY, String());
|
||||||
plugin_config.use_swift_runtime = config_file->get_value(PluginConfigIOS::CONFIG_SECTION, PluginConfigIOS::CONFIG_USE_SWIFT_KEY, false);
|
plugin_config.use_swift_runtime = config_file->get_value(PluginConfigAppleEmbedded::CONFIG_SECTION, PluginConfigAppleEmbedded::CONFIG_USE_SWIFT_KEY, false);
|
||||||
plugin_config.initialization_method = config_file->get_value(PluginConfigIOS::CONFIG_SECTION, PluginConfigIOS::CONFIG_INITIALIZE_KEY, String());
|
plugin_config.initialization_method = config_file->get_value(PluginConfigAppleEmbedded::CONFIG_SECTION, PluginConfigAppleEmbedded::CONFIG_INITIALIZE_KEY, String());
|
||||||
plugin_config.deinitialization_method = config_file->get_value(PluginConfigIOS::CONFIG_SECTION, PluginConfigIOS::CONFIG_DEINITIALIZE_KEY, String());
|
plugin_config.deinitialization_method = config_file->get_value(PluginConfigAppleEmbedded::CONFIG_SECTION, PluginConfigAppleEmbedded::CONFIG_DEINITIALIZE_KEY, String());
|
||||||
|
|
||||||
String binary_path = config_file->get_value(PluginConfigIOS::CONFIG_SECTION, PluginConfigIOS::CONFIG_BINARY_KEY, String());
|
String binary_path = config_file->get_value(PluginConfigAppleEmbedded::CONFIG_SECTION, PluginConfigAppleEmbedded::CONFIG_BINARY_KEY, String());
|
||||||
plugin_config.binary = resolve_local_dependency_path(config_base_dir, binary_path);
|
plugin_config.binary = resolve_local_dependency_path(config_base_dir, binary_path);
|
||||||
|
|
||||||
if (config_file->has_section(PluginConfigIOS::DEPENDENCIES_SECTION)) {
|
if (config_file->has_section(PluginConfigAppleEmbedded::DEPENDENCIES_SECTION)) {
|
||||||
Vector<String> linked_dependencies = config_file->get_value(PluginConfigIOS::DEPENDENCIES_SECTION, PluginConfigIOS::DEPENDENCIES_LINKED_KEY, Vector<String>());
|
Vector<String> linked_dependencies = config_file->get_value(PluginConfigAppleEmbedded::DEPENDENCIES_SECTION, PluginConfigAppleEmbedded::DEPENDENCIES_LINKED_KEY, Vector<String>());
|
||||||
Vector<String> embedded_dependencies = config_file->get_value(PluginConfigIOS::DEPENDENCIES_SECTION, PluginConfigIOS::DEPENDENCIES_EMBEDDED_KEY, Vector<String>());
|
Vector<String> embedded_dependencies = config_file->get_value(PluginConfigAppleEmbedded::DEPENDENCIES_SECTION, PluginConfigAppleEmbedded::DEPENDENCIES_EMBEDDED_KEY, Vector<String>());
|
||||||
Vector<String> system_dependencies = config_file->get_value(PluginConfigIOS::DEPENDENCIES_SECTION, PluginConfigIOS::DEPENDENCIES_SYSTEM_KEY, Vector<String>());
|
Vector<String> system_dependencies = config_file->get_value(PluginConfigAppleEmbedded::DEPENDENCIES_SECTION, PluginConfigAppleEmbedded::DEPENDENCIES_SYSTEM_KEY, Vector<String>());
|
||||||
Vector<String> files = config_file->get_value(PluginConfigIOS::DEPENDENCIES_SECTION, PluginConfigIOS::DEPENDENCIES_FILES_KEY, Vector<String>());
|
Vector<String> files = config_file->get_value(PluginConfigAppleEmbedded::DEPENDENCIES_SECTION, PluginConfigAppleEmbedded::DEPENDENCIES_FILES_KEY, Vector<String>());
|
||||||
|
|
||||||
plugin_config.linked_dependencies = resolve_local_dependencies(config_base_dir, linked_dependencies);
|
plugin_config.linked_dependencies = resolve_local_dependencies(config_base_dir, linked_dependencies);
|
||||||
plugin_config.embedded_dependencies = resolve_local_dependencies(config_base_dir, embedded_dependencies);
|
plugin_config.embedded_dependencies = resolve_local_dependencies(config_base_dir, embedded_dependencies);
|
||||||
@@ -203,77 +203,77 @@ PluginConfigIOS PluginConfigIOS::load_plugin_config(Ref<ConfigFile> config_file,
|
|||||||
|
|
||||||
plugin_config.files_to_copy = resolve_local_dependencies(config_base_dir, files);
|
plugin_config.files_to_copy = resolve_local_dependencies(config_base_dir, files);
|
||||||
|
|
||||||
plugin_config.capabilities = config_file->get_value(PluginConfigIOS::DEPENDENCIES_SECTION, PluginConfigIOS::DEPENDENCIES_CAPABILITIES_KEY, Vector<String>());
|
plugin_config.capabilities = config_file->get_value(PluginConfigAppleEmbedded::DEPENDENCIES_SECTION, PluginConfigAppleEmbedded::DEPENDENCIES_CAPABILITIES_KEY, Vector<String>());
|
||||||
|
|
||||||
plugin_config.linker_flags = config_file->get_value(PluginConfigIOS::DEPENDENCIES_SECTION, PluginConfigIOS::DEPENDENCIES_LINKER_FLAGS, Vector<String>());
|
plugin_config.linker_flags = config_file->get_value(PluginConfigAppleEmbedded::DEPENDENCIES_SECTION, PluginConfigAppleEmbedded::DEPENDENCIES_LINKER_FLAGS, Vector<String>());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config_file->has_section(PluginConfigIOS::PLIST_SECTION)) {
|
if (config_file->has_section(PluginConfigAppleEmbedded::PLIST_SECTION)) {
|
||||||
Vector<String> keys = config_file->get_section_keys(PluginConfigIOS::PLIST_SECTION);
|
Vector<String> keys = config_file->get_section_keys(PluginConfigAppleEmbedded::PLIST_SECTION);
|
||||||
|
|
||||||
for (const String &key : keys) {
|
for (const String &key : keys) {
|
||||||
Vector<String> key_components = key.split(":");
|
Vector<String> key_components = key.split(":");
|
||||||
|
|
||||||
String key_value = "";
|
String key_value = "";
|
||||||
PluginConfigIOS::PlistItemType key_type = PluginConfigIOS::PlistItemType::UNKNOWN;
|
PluginConfigAppleEmbedded::PlistItemType key_type = PluginConfigAppleEmbedded::PlistItemType::UNKNOWN;
|
||||||
|
|
||||||
if (key_components.size() == 1) {
|
if (key_components.size() == 1) {
|
||||||
key_value = key_components[0];
|
key_value = key_components[0];
|
||||||
key_type = PluginConfigIOS::PlistItemType::STRING;
|
key_type = PluginConfigAppleEmbedded::PlistItemType::STRING;
|
||||||
} else if (key_components.size() == 2) {
|
} else if (key_components.size() == 2) {
|
||||||
key_value = key_components[0];
|
key_value = key_components[0];
|
||||||
|
|
||||||
if (key_components[1].to_lower() == "string") {
|
if (key_components[1].to_lower() == "string") {
|
||||||
key_type = PluginConfigIOS::PlistItemType::STRING;
|
key_type = PluginConfigAppleEmbedded::PlistItemType::STRING;
|
||||||
} else if (key_components[1].to_lower() == "integer") {
|
} else if (key_components[1].to_lower() == "integer") {
|
||||||
key_type = PluginConfigIOS::PlistItemType::INTEGER;
|
key_type = PluginConfigAppleEmbedded::PlistItemType::INTEGER;
|
||||||
} else if (key_components[1].to_lower() == "boolean") {
|
} else if (key_components[1].to_lower() == "boolean") {
|
||||||
key_type = PluginConfigIOS::PlistItemType::BOOLEAN;
|
key_type = PluginConfigAppleEmbedded::PlistItemType::BOOLEAN;
|
||||||
} else if (key_components[1].to_lower() == "raw") {
|
} else if (key_components[1].to_lower() == "raw") {
|
||||||
key_type = PluginConfigIOS::PlistItemType::RAW;
|
key_type = PluginConfigAppleEmbedded::PlistItemType::RAW;
|
||||||
} else if (key_components[1].to_lower() == "string_input") {
|
} else if (key_components[1].to_lower() == "string_input") {
|
||||||
key_type = PluginConfigIOS::PlistItemType::STRING_INPUT;
|
key_type = PluginConfigAppleEmbedded::PlistItemType::STRING_INPUT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (key_value.is_empty() || key_type == PluginConfigIOS::PlistItemType::UNKNOWN) {
|
if (key_value.is_empty() || key_type == PluginConfigAppleEmbedded::PlistItemType::UNKNOWN) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
String value;
|
String value;
|
||||||
|
|
||||||
switch (key_type) {
|
switch (key_type) {
|
||||||
case PluginConfigIOS::PlistItemType::STRING: {
|
case PluginConfigAppleEmbedded::PlistItemType::STRING: {
|
||||||
String raw_value = config_file->get_value(PluginConfigIOS::PLIST_SECTION, key, String());
|
String raw_value = config_file->get_value(PluginConfigAppleEmbedded::PLIST_SECTION, key, String());
|
||||||
value = "<string>" + raw_value + "</string>";
|
value = "<string>" + raw_value + "</string>";
|
||||||
} break;
|
} break;
|
||||||
case PluginConfigIOS::PlistItemType::INTEGER: {
|
case PluginConfigAppleEmbedded::PlistItemType::INTEGER: {
|
||||||
int raw_value = config_file->get_value(PluginConfigIOS::PLIST_SECTION, key, 0);
|
int raw_value = config_file->get_value(PluginConfigAppleEmbedded::PLIST_SECTION, key, 0);
|
||||||
Dictionary value_dictionary;
|
Dictionary value_dictionary;
|
||||||
String value_format = "<integer>$value</integer>";
|
String value_format = "<integer>$value</integer>";
|
||||||
value_dictionary["value"] = raw_value;
|
value_dictionary["value"] = raw_value;
|
||||||
value = value_format.format(value_dictionary, "$_");
|
value = value_format.format(value_dictionary, "$_");
|
||||||
} break;
|
} break;
|
||||||
case PluginConfigIOS::PlistItemType::BOOLEAN:
|
case PluginConfigAppleEmbedded::PlistItemType::BOOLEAN:
|
||||||
if (config_file->get_value(PluginConfigIOS::PLIST_SECTION, key, false)) {
|
if (config_file->get_value(PluginConfigAppleEmbedded::PLIST_SECTION, key, false)) {
|
||||||
value = "<true/>";
|
value = "<true/>";
|
||||||
} else {
|
} else {
|
||||||
value = "<false/>";
|
value = "<false/>";
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case PluginConfigIOS::PlistItemType::RAW: {
|
case PluginConfigAppleEmbedded::PlistItemType::RAW: {
|
||||||
String raw_value = config_file->get_value(PluginConfigIOS::PLIST_SECTION, key, String());
|
String raw_value = config_file->get_value(PluginConfigAppleEmbedded::PLIST_SECTION, key, String());
|
||||||
value = raw_value;
|
value = raw_value;
|
||||||
} break;
|
} break;
|
||||||
case PluginConfigIOS::PlistItemType::STRING_INPUT: {
|
case PluginConfigAppleEmbedded::PlistItemType::STRING_INPUT: {
|
||||||
String raw_value = config_file->get_value(PluginConfigIOS::PLIST_SECTION, key, String());
|
String raw_value = config_file->get_value(PluginConfigAppleEmbedded::PLIST_SECTION, key, String());
|
||||||
value = raw_value;
|
value = raw_value;
|
||||||
} break;
|
} break;
|
||||||
default:
|
default:
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
plugin_config.plist[key_value] = PluginConfigIOS::PlistItem{ key_type, value };
|
plugin_config.plist[key_value] = PluginConfigAppleEmbedded::PlistItem{ key_type, value };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
/* godot_plugin_config.h */
|
/* plugin_config_apple_embedded.h */
|
||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
/* This file is part of: */
|
/* This file is part of: */
|
||||||
/* GODOT ENGINE */
|
/* GODOT ENGINE */
|
||||||
@@ -50,7 +50,7 @@ The `plist` section are optional.
|
|||||||
- **key**: key and value that would be added in Info.plist file.
|
- **key**: key and value that would be added in Info.plist file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
struct PluginConfigIOS {
|
struct PluginConfigAppleEmbedded {
|
||||||
inline static const char *PLUGIN_CONFIG_EXT = ".gdip";
|
inline static const char *PLUGIN_CONFIG_EXT = ".gdip";
|
||||||
|
|
||||||
inline static const char *CONFIG_SECTION = "config";
|
inline static const char *CONFIG_SECTION = "config";
|
||||||
@@ -121,11 +121,11 @@ struct PluginConfigIOS {
|
|||||||
|
|
||||||
static Vector<String> resolve_system_dependencies(Vector<String> p_paths);
|
static Vector<String> resolve_system_dependencies(Vector<String> p_paths);
|
||||||
|
|
||||||
static bool validate_plugin(PluginConfigIOS &plugin_config);
|
static bool validate_plugin(PluginConfigAppleEmbedded &plugin_config);
|
||||||
|
|
||||||
static String get_plugin_main_binary(PluginConfigIOS &plugin_config, bool p_debug);
|
static String get_plugin_main_binary(PluginConfigAppleEmbedded &plugin_config, bool p_debug);
|
||||||
|
|
||||||
static uint64_t get_plugin_modification_time(const PluginConfigIOS &plugin_config, const String &config_path);
|
static uint64_t get_plugin_modification_time(const PluginConfigAppleEmbedded &plugin_config, const String &config_path);
|
||||||
|
|
||||||
static PluginConfigIOS load_plugin_config(Ref<ConfigFile> config_file, const String &path);
|
static PluginConfigAppleEmbedded load_plugin_config(Ref<ConfigFile> config_file, const String &path);
|
||||||
};
|
};
|
||||||
@@ -115,9 +115,9 @@ void GDExtensionExportPlugin::_export_file(const String &p_path, const String &p
|
|||||||
libs_added.insert(library_path);
|
libs_added.insert(library_path);
|
||||||
add_shared_object(library_path, tags);
|
add_shared_object(library_path, tags);
|
||||||
|
|
||||||
if (p_features.has("ios") && (library_path.ends_with(".a") || library_path.ends_with(".xcframework"))) {
|
if (p_features.has("apple_embedded") && (library_path.ends_with(".a") || library_path.ends_with(".xcframework"))) {
|
||||||
String additional_code = "extern void register_dynamic_symbol(char *name, void *address);\n"
|
String additional_code = "extern void register_dynamic_symbol(char *name, void *address);\n"
|
||||||
"extern void add_ios_init_callback(void (*cb)());\n"
|
"extern void add_apple_embedded_platform_init_callback(void (*cb)());\n"
|
||||||
"\n"
|
"\n"
|
||||||
"extern \"C\" void $ENTRY();\n"
|
"extern \"C\" void $ENTRY();\n"
|
||||||
"void $ENTRY_init() {\n"
|
"void $ENTRY_init() {\n"
|
||||||
@@ -125,15 +125,15 @@ void GDExtensionExportPlugin::_export_file(const String &p_path, const String &p
|
|||||||
"}\n"
|
"}\n"
|
||||||
"struct $ENTRY_struct {\n"
|
"struct $ENTRY_struct {\n"
|
||||||
" $ENTRY_struct() {\n"
|
" $ENTRY_struct() {\n"
|
||||||
" add_ios_init_callback($ENTRY_init);\n"
|
" add_apple_embedded_platform_init_callback($ENTRY_init);\n"
|
||||||
" }\n"
|
" }\n"
|
||||||
"};\n"
|
"};\n"
|
||||||
"$ENTRY_struct $ENTRY_struct_instance;\n\n";
|
"$ENTRY_struct $ENTRY_struct_instance;\n\n";
|
||||||
additional_code = additional_code.replace("$ENTRY", entry_symbol);
|
additional_code = additional_code.replace("$ENTRY", entry_symbol);
|
||||||
add_ios_cpp_code(additional_code);
|
add_apple_embedded_platform_cpp_code(additional_code);
|
||||||
|
|
||||||
String linker_flags = "-Wl,-U,_" + entry_symbol;
|
String linker_flags = "-Wl,-U,_" + entry_symbol;
|
||||||
add_ios_linker_flags(linker_flags);
|
add_apple_embedded_platform_linker_flags(linker_flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update found library info.
|
// Update found library info.
|
||||||
|
|||||||
@@ -195,7 +195,7 @@ LightmapGIEditorPlugin::LightmapGIEditorPlugin() {
|
|||||||
#else
|
#else
|
||||||
// Disable lightmap baking if the module is disabled at compile-time.
|
// Disable lightmap baking if the module is disabled at compile-time.
|
||||||
bake->set_disabled(true);
|
bake->set_disabled(true);
|
||||||
#if defined(ANDROID_ENABLED) || defined(IOS_ENABLED)
|
#if defined(ANDROID_ENABLED) || defined(APPLE_EMBEDDED_ENABLED)
|
||||||
bake->set_tooltip_text(vformat(TTR("Lightmaps cannot be baked on %s."), OS::get_singleton()->get_name()));
|
bake->set_tooltip_text(vformat(TTR("Lightmaps cannot be baked on %s."), OS::get_singleton()->get_name()));
|
||||||
#else
|
#else
|
||||||
bake->set_tooltip_text(TTR("Lightmaps cannot be baked, as the `lightmapper_rd` module was disabled at compile-time."));
|
bake->set_tooltip_text(TTR("Lightmaps cannot be baked, as the `lightmapper_rd` module was disabled at compile-time."));
|
||||||
|
|||||||
@@ -47,6 +47,7 @@
|
|||||||
#include "editor/editor_undo_redo_manager.h"
|
#include "editor/editor_undo_redo_manager.h"
|
||||||
#include "editor/editor_vcs_interface.h"
|
#include "editor/editor_vcs_interface.h"
|
||||||
#include "editor/export/editor_export_platform.h"
|
#include "editor/export/editor_export_platform.h"
|
||||||
|
#include "editor/export/editor_export_platform_apple_embedded.h"
|
||||||
#include "editor/export/editor_export_platform_extension.h"
|
#include "editor/export/editor_export_platform_extension.h"
|
||||||
#include "editor/export/editor_export_platform_pc.h"
|
#include "editor/export/editor_export_platform_pc.h"
|
||||||
#include "editor/export/editor_export_plugin.h"
|
#include "editor/export/editor_export_plugin.h"
|
||||||
@@ -163,6 +164,7 @@ void register_editor_types() {
|
|||||||
GDREGISTER_CLASS(EditorExportPlugin);
|
GDREGISTER_CLASS(EditorExportPlugin);
|
||||||
GDREGISTER_ABSTRACT_CLASS(EditorExportPlatform);
|
GDREGISTER_ABSTRACT_CLASS(EditorExportPlatform);
|
||||||
GDREGISTER_ABSTRACT_CLASS(EditorExportPlatformPC);
|
GDREGISTER_ABSTRACT_CLASS(EditorExportPlatformPC);
|
||||||
|
GDREGISTER_ABSTRACT_CLASS(EditorExportPlatformAppleEmbedded);
|
||||||
GDREGISTER_CLASS(EditorExportPlatformExtension);
|
GDREGISTER_CLASS(EditorExportPlatformExtension);
|
||||||
GDREGISTER_ABSTRACT_CLASS(EditorExportPreset);
|
GDREGISTER_ABSTRACT_CLASS(EditorExportPreset);
|
||||||
|
|
||||||
|
|||||||
@@ -2191,6 +2191,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
|
|||||||
GLOBAL_DEF_RST(PropertyInfo(Variant::STRING, "rendering/rendering_device/driver.linuxbsd", PROPERTY_HINT_ENUM, "vulkan"), "vulkan");
|
GLOBAL_DEF_RST(PropertyInfo(Variant::STRING, "rendering/rendering_device/driver.linuxbsd", PROPERTY_HINT_ENUM, "vulkan"), "vulkan");
|
||||||
GLOBAL_DEF_RST(PropertyInfo(Variant::STRING, "rendering/rendering_device/driver.android", PROPERTY_HINT_ENUM, "vulkan"), "vulkan");
|
GLOBAL_DEF_RST(PropertyInfo(Variant::STRING, "rendering/rendering_device/driver.android", PROPERTY_HINT_ENUM, "vulkan"), "vulkan");
|
||||||
GLOBAL_DEF_RST(PropertyInfo(Variant::STRING, "rendering/rendering_device/driver.ios", PROPERTY_HINT_ENUM, "metal,vulkan"), "metal");
|
GLOBAL_DEF_RST(PropertyInfo(Variant::STRING, "rendering/rendering_device/driver.ios", PROPERTY_HINT_ENUM, "metal,vulkan"), "metal");
|
||||||
|
GLOBAL_DEF_RST(PropertyInfo(Variant::STRING, "rendering/rendering_device/driver.visionos", PROPERTY_HINT_ENUM, "metal"), "metal");
|
||||||
GLOBAL_DEF_RST(PropertyInfo(Variant::STRING, "rendering/rendering_device/driver.macos", PROPERTY_HINT_ENUM, "metal,vulkan"), "metal");
|
GLOBAL_DEF_RST(PropertyInfo(Variant::STRING, "rendering/rendering_device/driver.macos", PROPERTY_HINT_ENUM, "metal,vulkan"), "metal");
|
||||||
|
|
||||||
GLOBAL_DEF_RST("rendering/rendering_device/fallback_to_vulkan", true);
|
GLOBAL_DEF_RST("rendering/rendering_device/fallback_to_vulkan", true);
|
||||||
@@ -2672,6 +2673,7 @@ Error Main::setup(const char *execpath, int argc, char *argv[], bool p_second_ph
|
|||||||
GLOBAL_DEF_NOVAL(PropertyInfo(Variant::STRING, "display/display_server/driver.linuxbsd", PROPERTY_HINT_ENUM_SUGGESTION, "default,x11,wayland,headless"), "default");
|
GLOBAL_DEF_NOVAL(PropertyInfo(Variant::STRING, "display/display_server/driver.linuxbsd", PROPERTY_HINT_ENUM_SUGGESTION, "default,x11,wayland,headless"), "default");
|
||||||
GLOBAL_DEF_NOVAL(PropertyInfo(Variant::STRING, "display/display_server/driver.android", PROPERTY_HINT_ENUM_SUGGESTION, "default,android,headless"), "default");
|
GLOBAL_DEF_NOVAL(PropertyInfo(Variant::STRING, "display/display_server/driver.android", PROPERTY_HINT_ENUM_SUGGESTION, "default,android,headless"), "default");
|
||||||
GLOBAL_DEF_NOVAL(PropertyInfo(Variant::STRING, "display/display_server/driver.ios", PROPERTY_HINT_ENUM_SUGGESTION, "default,iOS,headless"), "default");
|
GLOBAL_DEF_NOVAL(PropertyInfo(Variant::STRING, "display/display_server/driver.ios", PROPERTY_HINT_ENUM_SUGGESTION, "default,iOS,headless"), "default");
|
||||||
|
GLOBAL_DEF_NOVAL(PropertyInfo(Variant::STRING, "display/display_server/driver.visionos", PROPERTY_HINT_ENUM_SUGGESTION, "default,visionOS,headless"), "default");
|
||||||
GLOBAL_DEF_NOVAL(PropertyInfo(Variant::STRING, "display/display_server/driver.macos", PROPERTY_HINT_ENUM_SUGGESTION, "default,macos,headless"), "default");
|
GLOBAL_DEF_NOVAL(PropertyInfo(Variant::STRING, "display/display_server/driver.macos", PROPERTY_HINT_ENUM_SUGGESTION, "default,macos,headless"), "default");
|
||||||
|
|
||||||
GLOBAL_DEF_RST_NOVAL("audio/driver/driver", AudioDriverManager::get_driver(0)->get_name());
|
GLOBAL_DEF_RST_NOVAL("audio/driver/driver", AudioDriverManager::get_driver(0)->get_name());
|
||||||
@@ -3797,7 +3799,7 @@ static MainTimerSync main_timer_sync;
|
|||||||
int Main::start() {
|
int Main::start() {
|
||||||
OS::get_singleton()->benchmark_begin_measure("Startup", "Main::Start");
|
OS::get_singleton()->benchmark_begin_measure("Startup", "Main::Start");
|
||||||
|
|
||||||
ERR_FAIL_COND_V(!_start_success, false);
|
ERR_FAIL_COND_V(!_start_success, EXIT_FAILURE);
|
||||||
|
|
||||||
bool has_icon = false;
|
bool has_icon = false;
|
||||||
String positional_arg;
|
String positional_arg;
|
||||||
|
|||||||
26
methods.py
26
methods.py
@@ -609,17 +609,41 @@ def Run(env, function):
|
|||||||
return Action(function, "$GENCOMSTR")
|
return Action(function, "$GENCOMSTR")
|
||||||
|
|
||||||
|
|
||||||
|
def detect_darwin_toolchain_path(env):
|
||||||
|
var_name = "APPLE_TOOLCHAIN_PATH"
|
||||||
|
if not env[var_name]:
|
||||||
|
try:
|
||||||
|
xcode_path = subprocess.check_output(["xcode-select", "-p"]).strip().decode("utf-8")
|
||||||
|
if xcode_path:
|
||||||
|
env[var_name] = xcode_path + "/Toolchains/XcodeDefault.xctoolchain"
|
||||||
|
except (subprocess.CalledProcessError, OSError):
|
||||||
|
print_error("Failed to find SDK path while running 'xcode-select -p'.")
|
||||||
|
raise
|
||||||
|
|
||||||
|
|
||||||
def detect_darwin_sdk_path(platform, env):
|
def detect_darwin_sdk_path(platform, env):
|
||||||
sdk_name = ""
|
sdk_name = ""
|
||||||
|
|
||||||
if platform == "macos":
|
if platform == "macos":
|
||||||
sdk_name = "macosx"
|
sdk_name = "macosx"
|
||||||
var_name = "MACOS_SDK_PATH"
|
var_name = "MACOS_SDK_PATH"
|
||||||
|
|
||||||
elif platform == "ios":
|
elif platform == "ios":
|
||||||
sdk_name = "iphoneos"
|
sdk_name = "iphoneos"
|
||||||
var_name = "IOS_SDK_PATH"
|
var_name = "IOS_SDK_PATH"
|
||||||
|
|
||||||
elif platform == "iossimulator":
|
elif platform == "iossimulator":
|
||||||
sdk_name = "iphonesimulator"
|
sdk_name = "iphonesimulator"
|
||||||
var_name = "IOS_SDK_PATH"
|
var_name = "IOS_SDK_PATH"
|
||||||
|
|
||||||
|
elif platform == "visionos":
|
||||||
|
sdk_name = "xros"
|
||||||
|
var_name = "VISIONOS_SDK_PATH"
|
||||||
|
|
||||||
|
elif platform == "visionossimulator":
|
||||||
|
sdk_name = "xrsimulator"
|
||||||
|
var_name = "VISIONOS_SDK_PATH"
|
||||||
|
|
||||||
else:
|
else:
|
||||||
raise Exception("Invalid platform argument passed to detect_darwin_sdk_path")
|
raise Exception("Invalid platform argument passed to detect_darwin_sdk_path")
|
||||||
|
|
||||||
@@ -629,7 +653,7 @@ def detect_darwin_sdk_path(platform, env):
|
|||||||
if sdk_path:
|
if sdk_path:
|
||||||
env[var_name] = sdk_path
|
env[var_name] = sdk_path
|
||||||
except (subprocess.CalledProcessError, OSError):
|
except (subprocess.CalledProcessError, OSError):
|
||||||
print_error("Failed to find SDK path while running xcrun --sdk {} --show-sdk-path.".format(sdk_name))
|
print_error("Failed to find SDK path while running 'xcrun --sdk {} --show-sdk-path'.".format(sdk_name))
|
||||||
raise
|
raise
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,6 @@
|
|||||||
objects = {
|
objects = {
|
||||||
|
|
||||||
/* Begin PBXBuildFile section */
|
/* Begin PBXBuildFile section */
|
||||||
054F8BE62D38852F00B81423 /* MetalFX.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 054F8BE52D38852F00B81423 /* MetalFX.framework */; settings = {ATTRIBUTES = (Weak, ); }; };
|
|
||||||
1F1575721F582BE20003B888 /* dylibs in Resources */ = {isa = PBXBuildFile; fileRef = 1F1575711F582BE20003B888 /* dylibs */; };
|
1F1575721F582BE20003B888 /* dylibs in Resources */ = {isa = PBXBuildFile; fileRef = 1F1575711F582BE20003B888 /* dylibs */; };
|
||||||
DEADBEEF2F582BE20003B888 /* $binary.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = DEADBEEF1F582BE20003B888 /* $binary.xcframework */; };
|
DEADBEEF2F582BE20003B888 /* $binary.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = DEADBEEF1F582BE20003B888 /* $binary.xcframework */; };
|
||||||
$modules_buildfile
|
$modules_buildfile
|
||||||
@@ -43,7 +42,6 @@
|
|||||||
1FF4C1881F584E6300A41E41 /* $binary.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "$binary.entitlements"; sourceTree = "<group>"; };
|
1FF4C1881F584E6300A41E41 /* $binary.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "$binary.entitlements"; sourceTree = "<group>"; };
|
||||||
1FF8DBB01FBA9DE1009DE660 /* dummy.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = dummy.cpp; sourceTree = "<group>"; };
|
1FF8DBB01FBA9DE1009DE660 /* dummy.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = dummy.cpp; sourceTree = "<group>"; };
|
||||||
9039D3BD24C093AC0020482C /* MoltenVK.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = MoltenVK; path = MoltenVK.xcframework; sourceTree = "<group>"; };
|
9039D3BD24C093AC0020482C /* MoltenVK.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = MoltenVK; path = MoltenVK.xcframework; sourceTree = "<group>"; };
|
||||||
054F8BE52D38852F00B81423 /* MetalFX.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MetalFX.framework; path = System/Library/Frameworks/MetalFX.framework; sourceTree = SDKROOT; };
|
|
||||||
D07CD44D1C5D589C00B7FB28 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = "<group>"; };
|
D07CD44D1C5D589C00B7FB28 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = "<group>"; };
|
||||||
D0BCFE3418AEBDA2004A7AAE /* $binary.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "$binary.app"; sourceTree = BUILT_PRODUCTS_DIR; };
|
D0BCFE3418AEBDA2004A7AAE /* $binary.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "$binary.app"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
D0BCFE4318AEBDA2004A7AAE /* $binary-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "$binary-Info.plist"; sourceTree = "<group>"; };
|
D0BCFE4318AEBDA2004A7AAE /* $binary-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "$binary-Info.plist"; sourceTree = "<group>"; };
|
||||||
@@ -62,7 +60,6 @@
|
|||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
9039D3BE24C093AC0020482C /* MoltenVK.xcframework in Frameworks */,
|
9039D3BE24C093AC0020482C /* MoltenVK.xcframework in Frameworks */,
|
||||||
054F8BE62D38852F00B81423 /* MetalFX.framework in Frameworks */,
|
|
||||||
DEADBEEF2F582BE20003B888 /* $binary.xcframework */,
|
DEADBEEF2F582BE20003B888 /* $binary.xcframework */,
|
||||||
$modules_buildphase
|
$modules_buildphase
|
||||||
$additional_pbx_frameworks_build
|
$additional_pbx_frameworks_build
|
||||||
@@ -97,7 +94,6 @@
|
|||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
9039D3BD24C093AC0020482C /* MoltenVK.xcframework */,
|
9039D3BD24C093AC0020482C /* MoltenVK.xcframework */,
|
||||||
054F8BE52D38852F00B81423 /* MetalFX.framework */,
|
|
||||||
DEADBEEF1F582BE20003B888 /* $binary.xcframework */,
|
DEADBEEF1F582BE20003B888 /* $binary.xcframework */,
|
||||||
$modules_buildgrp
|
$modules_buildgrp
|
||||||
$additional_pbx_frameworks_refs
|
$additional_pbx_frameworks_refs
|
||||||
|
|||||||
10
misc/dist/visionos_xcode/PrivacyInfo.xcprivacy
vendored
Normal file
10
misc/dist/visionos_xcode/PrivacyInfo.xcprivacy
vendored
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>NSPrivacyAccessedAPITypes</key>
|
||||||
|
$priv_api_types
|
||||||
|
$priv_tracking
|
||||||
|
$priv_collection
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
0
misc/dist/visionos_xcode/data.pck
vendored
Normal file
0
misc/dist/visionos_xcode/data.pck
vendored
Normal file
402
misc/dist/visionos_xcode/godot_visionos.xcodeproj/project.pbxproj
vendored
Normal file
402
misc/dist/visionos_xcode/godot_visionos.xcodeproj/project.pbxproj
vendored
Normal file
@@ -0,0 +1,402 @@
|
|||||||
|
// !$*UTF8*$!
|
||||||
|
{
|
||||||
|
archiveVersion = 1;
|
||||||
|
classes = {
|
||||||
|
};
|
||||||
|
objectVersion = 46;
|
||||||
|
objects = {
|
||||||
|
|
||||||
|
/* Begin PBXBuildFile section */
|
||||||
|
1F1575721F582BE20003B888 /* dylibs in Resources */ = {isa = PBXBuildFile; fileRef = 1F1575711F582BE20003B888 /* dylibs */; };
|
||||||
|
DEADBEEF2F582BE20003B888 /* $binary.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = DEADBEEF1F582BE20003B888 /* $binary.xcframework */; };
|
||||||
|
$modules_buildfile
|
||||||
|
$swift_runtime_buildfile
|
||||||
|
1FF8DBB11FBA9DE1009DE660 /* dummy.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1FF8DBB01FBA9DE1009DE660 /* dummy.cpp */; };
|
||||||
|
D07CD44E1C5D589C00B7FB28 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = D07CD44D1C5D589C00B7FB28 /* Images.xcassets */; };
|
||||||
|
D0BCFE4618AEBDA2004A7AAE /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = D0BCFE4418AEBDA2004A7AAE /* InfoPlist.strings */; };
|
||||||
|
D0BCFE7818AEBFEB004A7AAE /* $binary.pck in Resources */ = {isa = PBXBuildFile; fileRef = D0BCFE7718AEBFEB004A7AAE /* $binary.pck */; };
|
||||||
|
F965960D2BC2C3A800579C7E /* PrivacyInfo.xcprivacy in Resources */ = {isa = PBXBuildFile; fileRef = F965960C2BC2C3A800579C7E /* PrivacyInfo.xcprivacy */; };
|
||||||
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
|
/* Begin PBXCopyFilesBuildPhase section */
|
||||||
|
90A13CD024AA68E500E8464F /* Embed Frameworks */ = {
|
||||||
|
isa = PBXCopyFilesBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
dstPath = "";
|
||||||
|
dstSubfolderSpec = 10;
|
||||||
|
files = (
|
||||||
|
$pbx_embeded_frameworks
|
||||||
|
);
|
||||||
|
name = "Embed Frameworks";
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
|
/* End PBXCopyFilesBuildPhase section */
|
||||||
|
|
||||||
|
/* Begin PBXFileReference section */
|
||||||
|
1F1575711F582BE20003B888 /* dylibs */ = {isa = PBXFileReference; lastKnownFileType = folder; name = dylibs; path = "$binary/dylibs"; sourceTree = "<group>"; };
|
||||||
|
DEADBEEF1F582BE20003B888 /* $binary.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = godot; path = "$binary.xcframework"; sourceTree = "<group>"; };
|
||||||
|
$modules_fileref
|
||||||
|
$swift_runtime_fileref
|
||||||
|
1FF4C1881F584E6300A41E41 /* $binary.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "$binary.entitlements"; sourceTree = "<group>"; };
|
||||||
|
1FF8DBB01FBA9DE1009DE660 /* dummy.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = dummy.cpp; sourceTree = "<group>"; };
|
||||||
|
D07CD44D1C5D589C00B7FB28 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = "<group>"; };
|
||||||
|
D0BCFE3418AEBDA2004A7AAE /* $binary.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "$binary.app"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
|
D0BCFE4318AEBDA2004A7AAE /* $binary-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "$binary-Info.plist"; sourceTree = "<group>"; };
|
||||||
|
D0BCFE4518AEBDA2004A7AAE /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||||
|
$pbx_locale_file_reference
|
||||||
|
D0BCFE7718AEBFEB004A7AAE /* $binary.pck */ = {isa = PBXFileReference; lastKnownFileType = file; path = "$binary.pck"; sourceTree = "<group>"; };
|
||||||
|
F965960C2BC2C3A800579C7E /* PrivacyInfo.xcprivacy */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = PrivacyInfo.xcprivacy; sourceTree = "<group>"; };
|
||||||
|
/* End PBXFileReference section */
|
||||||
|
|
||||||
|
$additional_pbx_files
|
||||||
|
|
||||||
|
/* Begin PBXFrameworksBuildPhase section */
|
||||||
|
D0BCFE3118AEBDA2004A7AAE /* Frameworks */ = {
|
||||||
|
isa = PBXFrameworksBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
DEADBEEF2F582BE20003B888 /* $binary.xcframework */,
|
||||||
|
$modules_buildphase
|
||||||
|
$additional_pbx_frameworks_build
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
|
/* End PBXFrameworksBuildPhase section */
|
||||||
|
|
||||||
|
/* Begin PBXGroup section */
|
||||||
|
D0BCFE2B18AEBDA2004A7AAE = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
1F1575711F582BE20003B888 /* dylibs */,
|
||||||
|
D0BCFE7718AEBFEB004A7AAE /* $binary.pck */,
|
||||||
|
D0BCFE4118AEBDA2004A7AAE /* $binary */,
|
||||||
|
D0BCFE3618AEBDA2004A7AAE /* Frameworks */,
|
||||||
|
D0BCFE3518AEBDA2004A7AAE /* Products */,
|
||||||
|
F965960C2BC2C3A800579C7E /* PrivacyInfo.xcprivacy */,
|
||||||
|
$additional_pbx_resources_refs
|
||||||
|
);
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
D0BCFE3518AEBDA2004A7AAE /* Products */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
D0BCFE3418AEBDA2004A7AAE /* $binary.app */,
|
||||||
|
);
|
||||||
|
name = Products;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
D0BCFE3618AEBDA2004A7AAE /* Frameworks */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
DEADBEEF1F582BE20003B888 /* $binary.xcframework */,
|
||||||
|
$modules_buildgrp
|
||||||
|
$additional_pbx_frameworks_refs
|
||||||
|
);
|
||||||
|
name = Frameworks;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
D0BCFE4118AEBDA2004A7AAE /* $binary */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
1FF4C1881F584E6300A41E41 /* $binary.entitlements */,
|
||||||
|
D07CD44D1C5D589C00B7FB28 /* Images.xcassets */,
|
||||||
|
D0BCFE4218AEBDA2004A7AAE /* Supporting Files */,
|
||||||
|
1FF8DBB01FBA9DE1009DE660 /* dummy.cpp */,
|
||||||
|
$swift_runtime_binary_files
|
||||||
|
);
|
||||||
|
path = "$binary";
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
D0BCFE4218AEBDA2004A7AAE /* Supporting Files */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
D0BCFE4318AEBDA2004A7AAE /* $binary-Info.plist */,
|
||||||
|
D0BCFE4418AEBDA2004A7AAE /* InfoPlist.strings */,
|
||||||
|
);
|
||||||
|
name = "Supporting Files";
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
/* End PBXGroup section */
|
||||||
|
|
||||||
|
/* Begin PBXNativeTarget section */
|
||||||
|
D0BCFE3318AEBDA2004A7AAE /* $binary */ = {
|
||||||
|
isa = PBXNativeTarget;
|
||||||
|
buildConfigurationList = D0BCFE7118AEBDA3004A7AAE /* Build configuration list for PBXNativeTarget "$binary" */;
|
||||||
|
buildPhases = (
|
||||||
|
D0BCFE3018AEBDA2004A7AAE /* Sources */,
|
||||||
|
D0BCFE3118AEBDA2004A7AAE /* Frameworks */,
|
||||||
|
D0BCFE3218AEBDA2004A7AAE /* Resources */,
|
||||||
|
90A13CD024AA68E500E8464F /* Embed Frameworks */,
|
||||||
|
);
|
||||||
|
buildRules = (
|
||||||
|
);
|
||||||
|
dependencies = (
|
||||||
|
);
|
||||||
|
name = "$binary";
|
||||||
|
productName = "$name";
|
||||||
|
productReference = D0BCFE3418AEBDA2004A7AAE /* $binary.app */;
|
||||||
|
productType = "com.apple.product-type.application";
|
||||||
|
};
|
||||||
|
/* End PBXNativeTarget section */
|
||||||
|
|
||||||
|
/* Begin PBXProject section */
|
||||||
|
D0BCFE2C18AEBDA2004A7AAE /* Project object */ = {
|
||||||
|
isa = PBXProject;
|
||||||
|
attributes = {
|
||||||
|
LastUpgradeCheck = 0500;
|
||||||
|
ORGANIZATIONNAME = GodotEngine;
|
||||||
|
TargetAttributes = {
|
||||||
|
D0BCFE3318AEBDA2004A7AAE = {
|
||||||
|
DevelopmentTeam = $team_id;
|
||||||
|
$swift_runtime_migration
|
||||||
|
ProvisioningStyle = Automatic;
|
||||||
|
SystemCapabilities = {
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
buildConfigurationList = D0BCFE2F18AEBDA2004A7AAE /* Build configuration list for PBXProject "$binary" */;
|
||||||
|
compatibilityVersion = "Xcode 3.2";
|
||||||
|
developmentRegion = en;
|
||||||
|
hasScannedForEncodings = 0;
|
||||||
|
knownRegions = (
|
||||||
|
en,
|
||||||
|
Base,
|
||||||
|
);
|
||||||
|
mainGroup = D0BCFE2B18AEBDA2004A7AAE;
|
||||||
|
productRefGroup = D0BCFE3518AEBDA2004A7AAE /* Products */;
|
||||||
|
projectDirPath = "";
|
||||||
|
projectRoot = "";
|
||||||
|
targets = (
|
||||||
|
D0BCFE3318AEBDA2004A7AAE /* $binary */,
|
||||||
|
);
|
||||||
|
};
|
||||||
|
/* End PBXProject section */
|
||||||
|
|
||||||
|
/* Begin PBXResourcesBuildPhase section */
|
||||||
|
D0BCFE3218AEBDA2004A7AAE /* Resources */ = {
|
||||||
|
isa = PBXResourcesBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
D07CD44E1C5D589C00B7FB28 /* Images.xcassets in Resources */,
|
||||||
|
D0BCFE7818AEBFEB004A7AAE /* $binary.pck in Resources */,
|
||||||
|
D0BCFE4618AEBDA2004A7AAE /* InfoPlist.strings in Resources */,
|
||||||
|
F965960D2BC2C3A800579C7E /* PrivacyInfo.xcprivacy in Resources */,
|
||||||
|
$additional_pbx_resources_build
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
|
/* End PBXResourcesBuildPhase section */
|
||||||
|
|
||||||
|
/* Begin PBXSourcesBuildPhase section */
|
||||||
|
D0BCFE3018AEBDA2004A7AAE /* Sources */ = {
|
||||||
|
isa = PBXSourcesBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
1FF8DBB11FBA9DE1009DE660 /* dummy.cpp in Sources */,
|
||||||
|
$swift_runtime_build_phase
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
|
/* End PBXSourcesBuildPhase section */
|
||||||
|
|
||||||
|
/* Begin PBXVariantGroup section */
|
||||||
|
D0BCFE4418AEBDA2004A7AAE /* InfoPlist.strings */ = {
|
||||||
|
isa = PBXVariantGroup;
|
||||||
|
children = (
|
||||||
|
D0BCFE4518AEBDA2004A7AAE /* en */,
|
||||||
|
$pbx_locale_build_reference
|
||||||
|
);
|
||||||
|
name = InfoPlist.strings;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
/* End PBXVariantGroup section */
|
||||||
|
|
||||||
|
/* Begin XCBuildConfiguration section */
|
||||||
|
D0BCFE6F18AEBDA3004A7AAE /* Debug */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||||
|
ARCHS = "$godot_archs";
|
||||||
|
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||||
|
CLANG_CXX_LIBRARY = "libc++";
|
||||||
|
CLANG_ENABLE_MODULES = YES;
|
||||||
|
CLANG_ENABLE_OBJC_ARC = YES;
|
||||||
|
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||||
|
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||||
|
CLANG_WARN_EMPTY_BODY = YES;
|
||||||
|
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||||
|
CLANG_WARN_INT_CONVERSION = YES;
|
||||||
|
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||||
|
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||||
|
CODE_SIGN_IDENTITY = "$code_sign_identity_debug";
|
||||||
|
"CODE_SIGN_IDENTITY[sdk=xros*]" = "$code_sign_identity_debug";
|
||||||
|
COPY_PHASE_STRIP = NO;
|
||||||
|
ENABLE_BITCODE = NO;
|
||||||
|
"FRAMEWORK_SEARCH_PATHS[arch=*]" = (
|
||||||
|
"$(PROJECT_DIR)/**",
|
||||||
|
);
|
||||||
|
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||||
|
GCC_DYNAMIC_NO_PIC = NO;
|
||||||
|
GCC_OPTIMIZATION_LEVEL = 0;
|
||||||
|
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||||
|
"$(inherited)",
|
||||||
|
);
|
||||||
|
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
|
||||||
|
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||||
|
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||||
|
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||||
|
GCC_WARN_UNINITIALIZED_AUTOS = YES;
|
||||||
|
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||||
|
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||||
|
XROS_DEPLOYMENT_TARGET = $min_version;
|
||||||
|
"LD_CLASSIC_1500" = "-ld_classic";
|
||||||
|
"LD_CLASSIC_1501" = "-ld_classic";
|
||||||
|
"LD_CLASSIC_1510" = "-ld_classic";
|
||||||
|
OTHER_LDFLAGS = "$(LD_CLASSIC_$(XCODE_VERSION_ACTUAL)) $linker_flags";
|
||||||
|
SDKROOT = xros;
|
||||||
|
TARGETED_DEVICE_FAMILY = 7;
|
||||||
|
};
|
||||||
|
name = Debug;
|
||||||
|
};
|
||||||
|
D0BCFE7018AEBDA3004A7AAE /* Release */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||||
|
ARCHS = "$godot_archs";
|
||||||
|
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||||
|
CLANG_CXX_LIBRARY = "libc++";
|
||||||
|
CLANG_ENABLE_MODULES = YES;
|
||||||
|
CLANG_ENABLE_OBJC_ARC = YES;
|
||||||
|
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||||
|
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||||
|
CLANG_WARN_EMPTY_BODY = YES;
|
||||||
|
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||||
|
CLANG_WARN_INT_CONVERSION = YES;
|
||||||
|
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||||
|
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||||
|
CODE_SIGN_IDENTITY = "$code_sign_identity_release";
|
||||||
|
"CODE_SIGN_IDENTITY[sdk=xros*]" = "$code_sign_identity_release";
|
||||||
|
COPY_PHASE_STRIP = YES;
|
||||||
|
ENABLE_BITCODE = NO;
|
||||||
|
"FRAMEWORK_SEARCH_PATHS[arch=*]" = (
|
||||||
|
"$(PROJECT_DIR)/**",
|
||||||
|
);
|
||||||
|
ENABLE_NS_ASSERTIONS = NO;
|
||||||
|
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||||
|
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||||
|
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||||
|
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||||
|
GCC_WARN_UNINITIALIZED_AUTOS = YES;
|
||||||
|
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||||
|
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||||
|
XROS_DEPLOYMENT_TARGET = $min_version;
|
||||||
|
"LD_CLASSIC_1500" = "-ld_classic";
|
||||||
|
"LD_CLASSIC_1501" = "-ld_classic";
|
||||||
|
"LD_CLASSIC_1510" = "-ld_classic";
|
||||||
|
OTHER_LDFLAGS = "$(LD_CLASSIC_$(XCODE_VERSION_ACTUAL)) $linker_flags";
|
||||||
|
SDKROOT = xros;
|
||||||
|
TARGETED_DEVICE_FAMILY = 7;
|
||||||
|
VALIDATE_PRODUCT = YES;
|
||||||
|
};
|
||||||
|
name = Release;
|
||||||
|
};
|
||||||
|
D0BCFE7218AEBDA3004A7AAE /* Debug */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
ARCHS = "$godot_archs";
|
||||||
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
|
CODE_SIGN_ENTITLEMENTS = "$binary/$binary.entitlements";
|
||||||
|
CODE_SIGN_IDENTITY = "$code_sign_identity_debug";
|
||||||
|
"CODE_SIGN_IDENTITY[sdk=xros*]" = "$code_sign_identity_debug";
|
||||||
|
CODE_SIGN_STYLE = "$code_sign_style_debug";
|
||||||
|
CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)";
|
||||||
|
DEVELOPMENT_TEAM = $team_id;
|
||||||
|
INFOPLIST_FILE = "$binary/$binary-Info.plist";
|
||||||
|
XROS_DEPLOYMENT_TARGET = $min_version;
|
||||||
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
|
"$(inherited)",
|
||||||
|
"@executable_path/Frameworks",
|
||||||
|
);
|
||||||
|
LIBRARY_SEARCH_PATHS = (
|
||||||
|
"$(inherited)",
|
||||||
|
"$(PROJECT_DIR)/**",
|
||||||
|
);
|
||||||
|
PRODUCT_BUNDLE_IDENTIFIER = $bundle_identifier;
|
||||||
|
INFOPLIST_KEY_CFBundleDisplayName = "$name";
|
||||||
|
PRODUCT_NAME = "$binary";
|
||||||
|
EXECUTABLE_NAME = "$binary";
|
||||||
|
MARKETING_VERSION = $short_version;
|
||||||
|
CURRENT_PROJECT_VERSION = $version;
|
||||||
|
PROVISIONING_PROFILE = "$provisioning_profile_uuid_debug";
|
||||||
|
PROVISIONING_PROFILE_SPECIFIER = "$provisioning_profile_specifier_debug";
|
||||||
|
TARGETED_DEVICE_FAMILY = 7;
|
||||||
|
VALID_ARCHS = "arm64 x86_64";
|
||||||
|
WRAPPER_EXTENSION = app;
|
||||||
|
$swift_runtime_build_settings
|
||||||
|
};
|
||||||
|
name = Debug;
|
||||||
|
};
|
||||||
|
D0BCFE7318AEBDA3004A7AAE /* Release */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
ARCHS = "$godot_archs";
|
||||||
|
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||||
|
CODE_SIGN_ENTITLEMENTS = "$binary/$binary.entitlements";
|
||||||
|
CODE_SIGN_IDENTITY = "$code_sign_identity_release";
|
||||||
|
"CODE_SIGN_IDENTITY[sdk=xros*]" = "$code_sign_identity_release";
|
||||||
|
CODE_SIGN_STYLE = "$code_sign_style_release";
|
||||||
|
CONFIGURATION_BUILD_DIR = "$(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)";
|
||||||
|
DEVELOPMENT_TEAM = $team_id;
|
||||||
|
INFOPLIST_FILE = "$binary/$binary-Info.plist";
|
||||||
|
XROS_DEPLOYMENT_TARGET = $min_version;
|
||||||
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
|
"$(inherited)",
|
||||||
|
"@executable_path/Frameworks",
|
||||||
|
);
|
||||||
|
LIBRARY_SEARCH_PATHS = (
|
||||||
|
"$(inherited)",
|
||||||
|
"$(PROJECT_DIR)/**",
|
||||||
|
);
|
||||||
|
PRODUCT_BUNDLE_IDENTIFIER = $bundle_identifier;
|
||||||
|
INFOPLIST_KEY_CFBundleDisplayName = "$name";
|
||||||
|
PRODUCT_NAME = "$binary";
|
||||||
|
EXECUTABLE_NAME = "$binary";
|
||||||
|
MARKETING_VERSION = $short_version;
|
||||||
|
CURRENT_PROJECT_VERSION = $version;
|
||||||
|
PROVISIONING_PROFILE = "$provisioning_profile_uuid_release";
|
||||||
|
PROVISIONING_PROFILE_SPECIFIER = "$provisioning_profile_specifier_release";
|
||||||
|
TARGETED_DEVICE_FAMILY = 7;
|
||||||
|
VALID_ARCHS = "arm64";
|
||||||
|
WRAPPER_EXTENSION = app;
|
||||||
|
$swift_runtime_build_settings
|
||||||
|
};
|
||||||
|
name = Release;
|
||||||
|
};
|
||||||
|
/* End XCBuildConfiguration section */
|
||||||
|
|
||||||
|
/* Begin XCConfigurationList section */
|
||||||
|
D0BCFE2F18AEBDA2004A7AAE /* Build configuration list for PBXProject "$binary" */ = {
|
||||||
|
isa = XCConfigurationList;
|
||||||
|
buildConfigurations = (
|
||||||
|
D0BCFE6F18AEBDA3004A7AAE /* Debug */,
|
||||||
|
D0BCFE7018AEBDA3004A7AAE /* Release */,
|
||||||
|
);
|
||||||
|
defaultConfigurationIsVisible = 0;
|
||||||
|
defaultConfigurationName = Debug;
|
||||||
|
};
|
||||||
|
D0BCFE7118AEBDA3004A7AAE /* Build configuration list for PBXNativeTarget "$binary" */ = {
|
||||||
|
isa = XCConfigurationList;
|
||||||
|
buildConfigurations = (
|
||||||
|
D0BCFE7218AEBDA3004A7AAE /* Debug */,
|
||||||
|
D0BCFE7318AEBDA3004A7AAE /* Release */,
|
||||||
|
);
|
||||||
|
defaultConfigurationIsVisible = 0;
|
||||||
|
defaultConfigurationName = Debug;
|
||||||
|
};
|
||||||
|
/* End XCConfigurationList section */
|
||||||
|
};
|
||||||
|
rootObject = D0BCFE2C18AEBDA2004A7AAE /* Project object */;
|
||||||
|
}
|
||||||
7
misc/dist/visionos_xcode/godot_visionos.xcodeproj/project.xcworkspace/contents.xcworkspacedata
generated
vendored
Normal file
7
misc/dist/visionos_xcode/godot_visionos.xcodeproj/project.xcworkspace/contents.xcworkspacedata
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Workspace
|
||||||
|
version = "1.0">
|
||||||
|
<FileRef
|
||||||
|
location = "self:$binary.xcodeproj">
|
||||||
|
</FileRef>
|
||||||
|
</Workspace>
|
||||||
93
misc/dist/visionos_xcode/godot_visionos.xcodeproj/xcshareddata/xcschemes/godot_visionos.xcscheme
vendored
Normal file
93
misc/dist/visionos_xcode/godot_visionos.xcodeproj/xcshareddata/xcschemes/godot_visionos.xcscheme
vendored
Normal file
@@ -0,0 +1,93 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Scheme
|
||||||
|
LastUpgradeVersion = "0710"
|
||||||
|
version = "1.3">
|
||||||
|
<BuildAction
|
||||||
|
parallelizeBuildables = "YES"
|
||||||
|
buildImplicitDependencies = "YES">
|
||||||
|
<BuildActionEntries>
|
||||||
|
<BuildActionEntry
|
||||||
|
buildForTesting = "YES"
|
||||||
|
buildForRunning = "YES"
|
||||||
|
buildForProfiling = "YES"
|
||||||
|
buildForArchiving = "YES"
|
||||||
|
buildForAnalyzing = "YES">
|
||||||
|
<BuildableReference
|
||||||
|
BuildableIdentifier = "primary"
|
||||||
|
BlueprintIdentifier = "A340BDFEBCA49239A941883D"
|
||||||
|
BuildableName = "$binary.app"
|
||||||
|
BlueprintName = "$binary"
|
||||||
|
ReferencedContainer = "container:$binary.xcodeproj">
|
||||||
|
</BuildableReference>
|
||||||
|
</BuildActionEntry>
|
||||||
|
</BuildActionEntries>
|
||||||
|
</BuildAction>
|
||||||
|
<TestAction
|
||||||
|
buildConfiguration = "$default_build_config"
|
||||||
|
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||||
|
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||||
|
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||||
|
<Testables>
|
||||||
|
</Testables>
|
||||||
|
<MacroExpansion>
|
||||||
|
<BuildableReference
|
||||||
|
BuildableIdentifier = "primary"
|
||||||
|
BlueprintIdentifier = "A340BDFEBCA49239A941883D"
|
||||||
|
BuildableName = "$binary.app"
|
||||||
|
BlueprintName = "$binary"
|
||||||
|
ReferencedContainer = "container:$binary.xcodeproj">
|
||||||
|
</BuildableReference>
|
||||||
|
</MacroExpansion>
|
||||||
|
<AdditionalOptions>
|
||||||
|
</AdditionalOptions>
|
||||||
|
</TestAction>
|
||||||
|
<LaunchAction
|
||||||
|
buildConfiguration = "$default_build_config"
|
||||||
|
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||||
|
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||||
|
launchStyle = "0"
|
||||||
|
useCustomWorkingDirectory = "NO"
|
||||||
|
ignoresPersistentStateOnLaunch = "NO"
|
||||||
|
debugDocumentVersioning = "YES"
|
||||||
|
debugServiceExtension = "internal"
|
||||||
|
allowLocationSimulation = "YES">
|
||||||
|
<BuildableProductRunnable
|
||||||
|
runnableDebuggingMode = "0">
|
||||||
|
<BuildableReference
|
||||||
|
BuildableIdentifier = "primary"
|
||||||
|
BlueprintIdentifier = "A340BDFEBCA49239A941883D"
|
||||||
|
BuildableName = "$binary.app"
|
||||||
|
BlueprintName = "$binary"
|
||||||
|
ReferencedContainer = "container:$binary.xcodeproj">
|
||||||
|
</BuildableReference>
|
||||||
|
</BuildableProductRunnable>
|
||||||
|
<CommandLineArguments>
|
||||||
|
</CommandLineArguments>
|
||||||
|
<AdditionalOptions>
|
||||||
|
</AdditionalOptions>
|
||||||
|
</LaunchAction>
|
||||||
|
<ProfileAction
|
||||||
|
buildConfiguration = "$default_build_config"
|
||||||
|
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||||
|
savedToolIdentifier = ""
|
||||||
|
useCustomWorkingDirectory = "NO"
|
||||||
|
debugDocumentVersioning = "YES">
|
||||||
|
<BuildableProductRunnable
|
||||||
|
runnableDebuggingMode = "0">
|
||||||
|
<BuildableReference
|
||||||
|
BuildableIdentifier = "primary"
|
||||||
|
BlueprintIdentifier = "A340BDFEBCA49239A941883D"
|
||||||
|
BuildableName = "$binary.app"
|
||||||
|
BlueprintName = "$binary"
|
||||||
|
ReferencedContainer = "container:$binary.xcodeproj">
|
||||||
|
</BuildableReference>
|
||||||
|
</BuildableProductRunnable>
|
||||||
|
</ProfileAction>
|
||||||
|
<AnalyzeAction
|
||||||
|
buildConfiguration = "$default_build_config">
|
||||||
|
</AnalyzeAction>
|
||||||
|
<ArchiveAction
|
||||||
|
buildConfiguration = "$default_build_config"
|
||||||
|
revealArchiveInOrganizer = "YES">
|
||||||
|
</ArchiveAction>
|
||||||
|
</Scheme>
|
||||||
22
misc/dist/visionos_xcode/godot_visionos/Images.xcassets/SplashImage.imageset/Contents.json
vendored
Normal file
22
misc/dist/visionos_xcode/godot_visionos/Images.xcassets/SplashImage.imageset/Contents.json
vendored
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename" : "splash@2x.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename" : "splash@3x.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
misc/dist/visionos_xcode/godot_visionos/Images.xcassets/SplashImage.imageset/splash@2x.png
vendored
Normal file
BIN
misc/dist/visionos_xcode/godot_visionos/Images.xcassets/SplashImage.imageset/splash@2x.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 14 KiB |
BIN
misc/dist/visionos_xcode/godot_visionos/Images.xcassets/SplashImage.imageset/splash@3x.png
vendored
Normal file
BIN
misc/dist/visionos_xcode/godot_visionos/Images.xcassets/SplashImage.imageset/splash@3x.png
vendored
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 14 KiB |
31
misc/dist/visionos_xcode/godot_visionos/dummy.cpp
vendored
Normal file
31
misc/dist/visionos_xcode/godot_visionos/dummy.cpp
vendored
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
/**************************************************************************/
|
||||||
|
/* dummy.cpp */
|
||||||
|
/**************************************************************************/
|
||||||
|
/* 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. */
|
||||||
|
/**************************************************************************/
|
||||||
|
|
||||||
|
$cpp_code
|
||||||
33
misc/dist/visionos_xcode/godot_visionos/dummy.h
vendored
Normal file
33
misc/dist/visionos_xcode/godot_visionos/dummy.h
vendored
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
/**************************************************************************/
|
||||||
|
/* dummy.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. */
|
||||||
|
/**************************************************************************/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
// #import <Foundation/Foundation.h>
|
||||||
31
misc/dist/visionos_xcode/godot_visionos/dummy.swift
vendored
Normal file
31
misc/dist/visionos_xcode/godot_visionos/dummy.swift
vendored
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
/**************************************************************************/
|
||||||
|
/* dummy.swift */
|
||||||
|
/**************************************************************************/
|
||||||
|
/* 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 Foundation
|
||||||
1
misc/dist/visionos_xcode/godot_visionos/dylibs/empty
vendored
Normal file
1
misc/dist/visionos_xcode/godot_visionos/dylibs/empty
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
Dummy file to make dylibs folder exported
|
||||||
1
misc/dist/visionos_xcode/godot_visionos/en.lproj/InfoPlist.strings
vendored
Normal file
1
misc/dist/visionos_xcode/godot_visionos/en.lproj/InfoPlist.strings
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
/* Localized versions of Info.plist keys */
|
||||||
20
misc/dist/visionos_xcode/godot_visionos/export_options.plist
vendored
Normal file
20
misc/dist/visionos_xcode/godot_visionos/export_options.plist
vendored
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>method</key>
|
||||||
|
<string>$export_method</string>
|
||||||
|
|
||||||
|
<key>teamID</key>
|
||||||
|
<string>$team_id</string>
|
||||||
|
|
||||||
|
<key>provisioningProfiles</key>
|
||||||
|
<dict>
|
||||||
|
<key>$bundle_identifier</key>
|
||||||
|
<string>$provisioning_profile_uuid</string>
|
||||||
|
</dict>
|
||||||
|
|
||||||
|
<key>compileBitcode</key>
|
||||||
|
<false/>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
63
misc/dist/visionos_xcode/godot_visionos/godot_visionos-Info.plist
vendored
Normal file
63
misc/dist/visionos_xcode/godot_visionos/godot_visionos-Info.plist
vendored
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>CFBundleDevelopmentRegion</key>
|
||||||
|
<string>en</string>
|
||||||
|
<key>CFBundleDisplayName</key>
|
||||||
|
<string>$(INFOPLIST_KEY_CFBundleDisplayName)</string>
|
||||||
|
<key>CFBundleExecutable</key>
|
||||||
|
<string>$(EXECUTABLE_NAME)</string>
|
||||||
|
<key>CFBundleIcons</key>
|
||||||
|
<dict/>
|
||||||
|
<key>CFBundleIcons~ipad</key>
|
||||||
|
<dict/>
|
||||||
|
<key>CFBundleIdentifier</key>
|
||||||
|
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||||
|
<key>CFBundleInfoDictionaryVersion</key>
|
||||||
|
<string>6.0</string>
|
||||||
|
<key>CFBundleName</key>
|
||||||
|
<string>$(PRODUCT_NAME)</string>
|
||||||
|
<key>CFBundlePackageType</key>
|
||||||
|
<string>APPL</string>
|
||||||
|
<key>CFBundleShortVersionString</key>
|
||||||
|
<string>$(MARKETING_VERSION)</string>
|
||||||
|
<key>CFBundleSignature</key>
|
||||||
|
<string>$signature</string>
|
||||||
|
<key>CFBundleVersion</key>
|
||||||
|
<string>$(CURRENT_PROJECT_VERSION)</string>
|
||||||
|
<key>ITSAppUsesNonExemptEncryption</key>
|
||||||
|
<false />
|
||||||
|
<key>LSRequiresIPhoneOS</key>
|
||||||
|
<true/>
|
||||||
|
<key>LSSupportsOpeningDocumentsInPlace</key>
|
||||||
|
$docs_in_place
|
||||||
|
<key>UIFileSharingEnabled</key>
|
||||||
|
$docs_sharing
|
||||||
|
<key>UIRequiredDeviceCapabilities</key>
|
||||||
|
<array>
|
||||||
|
$required_device_capabilities
|
||||||
|
</array>
|
||||||
|
<key>NSCameraUsageDescription</key>
|
||||||
|
<string>$camera_usage_description</string>
|
||||||
|
<key>NSPhotoLibraryUsageDescription</key>
|
||||||
|
<string>$photolibrary_usage_description</string>
|
||||||
|
<key>NSMicrophoneUsageDescription</key>
|
||||||
|
<string>$microphone_usage_description</string>
|
||||||
|
<key>UIRequiresFullScreen</key>
|
||||||
|
<true/>
|
||||||
|
<key>UIStatusBarHidden</key>
|
||||||
|
<true/>
|
||||||
|
<key>UISupportedInterfaceOrientations</key>
|
||||||
|
<array>
|
||||||
|
$interface_orientations
|
||||||
|
</array>
|
||||||
|
<key>UISupportedInterfaceOrientations~ipad</key>
|
||||||
|
<array>
|
||||||
|
$ipad_interface_orientations
|
||||||
|
</array>
|
||||||
|
$additional_plist_content
|
||||||
|
$plist_launch_screen_name
|
||||||
|
<key>CADisableMinimumFrameDurationOnPhone</key><true/>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
7
misc/dist/visionos_xcode/godot_visionos/godot_visionos.entitlements
vendored
Normal file
7
misc/dist/visionos_xcode/godot_visionos/godot_visionos.entitlements
vendored
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
$entitlements_full
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
39
misc/dist/visionos_xcode/libgodot.visionos.debug.xcframework/Info.plist
vendored
Executable file
39
misc/dist/visionos_xcode/libgodot.visionos.debug.xcframework/Info.plist
vendored
Executable file
@@ -0,0 +1,39 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>AvailableLibraries</key>
|
||||||
|
<array>
|
||||||
|
<dict>
|
||||||
|
<key>LibraryIdentifier</key>
|
||||||
|
<string>xros-arm64</string>
|
||||||
|
<key>LibraryPath</key>
|
||||||
|
<string>libgodot.a</string>
|
||||||
|
<key>SupportedArchitectures</key>
|
||||||
|
<array>
|
||||||
|
<string>arm64</string>
|
||||||
|
</array>
|
||||||
|
<key>SupportedPlatform</key>
|
||||||
|
<string>xros</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>LibraryIdentifier</key>
|
||||||
|
<string>xros-arm64-simulator</string>
|
||||||
|
<key>LibraryPath</key>
|
||||||
|
<string>libgodot.a</string>
|
||||||
|
<key>SupportedArchitectures</key>
|
||||||
|
<array>
|
||||||
|
<string>arm64</string>
|
||||||
|
</array>
|
||||||
|
<key>SupportedPlatform</key>
|
||||||
|
<string>xros</string>
|
||||||
|
<key>SupportedPlatformVariant</key>
|
||||||
|
<string>simulator</string>
|
||||||
|
</dict>
|
||||||
|
</array>
|
||||||
|
<key>CFBundlePackageType</key>
|
||||||
|
<string>XFWK</string>
|
||||||
|
<key>XCFrameworkFormatVersion</key>
|
||||||
|
<string>1.0</string>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
1
misc/dist/visionos_xcode/libgodot.visionos.debug.xcframework/xros-arm64-simulator/empty
vendored
Normal file
1
misc/dist/visionos_xcode/libgodot.visionos.debug.xcframework/xros-arm64-simulator/empty
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
Dummy file to make dylibs folder exported
|
||||||
1
misc/dist/visionos_xcode/libgodot.visionos.debug.xcframework/xros-arm64/empty
vendored
Normal file
1
misc/dist/visionos_xcode/libgodot.visionos.debug.xcframework/xros-arm64/empty
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
Dummy file to make dylibs folder exported
|
||||||
39
misc/dist/visionos_xcode/libgodot.visionos.release.xcframework/Info.plist
vendored
Executable file
39
misc/dist/visionos_xcode/libgodot.visionos.release.xcframework/Info.plist
vendored
Executable file
@@ -0,0 +1,39 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>AvailableLibraries</key>
|
||||||
|
<array>
|
||||||
|
<dict>
|
||||||
|
<key>LibraryIdentifier</key>
|
||||||
|
<string>xros-arm64</string>
|
||||||
|
<key>LibraryPath</key>
|
||||||
|
<string>libgodot.a</string>
|
||||||
|
<key>SupportedArchitectures</key>
|
||||||
|
<array>
|
||||||
|
<string>arm64</string>
|
||||||
|
</array>
|
||||||
|
<key>SupportedPlatform</key>
|
||||||
|
<string>xros</string>
|
||||||
|
</dict>
|
||||||
|
<dict>
|
||||||
|
<key>LibraryIdentifier</key>
|
||||||
|
<string>xros-arm64-simulator</string>
|
||||||
|
<key>LibraryPath</key>
|
||||||
|
<string>libgodot.a</string>
|
||||||
|
<key>SupportedArchitectures</key>
|
||||||
|
<array>
|
||||||
|
<string>arm64</string>
|
||||||
|
</array>
|
||||||
|
<key>SupportedPlatform</key>
|
||||||
|
<string>xros</string>
|
||||||
|
<key>SupportedPlatformVariant</key>
|
||||||
|
<string>simulator</string>
|
||||||
|
</dict>
|
||||||
|
</array>
|
||||||
|
<key>CFBundlePackageType</key>
|
||||||
|
<string>XFWK</string>
|
||||||
|
<key>XCFrameworkFormatVersion</key>
|
||||||
|
<string>1.0</string>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
1
misc/dist/visionos_xcode/libgodot.visionos.release.xcframework/xros-arm64-simulator/empty
vendored
Normal file
1
misc/dist/visionos_xcode/libgodot.visionos.release.xcframework/xros-arm64-simulator/empty
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
Dummy file to make dylibs folder exported
|
||||||
1
misc/dist/visionos_xcode/libgodot.visionos.release.xcframework/xros-arm64/empty
vendored
Normal file
1
misc/dist/visionos_xcode/libgodot.visionos.release.xcframework/xros-arm64/empty
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
Dummy file to make dylibs folder exported
|
||||||
@@ -406,7 +406,7 @@ namespace GodotTools.Export
|
|||||||
{
|
{
|
||||||
if (platform == OS.Platforms.iOS && path.EndsWith(".dat", StringComparison.OrdinalIgnoreCase))
|
if (platform == OS.Platforms.iOS && path.EndsWith(".dat", StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
AddIosBundleFile(path);
|
AddAppleEmbeddedPlatformBundleFile(path);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -453,7 +453,7 @@ namespace GodotTools.Export
|
|||||||
throw new InvalidOperationException("Failed to generate xcframework.");
|
throw new InvalidOperationException("Failed to generate xcframework.");
|
||||||
}
|
}
|
||||||
|
|
||||||
AddIosEmbeddedFramework(xcFrameworkPath);
|
AddAppleEmbeddedPlatformEmbeddedFramework(xcFrameworkPath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ namespace {
|
|||||||
String get_hostfxr_file_name() {
|
String get_hostfxr_file_name() {
|
||||||
#if defined(WINDOWS_ENABLED)
|
#if defined(WINDOWS_ENABLED)
|
||||||
return "hostfxr.dll";
|
return "hostfxr.dll";
|
||||||
#elif defined(MACOS_ENABLED) || defined(IOS_ENABLED)
|
#elif defined(MACOS_ENABLED) || defined(APPLE_EMBEDDED_ENABLED)
|
||||||
return "libhostfxr.dylib";
|
return "libhostfxr.dylib";
|
||||||
#else
|
#else
|
||||||
return "libhostfxr.so";
|
return "libhostfxr.so";
|
||||||
|
|||||||
@@ -450,7 +450,7 @@ godot_plugins_initialize_fn try_load_native_aot_library(void *&r_aot_dll_handle)
|
|||||||
|
|
||||||
#if defined(WINDOWS_ENABLED)
|
#if defined(WINDOWS_ENABLED)
|
||||||
String native_aot_so_path = GodotSharpDirs::get_api_assemblies_dir().path_join(assembly_name + ".dll");
|
String native_aot_so_path = GodotSharpDirs::get_api_assemblies_dir().path_join(assembly_name + ".dll");
|
||||||
#elif defined(MACOS_ENABLED) || defined(IOS_ENABLED)
|
#elif defined(MACOS_ENABLED) || defined(APPLE_EMBEDDED_ENABLED)
|
||||||
String native_aot_so_path = GodotSharpDirs::get_api_assemblies_dir().path_join(assembly_name + ".dylib");
|
String native_aot_so_path = GodotSharpDirs::get_api_assemblies_dir().path_join(assembly_name + ".dylib");
|
||||||
#elif defined(ANDROID_ENABLED)
|
#elif defined(ANDROID_ENABLED)
|
||||||
String native_aot_so_path = "lib" + assembly_name + ".so";
|
String native_aot_so_path = "lib" + assembly_name + ".so";
|
||||||
@@ -599,7 +599,7 @@ void GDMono::initialize() {
|
|||||||
|
|
||||||
godot_plugins_initialize_fn godot_plugins_initialize = nullptr;
|
godot_plugins_initialize_fn godot_plugins_initialize = nullptr;
|
||||||
|
|
||||||
#if !defined(IOS_ENABLED)
|
#if !defined(APPLE_EMBEDDED_ENABLED)
|
||||||
// Check that the .NET assemblies directory exists before trying to use it.
|
// Check that the .NET assemblies directory exists before trying to use it.
|
||||||
if (!DirAccess::exists(GodotSharpDirs::get_api_assemblies_dir())) {
|
if (!DirAccess::exists(GodotSharpDirs::get_api_assemblies_dir())) {
|
||||||
OS::get_singleton()->alert(vformat(RTR("Unable to find the .NET assemblies directory.\nMake sure the '%s' directory exists and contains the .NET assemblies."), GodotSharpDirs::get_api_assemblies_dir()), RTR(".NET assemblies not found"));
|
OS::get_singleton()->alert(vformat(RTR("Unable to find the .NET assemblies directory.\nMake sure the '%s' directory exists and contains the .NET assemblies."), GodotSharpDirs::get_api_assemblies_dir()), RTR(".NET assemblies not found"));
|
||||||
@@ -640,7 +640,7 @@ void GDMono::initialize() {
|
|||||||
|
|
||||||
void *godot_dll_handle = nullptr;
|
void *godot_dll_handle = nullptr;
|
||||||
|
|
||||||
#if defined(UNIX_ENABLED) && !defined(MACOS_ENABLED) && !defined(IOS_ENABLED)
|
#if defined(UNIX_ENABLED) && !defined(MACOS_ENABLED) && !defined(APPLE_EMBEDDED_ENABLED)
|
||||||
// Managed code can access it on its own on other platforms
|
// Managed code can access it on its own on other platforms
|
||||||
godot_dll_handle = dlopen(nullptr, RTLD_NOW);
|
godot_dll_handle = dlopen(nullptr, RTLD_NOW);
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -713,7 +713,7 @@ Vector<PluginConfigAndroid> EditorExportPlatformAndroid::get_plugins() {
|
|||||||
Vector<String> plugins_filenames = list_gdap_files(plugins_dir);
|
Vector<String> plugins_filenames = list_gdap_files(plugins_dir);
|
||||||
|
|
||||||
if (!plugins_filenames.is_empty()) {
|
if (!plugins_filenames.is_empty()) {
|
||||||
Ref<ConfigFile> config_file = memnew(ConfigFile);
|
Ref<ConfigFile> config_file;
|
||||||
for (int i = 0; i < plugins_filenames.size(); i++) {
|
for (int i = 0; i < plugins_filenames.size(); i++) {
|
||||||
PluginConfigAndroid config = PluginConfigAndroid::load_plugin_config(config_file, plugins_dir.path_join(plugins_filenames[i]));
|
PluginConfigAndroid config = PluginConfigAndroid::load_plugin_config(config_file, plugins_dir.path_join(plugins_filenames[i]));
|
||||||
if (config.valid_config) {
|
if (config.valid_config) {
|
||||||
|
|||||||
@@ -3,6 +3,10 @@
|
|||||||
This folder contains the C++, Objective-C and Objective-C++ code for the iOS
|
This folder contains the C++, Objective-C and Objective-C++ code for the iOS
|
||||||
platform port.
|
platform port.
|
||||||
|
|
||||||
|
This platform derives from the Apple embedded abstract platform ([`drivers/apple_embedded`](/drivers/apple_embedded)).
|
||||||
|
|
||||||
|
This platform uses shared Apple code ([`drivers/apple`](/drivers/apple)).
|
||||||
|
|
||||||
See also [`misc/dist/ios_xcode`](/misc/dist/ios_xcode) folder for the Xcode
|
See also [`misc/dist/ios_xcode`](/misc/dist/ios_xcode) folder for the Xcode
|
||||||
project template used for packaging the iOS export templates.
|
project template used for packaging the iOS export templates.
|
||||||
|
|
||||||
|
|||||||
@@ -1,28 +1,19 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
from misc.utility.scons_hints import *
|
from misc.utility.scons_hints import *
|
||||||
|
|
||||||
import platform_ios_builders
|
from platform_ios_builders import generate_bundle
|
||||||
|
|
||||||
|
from platform_methods import combine_libs_apple_embedded
|
||||||
|
|
||||||
Import("env")
|
Import("env")
|
||||||
|
|
||||||
ios_lib = [
|
ios_lib = [
|
||||||
"godot_ios.mm",
|
"device_metrics.mm",
|
||||||
"os_ios.mm",
|
"display_layer_ios.mm",
|
||||||
"main.m",
|
|
||||||
"app_delegate.mm",
|
|
||||||
"view_controller.mm",
|
|
||||||
"ios.mm",
|
|
||||||
"rendering_context_driver_vulkan_ios.mm",
|
|
||||||
"display_server_ios.mm",
|
"display_server_ios.mm",
|
||||||
"godot_view.mm",
|
"godot_view_ios.mm",
|
||||||
"tts_ios.mm",
|
"main_ios.mm",
|
||||||
"display_layer.mm",
|
"os_ios.mm",
|
||||||
"godot_app_delegate.m",
|
|
||||||
"godot_view_renderer.mm",
|
|
||||||
"device_metrics.m",
|
|
||||||
"keyboard_input_view.mm",
|
|
||||||
"key_mapping_ios.mm",
|
|
||||||
"ios_terminal_logger.mm",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
env_ios = env.Clone()
|
env_ios = env.Clone()
|
||||||
@@ -31,12 +22,9 @@ ios_lib = env_ios.add_library("ios", ios_lib)
|
|||||||
# (iOS) Enable module support
|
# (iOS) Enable module support
|
||||||
env_ios.Append(CCFLAGS=["-fmodules", "-fcxx-modules"])
|
env_ios.Append(CCFLAGS=["-fmodules", "-fcxx-modules"])
|
||||||
|
|
||||||
|
|
||||||
combine_command = env_ios.CommandNoCache(
|
combine_command = env_ios.CommandNoCache(
|
||||||
"#bin/libgodot" + env_ios["LIBSUFFIX"], [ios_lib] + env_ios["LIBS"], env.Run(platform_ios_builders.combine_libs)
|
"#bin/libgodot" + env_ios["LIBSUFFIX"], [ios_lib] + env_ios["LIBS"], env.Run(combine_libs_apple_embedded)
|
||||||
)
|
)
|
||||||
|
|
||||||
if env["generate_bundle"]:
|
if env["generate_bundle"]:
|
||||||
env.AlwaysBuild(
|
env.AlwaysBuild(env.CommandNoCache("generate_bundle", combine_command, env.Run(generate_bundle)))
|
||||||
env.CommandNoCache("generate_bundle", combine_command, env.Run(platform_ios_builders.generate_bundle))
|
|
||||||
)
|
|
||||||
|
|||||||
@@ -33,11 +33,11 @@
|
|||||||
#if defined(IOS_ENABLED)
|
#if defined(IOS_ENABLED)
|
||||||
|
|
||||||
void register_ios_api() {
|
void register_ios_api() {
|
||||||
godot_ios_plugins_initialize();
|
godot_apple_embedded_plugins_initialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
void unregister_ios_api() {
|
void unregister_ios_api() {
|
||||||
godot_ios_plugins_deinitialize();
|
godot_apple_embedded_plugins_deinitialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|||||||
@@ -31,8 +31,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#if defined(IOS_ENABLED)
|
#if defined(IOS_ENABLED)
|
||||||
extern void godot_ios_plugins_initialize();
|
extern void godot_apple_embedded_plugins_initialize();
|
||||||
extern void godot_ios_plugins_deinitialize();
|
extern void godot_apple_embedded_plugins_deinitialize();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void register_ios_api();
|
void register_ios_api();
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import os
|
|||||||
import sys
|
import sys
|
||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
from methods import detect_darwin_sdk_path, print_error, print_warning
|
from methods import detect_darwin_sdk_path, detect_darwin_toolchain_path, print_error, print_warning
|
||||||
from platform_methods import validate_arch
|
from platform_methods import validate_arch
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
@@ -25,14 +25,11 @@ def get_opts():
|
|||||||
|
|
||||||
return [
|
return [
|
||||||
("vulkan_sdk_path", "Path to the Vulkan SDK", ""),
|
("vulkan_sdk_path", "Path to the Vulkan SDK", ""),
|
||||||
(
|
# APPLE_TOOLCHAIN_PATH Example: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain
|
||||||
"IOS_TOOLCHAIN_PATH",
|
(("APPLE_TOOLCHAIN_PATH", "IOS_TOOLCHAIN_PATH"), "Path to the Apple toolchain", ""),
|
||||||
"Path to iOS toolchain",
|
|
||||||
"/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain",
|
|
||||||
),
|
|
||||||
("IOS_SDK_PATH", "Path to the iOS SDK", ""),
|
("IOS_SDK_PATH", "Path to the iOS SDK", ""),
|
||||||
BoolVariable("ios_simulator", "Build for iOS Simulator", False),
|
(("apple_target_triple", "ios_triple"), "Triple for the corresponding target Apple platform toolchain", ""),
|
||||||
("ios_triple", "Triple for ios toolchain", ""),
|
BoolVariable(("simulator", "ios_simulator"), "Build for Simulator", False),
|
||||||
BoolVariable("generate_bundle", "Generate an APP bundle after building iOS/macOS binaries", False),
|
BoolVariable("generate_bundle", "Generate an APP bundle after building iOS/macOS binaries", False),
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -62,6 +59,7 @@ def configure(env: "SConsEnvironment"):
|
|||||||
# Validate arch.
|
# Validate arch.
|
||||||
supported_arches = ["x86_64", "arm64"]
|
supported_arches = ["x86_64", "arm64"]
|
||||||
validate_arch(env["arch"], get_name(), supported_arches)
|
validate_arch(env["arch"], get_name(), supported_arches)
|
||||||
|
detect_darwin_toolchain_path(env)
|
||||||
|
|
||||||
## LTO
|
## LTO
|
||||||
|
|
||||||
@@ -82,9 +80,9 @@ def configure(env: "SConsEnvironment"):
|
|||||||
if "OSXCROSS_IOS" in os.environ:
|
if "OSXCROSS_IOS" in os.environ:
|
||||||
env["osxcross"] = True
|
env["osxcross"] = True
|
||||||
|
|
||||||
env["ENV"]["PATH"] = env["IOS_TOOLCHAIN_PATH"] + "/Developer/usr/bin/:" + env["ENV"]["PATH"]
|
env["ENV"]["PATH"] = env["APPLE_TOOLCHAIN_PATH"] + "/Developer/usr/bin/:" + env["ENV"]["PATH"]
|
||||||
|
|
||||||
compiler_path = "$IOS_TOOLCHAIN_PATH/usr/bin/${ios_triple}"
|
compiler_path = "$APPLE_TOOLCHAIN_PATH/usr/bin/${apple_target_triple}"
|
||||||
|
|
||||||
ccache_path = os.environ.get("CCACHE")
|
ccache_path = os.environ.get("CCACHE")
|
||||||
if ccache_path is None:
|
if ccache_path is None:
|
||||||
@@ -102,7 +100,7 @@ def configure(env: "SConsEnvironment"):
|
|||||||
|
|
||||||
## Compile flags
|
## Compile flags
|
||||||
|
|
||||||
if env["ios_simulator"]:
|
if env["simulator"]:
|
||||||
detect_darwin_sdk_path("iossimulator", env)
|
detect_darwin_sdk_path("iossimulator", env)
|
||||||
env.Append(ASFLAGS=["-mios-simulator-version-min=12.0"])
|
env.Append(ASFLAGS=["-mios-simulator-version-min=12.0"])
|
||||||
env.Append(CCFLAGS=["-mios-simulator-version-min=12.0"])
|
env.Append(CCFLAGS=["-mios-simulator-version-min=12.0"])
|
||||||
@@ -114,8 +112,8 @@ def configure(env: "SConsEnvironment"):
|
|||||||
env.Append(CCFLAGS=["-miphoneos-version-min=12.0"])
|
env.Append(CCFLAGS=["-miphoneos-version-min=12.0"])
|
||||||
|
|
||||||
if env["arch"] == "x86_64":
|
if env["arch"] == "x86_64":
|
||||||
if not env["ios_simulator"]:
|
if not env["simulator"]:
|
||||||
print_error("Building for iOS with 'arch=x86_64' requires 'ios_simulator=yes'.")
|
print_error("Building for iOS with 'arch=x86_64' requires 'simulator=yes'.")
|
||||||
sys.exit(255)
|
sys.exit(255)
|
||||||
|
|
||||||
env["ENV"]["MACOSX_DEPLOYMENT_TARGET"] = "10.9"
|
env["ENV"]["MACOSX_DEPLOYMENT_TARGET"] = "10.9"
|
||||||
@@ -149,10 +147,10 @@ def configure(env: "SConsEnvironment"):
|
|||||||
)
|
)
|
||||||
|
|
||||||
env.Prepend(CPPPATH=["#platform/ios"])
|
env.Prepend(CPPPATH=["#platform/ios"])
|
||||||
env.Append(CPPDEFINES=["IOS_ENABLED", "UNIX_ENABLED", "COREAUDIO_ENABLED"])
|
env.Append(CPPDEFINES=["IOS_ENABLED", "APPLE_EMBEDDED_ENABLED", "UNIX_ENABLED", "COREAUDIO_ENABLED"])
|
||||||
|
|
||||||
if env["metal"] and env["ios_simulator"]:
|
if env["metal"] and env["simulator"]:
|
||||||
print_warning("iOS simulator does not support the Metal rendering driver")
|
print_warning("iOS Simulator does not support the Metal rendering driver")
|
||||||
env["metal"] = False
|
env["metal"] = False
|
||||||
|
|
||||||
if env["metal"]:
|
if env["metal"]:
|
||||||
@@ -166,8 +164,8 @@ def configure(env: "SConsEnvironment"):
|
|||||||
)
|
)
|
||||||
env.Prepend(CPPEXTPATH=["#thirdparty/spirv-cross"])
|
env.Prepend(CPPEXTPATH=["#thirdparty/spirv-cross"])
|
||||||
|
|
||||||
if env["vulkan"] and env["ios_simulator"]:
|
if env["vulkan"] and env["simulator"]:
|
||||||
print_warning("iOS simulator does not support the Vulkan rendering driver")
|
print_warning("iOS Simulator does not support the Vulkan rendering driver")
|
||||||
env["vulkan"] = False
|
env["vulkan"] = False
|
||||||
|
|
||||||
if env["vulkan"]:
|
if env["vulkan"]:
|
||||||
|
|||||||
@@ -32,7 +32,7 @@
|
|||||||
|
|
||||||
#import <Foundation/Foundation.h>
|
#import <Foundation/Foundation.h>
|
||||||
|
|
||||||
@interface GodotDeviceMetrics : NSObject
|
@interface GDTDeviceMetrics : NSObject
|
||||||
|
|
||||||
@property(nonatomic, class, readonly, strong) NSDictionary<NSArray *, NSNumber *> *dpiList;
|
@property(nonatomic, class, readonly, strong) NSDictionary<NSArray *, NSNumber *> *dpiList;
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
/* device_metrics.m */
|
/* device_metrics.mm */
|
||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
/* This file is part of: */
|
/* This file is part of: */
|
||||||
/* GODOT ENGINE */
|
/* GODOT ENGINE */
|
||||||
@@ -30,7 +30,7 @@
|
|||||||
|
|
||||||
#import "device_metrics.h"
|
#import "device_metrics.h"
|
||||||
|
|
||||||
@implementation GodotDeviceMetrics
|
@implementation GDTDeviceMetrics
|
||||||
|
|
||||||
+ (NSDictionary *)dpiList {
|
+ (NSDictionary *)dpiList {
|
||||||
return @{
|
return @{
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
/* display_layer.h */
|
/* display_layer_ios.h */
|
||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
/* This file is part of: */
|
/* This file is part of: */
|
||||||
/* GODOT ENGINE */
|
/* GODOT ENGINE */
|
||||||
@@ -30,32 +30,25 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "drivers/apple_embedded/display_layer_apple_embedded.h"
|
||||||
|
|
||||||
#import <OpenGLES/EAGLDrawable.h>
|
#import <OpenGLES/EAGLDrawable.h>
|
||||||
#import <QuartzCore/QuartzCore.h>
|
#import <QuartzCore/QuartzCore.h>
|
||||||
|
|
||||||
@protocol DisplayLayer <NSObject>
|
|
||||||
|
|
||||||
- (void)startRenderDisplayLayer;
|
|
||||||
- (void)stopRenderDisplayLayer;
|
|
||||||
- (void)initializeDisplayLayer;
|
|
||||||
- (void)layoutDisplayLayer;
|
|
||||||
|
|
||||||
@end
|
|
||||||
|
|
||||||
// An ugly workaround for iOS simulator
|
// An ugly workaround for iOS simulator
|
||||||
#if defined(TARGET_OS_SIMULATOR) && TARGET_OS_SIMULATOR
|
#if defined(TARGET_OS_SIMULATOR) && TARGET_OS_SIMULATOR
|
||||||
#if defined(__IPHONE_13_0)
|
#if defined(__IPHONE_13_0)
|
||||||
API_AVAILABLE(ios(13.0))
|
API_AVAILABLE(ios(13.0))
|
||||||
@interface GodotMetalLayer : CAMetalLayer <DisplayLayer>
|
@interface GDTMetalLayer : CAMetalLayer <GDTDisplayLayer>
|
||||||
#else
|
#else
|
||||||
@interface GodotMetalLayer : CALayer <DisplayLayer>
|
@interface GDTMetalLayer : CALayer <GDTDisplayLayer>
|
||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
@interface GodotMetalLayer : CAMetalLayer <DisplayLayer>
|
@interface GDTMetalLayer : CAMetalLayer <GDTDisplayLayer>
|
||||||
#endif
|
#endif
|
||||||
@end
|
@end
|
||||||
|
|
||||||
API_DEPRECATED("OpenGLES is deprecated", ios(2.0, 12.0))
|
API_DEPRECATED("OpenGLES is deprecated", ios(2.0, 12.0))
|
||||||
@interface GodotOpenGLLayer : CAEAGLLayer <DisplayLayer>
|
@interface GDTOpenGLLayer : CAEAGLLayer <GDTDisplayLayer>
|
||||||
|
|
||||||
@end
|
@end
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
/* display_layer.mm */
|
/* display_layer_ios.mm */
|
||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
/* This file is part of: */
|
/* This file is part of: */
|
||||||
/* GODOT ENGINE */
|
/* GODOT ENGINE */
|
||||||
@@ -28,7 +28,7 @@
|
|||||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||||
/**************************************************************************/
|
/**************************************************************************/
|
||||||
|
|
||||||
#import "display_layer.h"
|
#import "display_layer_ios.h"
|
||||||
|
|
||||||
#import "display_server_ios.h"
|
#import "display_server_ios.h"
|
||||||
#import "os_ios.h"
|
#import "os_ios.h"
|
||||||
@@ -46,7 +46,7 @@
|
|||||||
#import <QuartzCore/QuartzCore.h>
|
#import <QuartzCore/QuartzCore.h>
|
||||||
#import <UIKit/UIKit.h>
|
#import <UIKit/UIKit.h>
|
||||||
|
|
||||||
@implementation GodotMetalLayer
|
@implementation GDTMetalLayer
|
||||||
|
|
||||||
- (void)initializeDisplayLayer {
|
- (void)initializeDisplayLayer {
|
||||||
#if defined(TARGET_OS_SIMULATOR) && TARGET_OS_SIMULATOR
|
#if defined(TARGET_OS_SIMULATOR) && TARGET_OS_SIMULATOR
|
||||||
@@ -69,7 +69,7 @@
|
|||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@implementation GodotOpenGLLayer {
|
@implementation GDTOpenGLLayer {
|
||||||
// The pixel dimensions of the backbuffer
|
// The pixel dimensions of the backbuffer
|
||||||
GLint backingWidth;
|
GLint backingWidth;
|
||||||
GLint backingHeight;
|
GLint backingHeight;
|
||||||
@@ -30,209 +30,25 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "core/input/input.h"
|
#include "drivers/apple_embedded/display_server_apple_embedded.h"
|
||||||
#include "servers/display_server.h"
|
|
||||||
|
|
||||||
#if defined(RD_ENABLED)
|
class DisplayServerIOS : public DisplayServerAppleEmbedded {
|
||||||
#include "servers/rendering/renderer_rd/renderer_compositor_rd.h"
|
GDSOFTCLASS(DisplayServerIOS, DisplayServerAppleEmbedded);
|
||||||
#include "servers/rendering/rendering_device.h"
|
|
||||||
|
|
||||||
#if defined(VULKAN_ENABLED)
|
|
||||||
#import "rendering_context_driver_vulkan_ios.h"
|
|
||||||
|
|
||||||
#include "drivers/vulkan/godot_vulkan.h"
|
|
||||||
#endif // VULKAN_ENABLED
|
|
||||||
|
|
||||||
#if defined(METAL_ENABLED)
|
|
||||||
#import "drivers/metal/rendering_context_driver_metal.h"
|
|
||||||
#endif // METAL_ENABLED
|
|
||||||
#endif // RD_ENABLED
|
|
||||||
|
|
||||||
#if defined(GLES3_ENABLED)
|
|
||||||
#include "drivers/gles3/rasterizer_gles3.h"
|
|
||||||
#endif // GLES3_ENABLED
|
|
||||||
|
|
||||||
#import <Foundation/Foundation.h>
|
|
||||||
#import <QuartzCore/CAMetalLayer.h>
|
|
||||||
|
|
||||||
class DisplayServerIOS : public DisplayServer {
|
|
||||||
GDSOFTCLASS(DisplayServerIOS, DisplayServer);
|
|
||||||
|
|
||||||
_THREAD_SAFE_CLASS_
|
_THREAD_SAFE_CLASS_
|
||||||
|
|
||||||
#if defined(RD_ENABLED)
|
|
||||||
RenderingContextDriver *rendering_context = nullptr;
|
|
||||||
RenderingDevice *rendering_device = nullptr;
|
|
||||||
#endif
|
|
||||||
NativeMenu *native_menu = nullptr;
|
|
||||||
|
|
||||||
id tts = nullptr;
|
|
||||||
|
|
||||||
DisplayServer::ScreenOrientation screen_orientation;
|
|
||||||
|
|
||||||
ObjectID window_attached_instance_id;
|
|
||||||
|
|
||||||
Callable window_event_callback;
|
|
||||||
Callable window_resize_callback;
|
|
||||||
Callable input_event_callback;
|
|
||||||
Callable input_text_callback;
|
|
||||||
|
|
||||||
Callable system_theme_changed;
|
|
||||||
|
|
||||||
int virtual_keyboard_height = 0;
|
|
||||||
|
|
||||||
void perform_event(const Ref<InputEvent> &p_event);
|
|
||||||
|
|
||||||
void initialize_tts() const;
|
|
||||||
|
|
||||||
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(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();
|
~DisplayServerIOS();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
String rendering_driver;
|
|
||||||
|
|
||||||
static DisplayServerIOS *get_singleton();
|
static DisplayServerIOS *get_singleton();
|
||||||
|
|
||||||
static void register_ios_driver();
|
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, int64_t p_parent_window, 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
|
|
||||||
|
|
||||||
virtual void process_events() override;
|
|
||||||
|
|
||||||
virtual void window_set_rect_changed_callback(const Callable &p_callable, WindowID p_window = MAIN_WINDOW_ID) override;
|
|
||||||
virtual void window_set_window_event_callback(const Callable &p_callable, WindowID p_window = MAIN_WINDOW_ID) override;
|
|
||||||
virtual void window_set_input_event_callback(const Callable &p_callable, WindowID p_window = MAIN_WINDOW_ID) override;
|
|
||||||
virtual void window_set_input_text_callback(const Callable &p_callable, WindowID p_window = MAIN_WINDOW_ID) override;
|
|
||||||
virtual void window_set_drop_files_callback(const Callable &p_callable, WindowID p_window = MAIN_WINDOW_ID) override;
|
|
||||||
|
|
||||||
static void _dispatch_input_events(const Ref<InputEvent> &p_event);
|
|
||||||
void send_input_event(const Ref<InputEvent> &p_event) const;
|
|
||||||
void send_input_text(const String &p_text) const;
|
|
||||||
void send_window_event(DisplayServer::WindowEvent p_event) const;
|
|
||||||
void _window_callback(const Callable &p_callable, const Variant &p_arg) const;
|
|
||||||
|
|
||||||
void emit_system_theme_changed();
|
|
||||||
|
|
||||||
// MARK: - Input
|
|
||||||
|
|
||||||
// MARK: Touches and Apple Pencil
|
|
||||||
|
|
||||||
void touch_press(int p_idx, int p_x, int p_y, bool p_pressed, bool p_double_click);
|
|
||||||
void touch_drag(int p_idx, int p_prev_x, int p_prev_y, int p_x, int p_y, float p_pressure, Vector2 p_tilt);
|
|
||||||
void touches_canceled(int p_idx);
|
|
||||||
|
|
||||||
// MARK: Keyboard
|
|
||||||
|
|
||||||
void key(Key p_key, char32_t p_char, Key p_unshifted, Key p_physical, NSInteger p_modifier, bool p_pressed, KeyLocation p_location);
|
|
||||||
bool is_keyboard_active() const;
|
|
||||||
|
|
||||||
// MARK: Motion
|
|
||||||
|
|
||||||
void update_gravity(const Vector3 &p_gravity);
|
|
||||||
void update_accelerometer(const Vector3 &p_accelerometer);
|
|
||||||
void update_magnetometer(const Vector3 &p_magnetometer);
|
|
||||||
void update_gyroscope(const Vector3 &p_gyroscope);
|
|
||||||
|
|
||||||
// MARK: -
|
|
||||||
|
|
||||||
virtual bool has_feature(Feature p_feature) const override;
|
|
||||||
virtual String get_name() const override;
|
virtual String get_name() const override;
|
||||||
|
|
||||||
virtual bool tts_is_speaking() const override;
|
|
||||||
virtual bool tts_is_paused() const override;
|
|
||||||
virtual TypedArray<Dictionary> tts_get_voices() const override;
|
|
||||||
|
|
||||||
virtual void tts_speak(const String &p_text, const String &p_voice, int p_volume = 50, float p_pitch = 1.f, float p_rate = 1.f, int p_utterance_id = 0, bool p_interrupt = false) override;
|
|
||||||
virtual void tts_pause() override;
|
|
||||||
virtual void tts_resume() override;
|
|
||||||
virtual void tts_stop() override;
|
|
||||||
|
|
||||||
virtual bool is_dark_mode_supported() const override;
|
|
||||||
virtual bool is_dark_mode() const override;
|
|
||||||
virtual void set_system_theme_change_callback(const Callable &p_callable) override;
|
|
||||||
|
|
||||||
virtual Rect2i get_display_safe_area() const override;
|
|
||||||
|
|
||||||
virtual int get_screen_count() const override;
|
|
||||||
virtual int get_primary_screen() const override;
|
|
||||||
virtual Point2i screen_get_position(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
|
|
||||||
virtual Size2i screen_get_size(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
|
|
||||||
virtual Rect2i screen_get_usable_rect(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
|
|
||||||
virtual int screen_get_dpi(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
|
virtual int screen_get_dpi(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
|
||||||
virtual float screen_get_scale(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
|
virtual float screen_get_scale(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
|
||||||
virtual float screen_get_refresh_rate(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
|
virtual float screen_get_refresh_rate(int p_screen = SCREEN_OF_MAIN_WINDOW) const override;
|
||||||
|
|
||||||
virtual Vector<DisplayServer::WindowID> get_window_list() const override;
|
|
||||||
|
|
||||||
virtual WindowID get_window_at_screen_position(const Point2i &p_position) const override;
|
|
||||||
|
|
||||||
virtual int64_t window_get_native_handle(HandleType p_handle_type, WindowID p_window = MAIN_WINDOW_ID) const override;
|
|
||||||
|
|
||||||
virtual void window_attach_instance_id(ObjectID p_instance, WindowID p_window = MAIN_WINDOW_ID) override;
|
|
||||||
virtual ObjectID window_get_attached_instance_id(WindowID p_window = MAIN_WINDOW_ID) const override;
|
|
||||||
|
|
||||||
virtual void window_set_title(const String &p_title, WindowID p_window = MAIN_WINDOW_ID) override;
|
|
||||||
|
|
||||||
virtual int window_get_current_screen(WindowID p_window = MAIN_WINDOW_ID) const override;
|
|
||||||
virtual void window_set_current_screen(int p_screen, WindowID p_window = MAIN_WINDOW_ID) override;
|
|
||||||
|
|
||||||
virtual Point2i window_get_position(WindowID p_window = MAIN_WINDOW_ID) const override;
|
|
||||||
virtual Point2i window_get_position_with_decorations(WindowID p_window = MAIN_WINDOW_ID) const override;
|
|
||||||
virtual void window_set_position(const Point2i &p_position, WindowID p_window = MAIN_WINDOW_ID) override;
|
|
||||||
|
|
||||||
virtual void window_set_transient(WindowID p_window, WindowID p_parent) override;
|
|
||||||
|
|
||||||
virtual void window_set_max_size(const Size2i p_size, WindowID p_window = MAIN_WINDOW_ID) override;
|
|
||||||
virtual Size2i window_get_max_size(WindowID p_window = MAIN_WINDOW_ID) const override;
|
|
||||||
|
|
||||||
virtual void window_set_min_size(const Size2i p_size, WindowID p_window = MAIN_WINDOW_ID) override;
|
|
||||||
virtual Size2i window_get_min_size(WindowID p_window = MAIN_WINDOW_ID) const override;
|
|
||||||
|
|
||||||
virtual void window_set_size(const Size2i p_size, WindowID p_window = MAIN_WINDOW_ID) override;
|
|
||||||
virtual Size2i window_get_size(WindowID p_window = MAIN_WINDOW_ID) const override;
|
|
||||||
virtual Size2i window_get_size_with_decorations(WindowID p_window = MAIN_WINDOW_ID) const override;
|
|
||||||
|
|
||||||
virtual void window_set_mode(WindowMode p_mode, WindowID p_window = MAIN_WINDOW_ID) override;
|
|
||||||
virtual WindowMode window_get_mode(WindowID p_window = MAIN_WINDOW_ID) const override;
|
|
||||||
|
|
||||||
virtual bool window_is_maximize_allowed(WindowID p_window = MAIN_WINDOW_ID) const override;
|
|
||||||
|
|
||||||
virtual void window_set_flag(WindowFlags p_flag, bool p_enabled, WindowID p_window = MAIN_WINDOW_ID) override;
|
|
||||||
virtual bool window_get_flag(WindowFlags p_flag, WindowID p_window = MAIN_WINDOW_ID) const override;
|
|
||||||
|
|
||||||
virtual void window_request_attention(WindowID p_window = MAIN_WINDOW_ID) override;
|
|
||||||
virtual void window_move_to_foreground(WindowID p_window = MAIN_WINDOW_ID) override;
|
|
||||||
virtual bool window_is_focused(WindowID p_window = MAIN_WINDOW_ID) const override;
|
|
||||||
|
|
||||||
virtual float screen_get_max_scale() const override;
|
|
||||||
|
|
||||||
virtual void screen_set_orientation(DisplayServer::ScreenOrientation p_orientation, int p_screen) override;
|
|
||||||
virtual DisplayServer::ScreenOrientation screen_get_orientation(int p_screen) const override;
|
|
||||||
|
|
||||||
virtual bool window_can_draw(WindowID p_window = MAIN_WINDOW_ID) const override;
|
|
||||||
|
|
||||||
virtual bool can_any_window_draw() const override;
|
|
||||||
|
|
||||||
virtual void window_set_vsync_mode(DisplayServer::VSyncMode p_vsync_mode, WindowID p_window = MAIN_WINDOW_ID) override;
|
|
||||||
virtual DisplayServer::VSyncMode window_get_vsync_mode(WindowID p_vsync_mode) const override;
|
|
||||||
|
|
||||||
virtual bool is_touchscreen_available() const override;
|
|
||||||
|
|
||||||
virtual void virtual_keyboard_show(const String &p_existing_text, const Rect2 &p_screen_rect, VirtualKeyboardType p_type, int p_max_length, int p_cursor_start, int p_cursor_end) override;
|
|
||||||
virtual void virtual_keyboard_hide() override;
|
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
virtual void screen_set_keep_on(bool p_enable) override;
|
|
||||||
virtual bool screen_is_kept_on() const override;
|
|
||||||
|
|
||||||
void resize_window(CGSize size);
|
|
||||||
virtual void swap_buffers() override {}
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -30,492 +30,33 @@
|
|||||||
|
|
||||||
#import "display_server_ios.h"
|
#import "display_server_ios.h"
|
||||||
|
|
||||||
#import "app_delegate.h"
|
|
||||||
#import "device_metrics.h"
|
#import "device_metrics.h"
|
||||||
#import "godot_view.h"
|
|
||||||
#import "ios.h"
|
|
||||||
#import "key_mapping_ios.h"
|
|
||||||
#import "keyboard_input_view.h"
|
|
||||||
#import "os_ios.h"
|
|
||||||
#import "tts_ios.h"
|
|
||||||
#import "view_controller.h"
|
|
||||||
|
|
||||||
#include "core/config/project_settings.h"
|
|
||||||
#include "core/io/file_access_pack.h"
|
|
||||||
|
|
||||||
|
#import <UIKit/UIKit.h>
|
||||||
#import <sys/utsname.h>
|
#import <sys/utsname.h>
|
||||||
|
|
||||||
#import <GameController/GameController.h>
|
|
||||||
|
|
||||||
static const float kDisplayServerIOSAcceleration = 1.f;
|
|
||||||
|
|
||||||
DisplayServerIOS *DisplayServerIOS::get_singleton() {
|
DisplayServerIOS *DisplayServerIOS::get_singleton() {
|
||||||
return (DisplayServerIOS *)DisplayServer::get_singleton();
|
return (DisplayServerIOS *)DisplayServerAppleEmbedded::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, int64_t p_parent_window, 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();
|
DisplayServerAppleEmbedded(p_rendering_driver, p_mode, p_vsync_mode, p_flags, p_position, p_resolution, p_screen, p_context, p_parent_window, r_error) {
|
||||||
|
|
||||||
rendering_driver = p_rendering_driver;
|
|
||||||
|
|
||||||
// Init TTS
|
|
||||||
bool tts_enabled = GLOBAL_GET("audio/general/text_to_speech");
|
|
||||||
if (tts_enabled) {
|
|
||||||
initialize_tts();
|
|
||||||
}
|
|
||||||
native_menu = memnew(NativeMenu);
|
|
||||||
|
|
||||||
#if defined(RD_ENABLED)
|
|
||||||
rendering_context = nullptr;
|
|
||||||
rendering_device = nullptr;
|
|
||||||
|
|
||||||
CALayer *layer = nullptr;
|
|
||||||
|
|
||||||
union {
|
|
||||||
#ifdef VULKAN_ENABLED
|
|
||||||
RenderingContextDriverVulkanIOS::WindowPlatformData vulkan;
|
|
||||||
#endif
|
|
||||||
#ifdef METAL_ENABLED
|
|
||||||
GODOT_CLANG_WARNING_PUSH_AND_IGNORE("-Wunguarded-availability")
|
|
||||||
// Eliminate "RenderingContextDriverMetal is only available on iOS 14.0 or newer".
|
|
||||||
RenderingContextDriverMetal::WindowPlatformData metal;
|
|
||||||
GODOT_CLANG_WARNING_POP
|
|
||||||
#endif
|
|
||||||
} wpd;
|
|
||||||
|
|
||||||
#if defined(VULKAN_ENABLED)
|
|
||||||
if (rendering_driver == "vulkan") {
|
|
||||||
layer = [AppDelegate.viewController.godotView initializeRenderingForDriver:@"vulkan"];
|
|
||||||
if (!layer) {
|
|
||||||
ERR_FAIL_MSG("Failed to create iOS Vulkan rendering layer.");
|
|
||||||
}
|
|
||||||
wpd.vulkan.layer_ptr = (CAMetalLayer *const *)&layer;
|
|
||||||
rendering_context = memnew(RenderingContextDriverVulkanIOS);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#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);
|
|
||||||
rendering_context = nullptr;
|
|
||||||
r_error = ERR_UNAVAILABLE;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Size2i size = Size2i(layer.bounds.size.width, layer.bounds.size.height) * screen_get_max_scale();
|
|
||||||
rendering_context->window_set_size(MAIN_WINDOW_ID, size.width, size.height);
|
|
||||||
rendering_context->window_set_vsync_mode(MAIN_WINDOW_ID, p_vsync_mode);
|
|
||||||
|
|
||||||
rendering_device = memnew(RenderingDevice);
|
|
||||||
if (rendering_device->initialize(rendering_context, MAIN_WINDOW_ID) != OK) {
|
|
||||||
rendering_device = nullptr;
|
|
||||||
memdelete(rendering_context);
|
|
||||||
rendering_context = nullptr;
|
|
||||||
r_error = ERR_UNAVAILABLE;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
rendering_device->screen_create(MAIN_WINDOW_ID);
|
|
||||||
|
|
||||||
RendererCompositorRD::make_current();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(GLES3_ENABLED)
|
|
||||||
if (rendering_driver == "opengl3") {
|
|
||||||
CALayer *layer = [AppDelegate.viewController.godotView initializeRenderingForDriver:@"opengl3"];
|
|
||||||
|
|
||||||
if (!layer) {
|
|
||||||
ERR_FAIL_MSG("Failed to create iOS OpenGLES rendering layer.");
|
|
||||||
}
|
|
||||||
|
|
||||||
RasterizerGLES3::make_current(false);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
bool keep_screen_on = bool(GLOBAL_GET("display/window/energy_saving/keep_screen_on"));
|
|
||||||
screen_set_keep_on(keep_screen_on);
|
|
||||||
|
|
||||||
Input::get_singleton()->set_event_dispatch_function(_dispatch_input_events);
|
|
||||||
|
|
||||||
r_error = OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DisplayServerIOS::~DisplayServerIOS() {
|
DisplayServerIOS::~DisplayServerIOS() {
|
||||||
if (native_menu) {
|
|
||||||
memdelete(native_menu);
|
|
||||||
native_menu = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(RD_ENABLED)
|
|
||||||
if (rendering_device) {
|
|
||||||
rendering_device->screen_free(MAIN_WINDOW_ID);
|
|
||||||
memdelete(rendering_device);
|
|
||||||
rendering_device = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rendering_context) {
|
|
||||||
rendering_context->window_destroy(MAIN_WINDOW_ID);
|
|
||||||
memdelete(rendering_context);
|
|
||||||
rendering_context = nullptr;
|
|
||||||
}
|
|
||||||
#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, int64_t p_parent_window, Error &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));
|
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() {
|
|
||||||
Vector<String> drivers;
|
|
||||||
|
|
||||||
#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
|
|
||||||
|
|
||||||
return drivers;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DisplayServerIOS::register_ios_driver() {
|
void DisplayServerIOS::register_ios_driver() {
|
||||||
register_create_function("iOS", create_func, get_rendering_drivers_func);
|
register_create_function("iOS", create_func, get_rendering_drivers_func);
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: Events
|
|
||||||
|
|
||||||
void DisplayServerIOS::window_set_rect_changed_callback(const Callable &p_callable, WindowID p_window) {
|
|
||||||
window_resize_callback = p_callable;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DisplayServerIOS::window_set_window_event_callback(const Callable &p_callable, WindowID p_window) {
|
|
||||||
window_event_callback = p_callable;
|
|
||||||
}
|
|
||||||
void DisplayServerIOS::window_set_input_event_callback(const Callable &p_callable, WindowID p_window) {
|
|
||||||
input_event_callback = p_callable;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DisplayServerIOS::window_set_input_text_callback(const Callable &p_callable, WindowID p_window) {
|
|
||||||
input_text_callback = p_callable;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DisplayServerIOS::window_set_drop_files_callback(const Callable &p_callable, WindowID p_window) {
|
|
||||||
// Probably not supported for iOS
|
|
||||||
}
|
|
||||||
|
|
||||||
void DisplayServerIOS::process_events() {
|
|
||||||
Input::get_singleton()->flush_buffered_events();
|
|
||||||
}
|
|
||||||
|
|
||||||
void DisplayServerIOS::_dispatch_input_events(const Ref<InputEvent> &p_event) {
|
|
||||||
DisplayServerIOS::get_singleton()->send_input_event(p_event);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DisplayServerIOS::send_input_event(const Ref<InputEvent> &p_event) const {
|
|
||||||
_window_callback(input_event_callback, p_event);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DisplayServerIOS::send_input_text(const String &p_text) const {
|
|
||||||
_window_callback(input_text_callback, p_text);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DisplayServerIOS::send_window_event(DisplayServer::WindowEvent p_event) const {
|
|
||||||
_window_callback(window_event_callback, int(p_event));
|
|
||||||
}
|
|
||||||
|
|
||||||
void DisplayServerIOS::_window_callback(const Callable &p_callable, const Variant &p_arg) const {
|
|
||||||
if (p_callable.is_valid()) {
|
|
||||||
p_callable.call(p_arg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - Input
|
|
||||||
|
|
||||||
// MARK: Touches
|
|
||||||
|
|
||||||
void DisplayServerIOS::touch_press(int p_idx, int p_x, int p_y, bool p_pressed, bool p_double_click) {
|
|
||||||
Ref<InputEventScreenTouch> ev;
|
|
||||||
ev.instantiate();
|
|
||||||
|
|
||||||
ev->set_index(p_idx);
|
|
||||||
ev->set_pressed(p_pressed);
|
|
||||||
ev->set_position(Vector2(p_x, p_y));
|
|
||||||
ev->set_double_tap(p_double_click);
|
|
||||||
perform_event(ev);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DisplayServerIOS::touch_drag(int p_idx, int p_prev_x, int p_prev_y, int p_x, int p_y, float p_pressure, Vector2 p_tilt) {
|
|
||||||
Ref<InputEventScreenDrag> ev;
|
|
||||||
ev.instantiate();
|
|
||||||
ev->set_index(p_idx);
|
|
||||||
ev->set_pressure(p_pressure);
|
|
||||||
ev->set_tilt(p_tilt);
|
|
||||||
ev->set_position(Vector2(p_x, p_y));
|
|
||||||
ev->set_relative(Vector2(p_x - p_prev_x, p_y - p_prev_y));
|
|
||||||
ev->set_relative_screen_position(ev->get_relative());
|
|
||||||
perform_event(ev);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DisplayServerIOS::perform_event(const Ref<InputEvent> &p_event) {
|
|
||||||
Input::get_singleton()->parse_input_event(p_event);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DisplayServerIOS::touches_canceled(int p_idx) {
|
|
||||||
touch_press(p_idx, -1, -1, false, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: Keyboard
|
|
||||||
|
|
||||||
void DisplayServerIOS::key(Key p_key, char32_t p_char, Key p_unshifted, Key p_physical, NSInteger p_modifier, bool p_pressed, KeyLocation p_location) {
|
|
||||||
Ref<InputEventKey> ev;
|
|
||||||
ev.instantiate();
|
|
||||||
ev->set_echo(false);
|
|
||||||
ev->set_pressed(p_pressed);
|
|
||||||
ev->set_keycode(fix_keycode(p_char, p_key));
|
|
||||||
if (@available(iOS 13.4, *)) {
|
|
||||||
if (p_key != Key::SHIFT) {
|
|
||||||
ev->set_shift_pressed(p_modifier & UIKeyModifierShift);
|
|
||||||
}
|
|
||||||
if (p_key != Key::CTRL) {
|
|
||||||
ev->set_ctrl_pressed(p_modifier & UIKeyModifierControl);
|
|
||||||
}
|
|
||||||
if (p_key != Key::ALT) {
|
|
||||||
ev->set_alt_pressed(p_modifier & UIKeyModifierAlternate);
|
|
||||||
}
|
|
||||||
if (p_key != Key::META) {
|
|
||||||
ev->set_meta_pressed(p_modifier & UIKeyModifierCommand);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ev->set_key_label(p_unshifted);
|
|
||||||
ev->set_physical_keycode(p_physical);
|
|
||||||
ev->set_unicode(fix_unicode(p_char));
|
|
||||||
ev->set_location(p_location);
|
|
||||||
perform_event(ev);
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: Motion
|
|
||||||
|
|
||||||
void DisplayServerIOS::update_gravity(const Vector3 &p_gravity) {
|
|
||||||
Input::get_singleton()->set_gravity(p_gravity);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DisplayServerIOS::update_accelerometer(const Vector3 &p_accelerometer) {
|
|
||||||
Input::get_singleton()->set_accelerometer(p_accelerometer / kDisplayServerIOSAcceleration);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DisplayServerIOS::update_magnetometer(const Vector3 &p_magnetometer) {
|
|
||||||
Input::get_singleton()->set_magnetometer(p_magnetometer);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DisplayServerIOS::update_gyroscope(const Vector3 &p_gyroscope) {
|
|
||||||
Input::get_singleton()->set_gyroscope(p_gyroscope);
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: -
|
|
||||||
|
|
||||||
bool DisplayServerIOS::has_feature(Feature p_feature) const {
|
|
||||||
switch (p_feature) {
|
|
||||||
#ifndef DISABLE_DEPRECATED
|
|
||||||
case FEATURE_GLOBAL_MENU: {
|
|
||||||
return (native_menu && native_menu->has_feature(NativeMenu::FEATURE_GLOBAL_MENU));
|
|
||||||
} break;
|
|
||||||
#endif
|
|
||||||
// case FEATURE_CURSOR_SHAPE:
|
|
||||||
// case FEATURE_CUSTOM_CURSOR_SHAPE:
|
|
||||||
// case FEATURE_HIDPI:
|
|
||||||
// case FEATURE_ICON:
|
|
||||||
// case FEATURE_IME:
|
|
||||||
// case FEATURE_MOUSE:
|
|
||||||
// case FEATURE_MOUSE_WARP:
|
|
||||||
// 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:
|
|
||||||
case FEATURE_KEEP_SCREEN_ON:
|
|
||||||
case FEATURE_ORIENTATION:
|
|
||||||
case FEATURE_TOUCHSCREEN:
|
|
||||||
case FEATURE_VIRTUAL_KEYBOARD:
|
|
||||||
case FEATURE_TEXT_TO_SPEECH:
|
|
||||||
return true;
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
String DisplayServerIOS::get_name() const {
|
String DisplayServerIOS::get_name() const {
|
||||||
return "iOS";
|
return "iOS";
|
||||||
}
|
}
|
||||||
void DisplayServerIOS::initialize_tts() const {
|
|
||||||
const_cast<DisplayServerIOS *>(this)->tts = [[TTS_IOS alloc] init];
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DisplayServerIOS::tts_is_speaking() const {
|
|
||||||
if (unlikely(!tts)) {
|
|
||||||
initialize_tts();
|
|
||||||
}
|
|
||||||
ERR_FAIL_NULL_V(tts, false);
|
|
||||||
return [tts isSpeaking];
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DisplayServerIOS::tts_is_paused() const {
|
|
||||||
if (unlikely(!tts)) {
|
|
||||||
initialize_tts();
|
|
||||||
}
|
|
||||||
ERR_FAIL_NULL_V(tts, false);
|
|
||||||
return [tts isPaused];
|
|
||||||
}
|
|
||||||
|
|
||||||
TypedArray<Dictionary> DisplayServerIOS::tts_get_voices() const {
|
|
||||||
if (unlikely(!tts)) {
|
|
||||||
initialize_tts();
|
|
||||||
}
|
|
||||||
ERR_FAIL_NULL_V(tts, TypedArray<Dictionary>());
|
|
||||||
return [tts getVoices];
|
|
||||||
}
|
|
||||||
|
|
||||||
void DisplayServerIOS::tts_speak(const String &p_text, const String &p_voice, int p_volume, float p_pitch, float p_rate, int p_utterance_id, bool p_interrupt) {
|
|
||||||
if (unlikely(!tts)) {
|
|
||||||
initialize_tts();
|
|
||||||
}
|
|
||||||
ERR_FAIL_NULL(tts);
|
|
||||||
[tts speak:p_text voice:p_voice volume:p_volume pitch:p_pitch rate:p_rate utterance_id:p_utterance_id interrupt:p_interrupt];
|
|
||||||
}
|
|
||||||
|
|
||||||
void DisplayServerIOS::tts_pause() {
|
|
||||||
if (unlikely(!tts)) {
|
|
||||||
initialize_tts();
|
|
||||||
}
|
|
||||||
ERR_FAIL_NULL(tts);
|
|
||||||
[tts pauseSpeaking];
|
|
||||||
}
|
|
||||||
|
|
||||||
void DisplayServerIOS::tts_resume() {
|
|
||||||
if (unlikely(!tts)) {
|
|
||||||
initialize_tts();
|
|
||||||
}
|
|
||||||
ERR_FAIL_NULL(tts);
|
|
||||||
[tts resumeSpeaking];
|
|
||||||
}
|
|
||||||
|
|
||||||
void DisplayServerIOS::tts_stop() {
|
|
||||||
if (unlikely(!tts)) {
|
|
||||||
initialize_tts();
|
|
||||||
}
|
|
||||||
ERR_FAIL_NULL(tts);
|
|
||||||
[tts stopSpeaking];
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DisplayServerIOS::is_dark_mode_supported() const {
|
|
||||||
if (@available(iOS 13.0, *)) {
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DisplayServerIOS::is_dark_mode() const {
|
|
||||||
if (@available(iOS 13.0, *)) {
|
|
||||||
return [UITraitCollection currentTraitCollection].userInterfaceStyle == UIUserInterfaceStyleDark;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void DisplayServerIOS::set_system_theme_change_callback(const Callable &p_callable) {
|
|
||||||
system_theme_changed = p_callable;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DisplayServerIOS::emit_system_theme_changed() {
|
|
||||||
if (system_theme_changed.is_valid()) {
|
|
||||||
Variant ret;
|
|
||||||
Callable::CallError ce;
|
|
||||||
system_theme_changed.callp(nullptr, 0, ret, ce);
|
|
||||||
if (ce.error != Callable::CallError::CALL_OK) {
|
|
||||||
ERR_PRINT(vformat("Failed to execute system theme changed callback: %s.", Variant::get_callable_error_text(system_theme_changed, nullptr, 0, ce)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Rect2i DisplayServerIOS::get_display_safe_area() const {
|
|
||||||
UIEdgeInsets insets = UIEdgeInsetsZero;
|
|
||||||
UIView *view = AppDelegate.viewController.godotView;
|
|
||||||
if ([view respondsToSelector:@selector(safeAreaInsets)]) {
|
|
||||||
insets = [view safeAreaInsets];
|
|
||||||
}
|
|
||||||
float scale = screen_get_scale();
|
|
||||||
Size2i insets_position = Size2i(insets.left, insets.top) * scale;
|
|
||||||
Size2i insets_size = Size2i(insets.left + insets.right, insets.top + insets.bottom) * scale;
|
|
||||||
return Rect2i(screen_get_position() + insets_position, screen_get_size() - insets_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
int DisplayServerIOS::get_screen_count() const {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int DisplayServerIOS::get_primary_screen() const {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
Point2i DisplayServerIOS::screen_get_position(int p_screen) const {
|
|
||||||
return Size2i();
|
|
||||||
}
|
|
||||||
|
|
||||||
Size2i DisplayServerIOS::screen_get_size(int p_screen) const {
|
|
||||||
CALayer *layer = AppDelegate.viewController.godotView.renderingLayer;
|
|
||||||
|
|
||||||
if (!layer) {
|
|
||||||
return Size2i();
|
|
||||||
}
|
|
||||||
|
|
||||||
return Size2i(layer.bounds.size.width, layer.bounds.size.height) * screen_get_scale(p_screen);
|
|
||||||
}
|
|
||||||
|
|
||||||
Rect2i DisplayServerIOS::screen_get_usable_rect(int p_screen) const {
|
|
||||||
return Rect2i(screen_get_position(p_screen), screen_get_size(p_screen));
|
|
||||||
}
|
|
||||||
|
|
||||||
int DisplayServerIOS::screen_get_dpi(int p_screen) const {
|
int DisplayServerIOS::screen_get_dpi(int p_screen) const {
|
||||||
struct utsname systemInfo;
|
struct utsname systemInfo;
|
||||||
@@ -523,7 +64,7 @@ int DisplayServerIOS::screen_get_dpi(int p_screen) const {
|
|||||||
|
|
||||||
NSString *string = [NSString stringWithCString:systemInfo.machine encoding:NSUTF8StringEncoding];
|
NSString *string = [NSString stringWithCString:systemInfo.machine encoding:NSUTF8StringEncoding];
|
||||||
|
|
||||||
NSDictionary *iOSModelToDPI = [GodotDeviceMetrics dpiList];
|
NSDictionary *iOSModelToDPI = [GDTDeviceMetrics dpiList];
|
||||||
|
|
||||||
for (NSArray *keyArray in iOSModelToDPI) {
|
for (NSArray *keyArray in iOSModelToDPI) {
|
||||||
if ([keyArray containsObject:string]) {
|
if ([keyArray containsObject:string]) {
|
||||||
@@ -565,283 +106,3 @@ float DisplayServerIOS::screen_get_refresh_rate(int p_screen) const {
|
|||||||
float DisplayServerIOS::screen_get_scale(int p_screen) const {
|
float DisplayServerIOS::screen_get_scale(int p_screen) const {
|
||||||
return [UIScreen mainScreen].scale;
|
return [UIScreen mainScreen].scale;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector<DisplayServer::WindowID> DisplayServerIOS::get_window_list() const {
|
|
||||||
Vector<DisplayServer::WindowID> list;
|
|
||||||
list.push_back(MAIN_WINDOW_ID);
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
DisplayServer::WindowID DisplayServerIOS::get_window_at_screen_position(const Point2i &p_position) const {
|
|
||||||
return MAIN_WINDOW_ID;
|
|
||||||
}
|
|
||||||
|
|
||||||
int64_t DisplayServerIOS::window_get_native_handle(HandleType p_handle_type, WindowID p_window) const {
|
|
||||||
ERR_FAIL_COND_V(p_window != MAIN_WINDOW_ID, 0);
|
|
||||||
switch (p_handle_type) {
|
|
||||||
case DISPLAY_HANDLE: {
|
|
||||||
return 0; // Not supported.
|
|
||||||
}
|
|
||||||
case WINDOW_HANDLE: {
|
|
||||||
return (int64_t)AppDelegate.viewController;
|
|
||||||
}
|
|
||||||
case WINDOW_VIEW: {
|
|
||||||
return (int64_t)AppDelegate.viewController.godotView;
|
|
||||||
}
|
|
||||||
default: {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void DisplayServerIOS::window_attach_instance_id(ObjectID p_instance, WindowID p_window) {
|
|
||||||
window_attached_instance_id = p_instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
ObjectID DisplayServerIOS::window_get_attached_instance_id(WindowID p_window) const {
|
|
||||||
return window_attached_instance_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DisplayServerIOS::window_set_title(const String &p_title, WindowID p_window) {
|
|
||||||
// Probably not supported for iOS
|
|
||||||
}
|
|
||||||
|
|
||||||
int DisplayServerIOS::window_get_current_screen(WindowID p_window) const {
|
|
||||||
return SCREEN_OF_MAIN_WINDOW;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DisplayServerIOS::window_set_current_screen(int p_screen, WindowID p_window) {
|
|
||||||
// Probably not supported for iOS
|
|
||||||
}
|
|
||||||
|
|
||||||
Point2i DisplayServerIOS::window_get_position(WindowID p_window) const {
|
|
||||||
return Point2i();
|
|
||||||
}
|
|
||||||
|
|
||||||
Point2i DisplayServerIOS::window_get_position_with_decorations(WindowID p_window) const {
|
|
||||||
return Point2i();
|
|
||||||
}
|
|
||||||
|
|
||||||
void DisplayServerIOS::window_set_position(const Point2i &p_position, WindowID p_window) {
|
|
||||||
// Probably not supported for single window iOS app
|
|
||||||
}
|
|
||||||
|
|
||||||
void DisplayServerIOS::window_set_transient(WindowID p_window, WindowID p_parent) {
|
|
||||||
// Probably not supported for iOS
|
|
||||||
}
|
|
||||||
|
|
||||||
void DisplayServerIOS::window_set_max_size(const Size2i p_size, WindowID p_window) {
|
|
||||||
// Probably not supported for iOS
|
|
||||||
}
|
|
||||||
|
|
||||||
Size2i DisplayServerIOS::window_get_max_size(WindowID p_window) const {
|
|
||||||
return Size2i();
|
|
||||||
}
|
|
||||||
|
|
||||||
void DisplayServerIOS::window_set_min_size(const Size2i p_size, WindowID p_window) {
|
|
||||||
// Probably not supported for iOS
|
|
||||||
}
|
|
||||||
|
|
||||||
Size2i DisplayServerIOS::window_get_min_size(WindowID p_window) const {
|
|
||||||
return Size2i();
|
|
||||||
}
|
|
||||||
|
|
||||||
void DisplayServerIOS::window_set_size(const Size2i p_size, WindowID p_window) {
|
|
||||||
// Probably not supported for iOS
|
|
||||||
}
|
|
||||||
|
|
||||||
Size2i DisplayServerIOS::window_get_size(WindowID p_window) const {
|
|
||||||
CGRect screenBounds = [UIScreen mainScreen].bounds;
|
|
||||||
return Size2i(screenBounds.size.width, screenBounds.size.height) * screen_get_max_scale();
|
|
||||||
}
|
|
||||||
|
|
||||||
Size2i DisplayServerIOS::window_get_size_with_decorations(WindowID p_window) const {
|
|
||||||
return window_get_size(p_window);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DisplayServerIOS::window_set_mode(WindowMode p_mode, WindowID p_window) {
|
|
||||||
// Probably not supported for iOS
|
|
||||||
}
|
|
||||||
|
|
||||||
DisplayServer::WindowMode DisplayServerIOS::window_get_mode(WindowID p_window) const {
|
|
||||||
return WindowMode::WINDOW_MODE_FULLSCREEN;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DisplayServerIOS::window_is_maximize_allowed(WindowID p_window) const {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DisplayServerIOS::window_set_flag(WindowFlags p_flag, bool p_enabled, WindowID p_window) {
|
|
||||||
// Probably not supported for iOS
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DisplayServerIOS::window_get_flag(WindowFlags p_flag, WindowID p_window) const {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DisplayServerIOS::window_request_attention(WindowID p_window) {
|
|
||||||
// Probably not supported for iOS
|
|
||||||
}
|
|
||||||
|
|
||||||
void DisplayServerIOS::window_move_to_foreground(WindowID p_window) {
|
|
||||||
// Probably not supported for iOS
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DisplayServerIOS::window_is_focused(WindowID p_window) const {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
float DisplayServerIOS::screen_get_max_scale() const {
|
|
||||||
return screen_get_scale(SCREEN_OF_MAIN_WINDOW);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DisplayServerIOS::screen_set_orientation(DisplayServer::ScreenOrientation p_orientation, int p_screen) {
|
|
||||||
screen_orientation = p_orientation;
|
|
||||||
if (@available(iOS 16.0, *)) {
|
|
||||||
[AppDelegate.viewController setNeedsUpdateOfSupportedInterfaceOrientations];
|
|
||||||
} else {
|
|
||||||
[UIViewController attemptRotationToDeviceOrientation];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DisplayServer::ScreenOrientation DisplayServerIOS::screen_get_orientation(int p_screen) const {
|
|
||||||
return screen_orientation;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DisplayServerIOS::window_can_draw(WindowID p_window) const {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DisplayServerIOS::can_any_window_draw() const {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DisplayServerIOS::is_touchscreen_available() const {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
_FORCE_INLINE_ int _convert_utf32_offset_to_utf16(const String &p_existing_text, int p_pos) {
|
|
||||||
int limit = p_pos;
|
|
||||||
for (int i = 0; i < MIN(p_existing_text.length(), p_pos); i++) {
|
|
||||||
if (p_existing_text[i] > 0xffff) {
|
|
||||||
limit++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return limit;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DisplayServerIOS::virtual_keyboard_show(const String &p_existing_text, const Rect2 &p_screen_rect, VirtualKeyboardType p_type, int p_max_length, int p_cursor_start, int p_cursor_end) {
|
|
||||||
NSString *existingString = [[NSString alloc] initWithUTF8String:p_existing_text.utf8().get_data()];
|
|
||||||
|
|
||||||
AppDelegate.viewController.keyboardView.keyboardType = UIKeyboardTypeDefault;
|
|
||||||
AppDelegate.viewController.keyboardView.textContentType = nil;
|
|
||||||
switch (p_type) {
|
|
||||||
case KEYBOARD_TYPE_DEFAULT: {
|
|
||||||
AppDelegate.viewController.keyboardView.keyboardType = UIKeyboardTypeDefault;
|
|
||||||
} break;
|
|
||||||
case KEYBOARD_TYPE_MULTILINE: {
|
|
||||||
AppDelegate.viewController.keyboardView.keyboardType = UIKeyboardTypeDefault;
|
|
||||||
} break;
|
|
||||||
case KEYBOARD_TYPE_NUMBER: {
|
|
||||||
AppDelegate.viewController.keyboardView.keyboardType = UIKeyboardTypeNumberPad;
|
|
||||||
} break;
|
|
||||||
case KEYBOARD_TYPE_NUMBER_DECIMAL: {
|
|
||||||
AppDelegate.viewController.keyboardView.keyboardType = UIKeyboardTypeDecimalPad;
|
|
||||||
} break;
|
|
||||||
case KEYBOARD_TYPE_PHONE: {
|
|
||||||
AppDelegate.viewController.keyboardView.keyboardType = UIKeyboardTypePhonePad;
|
|
||||||
AppDelegate.viewController.keyboardView.textContentType = UITextContentTypeTelephoneNumber;
|
|
||||||
} break;
|
|
||||||
case KEYBOARD_TYPE_EMAIL_ADDRESS: {
|
|
||||||
AppDelegate.viewController.keyboardView.keyboardType = UIKeyboardTypeEmailAddress;
|
|
||||||
AppDelegate.viewController.keyboardView.textContentType = UITextContentTypeEmailAddress;
|
|
||||||
} break;
|
|
||||||
case KEYBOARD_TYPE_PASSWORD: {
|
|
||||||
AppDelegate.viewController.keyboardView.keyboardType = UIKeyboardTypeDefault;
|
|
||||||
AppDelegate.viewController.keyboardView.textContentType = UITextContentTypePassword;
|
|
||||||
} break;
|
|
||||||
case KEYBOARD_TYPE_URL: {
|
|
||||||
AppDelegate.viewController.keyboardView.keyboardType = UIKeyboardTypeWebSearch;
|
|
||||||
AppDelegate.viewController.keyboardView.textContentType = UITextContentTypeURL;
|
|
||||||
} break;
|
|
||||||
}
|
|
||||||
|
|
||||||
[AppDelegate.viewController.keyboardView
|
|
||||||
becomeFirstResponderWithString:existingString
|
|
||||||
cursorStart:_convert_utf32_offset_to_utf16(p_existing_text, p_cursor_start)
|
|
||||||
cursorEnd:_convert_utf32_offset_to_utf16(p_existing_text, p_cursor_end)];
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DisplayServerIOS::is_keyboard_active() const {
|
|
||||||
return [AppDelegate.viewController.keyboardView isFirstResponder];
|
|
||||||
}
|
|
||||||
|
|
||||||
void DisplayServerIOS::virtual_keyboard_hide() {
|
|
||||||
[AppDelegate.viewController.keyboardView resignFirstResponder];
|
|
||||||
}
|
|
||||||
|
|
||||||
void DisplayServerIOS::virtual_keyboard_set_height(int height) {
|
|
||||||
virtual_keyboard_height = height * screen_get_max_scale();
|
|
||||||
}
|
|
||||||
|
|
||||||
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().get_data()];
|
|
||||||
}
|
|
||||||
|
|
||||||
String DisplayServerIOS::clipboard_get() const {
|
|
||||||
NSString *text = [UIPasteboard generalPasteboard].string;
|
|
||||||
|
|
||||||
return String::utf8([text UTF8String]);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DisplayServerIOS::screen_set_keep_on(bool p_enable) {
|
|
||||||
[UIApplication sharedApplication].idleTimerDisabled = p_enable;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool DisplayServerIOS::screen_is_kept_on() const {
|
|
||||||
return [UIApplication sharedApplication].idleTimerDisabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DisplayServerIOS::resize_window(CGSize viewSize) {
|
|
||||||
Size2i size = Size2i(viewSize.width, viewSize.height) * screen_get_max_scale();
|
|
||||||
|
|
||||||
#if defined(RD_ENABLED)
|
|
||||||
if (rendering_context) {
|
|
||||||
rendering_context->window_set_size(MAIN_WINDOW_ID, size.x, size.y);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
Variant resize_rect = Rect2i(Point2i(), size);
|
|
||||||
_window_callback(window_resize_callback, resize_rect);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DisplayServerIOS::window_set_vsync_mode(DisplayServer::VSyncMode p_vsync_mode, WindowID p_window) {
|
|
||||||
_THREAD_SAFE_METHOD_
|
|
||||||
#if defined(RD_ENABLED)
|
|
||||||
if (rendering_context) {
|
|
||||||
rendering_context->window_set_vsync_mode(p_window, p_vsync_mode);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
DisplayServer::VSyncMode DisplayServerIOS::window_get_vsync_mode(WindowID p_window) const {
|
|
||||||
_THREAD_SAFE_METHOD_
|
|
||||||
#if defined(RD_ENABLED)
|
|
||||||
if (rendering_context) {
|
|
||||||
return rendering_context->window_get_vsync_mode(p_window);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return DisplayServer::VSYNC_ENABLED;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" ?>
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
<class name="EditorExportPlatformIOS" inherits="EditorExportPlatform" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
|
<class name="EditorExportPlatformIOS" inherits="EditorExportPlatformAppleEmbedded" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
|
||||||
<brief_description>
|
<brief_description>
|
||||||
Exporter for iOS.
|
Exporter for iOS.
|
||||||
</brief_description>
|
</brief_description>
|
||||||
@@ -24,10 +24,10 @@
|
|||||||
Unique application identifier in a reverse-DNS format, can only contain alphanumeric characters ([code]A-Z[/code], [code]a-z[/code], and [code]0-9[/code]), hyphens ([code]-[/code]), and periods ([code].[/code]).
|
Unique application identifier in a reverse-DNS format, can only contain alphanumeric characters ([code]A-Z[/code], [code]a-z[/code], and [code]0-9[/code]), hyphens ([code]-[/code]), and periods ([code].[/code]).
|
||||||
</member>
|
</member>
|
||||||
<member name="application/code_sign_identity_debug" type="String" setter="" getter="">
|
<member name="application/code_sign_identity_debug" type="String" setter="" getter="">
|
||||||
The "Full Name", "Common Name" or SHA-1 hash of the signing identity used for debug export.
|
The "Full Name", "Common Name", or SHA-1 hash of the signing identity used for debug export.
|
||||||
</member>
|
</member>
|
||||||
<member name="application/code_sign_identity_release" type="String" setter="" getter="">
|
<member name="application/code_sign_identity_release" type="String" setter="" getter="">
|
||||||
The "Full Name", "Common Name" or SHA-1 hash of the signing identity used for release export.
|
The "Full Name", "Common Name", or SHA-1 hash of the signing identity used for release export.
|
||||||
</member>
|
</member>
|
||||||
<member name="application/delete_old_export_files_unconditionally" type="bool" setter="" getter="">
|
<member name="application/delete_old_export_files_unconditionally" type="bool" setter="" getter="">
|
||||||
If [code]true[/code], existing "project name" and "project name.xcodeproj" in the export destination directory will be unconditionally deleted during export.
|
If [code]true[/code], existing "project name" and "project name.xcodeproj" in the export destination directory will be unconditionally deleted during export.
|
||||||
@@ -48,20 +48,20 @@
|
|||||||
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]).
|
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>
|
||||||
<member name="application/provisioning_profile_specifier_debug" type="String" setter="" getter="">
|
<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].
|
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].
|
Can be overridden with the environment variable [code]GODOT_APPLE_PLATFORM_PROFILE_SPECIFIER_DEBUG[/code].
|
||||||
</member>
|
</member>
|
||||||
<member name="application/provisioning_profile_specifier_release" type="String" setter="" getter="">
|
<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].
|
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].
|
Can be overridden with the environment variable [code]GODOT_APPLE_PLATFORM_PROFILE_SPECIFIER_RELEASE[/code].
|
||||||
</member>
|
</member>
|
||||||
<member name="application/provisioning_profile_uuid_debug" type="String" setter="" getter="">
|
<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].
|
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].
|
Can be overridden with the environment variable [code]GODOT_APPLE_PLATFORM_PROVISIONING_PROFILE_UUID_DEBUG[/code].
|
||||||
</member>
|
</member>
|
||||||
<member name="application/provisioning_profile_uuid_release" type="String" setter="" getter="">
|
<member name="application/provisioning_profile_uuid_release" 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].
|
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_RELEASE[/code].
|
Can be overridden with the environment variable [code]GODOT_APPLE_PLATFORM_PROVISIONING_PROFILE_UUID_RELEASE[/code].
|
||||||
</member>
|
</member>
|
||||||
<member name="application/short_version" type="String" setter="" getter="">
|
<member name="application/short_version" type="String" setter="" getter="">
|
||||||
Application version visible to the user, can only contain numeric characters ([code]0-9[/code]) and periods ([code].[/code]). Falls back to [member ProjectSettings.application/config/version] if left empty.
|
Application version visible to the user, can only contain numeric characters ([code]0-9[/code]) and periods ([code].[/code]). Falls back to [member ProjectSettings.application/config/version] if left empty.
|
||||||
@@ -86,7 +86,7 @@
|
|||||||
</member>
|
</member>
|
||||||
<member name="capabilities/performance_a12" type="bool" setter="" getter="">
|
<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).
|
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.
|
Enabling this option limits supported devices to: iPhone XS, iPhone XR, iPad Mini (5th gen.), iPad Air (3rd gen.), iPad (8th gen), and newer.
|
||||||
</member>
|
</member>
|
||||||
<member name="capabilities/performance_gaming_tier" type="bool" setter="" getter="">
|
<member name="capabilities/performance_gaming_tier" type="bool" setter="" getter="">
|
||||||
Requires the graphics performance and features of the A17 Pro and later chips.
|
Requires the graphics performance and features of the A17 Pro and later chips.
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -30,268 +30,35 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "godot_plugin_config.h"
|
#include "editor/export/editor_export_platform_apple_embedded.h"
|
||||||
|
|
||||||
#include "core/config/project_settings.h"
|
class EditorExportPlatformIOS : public EditorExportPlatformAppleEmbedded {
|
||||||
#include "core/io/file_access.h"
|
GDCLASS(EditorExportPlatformIOS, EditorExportPlatformAppleEmbedded);
|
||||||
#include "core/io/image_loader.h"
|
|
||||||
#include "core/io/marshalls.h"
|
|
||||||
#include "core/io/resource_saver.h"
|
|
||||||
#include "core/io/zip_io.h"
|
|
||||||
#include "core/os/os.h"
|
|
||||||
#include "core/templates/safe_refcount.h"
|
|
||||||
#include "editor/editor_settings.h"
|
|
||||||
#include "editor/export/editor_export_platform.h"
|
|
||||||
#include "main/splash.gen.h"
|
|
||||||
#include "scene/resources/image_texture.h"
|
|
||||||
|
|
||||||
#include <sys/stat.h>
|
virtual String get_platform_name() const override { return "ios"; }
|
||||||
|
|
||||||
// Optional environment variables for defining confidential information. If any
|
virtual String get_sdk_name() const override { return "iphoneos"; }
|
||||||
// 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 {
|
virtual String get_minimum_deployment_target() const override { return "14.0"; }
|
||||||
GDCLASS(EditorExportPlatformIOS, EditorExportPlatform);
|
|
||||||
|
|
||||||
Ref<ImageTexture> logo;
|
virtual Vector<IconInfo> get_icon_infos() const override;
|
||||||
Ref<ImageTexture> run_icon;
|
|
||||||
|
|
||||||
// Plugins
|
|
||||||
mutable SafeFlag plugins_changed;
|
|
||||||
SafeFlag devices_changed;
|
|
||||||
|
|
||||||
struct Device {
|
|
||||||
String id;
|
|
||||||
String name;
|
|
||||||
bool wifi = false;
|
|
||||||
bool use_ios_deploy = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
Vector<Device> devices;
|
|
||||||
Mutex device_lock;
|
|
||||||
|
|
||||||
Mutex plugins_lock;
|
|
||||||
mutable Vector<PluginConfigIOS> plugins;
|
|
||||||
#ifdef MACOS_ENABLED
|
|
||||||
Thread check_for_changes_thread;
|
|
||||||
SafeFlag quit_request;
|
|
||||||
SafeFlag has_runnable_preset;
|
|
||||||
|
|
||||||
static bool _check_xcode_install();
|
|
||||||
static void _check_for_changes_poll_thread(void *ud);
|
|
||||||
void _update_preset_status();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef Error (*FileHandler)(String p_file, void *p_userdata);
|
|
||||||
static Error _walk_dir_recursive(Ref<DirAccess> &p_da, FileHandler p_handler, void *p_userdata);
|
|
||||||
static Error _codesign(String p_file, void *p_userdata);
|
|
||||||
void _blend_and_rotate(Ref<Image> &p_dst, Ref<Image> &p_src, bool p_rot);
|
|
||||||
|
|
||||||
struct IOSConfigData {
|
|
||||||
String pkg_name;
|
|
||||||
String binary_name;
|
|
||||||
String plist_content;
|
|
||||||
String architectures;
|
|
||||||
String linker_flags;
|
|
||||||
String cpp_code;
|
|
||||||
String modules_buildfile;
|
|
||||||
String modules_fileref;
|
|
||||||
String modules_buildphase;
|
|
||||||
String modules_buildgrp;
|
|
||||||
Vector<String> capabilities;
|
|
||||||
bool use_swift_runtime;
|
|
||||||
};
|
|
||||||
struct ExportArchitecture {
|
|
||||||
String name;
|
|
||||||
bool is_default = false;
|
|
||||||
|
|
||||||
ExportArchitecture() {}
|
|
||||||
|
|
||||||
ExportArchitecture(String p_name, bool p_is_default) {
|
|
||||||
name = p_name;
|
|
||||||
is_default = p_is_default;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct IOSExportAsset {
|
|
||||||
String exported_path;
|
|
||||||
bool is_framework = false; // framework is anything linked to the binary, otherwise it's a resource
|
|
||||||
bool should_embed = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
String _get_additional_plist_content();
|
|
||||||
String _get_linker_flags();
|
|
||||||
String _get_cpp_code();
|
|
||||||
void _fix_config_file(const Ref<EditorExportPreset> &p_preset, Vector<uint8_t> &pfile, const IOSConfigData &p_config, bool p_debug);
|
|
||||||
Error _export_loading_screen_file(const Ref<EditorExportPreset> &p_preset, const String &p_dest_dir);
|
|
||||||
Error _export_icons(const Ref<EditorExportPreset> &p_preset, const String &p_iconset_dir);
|
|
||||||
|
|
||||||
Vector<ExportArchitecture> _get_supported_architectures() const;
|
|
||||||
Vector<String> _get_preset_architectures(const Ref<EditorExportPreset> &p_preset) 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;
|
|
||||||
|
|
||||||
void _add_assets_to_project(const String &p_out_dir, const Ref<EditorExportPreset> &p_preset, Vector<uint8_t> &p_project_data, const Vector<IOSExportAsset> &p_additional_assets);
|
|
||||||
Error _export_additional_assets(const Ref<EditorExportPreset> &p_preset, const String &p_out_dir, const Vector<String> &p_assets, bool p_is_framework, bool p_should_embed, Vector<IOSExportAsset> &r_exported_assets);
|
|
||||||
Error _copy_asset(const Ref<EditorExportPreset> &p_preset, const String &p_out_dir, const String &p_asset, const String *p_custom_file_name, bool p_is_framework, bool p_should_embed, Vector<IOSExportAsset> &r_exported_assets);
|
|
||||||
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, BitField<EditorExportPlatform::DebugFlags> p_flags, bool p_oneclick);
|
|
||||||
|
|
||||||
bool is_package_name_valid(const String &p_package, String *r_error = nullptr) const;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual void get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) const override;
|
|
||||||
virtual void get_export_options(List<ExportOption> *r_options) const override;
|
virtual void get_export_options(List<ExportOption> *r_options) const override;
|
||||||
virtual bool get_export_option_visibility(const EditorExportPreset *p_preset, const String &p_option) const 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 String get_export_option_warning(const EditorExportPreset *p_preset, const StringName &p_name) const override;
|
|
||||||
|
|
||||||
void _notification(int p_what);
|
virtual Error _export_loading_screen_file(const Ref<EditorExportPreset> &p_preset, const String &p_dest_dir) override;
|
||||||
|
virtual Error _export_icons(const Ref<EditorExportPreset> &p_preset, const String &p_iconset_dir) override;
|
||||||
|
virtual HashMap<String, Variant> get_custom_project_settings(const Ref<EditorExportPreset> &p_preset) const override;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual String get_name() const override { return "iOS"; }
|
virtual String get_name() const override { return "iOS"; }
|
||||||
virtual String get_os_name() const override { return "iOS"; }
|
virtual String get_os_name() const override { return "iOS"; }
|
||||||
virtual Ref<Texture2D> get_logo() const override { return logo; }
|
|
||||||
virtual Ref<Texture2D> get_run_icon() const override { return run_icon; }
|
|
||||||
|
|
||||||
virtual int get_options_count() const override;
|
|
||||||
virtual String get_options_tooltip() const override;
|
|
||||||
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, BitField<EditorExportPlatform::DebugFlags> p_debug_flags) override;
|
|
||||||
|
|
||||||
virtual bool poll_export() override {
|
|
||||||
bool dc = devices_changed.is_set();
|
|
||||||
if (dc) {
|
|
||||||
// don't clear unless we're reporting true, to avoid race
|
|
||||||
devices_changed.clear();
|
|
||||||
}
|
|
||||||
return dc;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual bool should_update_export_options() override {
|
|
||||||
bool export_options_changed = plugins_changed.is_set();
|
|
||||||
if (export_options_changed) {
|
|
||||||
// don't clear unless we're reporting true, to avoid race
|
|
||||||
plugins_changed.clear();
|
|
||||||
}
|
|
||||||
return export_options_changed;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual List<String> get_binary_extensions(const Ref<EditorExportPreset> &p_preset) const override {
|
|
||||||
List<String> list;
|
|
||||||
if (p_preset.is_valid()) {
|
|
||||||
bool project_only = p_preset->get("application/export_project_only");
|
|
||||||
if (project_only) {
|
|
||||||
list.push_back("xcodeproj");
|
|
||||||
} else {
|
|
||||||
list.push_back("ipa");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
virtual void get_platform_features(List<String> *r_features) const override {
|
virtual void get_platform_features(List<String> *r_features) const override {
|
||||||
r_features->push_back("mobile");
|
EditorExportPlatformAppleEmbedded::get_platform_features(r_features);
|
||||||
r_features->push_back("ios");
|
r_features->push_back("ios");
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void resolve_platform_feature_priorities(const Ref<EditorExportPreset> &p_preset, HashSet<String> &p_features) override {
|
|
||||||
}
|
|
||||||
|
|
||||||
EditorExportPlatformIOS();
|
EditorExportPlatformIOS();
|
||||||
~EditorExportPlatformIOS();
|
~EditorExportPlatformIOS();
|
||||||
|
|
||||||
/// List the gdip files in the directory specified by the p_path parameter.
|
|
||||||
static Vector<String> list_plugin_config_files(const String &p_path, bool p_check_directories) {
|
|
||||||
Vector<String> dir_files;
|
|
||||||
Ref<DirAccess> da = DirAccess::open(p_path);
|
|
||||||
if (da.is_valid()) {
|
|
||||||
da->list_dir_begin();
|
|
||||||
while (true) {
|
|
||||||
String file = da->get_next();
|
|
||||||
if (file.is_empty()) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (file == "." || file == "..") {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (da->current_is_hidden()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (da->current_is_dir()) {
|
|
||||||
if (p_check_directories) {
|
|
||||||
Vector<String> directory_files = list_plugin_config_files(p_path.path_join(file), false);
|
|
||||||
for (int i = 0; i < directory_files.size(); ++i) {
|
|
||||||
dir_files.push_back(file.path_join(directory_files[i]));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (file.ends_with(PluginConfigIOS::PLUGIN_CONFIG_EXT)) {
|
|
||||||
dir_files.push_back(file);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
da->list_dir_end();
|
|
||||||
}
|
|
||||||
|
|
||||||
return dir_files;
|
|
||||||
}
|
|
||||||
|
|
||||||
static Vector<PluginConfigIOS> get_plugins() {
|
|
||||||
Vector<PluginConfigIOS> loaded_plugins;
|
|
||||||
|
|
||||||
String plugins_dir = ProjectSettings::get_singleton()->get_resource_path().path_join("ios/plugins");
|
|
||||||
|
|
||||||
if (DirAccess::exists(plugins_dir)) {
|
|
||||||
Vector<String> plugins_filenames = list_plugin_config_files(plugins_dir, true);
|
|
||||||
|
|
||||||
if (!plugins_filenames.is_empty()) {
|
|
||||||
Ref<ConfigFile> config_file = memnew(ConfigFile);
|
|
||||||
for (int i = 0; i < plugins_filenames.size(); i++) {
|
|
||||||
PluginConfigIOS config = PluginConfigIOS::load_plugin_config(config_file, plugins_dir.path_join(plugins_filenames[i]));
|
|
||||||
if (config.valid_config) {
|
|
||||||
loaded_plugins.push_back(config);
|
|
||||||
} else {
|
|
||||||
print_error("Invalid plugin config file " + plugins_filenames[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return loaded_plugins;
|
|
||||||
}
|
|
||||||
|
|
||||||
static Vector<PluginConfigIOS> get_enabled_plugins(const Ref<EditorExportPreset> &p_presets) {
|
|
||||||
Vector<PluginConfigIOS> enabled_plugins;
|
|
||||||
Vector<PluginConfigIOS> all_plugins = get_plugins();
|
|
||||||
for (int i = 0; i < all_plugins.size(); i++) {
|
|
||||||
PluginConfigIOS plugin = all_plugins[i];
|
|
||||||
bool enabled = p_presets->get("plugins/" + plugin.name);
|
|
||||||
if (enabled) {
|
|
||||||
enabled_plugins.push_back(plugin);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return enabled_plugins;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|||||||
37
platform/ios/godot_view_ios.h
Normal file
37
platform/ios/godot_view_ios.h
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
/**************************************************************************/
|
||||||
|
/* godot_view_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. */
|
||||||
|
/**************************************************************************/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "drivers/apple_embedded/godot_view_apple_embedded.h"
|
||||||
|
|
||||||
|
@interface GDTViewIOS : GDTView
|
||||||
|
|
||||||
|
@end
|
||||||
87
platform/ios/godot_view_ios.mm
Normal file
87
platform/ios/godot_view_ios.mm
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
/**************************************************************************/
|
||||||
|
/* godot_view_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 "godot_view_ios.h"
|
||||||
|
|
||||||
|
#import "display_layer_ios.h"
|
||||||
|
|
||||||
|
#include "core/error/error_macros.h"
|
||||||
|
|
||||||
|
@interface GDTViewIOS ()
|
||||||
|
|
||||||
|
GODOT_CLANG_WARNING_PUSH_AND_IGNORE("-Wobjc-property-synthesis")
|
||||||
|
@property(strong, nonatomic) CALayer<GDTDisplayLayer> *renderingLayer;
|
||||||
|
GODOT_CLANG_WARNING_POP
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation GDTViewIOS
|
||||||
|
|
||||||
|
- (CALayer<GDTDisplayLayer> *)initializeRenderingForDriver:(NSString *)driverName {
|
||||||
|
if (self.renderingLayer) {
|
||||||
|
return self.renderingLayer;
|
||||||
|
}
|
||||||
|
|
||||||
|
CALayer<GDTDisplayLayer> *layer;
|
||||||
|
|
||||||
|
if ([driverName isEqualToString:@"vulkan"] || [driverName isEqualToString:@"metal"]) {
|
||||||
|
#if defined(TARGET_OS_SIMULATOR) && TARGET_OS_SIMULATOR
|
||||||
|
if (@available(iOS 13, *)) {
|
||||||
|
layer = [GDTMetalLayer layer];
|
||||||
|
} else {
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
layer = [GDTMetalLayer layer];
|
||||||
|
#endif
|
||||||
|
} else if ([driverName isEqualToString:@"opengl3"]) {
|
||||||
|
GODOT_CLANG_WARNING_PUSH_AND_IGNORE("-Wdeprecated-declarations") // OpenGL is deprecated in iOS 12.0.
|
||||||
|
layer = [GDTOpenGLLayer layer];
|
||||||
|
GODOT_CLANG_WARNING_POP
|
||||||
|
} else {
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
layer.frame = self.bounds;
|
||||||
|
layer.contentsScale = self.contentScaleFactor;
|
||||||
|
|
||||||
|
[self.layer addSublayer:layer];
|
||||||
|
self.renderingLayer = layer;
|
||||||
|
|
||||||
|
[layer initializeDisplayLayer];
|
||||||
|
|
||||||
|
return self.renderingLayer;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
GDTView *GDTViewCreate() {
|
||||||
|
return [GDTViewIOS new];
|
||||||
|
}
|
||||||
@@ -30,30 +30,8 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "core/object/class_db.h"
|
#include "drivers/apple_embedded/apple_embedded.h"
|
||||||
|
|
||||||
#import <CoreHaptics/CoreHaptics.h>
|
class iOS : public AppleEmbedded {
|
||||||
|
GDCLASS(iOS, AppleEmbedded);
|
||||||
class iOS : public Object {
|
|
||||||
GDCLASS(iOS, Object);
|
|
||||||
|
|
||||||
static void _bind_methods();
|
|
||||||
|
|
||||||
private:
|
|
||||||
CHHapticEngine *haptic_engine API_AVAILABLE(ios(13)) = nullptr;
|
|
||||||
|
|
||||||
CHHapticEngine *get_haptic_engine_instance() API_AVAILABLE(ios(13));
|
|
||||||
void start_haptic_engine();
|
|
||||||
void stop_haptic_engine();
|
|
||||||
|
|
||||||
public:
|
|
||||||
static void alert(const char *p_alert, const char *p_title);
|
|
||||||
|
|
||||||
bool supports_haptic_engine();
|
|
||||||
void vibrate_haptic_engine(float p_duration_seconds, float p_amplitude);
|
|
||||||
|
|
||||||
String get_model() const;
|
|
||||||
String get_rate_url(int p_app_id) const;
|
|
||||||
|
|
||||||
iOS();
|
|
||||||
};
|
};
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user