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