00d497f352b1cf938cdc726ea60277e02da9ab65
[rocksndiamonds.git] / src / joystick.c
1 /***********************************************************
2 *  Rocks'n'Diamonds -- McDuffin Strikes Back!              *
3 *----------------------------------------------------------*
4 *  (c) 1995-98 Artsoft Entertainment                       *
5 *              Holger Schemel                              *
6 *              Oststrasse 11a                              *
7 *              33604 Bielefeld                             *
8 *              phone: ++49 +521 290471                     *
9 *              email: aeglos@valinor.owl.de                *
10 *----------------------------------------------------------*
11 *  joystick.c                                              *
12 ***********************************************************/
13
14 #ifdef __FreeBSD__
15 #include <machine/joystick.h>
16 #endif
17
18 #include "joystick.h"
19 #include "misc.h"
20
21 #ifndef MSDOS
22 static int JoystickPosition(int middle, int margin, int actual)
23 {
24   long range, pos;
25   int percentage;
26
27   if (margin < middle && actual > middle)
28     return 0;
29   if (margin > middle && actual < middle)
30     return 0;
31
32   range = ABS(margin - middle);
33   pos = ABS(actual - middle);
34   percentage = (int)(pos * 100 / range);
35
36   if (percentage > 100)
37     percentage = 100;
38
39   return percentage;
40 }
41 #endif
42
43 #ifdef USE_SDL_JOYSTICK
44
45 static SDL_Joystick *sdl_joystick[MAX_PLAYERS] = { NULL, NULL, NULL, NULL };
46 static int sdl_js_axis[MAX_PLAYERS][2]   = { {0, 0}, {0, 0}, {0, 0}, {0, 0} };
47 static int sdl_js_button[MAX_PLAYERS][2] = { {0, 0}, {0, 0}, {0, 0}, {0, 0} };
48
49 SDL_Joystick *Get_SDL_Joystick(int nr)
50 {
51   return sdl_joystick[nr];
52 }
53
54 boolean Open_SDL_Joystick(int nr)
55 {
56   if (nr < 0 || nr > MAX_PLAYERS)
57     return FALSE;
58
59   return ((sdl_joystick[nr] = SDL_JoystickOpen(nr)) == NULL ? FALSE : TRUE);
60 }
61
62 void Close_SDL_Joystick(int nr)
63 {
64   if (nr < 0 || nr > MAX_PLAYERS)
65     return;
66
67   SDL_JoystickClose(sdl_joystick[nr]);
68 }
69
70 boolean Check_SDL_JoystickOpened(int nr)
71 {
72   if (nr < 0 || nr > MAX_PLAYERS)
73     return FALSE;
74
75   return (SDL_JoystickOpened(nr) ? TRUE : FALSE);
76 }
77
78 void HandleJoystickEvent(Event *event)
79 {
80   switch(event->type)
81   {
82     case SDL_JOYAXISMOTION:
83       if (event->jaxis.axis < 2)
84       {
85         sdl_js_axis[event->jaxis.which][event->jaxis.axis]= event->jaxis.value;
86
87 #if 0
88         printf("js_%d %s-axis: %d\n",
89                event->jaxis.which,
90                (event->jaxis.axis == 0 ? "x" : "y"),
91                event->jaxis.value);
92 #endif
93       }
94       break;
95
96     case SDL_JOYBUTTONDOWN:
97       if (event->jbutton.button < 2)
98       {
99         sdl_js_button[event->jbutton.which][event->jbutton.button] = TRUE;
100
101 #if 0
102         printf("js_%d button %d: pressed\n",
103                event->jbutton.which,
104                event->jbutton.button);
105 #endif
106       }
107       break;
108
109     case SDL_JOYBUTTONUP:
110       if (event->jbutton.button < 2)
111       {
112         sdl_js_button[event->jbutton.which][event->jbutton.button] = FALSE;
113
114 #if 0
115         printf("js_%d button %d: released\n",
116                event->jbutton.which,
117                event->jbutton.button);
118 #endif
119       }
120       break;
121
122     default:
123       break;
124   }
125 }
126
127 int Get_SDL_Joystick_Axis(int nr, int axis)
128 {
129   if (nr < 0 || nr > MAX_PLAYERS)
130     return 0;
131
132   if (axis < 0 || axis > 1)
133     return 0;
134
135   return sdl_js_axis[nr][axis];
136 }
137
138 void CheckJoystickData()
139 {
140 }
141
142 int Joystick(int player_nr)
143 {
144   int joystick_nr = stored_player[player_nr].joystick_fd;
145   int js_x,js_y, js_b1,js_b2;
146   int left, right, up, down;
147   int result = 0;
148
149   if (joystick_status == JOYSTICK_OFF)
150     return 0;
151
152   if (game_status == SETUPINPUT)
153     return 0;
154
155   if (!setup.input[player_nr].use_joystick ||
156       !Check_SDL_JoystickOpened(joystick_nr))
157     return 0;
158
159   js_x  = sdl_js_axis[joystick_nr][0];
160   js_y  = sdl_js_axis[joystick_nr][1];
161
162   js_b1 = sdl_js_button[joystick_nr][0];
163   js_b2 = sdl_js_button[joystick_nr][1];
164
165
166
167 #if 0
168   printf("JOYSTICK %d: js_x == %d, js_y == %d, js_b1 == %d, js_b2 == %d\n",
169          joystick_nr, js_x, js_y, js_b1, js_b2);
170 #endif
171
172
173
174   left  = JoystickPosition(setup.input[player_nr].joy.xmiddle,
175                            setup.input[player_nr].joy.xleft,  js_x);
176   right = JoystickPosition(setup.input[player_nr].joy.xmiddle,
177                            setup.input[player_nr].joy.xright, js_x);
178   up    = JoystickPosition(setup.input[player_nr].joy.ymiddle,
179                            setup.input[player_nr].joy.yupper, js_y);
180   down  = JoystickPosition(setup.input[player_nr].joy.ymiddle,
181                            setup.input[player_nr].joy.ylower, js_y);
182
183   if (left > JOYSTICK_PERCENT)
184     result |= JOY_LEFT;
185   else if (right > JOYSTICK_PERCENT)
186     result |= JOY_RIGHT;
187   if (up > JOYSTICK_PERCENT)
188     result |= JOY_UP;
189   else if (down > JOYSTICK_PERCENT)
190     result |= JOY_DOWN;
191
192   if (js_b1)
193     result |= JOY_BUTTON_1;
194   if (js_b2)
195     result |= JOY_BUTTON_2;
196
197
198
199 #if 0
200   printf("result == 0x%08x\n", result);
201 #endif
202
203
204
205   return result;
206 }
207
208 #else /* !USE_SDL_JOYSTICK */
209
210 void CheckJoystickData()
211 {
212   int i;
213   int distance = 100;
214
215   for(i=0; i<MAX_PLAYERS; i++)
216   {
217     if (setup.input[i].joy.xmiddle <= distance)
218       setup.input[i].joy.xmiddle = distance;
219     if (setup.input[i].joy.ymiddle <= distance)
220       setup.input[i].joy.ymiddle = distance;
221
222     if (setup.input[i].joy.xleft >= setup.input[i].joy.xmiddle)
223       setup.input[i].joy.xleft = setup.input[i].joy.xmiddle - distance;
224     if (setup.input[i].joy.xright <= setup.input[i].joy.xmiddle)
225       setup.input[i].joy.xright = setup.input[i].joy.xmiddle + distance;
226
227     if (setup.input[i].joy.yupper >= setup.input[i].joy.ymiddle)
228       setup.input[i].joy.yupper = setup.input[i].joy.ymiddle - distance;
229     if (setup.input[i].joy.ylower <= setup.input[i].joy.ymiddle)
230       setup.input[i].joy.ylower = setup.input[i].joy.ymiddle + distance;
231   }
232 }
233
234 #ifndef MSDOS
235 int Joystick(int player_nr)
236 {
237 #ifdef __FreeBSD__
238   struct joystick joy_ctrl;
239 #else
240   struct joystick_control
241   {
242     int buttons;
243     int x;
244     int y;
245   } joy_ctrl;
246 #endif
247
248   int joystick_fd = stored_player[player_nr].joystick_fd;
249   int js_x,js_y, js_b1,js_b2;
250   int left, right, up, down;
251   int result = 0;
252
253   if (joystick_status == JOYSTICK_OFF)
254     return 0;
255
256   if (game_status == SETUPINPUT)
257     return 0;
258
259   if (joystick_fd < 0 || !setup.input[player_nr].use_joystick)
260     return 0;
261
262   if (read(joystick_fd, &joy_ctrl, sizeof(joy_ctrl)) != sizeof(joy_ctrl))
263   {
264     Error(ERR_WARN, "cannot read joystick device '%s'",
265           setup.input[player_nr].joy.device_name);
266     joystick_status = JOYSTICK_OFF;
267     return 0;
268   }
269
270   js_x  = joy_ctrl.x;
271   js_y  = joy_ctrl.y;
272
273 #ifdef __FreeBSD__
274   js_b1 = joy_ctrl.b1;
275   js_b2 = joy_ctrl.b2;
276 #else
277   js_b1 = joy_ctrl.buttons & 1;
278   js_b2 = joy_ctrl.buttons & 2;
279 #endif
280
281   left  = JoystickPosition(setup.input[player_nr].joy.xmiddle,
282                            setup.input[player_nr].joy.xleft,  js_x);
283   right = JoystickPosition(setup.input[player_nr].joy.xmiddle,
284                            setup.input[player_nr].joy.xright, js_x);
285   up    = JoystickPosition(setup.input[player_nr].joy.ymiddle,
286                            setup.input[player_nr].joy.yupper, js_y);
287   down  = JoystickPosition(setup.input[player_nr].joy.ymiddle,
288                            setup.input[player_nr].joy.ylower, js_y);
289
290   if (left > JOYSTICK_PERCENT)
291     result |= JOY_LEFT;
292   else if (right > JOYSTICK_PERCENT)
293     result |= JOY_RIGHT;
294   if (up > JOYSTICK_PERCENT)
295     result |= JOY_UP;
296   else if (down > JOYSTICK_PERCENT)
297     result |= JOY_DOWN;
298
299   if (js_b1)
300     result |= JOY_BUTTON_1;
301   if (js_b2)
302     result |= JOY_BUTTON_2;
303
304   return result;
305 }
306
307 #else /* MSDOS */
308
309 /* allegro global variables for joystick control */
310 extern int num_joysticks;
311 extern JOYSTICK_INFO joy[];
312
313 int Joystick(int player_nr)
314 {
315   int joystick_nr = stored_player[player_nr].joystick_fd;
316   int result = 0;
317
318   if (joystick_status == JOYSTICK_OFF)
319     return 0;
320
321   if (game_status == SETUPINPUT)
322     return 0;
323
324   if (joystick_nr < 0)
325     return 0;
326
327   /* the allegro global variable 'num_joysticks' contains the number
328      of joysticks found at initialization under MSDOS / Windows */
329
330 #if 0
331   if (joystick_nr >= num_joysticks || !setup.input[player_nr].use_joystick)
332     return 0;
333 #else
334
335 #if 1
336   if (joystick_nr >= num_joysticks ||
337       (game_status == PLAYING && !setup.input[player_nr].use_joystick))
338     return 0;
339 #else
340   if (joystick_nr >= num_joysticks)
341     return 0;
342 #endif
343
344 #endif
345
346   poll_joystick();
347
348   if (joy[joystick_nr].stick[0].axis[0].d1)
349     result |= JOY_LEFT;
350   else if (joy[joystick_nr].stick[0].axis[0].d2)
351     result |= JOY_RIGHT;
352   if (joy[joystick_nr].stick[0].axis[1].d1)
353     result |= JOY_UP;
354   else if (joy[joystick_nr].stick[0].axis[1].d2)
355     result |= JOY_DOWN;
356
357   if (joy[joystick_nr].button[0].b)
358     result |= JOY_BUTTON_1;
359   if (joy[joystick_nr].button[1].b)
360     result |= JOY_BUTTON_2;
361
362   return result;
363 }
364 #endif /* MSDOS */
365
366 #endif /* !USE_SDL_JOYSTICK */
367
368 int JoystickButton(int player_nr)
369 {
370   static int last_joy_button[MAX_PLAYERS] = { 0, 0, 0, 0 };
371   int joy_button = (Joystick(player_nr) & JOY_BUTTON);
372   int result;
373
374   if (joy_button)
375   {
376     if (last_joy_button[player_nr])
377       result = JOY_BUTTON_PRESSED;
378     else
379       result = JOY_BUTTON_NEW_PRESSED;
380   }
381   else
382   {
383     if (last_joy_button[player_nr])
384       result = JOY_BUTTON_NEW_RELEASED;
385     else
386       result = JOY_BUTTON_NOT_PRESSED;
387   }
388
389   last_joy_button[player_nr] = joy_button;
390   return result;
391 }
392
393 int AnyJoystick()
394 {
395   int i;
396   int result = 0;
397
398   for (i=0; i<MAX_PLAYERS; i++)
399   {
400
401     /*
402     if (!setup.input[i].use_joystick)
403       continue;
404       */
405
406
407     result |= Joystick(i);
408   }
409
410   return result;
411 }
412
413 int AnyJoystickButton()
414 {
415   int i;
416   int result;
417
418   for (i=0; i<MAX_PLAYERS; i++)
419   {
420
421     /*
422     if (!setup.input[i].use_joystick)
423       continue;
424       */
425
426     /*
427     result |= JoystickButton(i);
428     */
429
430     result = JoystickButton(i);
431     if (result != JOY_BUTTON_NOT_PRESSED)
432       break;
433   }
434
435   return result;
436 }