mirror of
https://github.com/libretro/RetroArch
synced 2025-03-31 19:21:06 +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 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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user