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