Skip to content

Latest commit

 

History

History
322 lines (284 loc) · 11.3 KB

testhaptic.c

File metadata and controls

322 lines (284 loc) · 11.3 KB
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
/*
Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely.
*/
/*
Copyright (c) 2008, Edgar Simo Serra
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
* Neither the name of the Simple Directmedia Layer (SDL) nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/*
* includes
*/
#include <stdlib.h>
#include <string.h> /* strstr */
#include <ctype.h> /* isdigit */
#include "SDL.h"
#ifndef SDL_HAPTIC_DISABLED
#include "SDL_haptic.h"
static SDL_Haptic *haptic;
/*
* prototypes
*/
static void abort_execution(void);
static void HapticPrintSupported(SDL_Haptic * haptic);
/**
* @brief The entry point of this force feedback demo.
* @param[in] argc Number of arguments.
* @param[in] argv Array of argc arguments.
*/
int
main(int argc, char **argv)
{
int i;
char *name;
int index;
SDL_HapticEffect efx[5];
int id[5];
int nefx;
unsigned int supported;
Aug 15, 2013
Aug 15, 2013
64
65
66
/* Enable standard application logging */
SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO);
67
68
69
70
71
name = NULL;
index = -1;
if (argc > 1) {
name = argv[1];
if ((strcmp(name, "--help") == 0) || (strcmp(name, "-h") == 0)) {
Aug 15, 2013
Aug 15, 2013
72
SDL_Log("USAGE: %s [device]\n"
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
"If device is a two-digit number it'll use it as an index, otherwise\n"
"it'll use it as if it were part of the device's name.\n",
argv[0]);
return 0;
}
i = strlen(name);
if ((i < 3) && isdigit(name[0]) && ((i == 1) || isdigit(name[1]))) {
index = atoi(name);
name = NULL;
}
}
/* Initialize the force feedbackness */
SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_JOYSTICK |
SDL_INIT_HAPTIC);
Aug 15, 2013
Aug 15, 2013
89
SDL_Log("%d Haptic devices detected.\n", SDL_NumHaptics());
90
91
92
93
94
95
96
97
98
99
100
101
102
if (SDL_NumHaptics() > 0) {
/* We'll just use index or the first force feedback device found */
if (name == NULL) {
i = (index != -1) ? index : 0;
}
/* Try to find matching device */
else {
for (i = 0; i < SDL_NumHaptics(); i++) {
if (strstr(SDL_HapticName(i), name) != NULL)
break;
}
if (i >= SDL_NumHaptics()) {
Aug 15, 2013
Aug 15, 2013
103
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Unable to find device matching '%s', aborting.\n",
104
105
106
107
108
109
110
name);
return 1;
}
}
haptic = SDL_HapticOpen(i);
if (haptic == NULL) {
Aug 15, 2013
Aug 15, 2013
111
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Unable to create the haptic device: %s\n",
112
113
114
SDL_GetError());
return 1;
}
Aug 15, 2013
Aug 15, 2013
115
SDL_Log("Device: %s\n", SDL_HapticName(i));
116
117
HapticPrintSupported(haptic);
} else {
Aug 15, 2013
Aug 15, 2013
118
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "No Haptic devices found!\n");
119
120
121
122
123
124
125
126
127
128
129
return 1;
}
/* We only want force feedback errors. */
SDL_ClearError();
/* Create effects. */
memset(&efx, 0, sizeof(efx));
nefx = 0;
supported = SDL_HapticQuery(haptic);
Aug 15, 2013
Aug 15, 2013
130
SDL_Log("\nUploading effects\n");
131
132
/* First we'll try a SINE effect. */
if (supported & SDL_HAPTIC_SINE) {
Aug 15, 2013
Aug 15, 2013
133
SDL_Log(" effect %d: Sine Wave\n", nefx);
134
135
136
137
138
139
140
141
efx[nefx].type = SDL_HAPTIC_SINE;
efx[nefx].periodic.period = 1000;
efx[nefx].periodic.magnitude = 0x4000;
efx[nefx].periodic.length = 5000;
efx[nefx].periodic.attack_length = 1000;
efx[nefx].periodic.fade_length = 1000;
id[nefx] = SDL_HapticNewEffect(haptic, &efx[nefx]);
if (id[nefx] < 0) {
Aug 15, 2013
Aug 15, 2013
142
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "UPLOADING EFFECT ERROR: %s\n", SDL_GetError());
143
144
145
146
147
148
abort_execution();
}
nefx++;
}
/* Now we'll try a SAWTOOTHUP */
if (supported & SDL_HAPTIC_SAWTOOTHUP) {
Aug 15, 2013
Aug 15, 2013
149
SDL_Log(" effect %d: Sawtooth Up\n", nefx);
150
151
152
153
154
155
156
157
efx[nefx].type = SDL_HAPTIC_SAWTOOTHUP;
efx[nefx].periodic.period = 500;
efx[nefx].periodic.magnitude = 0x5000;
efx[nefx].periodic.length = 5000;
efx[nefx].periodic.attack_length = 1000;
efx[nefx].periodic.fade_length = 1000;
id[nefx] = SDL_HapticNewEffect(haptic, &efx[nefx]);
if (id[nefx] < 0) {
Aug 15, 2013
Aug 15, 2013
158
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "UPLOADING EFFECT ERROR: %s\n", SDL_GetError());
159
160
161
162
163
164
abort_execution();
}
nefx++;
}
/* Now the classical constant effect. */
if (supported & SDL_HAPTIC_CONSTANT) {
Aug 15, 2013
Aug 15, 2013
165
SDL_Log(" effect %d: Constant Force\n", nefx);
166
167
168
169
170
171
172
173
174
efx[nefx].type = SDL_HAPTIC_CONSTANT;
efx[nefx].constant.direction.type = SDL_HAPTIC_POLAR;
efx[nefx].constant.direction.dir[0] = 20000; /* Force comes from the south-west. */
efx[nefx].constant.length = 5000;
efx[nefx].constant.level = 0x6000;
efx[nefx].constant.attack_length = 1000;
efx[nefx].constant.fade_length = 1000;
id[nefx] = SDL_HapticNewEffect(haptic, &efx[nefx]);
if (id[nefx] < 0) {
Aug 15, 2013
Aug 15, 2013
175
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "UPLOADING EFFECT ERROR: %s\n", SDL_GetError());
176
177
178
179
180
181
abort_execution();
}
nefx++;
}
/* The cute spring effect. */
if (supported & SDL_HAPTIC_SPRING) {
Aug 15, 2013
Aug 15, 2013
182
SDL_Log(" effect %d: Condition Spring\n", nefx);
183
184
185
186
187
188
189
190
191
192
193
efx[nefx].type = SDL_HAPTIC_SPRING;
efx[nefx].condition.length = 5000;
for (i = 0; i < SDL_HapticNumAxes(haptic); i++) {
efx[nefx].condition.right_sat[i] = 0x7FFF;
efx[nefx].condition.left_sat[i] = 0x7FFF;
efx[nefx].condition.right_coeff[i] = 0x2000;
efx[nefx].condition.left_coeff[i] = 0x2000;
efx[nefx].condition.center[i] = 0x1000; /* Displace the center for it to move. */
}
id[nefx] = SDL_HapticNewEffect(haptic, &efx[nefx]);
if (id[nefx] < 0) {
Aug 15, 2013
Aug 15, 2013
194
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "UPLOADING EFFECT ERROR: %s\n", SDL_GetError());
195
196
197
198
199
200
abort_execution();
}
nefx++;
}
/* The pretty awesome inertia effect. */
if (supported & SDL_HAPTIC_INERTIA) {
Aug 15, 2013
Aug 15, 2013
201
SDL_Log(" effect %d: Condition Inertia\n", nefx);
202
203
204
205
206
207
208
209
210
211
efx[nefx].type = SDL_HAPTIC_SPRING;
efx[nefx].condition.length = 5000;
for (i = 0; i < SDL_HapticNumAxes(haptic); i++) {
efx[nefx].condition.right_sat[i] = 0x7FFF;
efx[nefx].condition.left_sat[i] = 0x7FFF;
efx[nefx].condition.right_coeff[i] = 0x2000;
efx[nefx].condition.left_coeff[i] = 0x2000;
}
id[nefx] = SDL_HapticNewEffect(haptic, &efx[nefx]);
if (id[nefx] < 0) {
Aug 15, 2013
Aug 15, 2013
212
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "UPLOADING EFFECT ERROR: %s\n", SDL_GetError());
213
214
215
216
217
218
219
abort_execution();
}
nefx++;
}
/* Finally we'll try a left/right effect. */
if (supported & SDL_HAPTIC_LEFTRIGHT) {
Aug 15, 2013
Aug 15, 2013
220
SDL_Log(" effect %d: Left/Right\n", nefx);
221
222
223
224
225
226
efx[nefx].type = SDL_HAPTIC_LEFTRIGHT;
efx[nefx].leftright.length = 5000;
efx[nefx].leftright.large_magnitude = 0x3000;
efx[nefx].leftright.small_magnitude = 0xFFFF;
id[nefx] = SDL_HapticNewEffect(haptic, &efx[nefx]);
if (id[nefx] < 0) {
Aug 15, 2013
Aug 15, 2013
227
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "UPLOADING EFFECT ERROR: %s\n", SDL_GetError());
228
229
230
231
232
233
abort_execution();
}
nefx++;
}
Aug 15, 2013
Aug 15, 2013
234
SDL_Log
235
236
("\nNow playing effects for 5 seconds each with 1 second delay between\n");
for (i = 0; i < nefx; i++) {
Aug 15, 2013
Aug 15, 2013
237
SDL_Log(" Playing effect %d\n", i);
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
SDL_HapticRunEffect(haptic, id[i], 1);
SDL_Delay(6000); /* Effects only have length 5000 */
}
/* Quit */
if (haptic != NULL)
SDL_HapticClose(haptic);
SDL_Quit();
return 0;
}
/*
* Cleans up a bit.
*/
static void
abort_execution(void)
{
Aug 15, 2013
Aug 15, 2013
257
SDL_Log("\nAborting program execution.\n");
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
SDL_HapticClose(haptic);
SDL_Quit();
exit(1);
}
/*
* Displays information about the haptic device.
*/
static void
HapticPrintSupported(SDL_Haptic * haptic)
{
unsigned int supported;
supported = SDL_HapticQuery(haptic);
Aug 15, 2013
Aug 15, 2013
275
SDL_Log(" Supported effects [%d effects, %d playing]:\n",
276
277
SDL_HapticNumEffects(haptic), SDL_HapticNumEffectsPlaying(haptic));
if (supported & SDL_HAPTIC_CONSTANT)
Aug 15, 2013
Aug 15, 2013
278
SDL_Log(" constant\n");
279
if (supported & SDL_HAPTIC_SINE)
Aug 15, 2013
Aug 15, 2013
280
SDL_Log(" sine\n");
281
/* !!! FIXME: put this back when we have more bits in 2.1 */
Aug 21, 2013
Aug 21, 2013
282
/* if (supported & SDL_HAPTIC_SQUARE)
Aug 21, 2013
Aug 21, 2013
283
SDL_Log(" square\n"); */
284
if (supported & SDL_HAPTIC_TRIANGLE)
Aug 15, 2013
Aug 15, 2013
285
SDL_Log(" triangle\n");
286
if (supported & SDL_HAPTIC_SAWTOOTHUP)
Aug 15, 2013
Aug 15, 2013
287
SDL_Log(" sawtoothup\n");
288
if (supported & SDL_HAPTIC_SAWTOOTHDOWN)
Aug 15, 2013
Aug 15, 2013
289
SDL_Log(" sawtoothdown\n");
290
if (supported & SDL_HAPTIC_RAMP)
Aug 15, 2013
Aug 15, 2013
291
SDL_Log(" ramp\n");
292
if (supported & SDL_HAPTIC_FRICTION)
Aug 15, 2013
Aug 15, 2013
293
SDL_Log(" friction\n");
294
if (supported & SDL_HAPTIC_SPRING)
Aug 15, 2013
Aug 15, 2013
295
SDL_Log(" spring\n");
296
if (supported & SDL_HAPTIC_DAMPER)
Aug 15, 2013
Aug 15, 2013
297
SDL_Log(" damper\n");
298
if (supported & SDL_HAPTIC_INERTIA)
Aug 15, 2013
Aug 15, 2013
299
SDL_Log(" inertia\n");
300
if (supported & SDL_HAPTIC_CUSTOM)
Aug 15, 2013
Aug 15, 2013
301
SDL_Log(" custom\n");
302
if (supported & SDL_HAPTIC_LEFTRIGHT)
Aug 15, 2013
Aug 15, 2013
303
304
SDL_Log(" left/right\n");
SDL_Log(" Supported capabilities:\n");
305
if (supported & SDL_HAPTIC_GAIN)
Aug 15, 2013
Aug 15, 2013
306
SDL_Log(" gain\n");
307
if (supported & SDL_HAPTIC_AUTOCENTER)
Aug 15, 2013
Aug 15, 2013
308
SDL_Log(" autocenter\n");
309
if (supported & SDL_HAPTIC_STATUS)
Aug 15, 2013
Aug 15, 2013
310
SDL_Log(" status\n");
311
312
313
314
315
316
317
}
#else
int
main(int argc, char *argv[])
{
Aug 15, 2013
Aug 15, 2013
318
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL compiled without Haptic support.\n");
319
320
321
322
exit(1);
}
#endif