home *** CD-ROM | disk | FTP | other *** search
/ Amiga ACS 1998 #6 / amigaacscoverdisc1998-061998.iso / games / descent / source / bios / joyc.c < prev    next >
Text File  |  1998-06-08  |  20KB  |  790 lines

  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.  * $Source: f:/miner/source/bios/rcs/joyc.c $
  15.  * $Revision: 1.37 $
  16.  * $Author: john $
  17.  * $Date: 1995/10/07 13:22:31 $
  18.  * 
  19.  * Routines for joystick reading.
  20.  * 
  21.  * $Log: joyc.c $
  22.  * Revision 1.37  1995/10/07  13:22:31  john
  23.  * Added new method of reading joystick that allows higher-priority
  24.  * interrupts to go off.
  25.  * 
  26.  * Revision 1.36  1995/03/30  11:03:40  john
  27.  * Made -JoyBios read buttons using BIOS.
  28.  * 
  29.  * Revision 1.35  1995/02/14  11:39:25  john
  30.  * Added polled/bios joystick readers..
  31.  * 
  32.  * Revision 1.34  1995/02/10  17:06:12  john
  33.  * Fixed bug with plugging in a joystick not getting detected.
  34.  * 
  35.  * Revision 1.33  1995/01/27  16:39:42  john
  36.  * Made so that if no joystick detected, it wont't
  37.  * read buttons.
  38.  * 
  39.  * Revision 1.32  1995/01/12  13:16:40  john
  40.  * Made it so that joystick can't lose an axis
  41.  * by 1 weird reading. Reading has to occurr during
  42.  * calibration for this to happen.
  43.  * 
  44.  * Revision 1.31  1994/12/28  15:56:03  john
  45.  * Fixed bug that refused to read joysticks whose 
  46.  * min,cen,max were less than 100 apart.
  47.  * 
  48.  * Revision 1.30  1994/12/28  15:31:53  john
  49.  * Added code to read joystick axis not all at one time.
  50.  * 
  51.  * Revision 1.29  1994/12/27  15:44:36  john
  52.  * Made the joystick timeout be at 1/100th of a second, 
  53.  * regardless of CPU speed.
  54.  * 
  55.  * Revision 1.28  1994/12/04  11:54:54  john
  56.  * Made stick read at whatever rate the clock is at, not
  57.  * at 18.2 times/second.
  58.  * 
  59.  * Revision 1.27  1994/11/29  02:25:40  john
  60.  * Made it so that the scaled reading returns 0 
  61.  * if the calibration factors look funny..
  62.  * 
  63.  * Revision 1.26  1994/11/22  11:08:07  john
  64.  * Commented out the ARCADE joystick.
  65.  * 
  66.  * Revision 1.25  1994/11/14  19:40:26  john
  67.  * Fixed bug with no joystick being detected.
  68.  * 
  69.  * Revision 1.24  1994/11/14  19:36:40  john
  70.  * Took out initial cheapy calibration.
  71.  * 
  72.  * Revision 1.23  1994/11/14  19:13:27  john
  73.  * Took out the calibration in joy_init
  74.  * 
  75.  * Revision 1.22  1994/10/17  10:09:57  john
  76.  * Made the state look at last_State, so that a joy_flush
  77.  * doesn't cause a new down state to be added next reading.
  78.  * 
  79.  * Revision 1.21  1994/10/13  11:36:23  john
  80.  * Made joy_down_time be kept track of in fixed seconds,
  81.  * not ticks.
  82.  * 
  83.  * Revision 1.20  1994/10/12  16:58:50  john
  84.  * Fixed bug w/ previous comment.
  85.  * 
  86.  * Revision 1.19  1994/10/12  16:57:44  john
  87.  * Added function to set a joystick button's state.
  88.  * 
  89.  * Revision 1.18  1994/10/11  10:20:13  john
  90.  * Fixed Flightstick Pro/
  91.  * ..
  92.  * 
  93.  * Revision 1.17  1994/09/29  18:29:20  john
  94.  * *** empty log message ***
  95.  * 
  96.  * Revision 1.16  1994/09/27  19:17:23  john
  97.  * Added code so that is joy_init is never called, joystick is not
  98.  * used at all.
  99.  * 
  100.  * Revision 1.15  1994/09/22  16:09:23  john
  101.  * Fixed some virtual memory lockdown problems with timer and
  102.  * joystick.
  103.  * 
  104.  * Revision 1.14  1994/09/16  11:44:42  john
  105.  * Fixed bug with slow joystick.
  106.  * 
  107.  * Revision 1.13  1994/09/16  11:36:15  john
  108.  * Fixed bug with reading non-present channels.
  109.  * 
  110.  * Revision 1.12  1994/09/15  20:52:48  john
  111.  * rme john
  112.  * Added support for the Arcade style joystick.
  113.  * 
  114.  * Revision 1.11  1994/09/13  20:04:49  john
  115.  * Fixed bug with joystick button down_time.
  116.  * 
  117.  * Revision 1.10  1994/09/10  13:48:07  john
  118.  * Made all 20 buttons read.
  119.  * 
  120.  * Revision 1.9  1994/08/31  09:55:02  john
  121.  * *** empty log message ***
  122.  * 
  123.  * Revision 1.8  1994/08/29  21:02:14  john
  124.  * Added joy_set_cal_values...
  125.  * 
  126.  * Revision 1.7  1994/08/29  20:52:17  john
  127.  * Added better cyberman support; also, joystick calibration
  128.  * value return funcctiionn,
  129.  * 
  130.  * Revision 1.6  1994/08/24  18:53:12  john
  131.  * Made Cyberman read like normal mouse; added dpmi module; moved
  132.  * mouse from assembly to c. Made mouse buttons return time_down.
  133.  * 
  134.  * Revision 1.5  1994/07/14  22:12:23  john
  135.  * Used intrinsic forms of outp to fix vmm error.
  136.  * 
  137.  * Revision 1.4  1994/07/07  19:52:59  matt
  138.  * Made joy_init() return success/fail flag
  139.  * Made joy_init() properly detect a stick if one is plugged in after joy_init()
  140.  * was called the first time.
  141.  * 
  142.  * Revision 1.3  1994/07/01  10:55:55  john
  143.  * Fixed some bugs... added support for 4 axis.
  144.  * 
  145.  * Revision 1.2  1994/06/30  20:36:55  john
  146.  * Revamped joystick code.
  147.  * 
  148.  * Revision 1.1  1994/06/30  15:42:15  john
  149.  * Initial revision
  150.  * 
  151.  * 
  152.  */
  153.  
  154.  
  155. #pragma off (unreferenced)
  156. static char rcsid[] = "$Id: joyc.c 1.37 1995/10/07 13:22:31 john Exp $";
  157. #pragma on (unreferenced)
  158.  
  159. #include <stdlib.h>
  160. #include <stdio.h>
  161. #include <conio.h>
  162. #include <dos.h>
  163. #include <i86.h>
  164.  
  165. //#define ARCADE 1
  166.  
  167. #include "types.h"
  168. #include "mono.h"
  169. #include "joy.h"
  170. #include "dpmi.h"
  171.  
  172. //In key.c
  173. // ebx = read mask                                                                           
  174. // edi = pointer to buffer                                                                                            
  175. // returns number of events                                                                                        
  176. int joy_read_stick_asm( int read_masks, int * event_buffer, int timeout );
  177. #pragma aux joy_read_stick_asm parm [ebx] [edi] [ecx] value [eax] modify exact [eax ebx ecx edx edi];
  178.  
  179. int joy_read_stick_friendly( int read_masks, int * event_buffer, int timeout );
  180. #pragma aux joy_read_stick_friendly parm [ebx] [edi] [ecx] value [eax] modify exact [eax ebx ecx edx edi];
  181.  
  182. int joy_read_stick_polled( int read_masks, int * event_buffer, int timeout );
  183. #pragma aux joy_read_stick_polled parm [ebx] [edi] [ecx] value [eax] modify exact [eax ebx ecx edx edi];
  184.  
  185. int joy_read_stick_bios( int read_masks, int * event_buffer, int timeout );
  186. #pragma aux joy_read_stick_bios parm [ebx] [edi] [ecx] value [eax] modify exact [eax ebx ecx edx edi];
  187.  
  188.  
  189. char joy_installed = 0;
  190. char joy_present = 0;
  191.  
  192. #define JOY_READ_BUTTONS     ((~(inp(0x201) >> 4))&0xf)
  193. #ifdef ARCADE
  194. #define JOY_READ_BUTTONS_ARCADE    (~(inp(0x2A1)))
  195. #define MAX_BUTTONS 28
  196. #else
  197. #define MAX_BUTTONS 20
  198. #endif
  199.  
  200. typedef struct Button_info {
  201.     ubyte        ignore;
  202.     ubyte        state;
  203.     ubyte        last_state;
  204.     int        timedown;
  205.     ubyte        downcount;
  206.     ubyte        upcount;
  207. } Button_info;
  208.  
  209. typedef struct Joy_info {
  210.     ubyte            present_mask;
  211.     ubyte            slow_read;
  212.     int            max_timer;
  213.     int            read_count;
  214.     ubyte            last_value;
  215.     Button_info    buttons[MAX_BUTTONS];
  216.     int            axis_min[4];
  217.     int            axis_center[4];
  218.     int            axis_max[4];
  219. } Joy_info;
  220.  
  221. Joy_info joystick;
  222.  
  223. extern int joy_bogus_reading;
  224. extern int joy_retries;
  225.  
  226. void joy_get_cal_vals(int *axis_min, int *axis_center, int *axis_max)
  227. {
  228.     int i;
  229.  
  230.     for (i=0; i<4; i++)        {
  231.         axis_min[i] = joystick.axis_min[i];
  232.         axis_center[i] = joystick.axis_center[i];
  233.         axis_max[i] = joystick.axis_max[i];
  234.     }
  235. }
  236.  
  237. void joy_set_cal_vals(int *axis_min, int *axis_center, int *axis_max)
  238. {
  239.     int i;
  240.  
  241.     for (i=0; i<4; i++)        {
  242.         joystick.axis_min[i] = axis_min[i];
  243.         joystick.axis_center[i] = axis_center[i];
  244.         joystick.axis_max[i] = axis_max[i];
  245.     }
  246. }
  247.  
  248.  
  249. ubyte joy_get_present_mask()    {
  250.     return joystick.present_mask;
  251. }
  252.  
  253. void joy_set_timer_rate(int max_value )    {
  254.     _disable();
  255.     joystick.max_timer = max_value;
  256.     _enable();
  257. }
  258.  
  259. int joy_get_timer_rate()    {
  260.     return joystick.max_timer;
  261. }
  262.  
  263.  
  264. void joy_flush()    {
  265.     int i;
  266.  
  267.     if (!joy_installed) return;
  268.  
  269.     _disable();
  270.     for (i=0; i<MAX_BUTTONS; i++ )    {
  271.         joystick.buttons[i].ignore = 0;
  272.         joystick.buttons[i].state = 0;    
  273.         joystick.buttons[i].timedown = 0;    
  274.         joystick.buttons[i].downcount = 0;    
  275.         joystick.buttons[i].upcount = 0;    
  276.     }
  277.     _enable();
  278.  
  279. }
  280.  
  281. #pragma off (check_stack)
  282.  
  283. extern int joy_read_buttons_bios();
  284.  
  285. void joy_handler(int ticks_this_time)    {
  286.     ubyte value;
  287. #ifdef ARCADE
  288.     ubyte valuea;
  289. #endif
  290.     int i, state;
  291.     Button_info * button;
  292.  
  293. //    joystick.max_timer = ticks_this_time;
  294.  
  295.     if ( joystick.slow_read & JOY_BIOS_READINGS )        {
  296.         joystick.read_count++;
  297.         if ( joystick.read_count > 7 )    {
  298.             joystick.read_count = 0;
  299.             value = joy_read_buttons_bios();
  300.             joystick.last_value = value;
  301.         } else {
  302.             value = joystick.last_value;
  303.         }        
  304.     } else {
  305.         value = JOY_READ_BUTTONS;
  306.     #ifdef ARCADE
  307.         valuea = JOY_READ_BUTTONS_ARCADE;
  308.     #endif
  309.     }
  310.  
  311.     for (i=0; i<MAX_BUTTONS; i++ )    {
  312.         button = &joystick.buttons[i];
  313.         if (!button->ignore) {
  314.             if ( i < 5 )
  315.                 state = (value >> i) & 1;
  316. #ifdef ARCADE
  317.             else if ( i >= 20 ) 
  318.                 state = (valuea >> (i-20)) & 1;
  319. #endif
  320.             else if (i==(value+4))    
  321.                 state = 1;
  322.             else
  323.                 state = 0;
  324.  
  325.             if ( button->last_state == state )    {
  326.                 if (state) button->timedown += ticks_this_time;
  327.             } else {
  328.                 if (state)    {
  329.                     button->downcount += state;
  330.                     button->state = 1;
  331.                 } else {    
  332.                     button->upcount += button->state;
  333.                     button->state = 0;
  334.                 }
  335.                 button->last_state = state;
  336.             }
  337.         }
  338.     }
  339. }
  340.  
  341. void joy_handler_end()    {        // Dummy function to help calculate size of joystick handler function
  342. }
  343.  
  344. #pragma off (check_stack)
  345.  
  346. ubyte joy_read_raw_buttons()    {
  347.     if ( joystick.slow_read & JOY_BIOS_READINGS )    
  348.         return joy_read_buttons_bios();
  349.     else 
  350.         return JOY_READ_BUTTONS;
  351. }
  352.  
  353. void joy_set_slow_reading(int flag)
  354. {
  355.     joystick.slow_read |= flag;
  356.     joy_set_cen();
  357. }
  358.  
  359. ubyte joystick_read_raw_axis( ubyte mask, int * axis )
  360. {
  361.     ubyte read_masks, org_masks;
  362.     int t, t1, t2, buffer[4*2+2];
  363.     int e, i, num_channels, c;
  364.  
  365.     axis[0] = 0; axis[1] = 0;
  366.     axis[2] = 0; axis[3] = 0;
  367.  
  368.     if (!joy_installed) return 0;
  369.  
  370.     read_masks = 0;
  371.     org_masks = mask;
  372.  
  373.     mask &= joystick.present_mask;            // Don't read non-present channels
  374.     if ( mask==0 )    {
  375.         return 0;        // Don't read if no stick connected.
  376.     }
  377.  
  378.     if ( joystick.slow_read & JOY_SLOW_READINGS )    {
  379.         for (c=0; c<4; c++ )    {        
  380.             if ( mask & (1 << c))    {
  381.                 // Time out at  (1/100th of a second)
  382.  
  383.                 if ( joystick.slow_read & JOY_POLLED_READINGS )
  384.                     num_channels = joy_read_stick_polled( (1 << c), buffer, 65536 );
  385.                 else if ( joystick.slow_read & JOY_BIOS_READINGS )
  386.                     num_channels = joy_read_stick_bios( (1 << c), buffer, 65536 );
  387.                 else if ( joystick.slow_read & JOY_FRIENDLY_READINGS )
  388.                     num_channels = joy_read_stick_friendly( (1 << c), buffer, (1193180/100) );
  389.                 else
  390.                     num_channels = joy_read_stick_asm( (1 << c), buffer, (1193180/100) );
  391.     
  392.                 if ( num_channels > 0 )    {
  393.                     t1 = buffer[0];
  394.                     e = buffer[1];
  395.                     t2 = buffer[2];
  396.                     if ( joystick.slow_read & (JOY_POLLED_READINGS|JOY_BIOS_READINGS) )    {
  397.                         t = t2 - t1;
  398.                     } else {            
  399.                         if ( t1 > t2 )
  400.                             t = t1 - t2;
  401.                         else                {
  402.                             t = t1 + joystick.max_timer - t2;
  403.                             //mprintf( 0, "%d, %d, %d, %d\n", t1, t2, joystick.max_timer, t );
  404.                         }
  405.                     }
  406.     
  407.                     if ( e & 1 ) { axis[0] = t; read_masks |= 1; }
  408.                     if ( e & 2 ) { axis[1] = t; read_masks |= 2; }
  409.                     if ( e & 4 ) { axis[2] = t; read_masks |= 4; }
  410.                     if ( e & 8 ) { axis[3] = t; read_masks |= 8; }
  411.                 }
  412.             }
  413.         }
  414.     } else {
  415.         // Time out at  (1/100th of a second)
  416.         if ( joystick.slow_read & JOY_POLLED_READINGS )
  417.             num_channels = joy_read_stick_polled( mask, buffer, 65536 );
  418.         else if ( joystick.slow_read & JOY_BIOS_READINGS )
  419.             num_channels = joy_read_stick_bios( (1 << c), buffer, 65536 );
  420.         else if ( joystick.slow_read & JOY_FRIENDLY_READINGS )
  421.             num_channels = joy_read_stick_friendly( mask, buffer, (1193180/100) );
  422.         else 
  423.             num_channels = joy_read_stick_asm( mask, buffer, (1193180/100) );
  424.         //mprintf(( 0, "(%d)\n", num_channels ));
  425.     
  426.         for (i=0; i<num_channels; i++ )    {
  427.             t1 = buffer[0];
  428.             t2 = buffer[i*2+2];
  429.             
  430.             if ( joystick.slow_read & (JOY_POLLED_READINGS|JOY_BIOS_READINGS) )    {
  431.                 t = t2 - t1;
  432.             } else {            
  433.                 if ( t1 > t2 )
  434.                     t = t1 - t2;
  435.                 else                {
  436.                     t = t1 + joystick.max_timer - t2;
  437.                     //mprintf(( 0, "%d, %d, %d, %d\n", t1, t2, joystick.max_timer, t ));
  438.                 }
  439.             }        
  440.             e = buffer[i*2+1];
  441.     
  442.             if ( e & 1 ) { axis[0] = t; read_masks |= 1; }
  443.             if ( e & 2 ) { axis[1] = t; read_masks |= 2; }
  444.             if ( e & 4 ) { axis[2] = t; read_masks |= 4; }
  445.             if ( e & 8 ) { axis[3] = t; read_masks |= 8; }
  446.         }
  447.         
  448.     }
  449.  
  450.     return read_masks;
  451. }
  452.  
  453. extern void timer_set_joyhandler( void (*joy_handler)() );
  454.  
  455. int joy_init()    
  456. {
  457.     int i;
  458.     int temp_axis[4];
  459.  
  460.     joy_flush();
  461.  
  462.     _disable();
  463.     for (i=0; i<MAX_BUTTONS; i++ )    
  464.         joystick.buttons[i].last_state = 0;
  465.     _enable();
  466.  
  467.     if ( !joy_installed )    {
  468.         joy_present = 0;
  469.         joy_installed = 1;
  470.         //joystick.max_timer = 65536;
  471.         joystick.slow_read = 0;
  472.         joystick.read_count = 0;
  473.         joystick.last_value = 0;
  474.  
  475.         //--------------- lock everything for the virtal memory ----------------------------------
  476.         if (!dpmi_lock_region ((void near *)joy_handler, (char *)joy_handler_end - (char near *)joy_handler))    {
  477.             printf( "Error locking joystick handler!\n" );
  478.             exit(1);
  479.         }
  480.  
  481.         if (!dpmi_lock_region (&joystick, sizeof(Joy_info)))    {
  482.             printf( "Error locking joystick handler's data!\n" );
  483.             exit(1);
  484.         }
  485.  
  486.         timer_set_joyhandler(joy_handler);
  487.     }
  488.  
  489.     // Do initial cheapy calibration...
  490.     joystick.present_mask = JOY_ALL_AXIS;        // Assume they're all present
  491.     do    {
  492.         joystick.present_mask = joystick_read_raw_axis( JOY_ALL_AXIS, temp_axis );
  493.     } while( joy_bogus_reading );
  494.  
  495.     if ( joystick.present_mask & 3 )
  496.         joy_present = 1;
  497.     else
  498.         joy_present = 0;
  499.  
  500.     return joy_present;
  501. }
  502.  
  503. void joy_close()    
  504. {
  505.     if (!joy_installed) return;
  506.     joy_installed = 0;
  507. }
  508.  
  509. void joy_set_ul()    
  510. {
  511.     joystick.present_mask = JOY_ALL_AXIS;        // Assume they're all present
  512.     do    {
  513.         joystick.present_mask = joystick_read_raw_axis( JOY_ALL_AXIS, joystick.axis_min );
  514.     } while( joy_bogus_reading );
  515.     if ( joystick.present_mask & 3 )
  516.         joy_present = 1;
  517.     else
  518.         joy_present = 0;
  519. }
  520.  
  521. void joy_set_lr()    
  522. {
  523.     joystick.present_mask = JOY_ALL_AXIS;        // Assume they're all present
  524.     do {
  525.         joystick.present_mask = joystick_read_raw_axis( JOY_ALL_AXIS, joystick.axis_max );
  526.     } while( joy_bogus_reading );
  527.  
  528.     if ( joystick.present_mask & 3 )
  529.         joy_present = 1;
  530.     else
  531.         joy_present = 0;
  532. }
  533.  
  534. void joy_set_cen() 
  535. {
  536.     joystick.present_mask = JOY_ALL_AXIS;        // Assume they're all present
  537.     do {
  538.         joystick.present_mask = joystick_read_raw_axis( JOY_ALL_AXIS, joystick.axis_center );
  539.     } while( joy_bogus_reading );
  540.  
  541.     if ( joystick.present_mask & 3 )
  542.         joy_present = 1;
  543.     else
  544.         joy_present = 0;
  545. }
  546.  
  547. void joy_set_cen_fake(int channel)    
  548. {
  549.  
  550.     int i,n=0;
  551.     int minx, maxx, cenx;
  552.     
  553.     minx=maxx=cenx=0;
  554.  
  555.     for (i=0; i<4; i++ )    {
  556.         if ( (joystick.present_mask & (1<<i)) && (i!=channel) )    {
  557.             n++;
  558.             minx += joystick.axis_min[i];
  559.             maxx += joystick.axis_max[i];
  560.             cenx += joystick.axis_center[i];
  561.         }
  562.     }
  563.     minx /= n;
  564.     maxx /= n;
  565.     cenx /= n;
  566.  
  567.     joystick.axis_min[channel] = minx;
  568.     joystick.axis_max[channel] = maxx;
  569.     joystick.axis_center[channel] = cenx;
  570. }
  571.  
  572. int joy_get_scaled_reading( int raw, int axn )    
  573. {
  574.     int x, d;
  575.  
  576.     // Make sure it's calibrated properly.
  577.     if ( joystick.axis_center[axn] - joystick.axis_min[axn] < 5 ) return 0;
  578.     if ( joystick.axis_max[axn] - joystick.axis_center[axn] < 5 ) return 0;
  579.  
  580.     raw -= joystick.axis_center[axn];
  581.  
  582.     if ( raw < 0 )    {
  583.         d = joystick.axis_center[axn]-joystick.axis_min[axn];
  584.     } else {
  585.         d = joystick.axis_max[axn]-joystick.axis_center[axn];
  586.     }
  587.  
  588.     if ( d )
  589.         x = (raw << 7) / d;
  590.     else 
  591.         x = 0;
  592.  
  593.     if ( x < -128 ) x = -128;
  594.     if ( x > 127 ) x = 127;
  595.  
  596.     return x;
  597. }
  598.  
  599. int last_reading[4] = { 0, 0, 0, 0 };
  600.  
  601. void joy_get_pos( int *x, int *y )    
  602. {
  603.     ubyte flags;
  604.     int axis[4];
  605.  
  606.     if ((!joy_installed)||(!joy_present)) { *x=*y=0; return; }
  607.  
  608.     flags=joystick_read_raw_axis( JOY_1_X_AXIS+JOY_1_Y_AXIS, axis );
  609.  
  610.     if ( joy_bogus_reading )    {
  611.         axis[0] = last_reading[0];
  612.         axis[1] = last_reading[1];
  613.         flags = JOY_1_X_AXIS+JOY_1_Y_AXIS;
  614.     } else {
  615.         last_reading[0] = axis[0];
  616.         last_reading[1] = axis[1];
  617.     }
  618.  
  619.     if ( flags & JOY_1_X_AXIS )
  620.         *x = joy_get_scaled_reading( axis[0], 0 );
  621.     else
  622.         *x = 0;
  623.  
  624.     if ( flags & JOY_1_Y_AXIS )
  625.         *y = joy_get_scaled_reading( axis[1], 1 );
  626.     else
  627.         *y = 0;
  628. }
  629.  
  630. ubyte joy_read_stick( ubyte masks, int *axis )    
  631. {
  632.     ubyte flags;
  633.     int raw_axis[4];
  634.  
  635.     if ((!joy_installed)||(!joy_present)) { 
  636.         axis[0] = 0; axis[1] = 0;
  637.         axis[2] = 0; axis[3] = 0;
  638.         return 0;  
  639.     }
  640.  
  641.     flags=joystick_read_raw_axis( masks, raw_axis );
  642.  
  643.     if ( joy_bogus_reading )    {
  644.         axis[0] = last_reading[0];
  645.         axis[1] = last_reading[1];
  646.         axis[2] = last_reading[2];
  647.         axis[3] = last_reading[3];
  648.         flags = masks;
  649.     } else {
  650.         last_reading[0] = axis[0];
  651.         last_reading[1] = axis[1];
  652.         last_reading[2] = axis[2];
  653.         last_reading[3] = axis[3];
  654.     }
  655.  
  656.     if ( flags & JOY_1_X_AXIS )
  657.         axis[0] = joy_get_scaled_reading( raw_axis[0], 0 );
  658.     else
  659.         axis[0] = 0;
  660.  
  661.     if ( flags & JOY_1_Y_AXIS )
  662.         axis[1] = joy_get_scaled_reading( raw_axis[1], 1 );
  663.     else
  664.         axis[1] = 0;
  665.  
  666.     if ( flags & JOY_2_X_AXIS )
  667.         axis[2] = joy_get_scaled_reading( raw_axis[2], 2 );
  668.     else
  669.         axis[2] = 0;
  670.  
  671.     if ( flags & JOY_2_Y_AXIS )
  672.         axis[3] = joy_get_scaled_reading( raw_axis[3], 3 );
  673.     else
  674.         axis[3] = 0;
  675.  
  676.     return flags;
  677. }
  678.  
  679.  
  680. int joy_get_btns()    
  681. {
  682.     if ((!joy_installed)||(!joy_present)) return 0;
  683.  
  684.     return joy_read_raw_buttons();
  685. }
  686.  
  687. void joy_get_btn_down_cnt( int *btn0, int *btn1 ) 
  688. {
  689.     if ((!joy_installed)||(!joy_present)) { *btn0=*btn1=0; return; }
  690.  
  691.     _disable();
  692.     *btn0 = joystick.buttons[0].downcount;
  693.     joystick.buttons[0].downcount = 0;
  694.     *btn1 = joystick.buttons[1].downcount;
  695.     joystick.buttons[1].downcount = 0;
  696.     _enable();
  697. }
  698.  
  699. int joy_get_button_state( int btn )    
  700. {
  701.     int count;
  702.  
  703.     if ((!joy_installed)||(!joy_present)) return 0;
  704.  
  705.     if ( btn >= MAX_BUTTONS ) return 0;
  706.  
  707.     _disable();
  708.     count = joystick.buttons[btn].state;
  709.     _enable();
  710.     
  711.     return  count;
  712. }
  713.  
  714. int joy_get_button_up_cnt( int btn ) 
  715. {
  716.     int count;
  717.  
  718.     if ((!joy_installed)||(!joy_present)) return 0;
  719.  
  720.     if ( btn >= MAX_BUTTONS ) return 0;
  721.  
  722.     _disable();
  723.     count = joystick.buttons[btn].upcount;
  724.     joystick.buttons[btn].upcount = 0;
  725.     _enable();
  726.  
  727.     return count;
  728. }
  729.  
  730. int joy_get_button_down_cnt( int btn ) 
  731. {
  732.     int count;
  733.  
  734.     if ((!joy_installed)||(!joy_present)) return 0;
  735.     if ( btn >= MAX_BUTTONS ) return 0;
  736.  
  737.     _disable();
  738.     count = joystick.buttons[btn].downcount;
  739.     joystick.buttons[btn].downcount = 0;
  740.     _enable();
  741.  
  742.     return count;
  743. }
  744.  
  745.     
  746. fix joy_get_button_down_time( int btn ) 
  747. {
  748.     fix count;
  749.  
  750.     if ((!joy_installed)||(!joy_present)) return 0;
  751.     if ( btn >= MAX_BUTTONS ) return 0;
  752.  
  753.     _disable();
  754.     count = joystick.buttons[btn].timedown;
  755.     joystick.buttons[btn].timedown = 0;
  756.     _enable();
  757.  
  758.     return fixmuldiv(count, 65536, 1193180 );
  759. }
  760.  
  761. void joy_get_btn_up_cnt( int *btn0, int *btn1 ) 
  762. {
  763.     if ((!joy_installed)||(!joy_present)) { *btn0=*btn1=0; return; }
  764.  
  765.     _disable();
  766.     *btn0 = joystick.buttons[0].upcount;
  767.     joystick.buttons[0].upcount = 0;
  768.     *btn1 = joystick.buttons[1].upcount;
  769.     joystick.buttons[1].upcount = 0;
  770.     _enable();
  771. }
  772.  
  773. void joy_set_btn_values( int btn, int state, fix timedown, int downcount, int upcount )
  774. {
  775.     _disable();
  776.     joystick.buttons[btn].ignore = 1;
  777.     joystick.buttons[btn].state = state;
  778.     joystick.buttons[btn].timedown = fixmuldiv( timedown, 1193180, 65536 );
  779.     joystick.buttons[btn].downcount = downcount;
  780.     joystick.buttons[btn].upcount = upcount;
  781.     _enable();
  782. }
  783.  
  784. void joy_poll()
  785. {
  786.     if ( joystick.slow_read & JOY_BIOS_READINGS )    
  787.         joystick.last_value = joy_read_buttons_bios();
  788. }
  789. 
  790.