summaryrefslogtreecommitdiff
path: root/platform/ios
diff options
context:
space:
mode:
Diffstat (limited to 'platform/ios')
-rw-r--r--platform/ios/README.md2
-rw-r--r--platform/ios/SCsub1
-rw-r--r--platform/ios/detect.py12
-rw-r--r--platform/ios/display_layer.h3
-rw-r--r--platform/ios/display_layer.mm29
-rw-r--r--platform/ios/display_server_ios.h10
-rw-r--r--platform/ios/display_server_ios.mm98
-rw-r--r--platform/ios/export/export_plugin.cpp24
-rw-r--r--platform/ios/export/export_plugin.h1
-rw-r--r--platform/ios/godot_view.mm18
-rw-r--r--platform/ios/key_mapping_ios.h46
-rw-r--r--platform/ios/key_mapping_ios.mm186
-rw-r--r--platform/ios/keyboard_input_view.mm18
-rw-r--r--platform/ios/logo.pngbin1297 -> 0 bytes
-rw-r--r--platform/ios/logo.svg1
-rw-r--r--platform/ios/view_controller.mm59
16 files changed, 421 insertions, 87 deletions
diff --git a/platform/ios/README.md b/platform/ios/README.md
index 82c275ad31..0e1d6802cb 100644
--- a/platform/ios/README.md
+++ b/platform/ios/README.md
@@ -8,7 +8,7 @@ project template used for packaging the iOS export templates.
## Documentation
-- [Compiling for iOS](https://docs.godotengine.org/en/latest/development/compiling/compiling_for_ios.html)
+- [Compiling for iOS](https://docs.godotengine.org/en/latest/contributing/development/compiling/compiling_for_ios.html)
- Instructions on building this platform port from source.
- [Exporting for iOS](https://docs.godotengine.org/en/latest/tutorials/export/exporting_for_ios.html)
- Instructions on using the compiled export templates to export a project.
diff --git a/platform/ios/SCsub b/platform/ios/SCsub
index bf12ab6dd7..f3925c146f 100644
--- a/platform/ios/SCsub
+++ b/platform/ios/SCsub
@@ -20,6 +20,7 @@ ios_lib = [
"godot_view_gesture_recognizer.mm",
"device_metrics.m",
"keyboard_input_view.mm",
+ "key_mapping_ios.mm",
]
env_ios = env.Clone()
diff --git a/platform/ios/detect.py b/platform/ios/detect.py
index 38e62134b5..71612cf1fa 100644
--- a/platform/ios/detect.py
+++ b/platform/ios/detect.py
@@ -99,8 +99,8 @@ def configure(env: "Environment"):
if env["ios_simulator"]:
detect_darwin_sdk_path("iossimulator", env)
- env.Append(ASFLAGS=["-mios-simulator-version-min=13.0"])
- env.Append(CCFLAGS=["-mios-simulator-version-min=13.0"])
+ env.Append(ASFLAGS=["-mios-simulator-version-min=11.0"])
+ env.Append(CCFLAGS=["-mios-simulator-version-min=11.0"])
env.extra_suffix = ".simulator" + env.extra_suffix
else:
detect_darwin_sdk_path("ios", env)
@@ -153,3 +153,11 @@ def configure(env: "Environment"):
if env["vulkan"]:
env.Append(CPPDEFINES=["VULKAN_ENABLED"])
+
+ if env["opengl3"]:
+ env.Append(CPPDEFINES=["GLES3_ENABLED"])
+ env.Prepend(
+ CPPPATH=[
+ "$IOS_SDK_PATH/System/Library/Frameworks/OpenGLES.framework/Headers",
+ ]
+ )
diff --git a/platform/ios/display_layer.h b/platform/ios/display_layer.h
index 10f42264df..e719a42cd9 100644
--- a/platform/ios/display_layer.h
+++ b/platform/ios/display_layer.h
@@ -33,7 +33,8 @@
@protocol DisplayLayer <NSObject>
-- (void)renderDisplayLayer;
+- (void)startRenderDisplayLayer;
+- (void)stopRenderDisplayLayer;
- (void)initializeDisplayLayer;
- (void)layoutDisplayLayer;
diff --git a/platform/ios/display_layer.mm b/platform/ios/display_layer.mm
index 24614fea56..3129ebb276 100644
--- a/platform/ios/display_layer.mm
+++ b/platform/ios/display_layer.mm
@@ -60,7 +60,10 @@
- (void)layoutDisplayLayer {
}
-- (void)renderDisplayLayer {
+- (void)startRenderDisplayLayer {
+}
+
+- (void)stopRenderDisplayLayer {
}
@end
@@ -76,8 +79,6 @@
}
- (void)initializeDisplayLayer {
- // Get our backing layer
-
// Configure it so that it is opaque, does not retain the contents of the backbuffer when displayed, and uses RGBA8888 color.
self.opaque = YES;
self.drawableProperties = [NSDictionary
@@ -87,8 +88,6 @@
kEAGLDrawablePropertyColorFormat,
nil];
- // FIXME: Add Vulkan support via MoltenVK. Add fallback code back?
-
// Create GL ES 3 context
if (GLOBAL_GET("rendering/renderer/rendering_method") == "gl_compatibility") {
context = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES3];
@@ -115,8 +114,22 @@
[self createFramebuffer];
}
-- (void)renderDisplayLayer {
+- (void)startRenderDisplayLayer {
[EAGLContext setCurrentContext:context];
+
+ glBindFramebufferOES(GL_FRAMEBUFFER_OES, viewFramebuffer);
+}
+
+- (void)stopRenderDisplayLayer {
+ glBindRenderbufferOES(GL_RENDERBUFFER_OES, viewRenderbuffer);
+ [context presentRenderbuffer:GL_RENDERBUFFER_OES];
+
+#ifdef DEBUG_ENABLED
+ GLenum err = glGetError();
+ if (err) {
+ NSLog(@"DrawView: %x error", err);
+ }
+#endif
}
- (void)dealloc {
@@ -154,11 +167,15 @@
return NO;
}
+ GLES3::TextureStorage::system_fbo = viewFramebuffer;
+
return YES;
}
// Clean up any buffers we have allocated.
- (void)destroyFramebuffer {
+ GLES3::TextureStorage::system_fbo = 0;
+
glDeleteFramebuffersOES(1, &viewFramebuffer);
viewFramebuffer = 0;
glDeleteRenderbuffersOES(1, &viewRenderbuffer);
diff --git a/platform/ios/display_server_ios.h b/platform/ios/display_server_ios.h
index dd1157f668..6eaa7c8edc 100644
--- a/platform/ios/display_server_ios.h
+++ b/platform/ios/display_server_ios.h
@@ -47,6 +47,10 @@
#endif
#endif
+#if defined(GLES3_ENABLED)
+#include "drivers/gles3/rasterizer_gles3.h"
+#endif // GLES3_ENABLED
+
#import <Foundation/Foundation.h>
#import <QuartzCore/CAMetalLayer.h>
@@ -109,11 +113,12 @@ public:
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_cancelled(int p_idx);
+ void touches_canceled(int p_idx);
// MARK: Keyboard
- void key(Key p_key, char32_t p_char, bool p_pressed);
+ void key(Key p_key, char32_t p_char, Key p_unshifted, Key p_physical, NSInteger p_modifier, bool p_pressed);
+ bool is_keyboard_active() const;
// MARK: Motion
@@ -216,6 +221,7 @@ public:
virtual bool screen_is_kept_on() const override;
void resize_window(CGSize size);
+ virtual void swap_buffers() override {}
};
#endif // DISPLAY_SERVER_IOS_H
diff --git a/platform/ios/display_server_ios.mm b/platform/ios/display_server_ios.mm
index bea88a7f9b..469bc9be17 100644
--- a/platform/ios/display_server_ios.mm
+++ b/platform/ios/display_server_ios.mm
@@ -36,6 +36,7 @@
#import "device_metrics.h"
#import "godot_view.h"
#include "ios.h"
+#import "key_mapping_ios.h"
#import "keyboard_input_view.h"
#include "os_ios.h"
#include "tts_ios.h"
@@ -50,52 +51,14 @@ DisplayServerIOS *DisplayServerIOS::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, Error &r_error) {
+ KeyMappingIOS::initialize();
+
rendering_driver = p_rendering_driver;
// Init TTS
tts = [[TTS_IOS alloc] init];
-#if defined(GLES3_ENABLED)
- // FIXME: Add support for both OpenGL and Vulkan when OpenGL is implemented
- // again,
- // Note that we should be checking "opengl3" as the driver, might never enable this seeing OpenGL is deprecated on iOS
- // We are hardcoding the rendering_driver to "vulkan" down below
-
- if (rendering_driver == "opengl3") {
- bool gl_initialization_error = false;
-
- // FIXME: Add Vulkan support via MoltenVK. Add fallback code back?
-
- if (RasterizerGLES3::is_viable() == OK) {
- RasterizerGLES3::register_config();
- RasterizerGLES3::make_current();
- } else {
- gl_initialization_error = true;
- }
-
- if (gl_initialization_error) {
- OS::get_singleton()->alert("Your device does not support any of the supported OpenGL versions.", "Unable to initialize video driver");
- // return ERR_UNAVAILABLE;
- }
-
- // rendering_server = memnew(RenderingServerDefault);
- // // FIXME: Reimplement threaded rendering
- // if (get_render_thread_mode() != RENDER_THREAD_UNSAFE) {
- // rendering_server = memnew(RenderingServerWrapMT(rendering_server,
- // false));
- // }
- // rendering_server->init();
- // rendering_server->cursor_set_visible(false, 0);
-
- // reset this to what it should be, it will have been set to 0 after
- // rendering_server->init() is called
- // RasterizerStorageGLES3system_fbo = gl_view_base_fb;
- }
-#endif
-
#if defined(VULKAN_ENABLED)
- rendering_driver = "vulkan";
-
context_vulkan = nullptr;
rendering_device_vulkan = nullptr;
@@ -110,13 +73,14 @@ DisplayServerIOS::DisplayServerIOS(const String &p_rendering_driver, WindowMode
CALayer *layer = [AppDelegate.viewController.godotView initializeRenderingForDriver:@"vulkan"];
if (!layer) {
- ERR_FAIL_MSG("Failed to create iOS rendering layer.");
+ ERR_FAIL_MSG("Failed to create iOS Vulkan rendering layer.");
}
Size2i size = Size2i(layer.bounds.size.width, layer.bounds.size.height) * screen_get_max_scale();
if (context_vulkan->window_create(MAIN_WINDOW_ID, p_vsync_mode, layer, size.width, size.height) != OK) {
memdelete(context_vulkan);
context_vulkan = nullptr;
+ r_error = ERR_UNAVAILABLE;
ERR_FAIL_MSG("Failed to create Vulkan window.");
}
@@ -127,6 +91,18 @@ DisplayServerIOS::DisplayServerIOS(const String &p_rendering_driver, WindowMode
}
#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();
+ }
+#endif
+
bool keep_screen_on = bool(GLOBAL_GET("display/window/energy_saving/keep_screen_on"));
screen_set_keep_on(keep_screen_on);
@@ -252,20 +228,35 @@ void DisplayServerIOS::perform_event(const Ref<InputEvent> &p_event) {
Input::get_singleton()->parse_input_event(p_event);
}
-void DisplayServerIOS::touches_cancelled(int p_idx) {
+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, bool p_pressed) {
+void DisplayServerIOS::key(Key p_key, char32_t p_char, Key p_unshifted, Key p_physical, NSInteger p_modifier, bool p_pressed) {
Ref<InputEventKey> ev;
ev.instantiate();
ev->set_echo(false);
ev->set_pressed(p_pressed);
- ev->set_keycode(p_key);
- ev->set_physical_keycode(p_key);
- ev->set_unicode(p_char);
+ 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));
perform_event(ev);
}
@@ -643,6 +634,10 @@ void DisplayServerIOS::virtual_keyboard_show(const String &p_existing_text, cons
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];
}
@@ -689,15 +684,18 @@ void DisplayServerIOS::resize_window(CGSize viewSize) {
void DisplayServerIOS::window_set_vsync_mode(DisplayServer::VSyncMode p_vsync_mode, WindowID p_window) {
_THREAD_SAFE_METHOD_
#if defined(VULKAN_ENABLED)
- context_vulkan->set_vsync_mode(p_window, p_vsync_mode);
+ if (context_vulkan) {
+ context_vulkan->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(VULKAN_ENABLED)
- return context_vulkan->get_vsync_mode(p_window);
-#else
- return DisplayServer::VSYNC_ENABLED;
+ if (context_vulkan) {
+ return context_vulkan->get_vsync_mode(p_window);
+ }
#endif
+ return DisplayServer::VSYNC_ENABLED;
}
diff --git a/platform/ios/export/export_plugin.cpp b/platform/ios/export/export_plugin.cpp
index 43eb0f4b1f..c6f7ec09b1 100644
--- a/platform/ios/export/export_plugin.cpp
+++ b/platform/ios/export/export_plugin.cpp
@@ -32,10 +32,18 @@
#include "core/string/translation.h"
#include "editor/editor_node.h"
+#include "editor/editor_scale.h"
+#include "platform/ios/logo_svg.gen.h"
+
+#include "modules/modules_enabled.gen.h" // For svg.
+#ifdef MODULE_SVG_ENABLED
+#include "modules/svg/image_loader_svg.h"
+#endif
void EditorExportPlatformIOS::get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features) const {
// Vulkan and OpenGL ES 3.0 both mandate ETC2 support.
r_features->push_back("etc2");
+ r_features->push_back("astc");
Vector<String> architectures = _get_preset_architectures(p_preset);
for (int i = 0; i < architectures.size(); ++i) {
@@ -1565,7 +1573,7 @@ Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_p
int ret = unzGoToFirstFile(src_pkg_zip);
Vector<uint8_t> project_file_data;
while (ret == UNZ_OK) {
-#if defined(MACOS_ENABLED) || defined(X11_ENABLED)
+#if defined(MACOS_ENABLED) || defined(LINUXBSD_ENABLED)
bool is_execute = false;
#endif
@@ -1598,7 +1606,7 @@ Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_p
continue; //ignore!
}
found_library = true;
-#if defined(MACOS_ENABLED) || defined(X11_ENABLED)
+#if defined(MACOS_ENABLED) || defined(LINUXBSD_ENABLED)
is_execute = true;
#endif
file = file.replace(library_to_use, binary_name + ".xcframework");
@@ -1641,7 +1649,7 @@ Error EditorExportPlatformIOS::export_project(const Ref<EditorExportPreset> &p_p
f->store_buffer(data.ptr(), data.size());
}
-#if defined(MACOS_ENABLED) || defined(X11_ENABLED)
+#if defined(MACOS_ENABLED) || defined(LINUXBSD_ENABLED)
if (is_execute) {
// we need execute rights on this file
chmod(file.utf8().get_data(), 0755);
@@ -1926,7 +1934,15 @@ bool EditorExportPlatformIOS::has_valid_project_configuration(const Ref<EditorEx
}
EditorExportPlatformIOS::EditorExportPlatformIOS() {
- logo = ImageTexture::create_from_image(memnew(Image(_ios_logo)));
+#ifdef MODULE_SVG_ENABLED
+ Ref<Image> img = memnew(Image);
+ const bool upsample = !Math::is_equal_approx(Math::round(EDSCALE), EDSCALE);
+
+ ImageLoaderSVG img_loader;
+ img_loader.create_image_from_string(img, _ios_logo_svg, EDSCALE, upsample, false);
+ logo = ImageTexture::create_from_image(img);
+#endif
+
plugins_changed.set();
#ifndef ANDROID_ENABLED
check_for_changes_thread.start(_check_for_changes_poll_thread, this);
diff --git a/platform/ios/export/export_plugin.h b/platform/ios/export/export_plugin.h
index deadec4b43..628dae2e6f 100644
--- a/platform/ios/export/export_plugin.h
+++ b/platform/ios/export/export_plugin.h
@@ -43,7 +43,6 @@
#include "editor/editor_settings.h"
#include "editor/export/editor_export_platform.h"
#include "main/splash.gen.h"
-#include "platform/ios/logo.gen.h"
#include "string.h"
#include "godot_plugin_config.h"
diff --git a/platform/ios/godot_view.mm b/platform/ios/godot_view.mm
index 1c8c578bd2..4b10f95ab8 100644
--- a/platform/ios/godot_view.mm
+++ b/platform/ios/godot_view.mm
@@ -74,16 +74,20 @@ static const float earth_gravity = 9.80665;
CALayer<DisplayLayer> *layer;
if ([driverName isEqualToString:@"vulkan"]) {
+#if defined(TARGET_OS_SIMULATOR) && TARGET_OS_SIMULATOR
+ if (@available(iOS 13, *)) {
+ layer = [GodotMetalLayer layer];
+ } else {
+ return nil;
+ }
+#else
layer = [GodotMetalLayer layer];
+#endif
} else if ([driverName isEqualToString:@"opengl3"]) {
if (@available(iOS 13, *)) {
NSLog(@"OpenGL ES is deprecated on iOS 13");
}
-#if defined(TARGET_OS_SIMULATOR) && TARGET_OS_SIMULATOR
- return nil;
-#else
layer = [GodotOpenGLLayer layer];
-#endif
} else {
return nil;
}
@@ -238,7 +242,7 @@ static const float earth_gravity = 9.80665;
[self.displayLink setPaused:NO];
}
- [self.renderingLayer renderDisplayLayer];
+ [self.renderingLayer startRenderDisplayLayer];
if (!self.renderer) {
return;
@@ -258,6 +262,8 @@ static const float earth_gravity = 9.80665;
[self handleMotion];
[self.renderer renderOnView:self];
+
+ [self.renderingLayer stopRenderDisplayLayer];
}
- (BOOL)canRender {
@@ -391,7 +397,7 @@ static const float earth_gravity = 9.80665;
UITouch *touch = [tlist objectAtIndex:i];
int tid = [self getTouchIDForTouch:touch];
ERR_FAIL_COND(tid == -1);
- DisplayServerIOS::get_singleton()->touches_cancelled(tid);
+ DisplayServerIOS::get_singleton()->touches_canceled(tid);
}
}
[self clearTouches];
diff --git a/platform/ios/key_mapping_ios.h b/platform/ios/key_mapping_ios.h
new file mode 100644
index 0000000000..6cc61175bb
--- /dev/null
+++ b/platform/ios/key_mapping_ios.h
@@ -0,0 +1,46 @@
+/**************************************************************************/
+/* key_mapping_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. */
+/**************************************************************************/
+
+#ifndef KEY_MAPPING_IOS_H
+#define KEY_MAPPING_IOS_H
+
+#include "core/os/keyboard.h"
+
+#import <UIKit/UIKit.h>
+
+class KeyMappingIOS {
+ KeyMappingIOS() {}
+
+public:
+ static void initialize();
+ static Key remap_key(CFIndex p_keycode);
+};
+
+#endif // KEY_MAPPING_IOS_H
diff --git a/platform/ios/key_mapping_ios.mm b/platform/ios/key_mapping_ios.mm
new file mode 100644
index 0000000000..c378186778
--- /dev/null
+++ b/platform/ios/key_mapping_ios.mm
@@ -0,0 +1,186 @@
+/**************************************************************************/
+/* key_mapping_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. */
+/**************************************************************************/
+
+#include "key_mapping_ios.h"
+
+#include "core/templates/hash_map.h"
+
+struct HashMapHasherKeys {
+ static _FORCE_INLINE_ uint32_t hash(const Key p_key) { return hash_fmix32(static_cast<uint32_t>(p_key)); }
+ static _FORCE_INLINE_ uint32_t hash(const CFIndex p_key) { return hash_fmix32(p_key); }
+};
+
+HashMap<CFIndex, Key, HashMapHasherKeys> keyusage_map;
+
+void KeyMappingIOS::initialize() {
+ if (@available(iOS 13.4, *)) {
+ keyusage_map[UIKeyboardHIDUsageKeyboardA] = Key::A;
+ keyusage_map[UIKeyboardHIDUsageKeyboardB] = Key::B;
+ keyusage_map[UIKeyboardHIDUsageKeyboardC] = Key::C;
+ keyusage_map[UIKeyboardHIDUsageKeyboardD] = Key::D;
+ keyusage_map[UIKeyboardHIDUsageKeyboardE] = Key::E;
+ keyusage_map[UIKeyboardHIDUsageKeyboardF] = Key::F;
+ keyusage_map[UIKeyboardHIDUsageKeyboardG] = Key::G;
+ keyusage_map[UIKeyboardHIDUsageKeyboardH] = Key::H;
+ keyusage_map[UIKeyboardHIDUsageKeyboardI] = Key::I;
+ keyusage_map[UIKeyboardHIDUsageKeyboardJ] = Key::J;
+ keyusage_map[UIKeyboardHIDUsageKeyboardK] = Key::K;
+ keyusage_map[UIKeyboardHIDUsageKeyboardL] = Key::L;
+ keyusage_map[UIKeyboardHIDUsageKeyboardM] = Key::M;
+ keyusage_map[UIKeyboardHIDUsageKeyboardN] = Key::N;
+ keyusage_map[UIKeyboardHIDUsageKeyboardO] = Key::O;
+ keyusage_map[UIKeyboardHIDUsageKeyboardP] = Key::P;
+ keyusage_map[UIKeyboardHIDUsageKeyboardQ] = Key::Q;
+ keyusage_map[UIKeyboardHIDUsageKeyboardR] = Key::R;
+ keyusage_map[UIKeyboardHIDUsageKeyboardS] = Key::S;
+ keyusage_map[UIKeyboardHIDUsageKeyboardT] = Key::T;
+ keyusage_map[UIKeyboardHIDUsageKeyboardU] = Key::U;
+ keyusage_map[UIKeyboardHIDUsageKeyboardV] = Key::V;
+ keyusage_map[UIKeyboardHIDUsageKeyboardW] = Key::W;
+ keyusage_map[UIKeyboardHIDUsageKeyboardX] = Key::X;
+ keyusage_map[UIKeyboardHIDUsageKeyboardY] = Key::Y;
+ keyusage_map[UIKeyboardHIDUsageKeyboardZ] = Key::Z;
+ keyusage_map[UIKeyboardHIDUsageKeyboard0] = Key::KEY_0;
+ keyusage_map[UIKeyboardHIDUsageKeyboard1] = Key::KEY_1;
+ keyusage_map[UIKeyboardHIDUsageKeyboard2] = Key::KEY_2;
+ keyusage_map[UIKeyboardHIDUsageKeyboard3] = Key::KEY_3;
+ keyusage_map[UIKeyboardHIDUsageKeyboard4] = Key::KEY_4;
+ keyusage_map[UIKeyboardHIDUsageKeyboard5] = Key::KEY_5;
+ keyusage_map[UIKeyboardHIDUsageKeyboard6] = Key::KEY_6;
+ keyusage_map[UIKeyboardHIDUsageKeyboard7] = Key::KEY_7;
+ keyusage_map[UIKeyboardHIDUsageKeyboard8] = Key::KEY_8;
+ keyusage_map[UIKeyboardHIDUsageKeyboard9] = Key::KEY_9;
+ keyusage_map[UIKeyboardHIDUsageKeyboardBackslash] = Key::BACKSLASH;
+ keyusage_map[UIKeyboardHIDUsageKeyboardCloseBracket] = Key::BRACKETRIGHT;
+ keyusage_map[UIKeyboardHIDUsageKeyboardComma] = Key::COMMA;
+ keyusage_map[UIKeyboardHIDUsageKeyboardEqualSign] = Key::EQUAL;
+ keyusage_map[UIKeyboardHIDUsageKeyboardHyphen] = Key::MINUS;
+ keyusage_map[UIKeyboardHIDUsageKeyboardNonUSBackslash] = Key::SECTION;
+ keyusage_map[UIKeyboardHIDUsageKeyboardNonUSPound] = Key::ASCIITILDE;
+ keyusage_map[UIKeyboardHIDUsageKeyboardOpenBracket] = Key::BRACKETLEFT;
+ keyusage_map[UIKeyboardHIDUsageKeyboardPeriod] = Key::PERIOD;
+ keyusage_map[UIKeyboardHIDUsageKeyboardQuote] = Key::QUOTEDBL;
+ keyusage_map[UIKeyboardHIDUsageKeyboardSemicolon] = Key::SEMICOLON;
+ keyusage_map[UIKeyboardHIDUsageKeyboardSeparator] = Key::SECTION;
+ keyusage_map[UIKeyboardHIDUsageKeyboardSlash] = Key::SLASH;
+ keyusage_map[UIKeyboardHIDUsageKeyboardSpacebar] = Key::SPACE;
+ keyusage_map[UIKeyboardHIDUsageKeyboardCapsLock] = Key::CAPSLOCK;
+ keyusage_map[UIKeyboardHIDUsageKeyboardLeftAlt] = Key::ALT;
+ keyusage_map[UIKeyboardHIDUsageKeyboardLeftControl] = Key::CTRL;
+ keyusage_map[UIKeyboardHIDUsageKeyboardLeftShift] = Key::SHIFT;
+ keyusage_map[UIKeyboardHIDUsageKeyboardRightAlt] = Key::ALT;
+ keyusage_map[UIKeyboardHIDUsageKeyboardRightControl] = Key::CTRL;
+ keyusage_map[UIKeyboardHIDUsageKeyboardRightShift] = Key::SHIFT;
+ keyusage_map[UIKeyboardHIDUsageKeyboardScrollLock] = Key::SCROLLLOCK;
+ keyusage_map[UIKeyboardHIDUsageKeyboardLeftArrow] = Key::LEFT;
+ keyusage_map[UIKeyboardHIDUsageKeyboardRightArrow] = Key::RIGHT;
+ keyusage_map[UIKeyboardHIDUsageKeyboardUpArrow] = Key::UP;
+ keyusage_map[UIKeyboardHIDUsageKeyboardDownArrow] = Key::DOWN;
+ keyusage_map[UIKeyboardHIDUsageKeyboardPageUp] = Key::PAGEUP;
+ keyusage_map[UIKeyboardHIDUsageKeyboardPageDown] = Key::PAGEDOWN;
+ keyusage_map[UIKeyboardHIDUsageKeyboardHome] = Key::HOME;
+ keyusage_map[UIKeyboardHIDUsageKeyboardEnd] = Key::END;
+ keyusage_map[UIKeyboardHIDUsageKeyboardDeleteForward] = Key::KEY_DELETE;
+ keyusage_map[UIKeyboardHIDUsageKeyboardDeleteOrBackspace] = Key::BACKSPACE;
+ keyusage_map[UIKeyboardHIDUsageKeyboardEscape] = Key::ESCAPE;
+ keyusage_map[UIKeyboardHIDUsageKeyboardInsert] = Key::INSERT;
+ keyusage_map[UIKeyboardHIDUsageKeyboardReturn] = Key::ENTER;
+ keyusage_map[UIKeyboardHIDUsageKeyboardTab] = Key::TAB;
+ keyusage_map[UIKeyboardHIDUsageKeyboardF1] = Key::F1;
+ keyusage_map[UIKeyboardHIDUsageKeyboardF2] = Key::F2;
+ keyusage_map[UIKeyboardHIDUsageKeyboardF3] = Key::F3;
+ keyusage_map[UIKeyboardHIDUsageKeyboardF4] = Key::F4;
+ keyusage_map[UIKeyboardHIDUsageKeyboardF5] = Key::F5;
+ keyusage_map[UIKeyboardHIDUsageKeyboardF6] = Key::F6;
+ keyusage_map[UIKeyboardHIDUsageKeyboardF7] = Key::F7;
+ keyusage_map[UIKeyboardHIDUsageKeyboardF8] = Key::F8;
+ keyusage_map[UIKeyboardHIDUsageKeyboardF9] = Key::F9;
+ keyusage_map[UIKeyboardHIDUsageKeyboardF10] = Key::F10;
+ keyusage_map[UIKeyboardHIDUsageKeyboardF11] = Key::F11;
+ keyusage_map[UIKeyboardHIDUsageKeyboardF12] = Key::F12;
+ keyusage_map[UIKeyboardHIDUsageKeyboardF13] = Key::F13;
+ keyusage_map[UIKeyboardHIDUsageKeyboardF14] = Key::F14;
+ keyusage_map[UIKeyboardHIDUsageKeyboardF15] = Key::F15;
+ keyusage_map[UIKeyboardHIDUsageKeyboardF16] = Key::F16;
+ keyusage_map[UIKeyboardHIDUsageKeyboardF17] = Key::F17;
+ keyusage_map[UIKeyboardHIDUsageKeyboardF18] = Key::F18;
+ keyusage_map[UIKeyboardHIDUsageKeyboardF19] = Key::F19;
+ keyusage_map[UIKeyboardHIDUsageKeyboardF20] = Key::F20;
+ keyusage_map[UIKeyboardHIDUsageKeyboardF21] = Key::F21;
+ keyusage_map[UIKeyboardHIDUsageKeyboardF22] = Key::F22;
+ keyusage_map[UIKeyboardHIDUsageKeyboardF23] = Key::F23;
+ keyusage_map[UIKeyboardHIDUsageKeyboardF24] = Key::F24;
+ keyusage_map[UIKeyboardHIDUsageKeypad0] = Key::KP_0;
+ keyusage_map[UIKeyboardHIDUsageKeypad1] = Key::KP_1;
+ keyusage_map[UIKeyboardHIDUsageKeypad2] = Key::KP_2;
+ keyusage_map[UIKeyboardHIDUsageKeypad3] = Key::KP_3;
+ keyusage_map[UIKeyboardHIDUsageKeypad4] = Key::KP_4;
+ keyusage_map[UIKeyboardHIDUsageKeypad5] = Key::KP_5;
+ keyusage_map[UIKeyboardHIDUsageKeypad6] = Key::KP_6;
+ keyusage_map[UIKeyboardHIDUsageKeypad7] = Key::KP_7;
+ keyusage_map[UIKeyboardHIDUsageKeypad8] = Key::KP_8;
+ keyusage_map[UIKeyboardHIDUsageKeypad9] = Key::KP_9;
+ keyusage_map[UIKeyboardHIDUsageKeypadAsterisk] = Key::KP_MULTIPLY;
+ keyusage_map[UIKeyboardHIDUsageKeyboardGraveAccentAndTilde] = Key::BAR;
+ keyusage_map[UIKeyboardHIDUsageKeypadEnter] = Key::KP_ENTER;
+ keyusage_map[UIKeyboardHIDUsageKeypadHyphen] = Key::KP_SUBTRACT;
+ keyusage_map[UIKeyboardHIDUsageKeypadNumLock] = Key::NUMLOCK;
+ keyusage_map[UIKeyboardHIDUsageKeypadPeriod] = Key::KP_PERIOD;
+ keyusage_map[UIKeyboardHIDUsageKeypadPlus] = Key::KP_ADD;
+ keyusage_map[UIKeyboardHIDUsageKeypadSlash] = Key::KP_DIVIDE;
+ keyusage_map[UIKeyboardHIDUsageKeyboardPause] = Key::PAUSE;
+ keyusage_map[UIKeyboardHIDUsageKeyboardStop] = Key::STOP;
+ keyusage_map[UIKeyboardHIDUsageKeyboardMute] = Key::VOLUMEMUTE;
+ keyusage_map[UIKeyboardHIDUsageKeyboardVolumeUp] = Key::VOLUMEUP;
+ keyusage_map[UIKeyboardHIDUsageKeyboardVolumeDown] = Key::VOLUMEDOWN;
+ keyusage_map[UIKeyboardHIDUsageKeyboardFind] = Key::SEARCH;
+ keyusage_map[UIKeyboardHIDUsageKeyboardHelp] = Key::HELP;
+ keyusage_map[UIKeyboardHIDUsageKeyboardLeftGUI] = Key::META;
+ keyusage_map[UIKeyboardHIDUsageKeyboardRightGUI] = Key::META;
+ keyusage_map[UIKeyboardHIDUsageKeyboardMenu] = Key::MENU;
+ keyusage_map[UIKeyboardHIDUsageKeyboardPrintScreen] = Key::PRINT;
+ keyusage_map[UIKeyboardHIDUsageKeyboardReturnOrEnter] = Key::ENTER;
+ keyusage_map[UIKeyboardHIDUsageKeyboardSysReqOrAttention] = Key::SYSREQ;
+ keyusage_map[0x01AE] = Key::KEYBOARD; // On-screen keyboard key on smart connector keyboard.
+ keyusage_map[0x029D] = Key::GLOBE; // "Globe" key on smart connector / Mac keyboard.
+ keyusage_map[UIKeyboardHIDUsageKeyboardLANG1] = Key::JIS_EISU;
+ keyusage_map[UIKeyboardHIDUsageKeyboardLANG2] = Key::JIS_KANA;
+ }
+}
+
+Key KeyMappingIOS::remap_key(CFIndex p_keycode) {
+ if (@available(iOS 13.4, *)) {
+ const Key *key = keyusage_map.getptr(p_keycode);
+ if (key) {
+ return *key;
+ }
+ }
+ return Key::NONE;
+}
diff --git a/platform/ios/keyboard_input_view.mm b/platform/ios/keyboard_input_view.mm
index f40db48ee3..2764403d68 100644
--- a/platform/ios/keyboard_input_view.mm
+++ b/platform/ios/keyboard_input_view.mm
@@ -115,8 +115,8 @@
- (void)deleteText:(NSInteger)charactersToDelete {
for (int i = 0; i < charactersToDelete; i++) {
- DisplayServerIOS::get_singleton()->key(Key::BACKSPACE, 0, true);
- DisplayServerIOS::get_singleton()->key(Key::BACKSPACE, 0, false);
+ DisplayServerIOS::get_singleton()->key(Key::BACKSPACE, 0, Key::BACKSPACE, Key::NONE, 0, true);
+ DisplayServerIOS::get_singleton()->key(Key::BACKSPACE, 0, Key::BACKSPACE, Key::NONE, 0, false);
}
}
@@ -134,20 +134,10 @@
key = Key::ENTER;
} else if (character == 0x2006) {
key = Key::SPACE;
- } else if (character == U'¥') {
- key = Key::YEN;
- } else if (character == U'§') {
- key = Key::SECTION;
- } else if (character >= 0x20 && character <= 0x7E) { // ASCII.
- if (character > 0x60 && character < 0x7B) { // Lowercase ASCII.
- key = (Key)(character - 32);
- } else {
- key = (Key)character;
- }
}
- DisplayServerIOS::get_singleton()->key(key, character, true);
- DisplayServerIOS::get_singleton()->key(key, character, false);
+ DisplayServerIOS::get_singleton()->key(key, character, key, Key::NONE, 0, true);
+ DisplayServerIOS::get_singleton()->key(key, character, key, Key::NONE, 0, false);
}
}
diff --git a/platform/ios/logo.png b/platform/ios/logo.png
deleted file mode 100644
index 966d8aa70a..0000000000
--- a/platform/ios/logo.png
+++ /dev/null
Binary files differ
diff --git a/platform/ios/logo.svg b/platform/ios/logo.svg
new file mode 100644
index 0000000000..47a72bcf49
--- /dev/null
+++ b/platform/ios/logo.svg
@@ -0,0 +1 @@
+<svg height="32" width="32" xmlns="http://www.w3.org/2000/svg"><path d="M1 23.27h2.504V12.61H1zm1.247-12.057c.784 0 1.398-.603 1.398-1.358 0-.764-.614-1.367-1.398-1.367-.774 0-1.388.603-1.388 1.367 0 .755.614 1.358 1.388 1.358zm9.594-2.695c-4.233 0-6.888 2.886-6.888 7.502s2.654 7.492 6.888 7.492c4.224 0 6.88-2.876 6.88-7.492s-2.656-7.502-6.88-7.502zm0 2.212c2.585 0 4.234 2.052 4.234 5.29 0 3.228-1.649 5.28-4.234 5.28-2.594 0-4.233-2.052-4.233-5.28 0-3.238 1.639-5.29 4.233-5.29zm7.936 8.458c.11 2.675 2.303 4.324 5.641 4.324 3.51 0 5.723-1.73 5.723-4.485 0-2.162-1.247-3.379-4.194-4.053l-1.67-.382c-1.78-.422-2.513-.985-2.513-1.95 0-1.208 1.106-2.012 2.745-2.012 1.66 0 2.796.814 2.916 2.172H30.9c-.06-2.554-2.172-4.284-5.37-4.284-3.158 0-5.4 1.74-5.4 4.314 0 2.072 1.267 3.36 3.942 3.973l1.88.442c1.83.433 2.575 1.036 2.575 2.082 0 1.207-1.217 2.072-2.967 2.072-1.77 0-3.107-.875-3.268-2.213h-2.514z" fill="#bfbfbf"/></svg>
diff --git a/platform/ios/view_controller.mm b/platform/ios/view_controller.mm
index b787ed6709..a5aba201d7 100644
--- a/platform/ios/view_controller.mm
+++ b/platform/ios/view_controller.mm
@@ -33,6 +33,7 @@
#include "display_server_ios.h"
#import "godot_view.h"
#import "godot_view_renderer.h"
+#import "key_mapping_ios.h"
#import "keyboard_input_view.h"
#include "os_ios.h"
@@ -54,6 +55,64 @@
return (GodotView *)self.view;
}
+- (void)pressesBegan:(NSSet<UIPress *> *)presses withEvent:(UIPressesEvent *)event {
+ [super pressesBegan:presses withEvent:event];
+
+ if (!DisplayServerIOS::get_singleton() || DisplayServerIOS::get_singleton()->is_keyboard_active()) {
+ return;
+ }
+ if (@available(iOS 13.4, *)) {
+ for (UIPress *press in presses) {
+ String u32lbl = String::utf8([press.key.charactersIgnoringModifiers UTF8String]);
+ String u32text = String::utf8([press.key.characters UTF8String]);
+ Key key = KeyMappingIOS::remap_key(press.key.keyCode);
+
+ if (press.key.keyCode == 0 && u32text.is_empty() && u32lbl.is_empty()) {
+ continue;
+ }
+
+ char32_t us = 0;
+ if (!u32lbl.is_empty() && !u32lbl.begins_with("UIKey")) {
+ us = u32lbl[0];
+ }
+
+ if (!u32text.is_empty() && !u32text.begins_with("UIKey")) {
+ for (int i = 0; i < u32text.length(); 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);
+ }
+ } else {
+ DisplayServerIOS::get_singleton()->key(fix_keycode(us, key), 0, fix_key_label(us, key), key, press.key.modifierFlags, true);
+ }
+ }
+ }
+}
+
+- (void)pressesEnded:(NSSet<UIPress *> *)presses withEvent:(UIPressesEvent *)event {
+ [super pressesEnded:presses withEvent:event];
+
+ if (!DisplayServerIOS::get_singleton() || DisplayServerIOS::get_singleton()->is_keyboard_active()) {
+ return;
+ }
+ if (@available(iOS 13.4, *)) {
+ for (UIPress *press in presses) {
+ String u32lbl = String::utf8([press.key.charactersIgnoringModifiers UTF8String]);
+ Key key = KeyMappingIOS::remap_key(press.key.keyCode);
+
+ if (press.key.keyCode == 0 && u32lbl.is_empty()) {
+ continue;
+ }
+
+ char32_t us = 0;
+ if (!u32lbl.is_empty() && !u32lbl.begins_with("UIKey")) {
+ us = u32lbl[0];
+ }
+
+ DisplayServerIOS::get_singleton()->key(fix_keycode(us, key), 0, fix_key_label(us, key), key, press.key.modifierFlags, false);
+ }
+ }
+}
+
- (void)loadView {
GodotView *view = [[GodotView alloc] init];
GodotViewRenderer *renderer = [[GodotViewRenderer alloc] init];