4848/* TODO/FIXME - static globals */
4949static uint32_t mfi_buttons[MAX_USERS];
5050static int16_t mfi_axes[MAX_USERS][MAX_MFI_AXES];
51- static uint32_t mfi_controllers[MAX_MFI_CONTROLLERS];
51+ static __weak GCController * mfi_controllers[MAX_MFI_CONTROLLERS];
5252static MFIRumbleController *mfi_rumblers[MAX_MFI_CONTROLLERS];
53- #define MFI_WEAK_RUMBLE 0 .5f
54- static NSMutableArray *mfiControllers;
53+ #define MFI_WEAK_RUMBLE 0 .7f
5554static bool mfi_inited;
5655
5756static bool apple_gamecontroller_available (void )
@@ -72,6 +71,15 @@ static bool mfi_controller_is_siri_remote(GCController *controller)
7271 return controller.microGamepad && !controller.extendedGamepad && [@" Remote" isEqualToString: controller.vendorName];
7372}
7473
74+ static bool mfi_controller_is_connected (GCController *controller)
75+ {
76+ int i;
77+ for (i = 0 ; i < MAX_MFI_CONTROLLERS; i++)
78+ if (mfi_controllers[i] == controller)
79+ return true ;
80+ return false ;
81+ }
82+
7583static void apple_gamecontroller_joypad_poll_internal (GCController *controller, uint32_t slot)
7684{
7785 uint32_t *buttons = &mfi_buttons[slot];
@@ -327,6 +335,46 @@ static void mfi_joypad_autodetect_add(unsigned autoconf_pad, const char *display
327335}
328336
329337#define MFI_RUMBLE_AVAIL API_AVAILABLE (macos(11.0 ), ios(14.0 ), tvos(14.0 ))
338+
339+ /* Helper function to create a haptic pattern player from an engine with given intensity */
340+ static id<CHHapticPatternPlayer> apple_gamecontroller_create_haptic_player(
341+ CHHapticEngine *engine, float intensity) MFI_RUMBLE_AVAIL
342+ {
343+ NSError *error;
344+ CHHapticEventParameter *intense;
345+ CHHapticEventParameter *sharp;
346+ CHHapticEvent *event;
347+ CHHapticPattern *pattern;
348+
349+ if (!engine)
350+ return nil ;
351+
352+ intense = [[CHHapticEventParameter alloc ]
353+ initWithParameterID: CHHapticEventParameterIDHapticIntensity
354+ value: intensity];
355+ sharp = [[CHHapticEventParameter alloc ]
356+ initWithParameterID: CHHapticEventParameterIDHapticSharpness
357+ value: 1.0 ];
358+ event = [[CHHapticEvent alloc ]
359+ initWithEventType: CHHapticEventTypeHapticContinuous
360+ parameters: [NSArray arrayWithObjects: intense, sharp, nil ]
361+ relativeTime: 0
362+ duration: GCHapticDurationInfinite];
363+ pattern = [[CHHapticPattern alloc ]
364+ initWithEvents: [NSArray arrayWithObject: event]
365+ parameters: [[NSArray alloc ] init ]
366+ error: &error];
367+
368+ if (error)
369+ return nil ;
370+
371+ id <CHHapticPatternPlayer> player = [engine createPlayerWithPattern: pattern error: &error];
372+ if (error)
373+ return nil ;
374+ [player stopAtTime: 0 error: &error];
375+ return player;
376+ }
377+
330378@interface MFIRumbleController : NSObject
331379@property (nonatomic , strong , readonly ) GCController *controller;
332380@property (nonatomic , strong ) NSMutableSet <CHHapticEngine *> *engines MFI_RUMBLE_AVAIL;
@@ -385,36 +433,7 @@ - (instancetype)initWithController:(GCController*)controller MFI_RUMBLE_AVAIL
385433 [eng startAndReturnError: nil ];
386434 };
387435
388- CHHapticEventParameter *intense;
389- CHHapticEvent *event;
390- CHHapticPattern *pattern;
391-
392- CHHapticEventParameter *sharp;
393-
394- intense = [[CHHapticEventParameter alloc ]
395- initWithParameterID: CHHapticEventParameterIDHapticIntensity
396- value: intensity];
397- sharp = [[CHHapticEventParameter alloc ]
398- initWithParameterID: CHHapticEventParameterIDHapticSharpness
399- value: 1.0 ];
400- event = [[CHHapticEvent alloc ]
401- initWithEventType: CHHapticEventTypeHapticContinuous
402- parameters: [NSArray arrayWithObjects: intense, sharp, nil ]
403- relativeTime: 0
404- duration: GCHapticDurationInfinite];
405- pattern = [[CHHapticPattern alloc ]
406- initWithEvents: [NSArray arrayWithObject: event]
407- parameters: [[NSArray alloc ] init ]
408- error: &error];
409-
410- if (error)
411- return nil ;
412-
413- id <CHHapticPatternPlayer> player = [engine createPlayerWithPattern: pattern error: &error];
414- if (error)
415- return nil ;
416- [player stopAtTime: 0 error: &error];
417- return player;
436+ return apple_gamecontroller_create_haptic_player (engine, intensity);
418437}
419438
420439- (id <CHHapticPatternPlayer>)strongPlayer
@@ -470,7 +489,7 @@ static void apple_gamecontroller_joypad_connect(GCController *controller)
470489 }
471490
472491 /* Prevent same controller getting set twice */
473- if ([mfiControllers containsObject: controller] )
492+ if (mfi_controller_is_connected ( controller) )
474493 {
475494 RARCH_DBG (" [MFI] Got connected notice for controller already connected.\n " );
476495 return ;
@@ -497,14 +516,14 @@ static void apple_gamecontroller_joypad_connect(GCController *controller)
497516 }
498517 }
499518
500- if (mfi_controllers[desired_index] != ( uint32_t ) controller. hash )
519+ if (mfi_controllers[desired_index] != controller)
501520 {
502521 /* Desired slot is unused, take it */
503522 if (!mfi_controllers[desired_index])
504523 {
505524 RARCH_LOG (" [MFI] Controller given desired index %d .\n " , desired_index);
506525 controller.playerIndex = desired_index;
507- mfi_controllers[desired_index] = ( uint32_t ) controller. hash ;
526+ mfi_controllers[desired_index] = controller;
508527 }
509528 else
510529 {
@@ -516,7 +535,7 @@ static void apple_gamecontroller_joypad_connect(GCController *controller)
516535 continue ;
517536
518537 RARCH_LOG (" [MFI] Controller reassigned from desired %d to %d .\n " , desired_index, i);
519- mfi_controllers[i] = ( uint32_t ) controller. hash ;
538+ mfi_controllers[i] = controller;
520539 controller.playerIndex = i;
521540 break ;
522541 }
@@ -530,8 +549,6 @@ static void apple_gamecontroller_joypad_connect(GCController *controller)
530549 }
531550 }
532551
533- [mfiControllers addObject: controller];
534-
535552 RARCH_LOG (" [MFI] Controller connected, beginning setup and autodetect...\n " );
536553 apple_gamecontroller_joypad_register (controller);
537554 apple_gamecontroller_joypad_setup_haptics (controller);
@@ -548,10 +565,10 @@ static void apple_gamecontroller_joypad_disconnect(GCController* controller)
548565 if (mfi_rumblers[pad])
549566 [mfi_rumblers[pad] shutdown ];
550567 mfi_rumblers[pad] = nil ;
551- mfi_controllers[pad] = 0 ;
552- if ([mfiControllers containsObject: controller] )
568+
569+ if (mfi_controllers[pad] == controller)
553570 {
554- [mfiControllers removeObject: controller] ;
571+ mfi_controllers[pad] = nil ;
555572 input_autoconfigure_disconnect ((unsigned )pad, mfi_joypad.ident );
556573 }
557574}
@@ -610,36 +627,7 @@ static void apple_gamecontroller_device_haptics_setup(void) IPHONE_RUMBLE_AVAIL
610627 return nil ;
611628 }
612629
613- CHHapticEventParameter *intense;
614- CHHapticEvent *event;
615- CHHapticPattern *pattern;
616-
617- CHHapticEventParameter *sharp;
618-
619- intense = [[CHHapticEventParameter alloc ]
620- initWithParameterID: CHHapticEventParameterIDHapticIntensity
621- value: intensity];
622- sharp = [[CHHapticEventParameter alloc ]
623- initWithParameterID: CHHapticEventParameterIDHapticSharpness
624- value: 1.0 ];
625- event = [[CHHapticEvent alloc ]
626- initWithEventType: CHHapticEventTypeHapticContinuous
627- parameters: [NSArray arrayWithObjects: intense, sharp, nil ]
628- relativeTime: 0
629- duration: GCHapticDurationInfinite];
630- pattern = [[CHHapticPattern alloc ]
631- initWithEvents: [NSArray arrayWithObject: event]
632- parameters: [[NSArray alloc ] init ]
633- error: &error];
634-
635- if (error)
636- return nil ;
637-
638- id <CHHapticPatternPlayer> player = [deviceHapticEngine createPlayerWithPattern: pattern error: &error];
639- if (error)
640- return nil ;
641- [player stopAtTime: 0 error: &error];
642- return player;
630+ return apple_gamecontroller_create_haptic_player (deviceHapticEngine, intensity);
643631}
644632
645633static id <CHHapticPatternPlayer> apple_gamecontroller_device_haptics_strong_player (void ) IPHONE_RUMBLE_AVAIL
@@ -652,7 +640,7 @@ static void apple_gamecontroller_device_haptics_setup(void) IPHONE_RUMBLE_AVAIL
652640static id <CHHapticPatternPlayer> apple_gamecontroller_device_haptics_weak_player (void ) IPHONE_RUMBLE_AVAIL
653641{
654642 if (!deviceWeakPlayer)
655- deviceWeakPlayer = apple_gamecontroller_device_haptics_create_player (0 . 7f );
643+ deviceWeakPlayer = apple_gamecontroller_device_haptics_create_player (MFI_WEAK_RUMBLE );
656644 return deviceWeakPlayer;
657645}
658646#endif
@@ -669,7 +657,6 @@ static void apple_gamecontroller_device_haptics_setup(void) IPHONE_RUMBLE_AVAIL
669657
670658 if (!apple_gamecontroller_available ())
671659 return NULL ;
672- mfiControllers = [[NSMutableArray alloc ] initWithCapacity: MAX_MFI_CONTROLLERS];
673660#ifdef __IPHONE_7_0
674661 [[NSNotificationCenter defaultCenter ] addObserverForName: GCControllerDidConnectNotification
675662 object: nil
@@ -766,12 +753,9 @@ static int16_t apple_gamecontroller_joypad_state(
766753 ? binds[i].joykey : joypad_info->auto_binds [i].joykey ;
767754 const uint32_t joyaxis = (binds[i].joyaxis != AXIS_NONE)
768755 ? binds[i].joyaxis : joypad_info->auto_binds [i].joyaxis ;
769- if ( (uint16_t )joykey != NO_BTN
770- && !GET_HAT_DIR (i)
771- && (i < 32 )
772- && ((mfi_buttons[port_idx] & (1 << i)) != 0 )
773- )
774- ret |= ( 1 << i);
756+ if ((uint16_t )joykey != NO_BTN
757+ && apple_gamecontroller_joypad_button (port_idx, (uint16_t )joykey))
758+ ret |= (1 << i);
775759 else if (joyaxis != AXIS_NONE &&
776760 ((float )abs (apple_gamecontroller_joypad_axis (port_idx, joyaxis))
777761 / 0x8000 ) > joypad_info->axis_threshold )
@@ -841,7 +825,7 @@ static bool apple_gamecontroller_joypad_set_rumble(unsigned pad,
841825 if (!error)
842826 [player startAtTime: 0 error: &error];
843827 }
844- return error;
828+ return ! error;
845829 }
846830 }
847831 }
0 commit comments