home *** CD-ROM | disk | FTP | other *** search
/ Amiga ACS 1998 #6 / amigaacscoverdisc1998-061998.iso / games / descent / source / bios / mouse.c < prev    next >
Text File  |  1998-06-08  |  16KB  |  613 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/mouse.c $
  15.  * $Revision: 1.11 $
  16.  * $Author: john $
  17.  * $Date: 1995/02/10 18:52:17 $
  18.  * 
  19.  * Functions to access Mouse and Cyberman...
  20.  * 
  21.  * $Log: mouse.c $
  22.  * Revision 1.11  1995/02/10  18:52:17  john
  23.  * Fixed bug with mouse not getting closed.
  24.  * 
  25.  * Revision 1.10  1995/02/02  11:10:33  john
  26.  * Changed a bunch of mouse stuff around to maybe get
  27.  * around PS/2 mouse hang.
  28.  * 
  29.  * Revision 1.9  1995/01/14  19:19:52  john
  30.  * Fixed signed short error cmp with -1 that caused mouse
  31.  * to break under Watcom 10.0
  32.  * 
  33.  * Revision 1.8  1994/12/27  12:38:23  john
  34.  * Made mouse use temporary dos buffer instead of
  35.  * 
  36.  * allocating its own.
  37.  * 
  38.  * 
  39.  * Revision 1.7  1994/12/05  23:54:53  john
  40.  * Fixed bug with mouse_get_delta only returning positive numbers..
  41.  * 
  42.  * Revision 1.6  1994/11/18  23:18:18  john
  43.  * Changed some shorts to ints.
  44.  * 
  45.  * Revision 1.5  1994/09/13  12:34:02  john
  46.  * Added functions to get down count and state.
  47.  * 
  48.  * Revision 1.4  1994/08/29  20:52:19  john
  49.  * Added better cyberman support; also, joystick calibration
  50.  * value return funcctiionn,
  51.  * 
  52.  * Revision 1.3  1994/08/24  18:54:32  john
  53.  * *** empty log message ***
  54.  * 
  55.  * Revision 1.2  1994/08/24  18:53:46  john
  56.  * Made Cyberman read like normal mouse; added dpmi module; moved
  57.  * mouse from assembly to c. Made mouse buttons return time_down.
  58.  * 
  59.  * Revision 1.1  1994/08/24  13:56:37  john
  60.  * Initial revision
  61.  * 
  62.  * 
  63.  */
  64.  
  65.  
  66. #pragma off (unreferenced)
  67. static char rcsid[] = "$Id: mouse.c 1.11 1995/02/10 18:52:17 john Exp $";
  68. #pragma on (unreferenced)
  69.  
  70. #include <stdlib.h>
  71. #include <stdio.h>
  72. #include <conio.h>
  73. #include <dos.h>
  74. #include <i86.h>
  75. #include <string.h>
  76.  
  77. #include "error.h"
  78. #include "fix.h"
  79. #include "dpmi.h"
  80. #include "mouse.h"
  81. #include "timer.h"
  82.  
  83. #define ME_CURSOR_MOVED    (1<<0)
  84. #define ME_LB_P             (1<<1)
  85. #define ME_LB_R             (1<<2)
  86. #define ME_RB_P             (1<<3)
  87. #define ME_RB_R             (1<<4)
  88. #define ME_MB_P             (1<<5)
  89. #define ME_MB_R             (1<<6)
  90. #define ME_OB_P             (1<<7)
  91. #define ME_OB_R             (1<<8)
  92. #define ME_X_C             (1<<9)
  93. #define ME_Y_C             (1<<10)
  94. #define ME_Z_C             (1<<11)
  95. #define ME_P_C             (1<<12)
  96. #define ME_B_C             (1<<13)
  97. #define ME_H_C             (1<<14)
  98. #define ME_O_C             (1<<15)
  99.  
  100. #define MOUSE_MAX_BUTTONS    11
  101.  
  102. typedef struct event_info {
  103.     short x;
  104.     short y;
  105.     short z;
  106.     short pitch;
  107.     short bank;
  108.     short heading;
  109.     ushort button_status;
  110.     ushort device_dependant;
  111. } event_info;
  112.  
  113. typedef struct mouse_info {
  114.     fix        ctime;
  115.     ubyte        cyberman;
  116.     int        num_buttons;
  117.     ubyte        pressed[MOUSE_MAX_BUTTONS];
  118.     fix        time_went_down[MOUSE_MAX_BUTTONS];
  119.     fix        time_held_down[MOUSE_MAX_BUTTONS];
  120.     uint        num_downs[MOUSE_MAX_BUTTONS];
  121.     uint        num_ups[MOUSE_MAX_BUTTONS];
  122.     event_info *x_info;
  123.     ushort    button_status;
  124. } mouse_info;
  125.  
  126. typedef struct cyberman_info {
  127.     ubyte device_type;
  128.     ubyte major_version;
  129.     ubyte minor_version;
  130.     ubyte x_descriptor;
  131.     ubyte y_descriptor;
  132.     ubyte z_descriptor;
  133.     ubyte pitch_descriptor;
  134.     ubyte roll_descriptor;
  135.     ubyte yaw_descriptor;
  136.     ubyte reserved;
  137. } cyberman_info;
  138.  
  139. static mouse_info Mouse;
  140.  
  141. static int Mouse_installed = 0;
  142.  
  143. #pragma off (check_stack)
  144. void _loadds far mouse_handler (int m_ax, int mbx, int mcx, int mdx, int msi, int mdi)
  145. {
  146. #pragma aux mouse_handler parm [EAX] [EBX] [ECX] [EDX] [ESI] [EDI]
  147.  
  148.     Mouse.ctime = timer_get_fixed_secondsX();
  149.  
  150.     if (m_ax & ME_LB_P)    {    // left button pressed
  151.         if (!Mouse.pressed[MB_LEFT])    {
  152.             Mouse.pressed[MB_LEFT] = 1;
  153.             Mouse.time_went_down[MB_LEFT] = Mouse.ctime;
  154.         }
  155.         Mouse.num_downs[MB_LEFT]++;
  156.     } else if (m_ax & ME_LB_R )    {  // left button released
  157.         if (Mouse.pressed[MB_LEFT])    {
  158.             Mouse.pressed[MB_LEFT] = 0;
  159.             Mouse.time_held_down[MB_LEFT] += Mouse.ctime-Mouse.time_went_down[MB_LEFT];
  160.         }
  161.         Mouse.num_ups[MB_LEFT]++;
  162.     }
  163.  
  164.     if (m_ax & ME_RB_P ) {    // right button pressed
  165.         if (!Mouse.pressed[MB_RIGHT])    {
  166.             Mouse.pressed[MB_RIGHT] = 1;
  167.             Mouse.time_went_down[MB_RIGHT] = Mouse.ctime;
  168.         }
  169.         Mouse.num_downs[MB_RIGHT]++;
  170.     } else if (m_ax & ME_RB_R )    {// right button released
  171.         if (Mouse.pressed[MB_RIGHT])    {
  172.             Mouse.pressed[MB_RIGHT] = 0;
  173.             Mouse.time_held_down[MB_RIGHT] += Mouse.ctime-Mouse.time_went_down[MB_RIGHT];
  174.         }
  175.         Mouse.num_ups[MB_RIGHT]++;
  176.     }
  177.  
  178.     if (m_ax & ME_MB_P )    { // middle button pressed
  179.         if (!Mouse.pressed[MB_MIDDLE])    {
  180.             Mouse.pressed[MB_MIDDLE] = 1;
  181.             Mouse.time_went_down[MB_MIDDLE] = Mouse.ctime;
  182.         }
  183.         Mouse.num_downs[MB_MIDDLE]++;
  184.     } else if (m_ax & ME_MB_R )    { // middle button released
  185.         if (Mouse.pressed[MB_MIDDLE])    {
  186.             Mouse.pressed[MB_MIDDLE] = 0;
  187.             Mouse.time_held_down[MB_MIDDLE] += Mouse.ctime-Mouse.time_went_down[MB_MIDDLE];
  188.         }
  189.         Mouse.num_ups[MB_MIDDLE]++;
  190.     }
  191.  
  192.     if (Mouse.cyberman && (m_ax & (ME_Z_C|ME_P_C|ME_B_C|ME_H_C)))    {
  193.         Mouse.x_info = (event_info *)((msi & 0xFFFF) << 4);
  194.  
  195.         if (m_ax & ME_Z_C )    { // z axis changed
  196.             if (Mouse.pressed[MB_Z_UP])    {
  197.                  // z up released
  198.                 Mouse.pressed[MB_Z_UP] = 0;
  199.                 Mouse.time_held_down[MB_Z_UP] += Mouse.ctime-Mouse.time_went_down[MB_Z_UP];
  200.                 Mouse.num_ups[MB_Z_UP]++;
  201.             }  else if ( Mouse.x_info->z>0 )    {
  202.                  // z up pressed
  203.                 Mouse.pressed[MB_Z_UP] = 1;
  204.                 Mouse.time_went_down[MB_Z_UP]=Mouse.ctime;
  205.                 Mouse.num_downs[MB_Z_UP]++;
  206.             }
  207.             if (Mouse.pressed[MB_Z_DOWN])    {
  208.                  // z down released
  209.                 Mouse.pressed[MB_Z_DOWN] = 0;
  210.                 Mouse.time_held_down[MB_Z_DOWN] += Mouse.ctime-Mouse.time_went_down[MB_Z_DOWN];
  211.                 Mouse.num_ups[MB_Z_DOWN]++;
  212.             }  else if ( Mouse.x_info->z<0 )    {
  213.                  // z down pressed
  214.                 Mouse.pressed[MB_Z_DOWN] = 1;
  215.                 Mouse.time_went_down[MB_Z_DOWN]=Mouse.ctime;
  216.                 Mouse.num_downs[MB_Z_DOWN]++;
  217.             }
  218.         }
  219.         if (m_ax & ME_P_C )    { // pitch changed
  220.             if (Mouse.pressed[MB_PITCH_BACKWARD])    {
  221.                  // pitch backward released
  222.                 Mouse.pressed[MB_PITCH_BACKWARD] = 0;
  223.                 Mouse.time_held_down[MB_PITCH_BACKWARD] += Mouse.ctime-Mouse.time_went_down[MB_PITCH_BACKWARD];
  224.                 Mouse.num_ups[MB_PITCH_BACKWARD]++;
  225.             }  else if ( Mouse.x_info->pitch>0 )    {
  226.                  // pitch backward pressed
  227.                 Mouse.pressed[MB_PITCH_BACKWARD] = 1;
  228.                 Mouse.time_went_down[MB_PITCH_BACKWARD]=Mouse.ctime;
  229.                 Mouse.num_downs[MB_PITCH_BACKWARD]++;
  230.             }
  231.             if (Mouse.pressed[MB_PITCH_FORWARD])    {
  232.                  // pitch forward released
  233.                 Mouse.pressed[MB_PITCH_FORWARD] = 0;
  234.                 Mouse.time_held_down[MB_PITCH_FORWARD] += Mouse.ctime-Mouse.time_went_down[MB_PITCH_FORWARD];
  235.                 Mouse.num_ups[MB_PITCH_FORWARD]++;
  236.             }  else if ( Mouse.x_info->pitch<0 )    {
  237.                  // pitch forward pressed
  238.                 Mouse.pressed[MB_PITCH_FORWARD] = 1;
  239.                 Mouse.time_went_down[MB_PITCH_FORWARD]=Mouse.ctime;
  240.                 Mouse.num_downs[MB_PITCH_FORWARD]++;
  241.             }
  242.         }
  243.  
  244.         if (m_ax & ME_B_C )    { // bank changed
  245.             if (Mouse.pressed[MB_BANK_LEFT])    {
  246.                  // bank left released
  247.                 Mouse.pressed[MB_BANK_LEFT] = 0;
  248.                 Mouse.time_held_down[MB_BANK_LEFT] += Mouse.ctime-Mouse.time_went_down[MB_BANK_LEFT];
  249.                 Mouse.num_ups[MB_BANK_LEFT]++;
  250.             }  else if ( Mouse.x_info->bank>0 )    {
  251.                  // bank left pressed
  252.                 Mouse.pressed[MB_BANK_LEFT] = 1;
  253.                 Mouse.time_went_down[MB_BANK_LEFT]=Mouse.ctime;
  254.                 Mouse.num_downs[MB_BANK_LEFT]++;
  255.             }
  256.             if (Mouse.pressed[MB_BANK_RIGHT])    {
  257.                  // bank right released
  258.                 Mouse.pressed[MB_BANK_RIGHT] = 0;
  259.                 Mouse.time_held_down[MB_BANK_RIGHT] += Mouse.ctime-Mouse.time_went_down[MB_BANK_RIGHT];
  260.                 Mouse.num_ups[MB_BANK_RIGHT]++;
  261.             }  else if ( Mouse.x_info->bank<0 )    {
  262.                  // bank right pressed
  263.                 Mouse.pressed[MB_BANK_RIGHT] = 1;
  264.                 Mouse.time_went_down[MB_BANK_RIGHT]=Mouse.ctime;
  265.                 Mouse.num_downs[MB_BANK_RIGHT]++;
  266.             }
  267.         }
  268.  
  269.         if (m_ax & ME_H_C )    { // heading changed
  270.             if (Mouse.pressed[MB_HEAD_LEFT])    {
  271.                  // head left released
  272.                 Mouse.pressed[MB_HEAD_LEFT] = 0;
  273.                 Mouse.time_held_down[MB_HEAD_LEFT] += Mouse.ctime-Mouse.time_went_down[MB_HEAD_LEFT];
  274.                 Mouse.num_ups[MB_HEAD_LEFT]++;
  275.             }  else if ( Mouse.x_info->heading>0 )    {
  276.                  // head left pressed
  277.                 Mouse.pressed[MB_HEAD_LEFT] = 1;
  278.                 Mouse.time_went_down[MB_HEAD_LEFT]=Mouse.ctime;
  279.                 Mouse.num_downs[MB_HEAD_LEFT]++;
  280.             }
  281.             if (Mouse.pressed[MB_HEAD_RIGHT])    {
  282.                  // head right released
  283.                 Mouse.pressed[MB_HEAD_RIGHT] = 0;
  284.                 Mouse.time_held_down[MB_HEAD_RIGHT] += Mouse.ctime-Mouse.time_went_down[MB_HEAD_RIGHT];
  285.                 Mouse.num_ups[MB_HEAD_RIGHT]++;
  286.             }  else if ( Mouse.x_info->heading<0 )    {
  287.                  // head right pressed
  288.                 Mouse.pressed[MB_HEAD_RIGHT] = 1;
  289.                 Mouse.time_went_down[MB_HEAD_RIGHT]=Mouse.ctime;
  290.                 Mouse.num_downs[MB_HEAD_RIGHT]++;
  291.             }
  292.         }
  293.     }
  294.     
  295. }
  296.  
  297.  
  298.  
  299.  
  300. void mouse_handler_end (void)  // dummy functions
  301. {
  302. }
  303. #pragma on (check_stack)
  304.  
  305. //--------------------------------------------------------
  306. // returns 0 if no mouse
  307. //           else number of buttons
  308. int mouse_init(int enable_cyberman)
  309. {
  310.     dpmi_real_regs rr;
  311.     cyberman_info *ci;
  312.     struct SREGS sregs;
  313.     union REGS inregs, outregs;
  314.     ubyte *Mouse_dos_mem;
  315.  
  316.     if (Mouse_installed)
  317.         return Mouse.num_buttons;
  318.  
  319.    if (_dos_getvect(0x33) == NULL) {
  320.       // No mouse driver loaded
  321.       return 0;
  322.    }
  323.  
  324.     // Reset the mouse driver
  325.     memset( &inregs, 0, sizeof(inregs) );
  326.     inregs.w.ax = 0;
  327.     int386(0x33, &inregs, &outregs);
  328.     if (outregs.w.ax != 0xffff)
  329.         return 0;
  330.  
  331.     Mouse.num_buttons = outregs.w.bx;
  332.     Mouse.cyberman = 0;
  333.  
  334.     // Enable mouse driver
  335.     memset( &inregs, 0, sizeof(inregs) );
  336.     inregs.w.ax = 0x0020;
  337.     int386(0x33, &inregs, &outregs);
  338.     if (outregs.w.ax != 0xffff )
  339.         return 0;
  340.  
  341.     if ( enable_cyberman )    {
  342.         Mouse_dos_mem = dpmi_get_temp_low_buffer( 64 );
  343.         if (Mouse_dos_mem==NULL)    {
  344.             printf( "Unable to allocate DOS buffer in mouse.c\n" );
  345.         } else {
  346.             // Check for Cyberman...    
  347.             memset( &rr, 0, sizeof(dpmi_real_regs) );
  348.             rr.es = DPMI_real_segment(Mouse_dos_mem);
  349.             rr.edx = DPMI_real_offset(Mouse_dos_mem);
  350.             rr.eax = 0x53c1;
  351.             dpmi_real_int386x( 0x33, &rr );
  352.             if (rr.eax==1)    {
  353.                 // SWIFT functions supported
  354.                 ci    = (cyberman_info *)Mouse_dos_mem;
  355.                 if (ci->device_type==1)    {    // Cyberman    
  356.                     Mouse.cyberman = 1;
  357.                     //printf( "Cyberman mouse detected\n" );
  358.                     Mouse.num_buttons = 11;
  359.                 }
  360.             }
  361.         }
  362.     }
  363.  
  364.     if (!dpmi_lock_region(&Mouse,sizeof(mouse_info)))    {
  365.         printf( "Unable to lock mouse data region" );
  366.         exit(1);
  367.     }
  368.     if (!dpmi_lock_region((void near *)mouse_handler,(char *)mouse_handler_end - (char near *)mouse_handler))    {
  369.         printf( "Unable to lock mouse handler" );
  370.         exit(1);
  371.     }
  372.  
  373.     // Install mouse handler
  374.     memset( &inregs, 0, sizeof(inregs));
  375.     memset( &sregs, 0, sizeof(sregs));
  376.     inregs.w.ax     = 0xC;
  377.     inregs.w.cx     = ME_LB_P|ME_LB_R|ME_RB_P|ME_RB_R|ME_MB_P|ME_MB_R;    // watch all 3 button ups/downs
  378.     if (Mouse.cyberman)
  379.         inregs.w.cx     |= ME_Z_C| ME_P_C| ME_B_C| ME_H_C;    // if using a cyberman, also watch z, pitch, bank, heading.
  380.     inregs.x.edx    = FP_OFF(mouse_handler);
  381.     sregs.es         = FP_SEG(mouse_handler);
  382.     int386x(0x33, &inregs, &outregs, &sregs);
  383.  
  384.     Mouse_installed = 1;
  385.  
  386.     atexit( mouse_close );
  387.  
  388.     mouse_flush();
  389.  
  390.     return Mouse.num_buttons;
  391. }
  392.  
  393.  
  394.  
  395. void mouse_close()
  396. {
  397.     struct SREGS sregs;
  398.     union REGS inregs, outregs;
  399.  
  400.     if (Mouse_installed)    {
  401.         Mouse_installed = 0;
  402.         // clear mouse handler by setting flags to 0.
  403.         memset( &inregs, 0, sizeof(inregs));
  404.         memset( &sregs, 0, sizeof(sregs));
  405.         inregs.w.ax     = 0xC;
  406.         inregs.w.cx        = 0;        // disable event handler by setting to zero.
  407.         inregs.x.edx     = 0;    
  408.         sregs.es       = 0;
  409.         int386x(0x33, &inregs, &outregs, &sregs);
  410.     }
  411. }
  412.  
  413.  
  414. void mouse_set_limits( int x1, int y1, int x2, int y2 )
  415. {
  416.     union REGS inregs, outregs;
  417.  
  418.     if (!Mouse_installed) return;
  419.  
  420.     memset( &inregs, 0, sizeof(inregs));
  421.     inregs.w.ax = 0x7;    // Set Horizontal Limits for Pointer
  422.     inregs.w.cx = x1;
  423.     inregs.w.dx = x2;
  424.     int386(0x33, &inregs, &outregs);
  425.  
  426.     memset( &inregs, 0, sizeof(inregs));
  427.     inregs.w.ax = 0x8;    // Set Vertical Limits for Pointer
  428.     inregs.w.cx = y1;
  429.     inregs.w.dx = y2;
  430.     int386(0x33, &inregs, &outregs);
  431. }
  432.  
  433. void mouse_get_pos( int *x, int *y)
  434. {
  435.     union REGS inregs, outregs;
  436.  
  437.     if (!Mouse_installed) {
  438.         *x = *y = 0;
  439.         return;
  440.     }
  441.     memset( &inregs, 0, sizeof(inregs));
  442.     inregs.w.ax = 0x3;    // Get Mouse Position and Button Status
  443.     int386(0x33, &inregs, &outregs);
  444.     *x = (short)outregs.w.cx; 
  445.     *y = (short)outregs.w.dx; 
  446. }
  447.  
  448. void mouse_get_delta( int *dx, int *dy )
  449. {
  450.     union REGS inregs, outregs;
  451.  
  452.     if (!Mouse_installed) {
  453.         *dx = *dy = 0;
  454.         return;
  455.     }
  456.  
  457.     memset( &inregs, 0, sizeof(inregs));
  458.     inregs.w.ax = 0xb;    // Read Mouse motion counters
  459.     int386(0x33, &inregs, &outregs);
  460.     *dx = (short)outregs.w.cx; 
  461.     *dy = (short)outregs.w.dx; 
  462. }
  463.  
  464. int mouse_get_btns()
  465. {
  466.     int i;
  467.     uint flag=1;
  468.     int status = 0;
  469.  
  470.     if (!Mouse_installed) 
  471.         return 0;
  472.  
  473.     for (i=0; i<MOUSE_MAX_BUTTONS; i++ )    {
  474.         if (Mouse.pressed[i])
  475.             status |= flag;
  476.         flag <<= 1;
  477.     }
  478.     return status;
  479. }
  480.  
  481. void mouse_set_pos( int x, int y)
  482. {
  483.     union REGS inregs, outregs;
  484.  
  485.     if (!Mouse_installed) 
  486.         return;
  487.  
  488.     memset( &inregs, 0, sizeof(inregs));
  489.     inregs.w.ax = 0x4;    // Set Mouse Pointer Position
  490.     inregs.w.cx = x;
  491.     inregs.w.dx = y;
  492.     int386(0x33, &inregs, &outregs);
  493.  
  494. }
  495.  
  496. void mouse_flush()
  497. {
  498.     int i;
  499.     fix CurTime;
  500.  
  501.     if (!Mouse_installed) 
  502.         return;
  503.  
  504.     _disable();
  505.  
  506.     //Clear the mouse data
  507.     CurTime =timer_get_fixed_secondsX();
  508.     for (i=0; i<MOUSE_MAX_BUTTONS; i++ )    {
  509.         Mouse.pressed[i] = 0;
  510.         Mouse.time_went_down[i] = CurTime;
  511.         Mouse.time_held_down[i] = 0;
  512.         Mouse.num_downs[i]=0;
  513.         Mouse.num_ups[i]=0;
  514.     }
  515.     _enable();
  516. }
  517.  
  518.  
  519. // Returns how many times this button has went down since last call.
  520. int mouse_button_down_count(int button)    
  521. {
  522.     int count;
  523.  
  524.     if (!Mouse_installed) 
  525.         return 0;
  526.  
  527.     _disable();
  528.  
  529.     count = Mouse.num_downs[button];
  530.     Mouse.num_downs[button]=0;
  531.  
  532.     _enable();
  533.  
  534.     return count;
  535. }
  536.  
  537. // Returns 1 if this button is currently down
  538. int mouse_button_state(int button)    
  539. {
  540.     int state;
  541.  
  542.     if (!Mouse_installed) 
  543.         return 0;
  544.  
  545.     _disable();
  546.  
  547.     state = Mouse.pressed[button];
  548.  
  549.     _enable();
  550.  
  551.     return state;
  552. }
  553.  
  554.  
  555.  
  556. // Returns how long this button has been down since last call.
  557. fix mouse_button_down_time(int button)    
  558. {
  559.     fix time_down, time;
  560.  
  561.     if (!Mouse_installed) 
  562.         return 0;
  563.  
  564.     _disable();
  565.  
  566.     if ( !Mouse.pressed[button] )    {
  567.         time_down = Mouse.time_held_down[button];
  568.         Mouse.time_held_down[button] = 0;
  569.     } else    {
  570.         time = timer_get_fixed_secondsX();
  571.         time_down =  time - Mouse.time_went_down[button];
  572.         Mouse.time_went_down[button] = time;
  573.     }
  574.  
  575.     _enable();
  576.  
  577.     return time_down;
  578. }
  579.  
  580. void mouse_get_cyberman_pos( int *x, int *y )
  581. {
  582.     dpmi_real_regs rr;
  583.     event_info * ei;
  584.     ubyte *Mouse_dos_mem;
  585.  
  586.     if ( (!Mouse_installed) || (!Mouse.cyberman) ) {
  587.         *x = *y = 0;
  588.         return;
  589.     }
  590.  
  591.     Mouse_dos_mem = dpmi_get_temp_low_buffer( 64 );
  592.  
  593.     if ( !Mouse_dos_mem )    {
  594.         *x = *y = 0;
  595.         return;
  596.     }
  597.  
  598.  
  599.     memset( &rr, 0, sizeof(dpmi_real_regs) );
  600.     rr.es = DPMI_real_segment(Mouse_dos_mem);
  601.     rr.edx = DPMI_real_offset(Mouse_dos_mem);
  602.     rr.eax = 0x5301;
  603.     dpmi_real_int386x( 0x33, &rr );
  604.  
  605.     ei = (event_info *)Mouse_dos_mem;
  606.  
  607.     *x = (((ei->x+8128)*256)/(8064+8128+1)) - 127;
  608.     *y = (((ei->y+8128)*256)/(8064+8128+1)) - 127;
  609.  
  610. }
  611.  
  612. 
  613.