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