mirror of
https://github.com/libretro/RetroArch
synced 2025-03-03 04:14:00 +00:00
iOS: use haptic engine instead of feedback generator for device rumble
This commit is contained in:
parent
2d66b5f863
commit
286ce51277
@ -33,7 +33,10 @@
|
||||
|
||||
#if TARGET_OS_IOS
|
||||
#include "../../configuration.h"
|
||||
static UIImpactFeedbackGenerator *deviceFeedbackGenerator;
|
||||
#define IPHONE_RUMBLE_AVAIL API_AVAILABLE(ios(14.0))
|
||||
static CHHapticEngine *deviceHapticEngine IPHONE_RUMBLE_AVAIL;
|
||||
static id<CHHapticPatternPlayer> deviceWeakPlayer IPHONE_RUMBLE_AVAIL;
|
||||
static id<CHHapticPatternPlayer> deviceStrongPlayer IPHONE_RUMBLE_AVAIL;
|
||||
#endif
|
||||
|
||||
enum
|
||||
@ -487,15 +490,100 @@ static void apple_gamecontroller_joypad_disconnect(GCController* controller)
|
||||
}
|
||||
}
|
||||
|
||||
#if TARGET_OS_IOS
|
||||
static void apple_gamecontroller_device_haptics_setup() IPHONE_RUMBLE_AVAIL
|
||||
{
|
||||
if (!CHHapticEngine.capabilitiesForHardware.supportsHaptics)
|
||||
return;
|
||||
|
||||
if (deviceHapticEngine)
|
||||
return;
|
||||
|
||||
NSError *error;
|
||||
CHHapticEngine *engine = [[CHHapticEngine alloc] initAndReturnError:&error];
|
||||
if (error)
|
||||
return;
|
||||
[engine startAndReturnError:&error];
|
||||
if (error)
|
||||
return;
|
||||
deviceHapticEngine = engine;
|
||||
|
||||
deviceHapticEngine.stoppedHandler = ^(CHHapticEngineStoppedReason reason)
|
||||
{
|
||||
deviceWeakPlayer = nil;
|
||||
deviceStrongPlayer = nil;
|
||||
deviceHapticEngine = nil;
|
||||
};
|
||||
deviceHapticEngine.resetHandler = ^{
|
||||
if (!deviceHapticEngine)
|
||||
return;
|
||||
[deviceHapticEngine startAndReturnError:nil];
|
||||
};
|
||||
}
|
||||
|
||||
static id<CHHapticPatternPlayer> apple_gamecontroller_device_haptics_create_player(float sharpness) IPHONE_RUMBLE_AVAIL
|
||||
{
|
||||
if (!CHHapticEngine.capabilitiesForHardware.supportsHaptics)
|
||||
return nil;
|
||||
|
||||
apple_gamecontroller_device_haptics_setup();
|
||||
if (!deviceHapticEngine)
|
||||
return nil;
|
||||
|
||||
CHHapticEventParameter *sharp, *intense;
|
||||
CHHapticEvent *event;
|
||||
CHHapticPattern *pattern;
|
||||
NSError *error;
|
||||
|
||||
sharp = [[CHHapticEventParameter alloc]
|
||||
initWithParameterID:CHHapticEventParameterIDHapticSharpness
|
||||
value:sharpness];
|
||||
intense = [[CHHapticEventParameter alloc]
|
||||
initWithParameterID:CHHapticEventParameterIDHapticIntensity
|
||||
value:1.0f];
|
||||
event = [[CHHapticEvent alloc]
|
||||
initWithEventType:CHHapticEventTypeHapticContinuous
|
||||
parameters:[NSArray arrayWithObjects:sharp, intense, nil]
|
||||
relativeTime:0
|
||||
duration:GCHapticDurationInfinite];
|
||||
pattern = [[CHHapticPattern alloc]
|
||||
initWithEvents:[NSArray arrayWithObject:event]
|
||||
parameters:[[NSArray alloc] init]
|
||||
error:&error];
|
||||
|
||||
if (error)
|
||||
return nil;
|
||||
|
||||
id<CHHapticPatternPlayer> player = [deviceHapticEngine createPlayerWithPattern:pattern error:&error];
|
||||
if (error)
|
||||
return nil;
|
||||
[player stopAtTime:0 error:&error];
|
||||
return player;
|
||||
}
|
||||
|
||||
static id<CHHapticPatternPlayer> apple_gamecontroller_device_haptics_strong_player() IPHONE_RUMBLE_AVAIL
|
||||
{
|
||||
if (!deviceStrongPlayer)
|
||||
deviceStrongPlayer = apple_gamecontroller_device_haptics_create_player(1.0f);
|
||||
return deviceStrongPlayer;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
#endif
|
||||
|
||||
void *apple_gamecontroller_joypad_init(void *data)
|
||||
{
|
||||
if (mfi_inited)
|
||||
return (void*)-1;
|
||||
|
||||
#if TARGET_OS_IOS
|
||||
if (!deviceFeedbackGenerator)
|
||||
deviceFeedbackGenerator = [[UIImpactFeedbackGenerator alloc] init];
|
||||
[deviceFeedbackGenerator prepare];
|
||||
if (@available(iOS 14, *))
|
||||
apple_gamecontroller_device_haptics_setup();
|
||||
#endif
|
||||
|
||||
if (!apple_gamecontroller_available())
|
||||
@ -603,10 +691,30 @@ static bool apple_gamecontroller_joypad_set_rumble(unsigned pad,
|
||||
settings_t *settings = config_get_ptr();
|
||||
bool enable_device_vibration = settings->bools.enable_device_vibration;
|
||||
|
||||
if (enable_device_vibration && pad == 0)
|
||||
{
|
||||
[deviceFeedbackGenerator impactOccurredWithIntensity:((float)strength)/65535.0f];
|
||||
[deviceFeedbackGenerator prepare];
|
||||
if (@available(iOS 14, *)) {
|
||||
if (enable_device_vibration && pad == 0)
|
||||
{
|
||||
NSError *error;
|
||||
id<CHHapticPatternPlayer> player = (type == RETRO_RUMBLE_STRONG ?
|
||||
apple_gamecontroller_device_haptics_strong_player() :
|
||||
apple_gamecontroller_device_haptics_weak_player());
|
||||
if (player)
|
||||
{
|
||||
if (strength == 0)
|
||||
[player stopAtTime:0 error:&error];
|
||||
else
|
||||
{
|
||||
float str = (float)strength / 65535.0f;
|
||||
CHHapticDynamicParameter *param = [[CHHapticDynamicParameter alloc]
|
||||
initWithParameterID:CHHapticDynamicParameterIDHapticIntensityControl
|
||||
value:str
|
||||
relativeTime:0];
|
||||
[player sendParameters:[NSArray arrayWithObject:param] atTime:0 error:&error];
|
||||
if (!error)
|
||||
[player startAtTime:0 error:&error];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user