SDL  2.0
testhaptic.c File Reference
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "SDL.h"
+ Include dependency graph for testhaptic.c:

Go to the source code of this file.

Functions

static void abort_execution (void)
static void HapticPrintSupported (SDL_Haptic *haptic)
int main (int argc, char **argv)
 The entry point of this force feedback demo.

Variables

static SDL_Haptic * haptic

Function Documentation

static void abort_execution ( void  )
static

Definition at line 302 of file testhaptic.c.

References haptic, SDL_HapticClose, SDL_Log, and SDL_Quit.

Referenced by main().

{
SDL_Log("\nAborting program execution.\n");
exit(1);
}
static void HapticPrintSupported ( SDL_Haptic *  haptic)
static

Definition at line 317 of file testhaptic.c.

References SDL_HAPTIC_AUTOCENTER, SDL_HAPTIC_CONSTANT, SDL_HAPTIC_CUSTOM, SDL_HAPTIC_DAMPER, SDL_HAPTIC_FRICTION, SDL_HAPTIC_GAIN, SDL_HAPTIC_INERTIA, SDL_HAPTIC_LEFTRIGHT, SDL_HAPTIC_RAMP, SDL_HAPTIC_SAWTOOTHDOWN, SDL_HAPTIC_SAWTOOTHUP, SDL_HAPTIC_SINE, SDL_HAPTIC_SPRING, SDL_HAPTIC_STATUS, SDL_HAPTIC_TRIANGLE, SDL_HapticNumEffects, SDL_HapticNumEffectsPlaying, SDL_HapticQuery, and SDL_Log.

Referenced by main().

