SDL 2.0
testhaptic.c File Reference
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "SDL.h"
+ Include dependency graph for testhaptic.c:

Go to the source code of this file.

Functions

static void abort_execution (void)
 
static void HapticPrintSupported (SDL_Haptic *haptic)
 
int main (int argc, char **argv)
 The entry point of this force feedback demo. More...
 

Variables

static SDL_Haptic * haptic
 

Function Documentation

◆ abort_execution()

static void abort_execution ( void  )
static

Definition at line 302 of file testhaptic.c.

303{
304 SDL_Log("\nAborting program execution.\n");
305
307 SDL_Quit();
308
309 exit(1);
310}
#define SDL_HapticClose
#define SDL_Quit
#define SDL_Log
static SDL_Haptic * haptic
Definition: testhaptic.c:25

References haptic, SDL_HapticClose, SDL_Log, and SDL_Quit.

Referenced by main().

◆ HapticPrintSupported()

static void HapticPrintSupported ( SDL_Haptic *  haptic)
static

Definition at line 317 of file testhaptic.c.

318{
319 unsigned int supported;
320
321 supported = SDL_HapticQuery(haptic);
322 SDL_Log(" Supported effects [%d effects, %d playing]:\n",
324 if (supported & SDL_HAPTIC_CONSTANT)
325 SDL_Log(" constant\n");
326 if (supported & SDL_HAPTIC_SINE)
327 SDL_Log(" sine\n");
328 /* !!! FIXME: put this back when we have more bits in 2.1 */
329 /* if (supported & SDL_HAPTIC_SQUARE)
330 SDL_Log(" square\n"); */
331 if (supported & SDL_HAPTIC_TRIANGLE)
332 SDL_Log(" triangle\n");
333 if (supported & SDL_HAPTIC_SAWTOOTHUP)
334 SDL_Log(" sawtoothup\n");
335 if (supported & SDL_HAPTIC_SAWTOOTHDOWN)
336 SDL_Log(" sawtoothdown\n");
337 if (supported & SDL_HAPTIC_RAMP)
338 SDL_Log(" ramp\n");
339 if (supported & SDL_HAPTIC_FRICTION)
340 SDL_Log(" friction\n");
341 if (supported & SDL_HAPTIC_SPRING)
342 SDL_Log(" spring\n");
343 if (supported & SDL_HAPTIC_DAMPER)
344 SDL_Log(" damper\n");
345 if (supported & SDL_HAPTIC_INERTIA)
346 SDL_Log(" inertia\n");
347 if (supported & SDL_HAPTIC_CUSTOM)
348 SDL_Log(" custom\n");
349 if (supported & SDL_HAPTIC_LEFTRIGHT)
350 SDL_Log(" left/right\n");
351 SDL_Log(" Supported capabilities:\n");
352 if (supported & SDL_HAPTIC_GAIN)
353 SDL_Log(" gain\n");
354 if (supported & SDL_HAPTIC_AUTOCENTER)
355 SDL_Log(" autocenter\n");
356 if (supported & SDL_HAPTIC_STATUS)
357 SDL_Log(" status\n");
358}
#define SDL_HapticNumEffectsPlaying
#define SDL_HapticQuery
#define SDL_HapticNumEffects
#define SDL_HAPTIC_INERTIA
Inertia effect supported - uses axes acceleration.
Definition: SDL_haptic.h:252
#define SDL_HAPTIC_AUTOCENTER
Device can set autocenter.
Definition: SDL_haptic.h:291
#define SDL_HAPTIC_GAIN
Device can set global gain.
Definition: SDL_haptic.h:282
#define SDL_HAPTIC_SPRING
Spring effect supported - uses axes position.
Definition: SDL_haptic.h:232
#define SDL_HAPTIC_DAMPER
Damper effect supported - uses axes velocity.
Definition: SDL_haptic.h:242
#define SDL_HAPTIC_CUSTOM
Custom effect is supported.
Definition: SDL_haptic.h:269
#define SDL_HAPTIC_CONSTANT
Constant effect supported.
Definition: SDL_haptic.h:163
#define SDL_HAPTIC_FRICTION
Friction effect supported - uses axes movement.
Definition: SDL_haptic.h:262
#define SDL_HAPTIC_SINE
Sine wave effect supported.
Definition: SDL_haptic.h:172
#define SDL_HAPTIC_SAWTOOTHUP
Sawtoothup wave effect supported.
Definition: SDL_haptic.h:204
#define SDL_HAPTIC_STATUS
Device can be queried for effect status.
Definition: SDL_haptic.h:300
#define SDL_HAPTIC_LEFTRIGHT
Left/Right effect supported.
Definition: SDL_haptic.h:183
#define SDL_HAPTIC_TRIANGLE
Triangle wave effect supported.
Definition: SDL_haptic.h:195
#define SDL_HAPTIC_RAMP
Ramp effect supported.
Definition: SDL_haptic.h:222
#define SDL_HAPTIC_SAWTOOTHDOWN
Sawtoothdown wave effect supported.
Definition: SDL_haptic.h:213

References haptic, SDL_HAPTIC_AUTOCENTER, SDL_HAPTIC_CONSTANT, SDL_HAPTIC_CUSTOM, SDL_HAPTIC_DAMPER, SDL_HAPTIC_FRICTION, SDL_HAPTIC_GAIN, SDL_HAPTIC_INERTIA, SDL_HAPTIC_LEFTRIGHT, SDL_HAPTIC_RAMP, SDL_HAPTIC_SAWTOOTHDOWN, SDL_HAPTIC_SAWTOOTHUP, SDL_HAPTIC_SINE, SDL_HAPTIC_SPRING, SDL_HAPTIC_STATUS, SDL_HAPTIC_TRIANGLE, SDL_HapticNumEffects, SDL_HapticNumEffectsPlaying, SDL_HapticQuery, and SDL_Log.

Referenced by main().

◆ main()

int main ( int  argc,
char **  argv 
)

The entry point of this force feedback demo.

Parameters
[in]argcNumber of arguments.
[in]argvArray of argc arguments.

Definition at line 41 of file testhaptic.c.

42{
43 int i;
44 char *name;
45 int index;
46 SDL_HapticEffect efx[9];
47 int id[9];
48 int nefx;
49 unsigned int supported;
50
51 /* Enable standard application logging */
53
54 name = NULL;
55 index = -1;
56 if (argc > 1) {
57 name = argv[1];
58 if ((strcmp(name, "--help") == 0) || (strcmp(name, "-h") == 0)) {
59 SDL_Log("USAGE: %s [device]\n"
60 "If device is a two-digit number it'll use it as an index, otherwise\n"
61 "it'll use it as if it were part of the device's name.\n",
62 argv[0]);
63 return 0;
64 }
65
66 i = strlen(name);
67 if ((i < 3) && isdigit(name[0]) && ((i == 1) || isdigit(name[1]))) {
68 index = atoi(name);
69 name = NULL;
70 }
71 }
72
73 /* Initialize the force feedbackness */
76 SDL_Log("%d Haptic devices detected.\n", SDL_NumHaptics());
77 if (SDL_NumHaptics() > 0) {
78 /* We'll just use index or the first force feedback device found */
79 if (name == NULL) {
80 i = (index != -1) ? index : 0;
81 }
82 /* Try to find matching device */
83 else {
84 for (i = 0; i < SDL_NumHaptics(); i++) {
85 if (strstr(SDL_HapticName(i), name) != NULL)
86 break;
87 }
88
89 if (i >= SDL_NumHaptics()) {
90 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Unable to find device matching '%s', aborting.\n",
91 name);
92 return 1;
93 }
94 }
95
97 if (haptic == NULL) {
98 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Unable to create the haptic device: %s\n",
99 SDL_GetError());
100 return 1;
101 }
102 SDL_Log("Device: %s\n", SDL_HapticName(i));
104 } else {
105 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "No Haptic devices found!\n");
106 return 1;
107 }
108
109 /* We only want force feedback errors. */
111
112 /* Create effects. */
113 memset(&efx, 0, sizeof(efx));
114 nefx = 0;
115 supported = SDL_HapticQuery(haptic);
116
117 SDL_Log("\nUploading effects\n");
118 /* First we'll try a SINE effect. */
119 if (supported & SDL_HAPTIC_SINE) {
120 SDL_Log(" effect %d: Sine Wave\n", nefx);
121 efx[nefx].type = SDL_HAPTIC_SINE;
122 efx[nefx].periodic.period = 1000;
123 efx[nefx].periodic.magnitude = -0x2000; /* Negative magnitude and ... */
124 efx[nefx].periodic.phase = 18000; /* ... 180 degrees phase shift => cancel eachother */
125 efx[nefx].periodic.length = 5000;
126 efx[nefx].periodic.attack_length = 1000;
127 efx[nefx].periodic.fade_length = 1000;
128 id[nefx] = SDL_HapticNewEffect(haptic, &efx[nefx]);
129 if (id[nefx] < 0) {
130 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "UPLOADING EFFECT ERROR: %s\n", SDL_GetError());
132 }
133 nefx++;
134 }
135 /* Now we'll try a SAWTOOTHUP */
136 if (supported & SDL_HAPTIC_SAWTOOTHUP) {
137 SDL_Log(" effect %d: Sawtooth Up\n", nefx);
138 efx[nefx].type = SDL_HAPTIC_SAWTOOTHUP;
139 efx[nefx].periodic.period = 500;
140 efx[nefx].periodic.magnitude = 0x5000;
141 efx[nefx].periodic.length = 5000;
142 efx[nefx].periodic.attack_length = 1000;
143 efx[nefx].periodic.fade_length = 1000;
144 id[nefx] = SDL_HapticNewEffect(haptic, &efx[nefx]);
145 if (id[nefx] < 0) {
146 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "UPLOADING EFFECT ERROR: %s\n", SDL_GetError());
148 }
149 nefx++;
150 }
151
152 /* Now the classical constant effect. */
153 if (supported & SDL_HAPTIC_CONSTANT) {
154 SDL_Log(" effect %d: Constant Force\n", nefx);
155 efx[nefx].type = SDL_HAPTIC_CONSTANT;
157 efx[nefx].constant.direction.dir[0] = 20000; /* Force comes from the south-west. */
158 efx[nefx].constant.length = 5000;
159 efx[nefx].constant.level = 0x6000;
160 efx[nefx].constant.attack_length = 1000;
161 efx[nefx].constant.fade_length = 1000;
162 id[nefx] = SDL_HapticNewEffect(haptic, &efx[nefx]);
163 if (id[nefx] < 0) {
164 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "UPLOADING EFFECT ERROR: %s\n", SDL_GetError());
166 }
167 nefx++;
168 }
169
170 /* The cute spring effect. */
171 if (supported & SDL_HAPTIC_SPRING) {
172 SDL_Log(" effect %d: Condition Spring\n", nefx);
173 efx[nefx].type = SDL_HAPTIC_SPRING;
174 efx[nefx].condition.length = 5000;
175 for (i = 0; i < SDL_HapticNumAxes(haptic); i++) {
176 efx[nefx].condition.right_sat[i] = 0xFFFF;
177 efx[nefx].condition.left_sat[i] = 0xFFFF;
178 efx[nefx].condition.right_coeff[i] = 0x2000;
179 efx[nefx].condition.left_coeff[i] = 0x2000;
180 efx[nefx].condition.center[i] = 0x1000; /* Displace the center for it to move. */
181 }
182 id[nefx] = SDL_HapticNewEffect(haptic, &efx[nefx]);
183 if (id[nefx] < 0) {
184 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "UPLOADING EFFECT ERROR: %s\n", SDL_GetError());
186 }
187 nefx++;
188 }
189 /* The interesting damper effect. */
190 if (supported & SDL_HAPTIC_DAMPER) {
191 SDL_Log(" effect %d: Condition Damper\n", nefx);
192 efx[nefx].type = SDL_HAPTIC_DAMPER;
193 efx[nefx].condition.length = 5000;
194 for (i = 0; i < SDL_HapticNumAxes(haptic); i++) {
195 efx[nefx].condition.right_sat[i] = 0xFFFF;
196 efx[nefx].condition.left_sat[i] = 0xFFFF;
197 efx[nefx].condition.right_coeff[i] = 0x2000;
198 efx[nefx].condition.left_coeff[i] = 0x2000;
199 }
200 id[nefx] = SDL_HapticNewEffect(haptic, &efx[nefx]);
201 if (id[nefx] < 0) {
202 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "UPLOADING EFFECT ERROR: %s\n", SDL_GetError());
204 }
205 nefx++;
206 }
207 /* The pretty awesome inertia effect. */
208 if (supported & SDL_HAPTIC_INERTIA) {
209 SDL_Log(" effect %d: Condition Inertia\n", nefx);
210 efx[nefx].type = SDL_HAPTIC_INERTIA;
211 efx[nefx].condition.length = 5000;
212 for (i = 0; i < SDL_HapticNumAxes(haptic); i++) {
213 efx[nefx].condition.right_sat[i] = 0xFFFF;
214 efx[nefx].condition.left_sat[i] = 0xFFFF;
215 efx[nefx].condition.right_coeff[i] = 0x2000;
216 efx[nefx].condition.left_coeff[i] = 0x2000;
217 efx[nefx].condition.deadband[i] = 0x1000; /* 1/16th of axis-range around the center is 'dead'. */
218 }
219 id[nefx] = SDL_HapticNewEffect(haptic, &efx[nefx]);
220 if (id[nefx] < 0) {
221 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "UPLOADING EFFECT ERROR: %s\n", SDL_GetError());
223 }
224 nefx++;
225 }
226 /* The hot friction effect. */
227 if (supported & SDL_HAPTIC_FRICTION) {
228 SDL_Log(" effect %d: Condition Friction\n", nefx);
229 efx[nefx].type = SDL_HAPTIC_FRICTION;
230 efx[nefx].condition.length = 5000;
231 for (i = 0; i < SDL_HapticNumAxes(haptic); i++) {
232 efx[nefx].condition.right_sat[i] = 0xFFFF;
233 efx[nefx].condition.left_sat[i] = 0xFFFF;
234 efx[nefx].condition.right_coeff[i] = 0x2000;
235 efx[nefx].condition.left_coeff[i] = 0x2000;
236 }
237 id[nefx] = SDL_HapticNewEffect(haptic, &efx[nefx]);
238 if (id[nefx] < 0) {
239 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "UPLOADING EFFECT ERROR: %s\n", SDL_GetError());
241 }
242 nefx++;
243 }
244
245 /* Now we'll try a ramp effect */
246 if (supported & SDL_HAPTIC_RAMP) {
247 SDL_Log(" effect %d: Ramp\n", nefx);
248 efx[nefx].type = SDL_HAPTIC_RAMP;
250 efx[nefx].ramp.direction.dir[0] = 1; /* Force comes from */
251 efx[nefx].ramp.direction.dir[1] = -1; /* the north-east. */
252 efx[nefx].ramp.length = 5000;
253 efx[nefx].ramp.start = 0x4000;
254 efx[nefx].ramp.end = -0x4000;
255 efx[nefx].ramp.attack_length = 1000;
256 efx[nefx].ramp.fade_length = 1000;
257 id[nefx] = SDL_HapticNewEffect(haptic, &efx[nefx]);
258 if (id[nefx] < 0) {
259 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "UPLOADING EFFECT ERROR: %s\n", SDL_GetError());
261 }
262 nefx++;
263 }
264
265 /* Finally we'll try a left/right effect. */
266 if (supported & SDL_HAPTIC_LEFTRIGHT) {
267 SDL_Log(" effect %d: Left/Right\n", nefx);
268 efx[nefx].type = SDL_HAPTIC_LEFTRIGHT;
269 efx[nefx].leftright.length = 5000;
270 efx[nefx].leftright.large_magnitude = 0x3000;
271 efx[nefx].leftright.small_magnitude = 0xFFFF;
272 id[nefx] = SDL_HapticNewEffect(haptic, &efx[nefx]);
273 if (id[nefx] < 0) {
274 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "UPLOADING EFFECT ERROR: %s\n", SDL_GetError());
276 }
277 nefx++;
278 }
279
280
281 SDL_Log
282 ("\nNow playing effects for 5 seconds each with 1 second delay between\n");
283 for (i = 0; i < nefx; i++) {
284 SDL_Log(" Playing effect %d\n", i);
286 SDL_Delay(6000); /* Effects only have length 5000 */
287 }
288
289 /* Quit */
290 if (haptic != NULL)
292 SDL_Quit();
293
294 return 0;
295}
#define SDL_INIT_TIMER
Definition: SDL.h:77
#define SDL_INIT_JOYSTICK
Definition: SDL.h:80
#define SDL_INIT_HAPTIC
Definition: SDL.h:81
#define SDL_INIT_VIDEO
Definition: SDL.h:79
#define SDL_GetError
#define SDL_HapticNewEffect
#define SDL_LogSetPriority
#define SDL_ClearError
#define SDL_LogError
#define SDL_HapticName
#define SDL_Delay
#define SDL_Init
#define SDL_HapticRunEffect
#define SDL_HapticOpen
#define SDL_NumHaptics
#define SDL_HapticNumAxes
#define SDL_HAPTIC_POLAR
Uses polar coordinates for the direction.
Definition: SDL_haptic.h:323
#define SDL_HAPTIC_CARTESIAN
Uses cartesian coordinates for the direction.
Definition: SDL_haptic.h:330
@ SDL_LOG_PRIORITY_INFO
Definition: SDL_log.h:106
@ SDL_LOG_CATEGORY_APPLICATION
Definition: SDL_log.h:66
#define memset
Definition: SDL_malloc.c:627
GLuint index
GLuint const GLchar * name
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int in i)
Definition: SDL_x11sym.h:50
#define NULL
Definition: begin_code.h:167
Sint16 left_coeff[3]
Definition: SDL_haptic.h:621
Sint16 right_coeff[3]
Definition: SDL_haptic.h:620
Uint16 right_sat[3]
Definition: SDL_haptic.h:618
Uint16 left_sat[3]
Definition: SDL_haptic.h:619
Uint16 deadband[3]
Definition: SDL_haptic.h:622
SDL_HapticDirection direction
Definition: SDL_haptic.h:472
SDL_HapticDirection direction
Definition: SDL_haptic.h:643
Uint16 fade_length
Definition: SDL_haptic.h:660
Uint16 attack_length
Definition: SDL_haptic.h:658
static void abort_execution(void)
Definition: testhaptic.c:302
static void HapticPrintSupported(SDL_Haptic *haptic)
Definition: testhaptic.c:317
The generic template for any haptic effect.
Definition: SDL_haptic.h:801
SDL_HapticRamp ramp
Definition: SDL_haptic.h:807
SDL_HapticLeftRight leftright
Definition: SDL_haptic.h:808
SDL_HapticPeriodic periodic
Definition: SDL_haptic.h:805
SDL_HapticCondition condition
Definition: SDL_haptic.h:806
SDL_HapticConstant constant
Definition: SDL_haptic.h:804

