1 /*         ______   ___    ___
2  *        /\  _  \ /\_ \  /\_ \
3  *        \ \ \L\ \\//\ \ \//\ \      __     __   _ __   ___
4  *         \ \  __ \ \ \ \  \ \ \   /'__`\ /'_ `\/\`'__\/ __`\
5  *          \ \ \/\ \ \_\ \_ \_\ \_/\  __//\ \L\ \ \ \//\ \L\ \
6  *           \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/
7  *            \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/
8  *                                           /\____/
9  *                                           \_/__/
10  *
11  *      Haptic API.
12  *
13  *      By Beoran.
14  *
15  *      See LICENSE.txt for copyright information.
16  */
17 
18 
19 #include "allegro5/allegro.h"
20 #include "allegro5/haptic.h"
21 #include "allegro5/internal/aintern.h"
22 #include "allegro5/internal/aintern_events.h"
23 #include "allegro5/internal/aintern_exitfunc.h"
24 #include "allegro5/internal/aintern_haptic.h"
25 #include "allegro5/internal/aintern_system.h"
26 
27 
28 /* the active haptic driver */
29 static ALLEGRO_HAPTIC_DRIVER *haptic_driver = NULL;
30 
31 
32 /* Function: al_install_haptic
33  */
al_install_haptic(void)34 bool al_install_haptic(void)
35 {
36    ALLEGRO_SYSTEM *sysdrv;
37    ALLEGRO_HAPTIC_DRIVER *hapdrv;
38 
39    if (haptic_driver)
40       return true;
41 
42    sysdrv = al_get_system_driver();
43    ASSERT(sysdrv);
44 
45    /* Currently every platform only has at most one haptic driver. */
46    if (sysdrv->vt->get_haptic_driver) {
47       hapdrv = sysdrv->vt->get_haptic_driver();
48       /* Avoid race condition in case the haptic driver generates an
49        * event right after ->init_haptic.
50        */
51       if (hapdrv && hapdrv->init_haptic()) {
52          haptic_driver = hapdrv;
53          _al_add_exit_func(al_uninstall_haptic, "al_uninstall_haptic");
54          return true;
55       }
56    }
57 
58    return false;
59 }
60 
61 
62 /* Function: al_uninstall_haptic
63  */
al_uninstall_haptic(void)64 void al_uninstall_haptic(void)
65 {
66    if (haptic_driver) {
67       /* perform driver clean up */
68       haptic_driver->exit_haptic();
69       haptic_driver = NULL;
70    }
71 }
72 
73 
74 /* Function: al_is_haptic_installed
75  */
al_is_haptic_installed(void)76 bool al_is_haptic_installed(void)
77 {
78    return (haptic_driver) ? true : false;
79 }
80 
81 
82 /* Function: al_is_joystick_haptic
83  */
al_is_joystick_haptic(ALLEGRO_JOYSTICK * dev)84 bool al_is_joystick_haptic(ALLEGRO_JOYSTICK *dev)
85 {
86    ASSERT(dev);
87    ASSERT(haptic_driver);
88 
89    return haptic_driver->is_joystick_haptic(dev);
90 }
91 
92 
93 /* Function: al_is_mouse_haptic
94  */
al_is_mouse_haptic(ALLEGRO_MOUSE * dev)95 bool al_is_mouse_haptic(ALLEGRO_MOUSE *dev)
96 {
97    ASSERT(dev);
98    ASSERT(haptic_driver);
99 
100    return haptic_driver->is_mouse_haptic(dev);
101 }
102 
103 
104 /* Function: al_is_keyboard_haptic
105  */
al_is_keyboard_haptic(ALLEGRO_KEYBOARD * dev)106 bool al_is_keyboard_haptic(ALLEGRO_KEYBOARD *dev)
107 {
108    ASSERT(dev);
109    ASSERT(haptic_driver);
110 
111    return haptic_driver->is_keyboard_haptic(dev);
112 }
113 
114 
115 /* Function: al_is_display_haptic
116  */
al_is_display_haptic(ALLEGRO_DISPLAY * dev)117 bool al_is_display_haptic(ALLEGRO_DISPLAY *dev)
118 {
119    ASSERT(dev);
120    ASSERT(haptic_driver);
121 
122    return haptic_driver->is_display_haptic(dev);
123 }
124 
125 /* Function: al_is_touch_input_haptic
126  */
al_is_touch_input_haptic(ALLEGRO_TOUCH_INPUT * dev)127 bool al_is_touch_input_haptic(ALLEGRO_TOUCH_INPUT *dev)
128 {
129    ASSERT(dev);
130    ASSERT(haptic_driver);
131 
132    return haptic_driver->is_touch_input_haptic(dev);
133 }
134 
135 /* Function: al_get_haptic_from_joystick
136  */
al_get_haptic_from_joystick(ALLEGRO_JOYSTICK * dev)137 ALLEGRO_HAPTIC *al_get_haptic_from_joystick(ALLEGRO_JOYSTICK *dev)
138 {
139    ASSERT(dev);
140    ASSERT(haptic_driver);
141 
142    return haptic_driver->get_from_joystick(dev);
143 }
144 
145 
146 /* Function: al_get_haptic_from_mouse
147  */
al_get_haptic_from_mouse(ALLEGRO_MOUSE * dev)148 ALLEGRO_HAPTIC *al_get_haptic_from_mouse(ALLEGRO_MOUSE *dev)
149 {
150    ASSERT(dev);
151    ASSERT(haptic_driver);
152 
153    return haptic_driver->get_from_mouse(dev);
154 }
155 
156 
157 /* Function: al_get_haptic_from_keyboard
158  */
al_get_haptic_from_keyboard(ALLEGRO_KEYBOARD * dev)159 ALLEGRO_HAPTIC *al_get_haptic_from_keyboard(ALLEGRO_KEYBOARD *dev)
160 {
161    ASSERT(dev);
162    ASSERT(haptic_driver);
163 
164    return haptic_driver->get_from_keyboard(dev);
165 }
166 
167 
168 /* Function: al_get_haptic_from_display
169  */
al_get_haptic_from_display(ALLEGRO_DISPLAY * dev)170 ALLEGRO_HAPTIC *al_get_haptic_from_display(ALLEGRO_DISPLAY *dev)
171 {
172    ASSERT(dev);
173    ASSERT(haptic_driver);
174 
175    return haptic_driver->get_from_display(dev);
176 }
177 
178 
179 /* Function: al_get_haptic_from_touch_input
180  */
al_get_haptic_from_touch_input(ALLEGRO_TOUCH_INPUT * dev)181 ALLEGRO_HAPTIC *al_get_haptic_from_touch_input(ALLEGRO_TOUCH_INPUT *dev)
182 {
183    ASSERT(dev);
184    ASSERT(haptic_driver);
185 
186    return haptic_driver->get_from_touch_input(dev);
187 }
188 
189 
190 /* Function: al_is_haptic_active
191  */
al_is_haptic_active(ALLEGRO_HAPTIC * hap)192 bool al_is_haptic_active(ALLEGRO_HAPTIC *hap)
193 {
194    ASSERT(hap);
195    ASSERT(haptic_driver);
196 
197    return haptic_driver->get_active(hap);
198 }
199 
200 
201 /* Function: al_get_haptic_capabilities
202  */
al_get_haptic_capabilities(ALLEGRO_HAPTIC * hap)203 int al_get_haptic_capabilities(ALLEGRO_HAPTIC *hap)
204 {
205    ASSERT(hap);
206    ASSERT(haptic_driver);
207 
208    return haptic_driver->get_capabilities(hap);
209 }
210 
211 /* Function: al_is_haptic_capable
212  */
al_is_haptic_capable(ALLEGRO_HAPTIC * hap,int query)213 bool al_is_haptic_capable(ALLEGRO_HAPTIC * hap, int query) {
214   int capabilities = al_get_haptic_capabilities(hap);
215   return (capabilities & query) == query;
216 }
217 
218 /* Function: al_get_haptic_gain
219  */
al_get_haptic_gain(ALLEGRO_HAPTIC * hap)220 double al_get_haptic_gain(ALLEGRO_HAPTIC *hap)
221 {
222    ASSERT(hap);
223    ASSERT(haptic_driver);
224 
225    return haptic_driver->get_gain(hap);
226 }
227 
228 
229 /* Function: al_set_haptic_gain
230  */
al_set_haptic_gain(ALLEGRO_HAPTIC * hap,double gain)231 bool al_set_haptic_gain(ALLEGRO_HAPTIC *hap, double gain)
232 {
233    ASSERT(hap);
234    ASSERT(haptic_driver);
235 
236    return haptic_driver->set_gain(hap, gain);
237 }
238 
239 /* Function: al_get_haptic_autocenter
240  */
al_get_haptic_autocenter(ALLEGRO_HAPTIC * hap)241 double al_get_haptic_autocenter(ALLEGRO_HAPTIC *hap)
242 {
243    ASSERT(hap);
244    ASSERT(haptic_driver);
245 
246    return haptic_driver->get_autocenter(hap);
247 }
248 
249 
250 /* Function: al_set_haptic_autocenter
251  */
al_set_haptic_autocenter(ALLEGRO_HAPTIC * hap,double intensity)252 bool al_set_haptic_autocenter(ALLEGRO_HAPTIC *hap, double intensity)
253 {
254    ASSERT(hap);
255    ASSERT(haptic_driver);
256 
257    return haptic_driver->set_autocenter(hap, intensity);
258 }
259 
260 
261 
262 /* Function: al_get_max_haptic_effects
263  */
al_get_max_haptic_effects(ALLEGRO_HAPTIC * hap)264 int al_get_max_haptic_effects(ALLEGRO_HAPTIC *hap)
265 {
266    ASSERT(hap);
267    ASSERT(haptic_driver);
268 
269    return haptic_driver->get_max_effects(hap);
270 }
271 
272 
273 /* Function: al_is_haptic_effect_ok
274  */
al_is_haptic_effect_ok(ALLEGRO_HAPTIC * hap,ALLEGRO_HAPTIC_EFFECT * effect)275 bool al_is_haptic_effect_ok(ALLEGRO_HAPTIC *hap, ALLEGRO_HAPTIC_EFFECT *effect)
276 {
277    ASSERT(hap);
278    ASSERT(haptic_driver);
279 
280    return haptic_driver->is_effect_ok(hap, effect);
281 }
282 
283 
284 /* Function: al_upload_haptic_effect
285  */
al_upload_haptic_effect(ALLEGRO_HAPTIC * hap,ALLEGRO_HAPTIC_EFFECT * effect,ALLEGRO_HAPTIC_EFFECT_ID * id)286 bool al_upload_haptic_effect(ALLEGRO_HAPTIC *hap,
287    ALLEGRO_HAPTIC_EFFECT *effect, ALLEGRO_HAPTIC_EFFECT_ID *id)
288 {
289    ASSERT(hap);
290    ASSERT(haptic_driver);
291 
292    return haptic_driver->upload_effect(hap, effect, id);
293 }
294 
295 
296 /* Function: al_play_haptic_effect
297  */
al_play_haptic_effect(ALLEGRO_HAPTIC_EFFECT_ID * id,int loop)298 bool al_play_haptic_effect(ALLEGRO_HAPTIC_EFFECT_ID *id, int loop)
299 {
300    ASSERT(haptic_driver);
301    ASSERT(id);
302 
303    return haptic_driver->play_effect(id, loop);
304 }
305 
306 
307 /* Function: al_upload_and_play_haptic_effect
308  */
al_upload_and_play_haptic_effect(ALLEGRO_HAPTIC * hap,ALLEGRO_HAPTIC_EFFECT * effect,ALLEGRO_HAPTIC_EFFECT_ID * id,int loop)309 bool al_upload_and_play_haptic_effect(ALLEGRO_HAPTIC *hap,
310    ALLEGRO_HAPTIC_EFFECT *effect, ALLEGRO_HAPTIC_EFFECT_ID *id, int loop)
311 {
312    ASSERT(hap);
313    ASSERT(effect);
314    ASSERT(id);
315 
316    if (!al_upload_haptic_effect(hap, effect, id))
317       return false;
318    /* If playing the effect failed, unload the haptic effect automatically
319     */
320    if (!al_play_haptic_effect(id, loop)) {
321      al_release_haptic_effect(id);
322      return false;
323    }
324    return true;
325 }
326 
327 
328 /* Function: al_stop_haptic_effect
329  */
al_stop_haptic_effect(ALLEGRO_HAPTIC_EFFECT_ID * id)330 bool al_stop_haptic_effect(ALLEGRO_HAPTIC_EFFECT_ID *id)
331 {
332    ASSERT(id);
333 
334    return haptic_driver->stop_effect(id);
335 }
336 
337 
338 /* Function: al_is_haptic_effect_playing
339  */
al_is_haptic_effect_playing(ALLEGRO_HAPTIC_EFFECT_ID * id)340 bool al_is_haptic_effect_playing(ALLEGRO_HAPTIC_EFFECT_ID *id)
341 {
342    ASSERT(id);
343 
344    return haptic_driver->is_effect_playing(id);
345 }
346 
347 /* Function: al_get_haptic_effect_duration
348  */
al_get_haptic_effect_duration(ALLEGRO_HAPTIC_EFFECT * effect)349 double al_get_haptic_effect_duration(ALLEGRO_HAPTIC_EFFECT * effect)
350 {
351   return effect->replay.delay + effect->replay.length;
352 }
353 
354 /* Function: al_rumble_haptic
355  */
al_rumble_haptic(ALLEGRO_HAPTIC * hap,double intensity,double duration,ALLEGRO_HAPTIC_EFFECT_ID * id)356 bool al_rumble_haptic(ALLEGRO_HAPTIC *hap,
357    double intensity, double duration, ALLEGRO_HAPTIC_EFFECT_ID *id)
358 {
359    ALLEGRO_HAPTIC_EFFECT effect;
360    ASSERT(hap);
361    ASSERT(id);
362 
363    effect.type = ALLEGRO_HAPTIC_RUMBLE;
364    effect.data.rumble.strong_magnitude = intensity;
365    effect.data.rumble.weak_magnitude = intensity;
366    effect.replay.delay = 0.0;
367    effect.replay.length = duration;
368    return al_upload_and_play_haptic_effect(hap, &effect, id, 1);
369 }
370 
371 
372 /* Function: al_release_haptic_effect
373  */
al_release_haptic_effect(ALLEGRO_HAPTIC_EFFECT_ID * id)374 bool al_release_haptic_effect(ALLEGRO_HAPTIC_EFFECT_ID *id)
375 {
376    ASSERT(haptic_driver);
377    ASSERT(id);
378 
379    return haptic_driver->release_effect(id);
380 }
381 
382 
383 /* Function: al_release_haptic
384  */
al_release_haptic(ALLEGRO_HAPTIC * haptic)385 bool al_release_haptic(ALLEGRO_HAPTIC *haptic)
386 {
387    ASSERT(haptic_driver);
388    ASSERT(haptic);
389 
390    return haptic_driver->release(haptic);
391 }
392 
393 
394 /* vim: set sts=3 sw=3 et: */
395