{
unsigned int supported;
supported = SDL_HapticQuery(haptic);
SDL_Log(" Supported effects [%d effects, %d playing]:\n",
if (supported & SDL_HAPTIC_CONSTANT)
SDL_Log(" constant\n");
if (supported & SDL_HAPTIC_SINE)
SDL_Log(" sine\n");
/* !!! FIXME: put this back when we have more bits in 2.1 */
/* if (supported & SDL_HAPTIC_SQUARE)
SDL_Log(" square\n"); */
if (supported & SDL_HAPTIC_TRIANGLE)
SDL_Log(" triangle\n");
if (supported & SDL_HAPTIC_SAWTOOTHUP)
SDL_Log(" sawtoothup\n");
if (supported & SDL_HAPTIC_SAWTOOTHDOWN)
SDL_Log(" sawtoothdown\n");
if (supported & SDL_HAPTIC_RAMP)
SDL_Log(" ramp\n");
if (supported & SDL_HAPTIC_FRICTION)
SDL_Log(" friction\n");
if (supported & SDL_HAPTIC_SPRING)
SDL_Log(" spring\n");
if (supported & SDL_HAPTIC_DAMPER)
SDL_Log(" damper\n");
if (supported & SDL_HAPTIC_INERTIA)
SDL_Log(" inertia\n");
if (supported & SDL_HAPTIC_CUSTOM)
SDL_Log(" custom\n");
if (supported & SDL_HAPTIC_LEFTRIGHT)
SDL_Log(" left/right\n");
SDL_Log(" Supported capabilities:\n");
if (supported & SDL_HAPTIC_GAIN)
SDL_Log(" gain\n");
if (supported & SDL_HAPTIC_AUTOCENTER)
SDL_Log(" autocenter\n");
if (supported & SDL_HAPTIC_STATUS)
SDL_Log(" status\n");
}
int main ( int  argc,
char **  argv 
)

The entry point of this force feedback demo.

Parameters
[in]argcNumber of arguments.
[in]argvArray of argc arguments.

Definition at line 41 of file testhaptic.c.

References abort_execution(), SDL_HapticConstant::attack_length, SDL_HapticPeriodic::attack_length, SDL_HapticRamp::attack_length, SDL_HapticCondition::center, SDL_HapticEffect::condition, SDL_HapticEffect::constant, SDL_HapticCondition::deadband, SDL_HapticDirection::dir, SDL_HapticConstant::direction, SDL_HapticRamp::direction, SDL_HapticRamp::end, SDL_HapticConstant::fade_length, SDL_HapticPeriodic::fade_length, SDL_HapticRamp::fade_length, haptic, HapticPrintSupported(), i, SDL_HapticLeftRight::large_magnitude, SDL_HapticCondition::left_coeff, SDL_HapticCondition::left_sat, SDL_HapticEffect::leftright, SDL_HapticConstant::length, SDL_HapticPeriodic::length, SDL_HapticCondition::length, SDL_HapticRamp::length, SDL_HapticLeftRight::length, SDL_HapticConstant::level, SDL_HapticPeriodic::magnitude, memset, NULL, SDL_HapticPeriodic::period, SDL_HapticEffect::periodic, SDL_HapticPeriodic::phase, SDL_HapticEffect::ramp, SDL_HapticCondition::right_coeff, SDL_HapticCondition::right_sat, SDL_ClearError, SDL_Delay, SDL_GetError, SDL_HAPTIC_CARTESIAN, SDL_HAPTIC_CONSTANT, SDL_HAPTIC_DAMPER, SDL_HAPTIC_FRICTION, SDL_HAPTIC_INERTIA, SDL_HAPTIC_LEFTRIGHT, SDL_HAPTIC_POLAR, SDL_HAPTIC_RAMP, SDL_HAPTIC_SAWTOOTHUP, SDL_HAPTIC_SINE, SDL_HAPTIC_SPRING, SDL_HapticClose, SDL_HapticName, SDL_HapticNewEffect, SDL_HapticNumAxes, SDL_HapticOpen, SDL_HapticQuery, SDL_HapticRunEffect, SDL_Init, SDL_INIT_HAPTIC, SDL_INIT_JOYSTICK, SDL_INIT_TIMER, SDL_INIT_VIDEO, SDL_Log, SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO, SDL_LogError, SDL_LogSetPriority, SDL_NumHaptics, SDL_Quit, SDL_HapticLeftRight::small_magnitude, SDL_HapticRamp::start, SDL_HapticDirection::type, and SDL_HapticEffect::type.

{
int i;
char *name;
int index;
int id[9];
int nefx;
unsigned int supported;
/* Enable standard application logging */
name = NULL;
index = -1;
if (argc > 1) {
name = argv[1];
if ((strcmp(name, "--help") == 0) || (strcmp(name, "-h") == 0)) {
SDL_Log("USAGE: %s [device]\n"
"If device is a two-digit number it'll use it as an index, otherwise\n"
"it'll use it as if it were part of the device's name.\n",
argv[0]);
return 0;
}
i = strlen(name);
if ((i < 3) && isdigit(name[0]) && ((i == 1) || isdigit(name[1]))) {
index = atoi(name);
name = NULL;
}
}
/* Initialize the force feedbackness */
SDL_Log("%d Haptic devices detected.\n", SDL_NumHaptics());
if (SDL_NumHaptics() > 0) {
/* We'll just use index or the first force feedback device found */
if (name == NULL) {
i = (index != -1) ? index : 0;
}
/* Try to find matching device */
else {
for (i = 0; i < SDL_NumHaptics(); i++) {
if (strstr(SDL_HapticName(i), name) != NULL)
break;
}
if (i >= SDL_NumHaptics()) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Unable to find device matching '%s', aborting.\n",
name);
return 1;
}
}
if (haptic == NULL) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Unable to create the haptic device: %s\n",
return 1;
}
SDL_Log("Device: %s\n", SDL_HapticName(i));
} else {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "No Haptic devices found!\n");
return 1;
}
/* We only want force feedback errors. */
/* Create effects. */
memset(&efx, 0, sizeof(efx));
nefx = 0;
supported = SDL_HapticQuery(haptic);
SDL_Log("\nUploading effects\n");
/* First we'll try a SINE effect. */
if (supported & SDL_HAPTIC_SINE) {
SDL_Log(" effect %d: Sine Wave\n", nefx);
efx[nefx].type = SDL_HAPTIC_SINE;
efx[nefx].periodic.period = 1000;
efx[nefx].periodic.magnitude = -0x2000; /* Negative magnitude and ... */
efx[nefx].periodic.phase = 18000; /* ... 180 degrees phase shift => cancel eachother */
efx[nefx].periodic.length = 5000;
efx[nefx].periodic.attack_length = 1000;
efx[nefx].periodic.fade_length = 1000;
id[nefx] = SDL_HapticNewEffect(haptic, &efx[nefx]);
if (id[nefx] < 0) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "UPLOADING EFFECT ERROR: %s\n", SDL_GetError());
}
nefx++;
}
/* Now we'll try a SAWTOOTHUP */
if (supported & SDL_HAPTIC_SAWTOOTHUP) {
SDL_Log(" effect %d: Sawtooth Up\n", nefx);
efx[nefx].periodic.period = 500;
efx[nefx].periodic.magnitude = 0x5000;
efx[nefx].periodic.length = 5000;
efx[nefx].periodic.attack_length = 1000;
efx[nefx].periodic.fade_length = 1000;
id[nefx] = SDL_HapticNewEffect(haptic, &efx[nefx]);
if (id[nefx] < 0) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "UPLOADING EFFECT ERROR: %s\n", SDL_GetError());
}
nefx++;
}
/* Now the classical constant effect. */
if (supported & SDL_HAPTIC_CONSTANT) {
SDL_Log(" effect %d: Constant Force\n", nefx);
efx[nefx].constant.direction.dir[0] = 20000; /* Force comes from the south-west. */
efx[nefx].constant.length = 5000;
efx[nefx].constant.level = 0x6000;
efx[nefx].constant.attack_length = 1000;
efx[nefx].constant.fade_length = 1000;
id[nefx] = SDL_HapticNewEffect(haptic, &efx[nefx]);
if (id[nefx] < 0) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "UPLOADING EFFECT ERROR: %s\n", SDL_GetError());
}
nefx++;
}
/* The cute spring effect. */
if (supported & SDL_HAPTIC_SPRING) {
SDL_Log(" effect %d: Condition Spring\n", nefx);
efx[nefx].type = SDL_HAPTIC_SPRING;
efx[nefx].condition.length = 5000;
for (i = 0; i < SDL_HapticNumAxes(haptic); i++) {
efx[nefx].condition.right_sat[i] = 0xFFFF;
efx[nefx].condition.left_sat[i] = 0xFFFF;
efx[nefx].condition.right_coeff[i] = 0x2000;
efx[nefx].condition.left_coeff[i] = 0x2000;
efx[nefx].condition.center[i] = 0x1000; /* Displace the center for it to move. */
}
id[nefx] = SDL_HapticNewEffect(haptic, &efx[nefx]);
if (id[nefx] < 0) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "UPLOADING EFFECT ERROR: %s\n", SDL_GetError());
}
nefx++;
}
/* The interesting damper effect. */
if (supported & SDL_HAPTIC_DAMPER) {
SDL_Log(" effect %d: Condition Damper\n", nefx);
efx[nefx].type = SDL_HAPTIC_DAMPER;
efx[nefx].condition.length = 5000;
for (i = 0; i < SDL_HapticNumAxes(haptic); i++) {
efx[nefx].condition.right_sat[i] = 0xFFFF;
efx[nefx].condition.left_sat[i] = 0xFFFF;
efx[nefx].condition.right_coeff[i] = 0x2000;
efx[nefx].condition.left_coeff[i] = 0x2000;
}
id[nefx] = SDL_HapticNewEffect(haptic, &efx[nefx]);
if (id[nefx] < 0) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "UPLOADING EFFECT ERROR: %s\n", SDL_GetError());
}
nefx++;
}
/* The pretty awesome inertia effect. */
if (supported & SDL_HAPTIC_INERTIA) {
SDL_Log(" effect %d: Condition Inertia\n", nefx);
efx[nefx].type = SDL_HAPTIC_INERTIA;
efx[nefx].condition.length = 5000;
for (i = 0; i < SDL_HapticNumAxes(haptic); i++) {
efx[nefx].condition.right_sat[i] = 0xFFFF;
efx[nefx].condition.left_sat[i] = 0xFFFF;
efx[nefx].condition.right_coeff[i] = 0x2000;
efx[nefx].condition.left_coeff[i] = 0x2000;
efx[nefx].condition.deadband[i] = 0x1000; /* 1/16th of axis-range around the center is 'dead'. */
}
id[nefx] = SDL_HapticNewEffect(haptic, &efx[nefx]);
if (id[nefx] < 0) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "UPLOADING EFFECT ERROR: %s\n", SDL_GetError());
}
nefx++;
}
/* The hot friction effect. */
if (supported & SDL_HAPTIC_FRICTION) {
SDL_Log(" effect %d: Condition Friction\n", nefx);
efx[nefx].condition.length = 5000;
for (i = 0; i < SDL_HapticNumAxes(haptic); i++) {
efx[nefx].condition.right_sat[i] = 0xFFFF;
efx[nefx].condition.left_sat[i] = 0xFFFF;
efx[nefx].condition.right_coeff[i] = 0x2000;
efx[nefx].condition.left_coeff[i] = 0x2000;
}
id[nefx] = SDL_HapticNewEffect(haptic, &efx[nefx]);
if (id[nefx] < 0) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "UPLOADING EFFECT ERROR: %s\n", SDL_GetError());
}
nefx++;
}
/* Now we'll try a ramp effect */
if (supported & SDL_HAPTIC_RAMP) {
SDL_Log(" effect %d: Ramp\n", nefx);
efx[nefx].type = SDL_HAPTIC_RAMP;
efx[nefx].ramp.direction.dir[0] = 1; /* Force comes from */
efx[nefx].ramp.direction.dir[1] = -1; /* the north-east. */
efx[nefx].ramp.length = 5000;
efx[nefx].ramp.start = 0x4000;
efx[nefx].ramp.end = -0x4000;
efx[nefx].ramp.attack_length = 1000;
efx[nefx].ramp.fade_length = 1000;
id[nefx] = SDL_HapticNewEffect(haptic, &efx[nefx]);
if (id[nefx] < 0) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "UPLOADING EFFECT ERROR: %s\n", SDL_GetError());
}
nefx++;
}
/* Finally we'll try a left/right effect. */
if (supported & SDL_HAPTIC_LEFTRIGHT) {
SDL_Log(" effect %d: Left/Right\n", nefx);
efx[nefx].leftright.length = 5000;
efx[nefx].leftright.large_magnitude = 0x3000;
efx[nefx].leftright.small_magnitude = 0xFFFF;
id[nefx] = SDL_HapticNewEffect(haptic, &efx[nefx]);
if (id[nefx] < 0) {
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "UPLOADING EFFECT ERROR: %s\n", SDL_GetError());
}
nefx++;
}
("\nNow playing effects for 5 seconds each with 1 second delay between\n");
for (i = 0; i < nefx; i++) {
SDL_Log(" Playing effect %d\n", i);
SDL_Delay(6000); /* Effects only have length 5000 */
}
/* Quit */
if (haptic != NULL)
return 0;
}

Variable Documentation

SDL_Haptic* haptic
static

Definition at line 25 of file testhaptic.c.

Referenced by abort_execution(), main(), SDL_HapticOpen(), and SDL_HapticOpenFromJoystick().