comparison test/testhaptic.c @ 2713:0906692aa6a4

Final merge of Google Summer of Code 2008 work... Force Feedback for SDL by Edgar Simo, mentored by Ryan C. Gordon
author Sam Lantinga <slouken@libsdl.org>
date Mon, 25 Aug 2008 09:55:03 +0000
parents
children 5668c3dfe7bc
comparison
equal deleted inserted replaced
2712:c4e697245676 2713:0906692aa6a4
1 /*
2 Copyright (c) 2008, Edgar Simo Serra
3 All rights reserved.
4
5 Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6
7 * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
8 * 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.
9 * 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.
10
11 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.
12 */
13
14 /*
15 * includes
16 */
17 #include "SDL.h"
18 #include "SDL_haptic.h"
19
20 #include <stdio.h> /* printf */
21 #include <string.h> /* strstr */
22
23
24
25 static SDL_Haptic *haptic;
26
27
28 /*
29 * prototypes
30 */
31 static void abort_execution(void);
32 static void HapticPrintSupported(SDL_Haptic * haptic);
33
34
35 /**
36 * @brief The entry point of this force feedback demo.
37 * @param[in] argc Number of arguments.
38 * @param[in] argv Array of argc arguments.
39 */
40 int
41 main(int argc, char **argv)
42 {
43 int i;
44 char *name;
45 SDL_HapticEffect efx[5];
46 int id[5];
47 int nefx;
48 unsigned int supported;
49
50 name = NULL;
51 if (argc > 1) {
52 name = argv[1];
53 if ((strcmp(name, "--help") == 0) || (strcmp(name, "-h") == 0)) {
54 printf("USAGE: %s [device name]\n"
55 "If device name is specified, it will try to find a device whose name\n"
56 "contains device name for testing.\n", argv[0]);
57 return 0;
58 }
59 }
60
61 /* Initialize the force feedbackness */
62 SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_JOYSTICK |
63 SDL_INIT_HAPTIC);
64 printf("%d Haptic devices detected.\n", SDL_NumHaptics());
65 if (SDL_NumHaptics() > 0) {
66 /* We'll just use the first force feedback device found */
67 if (name == NULL) {
68 i = 0;
69 }
70 /* Try to find matching device */
71 else {
72 for (i = 0; i < SDL_NumHaptics(); i++) {
73 if (strstr(SDL_HapticName(i), name) != NULL)
74 break;
75 }
76
77 if (i >= SDL_NumHaptics()) {
78 printf("Unable to find device matching '%s', aborting.\n",
79 name);
80 return 1;
81 }
82 }
83
84 haptic = SDL_HapticOpen(i);
85 if (haptic == NULL) {
86 perror("Unable to create the haptic device");
87 return 1;
88 }
89 printf("Device: %s\n", SDL_HapticName(i));
90 HapticPrintSupported(haptic);
91 } else {
92 printf("No Haptic devices found!\n");
93 return 1;
94 }
95
96 /* We only want force feedback errors. */
97 SDL_ClearError();
98
99 /* Create effects. */
100 memset(&efx, 0, sizeof(efx));
101 nefx = 0;
102 supported = SDL_HapticQuery(haptic);
103
104 printf("\nUploading effects\n");
105 /* First we'll try a SINE effect. */
106 if (supported & SDL_HAPTIC_SINE) {
107 printf(" effect %d: Sine Wave\n", nefx);
108 efx[nefx].type = SDL_HAPTIC_SINE;
109 efx[nefx].periodic.period = 1000;
110 efx[nefx].periodic.magnitude = 0x4000;
111 efx[nefx].periodic.length = 5000;
112 efx[nefx].periodic.attack_length = 1000;
113 efx[nefx].periodic.fade_length = 1000;
114 id[nefx] = SDL_HapticNewEffect(haptic, &efx[nefx]);
115 if (id[nefx] < 0) {
116 printf("UPLOADING EFFECT ERROR: %s\n", SDL_GetError());
117 abort_execution();
118 }
119 nefx++;
120 }
121 /* Now we'll try a SAWTOOTHUP */
122 if (supported & SDL_HAPTIC_SAWTOOTHUP) {
123 printf(" effect %d: Sawtooth Up\n", nefx);
124 efx[nefx].type = SDL_HAPTIC_SQUARE;
125 efx[nefx].periodic.period = 500;
126 efx[nefx].periodic.magnitude = 0x5000;
127 efx[nefx].periodic.length = 5000;
128 efx[nefx].periodic.attack_length = 1000;
129 efx[nefx].periodic.fade_length = 1000;
130 id[nefx] = SDL_HapticNewEffect(haptic, &efx[nefx]);
131 if (id[nefx] < 0) {
132 printf("UPLOADING EFFECT ERROR: %s\n", SDL_GetError());
133 abort_execution();
134 }
135 nefx++;
136 }
137 /* Now the classical constant effect. */
138 if (supported & SDL_HAPTIC_CONSTANT) {
139 printf(" effect %d: Constant Force\n", nefx);
140 efx[nefx].type = SDL_HAPTIC_CONSTANT;
141 efx[nefx].constant.direction.type = SDL_HAPTIC_POLAR;
142 efx[nefx].constant.direction.dir[0] = 20000; /* Force comes from the south-west. */
143 efx[nefx].constant.length = 5000;
144 efx[nefx].constant.level = 0x6000;
145 efx[nefx].constant.attack_length = 1000;
146 efx[nefx].constant.fade_length = 1000;
147 id[nefx] = SDL_HapticNewEffect(haptic, &efx[nefx]);
148 if (id[nefx] < 0) {
149 printf("UPLOADING EFFECT ERROR: %s\n", SDL_GetError());
150 abort_execution();
151 }
152 nefx++;
153 }
154 /* The cute spring effect. */
155 if (supported & SDL_HAPTIC_SPRING) {
156 printf(" effect %d: Condition Spring\n", nefx);
157 efx[nefx].type = SDL_HAPTIC_SPRING;
158 efx[nefx].condition.length = 5000;
159 for (i = 0; i < SDL_HapticNumAxes(haptic); i++) {
160 efx[nefx].condition.right_sat[i] = 0x7FFF;
161 efx[nefx].condition.left_sat[i] = 0x7FFF;
162 efx[nefx].condition.right_coeff[i] = 0x2000;
163 efx[nefx].condition.left_coeff[i] = 0x2000;
164 efx[nefx].condition.center[i] = 0x1000; /* Displace the center for it to move. */
165 }
166 id[nefx] = SDL_HapticNewEffect(haptic, &efx[nefx]);
167 if (id[nefx] < 0) {
168 printf("UPLOADING EFFECT ERROR: %s\n", SDL_GetError());
169 abort_execution();
170 }
171 nefx++;
172 }
173 /* The pretty awesome inertia effect. */
174 if (supported & SDL_HAPTIC_INERTIA) {
175 printf(" effect %d: Condition Inertia\n", nefx);
176 efx[nefx].type = SDL_HAPTIC_SPRING;
177 efx[nefx].condition.length = 5000;
178 for (i = 0; i < SDL_HapticNumAxes(haptic); i++) {
179 efx[nefx].condition.right_sat[i] = 0x7FFF;
180 efx[nefx].condition.left_sat[i] = 0x7FFF;
181 efx[nefx].condition.right_coeff[i] = 0x2000;
182 efx[nefx].condition.left_coeff[i] = 0x2000;
183 }
184 id[nefx] = SDL_HapticNewEffect(haptic, &efx[nefx]);
185 if (id[nefx] < 0) {
186 printf("UPLOADING EFFECT ERROR: %s\n", SDL_GetError());
187 abort_execution();
188 }
189 nefx++;
190 }
191
192 printf
193 ("\nNow playing effects for 5 seconds each with 1 second delay between\n");
194 for (i = 0; i < nefx; i++) {
195 printf(" Playing effect %d\n", i);
196 SDL_HapticRunEffect(haptic, id[i], 1);
197 SDL_Delay(6000); /* Effects only have length 5000 */
198 }
199
200 /* Quit */
201 if (haptic != NULL)
202 SDL_HapticClose(haptic);
203 SDL_Quit();
204
205 return 0;
206 }
207
208
209 /*
210 * Cleans up a bit.
211 */
212 static void
213 abort_execution(void)
214 {
215 printf("\nAborting program execution.\n");
216
217 SDL_HapticClose(haptic);
218 SDL_Quit();
219
220 exit(1);
221 }
222
223
224 /*
225 * Displays information about the haptic device.
226 */
227 static void
228 HapticPrintSupported(SDL_Haptic * haptic)
229 {
230 unsigned int supported;
231
232 supported = SDL_HapticQuery(haptic);
233 printf(" Supported effects [%d effects, %d playing]:\n",
234 SDL_HapticNumEffects(haptic), SDL_HapticNumEffectsPlaying(haptic));
235 if (supported & SDL_HAPTIC_CONSTANT)
236 printf(" constant\n");
237 if (supported & SDL_HAPTIC_SINE)
238 printf(" sine\n");
239 if (supported & SDL_HAPTIC_SQUARE)
240 printf(" square\n");
241 if (supported & SDL_HAPTIC_TRIANGLE)
242 printf(" triangle\n");
243 if (supported & SDL_HAPTIC_SAWTOOTHUP)
244 printf(" sawtoothup\n");
245 if (supported & SDL_HAPTIC_SAWTOOTHDOWN)
246 printf(" sawtoothdown\n");
247 if (supported & SDL_HAPTIC_RAMP)
248 printf(" ramp\n");
249 if (supported & SDL_HAPTIC_FRICTION)
250 printf(" friction\n");
251 if (supported & SDL_HAPTIC_SPRING)
252 printf(" spring\n");
253 if (supported & SDL_HAPTIC_DAMPER)
254 printf(" damper\n");
255 if (supported & SDL_HAPTIC_INERTIA)
256 printf(" intertia\n");
257 if (supported & SDL_HAPTIC_CUSTOM)
258 printf(" custom\n");
259 printf(" Supported capabilities:\n");
260 if (supported & SDL_HAPTIC_GAIN)
261 printf(" gain\n");
262 if (supported & SDL_HAPTIC_AUTOCENTER)
263 printf(" autocenter\n");
264 if (supported & SDL_HAPTIC_STATUS)
265 printf(" status\n");
266 }