Added infrastructure for reporting GameInput touchpads

PlayStation controllers don't seem to report touch info, so we'll need to figure out how to interpret the touch data once it's available.
main
Sam Lantinga 2024-02-17 21:21:54 -08:00
parent ae4aa25082
commit ae8a910781
1 changed files with 35 additions and 24 deletions

View File

@ -35,13 +35,9 @@ typedef struct GAMEINPUT_InternalDevice
IGameInputDevice *device; IGameInputDevice *device;
char path[(APP_LOCAL_DEVICE_ID_SIZE * 2) + 1]; char path[(APP_LOCAL_DEVICE_ID_SIZE * 2) + 1];
char *name; char *name;
Uint16 vendor;
Uint16 product;
SDL_JoystickGUID guid; /* generated by SDL */ SDL_JoystickGUID guid; /* generated by SDL */
SDL_JoystickID device_instance; /* generated by SDL */ SDL_JoystickID device_instance; /* generated by SDL */
SDL_bool wireless; const GameInputDeviceInfo *info;
SDL_bool sensors_supported;
GameInputRumbleMotors supportedRumbleMotors;
SDL_bool isAdded; SDL_bool isAdded;
SDL_bool isDeleteRequested; SDL_bool isDeleteRequested;
} GAMEINPUT_InternalDevice; } GAMEINPUT_InternalDevice;
@ -70,7 +66,7 @@ static int GAMEINPUT_InternalAddOrFind(IGameInputDevice *pDevice)
{ {
GAMEINPUT_InternalDevice **devicelist = NULL; GAMEINPUT_InternalDevice **devicelist = NULL;
GAMEINPUT_InternalDevice *elem = NULL; GAMEINPUT_InternalDevice *elem = NULL;
const GameInputDeviceInfo *devinfo = NULL; const GameInputDeviceInfo *info = NULL;
Uint16 bus = SDL_HARDWARE_BUS_USB; Uint16 bus = SDL_HARDWARE_BUS_USB;
Uint16 vendor = 0; Uint16 vendor = 0;
Uint16 product = 0; Uint16 product = 0;
@ -80,15 +76,15 @@ static int GAMEINPUT_InternalAddOrFind(IGameInputDevice *pDevice)
char tmp[4]; char tmp[4];
int idx = 0; int idx = 0;
devinfo = IGameInputDevice_GetDeviceInfo(pDevice); info = IGameInputDevice_GetDeviceInfo(pDevice);
if (devinfo->capabilities & GameInputDeviceCapabilityWireless) { if (info->capabilities & GameInputDeviceCapabilityWireless) {
bus = SDL_HARDWARE_BUS_BLUETOOTH; bus = SDL_HARDWARE_BUS_BLUETOOTH;
} else { } else {
bus = SDL_HARDWARE_BUS_USB; bus = SDL_HARDWARE_BUS_USB;
} }
vendor = devinfo->vendorId; vendor = info->vendorId;
product = devinfo->productId; product = info->productId;
version = (devinfo->firmwareVersion.major << 8) | devinfo->firmwareVersion.minor; version = (info->firmwareVersion.major << 8) | info->firmwareVersion.minor;
if (SDL_JoystickHandledByAnotherDriver(&SDL_GAMEINPUT_JoystickDriver, vendor, product, version, "")) { if (SDL_JoystickHandledByAnotherDriver(&SDL_GAMEINPUT_JoystickDriver, vendor, product, version, "")) {
return 0; return 0;
@ -115,28 +111,24 @@ static int GAMEINPUT_InternalAddOrFind(IGameInputDevice *pDevice)
/* Generate a device path */ /* Generate a device path */
for (idx = 0; idx < APP_LOCAL_DEVICE_ID_SIZE; ++idx) { for (idx = 0; idx < APP_LOCAL_DEVICE_ID_SIZE; ++idx) {
SDL_snprintf(tmp, SDL_arraysize(tmp), "%02hhX", devinfo->deviceId.value[idx]); SDL_snprintf(tmp, SDL_arraysize(tmp), "%02hhX", info->deviceId.value[idx]);
SDL_strlcat(elem->path, tmp, SDL_arraysize(tmp)); SDL_strlcat(elem->path, tmp, SDL_arraysize(tmp));
} }
if (devinfo->deviceStrings) { if (info->deviceStrings) {
/* In theory we could get the manufacturer and product strings here, but they're NULL for all the controllers I've tested */ /* In theory we could get the manufacturer and product strings here, but they're NULL for all the controllers I've tested */
} }
if (devinfo->displayName) { if (info->displayName) {
/* This could give us a product string, but it's NULL for all the controllers I've tested */ /* This could give us a product string, but it's NULL for all the controllers I've tested */
} }
IGameInputDevice_AddRef(pDevice); IGameInputDevice_AddRef(pDevice);
elem->device = pDevice; elem->device = pDevice;
elem->name = SDL_CreateJoystickName(vendor, product, manufacturer_string, product_string); elem->name = SDL_CreateJoystickName(vendor, product, manufacturer_string, product_string);
elem->vendor = vendor;
elem->product = product;
elem->guid = SDL_CreateJoystickGUID(bus, vendor, product, version, manufacturer_string, product_string, 'g', 0); elem->guid = SDL_CreateJoystickGUID(bus, vendor, product, version, manufacturer_string, product_string, 'g', 0);
elem->device_instance = SDL_GetNextObjectID(); elem->device_instance = SDL_GetNextObjectID();
elem->wireless = (devinfo->capabilities & GameInputDeviceCapabilityWireless); elem->info = info;
elem->sensors_supported = (devinfo->supportedInput & GameInputKindMotion);
elem->supportedRumbleMotors = devinfo->supportedRumbleMotors;
g_GameInputList.devices = devicelist; g_GameInputList.devices = devicelist;
g_GameInputList.devices[g_GameInputList.count++] = elem; g_GameInputList.devices[g_GameInputList.count++] = elem;
@ -297,7 +289,7 @@ static SDL_bool GAMEINPUT_JoystickIsDevicePresent(Uint16 vendor_id, Uint16 produ
for (idx = 0; idx < g_GameInputList.count; ++idx) { for (idx = 0; idx < g_GameInputList.count; ++idx) {
elem = g_GameInputList.devices[idx]; elem = g_GameInputList.devices[idx];
if (elem && vendor_id == elem->vendor && product_id == elem->product) { if (elem && vendor_id == elem->info->vendorId && product_id == elem->info->productId) {
return SDL_TRUE; return SDL_TRUE;
} }
} }
@ -374,20 +366,24 @@ static int GAMEINPUT_JoystickOpen(SDL_Joystick *joystick, int device_index)
joystick->nbuttons = 11; joystick->nbuttons = 11;
joystick->nhats = 1; joystick->nhats = 1;
if (elem->supportedRumbleMotors & (GameInputRumbleLowFrequency | GameInputRumbleHighFrequency)) { if (elem->info->supportedRumbleMotors & (GameInputRumbleLowFrequency | GameInputRumbleHighFrequency)) {
SDL_SetBooleanProperty(SDL_GetJoystickProperties(joystick), SDL_PROP_JOYSTICK_CAP_RUMBLE_BOOLEAN, SDL_TRUE); SDL_SetBooleanProperty(SDL_GetJoystickProperties(joystick), SDL_PROP_JOYSTICK_CAP_RUMBLE_BOOLEAN, SDL_TRUE);
} }
if (elem->supportedRumbleMotors & (GameInputRumbleLeftTrigger | GameInputRumbleRightTrigger)) { if (elem->info->supportedRumbleMotors & (GameInputRumbleLeftTrigger | GameInputRumbleRightTrigger)) {
SDL_SetBooleanProperty(SDL_GetJoystickProperties(joystick), SDL_PROP_JOYSTICK_CAP_TRIGGER_RUMBLE_BOOLEAN, SDL_TRUE); SDL_SetBooleanProperty(SDL_GetJoystickProperties(joystick), SDL_PROP_JOYSTICK_CAP_TRIGGER_RUMBLE_BOOLEAN, SDL_TRUE);
} }
if (elem->sensors_supported) { if (elem->info->supportedInput & GameInputKindTouch) {
SDL_PrivateJoystickAddTouchpad(joystick, elem->info->touchPointCount);
}
if (elem->info->supportedInput & GameInputKindMotion) {
/* FIXME: What's the sensor update rate? */ /* FIXME: What's the sensor update rate? */
SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_GYRO, 250.0f); SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_GYRO, 250.0f);
SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_ACCEL, 250.0f); SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_ACCEL, 250.0f);
} }
if (elem->wireless) { if (elem->info->capabilities & GameInputDeviceCapabilityWireless) {
joystick->epowerlevel = GAMEINPUT_InternalGetPowerLevel(elem->device); joystick->epowerlevel = GAMEINPUT_InternalGetPowerLevel(elem->device);
} else { } else {
joystick->epowerlevel = SDL_JOYSTICK_POWER_WIRED; joystick->epowerlevel = SDL_JOYSTICK_POWER_WIRED;
@ -451,6 +447,7 @@ static void GAMEINPUT_JoystickUpdate(SDL_Joystick *joystick)
Uint8 btnidx = 0, btnstate = 0, hat = 0; Uint8 btnidx = 0, btnstate = 0, hat = 0;
GAMEINPUT_InternalJoystickHwdata *hwdata = joystick->hwdata; GAMEINPUT_InternalJoystickHwdata *hwdata = joystick->hwdata;
IGameInputDevice *device = hwdata->devref->device; IGameInputDevice *device = hwdata->devref->device;
const GameInputDeviceInfo *info = hwdata->devref->info;
IGameInputReading *reading = NULL; IGameInputReading *reading = NULL;
Uint64 timestamp = SDL_GetTicksNS(); Uint64 timestamp = SDL_GetTicksNS();
GameInputGamepadState state; GameInputGamepadState state;
@ -497,6 +494,20 @@ static void GAMEINPUT_JoystickUpdate(SDL_Joystick *joystick)
#undef CONVERT_TRIGGER #undef CONVERT_TRIGGER
} }
if (info->supportedInput & GameInputKindTouch) {
GameInputTouchState *touch_state = SDL_stack_alloc(GameInputTouchState, info->touchPointCount);
if (touch_state) {
uint32_t i;
uint32_t touch_count = IGameInputReading_GetTouchState(reading, info->touchPointCount, touch_state);
for (i = 0; i < touch_count; ++i) {
GameInputTouchState *touch = &touch_state[i];
/* FIXME: We should use touch->touchId to track fingers instead of using i below */
SDL_SendJoystickTouchpad(timestamp, joystick, 0, i, SDL_PRESSED, touch->positionX * info->touchSensorInfo[i].resolutionX, touch->positionY * info->touchSensorInfo[0].resolutionY, touch->pressure);
}
SDL_stack_free(touch_state);
}
}
if (hwdata->report_sensors) { if (hwdata->report_sensors) {
GameInputMotionState motion_state; GameInputMotionState motion_state;