Skip to content

Commit

Permalink
Improvements to mfi rumble. (libretro#16431)
Browse files Browse the repository at this point in the history
  • Loading branch information
warmenhoven authored and Sunderland93 committed Dec 26, 2024
1 parent 4b2f8c5 commit 32a3a45
Showing 1 changed file with 29 additions and 49 deletions.
78 changes: 29 additions & 49 deletions input/drivers_joypad/mfi_joypad.m
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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<CHHapticEngine *> *engines MFI_RUMBLE_AVAIL;
@property (nonatomic, strong, readonly) id<CHHapticPatternPlayer> strongPlayer MFI_RUMBLE_AVAIL;
@property (nonatomic, strong, readonly) id<CHHapticPatternPlayer> weakPlayer MFI_RUMBLE_AVAIL;
@end
Expand All @@ -297,73 +298,54 @@ - (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<CHHapticPatternPlayer>)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)
return;

[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<CHHapticPatternPlayer>)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]
Expand All @@ -374,7 +356,7 @@ - (void)setupEngine MFI_RUMBLE_AVAIL
if (error)
return nil;

id<CHHapticPatternPlayer> player = [self.engine createPlayerWithPattern:pattern error:&error];
id<CHHapticPatternPlayer> player = [engine createPlayerWithPattern:pattern error:&error];
if (error)
return nil;
[player stopAtTime:0 error:&error];
Expand All @@ -383,13 +365,13 @@ - (void)setupEngine MFI_RUMBLE_AVAIL

- (id<CHHapticPatternPlayer>)strongPlayer
{
_strongPlayer = _strongPlayer ?: [self createPlayerWithSharpness:1.0];
_strongPlayer = _strongPlayer ?: [self createPlayerWithLocality:GCHapticsLocalityAll andIntensity:1.0];
return _strongPlayer;
}

- (id<CHHapticPatternPlayer>)weakPlayer
{
_weakPlayer = _weakPlayer ?: [self createPlayerWithSharpness:0.5f];
_weakPlayer = _weakPlayer ?: [self createPlayerWithLocality:GCHapticsLocalityTriggers andIntensity:MFI_WEAK_RUMBLE];
return _weakPlayer;
}

Expand All @@ -399,7 +381,7 @@ - (void)shutdown
{
_weakPlayer = nil;
_strongPlayer = nil;
self.engine = nil;
[self.engines removeAllObjects];
}
}

Expand Down Expand Up @@ -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)
return nil;
Expand All @@ -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]
Expand All @@ -577,9 +556,9 @@ static void apple_gamecontroller_device_haptics_setup() IPHONE_RUMBLE_AVAIL

static id<CHHapticPatternPlayer> 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

Expand Down Expand Up @@ -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
Expand Down

0 comments on commit 32a3a45

Please sign in to comment.