Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions src/common/ios.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,11 @@ namespace ios
std::string getLoveInResources(bool &fused);

/**
* Causes devices with vibration support to vibrate for about 0.5 seconds.
* Causes devices with vibration support to vibrate for the specified duration.
* On iOS 13+, uses Core Haptics for precise duration control.
* On iOS < 13, falls back to legacy 0.5 seconds of vibration.
**/
void vibrate();
void vibrate(double seconds);

/**
* Enable mix mode (e.g. with background music apps) and playback with a muted device.
Expand Down
50 changes: 49 additions & 1 deletion src/common/ios.mm
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@

#import <AudioToolbox/AudioServices.h>
#import <AVFoundation/AVFoundation.h>
#import <CoreHaptics/CoreHaptics.h>

#include "modules/audio/Audio.h"

Expand Down Expand Up @@ -364,10 +365,57 @@ - (void)applicationBecameActive:(NSNotification *)note
return path;
}

void vibrate()
void vibrate(double seconds)
{
@autoreleasepool
{
if (@available(iOS 13.0, *))
{
NSError *error = nil;
CHHapticEngine *engine = [[CHHapticEngine alloc]
initAndReturnError:&error];

if (engine != nil)
{
[engine startAndReturnError:nil];

NSDictionary *hapticDict = @{
CHHapticPatternKeyEvent: @[@{
CHHapticPatternKeyEventType:
CHHapticEventTypeHapticContinuous,
CHHapticPatternKeyTime: @0.0,
CHHapticPatternKeyEventDuration: @(seconds),
CHHapticPatternKeyEventParameters: @[
// Correlates to Android's default high intensity vibration.
@{
CHHapticPatternKeyParameterID:
CHHapticEventParameterIDHapticIntensity,
CHHapticPatternKeyParameterValue: @1.0
},
// Medium sharpness, 0.0 is dull rumble while 1.0 is crisp tap.
@{
CHHapticPatternKeyParameterID:
CHHapticEventParameterIDHapticSharpness,
CHHapticPatternKeyParameterValue: @0.5
}
]
}]
};

CHHapticPattern *pattern = [[CHHapticPattern alloc]
initWithDictionary:hapticDict error:nil];

if (pattern != nil)
{
id<CHHapticPatternPlayer> player =
[engine createPlayerWithPattern:pattern error:nil];
[player startAtTime:0 error:nil];
return;
}
}
}

// Fallback: iOS < 13 or Core Haptics unavailable.
AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/modules/system/System.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ void System::vibrate(double seconds) const
#ifdef LOVE_ANDROID
love::android::vibrate(seconds);
#elif defined(LOVE_IOS)
love::ios::vibrate();
love::ios::vibrate(seconds);
#else
LOVE_UNUSED(seconds);
#endif
Expand Down
Loading