SDL  2.0
SDL_syshaptic.c
Go to the documentation of this file.
1 /*
2  Simple DirectMedia Layer
3  Copyright (C) 1997-2014 Sam Lantinga <slouken@libsdl.org>
4 
5  This software is provided 'as-is', without any express or implied
6  warranty. In no event will the authors be held liable for any damages
7  arising from the use of this software.
8 
9  Permission is granted to anyone to use this software for any purpose,
10  including commercial applications, and to alter it and redistribute it
11  freely, subject to the following restrictions:
12 
13  1. The origin of this software must not be misrepresented; you must not
14  claim that you wrote the original software. If you use this software
15  in a product, an acknowledgment in the product documentation would be
16  appreciated but is not required.
17  2. Altered source versions must be plainly marked as such, and must not be
18  misrepresented as being the original software.
19  3. This notice may not be removed or altered from any source distribution.
20 */
21 #include "../../SDL_internal.h"
22 
23 #ifdef SDL_HAPTIC_ANDROID
24 
25 #include "SDL_assert.h"
26 #include "SDL_timer.h"
27 #include "SDL_syshaptic_c.h"
28 #include "../SDL_syshaptic.h"
29 #include "SDL_haptic.h"
30 #include "../../core/android/SDL_android.h"
31 #include "SDL_joystick.h"
32 #include "../../joystick/SDL_sysjoystick.h" /* For the real SDL_Joystick */
33 #include "../../joystick/android/SDL_sysjoystick_c.h" /* For joystick hwdata */
34 
35 
36 typedef struct SDL_hapticlist_item
37 {
38  int device_id;
39  char *name;
40  SDL_Haptic *haptic;
41  struct SDL_hapticlist_item *next;
43 
45 static SDL_hapticlist_item *SDL_hapticlist_tail = NULL;
46 static int numhaptics = 0;
47 
48 
49 int
51 {
52  /* Support for device connect/disconnect is API >= 16 only,
53  * so we poll every three seconds
54  * Ref: http://developer.android.com/reference/android/hardware/input/InputManager.InputDeviceListener.html
55  */
56  static Uint32 timeout = 0;
57  if (SDL_TICKS_PASSED(SDL_GetTicks(), timeout)) {
58  timeout = SDL_GetTicks() + 3000;
60  }
61  return (numhaptics);
62 }
63 
64 int
66 {
67  return (numhaptics);
68 }
69 
70 static SDL_hapticlist_item *
71 HapticByOrder(int index)
72 {
74  if ((index < 0) || (index >= numhaptics)) {
75  return NULL;
76  }
77  while (index > 0) {
78  SDL_assert(item != NULL);
79  --index;
80  item = item->next;
81  }
82  return item;
83 }
84 
85 static SDL_hapticlist_item *
86 HapticByDevId (int device_id)
87 {
88  SDL_hapticlist_item *item;
89  for (item = SDL_hapticlist; item != NULL; item = item->next) {
90  if (device_id == item->device_id) {
91  /*SDL_Log("=+=+=+=+=+= HapticByDevId id [%d]", device_id);*/
92  return item;
93  }
94  }
95  return NULL;
96 }
97 
98 const char *
99 SDL_SYS_HapticName(int index)
100 {
101  SDL_hapticlist_item *item = HapticByOrder(index);
102  if (item == NULL ) {
103  SDL_SetError("No such device");
104  return NULL;
105  }
106  return item->name;
107 }
108 
109 
110 static SDL_hapticlist_item *
111 OpenHaptic(SDL_Haptic *haptic, SDL_hapticlist_item *item)
112 {
113  if (item == NULL ) {
114  SDL_SetError("No such device");
115  return NULL;
116  }
117  if (item->haptic != NULL) {
118  SDL_SetError("Haptic already opened");
119  return NULL;
120  }
121 
122  haptic->hwdata = (struct haptic_hwdata *)item;
123  item->haptic = haptic;
124 
125  haptic->supported = SDL_HAPTIC_LEFTRIGHT;
126  haptic->neffects = 1;
127  haptic->nplaying = haptic->neffects;
128  haptic->effects = (struct haptic_effect *)SDL_malloc (sizeof (struct haptic_effect) * haptic->neffects);
129  if (haptic->effects == NULL) {
130  SDL_OutOfMemory();
131  return NULL;
132  }
133  SDL_memset(haptic->effects, 0, sizeof (struct haptic_effect) * haptic->neffects);
134  return item;
135 }
136 
137 static SDL_hapticlist_item *
138 OpenHapticByOrder(SDL_Haptic *haptic, int index)
139 {
140  return OpenHaptic (haptic, HapticByOrder(index));
141 }
142 
143 static SDL_hapticlist_item *
144 OpenHapticByDevId(SDL_Haptic *haptic, int device_id)
145 {
146  return OpenHaptic (haptic, HapticByDevId(device_id));
147 }
148 
149 int
150 SDL_SYS_HapticOpen(SDL_Haptic *haptic)
151 {
152  return (OpenHapticByOrder(haptic, haptic->index) == NULL ? -1 : 0);
153 }
154 
155 
156 int
158 {
159  return 0;
160 }
161 
162 
163 int
164 SDL_SYS_JoystickIsHaptic(SDL_Joystick *joystick)
165 {
166  SDL_hapticlist_item *item;
167  item = HapticByDevId(((joystick_hwdata *)joystick->hwdata)->device_id);
168  int ret = (item != NULL ? 1 : 0);
169  return ret;
170 }
171 
172 
173 int
174 SDL_SYS_HapticOpenFromJoystick(SDL_Haptic *haptic, SDL_Joystick *joystick)
175 {
176  return (OpenHapticByDevId(haptic, ((joystick_hwdata *)joystick->hwdata)->device_id) == NULL ? -1 : 0);
177 }
178 
179 
180 int
181 SDL_SYS_JoystickSameHaptic(SDL_Haptic * haptic, SDL_Joystick * joystick)
182 {
183  return (((SDL_hapticlist_item *)haptic->hwdata)->device_id == ((joystick_hwdata *)joystick->hwdata)->device_id ? 1 : 0);
184 }
185 
186 
187 void
188 SDL_SYS_HapticClose(SDL_Haptic * haptic)
189 {
190  ((SDL_hapticlist_item *)haptic->hwdata)->haptic = NULL;
191  haptic->hwdata = NULL;
192  return;
193 }
194 
195 
196 void
197 SDL_SYS_HapticQuit(void)
198 {
199  SDL_hapticlist_item *item = NULL;
201 
202  for (item = SDL_hapticlist; item; item = next) {
203  next = item->next;
204  SDL_free(item);
205  }
206 
207  SDL_hapticlist = SDL_hapticlist_tail = NULL;
208  numhaptics = 0;
209  return;
210 }
211 
212 
213 int
214 SDL_SYS_HapticNewEffect(SDL_Haptic * haptic,
215  struct haptic_effect *effect, SDL_HapticEffect * base)
216 {
217  return 0;
218 }
219 
220 
221 int
222 SDL_SYS_HapticUpdateEffect(SDL_Haptic * haptic,
223  struct haptic_effect *effect,
225 {
226  return 0;
227 }
228 
229 
230 int
231 SDL_SYS_HapticRunEffect(SDL_Haptic * haptic, struct haptic_effect *effect,
233 {
234  Android_JNI_HapticRun (((SDL_hapticlist_item *)haptic->hwdata)->device_id, effect->effect.leftright.length);
235  return 0;
236 }
237 
238 
239 int
240 SDL_SYS_HapticStopEffect(SDL_Haptic * haptic, struct haptic_effect *effect)
241 {
242  return 0;
243 }
244 
245 
246 void
247 SDL_SYS_HapticDestroyEffect(SDL_Haptic * haptic, struct haptic_effect *effect)
248 {
249  return;
250 }
251 
252 
253 int
254 SDL_SYS_HapticGetEffectStatus(SDL_Haptic * haptic,
255  struct haptic_effect *effect)
256 {
257  return 0;
258 }
259 
260 
261 int
262 SDL_SYS_HapticSetGain(SDL_Haptic * haptic, int gain)
263 {
264  return 0;
265 }
266 
267 
268 int
269 SDL_SYS_HapticSetAutocenter(SDL_Haptic * haptic, int autocenter)
270 {
271  return 0;
272 }
273 
274 int
275 SDL_SYS_HapticPause(SDL_Haptic * haptic)
276 {
277  return 0;
278 }
279 
280 int
281 SDL_SYS_HapticUnpause(SDL_Haptic * haptic)
282 {
283  return 0;
284 }
285 
286 int
287 SDL_SYS_HapticStopAll(SDL_Haptic * haptic)
288 {
289  return 0;
290 }
291 
292 
293 
294 int
295 Android_AddHaptic(int device_id, const char *name)
296 {
297  SDL_hapticlist_item *item;
298  item = (SDL_hapticlist_item *) SDL_calloc(1, sizeof (SDL_hapticlist_item));
299  if (item == NULL) {
300  return -1;
301  }
302 
303  item->device_id = device_id;
304  item->name = SDL_strdup (name);
305  if (item->name == NULL) {
306  SDL_free (item);
307  return -1;
308  }
309 
310  if (SDL_hapticlist_tail == NULL) {
311  SDL_hapticlist = SDL_hapticlist_tail = item;
312  } else {
313  SDL_hapticlist_tail->next = item;
314  SDL_hapticlist_tail = item;
315  }
316 
317  ++numhaptics;
318  return numhaptics;
319 }
320 
321 int
322 Android_RemoveHaptic(int device_id)
323 {
324  SDL_hapticlist_item *item;
325  SDL_hapticlist_item *prev = NULL;
326 
327  for (item = SDL_hapticlist; item != NULL; item = item->next) {
328  /* found it, remove it. */
329  if (device_id == item->device_id) {
330  const int retval = item->haptic ? item->haptic->index : -1;
331 
332  if (prev != NULL) {
333  prev->next = item->next;
334  } else {
335  SDL_assert(SDL_hapticlist == item);
336  SDL_hapticlist = item->next;
337  }
338  if (item == SDL_hapticlist_tail) {
339  SDL_hapticlist_tail = prev;
340  }
341 
342  /* Need to decrement the haptic count */
343  --numhaptics;
344  /* !!! TODO: Send a haptic remove event? */
345 
346  SDL_free(item->name);
347  SDL_free(item);
348  return retval;
349  }
350  prev = item;
351  }
352  return -1;
353 }
354 
355 
356 #endif /* SDL_HAPTIC_ANDROID */
357 
358 /* vi: set ts=4 sw=4 expandtab: */
int SDL_SYS_HapticOpenFromJoystick(SDL_Haptic *haptic, SDL_Joystick *joystick)
int SDL_SYS_HapticOpen(SDL_Haptic *haptic)
int SDL_SYS_HapticMouse(void)
int SDL_SYS_JoystickSameHaptic(SDL_Haptic *haptic, SDL_Joystick *joystick)
int SDL_SYS_HapticStopEffect(SDL_Haptic *haptic, struct haptic_effect *effect)
const char * SDL_SYS_HapticName(int index)
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: SDL_opengl.h:1974
The SDL haptic subsystem allows you to control haptic (force feedback) devices.
int SDL_SYS_HapticUnpause(SDL_Haptic *haptic)
static int iterations
Definition: testsprite2.c:43
uint32_t Uint32
An unsigned 32-bit integer type.
Definition: SDL_stdinc.h:169
int SDL_SYS_NumHaptics(void)
int SDL_SYS_HapticGetEffectStatus(SDL_Haptic *haptic, struct haptic_effect *effect)
GLuint const GLchar * name
SDL_hapticlist_item * SDL_hapticlist
struct SDL_hapticlist_item * next
SDL_bool retval
void * SDL_calloc(size_t nmemb, size_t size)
The generic template for any haptic effect.
Definition: SDL_haptic.h:789
int SDL_SYS_HapticSetAutocenter(SDL_Haptic *haptic, int autocenter)
Uint32 SDL_GetTicks(void)
Get the number of milliseconds since the SDL library initialization.
void SDL_free(void *mem)
int SDL_SYS_HapticUpdateEffect(SDL_Haptic *haptic, struct haptic_effect *effect, SDL_HapticEffect *data)
int SDL_SYS_JoystickIsHaptic(SDL_Joystick *joystick)
void Android_JNI_PollHapticDevices(void)
GLuint index
void SDL_SYS_HapticDestroyEffect(SDL_Haptic *haptic, struct haptic_effect *effect)
#define SDL_assert(condition)
Definition: SDL_assert.h:169
#define NULL
Definition: begin_code.h:164
#define SDL_OutOfMemory()
Definition: SDL_error.h:52
SDL_HapticEffect effect
Definition: SDL_syshaptic.h:32
int SDL_SYS_HapticInit(void)
void SDL_SYS_HapticQuit(void)
#define SDL_SetError
void SDL_SYS_HapticClose(SDL_Haptic *haptic)
int SDL_SYS_HapticPause(SDL_Haptic *haptic)
SDL_HapticLeftRight leftright
Definition: SDL_haptic.h:797
#define SDL_strdup
GLbitfield GLuint64 timeout
int SDL_SYS_HapticStopAll(SDL_Haptic *haptic)
#define SDL_malloc
int SDL_SYS_HapticSetGain(SDL_Haptic *haptic, int gain)
#define SDL_TICKS_PASSED(A, B)
Compare SDL ticks values, and return true if A has passed B.
Definition: SDL_timer.h:56
#define SDL_HAPTIC_LEFTRIGHT
Left/Right effect supported.
Definition: SDL_haptic.h:172
int SDL_SYS_HapticRunEffect(SDL_Haptic *haptic, struct haptic_effect *effect, Uint32 iterations)
void Android_JNI_HapticRun(int device_id, int length)
#define SDL_memset
int SDL_SYS_HapticNewEffect(SDL_Haptic *haptic, struct haptic_effect *effect, SDL_HapticEffect *base)