Repository: libsdl-org/SDL
File: src/joystick/hidapi/SDL_hidapi_ps4.c (C)

Code before:

    return HIDAPI_DriverPS4_InternalSendJoystickEffect(ctx, effect, size, true);
}

static bool HIDAPI_DriverPS4_SetJoystickSensorsEnabled(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, bool enabled)
{
    SDL_DriverPS4_Context *ctx = (SDL_DriverPS4_Context *)device->context;

    HIDAPI_DriverPS4_UpdateEnhancedModeOnApplicationUsage(ctx);

    if (!ctx->sensors_supported || (enabled && !ctx->enhanced_mode)) {
        return SDL_Unsupported();
    }

    if (enabled) {
        HIDAPI_DriverPS4_LoadCalibrationData(device);
    }
    ctx->report_sensors = enabled;

    return true;
}

static void HIDAPI_DriverPS4_HandleStatePacket(SDL_Joystick *joystick, SDL_hid_device *dev, SDL_DriverPS4_Context *ctx, PS4StatePacket_t *packet, int size)
{
    static const float TOUCHPAD_SCALEX = 1.0f / 1920;
    static const float TOUCHPAD_SCALEY = 1.0f / 920; // This is noted as being 944 resolution, but 920 feels better
    Sint16 axis;
    bool touchpad_down;
    int touchpad_x, touchpad_y;
    Uint64 timestamp = SDL_GetTicksNS();

    if (size > 9 && ctx->report_touchpad && ctx->enhanced_reports) {
        touchpad_down = ((packet->ucTouchpadCounter1 & 0x80) == 0);
        touchpad_x = packet->rgucTouchpadData1[0] | (((int)packet->rgucTouchpadData1[1] & 0x0F) << 8);
        touchpad_y = (packet->rgucTouchpadData1[1] >> 4) | ((int)packet->rgucTouchpadData1[2] << 4);
        SDL_SendJoystickTouchpad(timestamp, joystick, 0, 0, touchpad_down, touchpad_x * TOUCHPAD_SCALEX, touchpad_y * TOUCHPAD_SCALEY, touchpad_down ? 1.0f : 0.0f);

        touchpad_down = ((packet->ucTouchpadCounter2 & 0x80) == 0);
        touchpad_x = packet->rgucTouchpadData2[0] | (((int)packet->rgucTouchpadData2[1] & 0x0F) << 8);
        touchpad_y = (packet->rgucTouchpadData2[1] >> 4) | ((int)packet->rgucTouchpadData2[2] << 4);
        SDL_SendJoystickTouchpad(timestamp, joystick, 0, 1, touchpad_down, touchpad_x * TOUCHPAD_SCALEX, touchpad_y * TOUCHPAD_SCALEY, touchpad_down ? 1.0f : 0.0f);
    }

    if (ctx->last_state.rgucButtonsHatAndCounter[0] != packet->rgucButtonsHatAndCounter[0]) {
        {
            Uint8 data = (packet->rgucButtonsHatAndCounter[0] >> 4);

            SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_WEST, ((data & 0x01) != 0));
            SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_SOUTH, ((data & 0x02) != 0));
            SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_EAST, ((data & 0x04) != 0));
            SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_NORTH, ((data & 0x08) != 0));

Review comment (suggestion):
The precision is a bit arbitrary. Happy to change it to anything that's considered more suitable (I believe this is a couple decimal places more than single-precision can reliably represent either way, but I'm not FP expert).

Code after:

    return HIDAPI_DriverPS4_InternalSendJoystickEffect(ctx, effect, size, true);
}

static bool HIDAPI_DriverPS4_SetJoystickSensorsEnabled(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, bool enabled)
{
    SDL_DriverPS4_Context *ctx = (SDL_DriverPS4_Context *)device->context;

    HIDAPI_DriverPS4_UpdateEnhancedModeOnApplicationUsage(ctx);

    if (!ctx->sensors_supported || (enabled && !ctx->enhanced_mode)) {
        return SDL_Unsupported();
    }

    if (enabled) {
        HIDAPI_DriverPS4_LoadCalibrationData(device);
    }
    ctx->report_sensors = enabled;

    return true;
}

static void HIDAPI_DriverPS4_HandleStatePacket(SDL_Joystick *joystick, SDL_hid_device *dev, SDL_DriverPS4_Context *ctx, PS4StatePacket_t *packet, int size)
{
    static const float TOUCHPAD_SCALEX = 5.20833333e-4f; // 1.0f / 1920
    static const float TOUCHPAD_SCALEY = 1.08695652e-3f; // 1.0f / 920 // This is noted as being 944 resolution, but 920 feels better
    Sint16 axis;
    bool touchpad_down;
    int touchpad_x, touchpad_y;
    Uint64 timestamp = SDL_GetTicksNS();

    if (size > 9 && ctx->report_touchpad && ctx->enhanced_reports) {
        touchpad_down = ((packet->ucTouchpadCounter1 & 0x80) == 0);
        touchpad_x = packet->rgucTouchpadData1[0] | (((int)packet->rgucTouchpadData1[1] & 0x0F) << 8);
        touchpad_y = (packet->rgucTouchpadData1[1] >> 4) | ((int)packet->rgucTouchpadData1[2] << 4);
        SDL_SendJoystickTouchpad(timestamp, joystick, 0, 0, touchpad_down, touchpad_x * TOUCHPAD_SCALEX, touchpad_y * TOUCHPAD_SCALEY, touchpad_down ? 1.0f : 0.0f);

        touchpad_down = ((packet->ucTouchpadCounter2 & 0x80) == 0);
        touchpad_x = packet->rgucTouchpadData2[0] | (((int)packet->rgucTouchpadData2[1] & 0x0F) << 8);
        touchpad_y = (packet->rgucTouchpadData2[1] >> 4) | ((int)packet->rgucTouchpadData2[2] << 4);
        SDL_SendJoystickTouchpad(timestamp, joystick, 0, 1, touchpad_down, touchpad_x * TOUCHPAD_SCALEX, touchpad_y * TOUCHPAD_SCALEY, touchpad_down ? 1.0f : 0.0f);
    }

    if (ctx->last_state.rgucButtonsHatAndCounter[0] != packet->rgucButtonsHatAndCounter[0]) {
        {
            Uint8 data = (packet->rgucButtonsHatAndCounter[0] >> 4);

            SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_WEST, ((data & 0x01) != 0));
            SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_SOUTH, ((data & 0x02) != 0));
            SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_EAST, ((data & 0x04) != 0));
            SDL_SendJoystickButton(timestamp, joystick, SDL_GAMEPAD_BUTTON_NORTH, ((data & 0x08) != 0));