2 Copyright (c) 2008, Edgar Simo Serra
5 Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
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.
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.
19 #include "SDL_haptic.h"
21 #include <stdio.h> /* printf */
22 #include <string.h> /* strstr */
23 #include <ctype.h> /* isdigit */
26 static SDL_Haptic *haptic;
32 static void abort_execution(void);
33 static void HapticPrintSupported(SDL_Haptic * haptic);
37 * @brief The entry point of this force feedback demo.
38 * @param[in] argc Number of arguments.
39 * @param[in] argv Array of argc arguments.
42 main(int argc, char **argv)
47 SDL_HapticEffect efx[5];
50 unsigned int supported;
56 if ((strcmp(name, "--help") == 0) || (strcmp(name, "-h") == 0)) {
57 printf("USAGE: %s [device]\n"
58 "If device is a two-digit number it'll use it as an index, otherwise\n"
59 "it'll use it as if it were part of the device's name.\n",
65 if ((i < 3) && isdigit(name[0]) && ((i == 1) || isdigit(name[1]))) {
71 /* Initialize the force feedbackness */
72 SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_JOYSTICK |
74 printf("%d Haptic devices detected.\n", SDL_NumHaptics());
75 if (SDL_NumHaptics() > 0) {
76 /* We'll just use index or the first force feedback device found */
78 i = (index != -1) ? index : 0;
80 /* Try to find matching device */
82 for (i = 0; i < SDL_NumHaptics(); i++) {
83 if (strstr(SDL_HapticName(i), name) != NULL)
87 if (i >= SDL_NumHaptics()) {
88 printf("Unable to find device matching '%s', aborting.\n",
94 haptic = SDL_HapticOpen(i);
96 printf("Unable to create the haptic device: %s\n",
100 printf("Device: %s\n", SDL_HapticName(i));
101 HapticPrintSupported(haptic);
103 printf("No Haptic devices found!\n");
107 /* We only want force feedback errors. */
110 /* Create effects. */
111 memset(&efx, 0, sizeof(efx));
113 supported = SDL_HapticQuery(haptic);
115 printf("\nUploading effects\n");
116 /* First we'll try a SINE effect. */
117 if (supported & SDL_HAPTIC_SINE) {
118 printf(" effect %d: Sine Wave\n", nefx);
119 efx[nefx].type = SDL_HAPTIC_SINE;
120 efx[nefx].periodic.period = 1000;
121 efx[nefx].periodic.magnitude = 0x4000;
122 efx[nefx].periodic.length = 5000;
123 efx[nefx].periodic.attack_length = 1000;
124 efx[nefx].periodic.fade_length = 1000;
125 id[nefx] = SDL_HapticNewEffect(haptic, &efx[nefx]);
127 printf("UPLOADING EFFECT ERROR: %s\n", SDL_GetError());
132 /* Now we'll try a SAWTOOTHUP */
133 if (supported & SDL_HAPTIC_SAWTOOTHUP) {
134 printf(" effect %d: Sawtooth Up\n", nefx);
135 efx[nefx].type = SDL_HAPTIC_SQUARE;
136 efx[nefx].periodic.period = 500;
137 efx[nefx].periodic.magnitude = 0x5000;
138 efx[nefx].periodic.length = 5000;
139 efx[nefx].periodic.attack_length = 1000;
140 efx[nefx].periodic.fade_length = 1000;
141 id[nefx] = SDL_HapticNewEffect(haptic, &efx[nefx]);
143 printf("UPLOADING EFFECT ERROR: %s\n", SDL_GetError());
148 /* Now the classical constant effect. */
149 if (supported & SDL_HAPTIC_CONSTANT) {
150 printf(" effect %d: Constant Force\n", nefx);
151 efx[nefx].type = SDL_HAPTIC_CONSTANT;
152 efx[nefx].constant.direction.type = SDL_HAPTIC_POLAR;
153 efx[nefx].constant.direction.dir[0] = 20000; /* Force comes from the south-west. */
154 efx[nefx].constant.length = 5000;
155 efx[nefx].constant.level = 0x6000;
156 efx[nefx].constant.attack_length = 1000;
157 efx[nefx].constant.fade_length = 1000;
158 id[nefx] = SDL_HapticNewEffect(haptic, &efx[nefx]);
160 printf("UPLOADING EFFECT ERROR: %s\n", SDL_GetError());
165 /* The cute spring effect. */
166 if (supported & SDL_HAPTIC_SPRING) {
167 printf(" effect %d: Condition Spring\n", nefx);
168 efx[nefx].type = SDL_HAPTIC_SPRING;
169 efx[nefx].condition.length = 5000;
170 for (i = 0; i < SDL_HapticNumAxes(haptic); i++) {
171 efx[nefx].condition.right_sat[i] = 0x7FFF;
172 efx[nefx].condition.left_sat[i] = 0x7FFF;
173 efx[nefx].condition.right_coeff[i] = 0x2000;
174 efx[nefx].condition.left_coeff[i] = 0x2000;
175 efx[nefx].condition.center[i] = 0x1000; /* Displace the center for it to move. */
177 id[nefx] = SDL_HapticNewEffect(haptic, &efx[nefx]);
179 printf("UPLOADING EFFECT ERROR: %s\n", SDL_GetError());
184 /* The pretty awesome inertia effect. */
185 if (supported & SDL_HAPTIC_INERTIA) {
186 printf(" effect %d: Condition Inertia\n", nefx);
187 efx[nefx].type = SDL_HAPTIC_SPRING;
188 efx[nefx].condition.length = 5000;
189 for (i = 0; i < SDL_HapticNumAxes(haptic); i++) {
190 efx[nefx].condition.right_sat[i] = 0x7FFF;
191 efx[nefx].condition.left_sat[i] = 0x7FFF;
192 efx[nefx].condition.right_coeff[i] = 0x2000;
193 efx[nefx].condition.left_coeff[i] = 0x2000;
195 id[nefx] = SDL_HapticNewEffect(haptic, &efx[nefx]);
197 printf("UPLOADING EFFECT ERROR: %s\n", SDL_GetError());
204 ("\nNow playing effects for 5 seconds each with 1 second delay between\n");
205 for (i = 0; i < nefx; i++) {
206 printf(" Playing effect %d\n", i);
207 SDL_HapticRunEffect(haptic, id[i], 1);
208 SDL_Delay(6000); /* Effects only have length 5000 */
213 SDL_HapticClose(haptic);
224 abort_execution(void)
226 printf("\nAborting program execution.\n");
228 SDL_HapticClose(haptic);
236 * Displays information about the haptic device.
239 HapticPrintSupported(SDL_Haptic * haptic)
241 unsigned int supported;
243 supported = SDL_HapticQuery(haptic);
244 printf(" Supported effects [%d effects, %d playing]:\n",
245 SDL_HapticNumEffects(haptic), SDL_HapticNumEffectsPlaying(haptic));
246 if (supported & SDL_HAPTIC_CONSTANT)
247 printf(" constant\n");
248 if (supported & SDL_HAPTIC_SINE)
250 if (supported & SDL_HAPTIC_SQUARE)
252 if (supported & SDL_HAPTIC_TRIANGLE)
253 printf(" triangle\n");
254 if (supported & SDL_HAPTIC_SAWTOOTHUP)
255 printf(" sawtoothup\n");
256 if (supported & SDL_HAPTIC_SAWTOOTHDOWN)
257 printf(" sawtoothdown\n");
258 if (supported & SDL_HAPTIC_RAMP)
260 if (supported & SDL_HAPTIC_FRICTION)
261 printf(" friction\n");
262 if (supported & SDL_HAPTIC_SPRING)
264 if (supported & SDL_HAPTIC_DAMPER)
266 if (supported & SDL_HAPTIC_INERTIA)
267 printf(" intertia\n");
268 if (supported & SDL_HAPTIC_CUSTOM)
270 printf(" Supported capabilities:\n");
271 if (supported & SDL_HAPTIC_GAIN)
273 if (supported & SDL_HAPTIC_AUTOCENTER)
274 printf(" autocenter\n");
275 if (supported & SDL_HAPTIC_STATUS)