00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "OSX_Gamepad.h"
00025
00026
00027 static const UInt32 Logitech_F710_VendorID = 0x046D;
00028 static const UInt32 Logitech_F710_ProductID = 0xC219;
00029
00030 static const UInt32 Sony_DualShock3_VendorID = 0x054C;
00031 static const UInt32 Sony_DualShock3_ProductID = 0x0268;
00032
00033
00034 namespace OVR { namespace Platform { namespace OSX {
00035
00036
00037 GamepadManager::GamepadManager()
00038 : bStateChanged(false)
00039 {
00040
00041 HidManager = IOHIDManagerCreate(kCFAllocatorDefault, kIOHIDOptionsTypeNone);
00042 IOHIDManagerOpen(HidManager, kIOHIDOptionsTypeNone);
00043 IOHIDManagerScheduleWithRunLoop(HidManager,
00044 CFRunLoopGetCurrent(),
00045 kCFRunLoopDefaultMode);
00046
00047
00048
00049 CFStringRef keys[] = { CFSTR(kIOHIDDeviceUsagePageKey),
00050 CFSTR(kIOHIDDeviceUsageKey)};
00051
00052 int value;
00053 CFNumberRef values[2];
00054 CFDictionaryRef dictionaries[2];
00055
00056
00057 value = kHIDPage_GenericDesktop;
00058 values[0] = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &value);
00059
00060 value = kHIDUsage_GD_Joystick;
00061 values[1] = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &value);
00062
00063 dictionaries[0] = CFDictionaryCreate(kCFAllocatorDefault,
00064 (const void **) keys,
00065 (const void **) values,
00066 2,
00067 &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
00068 CFRelease(values[0]);
00069 CFRelease(values[1]);
00070
00071
00072 value = kHIDPage_GenericDesktop;
00073 values[0] = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &value);
00074
00075 value = kHIDUsage_GD_GamePad;
00076 values[1] = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &value);
00077
00078 dictionaries[1] = CFDictionaryCreate(kCFAllocatorDefault,
00079 (const void **) keys,
00080 (const void **) values,
00081 2,
00082 &kCFTypeDictionaryKeyCallBacks,
00083 &kCFTypeDictionaryValueCallBacks);
00084 CFRelease(values[0]);
00085 CFRelease(values[1]);
00086
00087 CFArrayRef array = CFArrayCreate( kCFAllocatorDefault,
00088 (const void **) dictionaries,
00089 2,
00090 &kCFTypeArrayCallBacks);
00091 CFRelease(dictionaries[0]);
00092 CFRelease(dictionaries[1]);
00093
00094 IOHIDManagerSetDeviceMatchingMultiple(HidManager, array);
00095
00096 CFRelease(array);
00097
00098
00099 IOHIDManagerRegisterDeviceMatchingCallback(HidManager, staticOnDeviceMatched, this);
00100 IOHIDManagerRegisterDeviceRemovalCallback(HidManager, staticOnDeviceRemoved, this);
00101
00102 }
00103
00104 GamepadManager::~GamepadManager()
00105 {
00106 CFRelease(HidManager);
00107 }
00108
00109 UInt32 GamepadManager::GetGamepadCount()
00110 {
00111 return 1;
00112 }
00113
00114 bool GamepadManager::GetGamepadState(UInt32 index, GamepadState* pState)
00115 {
00116
00117 OVR_UNUSED(index);
00118
00119 if (!bStateChanged)
00120 {
00121 return false;
00122 }
00123
00124 bStateChanged = false;
00125
00126
00127 *pState = State;
00128 return true;
00129 }
00130
00131 int GamepadManager::getIntDeviceProperty(IOHIDDeviceRef device, CFStringRef key)
00132 {
00133 CFTypeRef type = IOHIDDeviceGetProperty(device, key);
00134 OVR_ASSERT(type != NULL && CFGetTypeID(type) == CFNumberGetTypeID());
00135
00136 int value;
00137 CFNumberGetValue((CFNumberRef) type, kCFNumberSInt32Type, &value);
00138
00139 return value;
00140 }
00141
00142 void GamepadManager::staticOnDeviceMatched(void* context, IOReturn result, void* sender, IOHIDDeviceRef device)
00143 {
00144 GamepadManager* pManager = (GamepadManager*) context;
00145 pManager->onDeviceMatched(device);
00146 }
00147
00148 void GamepadManager::onDeviceMatched(IOHIDDeviceRef device)
00149 {
00150 IOHIDDeviceRegisterInputValueCallback(device, staticOnDeviceValueChanged, this);
00151 }
00152
00153 void GamepadManager::staticOnDeviceRemoved(void* context, IOReturn result, void* sender, IOHIDDeviceRef device)
00154 {
00155 GamepadManager* pManager = (GamepadManager*) context;
00156 pManager->onDeviceRemoved(device);
00157 }
00158
00159 void GamepadManager::onDeviceRemoved(IOHIDDeviceRef device)
00160 {
00161 IOHIDDeviceRegisterInputValueCallback(device, NULL, NULL);
00162 }
00163
00164 void GamepadManager::staticOnDeviceValueChanged(void* context, IOReturn result, void* sender, IOHIDValueRef value)
00165 {
00166 GamepadManager* pManager = (GamepadManager*) context;
00167 pManager->onDeviceValueChanged(value);
00168 }
00169
00170 float GamepadManager::mapAnalogAxis(IOHIDValueRef value, IOHIDElementRef element)
00171 {
00172
00173 CFIndex val = IOHIDValueGetIntegerValue(value);
00174 CFIndex min = IOHIDElementGetLogicalMin(element);
00175 CFIndex max = IOHIDElementGetLogicalMax(element);
00176
00177 float v = (float) (val - min) / (float) (max - min);
00178 v = v * 2.0f - 1.0f;
00179
00180
00181 if (v < 0.1f && v > -0.1f)
00182 {
00183 v = 0.0f;
00184 }
00185
00186 return v;
00187 }
00188
00189 bool GamepadManager::setStateIfDifferent(float& state, float newState)
00190 {
00191 if (state == newState)
00192 return false;
00193
00194 state = newState;
00195
00196 return true;
00197 }
00198
00199 void GamepadManager::onDeviceValueChanged(IOHIDValueRef value)
00200 {
00201
00202 IOHIDElementRef element = IOHIDValueGetElement(value);
00203 IOHIDDeviceRef device = IOHIDElementGetDevice(element);
00204
00205 int vendorID = getIntDeviceProperty(device, CFSTR(kIOHIDVendorIDKey));
00206 int productID = getIntDeviceProperty(device, CFSTR(kIOHIDProductIDKey));
00207 OVR_UNUSED(productID);
00208
00209 uint32_t usagePage = IOHIDElementGetUsagePage(element);
00210 uint32_t usage = IOHIDElementGetUsage(element);
00211
00212
00213
00214 if (vendorID == Logitech_F710_VendorID)
00215 {
00216
00217 if (usagePage == kHIDPage_Button)
00218 {
00219 bool buttonState = IOHIDValueGetIntegerValue(value);
00220
00221 switch(usage)
00222 {
00223 case kHIDUsage_Button_1:
00224 manipulateBitField(State.Buttons, Gamepad_X, buttonState);
00225 break;
00226 case kHIDUsage_Button_2:
00227 manipulateBitField(State.Buttons, Gamepad_A, buttonState);
00228 break;
00229 case kHIDUsage_Button_3:
00230 manipulateBitField(State.Buttons, Gamepad_B, buttonState);
00231 break;
00232 case kHIDUsage_Button_4:
00233 manipulateBitField(State.Buttons, Gamepad_Y, buttonState);
00234 break;
00235 case 0x05:
00236 manipulateBitField(State.Buttons, Gamepad_L1, buttonState);
00237 break;
00238 case 0x06:
00239 manipulateBitField(State.Buttons, Gamepad_R1, buttonState);
00240 break;
00241 case 0x07:
00242 State.LT = buttonState ? 1.0f:0.0f;
00243 break;
00244 case 0x08:
00245 State.RT = buttonState ? 1.0f:0.0f;
00246 break;
00247 case 0x09:
00248 manipulateBitField(State.Buttons, Gamepad_Back, buttonState);
00249 break;
00250 case 0x0A:
00251 manipulateBitField(State.Buttons, Gamepad_Start, buttonState);
00252 break;
00253 case 0x0B:
00254 manipulateBitField(State.Buttons, Gamepad_LStick, buttonState);
00255 break;
00256 case 0x0C:
00257 manipulateBitField(State.Buttons, Gamepad_RStick, buttonState);
00258 break;
00259 default:
00260 return;
00261 }
00262 }
00263 else if (usagePage == kHIDPage_GenericDesktop)
00264 {
00265 float v;
00266 switch(usage)
00267 {
00268 case kHIDUsage_GD_X:
00269 v = mapAnalogAxis(value, element);
00270 if (!setStateIfDifferent(State.LX, v))
00271 return;
00272 break;
00273 case kHIDUsage_GD_Y:
00274 v = mapAnalogAxis(value, element);
00275 if (!setStateIfDifferent(State.LY, -v))
00276 return;
00277 break;
00278 case kHIDUsage_GD_Z:
00279 v = mapAnalogAxis(value, element);
00280 if (!setStateIfDifferent(State.RX, v))
00281 return;
00282 break;
00283 case kHIDUsage_GD_Rz:
00284 v = mapAnalogAxis(value, element);
00285 if (!setStateIfDifferent(State.RY, -v))
00286 return;
00287 break;
00288 case kHIDUsage_GD_Hatswitch:
00289 {
00290 CFIndex integerValue = IOHIDValueGetIntegerValue(value);
00291
00292 manipulateBitField(State.Buttons,
00293 Gamepad_Up,
00294 integerValue == 7 || integerValue == 0 || integerValue == 1);
00295 manipulateBitField(State.Buttons,
00296 Gamepad_Down,
00297 integerValue == 3 || integerValue == 4 || integerValue == 5);
00298 manipulateBitField(State.Buttons,
00299 Gamepad_Left,
00300 integerValue == 5 || integerValue == 6 || integerValue == 7);
00301 manipulateBitField(State.Buttons,
00302 Gamepad_Right,
00303 integerValue == 1 || integerValue == 2 || integerValue == 3);
00304 }
00305 break;
00306 default:
00307 return;
00308 }
00309 }
00310 }
00311
00312
00313 else if (vendorID == Sony_DualShock3_VendorID)
00314 {
00315
00316 if (usagePage == kHIDPage_Button)
00317 {
00318 bool buttonState = IOHIDValueGetIntegerValue(value);
00319
00320 switch(usage)
00321 {
00322 case kHIDUsage_Button_1:
00323 manipulateBitField(State.Buttons, Gamepad_Back, buttonState);
00324 break;
00325 case kHIDUsage_Button_2:
00326 manipulateBitField(State.Buttons, Gamepad_LStick, buttonState);
00327 break;
00328 case kHIDUsage_Button_3:
00329 manipulateBitField(State.Buttons, Gamepad_RStick, buttonState);
00330 break;
00331 case kHIDUsage_Button_4:
00332 manipulateBitField(State.Buttons, Gamepad_Start, buttonState);
00333 break;
00334 case 0x05:
00335 manipulateBitField(State.Buttons, Gamepad_Up, buttonState);
00336 break;
00337 case 0x06:
00338 manipulateBitField(State.Buttons, Gamepad_Right, buttonState);
00339 break;
00340 case 0x07:
00341 manipulateBitField(State.Buttons, Gamepad_Down, buttonState);
00342 break;
00343 case 0x08:
00344 manipulateBitField(State.Buttons, Gamepad_Left, buttonState);
00345 break;
00346 case 0x09:
00347 State.LT = buttonState ? 1.0f:0.0f;
00348 break;
00349 case 0x0A:
00350 State.RT = buttonState ? 1.0f:0.0f;
00351 break;
00352 case 0x0B:
00353 manipulateBitField(State.Buttons, Gamepad_L1, buttonState);
00354 break;
00355 case 0x0C:
00356 manipulateBitField(State.Buttons, Gamepad_R1, buttonState);
00357 break;
00358 case 0x0D:
00359
00360 manipulateBitField(State.Buttons, Gamepad_TRIANGLE, buttonState);
00361 break;
00362 case 0x0E:
00363
00364 manipulateBitField(State.Buttons, Gamepad_CIRCLE, buttonState);
00365 break;
00366 case 0x0F:
00367
00368 manipulateBitField(State.Buttons, Gamepad_CROSS, buttonState);
00369 break;
00370 case 0x10:
00371
00372 manipulateBitField(State.Buttons, Gamepad_SQUARE, buttonState);
00373 break;
00374 default:
00375 return;
00376 }
00377 }
00378 else if (usagePage == kHIDPage_GenericDesktop)
00379 {
00380 float v;
00381 switch(usage)
00382 {
00383 case kHIDUsage_GD_X:
00384 v = mapAnalogAxis(value, element);
00385 if (!setStateIfDifferent(State.LX, v))
00386 return;
00387 break;
00388 case kHIDUsage_GD_Y:
00389 v = mapAnalogAxis(value, element);
00390 if (!setStateIfDifferent(State.LY, -v))
00391 return;
00392 break;
00393 case kHIDUsage_GD_Z:
00394 v = mapAnalogAxis(value, element);
00395 if (!setStateIfDifferent(State.RX, v))
00396 return;
00397 break;
00398 case kHIDUsage_GD_Rz:
00399 v = mapAnalogAxis(value, element);
00400 if (!setStateIfDifferent(State.RY, -v))
00401 return;
00402 break;
00403 default:
00404 return;
00405 }
00406 }
00407 }
00408
00409 bStateChanged = true;
00410 }
00411
00412 void GamepadManager::manipulateBitField(unsigned int& bitfield, unsigned int mask, bool val)
00413 {
00414 if (val)
00415 {
00416 bitfield |= mask;
00417 }
00418 else
00419 {
00420 bitfield &= ~mask;
00421 }
00422 }
00423
00424 }}}