test/testhaptic.c
author Sam Lantinga <slouken@libsdl.org>
Wed, 05 Jun 2013 22:33:10 -0700
changeset 7286 04087a99e3f4
parent 7263 8d69588e0269
child 7517 965d57022c01
permissions -rw-r--r--
Added testautomation to the Visual Studio 2008 project.
     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 <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     printf
   217         ("\nNow playing effects for 5 seconds each with 1 second delay between\n");
   218     for (i = 0; i < nefx; i++) {
   219         printf("   Playing effect %d\n", i);
   220         SDL_HapticRunEffect(haptic, id[i], 1);
   221         SDL_Delay(6000);        /* Effects only have length 5000 */
   222     }
   223 
   224     /* Quit */
   225     if (haptic != NULL)
   226         SDL_HapticClose(haptic);
   227     SDL_Quit();
   228 
   229     return 0;
   230 }
   231 
   232 
   233 /*
   234  * Cleans up a bit.
   235  */
   236 static void
   237 abort_execution(void)
   238 {
   239     printf("\nAborting program execution.\n");
   240 
   241     SDL_HapticClose(haptic);
   242     SDL_Quit();
   243 
   244     exit(1);
   245 }
   246 
   247 
   248 /*
   249  * Displays information about the haptic device.
   250  */
   251 static void
   252 HapticPrintSupported(SDL_Haptic * haptic)
   253 {
   254     unsigned int supported;
   255 
   256     supported = SDL_HapticQuery(haptic);
   257     printf("   Supported effects [%d effects, %d playing]:\n",
   258            SDL_HapticNumEffects(haptic), SDL_HapticNumEffectsPlaying(haptic));
   259     if (supported & SDL_HAPTIC_CONSTANT)
   260         printf("      constant\n");
   261     if (supported & SDL_HAPTIC_SINE)
   262         printf("      sine\n");
   263     if (supported & SDL_HAPTIC_SQUARE)
   264         printf("      square\n");
   265     if (supported & SDL_HAPTIC_TRIANGLE)
   266         printf("      triangle\n");
   267     if (supported & SDL_HAPTIC_SAWTOOTHUP)
   268         printf("      sawtoothup\n");
   269     if (supported & SDL_HAPTIC_SAWTOOTHDOWN)
   270         printf("      sawtoothdown\n");
   271     if (supported & SDL_HAPTIC_RAMP)
   272         printf("      ramp\n");
   273     if (supported & SDL_HAPTIC_FRICTION)
   274         printf("      friction\n");
   275     if (supported & SDL_HAPTIC_SPRING)
   276         printf("      spring\n");
   277     if (supported & SDL_HAPTIC_DAMPER)
   278         printf("      damper\n");
   279     if (supported & SDL_HAPTIC_INERTIA)
   280         printf("      intertia\n");
   281     if (supported & SDL_HAPTIC_CUSTOM)
   282         printf("      custom\n");
   283     printf("   Supported capabilities:\n");
   284     if (supported & SDL_HAPTIC_GAIN)
   285         printf("      gain\n");
   286     if (supported & SDL_HAPTIC_AUTOCENTER)
   287         printf("      autocenter\n");
   288     if (supported & SDL_HAPTIC_STATUS)
   289         printf("      status\n");
   290 }
   291 
   292 #else
   293 
   294 int
   295 main(int argc, char *argv[])
   296 {
   297     fprintf(stderr, "SDL compiled without Haptic support.\n");
   298     exit(1);
   299 }
   300 
   301 #endif