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