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