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