Update the existing haptic player when we rumble on iOS

This commit is contained in:
Sam Lantinga 2020-10-15 10:13:42 -07:00
parent 645a3280ec
commit d9aea0c3a0

View File

@ -827,6 +827,7 @@ IOS_MFIJoystickUpdate(SDL_Joystick * joystick)
@implementation SDL_RumbleMotor { @implementation SDL_RumbleMotor {
CHHapticEngine *engine API_AVAILABLE(ios(13.0), tvos(14.0)); CHHapticEngine *engine API_AVAILABLE(ios(13.0), tvos(14.0));
id<CHHapticPatternPlayer> player API_AVAILABLE(ios(13.0), tvos(14.0)); id<CHHapticPatternPlayer> player API_AVAILABLE(ios(13.0), tvos(14.0));
bool active;
} }
-(void)cleanup -(void)cleanup
@ -843,23 +844,24 @@ IOS_MFIJoystickUpdate(SDL_Joystick * joystick)
-(int)setIntensity:(float)intensity -(int)setIntensity:(float)intensity
{ {
@autoreleasepool {
if (@available(iOS 14.0, tvOS 14.0, *)) { if (@available(iOS 14.0, tvOS 14.0, *)) {
NSError *error; NSError *error;
if (self->player != nil) {
[self->player stopAtTime:0 error:&error];
self->player = nil;
}
if (self->engine == nil) { if (self->engine == nil) {
return SDL_SetError("Haptics engine not available"); return SDL_SetError("Haptics engine was stopped");
} }
if (intensity <= 0.01f) { if (intensity == 0.0f) {
if (self->player && self->active) {
[self->player stopAtTime:0 error:&error];
}
self->active = false;
return 0; return 0;
} }
CHHapticEventParameter *param = [[CHHapticEventParameter alloc] initWithParameterID:CHHapticEventParameterIDHapticIntensity value:intensity]; if (self->player == nil) {
CHHapticEventParameter *param = [[CHHapticEventParameter alloc] initWithParameterID:CHHapticEventParameterIDHapticIntensity value:1.0f];
CHHapticEvent *event = [[CHHapticEvent alloc] initWithEventType:CHHapticEventTypeHapticContinuous parameters:[NSArray arrayWithObjects:param, nil] relativeTime:0 duration:GCHapticDurationInfinite]; CHHapticEvent *event = [[CHHapticEvent alloc] initWithEventType:CHHapticEventTypeHapticContinuous parameters:[NSArray arrayWithObjects:param, nil] relativeTime:0 duration:GCHapticDurationInfinite];
CHHapticPattern *pattern = [[CHHapticPattern alloc] initWithEvents:[NSArray arrayWithObject:event] parameters:[[NSArray alloc] init] error:&error]; CHHapticPattern *pattern = [[CHHapticPattern alloc] initWithEvents:[NSArray arrayWithObject:event] parameters:[[NSArray alloc] init] error:&error];
if (error != nil) { if (error != nil) {
@ -870,27 +872,39 @@ IOS_MFIJoystickUpdate(SDL_Joystick * joystick)
if (error != nil) { if (error != nil) {
return SDL_SetError("Couldn't create haptic player: %s", [error.localizedDescription UTF8String]); return SDL_SetError("Couldn't create haptic player: %s", [error.localizedDescription UTF8String]);
} }
self->active = false;
}
[self->player startAtTime:0 error:&error]; CHHapticDynamicParameter *param = [[CHHapticDynamicParameter alloc] initWithParameterID:CHHapticDynamicParameterIDHapticIntensityControl value:intensity relativeTime:0];
[self->player sendParameters:[NSArray arrayWithObject:param] atTime:0 error:&error];
if (error != nil) { if (error != nil) {
self->player = nil; return SDL_SetError("Couldn't update haptic player: %s", [error.localizedDescription UTF8String]);
return SDL_SetError("Couldn't start playback: %s", [error.localizedDescription UTF8String]); }
if (!self->active) {
[self->player startAtTime:0 error:&error];
self->active = true;
} }
} }
return 0; return 0;
}
} }
-(id) initWithController:(GCController*)controller locality:(GCHapticsLocality)locality API_AVAILABLE(ios(14.0), tvos(14.0)) -(id) initWithController:(GCController*)controller locality:(GCHapticsLocality)locality API_AVAILABLE(ios(14.0), tvos(14.0))
{ {
@autoreleasepool {
NSError *error; NSError *error;
self->engine = [controller.haptics createEngineWithLocality:locality]; self->engine = [controller.haptics createEngineWithLocality:locality];
if (self->engine == nil) { if (self->engine == nil) {
SDL_SetError("Couldn't create haptics engine");
return nil; return nil;
} }
[self->engine startAndReturnError:&error]; [self->engine startAndReturnError:&error];
if (error != nil) { if (error != nil) {
SDL_SetError("Couldn't start haptics engine");
return nil; return nil;
} }
@ -915,6 +929,7 @@ IOS_MFIJoystickUpdate(SDL_Joystick * joystick)
}; };
return self; return self;
}
} }
@end @end
@ -943,6 +958,12 @@ IOS_MFIJoystickUpdate(SDL_Joystick * joystick)
return ((result < 0) ? -1 : 0); return ((result < 0) ? -1 : 0);
} }
-(void)cleanup
{
[self->low_frequency_motor cleanup];
[self->high_frequency_motor cleanup];
}
@end @end
static SDL_RumbleContext *IOS_JoystickInitRumble(GCController *controller) static SDL_RumbleContext *IOS_JoystickInitRumble(GCController *controller)
@ -1015,10 +1036,15 @@ IOS_JoystickClose(SDL_Joystick * joystick)
device->joystick = NULL; device->joystick = NULL;
@autoreleasepool { @autoreleasepool {
#ifdef ENABLE_MFI_RUMBLE
if (device->rumble) { if (device->rumble) {
SDL_RumbleContext *rumble = (__bridge SDL_RumbleContext *)device->rumble;
[rumble cleanup];
CFRelease(device->rumble); CFRelease(device->rumble);
device->rumble = NULL; device->rumble = NULL;
} }
#endif /* ENABLE_MFI_RUMBLE */
if (device->accelerometer) { if (device->accelerometer) {
#if !TARGET_OS_TV #if !TARGET_OS_TV