]> icculus.org git repositories - btb/d2x.git/blob - arch/dos/joyc.c
use the orientation parameter of g3_draw_bitmap
[btb/d2x.git] / arch / dos / 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-1998 PARALLAX SOFTWARE CORPORATION.  ALL RIGHTS RESERVED.
12 */
13
14 /*
15  * 
16  * Routines for joystick reading.
17  * 
18  */
19
20 #ifdef HAVE_CONFIG_H
21 #include <conf.h>
22 #endif
23
24 #include <stdlib.h>
25 #include <stdio.h>
26 #include <dos.h>
27
28 //#define ARCADE 1
29
30 #include "pstypes.h"
31 #include "mono.h"
32 #include "joy.h"
33 #include "u_dpmi.h"
34 #include "timer.h"
35
36 #include "args.h"
37
38 extern int joy_bogus_reading;
39 int JOY_PORT = 513; //201h;
40 int joy_deadzone = 0;
41
42 int joy_read_stick_asm2( int read_masks, int * event_buffer, int timeout );
43 int joy_read_stick_friendly2( int read_masks, int * event_buffer, int timeout );
44 int joy_read_stick_polled2( int read_masks, int * event_buffer, int timeout );
45 int joy_read_stick_bios2( int read_masks, int * event_buffer, int timeout );
46 int joy_read_buttons_bios2();
47 void joy_read_buttons_bios_end2();
48
49
50 //In key.c
51 // ebx = read mask                                                                           
52 // edi = pointer to buffer                                                                                                                                                                                      
53 // returns number of events                                                                                                                                                                             
54
55 char joy_installed = 0;
56 char joy_present = 0;
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[JOY_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 ubyte joy_read_buttons()
82 {
83  return ((~(inp(JOY_PORT) >> 4))&0xf);
84 }
85
86 void joy_get_cal_vals(int *axis_min, int *axis_center, int *axis_max)
87 {
88         int i;
89
90         for (i = 0; i < JOY_NUM_AXES; i++)
91         {
92                 axis_min[i] = joystick.axis_min[i];
93                 axis_center[i] = joystick.axis_center[i];
94                 axis_max[i] = joystick.axis_max[i];
95         }
96 }
97
98 void joy_set_cal_vals(int *axis_min, int *axis_center, int *axis_max)
99 {
100         int i;
101
102         for (i = 0; i < JOY_NUM_AXES; i++)
103         {
104                 joystick.axis_min[i] = axis_min[i];
105                 joystick.axis_center[i] = axis_center[i];
106                 joystick.axis_max[i] = axis_max[i];
107         }
108 }
109
110
111 ubyte joy_get_present_mask()    {
112         return joystick.present_mask;
113 }
114
115 void joy_set_timer_rate(int max_value ) {
116         _disable();
117         joystick.max_timer = max_value;
118         _enable();
119 }
120
121 int joy_get_timer_rate()        {
122         return joystick.max_timer;
123 }
124
125
126 void joy_flush()        {
127         int i;
128
129         if (!joy_installed) return;
130
131         _disable();
132         for (i = 0; i < JOY_MAX_BUTTONS; i++)
133         {
134                 joystick.buttons[i].ignore = 0;
135                 joystick.buttons[i].state = 0;
136                 joystick.buttons[i].timedown = 0;
137                 joystick.buttons[i].downcount = 0;      
138                 joystick.buttons[i].upcount = 0;        
139         }
140         _enable();
141
142 }
143
144
145 void joy_handler(int ticks_this_time)   {
146         ubyte value;
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_bios2();
157                         joystick.last_value = value;
158                 } else {
159                         value = joystick.last_value;
160                 }               
161         } else {
162                 value = joy_read_buttons(); //JOY_READ_BUTTONS;
163         }
164
165         for (i = 0; i < JOY_MAX_BUTTONS; i++)
166         {
167                 button = &joystick.buttons[i];
168                 if (!button->ignore) {
169                         if ( i < 5 )
170                                 state = (value >> i) & 1;
171                         else if (i==(value+4))  
172                                 state = 1;
173                         else
174                                 state = 0;
175
176                         if ( button->last_state == state )      {
177                                 if (state) button->timedown += ticks_this_time;
178                         } else {
179                                 if (state)      {
180                                         button->downcount += state;
181                                         button->state = 1;
182                                 } else {        
183                                         button->upcount += button->state;
184                                         button->state = 0;
185                                 }
186                                 button->last_state = state;
187                         }
188                 }
189         }
190 }
191
192 void joy_handler_end()  {               // Dummy function to help calculate size of joystick handler function
193 }
194
195
196 ubyte joy_read_raw_buttons()    {
197         if ( joystick.slow_read & JOY_BIOS_READINGS )   
198                 return joy_read_buttons_bios2();
199         else 
200                 return joy_read_buttons(); //JOY_READ_BUTTONS;
201 }
202
203 void joy_set_slow_reading(int flag)
204 {
205         joystick.slow_read |= flag;
206         joy_set_cen();
207 }
208
209 ubyte joystick_read_raw_axis( ubyte mask, int * axis )
210 {
211         ubyte read_masks, org_masks;
212         int t, t1, t2, buffer[4*2+2];
213         int e, i, num_channels, c;
214
215         axis[0] = 0; axis[1] = 0;
216         axis[2] = 0; axis[3] = 0;
217
218         if (!joy_installed) return 0;
219
220         read_masks = 0;
221         org_masks = mask;
222
223         mask &= joystick.present_mask;                  // Don't read non-present channels
224         if ( mask==0 )  {
225                 return 0;               // Don't read if no stick connected.
226         }
227
228         if ( joystick.slow_read & JOY_SLOW_READINGS )   {
229                 for (c=0; c<4; c++ )    {               
230                         if ( mask & (1 << c))   {
231                                 // Time out at  (1/100th of a second)
232
233                                 if ( joystick.slow_read & JOY_POLLED_READINGS )
234                                         num_channels = joy_read_stick_polled2( (1 << c), buffer, 65536 );
235                                 else if ( joystick.slow_read & JOY_BIOS_READINGS )
236                                         num_channels = joy_read_stick_bios2( (1 << c), buffer, 65536 );
237                                 else if ( joystick.slow_read & JOY_FRIENDLY_READINGS )
238                                         num_channels = joy_read_stick_friendly2( (1 << c), buffer, (1193180/100) );
239                                 else
240                                         num_channels = joy_read_stick_asm2( (1 << c), buffer, (1193180/100) );
241         
242                                 if ( num_channels > 0 ) {
243                                         t1 = buffer[0];
244                                         e = buffer[1];
245                                         t2 = buffer[2];
246                                         if ( joystick.slow_read & (JOY_POLLED_READINGS|JOY_BIOS_READINGS) )     {
247                                                 t = t2 - t1;
248                                         } else {                        
249                                                 if ( t1 > t2 )
250                                                         t = t1 - t2;
251                                                 else                            {
252                                                         t = t1 + joystick.max_timer - t2;
253                                                         //mprintf( 0, "%d, %d, %d, %d\n", t1, t2, joystick.max_timer, t );
254                                                 }
255                                         }
256         
257                                         if ( e & 1 ) { axis[0] = t; read_masks |= 1; }
258                                         if ( e & 2 ) { axis[1] = t; read_masks |= 2; }
259                                         if ( e & 4 ) { axis[2] = t; read_masks |= 4; }
260                                         if ( e & 8 ) { axis[3] = t; read_masks |= 8; }
261                                 }
262                         }
263                 }
264         } else {
265                 // Time out at  (1/100th of a second)
266                 if ( joystick.slow_read & JOY_POLLED_READINGS )
267                         num_channels = joy_read_stick_polled2( mask, buffer, 65536 );
268                 else if ( joystick.slow_read & JOY_BIOS_READINGS )
269                         num_channels = joy_read_stick_bios2( mask, buffer, 65536 );
270                 else if ( joystick.slow_read & JOY_FRIENDLY_READINGS )
271                         num_channels = joy_read_stick_friendly2( mask, buffer, (1193180/100) );
272                 else 
273                         num_channels = joy_read_stick_asm2( mask, buffer, (1193180/100) );
274                 //mprintf(( 0, "(%d)\n", num_channels ));
275         
276                 for (i=0; i<num_channels; i++ ) {
277                         t1 = buffer[0];
278                         t2 = buffer[i*2+2];
279                         
280                         if ( joystick.slow_read & (JOY_POLLED_READINGS|JOY_BIOS_READINGS) )     {
281                                 t = t2 - t1;
282                         } else {                        
283                                 if ( t1 > t2 )
284                                         t = t1 - t2;
285                                 else                            {
286                                         t = t1 + joystick.max_timer - t2;
287                                         //mprintf(( 0, "%d, %d, %d, %d\n", t1, t2, joystick.max_timer, t ));
288                                 }
289                         }               
290                         e = buffer[i*2+1];
291         
292                         if ( e & 1 ) { axis[0] = t; read_masks |= 1; }
293                         if ( e & 2 ) { axis[1] = t; read_masks |= 2; }
294                         if ( e & 4 ) { axis[2] = t; read_masks |= 4; }
295                         if ( e & 8 ) { axis[3] = t; read_masks |= 8; }
296                 }
297                 
298         }
299
300         return read_masks;
301 }
302
303 #ifdef __GNUC__
304 #define near
305 #endif
306
307 int joy_init()  
308 {
309         int i;
310         int temp_axis[4];
311
312 //        if(FindArg("-joy209"))
313 //         use_alt_joyport=1;
314         if(FindArg("-joy209"))
315          JOY_PORT = 521;  //209h;
316          
317         joy_flush();
318
319         _disable();
320         for (i = 0; i < JOY_MAX_BUTTONS; i++)
321                 joystick.buttons[i].last_state = 0;
322         _enable();
323
324         if ( !joy_installed )   {
325                 joy_present = 0;
326                 joy_installed = 1;
327                 //joystick.max_timer = 65536;
328                 joystick.slow_read = 0;
329                 joystick.read_count = 0;
330                 joystick.last_value = 0;
331
332                 //--------------- lock everything for the virtal memory ----------------------------------
333                 if (!dpmi_lock_region ((void near *)joy_read_buttons_bios2, (char *)joy_read_buttons_bios_end2 - (char near *)joy_read_buttons_bios2))   {
334                         printf( "Error locking joystick handler (read bios)!\n" );
335                         exit(1);
336                 }
337
338
339
340                 if (!dpmi_lock_region ((void near *)joy_handler, (char *)joy_handler_end - (char near *)joy_handler))   {
341                         printf( "Error locking joystick handler!\n" );
342                         exit(1);
343                 }
344
345                 if (!dpmi_lock_region (&joystick, sizeof(Joy_info)))    {
346                         printf( "Error locking joystick handler's data!\n" );
347                         exit(1);
348                 }
349
350                 timer_set_joyhandler(joy_handler);
351         }
352
353         // Do initial cheapy calibration...
354         joystick.present_mask = JOY_ALL_AXIS;           // Assume they're all present
355         do      {
356                 joystick.present_mask = joystick_read_raw_axis( JOY_ALL_AXIS, temp_axis );
357         } while( joy_bogus_reading );
358
359         if ( joystick.present_mask & 3 )
360                 joy_present = 1;
361         else
362                 joy_present = 0;
363
364         return joy_present;
365 }
366
367 void joy_close()        
368 {
369         if (!joy_installed) return;
370         joy_installed = 0;
371 }
372
373 void joy_set_ul()       
374 {
375         joystick.present_mask = JOY_ALL_AXIS;           // Assume they're all present
376         do      {
377                 joystick.present_mask = joystick_read_raw_axis( JOY_ALL_AXIS, joystick.axis_min );
378         } while( joy_bogus_reading );
379         if ( joystick.present_mask & 3 )
380                 joy_present = 1;
381         else
382                 joy_present = 0;
383 }
384
385 void joy_set_lr()       
386 {
387         joystick.present_mask = JOY_ALL_AXIS;           // Assume they're all present
388         do {
389                 joystick.present_mask = joystick_read_raw_axis( JOY_ALL_AXIS, joystick.axis_max );
390         } while( joy_bogus_reading );
391
392         if ( joystick.present_mask & 3 )
393                 joy_present = 1;
394         else
395                 joy_present = 0;
396 }
397
398 void joy_set_cen() 
399 {
400         joystick.present_mask = JOY_ALL_AXIS;           // Assume they're all present
401         do {
402                 joystick.present_mask = joystick_read_raw_axis( JOY_ALL_AXIS, joystick.axis_center );
403         } while( joy_bogus_reading );
404
405         if ( joystick.present_mask & 3 )
406                 joy_present = 1;
407         else
408                 joy_present = 0;
409 }
410
411 void joy_set_cen_fake(int channel)      
412 {
413
414         int i,n=0;
415         int minx, maxx, cenx;
416         
417         minx=maxx=cenx=0;
418
419         for (i=0; i<4; i++ )    {
420                 if ( (joystick.present_mask & (1<<i)) && (i!=channel) ) {
421                         n++;
422                         minx += joystick.axis_min[i];
423                         maxx += joystick.axis_max[i];
424                         cenx += joystick.axis_center[i];
425                 }
426         }
427         minx /= n;
428         maxx /= n;
429         cenx /= n;
430
431         joystick.axis_min[channel] = minx;
432         joystick.axis_max[channel] = maxx;
433         joystick.axis_center[channel] = cenx;
434 }
435
436 int joy_get_scaled_reading( int raw, int axn )  
437 {
438  int x, d, dz;
439
440  // Make sure it's calibrated properly.
441 //added/changed on 8/14/98 to allow smaller calibrating sticks to work (by Eivind Brendryen)--was <5
442    if ( joystick.axis_center[axn] - joystick.axis_min[axn] < 2 )
443     return 0;
444    if ( joystick.axis_max[axn] - joystick.axis_center[axn] < 2 )
445     return 0;
446 //end change - Victor Rachels  (by Eivind Brendryen)
447
448   raw -= joystick.axis_center[axn];
449
450    if ( raw < 0 )
451     d = joystick.axis_center[axn]-joystick.axis_min[axn];
452    else
453     d = joystick.axis_max[axn]-joystick.axis_center[axn];
454
455
456    if ( d )
457     x = (raw << 7) / d;
458    else
459     x = 0;
460
461
462    if ( x < -128 )
463     x = -128;
464    if ( x > 127 )
465     x = 127;
466
467 //added on 4/13/99 by Victor Rachels to add deadzone control
468   dz =  (joy_deadzone) * 6;
469    if ((x > (-1*dz)) && (x < dz))
470     x = 0;
471 //end this section addition -VR
472
473   return x;
474 }
475
476 int last_reading[4] = { 0, 0, 0, 0 };
477
478 void joy_get_pos( int *x, int *y )      
479 {
480         ubyte flags;
481         int axis[4];
482
483         if ((!joy_installed)||(!joy_present)) { *x=*y=0; return; }
484
485         flags=joystick_read_raw_axis( JOY_1_X_AXIS+JOY_1_Y_AXIS, axis );
486
487         if ( joy_bogus_reading )        {
488                 axis[0] = last_reading[0];
489                 axis[1] = last_reading[1];
490                 flags = JOY_1_X_AXIS+JOY_1_Y_AXIS;
491         } else {
492                 last_reading[0] = axis[0];
493                 last_reading[1] = axis[1];
494         }
495
496         if ( flags & JOY_1_X_AXIS )
497                 *x = joy_get_scaled_reading( axis[0], 0 );
498         else
499                 *x = 0;
500
501         if ( flags & JOY_1_Y_AXIS )
502                 *y = joy_get_scaled_reading( axis[1], 1 );
503         else
504                 *y = 0;
505 }
506
507 ubyte joy_read_stick( ubyte masks, int *axis )  
508 {
509         ubyte flags;
510         int raw_axis[4];
511
512         if ((!joy_installed)||(!joy_present)) { 
513                 axis[0] = 0; axis[1] = 0;
514                 axis[2] = 0; axis[3] = 0;
515                 return 0;  
516         }
517
518         flags=joystick_read_raw_axis( masks, raw_axis );
519
520         if ( joy_bogus_reading )        {
521                 axis[0] = last_reading[0];
522                 axis[1] = last_reading[1];
523                 axis[2] = last_reading[2];
524                 axis[3] = last_reading[3];
525                 flags = masks;
526         } else {
527                 last_reading[0] = axis[0];
528                 last_reading[1] = axis[1];
529                 last_reading[2] = axis[2];
530                 last_reading[3] = axis[3];
531         }
532
533         if ( flags & JOY_1_X_AXIS )
534                 axis[0] = joy_get_scaled_reading( raw_axis[0], 0 );
535         else
536                 axis[0] = 0;
537
538         if ( flags & JOY_1_Y_AXIS )
539                 axis[1] = joy_get_scaled_reading( raw_axis[1], 1 );
540         else
541                 axis[1] = 0;
542
543         if ( flags & JOY_2_X_AXIS )
544                 axis[2] = joy_get_scaled_reading( raw_axis[2], 2 );
545         else
546                 axis[2] = 0;
547
548         if ( flags & JOY_2_Y_AXIS )
549                 axis[3] = joy_get_scaled_reading( raw_axis[3], 3 );
550         else
551                 axis[3] = 0;
552
553         return flags;
554 }
555
556
557 int joy_get_btns()      
558 {
559         if ((!joy_installed)||(!joy_present)) return 0;
560
561         return joy_read_raw_buttons();
562 }
563
564 void joy_get_btn_down_cnt( int *btn0, int *btn1 ) 
565 {
566         if ((!joy_installed)||(!joy_present)) { *btn0=*btn1=0; return; }
567
568         _disable();
569         *btn0 = joystick.buttons[0].downcount;
570         joystick.buttons[0].downcount = 0;
571         *btn1 = joystick.buttons[1].downcount;
572         joystick.buttons[1].downcount = 0;
573         _enable();
574 }
575
576 int joy_get_button_state( int btn )     
577 {
578         int count;
579
580         if ((!joy_installed)||(!joy_present)) return 0;
581
582         if (btn >= JOY_MAX_BUTTONS)
583                 return 0;
584
585         _disable();
586         count = joystick.buttons[btn].state;
587         _enable();
588         
589         return  count;
590 }
591
592 int joy_get_button_up_cnt( int btn ) 
593 {
594         int count;
595
596         if ((!joy_installed)||(!joy_present)) return 0;
597
598         if (btn >= JOY_MAX_BUTTONS)
599                 return 0;
600
601         _disable();
602         count = joystick.buttons[btn].upcount;
603         joystick.buttons[btn].upcount = 0;
604         _enable();
605
606         return count;
607 }
608
609 int joy_get_button_down_cnt( int btn ) 
610 {
611         int count;
612
613         if ((!joy_installed)||(!joy_present)) return 0;
614         if (btn >= JOY_MAX_BUTTONS)
615                 return 0;
616
617         _disable();
618         count = joystick.buttons[btn].downcount;
619         joystick.buttons[btn].downcount = 0;
620         _enable();
621
622         return count;
623 }
624
625         
626 fix joy_get_button_down_time( int btn ) 
627 {
628         fix count;
629
630         if ((!joy_installed)||(!joy_present)) return 0;
631         if (btn >= JOY_MAX_BUTTONS)
632                 return 0;
633
634         _disable();
635         count = joystick.buttons[btn].timedown;
636         joystick.buttons[btn].timedown = 0;
637         _enable();
638
639         return fixmuldiv(count, 65536, 1193180 );
640 }
641
642 void joy_get_btn_up_cnt( int *btn0, int *btn1 ) 
643 {
644         if ((!joy_installed)||(!joy_present)) { *btn0=*btn1=0; return; }
645
646         _disable();
647         *btn0 = joystick.buttons[0].upcount;
648         joystick.buttons[0].upcount = 0;
649         *btn1 = joystick.buttons[1].upcount;
650         joystick.buttons[1].upcount = 0;
651         _enable();
652 }
653
654 void joy_set_btn_values( int btn, int state, fix timedown, int downcount, int upcount )
655 {
656         _disable();
657         joystick.buttons[btn].ignore = 1;
658         joystick.buttons[btn].state = state;
659         joystick.buttons[btn].timedown = fixmuldiv( timedown, 1193180, 65536 );
660         joystick.buttons[btn].downcount = downcount;
661         joystick.buttons[btn].upcount = upcount;
662         _enable();
663 }
664
665 void joy_poll()
666 {
667         if ( joystick.slow_read & JOY_BIOS_READINGS )   
668                 joystick.last_value = joy_read_buttons_bios2();
669 }