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;
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 *
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 /* We don't have any way to scan for joysticks (and their vibrators) at init, so don't wipe the list
199  * of joysticks here in case this is a reinit.
200  */
201 #if 0
202  SDL_hapticlist_item *item = NULL;
203  SDL_hapticlist_item *next = NULL;
204 
205  for (item = SDL_hapticlist; item; item = next) {
206  next = item->next;
207  SDL_free(item);
208  }
209 
210  SDL_hapticlist = SDL_hapticlist_tail = NULL;
211  numhaptics = 0;
212  return;
213 #endif
214 }
215 
216 
217 int
218 SDL_SYS_HapticNewEffect(SDL_Haptic * haptic,
219  struct haptic_effect *effect, SDL_HapticEffect * base)
220 {
221  return 0;
222 }
223 
224 
225 int
227  struct haptic_effect *effect,
229 {
230  return 0;
231 }
232 
233 
234 int
235 SDL_SYS_HapticRunEffect(SDL_Haptic * haptic, struct haptic_effect *effect,
237 {
238  float large = effect->effect.leftright.large_magnitude / 32767.0f;
239  float small = effect->effect.leftright.small_magnitude / 32767.0f;
240 
241  float total = (large * 0.6f) + (small * 0.4f);
242 
243  Android_JNI_HapticRun (((SDL_hapticlist_item *)haptic->hwdata)->device_id, total, effect->effect.leftright.length);
244  return 0;
245 }
246 
247 
248 int
250 {
251  Android_JNI_HapticStop (((SDL_hapticlist_item *)haptic->hwdata)->device_id);
252  return 0;
253 }
254 
255 
256 void
258 {
259  return;
260 }
261 
262 
263 int
265  struct haptic_effect *effect)
266 {
267  return 0;
268 }
269 
270 
271 int
272 SDL_SYS_HapticSetGain(SDL_Haptic * haptic, int gain)
273 {
274  return 0;
275 }
276 
277 
278 int
279 SDL_SYS_HapticSetAutocenter(SDL_Haptic * haptic, int autocenter)
280 {
281  return 0;
282 }
283 
284 int
285 SDL_SYS_HapticPause(SDL_Haptic * haptic)
286 {
287  return 0;
288 }
289 
290 int
291 SDL_SYS_HapticUnpause(SDL_Haptic * haptic)
292 {
293  return 0;
294 }
295 
296 int
297 SDL_SYS_HapticStopAll(SDL_Haptic * haptic)
298 {
299  return 0;
300 }
301 
302 
303 
304 int
305 Android_AddHaptic(int device_id, const char *name)
306 {
307  SDL_hapticlist_item *item;
308  item = (SDL_hapticlist_item *) SDL_calloc(1, sizeof (SDL_hapticlist_item));
309  if (item == NULL) {
310  return -1;
311  }
312 
313  item->device_id = device_id;
314  item->name = SDL_strdup (name);
315  if (item->name == NULL) {
316  SDL_free (item);
317  return -1;
318  }
319 
320  if (SDL_hapticlist_tail == NULL) {
321  SDL_hapticlist = SDL_hapticlist_tail = item;
322  } else {
323  SDL_hapticlist_tail->next = item;
324  SDL_hapticlist_tail = item;
325  }
326 
327  ++numhaptics;
328  return numhaptics;
329 }
330 
331 int
332 Android_RemoveHaptic(int device_id)
333 {
334  SDL_hapticlist_item *item;
335  SDL_hapticlist_item *prev = NULL;
336 
337  for (item = SDL_hapticlist; item != NULL; item = item->next) {
338  /* found it, remove it. */
339  if (device_id == item->device_id) {
340  const int retval = item->haptic ? item->haptic->index : -1;
341 
342  if (prev != NULL) {
343  prev->next = item->next;
344  } else {
345  SDL_assert(SDL_hapticlist == item);
346  SDL_hapticlist = item->next;
347  }
348  if (item == SDL_hapticlist_tail) {
349  SDL_hapticlist_tail = prev;
350  }
351 
352  /* Need to decrement the haptic count */
353  --numhaptics;
354  /* !!! TODO: Send a haptic remove event? */
355 
356  SDL_free(item->name);
357  SDL_free(item);
358  return retval;
359  }
360  prev = item;
361  }
362  return -1;
363 }
364 
365 
366 #endif /* SDL_HAPTIC_ANDROID */
367 
368 /* vi: set ts=4 sw=4 expandtab: */
SDL_HAPTIC_LEFTRIGHT
#define SDL_HAPTIC_LEFTRIGHT
Left/Right effect supported.
Definition: SDL_haptic.h:183
SDL_memset
#define SDL_memset
Definition: SDL_dynapi_overrides.h:386
SDL_SYS_HapticPause
int SDL_SYS_HapticPause(SDL_Haptic *haptic)
Android_JNI_HapticRun
void Android_JNI_HapticRun(int device_id, float intensity, int length)
NULL
#define NULL
Definition: begin_code.h:164
SDL_HapticLeftRight::large_magnitude
Uint16 large_magnitude
Definition: SDL_haptic.h:685
SDL_timer.h
SDL_SYS_HapticName
const char * SDL_SYS_HapticName(int index)
timeout
GLbitfield GLuint64 timeout
Definition: SDL_opengl_glext.h:1483
SDL_joystick.h
SDL_SYS_HapticUnpause
int SDL_SYS_HapticUnpause(SDL_Haptic *haptic)
SDL_hapticlist_item
Definition: SDL_windowshaptic_c.h:68
iterations
static int iterations
Definition: testsprite2.c:43
SDL_SYS_HapticInit
int SDL_SYS_HapticInit(void)
Uint32
uint32_t Uint32
Definition: SDL_stdinc.h:203
SDL_SYS_HapticUpdateEffect
int SDL_SYS_HapticUpdateEffect(SDL_Haptic *haptic, struct haptic_effect *effect, SDL_HapticEffect *data)
SDL_HapticEffect::leftright
SDL_HapticLeftRight leftright
Definition: SDL_haptic.h:808
index
GLuint index
Definition: SDL_opengl_glext.h:660
haptic_effect::effect
SDL_HapticEffect effect
Definition: SDL_syshaptic.h:32
data
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: SDL_opengl.h:1974
SDL_SYS_HapticDestroyEffect
void SDL_SYS_HapticDestroyEffect(SDL_Haptic *haptic, struct haptic_effect *effect)
haptic_hwdata
Definition: SDL_windowshaptic_c.h:35
SDL_HapticLeftRight::length
Uint32 length
Definition: SDL_haptic.h:682
SDL_SYS_HapticRunEffect
int SDL_SYS_HapticRunEffect(SDL_Haptic *haptic, struct haptic_effect *effect, Uint32 iterations)
SDL_haptic.h
The SDL haptic subsystem allows you to control haptic (force feedback) devices.
SDL_SYS_HapticQuit
void SDL_SYS_HapticQuit(void)
SDL_SYS_HapticSetGain
int SDL_SYS_HapticSetGain(SDL_Haptic *haptic, int gain)
retval
SDL_bool retval
Definition: testgamecontroller.c:65
SDL_SYS_HapticGetEffectStatus
int SDL_SYS_HapticGetEffectStatus(SDL_Haptic *haptic, struct haptic_effect *effect)
SDL_free
#define SDL_free
Definition: SDL_dynapi_overrides.h:377
SDL_HapticEffect
The generic template for any haptic effect.
Definition: SDL_haptic.h:801
f
GLfloat f
Definition: SDL_opengl_glext.h:1870
name
GLuint const GLchar * name
Definition: SDL_opengl_glext.h:660
SDL_SYS_HapticStopEffect
int SDL_SYS_HapticStopEffect(SDL_Haptic *haptic, struct haptic_effect *effect)
SDL_assert.h
SDL_GetTicks
Uint32 SDL_GetTicks(void)
Get the number of milliseconds since the SDL library initialization.
haptic_effect
Definition: SDL_syshaptic.h:31
SDL_SYS_HapticStopAll
int SDL_SYS_HapticStopAll(SDL_Haptic *haptic)
SDL_HapticLeftRight::small_magnitude
Uint16 small_magnitude
Definition: SDL_haptic.h:686
SDL_SYS_HapticClose
void SDL_SYS_HapticClose(SDL_Haptic *haptic)
SDL_assert
#define SDL_assert(condition)
Definition: SDL_assert.h:169
SDL_OutOfMemory
#define SDL_OutOfMemory()
Definition: SDL_error.h:52
SDL_hapticlist_item::next
struct SDL_hapticlist_item * next
Definition: SDL_windowshaptic_c.h:77
Android_JNI_PollHapticDevices
void Android_JNI_PollHapticDevices(void)
SDL_SYS_HapticOpen
int SDL_SYS_HapticOpen(SDL_Haptic *haptic)
SDL_SYS_HapticMouse
int SDL_SYS_HapticMouse(void)
SDL_calloc
#define SDL_calloc
Definition: SDL_dynapi_overrides.h:375
SDL_SYS_HapticNewEffect
int SDL_SYS_HapticNewEffect(SDL_Haptic *haptic, struct haptic_effect *effect, SDL_HapticEffect *base)
haptic
static SDL_Haptic * haptic
Definition: testhaptic.c:25
SDL_hapticlist_item::haptic
SDL_Haptic * haptic
Definition: SDL_windowshaptic_c.h:70
SDL_SetError
#define SDL_SetError
Definition: SDL_dynapi_overrides.h:30
SDL_SYS_HapticSetAutocenter
int SDL_SYS_HapticSetAutocenter(SDL_Haptic *haptic, int autocenter)
SDL_hapticlist_item::name
char * name
Definition: SDL_windowshaptic_c.h:69
SDL_SYS_NumHaptics
int SDL_SYS_NumHaptics(void)
SDL_strdup
#define SDL_strdup
Definition: SDL_dynapi_overrides.h:397
Android_JNI_HapticStop
void Android_JNI_HapticStop(int device_id)
SDL_TICKS_PASSED
#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
SDL_hapticlist_item * SDL_hapticlist
SDL_SYS_JoystickIsHaptic
int SDL_SYS_JoystickIsHaptic(SDL_Joystick *joystick)
SDL_SYS_JoystickSameHaptic
int SDL_SYS_JoystickSameHaptic(SDL_Haptic *haptic, SDL_Joystick *joystick)
SDL_malloc
#define SDL_malloc
Definition: SDL_dynapi_overrides.h:374
SDL_SYS_HapticOpenFromJoystick
int SDL_SYS_HapticOpenFromJoystick(SDL_Haptic *haptic, SDL_Joystick *joystick)
joystick_hwdata
Definition: SDL_sysjoystick_c.h:47