2
* Tests the force feedback driver
3
* Opens a window. When the user clicks in the window, a force effect
4
* is generated according to the position of the mouse.
5
* This program needs the SDL library (http://www.libsdl.org)
6
* Copyright 2001 Johann Deneux <deneux@ifrance.com>
10
* This program is free software; you can redistribute it and/or modify
11
* it under the terms of the GNU General Public License as published by
12
* the Free Software Foundation; either version 2 of the License, or
13
* (at your option) any later version.
15
* This program is distributed in the hope that it will be useful,
16
* but WITHOUT ANY WARRANTY; without even the implied warranty of
17
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
* GNU General Public License for more details.
20
* You should have received a copy of the GNU General Public License
21
* along with this program; if not, write to the Free Software
22
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24
* You can contact the author by email at this address:
25
* Johann Deneux <deneux@ifrance.com>
32
#include <sys/ioctl.h>
36
#include <linux/input.h>
39
#define BIT(x) (1<<(x))
43
#define max(a,b) ((a)>(b)?(a):(b))
45
/* File descriptor of the force feedback /dev entry */
47
static struct ff_effect effect;
52
"ffmvforce: test orientation of forces",
53
"Click in the window to generate a force whose direction will be the position",
54
"of your mouse relatively to the center of the window",
55
"USE WITH CARE !!! HOLD STRONGLY YOUR WHEEL OR JOYSTICK TO PREVENT DAMAGES",
56
"To run this program, run it with at least one argument.",
68
static void generate_force(int x, int y)
74
nx = 2*(x-WIN_W/2.0)/WIN_W;
75
ny = 2*(y-WIN_H/2.0)/WIN_H;
76
angle = atan2(nx, -ny);
77
printf("mouse: %d %d n: %4.2f %4.2f angle: %4.2f\n", x, y, nx, ny, angle);
78
effect.type = FF_CONSTANT;
79
effect.u.constant.level = 0x7fff * max(fabs(nx), fabs(ny));
80
effect.direction = 0x8000 * (angle + M_PI)/M_PI;
81
printf("level: %04x direction: %04x\n", (unsigned int)effect.u.constant.level, (unsigned int)effect.direction);
82
effect.u.constant.envelope.attack_length = 0;
83
effect.u.constant.envelope.attack_level = 0;
84
effect.u.constant.envelope.fade_length = 0;
85
effect.u.constant.envelope.fade_level = 0;
86
effect.trigger.button = 0;
87
effect.trigger.interval = 0;
88
effect.replay.length = 0xffff;
89
effect.replay.delay = 0;
95
if (ioctl(ff_fd, EVIOCSFF, &effect) < 0) {
96
/* If updates are sent to frequently, they can be refused */
99
/* If first time, start to play the effect */
101
struct input_event play;
103
play.code = effect.id;
106
if (write(ff_fd, (const void*) &play, sizeof(play)) == -1) {
107
perror("Play effect");
115
int main(int argc, char** argv)
118
char dev_name[STR_LEN];
120
Uint32 ticks, period = 200;
123
if (argc <= 1) return 0;
125
/* Parse parameters */
126
strcpy(dev_name, "/dev/input/event0");
127
for (i=1; i<argc; ++i) {
128
if (strcmp(argv[i], "--help") == 0) {
129
printf("Usage: %s /dev/input/eventXX [-u update frequency in HZ]\n", argv[0]);
130
printf("Generates constant force effects depending on the position of the mouse\n");
133
else if (strcmp(argv[i], "-u") == 0) {
135
fprintf(stderr, "Missing update frequency\n");
138
period = 1000.0/atof(argv[i]);
141
strncpy(dev_name, argv[i], STR_LEN);
146
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
147
fprintf(stderr, "Could not initialize SDL: %s\n", SDL_GetError());
150
on_exit(SDL_Quit, NULL);
151
screen = SDL_SetVideoMode(WIN_W, WIN_H, 0, SDL_SWSURFACE);
152
if (screen == NULL) {
153
fprintf(stderr, "Could not set video mode: %s\n", SDL_GetError());
157
/* Open force feedback device */
158
ff_fd = open(dev_name, O_RDWR);
160
perror("Open device file");
164
ticks = SDL_GetTicks();
168
SDL_WaitEvent(&event);
170
switch (event.type) {
175
case SDL_MOUSEMOTION:
176
if (event.motion.state && SDL_GetTicks()-ticks > period) {
177
ticks = SDL_GetTicks();
178
generate_force(event.motion.x, event.motion.y);