SDL  2.0
SDL_syshaptic.c
Go to the documentation of this file.
1 /*
2  Simple DirectMedia Layer
3  Copyright (C) 1997-2020 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_timer.h"
26 #include "SDL_syshaptic_c.h"
27 #include "../SDL_syshaptic.h"
28 #include "SDL_haptic.h"
29 #include "../../core/android/SDL_android.h"
30 #include "SDL_joystick.h"
31 #include "../../joystick/SDL_sysjoystick.h" /* For the real SDL_Joystick */
32 #include "../../joystick/android/SDL_sysjoystick_c.h" /* For joystick hwdata */
33 
34 
35 typedef struct SDL_hapticlist_item
36 {
37  int device_id;
38  char *name;
39  SDL_Haptic *haptic;
40  struct SDL_hapticlist_item *next;
42 
44 static SDL_hapticlist_item *SDL_hapticlist_tail = NULL;
45 static int numhaptics = 0;
46 
47 
48 int
50 {
51  /* Support for device connect/disconnect is API >= 16 only,
52  * so we poll every three seconds
53  * Ref: http://developer.android.com/reference/android/hardware/input/InputManager.InputDeviceListener.html
54  */
55  static Uint32 timeout = 0;
57  timeout = SDL_GetTicks() + 3000;
59  }
60  return (numhaptics);
61 }
62 
63 int
65 {
66  return (numhaptics);
67 }
68 
69 static SDL_hapticlist_item *
70 HapticByOrder(int index)
71 {
73  if ((index < 0) || (index >= numhaptics)) {
74  return NULL;
75  }
76  while (index > 0) {
77  SDL_assert(item != NULL);
78  --index;
79  item = item->next;
80  }
81  return item;
82 }
83 
84 static SDL_hapticlist_item *
85 HapticByDevId (int device_id)
86 {
87  SDL_hapticlist_item *item;
88  for (item = SDL_hapticlist; item != NULL; item = item->next) {
89  if (device_id == item->device_id) {
90  /*SDL_Log("=+=+=+=+=+= HapticByDevId id [%d]", device_id);*/
91  return item;
92  }
93  }
94  return NULL;
95 }
96 
97 const char *
99 {
100  SDL_hapticlist_item *item = HapticByOrder(index);
101  if (item == NULL ) {
102  SDL_SetError("No such device");
103  return NULL;
104  }
105  return item->name;
106 }
107 
108 
109 static SDL_hapticlist_item *
110 OpenHaptic(SDL_Haptic *haptic, SDL_hapticlist_item *item)
111 {
112  if (item == NULL ) {
113  SDL_SetError("No such device");
114  return NULL;
115  }
116  if (item->haptic != NULL) {
117  SDL_SetError("Haptic already opened");
118  return NULL;
119  }
120 
121  haptic->hwdata = (struct haptic_hwdata *)item;
122  item->haptic = haptic;
123 
124  haptic->supported = SDL_HAPTIC_LEFTRIGHT;
125  haptic->neffects = 1;
126  haptic->nplaying = haptic->neffects;
127  haptic->effects = (struct haptic_effect *)SDL_malloc (sizeof (struct haptic_effect) * haptic->neffects);
128  if (haptic->effects == NULL) {
129  SDL_OutOfMemory();
130  return NULL;
131  }
132  SDL_memset(haptic->effects, 0, sizeof (struct haptic_effect) * haptic->neffects);
133  return item;
134 }
135 
136 static SDL_hapticlist_item *
137 OpenHapticByOrder(SDL_Haptic *haptic, int index)
138 {
139  return OpenHaptic (haptic, HapticByOrder(index));
140 }
141 
142 static SDL_hapticlist_item *
143 OpenHapticByDevId(SDL_Haptic *haptic, int device_id)
144 {
145  return OpenHaptic (haptic, HapticByDevId(device_id));
146 }
147 
148 int
149 SDL_SYS_HapticOpen(SDL_Haptic *haptic)
150 {
151  return (OpenHapticByOrder(haptic, haptic->index) == NULL ? -1 : 0);
152 }
153 
154 
155 int
157 {
158  return 0;
159 }
160 
161 
162 int
163 SDL_SYS_JoystickIsHaptic(SDL_Joystick *joystick)
164 {
165  SDL_hapticlist_item *item;
166  item = HapticByDevId(((joystick_hwdata *)joystick->hwdata)->device_id);
167  return (item != NULL) ? 1 : 0;
168 }
169 
170 
171 int
172 SDL_SYS_HapticOpenFromJoystick(SDL_Haptic *haptic, SDL_Joystick *joystick)
173 {
174  return (OpenHapticByDevId(haptic, ((joystick_hwdata *)joystick->hwdata)->device_id) == NULL ? -1 : 0);
175 }
176 
177 
178 int
179 SDL_SYS_JoystickSameHaptic(SDL_Haptic * haptic, SDL_Joystick * joystick)
180 {
181  return (((SDL_hapticlist_item *)haptic->hwdata)->device_id == ((joystick_hwdata *)joystick->hwdata)->device_id ? 1 : 0);
182 }
183 
184 
185 void
186 SDL_SYS_HapticClose(SDL_Haptic * haptic)
187 {
188  ((SDL_hapticlist_item *)haptic->hwdata)->haptic = NULL;
189  haptic->hwdata = NULL;
190  return;
191 }
192 
193 
194 void
195 SDL_SYS_HapticQuit(void)
196 {
197 /* We don't have any way to scan for joysticks (and their vibrators) at init, so don't wipe the list
198  * of joysticks here in case this is a reinit.
199  */
200 #if 0
201  SDL_hapticlist_item *item = NULL;
202  SDL_hapticlist_item *next = NULL;
203 
204  for (item = SDL_hapticlist; item; item = next) {
205  next = item->next;
206  SDL_free(item);
207  }
208 
209  SDL_hapticlist = SDL_hapticlist_tail = NULL;
210  numhaptics = 0;
211  return;
212 #endif
213 }
214 
215 
216 int
217 SDL_SYS_HapticNewEffect(SDL_Haptic * haptic,
219 {
220  return 0;
221 }
222 
223 
224 int
226  struct haptic_effect *effect,
228 {
229  return 0;
230 }
231 
232 
233 int
234 SDL_SYS_HapticRunEffect(SDL_Haptic * haptic, struct haptic_effect *effect,
236 {
237  float large = effect->effect.leftright.large_magnitude / 32767.0f;
238  float small = effect->effect.leftright.small_magnitude / 32767.0f;
239 
240  float total = (large * 0.6f) + (small * 0.4f);
241 
242  Android_JNI_HapticRun (((SDL_hapticlist_item *)haptic->hwdata)->device_id, total, effect->effect.leftright.length);
243  return 0;
244 }
245 
246 
247 int
249 {
250  Android_JNI_HapticStop (((SDL_hapticlist_item *)haptic->hwdata)->device_id);
251  return 0;
252 }
253 
254 
255 void
257 {
258  return;
259 }
260 
261 
262 int
264  struct haptic_effect *effect)
265 {
266  return 0;
267 }
268 
269 
270 int
271 SDL_SYS_HapticSetGain(SDL_Haptic * haptic, int gain)
272 {
273  return 0;
274 }
275 
276 
277 int
278 SDL_SYS_HapticSetAutocenter(SDL_Haptic * haptic, int autocenter)
279 {
280  return 0;
281 }
282 
283 int
284 SDL_SYS_HapticPause(SDL_Haptic * haptic)
285 {
286  return 0;
287 }
288 
289 int
290 SDL_SYS_HapticUnpause(SDL_Haptic * haptic)
291 {
292  return 0;
293 }
294 
295 int
296 SDL_SYS_HapticStopAll(SDL_Haptic * haptic)
297 {
298  return 0;
299 }
300 
301 
302 
303 int
304 Android_AddHaptic(int device_id, const char *name)
305 {
306  SDL_hapticlist_item *item;
307  item = (SDL_hapticlist_item *) SDL_calloc(1, sizeof (SDL_hapticlist_item));
308  if (item == NULL) {
309  return -1;
310  }
311 
312  item->device_id = device_id;
313  item->name = SDL_strdup (name);
314  if (item->name == NULL) {
315  SDL_free (item);
316  return -1;
317  }
318 
319  if (SDL_hapticlist_tail == NULL) {
320  SDL_hapticlist = SDL_hapticlist_tail = item;
321  } else {
322  SDL_hapticlist_tail->next = item;
323  SDL_hapticlist_tail = item;
324  }
325 
326  ++numhaptics;
327  return numhaptics;
328 }
329 
330 int
331 Android_RemoveHaptic(int device_id)
332 {
333  SDL_hapticlist_item *item;
334  SDL_hapticlist_item *prev = NULL;
335 
336  for (item = SDL_hapticlist; item != NULL; item = item->next) {
337  /* found it, remove it. */
338  if (device_id == item->device_id) {
339  const int retval = item->haptic ? item->haptic->index : -1;
340 
341  if (prev != NULL) {
342  prev->next = item->next;
343  } else {
344  SDL_assert(SDL_hapticlist == item);
345  SDL_hapticlist = item->next;
346  }
347  if (item == SDL_hapticlist_tail) {
348  SDL_hapticlist_tail = prev;
349  }
350 
351  /* Need to decrement the haptic count */
352  --numhaptics;
353  /* !!! TODO: Send a haptic remove event? */
354 
355  SDL_free(item->name);
356  SDL_free(item);
357  return retval;
358  }
359  prev = item;
360  }
361  return -1;
362 }
363 
364 
365 #endif /* SDL_HAPTIC_ANDROID */
366 
367 /* vi: set ts=4 sw=4 expandtab: */
void Android_JNI_HapticRun(int device_id, float intensity, int length)
void Android_JNI_PollHapticDevices(void)
void Android_JNI_HapticStop(int device_id)
#define SDL_assert(condition)
Definition: SDL_assert.h:171
#define SDL_SetError
#define SDL_memset
#define SDL_malloc
#define SDL_free
#define SDL_strdup
#define SDL_calloc
#define SDL_OutOfMemory()
Definition: SDL_error.h:88
The SDL haptic subsystem allows you to control haptic (force feedback) devices.
#define SDL_HAPTIC_LEFTRIGHT
Left/Right effect supported.
Definition: SDL_haptic.h:183
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: SDL_opengl.h:1974
GLuint index
GLbitfield GLuint64 timeout
GLuint const GLchar * name
uint32_t Uint32
Definition: SDL_stdinc.h:209
void SDL_SYS_HapticClose(SDL_Haptic *haptic)
int SDL_SYS_HapticStopEffect(SDL_Haptic *haptic, struct haptic_effect *effect)
int SDL_SYS_HapticPause(SDL_Haptic *haptic)
int SDL_SYS_HapticSetGain(SDL_Haptic *haptic, int gain)
const char * SDL_SYS_HapticName(int index)
void SDL_SYS_HapticQuit(void)
int SDL_SYS_JoystickSameHaptic(SDL_Haptic *haptic, SDL_Joystick *joystick)
int SDL_SYS_HapticMouse(void)
int SDL_SYS_HapticUnpause(SDL_Haptic *haptic)
int SDL_SYS_HapticSetAutocenter(SDL_Haptic *haptic, int autocenter)
int SDL_SYS_HapticUpdateEffect(SDL_Haptic *haptic, struct haptic_effect *effect, SDL_HapticEffect *data)
int SDL_SYS_HapticStopAll(SDL_Haptic *haptic)
int SDL_SYS_HapticNewEffect(SDL_Haptic *haptic, struct haptic_effect *effect, SDL_HapticEffect *base)
int SDL_SYS_NumHaptics(void)
void SDL_SYS_HapticDestroyEffect(SDL_Haptic *haptic, struct haptic_effect *effect)
int SDL_SYS_HapticRunEffect(SDL_Haptic *haptic, struct haptic_effect *effect, Uint32 iterations)
int SDL_SYS_HapticOpenFromJoystick(SDL_Haptic *haptic, SDL_Joystick *joystick)
int SDL_SYS_HapticOpen(SDL_Haptic *haptic)
int SDL_SYS_HapticGetEffectStatus(SDL_Haptic *haptic, struct haptic_effect *effect)
int SDL_SYS_HapticInit(void)
int SDL_SYS_JoystickIsHaptic(SDL_Joystick *joystick)
Uint32 SDL_GetTicks(void)
Get the number of milliseconds since the SDL library initialization.
#define SDL_TICKS_PASSED(A, B)
Compare SDL ticks values, and return true if A has passed B.
Definition: SDL_timer.h:56
SDL_hapticlist_item * SDL_hapticlist
#define NULL
Definition: begin_code.h:163
set set set set set set set set set set set set set set set set set set set set *set set set macro pixldst base
struct SDL_hapticlist_item * next
SDL_HapticEffect effect
Definition: SDL_syshaptic.h:32
SDL_bool retval
static SDL_Haptic * haptic
Definition: testhaptic.c:25
static SDL_Joystick * joystick
Definition: testjoystick.c:37
static int iterations
Definition: testsprite2.c:45
The generic template for any haptic effect.
Definition: SDL_haptic.h:810
SDL_HapticLeftRight leftright
Definition: SDL_haptic.h:817