References abort_execution(), SDL_HapticConstant::attack_length, SDL_HapticPeriodic::attack_length, SDL_HapticRamp::attack_length, SDL_HapticCondition::center, SDL_HapticEffect::condition, SDL_HapticEffect::constant, SDL_HapticCondition::deadband, SDL_HapticDirection::dir, SDL_HapticConstant::direction, SDL_HapticRamp::direction, SDL_HapticRamp::end, SDL_HapticConstant::fade_length, SDL_HapticPeriodic::fade_length, SDL_HapticRamp::fade_length, haptic, HapticPrintSupported(), i, SDL_HapticLeftRight::large_magnitude, SDL_HapticCondition::left_coeff, SDL_HapticCondition::left_sat, SDL_HapticEffect::leftright, SDL_HapticConstant::length, SDL_HapticPeriodic::length, SDL_HapticCondition::length, SDL_HapticRamp::length, SDL_HapticLeftRight::length, SDL_HapticConstant::level, SDL_HapticPeriodic::magnitude, memset, NULL, SDL_HapticPeriodic::period, SDL_HapticEffect::periodic, SDL_HapticPeriodic::phase, SDL_HapticEffect::ramp, SDL_HapticCondition::right_coeff, SDL_HapticCondition::right_sat, SDL_ClearError, SDL_Delay, SDL_GetError, SDL_HAPTIC_CARTESIAN, SDL_HAPTIC_CONSTANT, SDL_HAPTIC_DAMPER, SDL_HAPTIC_FRICTION, SDL_HAPTIC_INERTIA, SDL_HAPTIC_LEFTRIGHT, SDL_HAPTIC_POLAR, SDL_HAPTIC_RAMP, SDL_HAPTIC_SAWTOOTHUP, SDL_HAPTIC_SINE, SDL_HAPTIC_SPRING, SDL_HapticClose, SDL_HapticName, SDL_HapticNewEffect, SDL_HapticNumAxes, SDL_HapticOpen, SDL_HapticQuery, SDL_HapticRunEffect, SDL_Init, SDL_INIT_HAPTIC, SDL_INIT_JOYSTICK, SDL_INIT_TIMER, SDL_INIT_VIDEO, SDL_Log, SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO, SDL_LogError, SDL_LogSetPriority, SDL_NumHaptics, SDL_Quit, SDL_HapticLeftRight::small_magnitude, SDL_HapticRamp::start, SDL_HapticDirection::type, and SDL_HapticEffect::type.

Variable Documentation

◆ haptic