From ae8a9107813d4a8bbb6c82c5633c1f64b8a0bb3c Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Sat, 17 Feb 2024 21:21:54 -0800 Subject: [PATCH] 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. --- src/joystick/gdk/SDL_gameinputjoystick.c | 59 ++++++++++++++---------- 1 file changed, 35 insertions(+), 24 deletions(-) diff --git a/src/joystick/gdk/SDL_gameinputjoystick.c b/src/joystick/gdk/SDL_gameinputjoystick.c index ee302305b..f402b231e 100644 --- a/src/joystick/gdk/SDL_gameinputjoystick.c +++ b/src/joystick/gdk/SDL_gameinputjoystick.c @@ -35,13 +35,9 @@ typedef struct GAMEINPUT_InternalDevice IGameInputDevice *device; char path[(APP_LOCAL_DEVICE_ID_SIZE * 2) + 1]; char *name; - Uint16 vendor; - Uint16 product; SDL_JoystickGUID guid; /* generated by SDL */ SDL_JoystickID device_instance; /* generated by SDL */ - SDL_bool wireless; - SDL_bool sensors_supported; - GameInputRumbleMotors supportedRumbleMotors; + const GameInputDeviceInfo *info; SDL_bool isAdded; SDL_bool isDeleteRequested; } GAMEINPUT_InternalDevice; @@ -70,7 +66,7 @@ static int GAMEINPUT_InternalAddOrFind(IGameInputDevice *pDevice) { GAMEINPUT_InternalDevice **devicelist = NULL; GAMEINPUT_InternalDevice *elem = NULL; - const GameInputDeviceInfo *devinfo = NULL; + const GameInputDeviceInfo *info = NULL; Uint16 bus = SDL_HARDWARE_BUS_USB; Uint16 vendor = 0; Uint16 product = 0; @@ -80,15 +76,15 @@ static int GAMEINPUT_InternalAddOrFind(IGameInputDevice *pDevice) char tmp[4]; int idx = 0; - devinfo = IGameInputDevice_GetDeviceInfo(pDevice); - if (devinfo->capabilities & GameInputDeviceCapabilityWireless) { + info = IGameInputDevice_GetDeviceInfo(pDevice); + if (info->capabilities & GameInputDeviceCapabilityWireless) { bus = SDL_HARDWARE_BUS_BLUETOOTH; } else { bus = SDL_HARDWARE_BUS_USB; } - vendor = devinfo->vendorId; - product = devinfo->productId; - version = (devinfo->firmwareVersion.major << 8) | devinfo->firmwareVersion.minor; + vendor = info->vendorId; + product = info->productId; + version = (info->firmwareVersion.major << 8) | info->firmwareVersion.minor; if (SDL_JoystickHandledByAnotherDriver(&SDL_GAMEINPUT_JoystickDriver, vendor, product, version, "")) { return 0; @@ -115,28 +111,24 @@ static int GAMEINPUT_InternalAddOrFind(IGameInputDevice *pDevice) /* Generate a device path */ 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)); } - 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 */ } - if (devinfo->displayName) { + if (info->displayName) { /* This could give us a product string, but it's NULL for all the controllers I've tested */ } IGameInputDevice_AddRef(pDevice); elem->device = pDevice; 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->device_instance = SDL_GetNextObjectID(); - elem->wireless = (devinfo->capabilities & GameInputDeviceCapabilityWireless); - elem->sensors_supported = (devinfo->supportedInput & GameInputKindMotion); - elem->supportedRumbleMotors = devinfo->supportedRumbleMotors; + elem->info = info; g_GameInputList.devices = devicelist; 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) { 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; } } @@ -374,20 +366,24 @@ static int GAMEINPUT_JoystickOpen(SDL_Joystick *joystick, int device_index) joystick->nbuttons = 11; 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); } - 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); } - 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? */ SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_GYRO, 250.0f); SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_ACCEL, 250.0f); } - if (elem->wireless) { + if (elem->info->capabilities & GameInputDeviceCapabilityWireless) { joystick->epowerlevel = GAMEINPUT_InternalGetPowerLevel(elem->device); } else { joystick->epowerlevel = SDL_JOYSTICK_POWER_WIRED; @@ -451,6 +447,7 @@ static void GAMEINPUT_JoystickUpdate(SDL_Joystick *joystick) Uint8 btnidx = 0, btnstate = 0, hat = 0; GAMEINPUT_InternalJoystickHwdata *hwdata = joystick->hwdata; IGameInputDevice *device = hwdata->devref->device; + const GameInputDeviceInfo *info = hwdata->devref->info; IGameInputReading *reading = NULL; Uint64 timestamp = SDL_GetTicksNS(); GameInputGamepadState state; @@ -497,6 +494,20 @@ static void GAMEINPUT_JoystickUpdate(SDL_Joystick *joystick) #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) { GameInputMotionState motion_state;