Eric Warmenhoven 2024-04-11 19:48:02 -04:00 committed by GitHub
parent b7404930ac
commit 3229d645d6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

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