diff --git a/SConstruct b/SConstruct index c943b12..09792b9 100644 --- a/SConstruct +++ b/SConstruct @@ -24,7 +24,7 @@ opts.Add(EnumVariable('arch', "Compilation Architecture", '', ['', 'arm64', 'arm opts.Add(BoolVariable('simulator', "Compilation platform", 'no')) opts.Add(BoolVariable('use_llvm', "Use the LLVM / Clang compiler", 'no')) opts.Add(PathVariable('target_path', 'The path where the lib is installed.', 'bin/')) -opts.Add(EnumVariable('plugin', 'Plugin to build', '', ['', 'apn', 'arkit', 'camera', 'icloud', 'gamecenter', 'inappstore', 'photo_picker'])) +opts.Add(EnumVariable('plugin', 'Plugin to build', '', ['', 'apn', 'arkit', 'camera', 'icloud', 'gamecenter', 'haptic_engine', 'inappstore', 'photo_picker'])) opts.Add(EnumVariable('version', 'Godot version to target', '', ['', '3.x', '4.0'])) # Updates the environment with the option variables. diff --git a/plugins/haptic_engine/haptic_engine.gdip b/plugins/haptic_engine/haptic_engine.gdip new file mode 100644 index 0000000..718b989 --- /dev/null +++ b/plugins/haptic_engine/haptic_engine.gdip @@ -0,0 +1,17 @@ +[config] +name="HapticEngine" +binary="haptic_engine.xcframework" + +initialization="haptic_engine_init" +deinitialization="haptic_engine_deinit" + +[dependencies] +linked=[] +embedded=[] +system=[] + +capabilities=[] + +files=[] + +[plist] diff --git a/plugins/haptic_engine/haptic_engine.h b/plugins/haptic_engine/haptic_engine.h new file mode 100644 index 0000000..a02a576 --- /dev/null +++ b/plugins/haptic_engine/haptic_engine.h @@ -0,0 +1,62 @@ +/*************************************************************************/ +/* haptic_engine.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#ifndef HAPTIC_ENGINE_H +#define HAPTIC_ENGINE_H + +#include "core/version.h" + +#if VERSION_MAJOR == 4 +#include "core/object/class_db.h" +#else +#include "core/object.h" +#endif + +#import + +class HapticEngine : public Object { + GDCLASS(HapticEngine, Object); + + static HapticEngine *instance; + static void _bind_methods(); + +private: + CHHapticEngine *haptic_engine API_AVAILABLE(ios(13)) = nullptr; + +public: + void vibrate(int duration_ms, float intensity, float sharpness); + + static HapticEngine *get_singleton(); + + HapticEngine(); + ~HapticEngine(); +}; + +#endif diff --git a/plugins/haptic_engine/haptic_engine.mm b/plugins/haptic_engine/haptic_engine.mm new file mode 100644 index 0000000..68d0d09 --- /dev/null +++ b/plugins/haptic_engine/haptic_engine.mm @@ -0,0 +1,126 @@ +/*************************************************************************/ +/* haptic_engine.mm */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "haptic_engine.h" + +#if VERSION_MAJOR == 4 +#import "platform/ios/app_delegate.h" +#else +#import "platform/iphone/app_delegate.h" +#endif + +#import + +HapticEngine *HapticEngine::instance = NULL; + +void HapticEngine::_bind_methods() { + ClassDB::bind_method(D_METHOD("vibrate"), &HapticEngine::vibrate); +}; + +void HapticEngine::vibrate(int duration_ms, float intensity, float sharpness) API_AVAILABLE(ios(13)) { + if (haptic_engine == nullptr) { + NSLog(@"Haptic engine not available"); + return; + } + + NSDictionary *hapticDict = @{ + CHHapticPatternKeyPattern : @[ + @{CHHapticPatternKeyEvent : @{ + CHHapticPatternKeyEventType : CHHapticEventTypeHapticContinuous, + CHHapticPatternKeyTime : @(CHHapticTimeImmediate), + CHHapticPatternKeyEventDuration : @((float)duration_ms / 1000.f), + CHHapticPatternKeyEventParameters : @[ + @{ + CHHapticPatternKeyParameterID : CHHapticEventParameterIDHapticIntensity, + CHHapticPatternKeyParameterValue : @(intensity) + }, + @{ + CHHapticPatternKeyParameterID : CHHapticEventParameterIDHapticSharpness, + CHHapticPatternKeyParameterValue : @(sharpness) + } + ] + }, + }, + ], + }; + + NSError *error; + CHHapticPattern *pattern = [[CHHapticPattern alloc] initWithDictionary:hapticDict error:&error]; + if (error) { + NSLog(@"Could not initialize haptic pattern: %@", error); + return; + } + + [[haptic_engine createPlayerWithPattern:pattern error:&error] startAtTime:0 error:&error]; + if (error) { + NSLog(@"Could not play haptic pattern: %@", error); + return; + } +} + +HapticEngine *HapticEngine::get_singleton() { + return instance; +} + +HapticEngine::HapticEngine() { + ERR_FAIL_COND(instance != NULL); + instance = this; + + if (@available(iOS 13, *)) { + id capabilities = [CHHapticEngine capabilitiesForHardware]; + if (!capabilities.supportsHaptics) { + NSLog(@"Hardware does not support haptics"); + return; + } + + NSError *error = nullptr; + haptic_engine = [[CHHapticEngine alloc] initAndReturnError:&error]; + if (error) { + haptic_engine = nullptr; + NSLog(@"Could not initialize haptic engine: %@", error); + } + + [haptic_engine setAutoShutdownEnabled:true]; + } else { + NSLog(@"Haptic engine requires iOS 13 or older"); + } +}; + +HapticEngine::~HapticEngine() { + if (@available(iOS 13, *)) { + if (haptic_engine) { + [haptic_engine stopWithCompletionHandler:^(NSError *error) { + if (error) { + NSLog(@"Could not stop haptic engine: %@", error); + } + }]; + } + } +} diff --git a/plugins/haptic_engine/haptic_engine_module.h b/plugins/haptic_engine/haptic_engine_module.h new file mode 100644 index 0000000..26dd8d2 --- /dev/null +++ b/plugins/haptic_engine/haptic_engine_module.h @@ -0,0 +1,32 @@ +/*************************************************************************/ +/* game_center_delegate.h */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +void haptic_engine_init(); +void haptic_engine_deinit(); diff --git a/plugins/haptic_engine/haptic_engine_module.mm b/plugins/haptic_engine/haptic_engine_module.mm new file mode 100644 index 0000000..fb448b8 --- /dev/null +++ b/plugins/haptic_engine/haptic_engine_module.mm @@ -0,0 +1,54 @@ +/*************************************************************************/ +/* haptic_engine_module.mm */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +#include "haptic_engine_module.h" + +#include "core/version.h" + +#if VERSION_MAJOR == 4 +#include "core/config/engine.h" +#else +#include "core/engine.h" +#endif + +#include "haptic_engine.h" + +HapticEngine *haptic_engine; + +void haptic_engine_init() { + haptic_engine = memnew(HapticEngine); + Engine::get_singleton()->add_singleton(Engine::Singleton("HapticEngine", haptic_engine)); +} + +void haptic_engine_deinit() { + if (haptic_engine) { + memdelete(haptic_engine); + } +}