From 46869db01c1c616b6f6ab9364f18c283d57513b3 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Mon, 26 Jul 2021 23:27:13 -0700 Subject: [PATCH] Fixed controller rumble on macOS Needed to add a strong reference to the haptics engine --- src/joystick/iphoneos/SDL_mfijoystick.m | 90 ++++++++++++------------- 1 file changed, 45 insertions(+), 45 deletions(-) diff --git a/src/joystick/iphoneos/SDL_mfijoystick.m b/src/joystick/iphoneos/SDL_mfijoystick.m index 9dae6f712..2e8c137c6 100644 --- a/src/joystick/iphoneos/SDL_mfijoystick.m +++ b/src/joystick/iphoneos/SDL_mfijoystick.m @@ -1019,23 +1019,23 @@ IOS_MFIJoystickUpdate(SDL_Joystick *joystick) #ifdef ENABLE_MFI_RUMBLE @interface SDL_RumbleMotor : NSObject + @property(nonatomic,strong) CHHapticEngine *engine API_AVAILABLE(macos(11.0), ios(13.0), tvos(14.0)); + @property(nonatomic,strong) id player API_AVAILABLE(macos(11.0), ios(13.0), tvos(14.0)); + @property bool active; @end @implementation SDL_RumbleMotor { - CHHapticEngine *engine API_AVAILABLE(macos(11.0), ios(13.0), tvos(14.0)); - id player API_AVAILABLE(macos(11.0), ios(13.0), tvos(14.0)); - bool active; } -(void)cleanup { - if (self->player != nil) { - [self->player cancelAndReturnError:nil]; - self->player = nil; + if (self.player != nil) { + [self.player cancelAndReturnError:nil]; + self.player = nil; } - if (self->engine != nil) { - [self->engine stopWithCompletionHandler:nil]; - self->engine = nil; + if (self.engine != nil) { + [self.engine stopWithCompletionHandler:nil]; + self.engine = nil; } } @@ -1043,21 +1043,21 @@ IOS_MFIJoystickUpdate(SDL_Joystick *joystick) { @autoreleasepool { if (@available(macos 11.0, iOS 14.0, tvOS 14.0, *)) { - NSError *error; + NSError *error = nil; - if (self->engine == nil) { + if (self.engine == nil) { return SDL_SetError("Haptics engine was stopped"); } if (intensity == 0.0f) { - if (self->player && self->active) { - [self->player stopAtTime:0 error:&error]; + if (self.player && self.active) { + [self.player stopAtTime:0 error:&error]; } - self->active = false; + self.active = false; return 0; } - if (self->player == nil) { + 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]; CHHapticPattern *pattern = [[CHHapticPattern alloc] initWithEvents:[NSArray arrayWithObject:event] parameters:[[NSArray alloc] init] error:&error]; @@ -1065,22 +1065,22 @@ IOS_MFIJoystickUpdate(SDL_Joystick *joystick) return SDL_SetError("Couldn't create haptic pattern: %s", [error.localizedDescription UTF8String]); } - self->player = [self->engine createPlayerWithPattern:pattern error:&error]; + self.player = [self.engine createPlayerWithPattern:pattern error:&error]; if (error != nil) { return SDL_SetError("Couldn't create haptic player: %s", [error.localizedDescription UTF8String]); } - self->active = false; + self.active = false; } CHHapticDynamicParameter *param = [[CHHapticDynamicParameter alloc] initWithParameterID:CHHapticDynamicParameterIDHapticIntensityControl value:intensity relativeTime:0]; - [self->player sendParameters:[NSArray arrayWithObject:param] atTime:0 error:&error]; + [self.player sendParameters:[NSArray arrayWithObject:param] atTime:0 error:&error]; if (error != nil) { return SDL_SetError("Couldn't update haptic player: %s", [error.localizedDescription UTF8String]); } - if (!self->active) { - [self->player startAtTime:0 error:&error]; - self->active = true; + if (!self.active) { + [self.player startAtTime:0 error:&error]; + self.active = true; } } @@ -1094,36 +1094,36 @@ IOS_MFIJoystickUpdate(SDL_Joystick *joystick) self = [super init]; NSError *error; - self->engine = [controller.haptics createEngineWithLocality:locality]; - if (self->engine == nil) { + self.engine = [controller.haptics createEngineWithLocality:locality]; + if (self.engine == nil) { SDL_SetError("Couldn't create haptics engine"); return nil; } - [self->engine startAndReturnError:&error]; + [self.engine startAndReturnError:&error]; if (error != nil) { SDL_SetError("Couldn't start haptics engine"); return nil; } __weak typeof(self) weakSelf = self; - self->engine.stoppedHandler = ^(CHHapticEngineStoppedReason stoppedReason) { + self.engine.stoppedHandler = ^(CHHapticEngineStoppedReason stoppedReason) { SDL_RumbleMotor *_this = weakSelf; if (_this == nil) { return; } - _this->player = nil; - _this->engine = nil; + _this.player = nil; + _this.engine = nil; }; - self->engine.resetHandler = ^{ + self.engine.resetHandler = ^{ SDL_RumbleMotor *_this = weakSelf; if (_this == nil) { return; } - _this->player = nil; - [_this->engine startAndReturnError:nil]; + _this.player = nil; + [_this.engine startAndReturnError:nil]; }; return self; @@ -1133,13 +1133,13 @@ IOS_MFIJoystickUpdate(SDL_Joystick *joystick) @end @interface SDL_RumbleContext : NSObject + @property(nonatomic,strong) SDL_RumbleMotor *m_low_frequency_motor; + @property(nonatomic,strong) SDL_RumbleMotor *m_high_frequency_motor; + @property(nonatomic,strong) SDL_RumbleMotor *m_left_trigger_motor; + @property(nonatomic,strong) SDL_RumbleMotor *m_right_trigger_motor; @end @implementation SDL_RumbleContext { - SDL_RumbleMotor *m_low_frequency_motor; - SDL_RumbleMotor *m_high_frequency_motor; - SDL_RumbleMotor *m_left_trigger_motor; - SDL_RumbleMotor *m_right_trigger_motor; } -(id) initWithLowFrequencyMotor:(SDL_RumbleMotor*)low_frequency_motor @@ -1148,10 +1148,10 @@ IOS_MFIJoystickUpdate(SDL_Joystick *joystick) RightTriggerMotor:(SDL_RumbleMotor*)right_trigger_motor { self = [super init]; - self->m_low_frequency_motor = low_frequency_motor; - self->m_high_frequency_motor = high_frequency_motor; - self->m_left_trigger_motor = left_trigger_motor; - self->m_right_trigger_motor = right_trigger_motor; + self.m_low_frequency_motor = low_frequency_motor; + self.m_high_frequency_motor = high_frequency_motor; + self.m_left_trigger_motor = left_trigger_motor; + self.m_right_trigger_motor = right_trigger_motor; return self; } @@ -1159,8 +1159,8 @@ IOS_MFIJoystickUpdate(SDL_Joystick *joystick) { int result = 0; - result += [self->m_low_frequency_motor setIntensity:((float)low_frequency_rumble / 65535.0f)]; - result += [self->m_high_frequency_motor setIntensity:((float)high_frequency_rumble / 65535.0f)]; + result += [self.m_low_frequency_motor setIntensity:((float)low_frequency_rumble / 65535.0f)]; + result += [self.m_high_frequency_motor setIntensity:((float)high_frequency_rumble / 65535.0f)]; return ((result < 0) ? -1 : 0); } @@ -1168,9 +1168,9 @@ IOS_MFIJoystickUpdate(SDL_Joystick *joystick) { int result = 0; - if (self->m_left_trigger_motor && self->m_right_trigger_motor) { - result += [self->m_left_trigger_motor setIntensity:((float)left_rumble / 65535.0f)]; - result += [self->m_right_trigger_motor setIntensity:((float)right_rumble / 65535.0f)]; + if (self.m_left_trigger_motor && self.m_right_trigger_motor) { + result += [self.m_left_trigger_motor setIntensity:((float)left_rumble / 65535.0f)]; + result += [self.m_right_trigger_motor setIntensity:((float)right_rumble / 65535.0f)]; } else { result = SDL_Unsupported(); } @@ -1179,8 +1179,8 @@ IOS_MFIJoystickUpdate(SDL_Joystick *joystick) -(void)cleanup { - [self->m_low_frequency_motor cleanup]; - [self->m_high_frequency_motor cleanup]; + [self.m_low_frequency_motor cleanup]; + [self.m_high_frequency_motor cleanup]; } @end