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