]> icculus.org git repositories - btb/d2x.git/blob - arch/dos/mouse.c
use the orientation parameter of g3_draw_bitmap
[btb/d2x.git] / arch / 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  *
16  * Functions to access Mouse and Cyberman...
17  *
18  */
19
20 #ifdef HAVE_CONFIG_H
21 #include <conf.h>
22 #endif
23
24 #ifdef __DJGPP__
25 #include <dpmi.h>
26 #define _BORLAND_DOS_REGS 1
27 #define near
28 _go32_dpmi_registers handler_regs;
29 #endif
30
31 #include <go32.h>
32
33 #include <stdlib.h>
34 #include <stdio.h>
35 //#include <conio.h>
36 #include <dos.h>
37 //#include <i86.h>
38 #include <string.h>
39
40 #include "dxxerror.h"
41 #include "fix.h"
42 #include "u_dpmi.h"
43 #include "mouse.h"
44 #include "timer.h"
45
46 #define ME_CURSOR_MOVED (1<<0)
47 #define ME_LB_P                         (1<<1)
48 #define ME_LB_R                         (1<<2)
49 #define ME_RB_P                         (1<<3)
50 #define ME_RB_R                         (1<<4)
51 #define ME_MB_P                         (1<<5)
52 #define ME_MB_R                         (1<<6)
53 #define ME_OB_P                         (1<<7)
54 #define ME_OB_R                         (1<<8)
55 #define ME_X_C                  (1<<9)
56 #define ME_Y_C                  (1<<10)
57 #define ME_Z_C                  (1<<11)
58 #define ME_P_C                  (1<<12)
59 #define ME_B_C                  (1<<13)
60 #define ME_H_C                  (1<<14)
61 #define ME_O_C                  (1<<15)
62
63 #define MOUSE_MAX_BUTTONS       11
64
65 typedef struct event_info {
66         short x;
67         short y;
68         short z;
69         short pitch;
70         short bank;
71         short heading;
72         ushort button_status;
73         ushort device_dependant;
74 } event_info;
75
76 typedef struct mouse_info {
77         fix             ctime;
78         ubyte           cyberman;
79         int             num_buttons;
80         ubyte           pressed[MOUSE_MAX_BUTTONS];
81         fix             time_went_down[MOUSE_MAX_BUTTONS];
82         fix             time_held_down[MOUSE_MAX_BUTTONS];
83         uint            num_downs[MOUSE_MAX_BUTTONS];
84         uint            num_ups[MOUSE_MAX_BUTTONS];
85         event_info *x_info;
86         ushort  button_status;
87 } mouse_info;
88
89 typedef struct cyberman_info {
90         ubyte device_type;
91         ubyte major_version;
92         ubyte minor_version;
93         ubyte x_descriptor;
94         ubyte y_descriptor;
95         ubyte z_descriptor;
96         ubyte pitch_descriptor;
97         ubyte roll_descriptor;
98         ubyte yaw_descriptor;
99         ubyte reserved;
100 } cyberman_info;
101
102 static mouse_info Mouse;
103
104 static int Mouse_installed = 0;
105
106 #ifdef __DJGPP__
107 #define m_ax r->d.eax
108 #define mbx r->d.ebx
109 #define mcx r->d.ecx
110 #define mdx r->d.edx
111 #define msi r->d.esi
112 #define mdi r->d.edi
113 void mouse_handler (_go32_dpmi_registers *r)
114 {
115 #else
116 #pragma off (check_stack)
117 void _loadds far mouse_handler (int m_ax, int mbx, int mcx, int mdx, int msi, int mdi)
118 {
119 #pragma aux mouse_handler parm [EAX] [EBX] [ECX] [EDX] [ESI] [EDI]
120 #endif
121         Mouse.ctime = timer_get_fixed_secondsX();
122
123         if (m_ax & ME_LB_P)     {       // left button pressed
124                 if (!Mouse.pressed[MB_LEFT])    {
125                         Mouse.pressed[MB_LEFT] = 1;
126                         Mouse.time_went_down[MB_LEFT] = Mouse.ctime;
127                 }
128                 Mouse.num_downs[MB_LEFT]++;
129         } else if (m_ax & ME_LB_R )     {  // left button released
130                 if (Mouse.pressed[MB_LEFT])     {
131                         Mouse.pressed[MB_LEFT] = 0;
132                         Mouse.time_held_down[MB_LEFT] += Mouse.ctime-Mouse.time_went_down[MB_LEFT];
133                 }
134                 Mouse.num_ups[MB_LEFT]++;
135         }
136
137         if (m_ax & ME_RB_P ) {  // right button pressed
138                 if (!Mouse.pressed[MB_RIGHT])   {
139                         Mouse.pressed[MB_RIGHT] = 1;
140                         Mouse.time_went_down[MB_RIGHT] = Mouse.ctime;
141                 }
142                 Mouse.num_downs[MB_RIGHT]++;
143         } else if (m_ax & ME_RB_R )     {// right button released
144                 if (Mouse.pressed[MB_RIGHT])    {
145                         Mouse.pressed[MB_RIGHT] = 0;
146                         Mouse.time_held_down[MB_RIGHT] += Mouse.ctime-Mouse.time_went_down[MB_RIGHT];
147                 }
148                 Mouse.num_ups[MB_RIGHT]++;
149         }
150
151         if (m_ax & ME_MB_P )    { // middle button pressed
152                 if (!Mouse.pressed[MB_MIDDLE])  {
153                         Mouse.pressed[MB_MIDDLE] = 1;
154                         Mouse.time_went_down[MB_MIDDLE] = Mouse.ctime;
155                 }
156                 Mouse.num_downs[MB_MIDDLE]++;
157         } else if (m_ax & ME_MB_R )     { // middle button released
158                 if (Mouse.pressed[MB_MIDDLE])   {
159                         Mouse.pressed[MB_MIDDLE] = 0;
160                         Mouse.time_held_down[MB_MIDDLE] += Mouse.ctime-Mouse.time_went_down[MB_MIDDLE];
161                 }
162                 Mouse.num_ups[MB_MIDDLE]++;
163         }
164
165         if (Mouse.cyberman && (m_ax & (ME_Z_C|ME_P_C|ME_B_C|ME_H_C)))   {
166                 Mouse.x_info = (event_info *)((msi & 0xFFFF) << 4);
167
168                 if (m_ax & ME_Z_C )     { // z axis changed
169                         if (Mouse.pressed[MB_Z_UP])     {
170                                 // z up released
171                                 Mouse.pressed[MB_Z_UP] = 0;
172                                 Mouse.time_held_down[MB_Z_UP] += Mouse.ctime-Mouse.time_went_down[MB_Z_UP];
173                                 Mouse.num_ups[MB_Z_UP]++;
174                         }  else if ( Mouse.x_info->z>0 )        {
175                                 // z up pressed
176                                 Mouse.pressed[MB_Z_UP] = 1;
177                                 Mouse.time_went_down[MB_Z_UP]=Mouse.ctime;
178                                 Mouse.num_downs[MB_Z_UP]++;
179                         }
180                         if (Mouse.pressed[MB_Z_DOWN])   {
181                                 // z down released
182                                 Mouse.pressed[MB_Z_DOWN] = 0;
183                                 Mouse.time_held_down[MB_Z_DOWN] += Mouse.ctime-Mouse.time_went_down[MB_Z_DOWN];
184                                 Mouse.num_ups[MB_Z_DOWN]++;
185                         }  else if ( Mouse.x_info->z<0 )        {
186                                 // z down pressed
187                                 Mouse.pressed[MB_Z_DOWN] = 1;
188                                 Mouse.time_went_down[MB_Z_DOWN]=Mouse.ctime;
189                                 Mouse.num_downs[MB_Z_DOWN]++;
190                         }
191                 }
192                 if (m_ax & ME_P_C )     { // pitch changed
193                         if (Mouse.pressed[MB_PITCH_BACKWARD])   {
194                                 // pitch backward released
195                                 Mouse.pressed[MB_PITCH_BACKWARD] = 0;
196                                 Mouse.time_held_down[MB_PITCH_BACKWARD] += Mouse.ctime-Mouse.time_went_down[MB_PITCH_BACKWARD];
197                                 Mouse.num_ups[MB_PITCH_BACKWARD]++;
198                         }  else if ( Mouse.x_info->pitch>0 )    {
199                                 // pitch backward pressed
200                                 Mouse.pressed[MB_PITCH_BACKWARD] = 1;
201                                 Mouse.time_went_down[MB_PITCH_BACKWARD]=Mouse.ctime;
202                                 Mouse.num_downs[MB_PITCH_BACKWARD]++;
203                         }
204                         if (Mouse.pressed[MB_PITCH_FORWARD])    {
205                                 // pitch forward released
206                                 Mouse.pressed[MB_PITCH_FORWARD] = 0;
207                                 Mouse.time_held_down[MB_PITCH_FORWARD] += Mouse.ctime-Mouse.time_went_down[MB_PITCH_FORWARD];
208                                 Mouse.num_ups[MB_PITCH_FORWARD]++;
209                         }  else if ( Mouse.x_info->pitch<0 )    {
210                                 // pitch forward pressed
211                                 Mouse.pressed[MB_PITCH_FORWARD] = 1;
212                                 Mouse.time_went_down[MB_PITCH_FORWARD]=Mouse.ctime;
213                                 Mouse.num_downs[MB_PITCH_FORWARD]++;
214                         }
215                 }
216
217                 if (m_ax & ME_B_C )     { // bank changed
218                         if (Mouse.pressed[MB_BANK_LEFT])        {
219                                 // bank left released
220                                 Mouse.pressed[MB_BANK_LEFT] = 0;
221                                 Mouse.time_held_down[MB_BANK_LEFT] += Mouse.ctime-Mouse.time_went_down[MB_BANK_LEFT];
222                                 Mouse.num_ups[MB_BANK_LEFT]++;
223                         }  else if ( Mouse.x_info->bank>0 )     {
224                                 // bank left pressed
225                                 Mouse.pressed[MB_BANK_LEFT] = 1;
226                                 Mouse.time_went_down[MB_BANK_LEFT]=Mouse.ctime;
227                                 Mouse.num_downs[MB_BANK_LEFT]++;
228                         }
229                         if (Mouse.pressed[MB_BANK_RIGHT])       {
230                                 // bank right released
231                                 Mouse.pressed[MB_BANK_RIGHT] = 0;
232                                 Mouse.time_held_down[MB_BANK_RIGHT] += Mouse.ctime-Mouse.time_went_down[MB_BANK_RIGHT];
233                                 Mouse.num_ups[MB_BANK_RIGHT]++;
234                         }  else if ( Mouse.x_info->bank<0 )     {
235                                 // bank right pressed
236                                 Mouse.pressed[MB_BANK_RIGHT] = 1;
237                                 Mouse.time_went_down[MB_BANK_RIGHT]=Mouse.ctime;
238                                 Mouse.num_downs[MB_BANK_RIGHT]++;
239                         }
240                 }
241
242                 if (m_ax & ME_H_C )     { // heading changed
243                         if (Mouse.pressed[MB_HEAD_LEFT])        {
244                                 // head left released
245                                 Mouse.pressed[MB_HEAD_LEFT] = 0;
246                                 Mouse.time_held_down[MB_HEAD_LEFT] += Mouse.ctime-Mouse.time_went_down[MB_HEAD_LEFT];
247                                 Mouse.num_ups[MB_HEAD_LEFT]++;
248                         }  else if ( Mouse.x_info->heading>0 )  {
249                                 // head left pressed
250                                 Mouse.pressed[MB_HEAD_LEFT] = 1;
251                                 Mouse.time_went_down[MB_HEAD_LEFT]=Mouse.ctime;
252                                 Mouse.num_downs[MB_HEAD_LEFT]++;
253                         }
254                         if (Mouse.pressed[MB_HEAD_RIGHT])       {
255                                 // head right released
256                                 Mouse.pressed[MB_HEAD_RIGHT] = 0;
257                                 Mouse.time_held_down[MB_HEAD_RIGHT] += Mouse.ctime-Mouse.time_went_down[MB_HEAD_RIGHT];
258                                 Mouse.num_ups[MB_HEAD_RIGHT]++;
259                         }  else if ( Mouse.x_info->heading<0 )  {
260                                 // head right pressed
261                                 Mouse.pressed[MB_HEAD_RIGHT] = 1;
262                                 Mouse.time_went_down[MB_HEAD_RIGHT]=Mouse.ctime;
263                                 Mouse.num_downs[MB_HEAD_RIGHT]++;
264                         }
265                 }
266         }
267         
268 }
269
270
271
272
273 void mouse_handler_end (void)  // dummy functions
274 {
275 }
276 #ifndef __DJGPP__
277 #pragma on (check_stack)
278 #endif
279
280 //--------------------------------------------------------
281 // returns 0 if no mouse
282 //           else number of buttons
283 int mouse_init(int enable_cyberman)
284 {
285         dpmi_real_regs rr;
286         cyberman_info *ci;
287 #ifndef __DJGPP__
288         struct SREGS sregs;
289 #endif
290         union REGS inregs, outregs;
291         ubyte *Mouse_dos_mem;
292
293         if (Mouse_installed)
294                 return Mouse.num_buttons;
295
296 #ifdef __DJGPP__
297        if (_farpeekl(_dos_ds, 0x33 * 4) == 0) {
298 #else
299        if (_dos_getvect(0x33) == NULL) {
300 #endif
301                         // added on 1/13/2000 by Victor Rachels for more info
302                         con_printf(CON_NORMAL, "\nNo mouse driver found!\n");
303                         // end this section addition - VR
304                 // No mouse driver loaded
305                 return 0;
306        }
307
308         // Reset the mouse driver
309         memset( &inregs, 0, sizeof(inregs) );
310         inregs.w.ax = 0;
311         int386(0x33, &inregs, &outregs);
312         if (outregs.w.ax != 0xffff)
313         {
314                 // added on 1/13/2000 by Victor Rachels for more info
315                 con_printf(CON_NORMAL, "\nUnable to reset mouse!\n");
316                 // end this section edit - VR
317
318                 return 0;
319         }
320
321         Mouse.num_buttons = outregs.w.bx;
322         Mouse.cyberman = 0;
323
324         // Enable mouse driver
325         // added/edited on 1/15/2000 by Victor Rachels to make this optional - can usually be used w or w/o this reset
326         if(!FindArg("-ihaveabrokenmouse"))
327         {
328                 memset(&inregs, 0, sizeof(inregs));
329                 inregs.w.ax = 0x0020;
330                 int386(0x33, &inregs, &outregs);
331                 if (outregs.w.ax != 0xffff)
332                 {
333                         // added on 1/13/2000 by Victor Rachels for more info
334                         con_printf(CON_NORMAL, "\nUnable to enable mouse! (%x)\n", outregs.w.ax);
335                         // end this section edit - VR
336                         return 0;
337                 }
338         }
339         // end this section edit/addition - VR
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 #ifdef __DJGPP__
375         {
376          dpmi_real_regs rregs;
377          _go32_dpmi_seginfo info;
378          memset(&rregs, 0, sizeof(rregs));
379          info.pm_offset = (unsigned int)&mouse_handler;
380          if (_go32_dpmi_allocate_real_mode_callback_retf(&info, &handler_regs)) {
381                 printf( "Unable allocate mouse handler callback" );
382                 exit(1);
383          }
384          rregs.eax     = 0xC;
385          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
386          if (Mouse.cyberman)
387                 rregs.ecx     |= ME_Z_C| ME_P_C| ME_B_C| ME_H_C;      // if using a cyberman, also watch z, pitch, bank, heading.
388          rregs.edx       = info.rm_offset;
389          rregs.es        = info.rm_segment;
390          dpmi_real_int386x( 0x33, &rregs );
391         }
392 #else
393         memset( &inregs, 0, sizeof(inregs));
394         memset( &sregs, 0, sizeof(sregs));
395         inregs.w.ax     = 0xC;
396         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
397         if (Mouse.cyberman)
398                 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.
399         inregs.x.edx    = FP_OFF(mouse_handler);
400         sregs.es                = FP_SEG(mouse_handler);
401         int386x(0x33, &inregs, &outregs, &sregs);
402 #endif
403
404         Mouse_installed = 1;
405
406         atexit( mouse_close );
407
408         mouse_flush();
409
410         return Mouse.num_buttons;
411 }
412
413
414
415 void mouse_close()
416 {
417         struct SREGS sregs;
418         union REGS inregs, outregs;
419
420         if (Mouse_installed)    {
421                 Mouse_installed = 0;
422                 // clear mouse handler by setting flags to 0.
423                 memset( &inregs, 0, sizeof(inregs));
424                 memset( &sregs, 0, sizeof(sregs));
425                 inregs.w.ax     = 0xC;
426                 inregs.w.cx             = 0;            // disable event handler by setting to zero.
427                 inregs.x.edx    = 0;    
428                 sregs.es       = 0;
429                 int386x(0x33, &inregs, &outregs, &sregs);
430         }
431 }
432
433
434 void mouse_set_limits( int x1, int y1, int x2, int y2 )
435 {
436         union REGS inregs, outregs;
437
438         if (!Mouse_installed) return;
439
440         memset( &inregs, 0, sizeof(inregs));
441         inregs.w.ax = 0x7;      // Set Horizontal Limits for Pointer
442         inregs.w.cx = x1;
443         inregs.w.dx = x2;
444         int386(0x33, &inregs, &outregs);
445
446         memset( &inregs, 0, sizeof(inregs));
447         inregs.w.ax = 0x8;      // Set Vertical Limits for Pointer
448         inregs.w.cx = y1;
449         inregs.w.dx = y2;
450         int386(0x33, &inregs, &outregs);
451 }
452
453 void mouse_get_pos( int *x, int *y)
454 {
455         union REGS inregs, outregs;
456
457         if (!Mouse_installed) {
458                 *x = *y = 0;
459                 return;
460         }
461         memset( &inregs, 0, sizeof(inregs));
462         inregs.w.ax = 0x3;      // Get Mouse Position and Button Status
463         int386(0x33, &inregs, &outregs);
464         *x = (short)outregs.w.cx; 
465         *y = (short)outregs.w.dx; 
466 }
467
468 void mouse_get_delta( int *dx, int *dy, int *dz )
469 {
470         union REGS inregs, outregs;
471
472         if (!Mouse_installed) {
473                 *dx = *dy = 0;
474                 return;
475         }
476
477         memset( &inregs, 0, sizeof(inregs));
478         inregs.w.ax = 0xb;      // Read Mouse motion counters
479         int386(0x33, &inregs, &outregs);
480         *dx = (short)outregs.w.cx; 
481         *dy = (short)outregs.w.dx; 
482         *dz = 0;
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 }