test/testhaptic.c
author Sam Lantinga <slouken@libsdl.org>
Fri, 08 Apr 2011 13:03:26 -0700
changeset 5535 96594ac5fd1a
parent 3338 9de326b3099c
child 6771 55337ff4256f
permissions -rw-r--r--
SDL 1.3 is now under the zlib license.
     1 /*
     2   Copyright (C) 1997-2011 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 "SDL.h"
    30 #include "SDL_haptic.h"
    31 
    32 #include <stdio.h>              /* printf */
    33 #include <string.h>             /* strstr */
    34 #include <ctype.h>              /* isdigit */
    35 
    36 
    37 static SDL_Haptic *haptic;
    38 
    39 
    40 /*
    41  * prototypes
    42  */
    43 static void abort_execution(void);
    44 static void HapticPrintSupported(SDL_Haptic * haptic);
    45 
    46 
    47 /**
    48  * @brief The entry point of this force feedback demo.
    49  * @param[in] argc Number of arguments.
    50  * @param[in] argv Array of argc arguments.
    51  */
    52 int
    53 main(int argc, char **argv)
    54 {
    55     int i;
    56     char *name;
    57     int index;
    58     SDL_HapticEffect efx[5];
    59     int id[5];
    60     int nefx;
    61     unsigned int supported;
    62 
    63     name = NULL;
    64     index = -1;
    65     if (argc > 1) {
    66         name = argv[1];
    67         if ((strcmp(name, "--help") == 0) || (strcmp(name, "-h") == 0)) {
    68             printf("USAGE: %s [device]\n"
    69                    "If device is a two-digit number it'll use it as an index, otherwise\n"
    70                    "it'll use it as if it were part of the device's name.\n",
    71                    argv[0]);
    72             return 0;
    73         }
    74 
    75         i = strlen(name);
    76         if ((i < 3) && isdigit(name[0]) && ((i == 1) || isdigit(name[1]))) {
    77             index = atoi(name);
    78             name = NULL;
    79         }
    80     }
    81 
    82     /* Initialize the force feedbackness */
    83     SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_JOYSTICK |
    84              SDL_INIT_HAPTIC);
    85     printf("%d Haptic devices detected.\n", SDL_NumHaptics());
    86     if (SDL_NumHaptics() > 0) {
    87         /* We'll just use index or the first force feedback device found */
    88         if (name == NULL) {
    89             i = (index != -1) ? index : 0;
    90         }
    91         /* Try to find matching device */
    92         else {
    93             for (i = 0; i < SDL_NumHaptics(); i++) {
    94                 if (strstr(SDL_HapticName(i), name) != NULL)
    95                     break;
    96             }
    97 
    98             if (i >= SDL_NumHaptics()) {
    99                 printf("Unable to find device matching '%s', aborting.\n",
   100                        name);
   101                 return 1;
   102             }
   103         }
   104 
   105         haptic = SDL_HapticOpen(i);
   106         if (haptic == NULL) {
   107             printf("Unable to create the haptic device: %s\n",
   108                    SDL_GetError());
   109             return 1;
   110         }
   111         printf("Device: %s\n", SDL_HapticName(i));
   112         HapticPrintSupported(haptic);
   113     } else {
   114         printf("No Haptic devices found!\n");
   115         return 1;
   116     }
   117 
   118     /* We only want force feedback errors. */
   119     SDL_ClearError();
   120 
   121     /* Create effects. */
   122     memset(&efx, 0, sizeof(efx));
   123     nefx = 0;
   124     supported = SDL_HapticQuery(haptic);
   125 
   126     printf("\nUploading effects\n");
   127     /* First we'll try a SINE effect. */
   128     if (supported & SDL_HAPTIC_SINE) {
   129         printf("   effect %d: Sine Wave\n", nefx);
   130         efx[nefx].type = SDL_HAPTIC_SINE;
   131         efx[nefx].periodic.period = 1000;
   132         efx[nefx].periodic.magnitude = 0x4000;
   133         efx[nefx].periodic.length = 5000;
   134         efx[nefx].periodic.attack_length = 1000;
   135         efx[nefx].periodic.fade_length = 1000;
   136         id[nefx] = SDL_HapticNewEffect(haptic, &efx[nefx]);
   137         if (id[nefx] < 0) {
   138             printf("UPLOADING EFFECT ERROR: %s\n", SDL_GetError());
   139             abort_execution();
   140         }
   141         nefx++;
   142     }
   143     /* Now we'll try a SAWTOOTHUP */
   144     if (supported & SDL_HAPTIC_SAWTOOTHUP) {
   145         printf("   effect %d: Sawtooth Up\n", nefx);
   146         efx[nefx].type = SDL_HAPTIC_SQUARE;
   147         efx[nefx].periodic.period = 500;
   148         efx[nefx].periodic.magnitude = 0x5000;
   149         efx[nefx].periodic.length = 5000;
   150         efx[nefx].periodic.attack_length = 1000;
   151         efx[nefx].periodic.fade_length = 1000;
   152         id[nefx] = SDL_HapticNewEffect(haptic, &efx[nefx]);
   153         if (id[nefx] < 0) {
   154             printf("UPLOADING EFFECT ERROR: %s\n", SDL_GetError());
   155             abort_execution();
   156         }
   157         nefx++;
   158     }
   159     /* Now the classical constant effect. */
   160     if (supported & SDL_HAPTIC_CONSTANT) {
   161         printf("   effect %d: Constant Force\n", nefx);
   162         efx[nefx].type = SDL_HAPTIC_CONSTANT;
   163         efx[nefx].constant.direction.type = SDL_HAPTIC_POLAR;
   164         efx[nefx].constant.direction.dir[0] = 20000;    /* Force comes from the south-west. */
   165         efx[nefx].constant.length = 5000;
   166         efx[nefx].constant.level = 0x6000;
   167         efx[nefx].constant.attack_length = 1000;
   168         efx[nefx].constant.fade_length = 1000;
   169         id[nefx] = SDL_HapticNewEffect(haptic, &efx[nefx]);
   170         if (id[nefx] < 0) {
   171             printf("UPLOADING EFFECT ERROR: %s\n", SDL_GetError());
   172             abort_execution();
   173         }
   174         nefx++;
   175     }
   176     /* The cute spring effect. */
   177     if (supported & SDL_HAPTIC_SPRING) {
   178         printf("   effect %d: Condition Spring\n", nefx);
   179         efx[nefx].type = SDL_HAPTIC_SPRING;
   180         efx[nefx].condition.length = 5000;
   181         for (i = 0; i < SDL_HapticNumAxes(haptic); i++) {
   182             efx[nefx].condition.right_sat[i] = 0x7FFF;
   183             efx[nefx].condition.left_sat[i] = 0x7FFF;
   184             efx[nefx].condition.right_coeff[i] = 0x2000;
   185             efx[nefx].condition.left_coeff[i] = 0x2000;
   186             efx[nefx].condition.center[i] = 0x1000;     /* Displace the center for it to move. */
   187         }
   188         id[nefx] = SDL_HapticNewEffect(haptic, &efx[nefx]);
   189         if (id[nefx] < 0) {
   190             printf("UPLOADING EFFECT ERROR: %s\n", SDL_GetError());
   191             abort_execution();
   192         }
   193         nefx++;
   194     }
   195     /* The pretty awesome inertia effect. */
   196     if (supported & SDL_HAPTIC_INERTIA) {
   197         printf("   effect %d: Condition Inertia\n", nefx);
   198         efx[nefx].type = SDL_HAPTIC_SPRING;
   199         efx[nefx].condition.length = 5000;
   200         for (i = 0; i < SDL_HapticNumAxes(haptic); i++) {
   201             efx[nefx].condition.right_sat[i] = 0x7FFF;
   202             efx[nefx].condition.left_sat[i] = 0x7FFF;
   203             efx[nefx].condition.right_coeff[i] = 0x2000;
   204             efx[nefx].condition.left_coeff[i] = 0x2000;
   205         }
   206         id[nefx] = SDL_HapticNewEffect(haptic, &efx[nefx]);
   207         if (id[nefx] < 0) {
   208             printf("UPLOADING EFFECT ERROR: %s\n", SDL_GetError());
   209             abort_execution();
   210         }
   211         nefx++;
   212     }
   213 
   214     printf
   215         ("\nNow playing effects for 5 seconds each with 1 second delay between\n");
   216     for (i = 0; i < nefx; i++) {
   217         printf("   Playing effect %d\n", i);
   218         SDL_HapticRunEffect(haptic, id[i], 1);
   219         SDL_Delay(6000);        /* Effects only have length 5000 */
   220     }
   221 
   222     /* Quit */
   223     if (haptic != NULL)
   224         SDL_HapticClose(haptic);
   225     SDL_Quit();
   226 
   227     return 0;
   228 }
   229 
   230 
   231 /*
   232  * Cleans up a bit.
   233  */
   234 static void
   235 abort_execution(void)
   236 {
   237     printf("\nAborting program execution.\n");
   238 
   239     SDL_HapticClose(haptic);
   240     SDL_Quit();
   241 
   242     exit(1);
   243 }
   244 
   245 
   246 /*
   247  * Displays information about the haptic device.
   248  */
   249 static void
   250 HapticPrintSupported(SDL_Haptic * haptic)
   251 {
   252     unsigned int supported;
   253 
   254     supported = SDL_HapticQuery(haptic);
   255     printf("   Supported effects [%d effects, %d playing]:\n",
   256            SDL_HapticNumEffects(haptic), SDL_HapticNumEffectsPlaying(haptic));
   257     if (supported & SDL_HAPTIC_CONSTANT)
   258         printf("      constant\n");
   259     if (supported & SDL_HAPTIC_SINE)
   260         printf("      sine\n");
   261     if (supported & SDL_HAPTIC_SQUARE)
   262         printf("      square\n");
   263     if (supported & SDL_HAPTIC_TRIANGLE)
   264         printf("      triangle\n");
   265     if (supported & SDL_HAPTIC_SAWTOOTHUP)
   266         printf("      sawtoothup\n");
   267     if (supported & SDL_HAPTIC_SAWTOOTHDOWN)
   268         printf("      sawtoothdown\n");
   269     if (supported & SDL_HAPTIC_RAMP)
   270         printf("      ramp\n");
   271     if (supported & SDL_HAPTIC_FRICTION)
   272         printf("      friction\n");
   273     if (supported & SDL_HAPTIC_SPRING)
   274         printf("      spring\n");
   275     if (supported & SDL_HAPTIC_DAMPER)
   276         printf("      damper\n");
   277     if (supported & SDL_HAPTIC_INERTIA)
   278         printf("      intertia\n");
   279     if (supported & SDL_HAPTIC_CUSTOM)
   280         printf("      custom\n");
   281     printf("   Supported capabilities:\n");
   282     if (supported & SDL_HAPTIC_GAIN)
   283         printf("      gain\n");
   284     if (supported & SDL_HAPTIC_AUTOCENTER)
   285         printf("      autocenter\n");
   286     if (supported & SDL_HAPTIC_STATUS)
   287         printf("      status\n");
   288 }