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