TORCS  1.3.9
The Open Racing Car Simulator
control.cpp
Go to the documentation of this file.
1 /***************************************************************************
2 
3  file : control.cpp
4  created : Thu Mar 6 22:01:33 CET 2003
5  copyright : (C) 2003-2015 by Eric Espie, Bernhard Wymann
6  email : eric.espie@torcs.org
7  version : $Id$
8 
9  ***************************************************************************/
10 
11 /***************************************************************************
12  * *
13  * This program is free software; you can redistribute it and/or modify *
14  * it under the terms of the GNU General Public License as published by *
15  * the Free Software Foundation; either version 2 of the License, or *
16  * (at your option) any later version. *
17  * *
18  ***************************************************************************/
19 
26 #include <stdlib.h>
27 #include <stdio.h>
28 #include <plib/js.h>
29 
30 #include <tgfclient.h>
31 #include <portability.h>
32 #include <playerpref.h>
33 
34 static const char *GfJoyBtn[] = {
35 "BTN1-0","BTN2-0","BTN3-0","BTN4-0","BTN5-0","BTN6-0","BTN7-0","BTN8-0","BTN9-0","BTN10-0","BTN11-0","BTN12-0","BTN13-0","BTN14-0","BTN15-0","BTN16-0",
36 "BTN17-0","BTN18-0","BTN19-0","BTN20-0","BTN21-0","BTN22-0","BTN23-0","BTN24-0","BTN25-0","BTN26-0","BTN27-0","BTN28-0","BTN29-0","BTN30-0","BTN31-0","BTN32-0",
37 "BTN1-1","BTN2-1","BTN3-1","BTN4-1","BTN5-1","BTN6-1","BTN7-1","BTN8-1","BTN9-1","BTN10-1","BTN11-1","BTN12-1","BTN13-1","BTN14-1","BTN15-1","BTN16-1",
38 "BTN17-1","BTN18-1","BTN19-1","BTN20-1","BTN21-1","BTN22-1","BTN23-1","BTN24-1","BTN25-1","BTN26-1","BTN27-1","BTN28-1","BTN29-1","BTN30-1","BTN31-1","BTN32-1",
39 "BTN1-2","BTN2-2","BTN3-2","BTN4-2","BTN5-2","BTN6-2","BTN7-2","BTN8-2","BTN9-2","BTN10-2","BTN11-2","BTN12-2","BTN13-2","BTN14-2","BTN15-2","BTN16-2",
40 "BTN17-2","BTN18-2","BTN19-2","BTN20-2","BTN21-2","BTN22-2","BTN23-2","BTN24-2","BTN25-2","BTN26-2","BTN27-2","BTN28-2","BTN29-2","BTN30-2","BTN31-2","BTN32-2",
41 "BTN1-3","BTN2-3","BTN3-3","BTN4-3","BTN5-3","BTN6-3","BTN7-3","BTN8-3","BTN9-3","BTN10-3","BTN11-3","BTN12-3","BTN13-3","BTN14-3","BTN15-3","BTN16-3",
42 "BTN17-3","BTN18-3","BTN19-3","BTN20-3","BTN21-3","BTN22-3","BTN23-3","BTN24-3","BTN25-3","BTN26-3","BTN27-3","BTN28-3","BTN29-3","BTN30-3","BTN31-3","BTN32-3",
43 "BTN1-4","BTN2-4","BTN3-4","BTN4-4","BTN5-4","BTN6-4","BTN7-4","BTN8-4","BTN9-4","BTN10-4","BTN11-4","BTN12-4","BTN13-4","BTN14-4","BTN15-4","BTN16-4",
44 "BTN17-4","BTN18-4","BTN19-4","BTN20-4","BTN21-4","BTN22-4","BTN23-4","BTN24-4","BTN25-4","BTN26-4","BTN27-4","BTN28-4","BTN29-4","BTN30-4","BTN31-4","BTN32-4",
45 "BTN1-5","BTN2-5","BTN3-5","BTN4-5","BTN5-5","BTN6-5","BTN7-5","BTN8-5","BTN9-5","BTN10-5","BTN11-5","BTN12-5","BTN13-5","BTN14-5","BTN15-5","BTN16-5",
46 "BTN17-5","BTN18-5","BTN19-5","BTN20-5","BTN21-5","BTN22-5","BTN23-5","BTN24-5","BTN25-5","BTN26-5","BTN27-5","BTN28-5","BTN29-5","BTN30-5","BTN31-5","BTN32-5",
47 "BTN1-6","BTN2-6","BTN3-6","BTN4-6","BTN5-6","BTN6-6","BTN7-6","BTN8-6","BTN9-6","BTN10-6","BTN11-6","BTN12-6","BTN13-6","BTN14-6","BTN15-6","BTN16-6",
48 "BTN17-6","BTN18-6","BTN19-6","BTN20-6","BTN21-6","BTN22-6","BTN23-6","BTN24-6","BTN25-6","BTN26-6","BTN27-6","BTN28-6","BTN29-6","BTN30-6","BTN31-6","BTN32-6",
49 "BTN1-7","BTN2-7","BTN3-7","BTN4-7","BTN5-7","BTN6-7","BTN7-7","BTN8-7","BTN9-7","BTN10-7","BTN11-7","BTN12-7","BTN13-7","BTN14-7","BTN15-7","BTN16-7",
50 "BTN17-7","BTN18-7","BTN19-7","BTN20-7","BTN21-7","BTN22-7","BTN23-7","BTN24-7","BTN25-7","BTN26-7","BTN27-7","BTN28-7","BTN29-7","BTN30-7","BTN31-7","BTN32-7"
51 };
52 
53 static const char *GfJoyAxis[] = {
54  "AXIS0-0", "AXIS1-0", "AXIS2-0", "AXIS3-0", "AXIS4-0", "AXIS5-0", "AXIS6-0", "AXIS7-0", "AXIS8-0", "AXIS9-0", "AXIS10-0", "AXIS11-0", "AXIS12-0", "AXIS13-0", "AXIS14-0", "AXIS15-0",
55  "AXIS0-1", "AXIS1-1", "AXIS2-1", "AXIS3-1", "AXIS4-1", "AXIS5-1", "AXIS6-1", "AXIS7-1", "AXIS8-1", "AXIS9-1", "AXIS10-1", "AXIS11-1", "AXIS12-1", "AXIS13-1", "AXIS14-1", "AXIS15-1",
56  "AXIS0-2", "AXIS1-2", "AXIS2-2", "AXIS3-2", "AXIS4-2", "AXIS5-2", "AXIS6-2", "AXIS7-2", "AXIS8-2", "AXIS9-2", "AXIS10-2", "AXIS11-2", "AXIS12-2", "AXIS13-2", "AXIS14-2", "AXIS15-2",
57  "AXIS0-3", "AXIS1-3", "AXIS2-3", "AXIS3-3", "AXIS4-3", "AXIS5-3", "AXIS6-3", "AXIS7-3", "AXIS8-3", "AXIS9-3", "AXIS10-3", "AXIS11-3", "AXIS12-3", "AXIS13-3", "AXIS14-3", "AXIS15-3",
58  "AXIS0-4", "AXIS1-4", "AXIS2-4", "AXIS3-4", "AXIS4-4", "AXIS5-4", "AXIS6-4", "AXIS7-4", "AXIS8-4", "AXIS9-4", "AXIS10-4", "AXIS11-4", "AXIS12-4", "AXIS13-4", "AXIS14-4", "AXIS15-4",
59  "AXIS0-5", "AXIS1-5", "AXIS2-5", "AXIS3-5", "AXIS4-5", "AXIS5-5", "AXIS6-5", "AXIS7-5", "AXIS8-5", "AXIS9-5", "AXIS10-5", "AXIS11-5", "AXIS12-5", "AXIS13-5", "AXIS14-5", "AXIS15-5",
60  "AXIS0-6", "AXIS1-6", "AXIS2-6", "AXIS3-6", "AXIS4-6", "AXIS5-6", "AXIS6-6", "AXIS7-6", "AXIS8-6", "AXIS9-6", "AXIS10-6", "AXIS11-6", "AXIS12-6", "AXIS13-6", "AXIS14-6", "AXIS15-6",
61  "AXIS0-7", "AXIS1-7", "AXIS2-7", "AXIS3-7", "AXIS4-7", "AXIS5-7", "AXIS6-7", "AXIS7-7", "AXIS8-7", "AXIS9-7", "AXIS10-7", "AXIS11-7", "AXIS12-7", "AXIS13-7", "AXIS14-7", "AXIS15-7"
62 };
63 
64 static const char *GfMouseBtn[] = {"MOUSE_LEFT_BTN", "MOUSE_MIDDLE_BTN", "MOUSE_RIGHT_BTN"}; /* glut order */
65 
66 static const char *GfMouseAxis[] = {"MOUSE_LEFT", "MOUSE_RIGHT", "MOUSE_UP", "MOUSE_DOWN"};
67 
68 typedef struct
69 {
70  const char *descr;
71  int val;
73 
74 static tgfKeyBinding GfSKey[] = {
75  {"F1", GLUT_KEY_F1},
76  {"F2", GLUT_KEY_F2},
77  {"F3", GLUT_KEY_F3},
78  {"F4", GLUT_KEY_F4},
79  {"F5", GLUT_KEY_F5},
80  {"F6", GLUT_KEY_F6},
81  {"F7", GLUT_KEY_F7},
82  {"F8", GLUT_KEY_F8},
83  {"F9", GLUT_KEY_F9},
84  {"F10", GLUT_KEY_F10},
85  {"F11", GLUT_KEY_F11},
86  {"F12", GLUT_KEY_F12},
87  {"Left Arrow", GLUT_KEY_LEFT},
88  {"Up Arrow", GLUT_KEY_UP},
89  {"Right Arrow", GLUT_KEY_RIGHT},
90  {"Down Arrow", GLUT_KEY_DOWN},
91  {"Page Up", GLUT_KEY_PAGE_UP},
92  {"Page Down", GLUT_KEY_PAGE_DOWN},
93  {"Home", GLUT_KEY_HOME},
94  {"End", GLUT_KEY_END},
95  {"Insert", GLUT_KEY_INSERT}
96 };
97 
98 static tgfKeyBinding GfKey[] = {
99  {"backspace", 8},
100  {"tab", 9},
101  {"enter", 13},
102  {"esc", 27},
103  {"space", ' '}
104 };
105 
106 static int gfmaxJoyButton = sizeof(GfJoyBtn) / sizeof(GfJoyBtn[0]);
107 static int gfmaxJoyAxis = sizeof(GfJoyAxis) / sizeof(GfJoyAxis[0]);
108 static int gfmaxMouseButton = sizeof(GfMouseBtn) / sizeof(GfMouseBtn[0]);
109 static int gfmaxMouseAxis = sizeof(GfMouseAxis) / sizeof(GfMouseAxis[0]);
110 static int gfmaxSKey = sizeof(GfSKey) / sizeof(GfSKey[0]);
111 static int gfmaxKey = sizeof(GfKey) / sizeof(GfKey[0]);
112 
114 static jsJoystick *js[NUM_JOY] = {NULL};
115 
116 
123 void GfctrlGetRefByName(const char *name, tCtrlRef* ref)
124 {
125  int i;
126 
127  if (!name || !strlen(name)) {
128  ref->index = -1;
130  return;
131  }
132 
133  for (i = 0; i < gfmaxJoyButton; i++) {
134  if (strcmp(name, GfJoyBtn[i]) == 0) {
135  ref->index = i;
136  ref->type = GFCTRL_TYPE_JOY_BUT;
137  return;
138  }
139  }
140 
141  for (i = 0; i < gfmaxJoyAxis; i++) {
142  if (strcmp(name, GfJoyAxis[i]) == 0) {
143  ref->index = i;
144  ref->type = GFCTRL_TYPE_JOY_AXIS;
145  return;
146  }
147  }
148 
149  for (i = 0; i < gfmaxMouseButton; i++) {
150  if (strcmp(name, GfMouseBtn[i]) == 0) {
151  ref->index = i;
153  return;
154  }
155  }
156 
157  for (i = 0; i < gfmaxMouseAxis; i++) {
158  if (strcmp(name, GfMouseAxis[i]) == 0) {
159  ref->index = i;
161  return;
162  }
163  }
164 
165  for (i = 0; i < gfmaxSKey; i++) {
166  if (strcmp(name, GfSKey[i].descr) == 0) {
167  ref->index = GfSKey[i].val;
169  return;
170  }
171  }
172 
173  for (i = 0; i < gfmaxKey; i++) {
174  if (strcmp(name, GfKey[i].descr) == 0) {
175  ref->index = GfKey[i].val;
176  ref->type = GFCTRL_TYPE_KEYBOARD;
177  return;
178  }
179  }
180 
181  ref->index = name[0];
182  ref->type = GFCTRL_TYPE_KEYBOARD;
183 }
184 
191 const char *GfctrlGetNameByRef(GfCtrlType type, int index)
192 {
193  static const int BUFSIZE = 4;
194  static char buf[BUFSIZE];
195  int i;
196 
197  switch (type) {
199  return NULL;
200 
201  case GFCTRL_TYPE_JOY_BUT:
202  if (index < gfmaxJoyButton) {
203  return GfJoyBtn[index];
204  } else {
205  return NULL;
206  }
207  break;
208 
210  if (index < gfmaxJoyAxis) {
211  return GfJoyAxis[index];
212  } else {
213  return NULL;
214  }
215  break;
216 
218  if (index < gfmaxMouseButton) {
219  return GfMouseBtn[index];
220  } else {
221  return NULL;
222  }
223  break;
224 
226  if (index < gfmaxMouseAxis) {
227  return GfMouseAxis[index];
228  } else {
229  return NULL;
230  }
231  break;
232 
234  for (i = 0; i < gfmaxSKey; i++) {
235  if (index == GfSKey[i].val) {
236  return GfSKey[i].descr;
237  }
238  }
239  return NULL;
240  break;
241 
243  for (i = 0; i < gfmaxKey; i++) {
244  if (index == GfKey[i].val) {
245  return GfKey[i].descr;
246  }
247  }
248  if (isprint(index)) {
249  snprintf(buf, BUFSIZE, "%c", index);
250  return buf;
251  }
252  return NULL;
253  break;
254 
255  default:
256  break;
257  }
258 
259  return NULL;
260 }
261 
262 
263 static void gfJoyFirstInit(void)
264 {
265  int index;
266 
268 
269  for (index = 0; index < NUM_JOY; index++) {
270  if (js[index] == NULL) {
271  js[index] = new jsJoystick(index);
272  }
273 
274  if (js[index]->notWorking()) {
275  /* don't configure the joystick */
276  js[index] = NULL;
277  } else {
279  }
280  }
281 }
282 
283 
285 {
286  switch (type) {
288  return HM_SECT_JSPREF;
289  default:
290  return HM_SECT_MOUSEPREF;
291  }
292  return "";
293 }
294 
304 {
305  tCtrlJoyInfo *joyInfo = NULL;
306 
308  gfJoyFirstInit();
309  }
310 
311  joyInfo = (tCtrlJoyInfo *)calloc(1, sizeof(tCtrlJoyInfo));
312  return joyInfo;
313 }
314 
315 
322 {
323  FREEZ(joyInfo);
324 }
325 
326 
333 {
335  gfJoyFirstInit();
336  }
337 
338  return gfctrlJoyPresent;
339 }
340 
341 
350 {
351  int ind;
352  int i;
353  int b;
354  unsigned int mask;
355 
357  for (ind = 0; ind < NUM_JOY; ind++) {
358  if (js[ind]) {
359  js[ind]->read(&b, &(joyInfo->ax[_JS_MAX_AXES * ind]));
360 
361  /* Joystick buttons */
362  for (i = 0, mask = 1; i < GFCTRL_JOY_MAXBUTTON; i++, mask *= 2) {
363  if (((b & mask) != 0) && ((joyInfo->oldb[ind] & mask) == 0)) {
364  joyInfo->edgeup[i + GFCTRL_JOY_MAXBUTTON * ind] = 1;
365  } else {
366  joyInfo->edgeup[i + GFCTRL_JOY_MAXBUTTON * ind] = 0;
367  }
368 
369  if (((b & mask) == 0) && ((joyInfo->oldb[ind] & mask) != 0)) {
370  joyInfo->edgedn[i + GFCTRL_JOY_MAXBUTTON * ind] = 1;
371  } else {
372  joyInfo->edgedn[i + GFCTRL_JOY_MAXBUTTON * ind] = 0;
373  }
374 
375  if ((b & mask) != 0) {
376  joyInfo->levelup[i + GFCTRL_JOY_MAXBUTTON * ind] = 1;
377  } else {
378  joyInfo->levelup[i + GFCTRL_JOY_MAXBUTTON * ind] = 0;
379  }
380  }
381  joyInfo->oldb[ind] = b;
382  }
383  }
384  } else {
385  return -1;
386  }
387 
388  return 0;
389 }
390 
391 
400 {
401  tCtrlMouseInfo *mouseInfo = NULL;
402  mouseInfo = (tCtrlMouseInfo *)calloc(1, sizeof(tCtrlMouseInfo));
403  return mouseInfo;
404 }
405 
406 
413 {
414  FREEZ(mouseInfo);
415 }
416 
417 
419 
428 {
429  float mouseMove;
430  tMouseInfo *mouse;
431  int i;
432 
433  mouse = GfuiMouseInfo();
434  mouseMove = (float)(refMouse.X - mouse->X);
435 
436  if (mouseMove < 0) {
437  mouseInfo->ax[1] = -mouseMove;
438  mouseInfo->ax[0] = 0;
439  } else {
440  mouseInfo->ax[0] = mouseMove;
441  mouseInfo->ax[1] = 0;
442  }
443 
444  mouseMove = (float)(refMouse.Y - mouse->Y);
445  if (mouseMove < 0) {
446  mouseInfo->ax[2] = -mouseMove;
447  mouseInfo->ax[3] = 0;
448  } else {
449  mouseInfo->ax[3] = mouseMove;
450  mouseInfo->ax[2] = 0;
451  }
452 
453  for (i = 0; i < 3; i++) {
454  if (mouseInfo->button[i] != mouse->button[i]) {
455  if (mouse->button[i]) {
456  mouseInfo->edgedn[i] = 1;
457  mouseInfo->edgeup[i] = 0;
458  } else {
459  mouseInfo->edgeup[i] = 1;
460  mouseInfo->edgedn[i] = 0;
461  }
462  mouseInfo->button[i] = mouse->button[i];
463  } else {
464  mouseInfo->edgeup[i] = 0;
465  mouseInfo->edgedn[i] = 0;
466  }
467  }
468  return 0;
469 }
470 
471 
477 {
478  int sw, sh, vw, vh;
479 
480  GfScrGetSize(&sw, &sh, &vw, &vh);
481  GfuiMouseSetPos(sw / 2, sh / 2);
482 }
483 
484 
490 {
491  memcpy(&refMouse, GfuiMouseInfo(), sizeof(refMouse));
492 }
493 
494 
502 bool GfctrlIsEventBlacklisted(void *parmHandle, const char* driversSection, const char* event)
503 {
504  const char* eventBlacklist = GfParmGetStr(parmHandle, driversSection, HM_ATT_EVENTBLACKLIST, NULL);
505  if (eventBlacklist && strstr(eventBlacklist, event)) {
506  GfOut("Blacklisted event: %s\n", event);
507  return true;
508  }
509 
510  return false;
511 }
int GfctrlMouseGetCurrent(tCtrlMouseInfo *mouseInfo)
Get the mouse current values.
Definition: control.cpp:427
tCtrlJoyInfo * GfctrlJoyInit(void)
Initialize the joystick control.
Definition: control.cpp:303
const char * descr
Definition: control.cpp:70
static int gfmaxMouseButton
Definition: control.cpp:108
static tMouseInfo refMouse
Definition: control.cpp:418
bool GfctrlIsEventBlacklisted(void *parmHandle, const char *driversSection, const char *event)
Check if given event is blacklisted (used for buttons or axis which fire a button AND move event)...
Definition: control.cpp:502
static int gfmaxJoyAxis
Definition: control.cpp:107
void GfuiMouseSetPos(int x, int y)
Set the mouse position.
Definition: gui.cpp:391
int edgedn[3]
Button transition from up to down.
Definition: tgfclient.h:297
#define FREEZ(x)
Definition: tgf.h:60
#define HM_SECT_JSPREF
Definition: playerpref.h:30
Joystick Information Structure.
Definition: tgfclient.h:278
void GfctrlMouseRelease(tCtrlMouseInfo *mouseInfo)
Release the tCtrlMouseInfo structure.
Definition: control.cpp:412
tCtrlMouseInfo * GfctrlMouseInit(void)
Initialize the mouse control.
Definition: control.cpp:399
int edgeup[3]
Button transition from down (pressed) to up.
Definition: tgfclient.h:296
static tCtrlMouseInfo mouseInfo
int GfctrlJoyGetCurrent(tCtrlJoyInfo *joyInfo)
Get the joystick current values.
Definition: control.cpp:349
static int gfmaxKey
Definition: control.cpp:111
static int gfctrlJoyPresent
Definition: control.cpp:113
#define GFCTRL_JOY_NONE
Definition: tgfclient.h:272
void GfctrlJoyRelease(tCtrlJoyInfo *joyInfo)
Release the tCtrlJoyInfo structure.
Definition: control.cpp:321
static tgfKeyBinding GfKey[]
Definition: control.cpp:98
const char * GfParmGetStr(void *parmHandle, const char *path, const char *key, const char *deflt)
Get a string parameter from the parameter set handle.
Definition: params.cpp:2311
GfCtrlType type
Definition: tgfclient.h:267
static tgfKeyBinding GfSKey[]
Definition: control.cpp:74
The Gaming Framework API (client part).
int button[3]
Definition: tgfclient.h:148
GfCtrlType
Definition: tgfclient.h:254
int button[3]
Button state (1 = up)
Definition: tgfclient.h:298
#define GFCTRL_JOY_PRESENT
Definition: tgfclient.h:273
static int gfmaxSKey
Definition: control.cpp:110
int oldb[NUM_JOY]
Definition: tgfclient.h:280
const char * GfctrlGetDefaultSection(GfCtrlType type)
Definition: control.cpp:284
const char * GfctrlGetNameByRef(GfCtrlType type, int index)
Get a control name by its reference.
Definition: control.cpp:191
#define GfOut
Definition: tgf.h:373
float ax[_JS_MAX_AXES *NUM_JOY]
Axis values.
Definition: tgfclient.h:281
Parameter set handle structure, multiple handles can reference the same parameter set...
Definition: params.cpp:125
tMouseInfo * GfuiMouseInfo(void)
Get the mouse information (position and buttons)
Definition: gui.cpp:380
int levelup[GFCTRL_JOY_MAXBUTTON *NUM_JOY]
Button state (1 = up)
Definition: tgfclient.h:284
static const char * GfMouseBtn[]
Definition: control.cpp:64
int GfctrlJoyIsPresent(void)
Check if a joystick is present.
Definition: control.cpp:332
static jsJoystick * js[NUM_JOY]
Definition: control.cpp:114
#define HM_SECT_MOUSEPREF
Definition: playerpref.h:31
void GfctrlMouseInitCenter(void)
Get the reference position.
Definition: control.cpp:489
int edgedn[GFCTRL_JOY_MAXBUTTON *NUM_JOY]
Button transition from up to down.
Definition: tgfclient.h:283
#define GFCTRL_JOY_MAXBUTTON
Definition: tgfclient.h:275
static int gfmaxMouseAxis
Definition: control.cpp:109
void GfctrlGetRefByName(const char *name, tCtrlRef *ref)
Get a control reference by its name.
Definition: control.cpp:123
void GfScrGetSize(int *scrw, int *scrh, int *vieww, int *viewh)
Get the screen and viewport sizes.
Definition: screen.cpp:471
#define GFCTRL_JOY_UNTESTED
Definition: tgfclient.h:271
int edgeup[GFCTRL_JOY_MAXBUTTON *NUM_JOY]
Button transition from down (pressed) to up.
Definition: tgfclient.h:282
#define HM_ATT_EVENTBLACKLIST
Definition: playerpref.h:111
void GfctrlMouseCenter(void)
Recentre the mouse on the screen.
Definition: control.cpp:476
Mouse information structure.
Definition: tgfclient.h:294
float ax[4]
mouse axis position (mouse considered as a joystick)
Definition: tgfclient.h:299
int index
Definition: tgfclient.h:266
static void gfJoyFirstInit(void)
Definition: control.cpp:263
static const char * GfJoyAxis[]
Definition: control.cpp:53
static const char * GfJoyBtn[]
Definition: control.cpp:34
#define NUM_JOY
Definition: tgfclient.h:35
static const char * GfMouseAxis[]
Definition: control.cpp:66
static int gfmaxJoyButton
Definition: control.cpp:106