git.y1.nz

SameBoy

Accurate GB/GBC emulator
download: https://git.y1.nz/archives/sameboy.tar.gz
README | Files | Log | Refs | LICENSE

iOS/GCControllerGetElements.m

      1 #import "GCControllerGetElements.h"
      2 #import <objc/runtime.h>
      3 
      4 static NSDictionary <NSNumber *, GCControllerElement *> *GCControllerGetElementsLegacy(GCExtendedGamepad *self)
      5 {
      6     if (!self) return nil;
      7     NSMutableDictionary <NSNumber *, GCControllerElement *> *ret = [NSMutableDictionary dictionary];
      8     if (self.dpad) ret[@(GBUsageDpad)] = self.dpad;
      9     if (self.buttonA) ret[@(GBUsageButtonA)] = self.buttonA;
     10     if (self.buttonB) ret[@(GBUsageButtonB)] = self.buttonB;
     11     if (self.buttonX) ret[@(GBUsageButtonX)] = self.buttonX;
     12     if (self.buttonY) ret[@(GBUsageButtonY)] = self.buttonY;
     13     if (@available(iOS 13.0, *)) {
     14         if (self.buttonMenu) ret[@(GBUsageButtonMenu)] = self.buttonMenu;
     15         if (self.buttonOptions) ret[@(GBUsageButtonOptions)] = self.buttonOptions;
     16     }
     17     // Can't be used
     18     /* if (@available(iOS 14.0, *)) {
     19         if (self.buttonHome) ret[@(GBUsageButtonHome)] = self.buttonHome;
     20     } */
     21     if (self.leftThumbstick) ret[@(GBUsageLeftThumbstick)] = self.leftThumbstick;
     22     if (self.rightThumbstick) ret[@(GBUsageRightThumbstick)] = self.rightThumbstick;
     23     if (self.leftShoulder) ret[@(GBUsageLeftShoulder)] = self.leftShoulder;
     24     if (self.rightShoulder) ret[@(GBUsageRightShoulder)] = self.rightShoulder;
     25     if (self.leftTrigger) ret[@(GBUsageLeftTrigger)] = self.leftTrigger;
     26     if (self.rightTrigger) ret[@(GBUsageRightTrigger)] = self.rightTrigger;
     27     if (@available(iOS 12.1, *)) {
     28         if (self.leftThumbstickButton) ret[@(GBUsageLeftThumbstickButton)] = self.leftThumbstickButton;
     29         if (self.rightThumbstickButton) ret[@(GBUsageRightThumbstickButton)] = self.rightThumbstickButton;
     30     }
     31     return ret;
     32 }
     33 
     34 API_AVAILABLE(ios(14.0))
     35 static NSDictionary <NSNumber *, GCControllerElement *> *GCControllerGetElementsModern(GCPhysicalInputProfile *self)
     36 {
     37     static NSDictionary * nameToUsage = nil;
     38     static dispatch_once_t onceToken;
     39     dispatch_once(&onceToken, ^{
     40         nameToUsage = @{
     41             GCInputButtonA: @(GBUsageButtonA),
     42             GCInputButtonB: @(GBUsageButtonB),
     43             GCInputButtonX: @(GBUsageButtonX),
     44             GCInputButtonY: @(GBUsageButtonY),
     45             
     46             GCInputLeftThumbstick: @(GBUsageLeftThumbstick),
     47             GCInputRightThumbstick: @(GBUsageRightThumbstick),
     48             GCInputLeftThumbstickButton: @(GBUsageLeftThumbstickButton),
     49             GCInputRightThumbstickButton: @(GBUsageRightThumbstickButton),
     50             GCInputLeftShoulder: @(GBUsageLeftShoulder),
     51             GCInputRightShoulder: @(GBUsageRightShoulder),
     52             GCInputLeftTrigger: @(GBUsageLeftTrigger),
     53             GCInputRightTrigger: @(GBUsageRightTrigger),
     54             
     55             GCInputButtonMenu: @(GBUsageButtonMenu),
     56             GCInputButtonOptions: @(GBUsageButtonOptions),
     57             GCInputDualShockTouchpadButton: @(GBUsageTouchpadButton),
     58         };
     59     });
     60     
     61     NSArray<NSString *> *elementNames = [self.elements.allKeys sortedArrayUsingSelector:@selector(compare:)];
     62     
     63     NSMutableDictionary <NSNumber *, GCControllerElement *> *ret = [NSMutableDictionary dictionary];
     64     GBControllerUsage miscUsage = GBUsageMiscStartIndex;
     65     for (NSString *name in elementNames) {
     66         if ([name isEqualToString:GCInputButtonHome]) continue;
     67         GCControllerElement *input = self.elements[name];
     68         NSNumber *_usage = nameToUsage[name];
     69         GBControllerUsage usage;
     70         if (_usage) {
     71             usage = _usage.unsignedIntValue;
     72             // These get weird mappings by default
     73             if ([self.device.vendorName isEqualToString:@"Joy-Con (L)"] ||
     74                 [self.device.vendorName isEqualToString:@"Joy-Con (R)"]) {
     75                 switch (usage) {
     76                     case GBUsageButtonA: usage = GBUsageButtonB; break;
     77                     case GBUsageButtonB: usage = GBUsageButtonY; break;
     78                     case GBUsageButtonX: usage = GBUsageButtonA; break;
     79                     case GBUsageButtonY: usage = GBUsageButtonX; break;
     80                     default: break;
     81                 }
     82             }
     83         }
     84         else if ([input isKindOfClass:[GCControllerDirectionPad class]] && !ret[@(GBUsageDpad)]) {
     85             usage = GBUsageDpad;
     86         }
     87         else {
     88             usage = miscUsage++;
     89         }
     90         if ([ret.allValues containsObject:input]) {
     91             NSNumber *alias = [ret allKeysForObject:input][0];
     92             if (alias.unsignedIntValue >= GBUsageMiscStartIndex) {
     93                 [ret removeObjectForKey:alias];
     94             }
     95             else {
     96                 continue;
     97             }
     98         }
     99         ret[@(usage)] = input;
    100     }
    101     
    102     return ret;
    103 }
    104 
    105 NSDictionary <NSNumber *, GCControllerElement *> *GCControllerGetElements(GCController *self)
    106 {
    107     NSDictionary <NSNumber *, GCControllerElement *> *ret = nil;
    108     ret = objc_getAssociatedObject(self, GCControllerGetElements);
    109     if (ret) return ret;
    110     if (@available(iOS 14.0, *)) {
    111         ret = GCControllerGetElementsModern(self.physicalInputProfile);
    112     }
    113     else {
    114         ret = GCControllerGetElementsLegacy(self.extendedGamepad);
    115     }
    116     objc_setAssociatedObject(self, GCControllerGetElements, ret, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
    117     return ret;
    118 }

This webpage is intended to be an accessible preview of this repository. To get a fuller picture, clone it and use the git CLI.