mirror of
https://github.com/libretro/RetroArch
synced 2025-03-28 19:20:35 +00:00
Improvements to mfi rumble. (#16431)
Fixes https://github.com/libretro/RetroArch/issues/15300 and https://github.com/libretro/beetle-psx-libretro/issues/891
This commit is contained in:
parent
b7404930ac
commit
3229d645d6
@ -54,6 +54,7 @@ static uint32_t mfi_buttons[MAX_USERS];
|
||||
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<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
|
||||
@ -297,34 +298,28 @@ static void mfi_joypad_autodetect_add(unsigned autoconf_pad, const char *display
|
||||
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)
|
||||
@ -332,38 +327,25 @@ static void mfi_joypad_autodetect_add(unsigned autoconf_pad, const char *display
|
||||
|
||||
[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]
|
||||
@ -374,7 +356,7 @@ static void mfi_joypad_autodetect_add(unsigned autoconf_pad, const char *display
|
||||
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];
|
||||
@ -383,13 +365,13 @@ static void mfi_joypad_autodetect_add(unsigned autoconf_pad, const char *display
|
||||
|
||||
- (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;
|
||||
}
|
||||
|
||||
@ -399,7 +381,7 @@ static void mfi_joypad_autodetect_add(unsigned autoconf_pad, const char *display
|
||||
{
|
||||
_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<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;
|
||||
@ -537,20 +519,17 @@ static id<CHHapticPatternPlayer> apple_gamecontroller_device_haptics_create_play
|
||||
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 id<CHHapticPatternPlayer> apple_gamecontroller_device_haptics_strong_play
|
||||
|
||||
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
|
||||
|
||||
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user