replaced by maths.h
[btb/d2x.git] / unused / bios / joyc.c
1 /*
2 THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
3 SOFTWARE CORPORATION ("PARALLAX").  PARALLAX, IN DISTRIBUTING THE CODE TO
4 END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
5 ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
6 IN USING, DISPLAYING,  AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
7 SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
8 FREE PURPOSES.  IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
9 CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES.  THE END-USER UNDERSTANDS
10 AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.  
11 COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION.  ALL RIGHTS RESERVED.
12 */
13
14
15 #pragma off (unreferenced)
16 static char rcsid[] = "$Id: joyc.c,v 1.1.1.1 2001-01-19 03:30:14 bradleyb Exp $";
17 #pragma on (unreferenced)
18
19 #include <stdlib.h>
20 #include <stdio.h>
21 #include <conio.h>
22 #include <dos.h>
23 #include <i86.h>
24
25 //#define ARCADE 1
26
27 #include "types.h"
28 #include "error.h"
29 #include "mono.h"
30 #include "joy.h"
31 #include "dpmi.h"
32
33 //In key.c
34 // ebx = read mask                                                                           
35 // edi = pointer to buffer                                                                                                                                                                                      
36 // returns number of events                                                                                                                                                                             
37 int joy_read_stick_asm( int read_masks, int * event_buffer, int timeout );
38 #pragma aux joy_read_stick_asm parm [ebx] [edi] [ecx] value [eax] modify exact [eax ebx ecx edx edi];
39
40 int joy_read_stick_polled( int read_masks, int * event_buffer, int timeout );
41 #pragma aux joy_read_stick_polled parm [ebx] [edi] [ecx] value [eax] modify exact [eax ebx ecx edx edi];
42
43 int joy_read_stick_bios( int read_masks, int * event_buffer, int timeout );
44 #pragma aux joy_read_stick_bios parm [ebx] [edi] [ecx] value [eax] modify exact [eax ebx ecx edx edi];
45
46
47 char joy_installed = 0;
48 char joy_present = 0;
49
50 #define JOY_READ_BUTTONS        ((~(inp(0x201) >> 4))&0xf)
51 #ifdef ARCADE
52 #define JOY_READ_BUTTONS_ARCADE (~(inp(0x2A1)))
53 #define MAX_BUTTONS 28
54 #else
55 #define MAX_BUTTONS 20
56 #endif
57
58 typedef struct Button_info {
59         ubyte           ignore;
60         ubyte           state;
61         ubyte           last_state;
62         int             timedown;
63         ubyte           downcount;
64         ubyte           upcount;
65 } Button_info;
66
67 typedef struct Joy_info {
68         ubyte                   present_mask;
69         ubyte                   slow_read;
70         int                     max_timer;
71         int                     read_count;
72         ubyte                   last_value;
73         Button_info     buttons[MAX_BUTTONS];
74         int                     axis_min[4];
75         int                     axis_center[4];
76         int                     axis_max[4];
77 } Joy_info;
78
79 Joy_info joystick;
80
81 void joy_get_cal_vals(int *axis_min, int *axis_center, int *axis_max)
82 {
83         int i;
84
85         for (i=0; i<4; i++)             {
86                 axis_min[i] = joystick.axis_min[i];
87                 axis_center[i] = joystick.axis_center[i];
88                 axis_max[i] = joystick.axis_max[i];
89         }
90 }
91
92 void joy_set_cal_vals(int *axis_min, int *axis_center, int *axis_max)
93 {
94         int i;
95
96         for (i=0; i<4; i++)             {
97                 joystick.axis_min[i] = axis_min[i];
98                 joystick.axis_center[i] = axis_center[i];
99                 joystick.axis_max[i] = axis_max[i];
100         }
101 }
102
103
104 ubyte joy_get_present_mask()    {
105         return joystick.present_mask;
106 }
107
108 void joy_set_timer_rate(int max_value ) {
109         _disable();
110         joystick.max_timer = max_value;
111         _enable();
112 }
113
114 int joy_get_timer_rate()        {
115         return joystick.max_timer;
116 }
117
118
119 void joy_flush()        {
120         int i;
121
122         if (!joy_installed) return;
123
124         _disable();
125         for (i=0; i<MAX_BUTTONS; i++ )  {
126                 joystick.buttons[i].ignore = 0;
127                 joystick.buttons[i].state = 0;  
128                 joystick.buttons[i].timedown = 0;       
129                 joystick.buttons[i].downcount = 0;      
130                 joystick.buttons[i].upcount = 0;        
131         }
132         _enable();
133
134 }
135
136 #pragma off (check_stack)
137
138 extern int joy_read_buttons_bios();
139
140 void joy_handler(int ticks_this_time)   {
141         ubyte value;
142 #ifdef ARCADE
143         ubyte valuea;
144 #endif
145         int i, state;
146         Button_info * button;
147
148         joystick.max_timer = ticks_this_time;
149
150         if ( joystick.slow_read & JOY_BIOS_READINGS )           {
151                 joystick.read_count++;
152                 if ( joystick.read_count > 7 )  {
153                         joystick.read_count = 0;
154                         value = joy_read_buttons_bios();
155                         joystick.last_value = value;
156                 } else {
157                         value = joystick.last_value;
158                 }               
159         } else {
160                 value = JOY_READ_BUTTONS;
161         #ifdef ARCADE
162                 valuea = JOY_READ_BUTTONS_ARCADE;
163         #endif
164         }
165
166         for (i=0; i<MAX_BUTTONS; i++ )  {
167                 button = &joystick.buttons[i];
168                 if (!button->ignore) {
169                         if ( i < 5 )
170                                 state = (value >> i) & 1;
171 #ifdef ARCADE
172                         else if ( i >= 20 ) 
173                                 state = (valuea >> (i-20)) & 1;
174 #endif
175                         else if (i==(value+4))  
176                                 state = 1;
177                         else
178                                 state = 0;
179
180                         if ( button->last_state == state )      {
181                                 if (state) button->timedown += ticks_this_time;
182                         } else {
183                                 if (state)      {
184                                         button->downcount += state;
185                                         button->state = 1;
186                                 } else {        
187                                         button->upcount += button->state;
188                                         button->state = 0;
189                                 }
190                                 button->last_state = state;
191                         }
192                 }
193         }
194 }
195
196 void joy_handler_end()  {               // Dummy function to help calculate size of joystick handler function
197 }
198
199 #pragma off (check_stack)
200
201 ubyte joy_read_raw_buttons()    {
202         if ( joystick.slow_read & JOY_BIOS_READINGS )   
203                 return joy_read_buttons_bios();
204         else 
205                 return JOY_READ_BUTTONS;
206 }
207
208 void joy_set_slow_reading(int flag)
209 {
210         joystick.slow_read |= flag;
211         joy_set_cen();
212 }
213
214 ubyte joystick_read_raw_axis( ubyte mask, int * axis )
215 {
216         ubyte read_masks, org_masks;
217         int t, t1, t2, buffer[4*2+2];
218         int e, i, num_channels, c;
219
220         axis[0] = 0; axis[1] = 0;
221         axis[2] = 0; axis[3] = 0;
222
223         if (!joy_installed) return 0;
224
225         read_masks = 0;
226         org_masks = mask;
227
228         mask &= joystick.present_mask;                  // Don't read non-present channels
229         if ( mask==0 )  {
230                 return 0;               // Don't read if no stick connected.
231         }
232
233         if ( joystick.slow_read & JOY_SLOW_READINGS )   {
234                 for (c=0; c<4; c++ )    {               
235                         if ( mask & (1 << c))   {
236                                 // Time out at  (1/100th of a second)
237
238                                 if ( joystick.slow_read & JOY_POLLED_READINGS )
239                                         num_channels = joy_read_stick_polled( (1 << c), buffer, 65536 );
240                                 else if ( joystick.slow_read & JOY_BIOS_READINGS )
241                                         num_channels = joy_read_stick_bios( (1 << c), buffer, 65536 );
242                                 else
243                                         num_channels = joy_read_stick_asm( (1 << c), buffer, (1193180/100) );
244         
245                                 if ( num_channels > 0 ) {
246                                         t1 = buffer[0];
247                                         e = buffer[1];
248                                         t2 = buffer[2];
249                                         if ( joystick.slow_read & (JOY_POLLED_READINGS|JOY_BIOS_READINGS) )     {
250                                                 t = t2 - t1;
251                                         } else {                        
252                                                 if ( t1 > t2 )
253                                                         t = t1 - t2;
254                                                 else                            {
255                                                         t = t1 + joystick.max_timer - t2;
256                                                         //mprintf( 0, "%d, %d, %d, %d\n", t1, t2, joystick.max_timer, t );
257                                                 }
258                                         }
259         
260                                         if ( e & 1 ) { axis[0] = t; read_masks |= 1; }
261                                         if ( e & 2 ) { axis[1] = t; read_masks |= 2; }
262                                         if ( e & 4 ) { axis[2] = t; read_masks |= 4; }
263                                         if ( e & 8 ) { axis[3] = t; read_masks |= 8; }
264                                 }
265                         }
266                 }
267         } else {
268                 // Time out at  (1/100th of a second)
269                 if ( joystick.slow_read & JOY_POLLED_READINGS )
270                         num_channels = joy_read_stick_polled( mask, buffer, 65536 );
271                 else if ( joystick.slow_read & JOY_BIOS_READINGS )
272                         num_channels = joy_read_stick_bios( (1 << c), buffer, 65536 );
273                 else 
274                         num_channels = joy_read_stick_asm( mask, buffer, (1193180/100) );
275                 //mprintf(( 0, "(%d)\n", num_channels ));
276         
277                 for (i=0; i<num_channels; i++ ) {
278                         t1 = buffer[0];
279                         t2 = buffer[i*2+2];
280                         
281                         if ( joystick.slow_read & (JOY_POLLED_READINGS|JOY_BIOS_READINGS) )     {
282                                 t = t2 - t1;
283                         } else {                        
284                                 if ( t1 > t2 )
285                                         t = t1 - t2;
286                                 else                            {
287                                         t = t1 + joystick.max_timer - t2;
288                                         //mprintf(( 0, "%d, %d, %d, %d\n", t1, t2, joystick.max_timer, t ));
289                                 }
290                         }               
291                         e = buffer[i*2+1];
292         
293                         if ( e & 1 ) { axis[0] = t; read_masks |= 1; }
294                         if ( e & 2 ) { axis[1] = t; read_masks |= 2; }
295                         if ( e & 4 ) { axis[2] = t; read_masks |= 4; }
296                         if ( e & 8 ) { axis[3] = t; read_masks |= 8; }
297                 }
298                 
299         }
300
301         return read_masks;
302 }
303
304 extern void timer_set_joyhandler( void (*joy_handler)() );
305
306 int joy_init()  
307 {
308         int i;
309         int temp_axis[4];
310
311         joy_flush();
312
313         _disable();
314         for (i=0; i<MAX_BUTTONS; i++ )  
315                 joystick.buttons[i].last_state = 0;
316         _enable();
317
318         if ( !joy_installed )   {
319                 joy_present = 0;
320                 joy_installed = 1;
321                 joystick.max_timer = 65536;
322                 joystick.slow_read = 0;
323                 joystick.read_count = 0;
324                 joystick.last_value = 0;
325
326                 //--------------- lock everything for the virtal memory ----------------------------------
327                 if (!dpmi_lock_region ((void near *)joy_handler, (char *)joy_handler_end - (char near *)joy_handler))   {
328                         Error( "Can't lock joystick handler!\n" );
329                 }
330
331                 if (!dpmi_lock_region (&joystick, sizeof(Joy_info)))    {
332                         Error( "Can't lock joystick handler's data!\n" );
333                 }
334
335                 timer_set_joyhandler(joy_handler);
336         }
337
338         // Do initial cheapy calibration...
339         joystick.present_mask = JOY_ALL_AXIS;           // Assume they're all present
340         joystick.present_mask = joystick_read_raw_axis( JOY_ALL_AXIS, temp_axis );
341
342         if ( joystick.present_mask & 3 )
343                 joy_present = 1;
344         else
345                 joy_present = 0;
346
347         return joy_present;
348 }
349
350 void joy_close()        
351 {
352         if (!joy_installed) return;
353         joy_installed = 0;
354 }
355
356 void joy_set_ul()       
357 {
358         joystick.present_mask = JOY_ALL_AXIS;           // Assume they're all present
359         joystick.present_mask = joystick_read_raw_axis( JOY_ALL_AXIS, joystick.axis_min );
360         if ( joystick.present_mask & 3 )
361                 joy_present = 1;
362         else
363                 joy_present = 0;
364 }
365
366 void joy_set_lr()       
367 {
368         joystick.present_mask = JOY_ALL_AXIS;           // Assume they're all present
369         joystick.present_mask = joystick_read_raw_axis( JOY_ALL_AXIS, joystick.axis_max );
370         if ( joystick.present_mask & 3 )
371                 joy_present = 1;
372         else
373                 joy_present = 0;
374 }
375
376 void joy_set_cen() 
377 {
378         joystick.present_mask = JOY_ALL_AXIS;           // Assume they're all present
379         joystick.present_mask = joystick_read_raw_axis( JOY_ALL_AXIS, joystick.axis_center );
380         if ( joystick.present_mask & 3 )
381                 joy_present = 1;
382         else
383                 joy_present = 0;
384 }
385
386 void joy_set_cen_fake(int channel)      
387 {
388
389         int i,n=0;
390         int minx, maxx, cenx;
391         
392         minx=maxx=cenx=0;
393
394         for (i=0; i<4; i++ )    {
395                 if ( (joystick.present_mask & (1<<i)) && (i!=channel) ) {
396                         n++;
397                         minx += joystick.axis_min[i];
398                         maxx += joystick.axis_max[i];
399                         cenx += joystick.axis_center[i];
400                 }
401         }
402         minx /= n;
403         maxx /= n;
404         cenx /= n;
405
406         joystick.axis_min[channel] = minx;
407         joystick.axis_max[channel] = maxx;
408         joystick.axis_center[channel] = cenx;
409 }
410
411 int joy_get_scaled_reading( int raw, int axn )  
412 {
413         int x, d;
414
415         // Make sure it's calibrated properly.
416         if ( joystick.axis_center[axn] - joystick.axis_min[axn] < 5 ) return 0;
417         if ( joystick.axis_max[axn] - joystick.axis_center[axn] < 5 ) return 0;
418
419         raw -= joystick.axis_center[axn];
420
421         if ( raw < 0 )  {
422                 d = joystick.axis_center[axn]-joystick.axis_min[axn];
423         } else {
424                 d = joystick.axis_max[axn]-joystick.axis_center[axn];
425         }
426
427         if ( d )
428                 x = (raw << 7) / d;
429         else 
430                 x = 0;
431
432         if ( x < -128 ) x = -128;
433         if ( x > 127 ) x = 127;
434
435         return x;
436 }
437
438 void joy_get_pos( int *x, int *y )      
439 {
440         ubyte flags;
441         int axis[4];
442
443         if ((!joy_installed)||(!joy_present)) { *x=*y=0; return; }
444
445         flags=joystick_read_raw_axis( JOY_1_X_AXIS+JOY_1_Y_AXIS, axis );
446
447         if ( flags & JOY_1_X_AXIS )
448                 *x = joy_get_scaled_reading( axis[0], 0 );
449         else
450                 *x = 0;
451
452         if ( flags & JOY_1_Y_AXIS )
453                 *y = joy_get_scaled_reading( axis[1], 1 );
454         else
455                 *y = 0;
456 }
457
458 ubyte joy_read_stick( ubyte masks, int *axis )  
459 {
460         ubyte flags;
461         int raw_axis[4];
462
463         if ((!joy_installed)||(!joy_present)) { 
464                 axis[0] = 0; axis[1] = 0;
465                 axis[2] = 0; axis[3] = 0;
466                 return 0;  
467         }
468
469         flags=joystick_read_raw_axis( masks, raw_axis );
470
471         if ( flags & JOY_1_X_AXIS )
472                 axis[0] = joy_get_scaled_reading( raw_axis[0], 0 );
473         else
474                 axis[0] = 0;
475
476         if ( flags & JOY_1_Y_AXIS )
477                 axis[1] = joy_get_scaled_reading( raw_axis[1], 1 );
478         else
479                 axis[1] = 0;
480
481         if ( flags & JOY_2_X_AXIS )
482                 axis[2] = joy_get_scaled_reading( raw_axis[2], 2 );
483         else
484                 axis[2] = 0;
485
486         if ( flags & JOY_2_Y_AXIS )
487                 axis[3] = joy_get_scaled_reading( raw_axis[3], 3 );
488         else
489                 axis[3] = 0;
490
491         return flags;
492 }
493
494
495 int joy_get_btns()      
496 {
497         if ((!joy_installed)||(!joy_present)) return 0;
498
499         return joy_read_raw_buttons();
500 }
501
502 void joy_get_btn_down_cnt( int *btn0, int *btn1 ) 
503 {
504         if ((!joy_installed)||(!joy_present)) { *btn0=*btn1=0; return; }
505
506         _disable();
507         *btn0 = joystick.buttons[0].downcount;
508         joystick.buttons[0].downcount = 0;
509         *btn1 = joystick.buttons[1].downcount;
510         joystick.buttons[1].downcount = 0;
511         _enable();
512 }
513
514 int joy_get_button_state( int btn )     
515 {
516         int count;
517
518         if ((!joy_installed)||(!joy_present)) return 0;
519
520         if ( btn >= MAX_BUTTONS ) return 0;
521
522         _disable();
523         count = joystick.buttons[btn].state;
524         _enable();
525         
526         return  count;
527 }
528
529 int joy_get_button_up_cnt( int btn ) 
530 {
531         int count;
532
533         if ((!joy_installed)||(!joy_present)) return 0;
534
535         if ( btn >= MAX_BUTTONS ) return 0;
536
537         _disable();
538         count = joystick.buttons[btn].upcount;
539         joystick.buttons[btn].upcount = 0;
540         _enable();
541
542         return count;
543 }
544
545 int joy_get_button_down_cnt( int btn ) 
546 {
547         int count;
548
549         if ((!joy_installed)||(!joy_present)) return 0;
550         if ( btn >= MAX_BUTTONS ) return 0;
551
552         _disable();
553         count = joystick.buttons[btn].downcount;
554         joystick.buttons[btn].downcount = 0;
555         _enable();
556
557         return count;
558 }
559
560         
561 fix joy_get_button_down_time( int btn ) 
562 {
563         fix count;
564
565         if ((!joy_installed)||(!joy_present)) return 0;
566         if ( btn >= MAX_BUTTONS ) return 0;
567
568         _disable();
569         count = joystick.buttons[btn].timedown;
570         joystick.buttons[btn].timedown = 0;
571         _enable();
572
573         return fixmuldiv(count, 65536, 1193180 );
574 }
575
576 void joy_get_btn_up_cnt( int *btn0, int *btn1 ) 
577 {
578         if ((!joy_installed)||(!joy_present)) { *btn0=*btn1=0; return; }
579
580         _disable();
581         *btn0 = joystick.buttons[0].upcount;
582         joystick.buttons[0].upcount = 0;
583         *btn1 = joystick.buttons[1].upcount;
584         joystick.buttons[1].upcount = 0;
585         _enable();
586 }
587
588 void joy_set_btn_values( int btn, int state, fix timedown, int downcount, int upcount )
589 {
590         _disable();
591         joystick.buttons[btn].ignore = 1;
592         joystick.buttons[btn].state = state;
593         joystick.buttons[btn].timedown = fixmuldiv( timedown, 1193180, 65536 );
594         joystick.buttons[btn].downcount = downcount;
595         joystick.buttons[btn].upcount = upcount;
596         _enable();
597 }
598
599 void joy_poll()
600 {
601         if ( joystick.slow_read & JOY_BIOS_READINGS )   
602                 joystick.last_value = joy_read_buttons_bios();
603 }