| | |
| | | /* |
| | | Simple DirectMedia Layer |
| | | Copyright (C) 1997-2016 Sam Lantinga <slouken@libsdl.org> |
| | | Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org> |
| | | |
| | | This software is provided 'as-is', without any express or implied |
| | | warranty. In no event will the authors be held liable for any damages |
| | |
| | | static int MaybeAddDevice(const char *path); |
| | | #if SDL_USE_LIBUDEV |
| | | static int MaybeRemoveDevice(const char *path); |
| | | void haptic_udev_callback(SDL_UDEV_deviceevent udev_type, int udev_class, const char *devpath); |
| | | static void haptic_udev_callback(SDL_UDEV_deviceevent udev_type, int udev_class, const char *devpath); |
| | | #endif /* SDL_USE_LIBUDEV */ |
| | | |
| | | /* |
| | |
| | | SDL_UDEV_Quit(); |
| | | return SDL_SetError("Could not setup haptic <-> udev callback"); |
| | | } |
| | | |
| | | /* Force a scan to build the initial device list */ |
| | | SDL_UDEV_Scan(); |
| | | #endif /* SDL_USE_LIBUDEV */ |
| | | |
| | | return numhaptics; |
| | | } |
| | | |
| | | int |
| | | SDL_SYS_NumHaptics() |
| | | SDL_SYS_NumHaptics(void) |
| | | { |
| | | return numhaptics; |
| | | } |
| | |
| | | } |
| | | |
| | | #if SDL_USE_LIBUDEV |
| | | void haptic_udev_callback(SDL_UDEV_deviceevent udev_type, int udev_class, const char *devpath) |
| | | static void haptic_udev_callback(SDL_UDEV_deviceevent udev_type, int udev_class, const char *devpath) |
| | | { |
| | | if (devpath == NULL || !(udev_class & SDL_UDEV_DEVICE_JOYSTICK)) { |
| | | return; |
| | |
| | | /* Opened and not closed haptics are leaked, this is on purpose. |
| | | * Close your haptic devices after usage. */ |
| | | SDL_free(item->fname); |
| | | item->fname = NULL; |
| | | SDL_free(item); |
| | | } |
| | | |
| | | #if SDL_USE_LIBUDEV |
| | |
| | | else if (!src->dir[0]) |
| | | *dest = (src->dir[1] >= 0 ? 0x8000 : 0); |
| | | else { |
| | | float f = atan2(src->dir[1], src->dir[0]); /* Ideally we'd use fixed point math instead of floats... */ |
| | | float f = SDL_atan2(src->dir[1], src->dir[0]); /* Ideally we'd use fixed point math instead of floats... */ |
| | | /* |
| | | atan2 takes the parameters: Y-axis-value and X-axis-value (in that order) |
| | | - Y-axis-value is the second coordinate (from center to SOUTH) |
| | |
| | | else if (periodic->type == SDL_HAPTIC_SAWTOOTHDOWN) |
| | | dest->u.periodic.waveform = FF_SAW_DOWN; |
| | | dest->u.periodic.period = CLAMP(periodic->period); |
| | | dest->u.periodic.magnitude = periodic->magnitude; |
| | | /* Linux expects 0-65535, so multiply by 2 */ |
| | | dest->u.periodic.magnitude = CLAMP(periodic->magnitude) * 2; |
| | | dest->u.periodic.offset = periodic->offset; |
| | | /* Linux phase is defined in interval "[0x0000, 0x10000[", corresponds with "[0deg, 360deg[" phase shift. */ |
| | | dest->u.periodic.phase = ((Uint32)periodic->phase * 0x10000U) / 36000; |
| | |
| | | dest->trigger.button = 0; |
| | | dest->trigger.interval = 0; |
| | | |
| | | /* Rumble */ |
| | | dest->u.rumble.strong_magnitude = leftright->large_magnitude; |
| | | dest->u.rumble.weak_magnitude = leftright->small_magnitude; |
| | | /* Rumble (Linux expects 0-65535, so multiply by 2) */ |
| | | dest->u.rumble.strong_magnitude = CLAMP(leftright->large_magnitude) * 2; |
| | | dest->u.rumble.weak_magnitude = CLAMP(leftright->small_magnitude) * 2; |
| | | |
| | | break; |
| | | |