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