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