Пример #1
0
static void processQueuedEvent(struct Gamepad_queuedEvent event) {
  switch (event.eventType) {
  case GAMEPAD_EVENT_DEVICE_ATTACHED:
    if (Gamepad_deviceAttachCallback != NULL) {
      Gamepad_deviceAttachCallback(event.eventData, Gamepad_deviceAttachContext);
    }
    break;
			
  case GAMEPAD_EVENT_DEVICE_REMOVED:
    if (Gamepad_deviceRemoveCallback != NULL) {
      Gamepad_deviceRemoveCallback(event.eventData, Gamepad_deviceRemoveContext);
    }
    break;
			
  case GAMEPAD_EVENT_BUTTON_DOWN:
    if (Gamepad_buttonDownCallback != NULL) {
      struct Gamepad_buttonEvent * buttonEvent = event.eventData;
      Gamepad_buttonDownCallback(buttonEvent->device, buttonEvent->buttonID, buttonEvent->timestamp, Gamepad_buttonDownContext);
    }
    break;
			
  case GAMEPAD_EVENT_BUTTON_UP:
    if (Gamepad_buttonUpCallback != NULL) {
      struct Gamepad_buttonEvent * buttonEvent = event.eventData;
      Gamepad_buttonUpCallback(buttonEvent->device, buttonEvent->buttonID, buttonEvent->timestamp, Gamepad_buttonUpContext);
    }
    break;
			
  case GAMEPAD_EVENT_AXIS_MOVED:
    if (Gamepad_axisMoveCallback != NULL) {
      struct Gamepad_axisEvent * axisEvent = event.eventData;
      Gamepad_axisMoveCallback(axisEvent->device, axisEvent->axisID, axisEvent->value, axisEvent->lastValue, axisEvent->timestamp, Gamepad_axisMoveContext);
    }
    break;
  }
}
Пример #2
0
void Gamepad_detectDevices() {
	struct input_id id;
	DIR * dev_input;
	struct dirent * entity;
	unsigned int charsConsumed;
	int num;
	int fd;
	int evCapBits[(EV_CNT - 1) / sizeof(int) * 8 + 1];
	int evKeyBits[(KEY_CNT - 1) / sizeof(int) * 8 + 1];
	int evAbsBits[(ABS_CNT - 1) / sizeof(int) * 8 + 1];
	char fileName[PATH_MAX];
	bool duplicate;
	unsigned int gamepadIndex;
	struct stat statBuf;
	struct Gamepad_device * deviceRecord;
	struct Gamepad_devicePrivate * deviceRecordPrivate;
	char name[128];
	char * description;
	int bit;
	time_t currentTime;
	static time_t lastInputStatTime;
	
	if (!inited) {
		return;
	}
	
	pthread_mutex_lock(&devicesMutex);
	
	dev_input = opendir("/dev/input");
	currentTime = time(NULL);
	if (dev_input != NULL) {
		while ((entity = readdir(dev_input)) != NULL) {
			charsConsumed = 0;
			if (sscanf(entity->d_name, "event%d%n", &num, &charsConsumed) && charsConsumed == strlen(entity->d_name)) {
				snprintf(fileName, PATH_MAX, "/dev/input/%s", entity->d_name);
				if (stat(fileName, &statBuf) || statBuf.st_mtime < lastInputStatTime) {
					continue;
				}
				
				duplicate = false;
				for (gamepadIndex = 0; gamepadIndex < numDevices; gamepadIndex++) {
					if (!strcmp(((struct Gamepad_devicePrivate *) devices[gamepadIndex]->privateData)->path, fileName)) {
						duplicate = true;
						break;
					}
				}
				if (duplicate) {
					continue;
				}
				
				fd = open(fileName, O_RDONLY, 0);
				memset(evCapBits, 0, sizeof(evCapBits));
				memset(evKeyBits, 0, sizeof(evKeyBits));
				memset(evAbsBits, 0, sizeof(evAbsBits));
				if (ioctl(fd, EVIOCGBIT(0, sizeof(evCapBits)), evCapBits) < 0 ||
				    ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(evKeyBits)), evKeyBits) < 0 ||
				    ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(evAbsBits)), evAbsBits) < 0) {
					close(fd);
					continue;
				}
				if (!test_bit(EV_KEY, evCapBits) || !test_bit(EV_ABS, evCapBits) ||
				    !test_bit(ABS_X, evAbsBits) || !test_bit(ABS_Y, evAbsBits) ||
				    (!test_bit(BTN_TRIGGER, evKeyBits) && !test_bit(BTN_A, evKeyBits) && !test_bit(BTN_1, evKeyBits))) {
					close(fd);
					continue;
				}
				
				deviceRecord = malloc(sizeof(struct Gamepad_device));
				deviceRecord->deviceID = nextDeviceID++;
				devices = realloc(devices, sizeof(struct Gamepad_device *) * (numDevices + 1));
				devices[numDevices++] = deviceRecord;
				
				deviceRecordPrivate = malloc(sizeof(struct Gamepad_devicePrivate));
				deviceRecordPrivate->fd = fd;
				deviceRecordPrivate->path = malloc(strlen(fileName) + 1);
				strcpy(deviceRecordPrivate->path, fileName);
				memset(deviceRecordPrivate->buttonMap, 0xFF, sizeof(deviceRecordPrivate->buttonMap));
				memset(deviceRecordPrivate->axisMap, 0xFF, sizeof(deviceRecordPrivate->axisMap));
				deviceRecord->privateData = deviceRecordPrivate;
				
				if (ioctl(fd, EVIOCGNAME(sizeof(name)), name) > 0) {
					description = malloc(strlen(name) + 1);
					strcpy(description, name);
				} else {
					description = malloc(strlen(fileName) + 1);
					strcpy(description, fileName);
				}
				deviceRecord->description = description;
				
				if (!ioctl(fd, EVIOCGID, &id)) {
					deviceRecord->vendorID = id.vendor;
					deviceRecord->productID = id.product;
				} else {
					deviceRecord->vendorID = deviceRecord->productID = 0;
				}
				
				memset(evKeyBits, 0, sizeof(evKeyBits));
				memset(evAbsBits, 0, sizeof(evAbsBits));
				ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(evKeyBits)), evKeyBits);
				ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(evAbsBits)), evAbsBits);
				
				deviceRecord->numAxes = 0;
				for (bit = 0; bit < ABS_CNT; bit++) {
					if (test_bit(bit, evAbsBits)) {
						if (ioctl(fd, EVIOCGABS(bit), &deviceRecordPrivate->axisInfo[bit]) < 0 ||
							  deviceRecordPrivate->axisInfo[bit].minimum == deviceRecordPrivate->axisInfo[bit].maximum) {
							continue;
						}
						deviceRecordPrivate->axisMap[bit] = deviceRecord->numAxes;
						deviceRecord->numAxes++;
					}
				}
				deviceRecord->numButtons = 0;
				for (bit = BTN_MISC; bit < KEY_CNT; bit++) {
					if (test_bit(bit, evKeyBits)) {
						deviceRecordPrivate->buttonMap[bit - BTN_MISC] = deviceRecord->numButtons;
						deviceRecord->numButtons++;
					}
				}
				
				deviceRecord->axisStates = calloc(sizeof(float), deviceRecord->numAxes);
				deviceRecord->buttonStates = calloc(sizeof(bool), deviceRecord->numButtons);
				
				if (Gamepad_deviceAttachCallback != NULL) {
					Gamepad_deviceAttachCallback(deviceRecord, Gamepad_deviceAttachContext);
				}
				
				pthread_create(&deviceRecordPrivate->thread, NULL, deviceThread, deviceRecord);
			}
		}
		closedir(dev_input);
	}
	
	lastInputStatTime = currentTime;
	pthread_mutex_unlock(&devicesMutex);
}
Пример #3
0
void Gamepad_detectDevices() {
	unsigned int numPadsSupported;
	unsigned int deviceIndex, deviceIndex2;
	JOYINFOEX info;
	JOYCAPS caps;
	bool duplicate;
	struct Gamepad_device * deviceRecord;
	struct Gamepad_devicePrivate * deviceRecordPrivate;
	UINT joystickID;
	int axisIndex;
	
	if (!inited) {
		return;
	}
	
	numPadsSupported = joyGetNumDevs();
	for (deviceIndex = 0; deviceIndex < numPadsSupported; deviceIndex++) {
		info.dwSize = sizeof(info);
		info.dwFlags = JOY_RETURNALL;
		joystickID = JOYSTICKID1 + deviceIndex;
		if (joyGetPosEx(joystickID, &info) == JOYERR_NOERROR &&
		    joyGetDevCaps(joystickID, &caps, sizeof(JOYCAPS)) == JOYERR_NOERROR) {
			
			duplicate = false;
			for (deviceIndex2 = 0; deviceIndex2 < numDevices; deviceIndex2++) {
				if (((struct Gamepad_devicePrivate *) devices[deviceIndex2]->privateData)->joystickID == joystickID) {
					duplicate = true;
					break;
				}
			}
			if (duplicate) {
				continue;
			}
			
			deviceRecord = malloc(sizeof(struct Gamepad_device));
			deviceRecord->deviceID = nextDeviceID++;
			deviceRecord->description = getDeviceDescription(joystickID, caps);
			deviceRecord->vendorID = caps.wMid;
			deviceRecord->productID = caps.wPid;
			deviceRecord->numAxes = caps.wNumAxes + ((caps.wCaps & JOYCAPS_HASPOV) ? 2 : 0);
			deviceRecord->numButtons = caps.wNumButtons;
			deviceRecord->axisStates = calloc(sizeof(float), deviceRecord->numAxes);
			deviceRecord->buttonStates = calloc(sizeof(bool), deviceRecord->numButtons);
			devices = realloc(devices, sizeof(struct Gamepad_device *) * (numDevices + 1));
			devices[numDevices++] = deviceRecord;
			
			deviceRecordPrivate = malloc(sizeof(struct Gamepad_devicePrivate));
			deviceRecordPrivate->joystickID = joystickID;
			deviceRecordPrivate->lastState = info;
			
			deviceRecordPrivate->xAxisIndex = 0;
			deviceRecordPrivate->yAxisIndex = 1;
			axisIndex = 2;
			deviceRecordPrivate->zAxisIndex = (caps.wCaps & JOYCAPS_HASZ) ? axisIndex++ : -1;
			deviceRecordPrivate->rAxisIndex = (caps.wCaps & JOYCAPS_HASR) ? axisIndex++ : -1;
			deviceRecordPrivate->uAxisIndex = (caps.wCaps & JOYCAPS_HASU) ? axisIndex++ : -1;
			deviceRecordPrivate->vAxisIndex = (caps.wCaps & JOYCAPS_HASV) ? axisIndex++ : -1;
			
			deviceRecordPrivate->axisRanges = malloc(sizeof(UINT[2]) * axisIndex);
			deviceRecordPrivate->axisRanges[0][0] = caps.wXmin;
			deviceRecordPrivate->axisRanges[0][1] = caps.wXmax;
			deviceRecordPrivate->axisRanges[1][0] = caps.wYmin;
			deviceRecordPrivate->axisRanges[1][1] = caps.wYmax;
			if (deviceRecordPrivate->zAxisIndex != -1) {
				deviceRecordPrivate->axisRanges[deviceRecordPrivate->zAxisIndex][0] = caps.wZmin;
				deviceRecordPrivate->axisRanges[deviceRecordPrivate->zAxisIndex][1] = caps.wZmax;
			}
			if (deviceRecordPrivate->rAxisIndex != -1) {
				deviceRecordPrivate->axisRanges[deviceRecordPrivate->rAxisIndex][0] = caps.wRmin;
				deviceRecordPrivate->axisRanges[deviceRecordPrivate->rAxisIndex][1] = caps.wRmax;
			}
			if (deviceRecordPrivate->uAxisIndex != -1) {
				deviceRecordPrivate->axisRanges[deviceRecordPrivate->uAxisIndex][0] = caps.wUmin;
				deviceRecordPrivate->axisRanges[deviceRecordPrivate->uAxisIndex][1] = caps.wUmax;
			}
			if (deviceRecordPrivate->vAxisIndex != -1) {
				deviceRecordPrivate->axisRanges[deviceRecordPrivate->vAxisIndex][0] = caps.wVmin;
				deviceRecordPrivate->axisRanges[deviceRecordPrivate->vAxisIndex][1] = caps.wVmax;
			}
			
			deviceRecordPrivate->povXAxisIndex = (caps.wCaps & JOYCAPS_HASPOV) ? axisIndex++ : -1;
			deviceRecordPrivate->povYAxisIndex = (caps.wCaps & JOYCAPS_HASPOV) ? axisIndex++ : -1;
			
			deviceRecord->privateData = deviceRecordPrivate;
			
			if (Gamepad_deviceAttachCallback != NULL) {
				Gamepad_deviceAttachCallback(deviceRecord, Gamepad_deviceAttachContext);
			}
		}
	}
}