SDL  2.0
SDL_syshaptic.c
Go to the documentation of this file.
1 /*
2  Simple DirectMedia Layer
3  Copyright (C) 1997-2018 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  return (item != NULL) ? 1 : 0;
169 }
170 
171 
172 int
173 SDL_SYS_HapticOpenFromJoystick(SDL_Haptic *haptic, SDL_Joystick *joystick)
174 {
175  return (OpenHapticByDevId(haptic, ((joystick_hwdata *)joystick->hwdata)->device_id) == NULL ? -1 : 0);
176 }
177 
178 
179 int
180 SDL_SYS_JoystickSameHaptic(SDL_Haptic * haptic, SDL_Joystick * joystick)
181 {
182  return (((SDL_hapticlist_item *)haptic->hwdata)->device_id == ((joystick_hwdata *)joystick->hwdata)->device_id ? 1 : 0);
183 }
184 
185 
186 void
187 SDL_SYS_HapticClose(SDL_Haptic * haptic)
188 {
189  ((SDL_hapticlist_item *)haptic->hwdata)->haptic = NULL;
190  haptic->hwdata = NULL;
191  return;
192 }
193 
194 
195 void
196 SDL_SYS_HapticQuit(void)
197 {
198  SDL_hapticlist_item *item = NULL;
200 
201  for (item = SDL_hapticlist; item; item = next) {
202  next = item->next;
203  SDL_free(item);
204  }
205 
206  SDL_hapticlist = SDL_hapticlist_tail = NULL;
207  numhaptics = 0;
208  return;
209 }
210 
211 
212 int
213 SDL_SYS_HapticNewEffect(SDL_Haptic * haptic,
214  struct haptic_effect *effect, SDL_HapticEffect * base)
215 {
216  return 0;
217 }
218 
219 
220 int
221 SDL_SYS_HapticUpdateEffect(SDL_Haptic * haptic,
222  struct haptic_effect *effect,
224 {
225  return 0;
226 }
227 
228 
229 int
230 SDL_SYS_HapticRunEffect(SDL_Haptic * haptic, struct haptic_effect *effect,
232 {
233  Android_JNI_HapticRun (((SDL_hapticlist_item *)haptic->hwdata)->device_id, effect->effect.leftright.length);
234  return 0;
235 }
236 
237 
238 int
239 SDL_SYS_HapticStopEffect(SDL_Haptic * haptic, struct haptic_effect *effect)
240 {
241  return 0;
242 }
243 
244 
245 void
246 SDL_SYS_HapticDestroyEffect(SDL_Haptic * haptic, struct haptic_effect *effect)
247 {
248  return;
249 }
250 
251 
252 int
253 SDL_SYS_HapticGetEffectStatus(SDL_Haptic * haptic,
254  struct haptic_effect *effect)
255 {
256  return 0;
257 }
258 
259 
260 int
261 SDL_SYS_HapticSetGain(SDL_Haptic * haptic, int gain)
262 {
263  return 0;
264 }
265 
266 
267 int
268 SDL_SYS_HapticSetAutocenter(SDL_Haptic * haptic, int autocenter)
269 {
270  return 0;
271 }
272 
273 int
274 SDL_SYS_HapticPause(SDL_Haptic * haptic)
275 {
276  return 0;
277 }
278 
279 int
280 SDL_SYS_HapticUnpause(SDL_Haptic * haptic)
281 {
282  return 0;
283 }
284 
285 int
286 SDL_SYS_HapticStopAll(SDL_Haptic * haptic)
287 {
288  return 0;
289 }
290 
291 
292 
293 int
294 Android_AddHaptic(int device_id, const char *name)
295 {
296  SDL_hapticlist_item *item;
297  item = (SDL_hapticlist_item *) SDL_calloc(1, sizeof (SDL_hapticlist_item));
298  if (item == NULL) {
299  return -1;
300  }
301 
302  item->device_id = device_id;
303  item->name = SDL_strdup (name);
304  if (item->name == NULL) {
305  SDL_free (item);
306  return -1;
307  }
308 
309  if (SDL_hapticlist_tail == NULL) {
310  SDL_hapticlist = SDL_hapticlist_tail = item;
311  } else {
312  SDL_hapticlist_tail->next = item;
313  SDL_hapticlist_tail = item;
314  }
315 
316  ++numhaptics;
317  return numhaptics;
318 }
319 
320 int
321 Android_RemoveHaptic(int device_id)
322 {
323  SDL_hapticlist_item *item;
324  SDL_hapticlist_item *prev = NULL;
325 
326  for (item = SDL_hapticlist; item != NULL; item = item->next) {
327  /* found it, remove it. */
328  if (device_id == item->device_id) {
329  const int retval = item->haptic ? item->haptic->index : -1;
330 
331  if (prev != NULL) {
332  prev->next = item->next;
333  } else {
334  SDL_assert(SDL_hapticlist == item);
335  SDL_hapticlist = item->next;
336  }
337  if (item == SDL_hapticlist_tail) {
338  SDL_hapticlist_tail = prev;
339  }
340 
341  /* Need to decrement the haptic count */
342  --numhaptics;
343  /* !!! TODO: Send a haptic remove event? */
344 
345  SDL_free(item->name);
346  SDL_free(item);
347  return retval;
348  }
349  prev = item;
350  }
351  return -1;
352 }
353 
354 
355 #endif /* SDL_HAPTIC_ANDROID */
356 
357 /* 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
Definition: SDL_stdinc.h:181
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
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.
#define SDL_free
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)
#define SDL_calloc
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)