|
|
@@ -15,10 +15,14 @@
|
|
|
#import <Foundation/Foundation.h>
|
|
|
|
|
|
// These should probably be moved to a platform common file
|
|
|
-#define SONY_USB_VENDOR_ID 0x54c
|
|
|
-#define SONY_USB_PS3_PRODUCT_ID 0x268
|
|
|
-#define MICROSOFT_VENDOR_ID 0x45e
|
|
|
-#define MICROSOFT_XBOX360_PRODUCT_ID 0x28e
|
|
|
+#define SONY_USB_VENDOR_ID 0x054c
|
|
|
+#define SONY_USB_PS3_PRODUCT_ID 0x0268
|
|
|
+#define MICROSOFT_VENDOR_ID 0x045e
|
|
|
+#define MICROSOFT_XBOX360_PRODUCT_ID 0x028e
|
|
|
+#define STEELSERIES_VENDOR_ID 0x1038
|
|
|
+#define STEELSERIES_FREE_PRODUCT_ID 0x1412
|
|
|
+#define FRUCTEL_VENDOR_ID 0x25B6
|
|
|
+#define FRUCTEL_GAMETEL_PRODUCT_ID 0x0001
|
|
|
|
|
|
using namespace std;
|
|
|
using namespace gameplay;
|
|
|
@@ -75,8 +79,6 @@ static void hidDeviceDiscoveredCallback(void *inContext, IOReturn inResult, void
|
|
|
static void hidDeviceRemovalCallback(void *inContext, IOReturn inResult, void *inSender, IOHIDDeviceRef inIOHIDDeviceRef);
|
|
|
static void hidDeviceValueAvailableCallback(void *inContext, IOReturn inResult, void *inSender);
|
|
|
|
|
|
-
|
|
|
-
|
|
|
double getMachTimeInMilliseconds()
|
|
|
{
|
|
|
static const double kOneMillion = 1000 * 1000;
|
|
|
@@ -97,6 +99,7 @@ double getMachTimeInMilliseconds()
|
|
|
CFIndex logMin;
|
|
|
CFIndex logMax;
|
|
|
}
|
|
|
+
|
|
|
+ gamepadAxisWithAxisElement:(IOHIDElementRef)element;
|
|
|
- initWithAxisElement:(IOHIDElementRef)element;
|
|
|
- (IOHIDElementRef)element;
|
|
|
@@ -110,11 +113,13 @@ double getMachTimeInMilliseconds()
|
|
|
- (CFIndex)value;
|
|
|
- (void)setValue:(CFIndex)value;
|
|
|
@end
|
|
|
+
|
|
|
@implementation HIDGamepadAxis
|
|
|
+ gamepadAxisWithAxisElement:(IOHIDElementRef)element
|
|
|
{
|
|
|
return [[[[self class] alloc] initWithAxisElement:element] autorelease];
|
|
|
}
|
|
|
+
|
|
|
- initWithAxisElement:(IOHIDElementRef)element
|
|
|
{
|
|
|
if((self = [super init]))
|
|
|
@@ -123,48 +128,59 @@ double getMachTimeInMilliseconds()
|
|
|
}
|
|
|
return self;
|
|
|
}
|
|
|
+
|
|
|
- (void)dealloc
|
|
|
{
|
|
|
CFRelease(e);
|
|
|
[super dealloc];
|
|
|
}
|
|
|
+
|
|
|
- (IOHIDElementRef)element
|
|
|
{
|
|
|
return e;
|
|
|
}
|
|
|
+
|
|
|
- (IOHIDElementCookie)cookie
|
|
|
{
|
|
|
return IOHIDElementGetCookie(e);
|
|
|
}
|
|
|
+
|
|
|
- (bool)isHatSwitch {
|
|
|
return (IOHIDElementGetUsage(e) == kHIDUsage_GD_Hatswitch);
|
|
|
}
|
|
|
+
|
|
|
- (uint32_t)usage
|
|
|
{
|
|
|
return IOHIDElementGetUsage(e);
|
|
|
}
|
|
|
+
|
|
|
- (uint32_t)usagePage
|
|
|
{
|
|
|
return IOHIDElementGetUsagePage(e);
|
|
|
}
|
|
|
+
|
|
|
- (CFIndex)logicalMinimum
|
|
|
{
|
|
|
return IOHIDElementGetLogicalMin(e);
|
|
|
}
|
|
|
+
|
|
|
- (CFIndex)logicalMaximum
|
|
|
{
|
|
|
return IOHIDElementGetLogicalMax(e);
|
|
|
}
|
|
|
+
|
|
|
- (float)calibratedValue
|
|
|
{
|
|
|
float cmax = 2.0f;
|
|
|
float cmin = 0.0f;
|
|
|
return ((((v - [self logicalMinimum]) * (cmax - cmin)) / ([self logicalMaximum] - [self logicalMinimum])) + cmin - 1.0f);
|
|
|
}
|
|
|
+
|
|
|
- (CFIndex)value
|
|
|
{
|
|
|
return v;
|
|
|
}
|
|
|
+
|
|
|
- (void)setValue:(CFIndex)value
|
|
|
{
|
|
|
v = value;
|
|
|
@@ -178,6 +194,7 @@ double getMachTimeInMilliseconds()
|
|
|
bool state;
|
|
|
int triggerValue;
|
|
|
}
|
|
|
+
|
|
|
+ gamepadButtonWithButtonElement:(IOHIDElementRef)element;
|
|
|
- initWithButtonElement:(IOHIDElementRef)element;
|
|
|
- (void)setTriggerElement:(IOHIDElementRef)element;
|
|
|
@@ -195,11 +212,13 @@ double getMachTimeInMilliseconds()
|
|
|
- (bool)state;
|
|
|
- (void)setState:(bool)state;
|
|
|
@end
|
|
|
+
|
|
|
@implementation HIDGamepadButton
|
|
|
+ gamepadButtonWithButtonElement:(IOHIDElementRef)element
|
|
|
{
|
|
|
return [[[[self class] alloc] initWithButtonElement:element] autorelease];
|
|
|
}
|
|
|
+
|
|
|
- initWithButtonElement:(IOHIDElementRef)element
|
|
|
{
|
|
|
if((self = [super init]))
|
|
|
@@ -210,12 +229,14 @@ double getMachTimeInMilliseconds()
|
|
|
}
|
|
|
return self;
|
|
|
}
|
|
|
+
|
|
|
- (void)dealloc
|
|
|
{
|
|
|
CFRelease(e);
|
|
|
if(te != NULL) CFRelease(te);
|
|
|
[super dealloc];
|
|
|
}
|
|
|
+
|
|
|
- (void)setTriggerElement:(IOHIDElementRef)element {
|
|
|
if(te)
|
|
|
{
|
|
|
@@ -227,49 +248,61 @@ double getMachTimeInMilliseconds()
|
|
|
te = (IOHIDElementRef)CFRetain(element);
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
- (IOHIDElementRef)element
|
|
|
{
|
|
|
return e;
|
|
|
}
|
|
|
+
|
|
|
- (IOHIDElementCookie)cookie
|
|
|
{
|
|
|
return IOHIDElementGetCookie(e);
|
|
|
}
|
|
|
+
|
|
|
- (IOHIDElementRef)triggerElement
|
|
|
{
|
|
|
return te;
|
|
|
}
|
|
|
+
|
|
|
- (IOHIDElementCookie)triggerCookie
|
|
|
{
|
|
|
return IOHIDElementGetCookie(te);
|
|
|
}
|
|
|
+
|
|
|
- (bool)isTriggerButton
|
|
|
{
|
|
|
return (te != NULL);
|
|
|
}
|
|
|
+
|
|
|
- (uint32_t)usage
|
|
|
{
|
|
|
return IOHIDElementGetUsage(e);
|
|
|
}
|
|
|
+
|
|
|
- (uint32_t)usagePage
|
|
|
{
|
|
|
return IOHIDElementGetUsagePage(e);
|
|
|
}
|
|
|
+
|
|
|
- (void)setStateValue:(int)value {
|
|
|
triggerValue = value;
|
|
|
}
|
|
|
+
|
|
|
- (int)stateValue
|
|
|
{
|
|
|
return triggerValue;
|
|
|
}
|
|
|
+
|
|
|
- (float)calibratedStateValue
|
|
|
{
|
|
|
return (float)triggerValue / 255.0f;
|
|
|
}
|
|
|
+
|
|
|
- (bool)state
|
|
|
{
|
|
|
return state;
|
|
|
}
|
|
|
+
|
|
|
- (void)setState:(bool)s
|
|
|
{
|
|
|
state = s;
|
|
|
@@ -280,15 +313,17 @@ double getMachTimeInMilliseconds()
|
|
|
{
|
|
|
IOHIDDeviceRef hidDeviceRef;
|
|
|
IOHIDQueueRef queueRef;
|
|
|
- NSMutableArray *buttons;
|
|
|
- NSMutableArray *triggerButtons;
|
|
|
- NSMutableArray *axes;
|
|
|
+ NSMutableArray* buttons;
|
|
|
+ NSMutableArray* triggerButtons;
|
|
|
+ NSMutableArray* axes;
|
|
|
+ HIDGamepadAxis* hatSwitch;
|
|
|
}
|
|
|
@property (assign) IOHIDDeviceRef hidDeviceRef;
|
|
|
@property (assign) IOHIDQueueRef queueRef;
|
|
|
-@property (retain) NSMutableArray *buttons;
|
|
|
-@property (retain) NSMutableArray *triggerButtons;
|
|
|
-@property (retain) NSMutableArray *axes;
|
|
|
+@property (retain) NSMutableArray* buttons;
|
|
|
+@property (retain) NSMutableArray* triggerButtons;
|
|
|
+@property (retain) NSMutableArray* axes;
|
|
|
+@property (retain) HIDGamepadAxis* hatSwitch;
|
|
|
|
|
|
- initWithDevice:(IOHIDDeviceRef)rawDevice;
|
|
|
- (IOHIDDeviceRef)rawDevice;
|
|
|
@@ -300,10 +335,11 @@ double getMachTimeInMilliseconds()
|
|
|
- (bool)startListening;
|
|
|
- (void)stopListening;
|
|
|
|
|
|
-- (NSString *)identifierName;
|
|
|
-- (NSString *)productName;
|
|
|
-- (NSString *)manufacturerName;
|
|
|
-- (NSString *)serialNumber;
|
|
|
+- (NSString*)identifierName;
|
|
|
+- (NSString*)productName;
|
|
|
+- (NSString*)manufacturerName;
|
|
|
+- (NSString*)serialNumber;
|
|
|
+- (int)versionNumber;
|
|
|
- (int)vendorID;
|
|
|
- (int)productID;
|
|
|
|
|
|
@@ -314,6 +350,7 @@ double getMachTimeInMilliseconds()
|
|
|
- (HIDGamepadAxis*)axisAtIndex:(NSUInteger)index;
|
|
|
- (HIDGamepadButton*)buttonAtIndex:(NSUInteger)index;
|
|
|
- (HIDGamepadButton*)triggerButtonAtIndex:(NSUInteger)index;
|
|
|
+- (HIDGamepadAxis*)getHatSwitch;
|
|
|
@end
|
|
|
|
|
|
@implementation HIDGamepad
|
|
|
@@ -323,6 +360,7 @@ double getMachTimeInMilliseconds()
|
|
|
@synthesize buttons;
|
|
|
@synthesize triggerButtons;
|
|
|
@synthesize axes;
|
|
|
+@synthesize hatSwitch;
|
|
|
|
|
|
- initWithDevice:(IOHIDDeviceRef)rawDevice
|
|
|
{
|
|
|
@@ -331,6 +369,7 @@ double getMachTimeInMilliseconds()
|
|
|
[self setButtons:[NSMutableArray array]];
|
|
|
[self setTriggerButtons:[NSMutableArray array]];
|
|
|
[self setAxes:[NSMutableArray array]];
|
|
|
+ hatSwitch = NULL;
|
|
|
|
|
|
CFRetain(rawDevice);
|
|
|
IOHIDQueueRef queue = IOHIDQueueCreate(CFAllocatorGetDefault(), rawDevice, 10, kIOHIDOptionsTypeNone);
|
|
|
@@ -342,6 +381,7 @@ double getMachTimeInMilliseconds()
|
|
|
}
|
|
|
return self;
|
|
|
}
|
|
|
+
|
|
|
- (void)dealloc
|
|
|
{
|
|
|
[self stopListening];
|
|
|
@@ -354,12 +394,19 @@ double getMachTimeInMilliseconds()
|
|
|
[self setButtons:NULL];
|
|
|
[self setTriggerButtons:NULL];
|
|
|
[self setAxes:NULL];
|
|
|
+ if (hatSwitch != NULL)
|
|
|
+ {
|
|
|
+ [hatSwitch dealloc];
|
|
|
+ }
|
|
|
+
|
|
|
[super dealloc];
|
|
|
}
|
|
|
+
|
|
|
- (IOHIDDeviceRef)rawDevice
|
|
|
{
|
|
|
return [self hidDeviceRef];
|
|
|
}
|
|
|
+
|
|
|
- (NSNumber*)locationID
|
|
|
{
|
|
|
return (NSNumber*)IOHIDDeviceGetProperty([self rawDevice], CFSTR(kIOHIDLocationIDKey));
|
|
|
@@ -400,11 +447,17 @@ double getMachTimeInMilliseconds()
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- HIDGamepadAxis *axis = [HIDGamepadAxis gamepadAxisWithAxisElement:hidElement];
|
|
|
+ HIDGamepadAxis* axis = [HIDGamepadAxis gamepadAxisWithAxisElement:hidElement];
|
|
|
[[self axes] addObject:axis];
|
|
|
}
|
|
|
break;
|
|
|
}
|
|
|
+ case kHIDUsage_GD_Hatswitch:
|
|
|
+ {
|
|
|
+ HIDGamepadAxis* hat = [[HIDGamepadAxis alloc] initWithAxisElement:hidElement];
|
|
|
+ [hat setValue: -1];
|
|
|
+ hatSwitch = hat;
|
|
|
+ }
|
|
|
default:
|
|
|
// Ignore the pointers
|
|
|
// Note: Some of the pointers are for the 6-axis accelerometer in a PS3 controller
|
|
|
@@ -428,30 +481,24 @@ double getMachTimeInMilliseconds()
|
|
|
IOHIDElementCookie cookie = IOHIDElementGetCookie(hidElement);
|
|
|
|
|
|
// Gamepad specific code
|
|
|
- // Not sure if there is a better way to associate buttons and misc hid elements :/
|
|
|
if(vendorID == SONY_USB_VENDOR_ID && productID == SONY_USB_PS3_PRODUCT_ID)
|
|
|
{
|
|
|
if((unsigned long)cookie == 39)
|
|
|
{
|
|
|
- //[self buttonAtIndex:8];
|
|
|
HIDGamepadButton *leftTriggerButton = [self buttonWithCookie:(IOHIDElementCookie)9];
|
|
|
if(leftTriggerButton)
|
|
|
{
|
|
|
[leftTriggerButton setTriggerElement:hidElement];
|
|
|
[[self triggerButtons] addObject:leftTriggerButton];
|
|
|
- // I would have thought this would work but it seems to mess things up, even after re-mapping the buttons.
|
|
|
- //[[self buttons] removeObject:leftTriggerButton];
|
|
|
}
|
|
|
}
|
|
|
if((unsigned long)cookie == 40)
|
|
|
{
|
|
|
- //[self buttonAtIndex:9];
|
|
|
HIDGamepadButton *rightTriggerButton = [self buttonWithCookie:(IOHIDElementCookie)10];
|
|
|
if(rightTriggerButton)
|
|
|
{
|
|
|
[rightTriggerButton setTriggerElement:hidElement];
|
|
|
[[self triggerButtons] addObject:rightTriggerButton];
|
|
|
- //[[self buttons] removeObject:rightTriggerButton];
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
@@ -488,6 +535,7 @@ double getMachTimeInMilliseconds()
|
|
|
|
|
|
return true;
|
|
|
}
|
|
|
+
|
|
|
- (void)stopListening
|
|
|
{
|
|
|
IOHIDQueueUnscheduleFromRunLoop([self queueRef], CFRunLoopGetCurrent(), kCFRunLoopDefaultMode);
|
|
|
@@ -497,9 +545,9 @@ double getMachTimeInMilliseconds()
|
|
|
IOHIDDeviceClose([self hidDeviceRef], kIOHIDOptionsTypeNone);
|
|
|
}
|
|
|
|
|
|
-- (NSString *)identifierName
|
|
|
+- (NSString*)identifierName
|
|
|
{
|
|
|
- NSString *idName = NULL;
|
|
|
+ NSString* idName = NULL;
|
|
|
if(idName == NULL) idName = [self productName];
|
|
|
if(idName == NULL) idName = [self manufacturerName];
|
|
|
if(idName == NULL) idName = [self serialNumber];
|
|
|
@@ -507,51 +555,66 @@ double getMachTimeInMilliseconds()
|
|
|
return idName;
|
|
|
}
|
|
|
|
|
|
-- (NSString *)productName {
|
|
|
+- (NSString*)productName
|
|
|
+{
|
|
|
CFStringRef productName = (CFStringRef)IOHIDDeviceGetProperty([self rawDevice], CFSTR(kIOHIDProductKey));
|
|
|
- if(productName == NULL || CFGetTypeID(productName) != CFStringGetTypeID()) {
|
|
|
+ if(productName == NULL || CFGetTypeID(productName) != CFStringGetTypeID())
|
|
|
+ {
|
|
|
return NULL;
|
|
|
}
|
|
|
return (NSString*)productName;
|
|
|
}
|
|
|
-- (NSString *)manufacturerName {
|
|
|
+
|
|
|
+- (NSString*)manufacturerName
|
|
|
+{
|
|
|
CFStringRef manufacturerName = (CFStringRef)IOHIDDeviceGetProperty([self rawDevice], CFSTR(kIOHIDManufacturerKey));
|
|
|
- if(manufacturerName == NULL || CFGetTypeID(manufacturerName) != CFStringGetTypeID()) {
|
|
|
+ if(manufacturerName == NULL || CFGetTypeID(manufacturerName) != CFStringGetTypeID())
|
|
|
+ {
|
|
|
return NULL;
|
|
|
}
|
|
|
return (NSString*)manufacturerName;
|
|
|
}
|
|
|
-- (NSString *)serialNumber {
|
|
|
+
|
|
|
+- (NSString*)serialNumber
|
|
|
+{
|
|
|
CFStringRef serialNumber = (CFStringRef)IOHIDDeviceGetProperty([self rawDevice], CFSTR(kIOHIDSerialNumberKey));
|
|
|
- if(serialNumber == NULL || CFGetTypeID(serialNumber) != CFStringGetTypeID()) {
|
|
|
+ if(serialNumber == NULL || CFGetTypeID(serialNumber) != CFStringGetTypeID())
|
|
|
+ {
|
|
|
return NULL;
|
|
|
}
|
|
|
return (NSString*)serialNumber;
|
|
|
}
|
|
|
|
|
|
+- (int)versionNumber
|
|
|
+{
|
|
|
+ return IOHIDDeviceGetIntProperty([self rawDevice], CFSTR(kIOHIDVersionNumberKey));
|
|
|
+}
|
|
|
|
|
|
- (int)vendorID
|
|
|
{
|
|
|
return IOHIDDeviceGetIntProperty([self rawDevice], CFSTR(kIOHIDVendorIDKey));
|
|
|
}
|
|
|
+
|
|
|
- (int)productID
|
|
|
{
|
|
|
return IOHIDDeviceGetIntProperty([self rawDevice], CFSTR(kIOHIDProductIDKey));
|
|
|
}
|
|
|
|
|
|
-
|
|
|
- (NSUInteger)numberOfAxes
|
|
|
{
|
|
|
return [[self axes] count];
|
|
|
}
|
|
|
+
|
|
|
- (NSUInteger)numberOfSticks
|
|
|
{
|
|
|
return ([[self axes] count] / 2);
|
|
|
}
|
|
|
+
|
|
|
- (NSUInteger)numberOfButtons
|
|
|
{
|
|
|
return [[self buttons] count];
|
|
|
}
|
|
|
+
|
|
|
- (NSUInteger)numberOfTriggerButtons
|
|
|
{
|
|
|
return [[self triggerButtons] count];
|
|
|
@@ -576,6 +639,7 @@ double getMachTimeInMilliseconds()
|
|
|
}
|
|
|
return a;
|
|
|
}
|
|
|
+
|
|
|
- (HIDGamepadButton*)buttonAtIndex:(NSUInteger)index
|
|
|
{
|
|
|
HIDGamepadButton *b = NULL;
|
|
|
@@ -585,6 +649,16 @@ double getMachTimeInMilliseconds()
|
|
|
}
|
|
|
return b;
|
|
|
}
|
|
|
+
|
|
|
+- (HIDGamepadAxis*)getHatSwitch
|
|
|
+{
|
|
|
+ if (hatSwitch != NULL)
|
|
|
+ {
|
|
|
+ return hatSwitch;
|
|
|
+ }
|
|
|
+ return NULL;
|
|
|
+}
|
|
|
+
|
|
|
- (NSArray*)watchedElements
|
|
|
{
|
|
|
NSMutableArray *r = [NSMutableArray array];
|
|
|
@@ -600,6 +674,10 @@ double getMachTimeInMilliseconds()
|
|
|
{
|
|
|
[r addObject:(id)[t triggerElement]];
|
|
|
}
|
|
|
+ if (hatSwitch)
|
|
|
+ {
|
|
|
+ [r addObject:(id)[hatSwitch element]];
|
|
|
+ }
|
|
|
return [NSArray arrayWithArray:r];
|
|
|
}
|
|
|
|
|
|
@@ -637,9 +715,11 @@ double getMachTimeInMilliseconds()
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ if (hatSwitch && [hatSwitch cookie] == cookie)
|
|
|
+ {
|
|
|
+ [hatSwitch setValue:integerValue];
|
|
|
+ }
|
|
|
}
|
|
|
-
|
|
|
-
|
|
|
@end
|
|
|
|
|
|
|
|
|
@@ -1864,7 +1944,6 @@ bool Platform::isGestureRegistered(Gesture::GestureEvent evt)
|
|
|
void Platform::pollGamepadState(Gamepad* gamepad)
|
|
|
{
|
|
|
HIDGamepad* gp = gamepadForGameHandle(gamepad->_handle);
|
|
|
-
|
|
|
if (gp)
|
|
|
{
|
|
|
// Haven't figured out how to have the triggers not also show up in the buttons array.
|
|
|
@@ -1908,6 +1987,35 @@ void Platform::pollGamepadState(Gamepad* gamepad)
|
|
|
Gamepad::BUTTON_Y
|
|
|
};
|
|
|
|
|
|
+ static const int SteelSeriesFreeMapping[13] = {
|
|
|
+ Gamepad::BUTTON_A,
|
|
|
+ Gamepad::BUTTON_B,
|
|
|
+ -1,
|
|
|
+ Gamepad::BUTTON_X,
|
|
|
+ Gamepad::BUTTON_Y,
|
|
|
+ -1,
|
|
|
+ Gamepad::BUTTON_L1,
|
|
|
+ Gamepad::BUTTON_R1,
|
|
|
+ -1, -1, -1,
|
|
|
+ Gamepad::BUTTON_MENU2,
|
|
|
+ Gamepad::BUTTON_MENU1
|
|
|
+ };
|
|
|
+
|
|
|
+ static const int GametelMapping103[12] = {
|
|
|
+ Gamepad::BUTTON_B,
|
|
|
+ Gamepad::BUTTON_X,
|
|
|
+ Gamepad::BUTTON_Y,
|
|
|
+ Gamepad::BUTTON_A,
|
|
|
+ Gamepad::BUTTON_L1,
|
|
|
+ Gamepad::BUTTON_R1,
|
|
|
+ Gamepad::BUTTON_MENU1,
|
|
|
+ Gamepad::BUTTON_MENU2,
|
|
|
+ Gamepad::BUTTON_RIGHT,
|
|
|
+ Gamepad::BUTTON_LEFT,
|
|
|
+ Gamepad::BUTTON_DOWN,
|
|
|
+ Gamepad::BUTTON_UP
|
|
|
+ };
|
|
|
+
|
|
|
const int* mapping = NULL;
|
|
|
float axisDeadZone = 0.0f;
|
|
|
if (gamepad->_vendorId == SONY_USB_VENDOR_ID &&
|
|
|
@@ -1922,9 +2030,25 @@ void Platform::pollGamepadState(Gamepad* gamepad)
|
|
|
mapping = XBox360Mapping;
|
|
|
axisDeadZone = 0.2f;
|
|
|
}
|
|
|
+ else if (gamepad->_vendorId == STEELSERIES_VENDOR_ID &&
|
|
|
+ gamepad->_productId == STEELSERIES_FREE_PRODUCT_ID)
|
|
|
+ {
|
|
|
+ mapping = SteelSeriesFreeMapping;
|
|
|
+ axisDeadZone = 0.005f;
|
|
|
+ }
|
|
|
+ else if (gamepad->_vendorId == FRUCTEL_VENDOR_ID &&
|
|
|
+ gamepad->_productId == FRUCTEL_GAMETEL_PRODUCT_ID)
|
|
|
+ {
|
|
|
+ int ver = [gp versionNumber];
|
|
|
+ int major = ver >> 8;
|
|
|
+ int minor = ver & 0x00ff;
|
|
|
+ if (major >= 1 && minor > 1)
|
|
|
+ {
|
|
|
+ mapping = GametelMapping103;
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
gamepad->_buttons = 0;
|
|
|
-
|
|
|
for (int i = 0; i < [gp numberOfButtons]; ++i)
|
|
|
{
|
|
|
HIDGamepadButton* b = [gp buttonAtIndex: i];
|
|
|
@@ -1943,6 +2067,41 @@ void Platform::pollGamepadState(Gamepad* gamepad)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ HIDGamepadAxis* hatSwitch = [gp getHatSwitch];
|
|
|
+ if (hatSwitch != NULL)
|
|
|
+ {
|
|
|
+ CFIndex v = [hatSwitch value];
|
|
|
+ switch (v)
|
|
|
+ {
|
|
|
+ case -1:
|
|
|
+ break;
|
|
|
+ case 0:
|
|
|
+ gamepad->_buttons |= (1 << Gamepad::BUTTON_UP);
|
|
|
+ break;
|
|
|
+ case 1:
|
|
|
+ gamepad->_buttons |= (1 << Gamepad::BUTTON_UP) | (1 << Gamepad::BUTTON_RIGHT);
|
|
|
+ break;
|
|
|
+ case 2:
|
|
|
+ gamepad->_buttons |= (1 << Gamepad::BUTTON_RIGHT);
|
|
|
+ break;
|
|
|
+ case 3:
|
|
|
+ gamepad->_buttons |= (1 << Gamepad::BUTTON_RIGHT) | (1 << Gamepad::BUTTON_DOWN);
|
|
|
+ break;
|
|
|
+ case 4:
|
|
|
+ gamepad->_buttons |= (1 << Gamepad::BUTTON_DOWN);
|
|
|
+ break;
|
|
|
+ case 5:
|
|
|
+ gamepad->_buttons |= (1 << Gamepad::BUTTON_DOWN) | (1 << Gamepad::BUTTON_LEFT);
|
|
|
+ break;
|
|
|
+ case 6:
|
|
|
+ gamepad->_buttons |= (1 << Gamepad::BUTTON_LEFT);
|
|
|
+ break;
|
|
|
+ case 7:
|
|
|
+ gamepad->_buttons |= (1 << Gamepad::BUTTON_LEFT) | (1 << Gamepad::BUTTON_UP);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
for (unsigned int i = 0; i < [gp numberOfSticks]; ++i)
|
|
|
{
|
|
|
float rawX = [[gp axisAtIndex: i*2] calibratedValue];
|
|
|
@@ -2074,10 +2233,10 @@ static void hidDeviceDiscoveredCallback(void* inContext, IOReturn inResult, void
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-static void hidDeviceRemovalCallback(void* inContext, IOReturn inResult, void* inSender, IOHIDDeviceRef inIOHIDDeviceRef)
|
|
|
+static void hidDeviceRemovalCallback(void* inContext, IOReturn inResult, void* inSender, IOHIDDeviceRef device)
|
|
|
{
|
|
|
int removeIndex = -1;
|
|
|
- NSNumber *locID = (NSNumber*)IOHIDDeviceGetProperty(inIOHIDDeviceRef, CFSTR(kIOHIDLocationIDKey));
|
|
|
+ NSNumber *locID = (NSNumber*)IOHIDDeviceGetProperty(device, CFSTR(kIOHIDLocationIDKey));
|
|
|
if(locID)
|
|
|
{
|
|
|
for(int i = 0; i < [__gamepads count]; i++)
|