diff --git a/input/drivers_joypad/mfi_joypad.m b/input/drivers_joypad/mfi_joypad.m index 020a288b990..77380328f41 100644 --- a/input/drivers_joypad/mfi_joypad.m +++ b/input/drivers_joypad/mfi_joypad.m @@ -54,6 +54,7 @@ static int16_t mfi_axes[MAX_USERS][MAX_MFI_AXES]; static uint32_t mfi_controllers[MAX_MFI_CONTROLLERS]; static MFIRumbleController *mfi_rumblers[MAX_MFI_CONTROLLERS]; +#define MFI_WEAK_RUMBLE 0.3f static NSMutableArray *mfiControllers; static bool mfi_inited; @@ -280,7 +281,7 @@ static void mfi_joypad_autodetect_add(unsigned autoconf_pad, const char *display #define MFI_RUMBLE_AVAIL API_AVAILABLE(macos(11.0), ios(14.0), tvos(14.0)) @interface MFIRumbleController : NSObject @property (nonatomic, strong, readonly) GCController *controller; -@property (nonatomic, strong) CHHapticEngine *engine MFI_RUMBLE_AVAIL; +@property (nonatomic, strong) NSMutableSet *engines MFI_RUMBLE_AVAIL; @property (nonatomic, strong, readonly) id strongPlayer MFI_RUMBLE_AVAIL; @property (nonatomic, strong, readonly) id weakPlayer MFI_RUMBLE_AVAIL; @end @@ -297,34 +298,28 @@ - (instancetype)initWithController:(GCController*)controller MFI_RUMBLE_AVAIL return self; _controller = controller; - - [self setupEngine]; - if (!self.engine) - return self; - - _strongPlayer = [self createPlayerWithSharpness:1.0f]; - _weakPlayer = [self createPlayerWithSharpness:0.5f]; + _engines = [[NSMutableSet alloc] init]; } return self; } -- (void)setupEngine MFI_RUMBLE_AVAIL +- (id)createPlayerWithLocality:(GCHapticsLocality)locality andIntensity:(float)intensity MFI_RUMBLE_AVAIL { NSError *error; - if (self.engine) - return; if (!self.controller) - return; + return nil; - CHHapticEngine *engine = [self.controller.haptics createEngineWithLocality:GCHapticsLocalityDefault]; + if (![self.controller.haptics.supportedLocalities containsObject:locality]) + locality = GCHapticsLocalityDefault; + CHHapticEngine *engine = [self.controller.haptics createEngineWithLocality:locality]; [engine startAndReturnError:&error]; if (error) - return; + return nil; - self.engine = engine; + [self.engines addObject:engine]; __weak MFIRumbleController *weakSelf = self; - self.engine.stoppedHandler = ^(CHHapticEngineStoppedReason stoppedReason) + engine.stoppedHandler = ^(CHHapticEngineStoppedReason stoppedReason) { MFIRumbleController *strongSelf = weakSelf; if (!strongSelf) @@ -332,38 +327,25 @@ - (void)setupEngine MFI_RUMBLE_AVAIL [strongSelf shutdown]; }; - self.engine.resetHandler = ^{ + engine.resetHandler = ^{ MFIRumbleController *strongSelf = weakSelf; if (!strongSelf) return; - [strongSelf.engine startAndReturnError:nil]; + for (CHHapticEngine *eng in strongSelf.engines) + [eng startAndReturnError:nil]; }; -} -- (id)createPlayerWithSharpness:(float)sharpness MFI_RUMBLE_AVAIL -{ - if (!self.controller) - return nil; - - [self setupEngine]; - if (!self.engine) - return nil; - - CHHapticEventParameter *sharp, *intense; + CHHapticEventParameter *intense; CHHapticEvent *event; CHHapticPattern *pattern; - NSError *error; - sharp = [[CHHapticEventParameter alloc] - initWithParameterID:CHHapticEventParameterIDHapticSharpness - value:sharpness]; intense = [[CHHapticEventParameter alloc] initWithParameterID:CHHapticEventParameterIDHapticIntensity - value:1.0f]; + value:intensity]; event = [[CHHapticEvent alloc] initWithEventType:CHHapticEventTypeHapticContinuous - parameters:[NSArray arrayWithObjects:sharp, intense, nil] + parameters:[NSArray arrayWithObjects:intense, nil] relativeTime:0 duration:GCHapticDurationInfinite]; pattern = [[CHHapticPattern alloc] @@ -374,7 +356,7 @@ - (void)setupEngine MFI_RUMBLE_AVAIL if (error) return nil; - id player = [self.engine createPlayerWithPattern:pattern error:&error]; + id player = [engine createPlayerWithPattern:pattern error:&error]; if (error) return nil; [player stopAtTime:0 error:&error]; @@ -383,13 +365,13 @@ - (void)setupEngine MFI_RUMBLE_AVAIL - (id)strongPlayer { - _strongPlayer = _strongPlayer ?: [self createPlayerWithSharpness:1.0]; + _strongPlayer = _strongPlayer ?: [self createPlayerWithLocality:GCHapticsLocalityAll andIntensity:1.0]; return _strongPlayer; } - (id)weakPlayer { - _weakPlayer = _weakPlayer ?: [self createPlayerWithSharpness:0.5f]; + _weakPlayer = _weakPlayer ?: [self createPlayerWithLocality:GCHapticsLocalityTriggers andIntensity:MFI_WEAK_RUMBLE]; return _weakPlayer; } @@ -399,7 +381,7 @@ - (void)shutdown { _weakPlayer = nil; _strongPlayer = nil; - self.engine = nil; + [self.engines removeAllObjects]; } } @@ -528,7 +510,7 @@ static void apple_gamecontroller_device_haptics_setup() IPHONE_RUMBLE_AVAIL }; } -static id apple_gamecontroller_device_haptics_create_player(float sharpness) IPHONE_RUMBLE_AVAIL +static id apple_gamecontroller_device_haptics_create_player(float intensity) IPHONE_RUMBLE_AVAIL { if (!CHHapticEngine.capabilitiesForHardware.supportsHaptics) return nil; @@ -537,20 +519,17 @@ static void apple_gamecontroller_device_haptics_setup() IPHONE_RUMBLE_AVAIL if (!deviceHapticEngine) return nil; - CHHapticEventParameter *sharp, *intense; + CHHapticEventParameter *intense; CHHapticEvent *event; CHHapticPattern *pattern; NSError *error; - sharp = [[CHHapticEventParameter alloc] - initWithParameterID:CHHapticEventParameterIDHapticSharpness - value:sharpness]; intense = [[CHHapticEventParameter alloc] initWithParameterID:CHHapticEventParameterIDHapticIntensity - value:1.0f]; + value:intensity]; event = [[CHHapticEvent alloc] initWithEventType:CHHapticEventTypeHapticContinuous - parameters:[NSArray arrayWithObjects:sharp, intense, nil] + parameters:[NSArray arrayWithObjects:intense, nil] relativeTime:0 duration:GCHapticDurationInfinite]; pattern = [[CHHapticPattern alloc] @@ -577,9 +556,9 @@ static void apple_gamecontroller_device_haptics_setup() IPHONE_RUMBLE_AVAIL static id apple_gamecontroller_device_haptics_weak_player() IPHONE_RUMBLE_AVAIL { - if (!deviceStrongPlayer) - deviceStrongPlayer = apple_gamecontroller_device_haptics_create_player(0.5f); - return deviceStrongPlayer; + if (!deviceWeakPlayer) + deviceWeakPlayer = apple_gamecontroller_device_haptics_create_player(0.5f); + return deviceWeakPlayer; } #endif @@ -741,6 +720,7 @@ static bool apple_gamecontroller_joypad_set_rumble(unsigned pad, else { float str = (float)strength / 65535.0f; + if (type == RETRO_RUMBLE_WEAK) str *= MFI_WEAK_RUMBLE; CHHapticDynamicParameter *param = [[CHHapticDynamicParameter alloc] initWithParameterID:CHHapticDynamicParameterIDHapticIntensityControl value:str