First commit of the SDL_haptic subsystem.
Code compiles and works, very limited functionality (linux only).
--- a/configure.in Wed Apr 23 06:26:07 2008 +0000
+++ b/configure.in Sun Jun 01 11:44:25 2008 +0000
@@ -235,6 +235,14 @@
else
SOURCES="$SOURCES $srcdir/src/joystick/*.c"
fi
+AC_ARG_ENABLE(haptic,
+AC_HELP_STRING([--enable-haptic], [Enable the haptic (force feedback) subsystem [[default=yes]]]),
+ , enable_haptic=yes)
+if test x$enable_haptic != xyes; then
+ AC_DEFINE(SDL_HAPTIC_DISABLE)
+else
+ SOURCES="$SOURCES $srcdir/src/haptic/*.c"
+fi
AC_ARG_ENABLE(cdrom,
AC_HELP_STRING([--enable-cdrom], [Enable the cdrom subsystem [[default=yes]]]),
, enable_cdrom=yes)
@@ -2176,6 +2184,16 @@
;;
esac
fi
+ # Set up files for the haptic library
+ if test x$enable_haptic = xyes; then
+ case $ARCH in
+ linux)
+ AC_DEFINE(SDL_HAPTIC_LINUX)
+ SOURCES="$SOURCES $srcdir/src/haptic/linux/*.c"
+ have_haptic=yes
+ ;;
+ esac
+ fi
# Set up files for the cdrom library
if test x$enable_cdrom = xyes; then
case $ARCH in
--- a/include/SDL.h Wed Apr 23 06:26:07 2008 +0000
+++ b/include/SDL.h Sun Jun 01 11:44:25 2008 +0000
@@ -109,6 +109,7 @@
#define SDL_INIT_VIDEO 0x00000020
#define SDL_INIT_CDROM 0x00000100
#define SDL_INIT_JOYSTICK 0x00000200
+#define SDL_INIT_HAPTIC 0x00001000
#define SDL_INIT_NOPARACHUTE 0x00100000 /* Don't catch fatal signals */
#define SDL_INIT_EVENTTHREAD 0x01000000 /* Not supported on all OS's */
#define SDL_INIT_EVERYTHING 0x0000FFFF
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/SDL_haptic.h Sun Jun 01 11:44:25 2008 +0000
@@ -0,0 +1,87 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 2008 Edgar Simo
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+ Sam Lantinga
+ slouken@libsdl.org
+*/
+
+/**
+ * \file SDL_haptic.h
+ *
+ * Include file for SDL haptic subsystem
+ */
+
+#ifndef _SDL_haptic_h
+#define _SDL_haptic_h
+
+#include "SDL_stdinc.h"
+#include "SDL_error.h"
+
+#include "begin_code.h"
+/* Set up for C function definitions, even when using C++ */
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+extern "C" {
+ /* *INDENT-ON* */
+#endif
+
+/* The haptic structure used to identify an SDL haptic */
+struct _SDL_Haptic;
+typedef struct _SDL_Haptic SDL_Haptic;
+
+
+/* Different effects that can be generated */
+#define SDL_HAPTIC_CONSTANT (1<<0)
+#define SDL_HAPTIC_PERIODIC (1<<1)
+#define SDL_HAPTIC_RAMP (1<<2)
+#define SDL_HAPTIC_SPRING (1<<3)
+#define SDL_HAPTIC_FRICTION (1<<4)
+#define SDL_HAPTIC_DAMPER (1<<5)
+#define SDL_HAPTIC_RUMBLE (1<<6)
+#define SDL_HAPTIC_INERTIA (1<<7)
+#define SDL_HAPTIC_GAIN (1<<8)
+#define SDL_HAPTIC_AUTOCENTER (1<<9)
+
+
+/* Function prototypes */
+/*
+ * Count the number of joysticks attached to the system
+ */
+extern DECLSPEC int SDLCALL SDL_NumHaptics(void);
+
+/*
+ * Get the implementation dependent name of a joystick.
+ * This can be called before any joysticks are opened.
+ * If no name can be found, this function returns NULL.
+ */
+extern DECLSPEC const char *SDLCALL SDL_HapticName(int device_index);
+
+
+/* Ends C function definitions when using C++ */
+#ifdef __cplusplus
+/* *INDENT-OFF* */
+}
+/* *INDENT-ON* */
+#endif
+#include "close_code.h"
+
+#endif /* _SDL_haptic_h */
+
+/* vi: set ts=4 sw=4 expandtab: */
+
+
--- a/src/SDL.c Wed Apr 23 06:26:07 2008 +0000
+++ b/src/SDL.c Sun Jun 01 11:44:25 2008 +0000
@@ -38,6 +38,10 @@
extern int SDL_JoystickInit(void);
extern void SDL_JoystickQuit(void);
#endif
+#if !SDL_HAPTIC_DISABLED
+extern int SDL_HapticInit(void);
+extern int SDL_HapticQuit(void);
+#endif
#if !SDL_CDROM_DISABLED
extern int SDL_CDROMInit(void);
extern void SDL_CDROMQuit(void);
@@ -123,6 +127,22 @@
}
#endif
+#if !SDL_HAPTIC_DISABLED
+ /* Initialize the haptic subsystem */
+ if ((flags & SDL_INIT_HAPTIC) && !(SDL_initialized & SDL_INIT_HAPTIC)) {
+ if (SDL_HapticInit() < 0) {
+ return (-1);
+ }
+ SDL_initialized |= SDL_INIT_HAPTIC;
+ }
+#else
+ if (flags & SDL_INIT_HAPTIC) {
+ SDL_SetError("SDL not built with haptic (force feedback) support");
+ return (-1);
+ }
+#endif
+
+
#if !SDL_CDROM_DISABLED
/* Initialize the CD-ROM subsystem */
if ((flags & SDL_INIT_CDROM) && !(SDL_initialized & SDL_INIT_CDROM)) {
@@ -180,6 +200,12 @@
SDL_initialized &= ~SDL_INIT_JOYSTICK;
}
#endif
+#if !SDL_HAPTIC_DISABLED
+ if ((flags & SDL_initialized & SDL_INIT_HAPTIC)) {
+ SDL_HapticQuit();
+ SDL_initialized &= ~SDL_INIT_HAPTIC;
+ }
+#endif
#if !SDL_TIMERS_DISABLED
if ((flags & SDL_initialized & SDL_INIT_TIMER)) {
SDL_TimerQuit();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/haptic/SDL_haptic.c Sun Jun 01 11:44:25 2008 +0000
@@ -0,0 +1,127 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 2008 Edgar Simo
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+ Sam Lantinga
+ slouken@libsdl.org
+*/
+#include "SDL_config.h"
+
+#include "SDL_haptic_c.h"
+#include "SDL_syshaptic.h"
+
+
+static Uint8 SDL_numhaptics = 0;
+SDL_Haptic **SDL_haptics = NULL;
+static SDL_Haptic *default_haptic = NULL;
+
+
+/*
+ * Initializes the Haptic devices.
+ */
+int
+SDL_HapticInit(void)
+{
+ int arraylen;
+ int status;
+
+ SDL_numhaptics = 0;
+ status = SDL_SYS_HapticInit();
+ if (status >= 0) {
+ arraylen = (status + 1) * sizeof(*SDL_haptics);
+ SDL_haptics = (SDL_Haptic **) SDL_malloc(arraylen);
+ if (SDL_haptics == NULL) {
+ SDL_numhaptics = 0;
+ } else {
+ SDL_memset(SDL_haptics, 0, arraylen);
+ SDL_numhaptics = status;
+ }
+ status = 0;
+ }
+ default_haptic = NULL;
+
+ return status;
+}
+
+
+/*
+ * Returns the number of available devices.
+ */
+int
+SDL_NumHaptics(void)
+{
+ return SDL_numhaptics;
+}
+
+
+/*
+ * Gets the name of a Haptic device by index.
+ */
+const char *
+SDL_HapticName(int device_index)
+{
+ if ((device_index < 0) || (device_index >= SDL_numhaptics)) {
+ SDL_SetError("There are %d haptic devices available", SDL_numhaptics);
+ return NULL;
+ }
+ return SDL_SYS_HapticName(device_index);
+}
+
+
+/*
+ * Opens a Haptic device
+ */
+SDL_Haptic *
+SDL_HapticOpen(int device_index)
+{
+ int i;
+ SDL_Haptic *haptic;
+
+ if ((device_index < 0) || (device_index >= SDL_numhaptics)) {
+ SDL_SetError("There are %d haptic devices available", SDL_numhaptics);
+ return NULL;
+ }
+
+ /* If the haptic is already open, return it */
+ for (i = 0; SDL_haptics[i]; ++i) {
+ if (device_index == SDL_haptics[i]->index) {
+ haptic = SDL_haptics[i];
+ ++haptic->ref_count;
+ return haptic;
+ }
+ }
+
+ /* Create and initialize the haptic */
+ haptic = (SDL_Haptic *) SDL_malloc((sizeof *haptic));
+ if (haptic != NULL) {
+ SDL_memset(haptic, 0, (sizeof *haptic));
+ haptic->index = device_index;
+ if (SDL_SYS_HapticOpen(haptic) < 0) {
+ SDL_free(haptic);
+ haptic = NULL;
+ } else {
+ }
+ }
+ if (haptic) {
+ /* Add haptic to list */
+ ++haptic->ref_count;
+ for (i = 0; SDL_haptics[i]; ++i)
+ /* Skip to next haptic */ ;
+ SDL_haptics[i] = haptic;
+ }
+ return haptic;
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/haptic/SDL_haptic_c.h Sun Jun 01 11:44:25 2008 +0000
@@ -0,0 +1,33 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 2008 Edgar Simo
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+ Sam Lantinga
+ slouken@libsdl.org
+*/
+
+#include "SDL_haptic.h"
+
+struct _SDL_Haptic;
+
+extern int SDL_HapticInit(void);
+extern int SDL_NumHaptics(void);
+extern const char * SDL_HapticName(int device_index);
+extern struct _SDL_Haptic * SDL_HapticOpen(int device_index);
+extern int SDL_HapticOpened(int device_index);
+extern int SDL_HapticIndex(struct _SDL_Haptic *haptic);
+extern void SDL_HapticClose(struct _SDL_Haptic *haptic);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/haptic/SDL_syshaptic.h Sun Jun 01 11:44:25 2008 +0000
@@ -0,0 +1,44 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 2008 Edgar Simo
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+ Sam Lantinga
+ slouken@libsdl.org
+*/
+
+#include "SDL_config.h"
+
+#include "SDL_haptic.h"
+
+
+struct _SDL_Haptic
+{
+ Uint8 index;
+ const char* name;
+
+ int neffects; /* maximum amount of effects */
+ unsigned int supported; /* supported effects */
+
+ struct haptic_hwdata *hwdata; /* driver dependent */
+ int ref_count; /* count for multiple opens */
+};
+
+
+extern int SDL_SYS_HapticInit(void);
+
+extern const char * SDL_SYS_HapticName(int index);
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/haptic/linux/SDL_syshaptic.c Sun Jun 01 11:44:25 2008 +0000
@@ -0,0 +1,185 @@
+/*
+ SDL - Simple DirectMedia Layer
+ Copyright (C) 2008 Edgar Simo
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+ Sam Lantinga
+ slouken@libsdl.org
+*/
+#include "SDL_config.h"
+
+#ifdef SDL_JOYSTICK_LINUX
+
+#include "SDL_haptic.h"
+#include "../SDL_haptic_c.h"
+#include "../SDL_syshaptic.h"
+
+#include <unistd.h> /* close */
+#include <linux/input.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <linux/limits.h>
+#include <string.h>
+
+
+#include <stdio.h>
+
+
+#define MAX_HAPTICS 32
+
+
+static struct
+{
+ char *fname;
+ SDL_Haptic *haptic;
+} SDL_hapticlist[MAX_HAPTICS];
+
+struct haptic_hwdata
+{
+ int fd;
+};
+
+
+#define test_bit(nr, addr) \
+ (((1UL << ((nr) & 31)) & (((const unsigned int *) addr)[(nr) >> 5])) != 0)
+#define EV_TEST(ev,f) \
+ if (test_bit((ev), features)) ret |= (f);
+static int
+EV_IsHaptic(int fd)
+{
+ unsigned int ret;
+ unsigned long features[1 + FF_MAX/sizeof(unsigned long)];
+
+ ret = 0;
+
+ ioctl(fd, EVIOCGBIT(EV_FF, sizeof(unsigned long) * 4), features);
+
+ EV_TEST(FF_CONSTANT, SDL_HAPTIC_CONSTANT);
+ EV_TEST(FF_PERIODIC, SDL_HAPTIC_PERIODIC);
+ EV_TEST(FF_RAMP, SDL_HAPTIC_RAMP);
+ EV_TEST(FF_SPRING, SDL_HAPTIC_SPRING);
+ EV_TEST(FF_FRICTION, SDL_HAPTIC_FRICTION);
+ EV_TEST(FF_DAMPER, SDL_HAPTIC_DAMPER);
+ EV_TEST(FF_RUMBLE, SDL_HAPTIC_RUMBLE);
+ EV_TEST(FF_INERTIA, SDL_HAPTIC_INERTIA);
+ EV_TEST(FF_GAIN, SDL_HAPTIC_GAIN);
+ EV_TEST(FF_AUTOCENTER, SDL_HAPTIC_AUTOCENTER);
+
+ return ret;
+}
+
+int
+SDL_SYS_HapticInit(void)
+{
+ const char joydev_pattern[] = "/dev/input/event%d";
+ dev_t dev_nums[MAX_HAPTICS];
+ char path[PATH_MAX];
+ struct stat sb;
+ int fd;
+ int i, j, k;
+ int duplicate;
+ int numhaptics;
+
+ numhaptics = 0;
+
+ i = 0;
+ for (j = 0; j < MAX_HAPTICS; ++j) {
+
+ snprintf(path, PATH_MAX, joydev_pattern, i++);
+
+ /* check to see if file exists */
+ if (stat(path,&sb) != 0)
+ break;
+
+ /* check for duplicates */
+ duplicate = 0;
+ for (k = 0; (k < numhaptics) && !duplicate; ++k) {
+ if (sb.st_rdev == dev_nums[k]) {
+ duplicate = 1;
+ }
+ }
+ if (duplicate) {
+ continue;
+ }
+
+ /* try to open */
+ fd = open(path, O_RDWR, 0);
+ if (fd < 0) continue;
+
+#ifdef DEBUG_INPUT_EVENTS
+ printf("Checking %s\n", path);
+#endif
+
+ /* see if it works */
+ if (EV_IsHaptic(fd)!=0) {
+ SDL_hapticlist[numhaptics].fname = SDL_strdup(path);
+ SDL_hapticlist[numhaptics].haptic = NULL;
+ dev_nums[numhaptics] = sb.st_rdev;
+ ++numhaptics;
+ }
+ close(fd);
+ }
+
+ return numhaptics;
+}
+
+
+const char *
+SDL_SYS_HapticName(int index)
+{
+ int fd;
+ static char namebuf[128];
+ char *name;
+
+ name = NULL;
+ fd = open(SDL_hapticlist[index].fname, O_RDONLY, 0);
+ if (fd >= 0) {
+ if (ioctl(fd, EVIOCGNAME(sizeof(namebuf)), namebuf) <= 0) {
+ name = SDL_hapticlist[index].fname;
+ }
+ else {
+ name = namebuf;
+ }
+ }
+ close(fd);
+
+ return name;
+}
+
+
+int
+SDL_SYS_HapticOpen(SDL_Haptic * haptic)
+{
+ /* TODO finish
+ int fd;
+
+ fd = open(SDL_hapticlist[haptic->index].fname, O_RDWR, 0);
+
+ if (fd < 0) {
+ SDL_SetError("Unable to open %s\n", SDL_hapticlist[haptic->index]);
+ return (-1);
+ }
+
+
+
+ return 0;
+ */
+}
+
+
+#endif /* SDL_HAPTIC_LINUX */