Пример #1
0
static void * deviceThread(void * context) {
	unsigned int gamepadIndex;
	struct Gamepad_device * device;
	struct Gamepad_devicePrivate * devicePrivate;
	struct input_event event;
	
	device = context;
	devicePrivate = device->privateData;
	
	while (read(devicePrivate->fd, &event, sizeof(struct input_event)) > 0) {
		if (event.type == EV_ABS) {
			float value;
			
			if (event.code > ABS_MAX || devicePrivate->axisMap[event.code] == -1) {
				continue;
			}
			
			value = (event.value - devicePrivate->axisInfo[event.code].minimum) / (float) (devicePrivate->axisInfo[event.code].maximum - devicePrivate->axisInfo[event.code].minimum) * 2.0f - 1.0f;
			queueAxisEvent(device,
			               event.time.tv_sec + event.time.tv_usec * 0.000001,
			               devicePrivate->axisMap[event.code],
			               value,
			               device->axisStates[devicePrivate->axisMap[event.code]]);
			
			device->axisStates[devicePrivate->axisMap[event.code]] = value;
			
		} else if (event.type == EV_KEY) {
			if (event.code < BTN_MISC || event.code > KEY_MAX || devicePrivate->buttonMap[event.code - BTN_MISC] == -1) {
				continue;
			}
			
			queueButtonEvent(device,
			                 event.time.tv_sec + event.time.tv_usec * 0.000001,
			                 devicePrivate->buttonMap[event.code - BTN_MISC],
			                 !!event.value);
			
			device->buttonStates[devicePrivate->buttonMap[event.code - BTN_MISC]] = !!event.value;
		}
	}
	
	queueEvent(device->deviceID, GAMEPAD_EVENT_DEVICE_REMOVED, device);
	
	pthread_mutex_lock(&devicesMutex);
	for (gamepadIndex = 0; gamepadIndex < numDevices; gamepadIndex++) {
		if (devices[gamepadIndex] == device) {
			unsigned int gamepadIndex2;
			
			numDevices--;
			for (gamepadIndex2 = gamepadIndex; gamepadIndex2 < numDevices; gamepadIndex2++) {
				devices[gamepadIndex2] = devices[gamepadIndex2 + 1];
			}
			gamepadIndex--;
		}
	}
	pthread_mutex_unlock(&devicesMutex);
	
	return NULL;
}
Пример #2
0
static void onDeviceValueChanged(void * context, IOReturn result, void * sender, IOHIDValueRef value) {
  struct Gamepad_device * deviceRecord;
  struct Gamepad_devicePrivate * hidDeviceRecord;
  IOHIDElementRef element;
  IOHIDElementCookie cookie;
  unsigned int axisIndex, buttonIndex;
  static mach_timebase_info_data_t timebaseInfo;
	
  if (timebaseInfo.denom == 0) {
    mach_timebase_info(&timebaseInfo);
  }
	
  deviceRecord = context;
  hidDeviceRecord = deviceRecord->privateData;
  element = IOHIDValueGetElement(value);
  cookie = IOHIDElementGetCookie(element);
	
  for (axisIndex = 0; axisIndex < deviceRecord->numAxes; axisIndex++) {
    if (!hidDeviceRecord->axisElements[axisIndex].isHatSwitchSecondAxis &&
        hidDeviceRecord->axisElements[axisIndex].cookie == cookie) {
      CFIndex integerValue;
			
      if (IOHIDValueGetLength(value) > 4) {
        // Workaround for a strange crash that occurs with PS3 controller; was getting lengths of 39 (!)
        continue;
      }
      integerValue = IOHIDValueGetIntegerValue(value);
			
      if (hidDeviceRecord->axisElements[axisIndex].isHatSwitch) {
        int x, y;
				
        // Fix for Saitek X52
        if (!hidDeviceRecord->axisElements[axisIndex].hasNullState) {
          if (integerValue < hidDeviceRecord->axisElements[axisIndex].logicalMin) {
            integerValue = hidDeviceRecord->axisElements[axisIndex].logicalMax - hidDeviceRecord->axisElements[axisIndex].logicalMin + 1;
          } else {
            integerValue--;
          }
        }
				
        hatValueToXY(integerValue, hidDeviceRecord->axisElements[axisIndex].logicalMax - hidDeviceRecord->axisElements[axisIndex].logicalMin + 1, &x, &y);
				
        if (x != deviceRecord->axisStates[axisIndex]) {
          queueAxisEvent(deviceRecord,
                         IOHIDValueGetTimeStamp(value) * timebaseInfo.numer / timebaseInfo.denom * 0.000000001,
                         axisIndex,
                         x,
                         deviceRecord->axisStates[axisIndex]);
					
          deviceRecord->axisStates[axisIndex] = x;
        }
				
        if (y != deviceRecord->axisStates[axisIndex + 1]) {
          queueAxisEvent(deviceRecord,
                         IOHIDValueGetTimeStamp(value) * timebaseInfo.numer / timebaseInfo.denom * 0.000000001,
                         axisIndex + 1,
                         y,
                         deviceRecord->axisStates[axisIndex + 1]);
					
          deviceRecord->axisStates[axisIndex + 1] = y;
        }
				
      } else {
        float floatValue;
				
        if (integerValue < hidDeviceRecord->axisElements[axisIndex].logicalMin) {
          hidDeviceRecord->axisElements[axisIndex].logicalMin = integerValue;
        }
        if (integerValue > hidDeviceRecord->axisElements[axisIndex].logicalMax) {
          hidDeviceRecord->axisElements[axisIndex].logicalMax = integerValue;
        }
        floatValue = (integerValue - hidDeviceRecord->axisElements[axisIndex].logicalMin) / (float) (hidDeviceRecord->axisElements[axisIndex].logicalMax - hidDeviceRecord->axisElements[axisIndex].logicalMin) * 2.0f - 1.0f;
				
        queueAxisEvent(deviceRecord,
                       IOHIDValueGetTimeStamp(value) * timebaseInfo.numer / timebaseInfo.denom * 0.000000001,
                       axisIndex,
                       floatValue,
                       deviceRecord->axisStates[axisIndex]);
				
        deviceRecord->axisStates[axisIndex] = floatValue;
      }
			
      return;
    }
  }
	
  for (buttonIndex = 0; buttonIndex < deviceRecord->numButtons; buttonIndex++) {
    if (hidDeviceRecord->buttonElements[buttonIndex].cookie == cookie) {
      bool down;
			
      down = IOHIDValueGetIntegerValue(value);
      queueButtonEvent(deviceRecord,
                       IOHIDValueGetTimeStamp(value) * timebaseInfo.numer / timebaseInfo.denom * 0.000000001,
                       buttonIndex,
                       down);
			
      deviceRecord->buttonStates[buttonIndex] = down;
			
      return;
    }
  }
}