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