1 /*
2
3 Copyright (C) 2015-2018 Night Dive Studios, LLC.
4 Copyright (C) 2019 Shockolate Project
5
6 This program is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
18
19 */
20 /*
21 * $Source: n:/project/lib/src/input/RCS/mouse.c $
22 * $Revision: 1.15 $
23 * $Author: mahk $
24 * $Date: 1994/06/21 06:16:42 $
25 *
26 * Mouse handler adapted from Rex Bradford's Freefall mouse code.
27 *
28 * This file is part of the input library.
29 */
30
31 // This file only vaguely resembles the freefall mouse code from
32 // which it descended. It supports some very-low-level input routines
33 // for the mouse. It provides an interrupt-driven event queue, polling,
34 // and callbacks from the interrupt handler.
35
36 // ---------------------------------------------------------
37 // 6/21/94 ML Added mouse velocity support in mousevel.h so that we can emulate the mouse
38 // using other devices.
39 // ---------------------------------------------------------
40 // For the Mac version I use a TimeManager task to poll the mouse for mouse
41 // movement callback routines. Mouse click events will be handled throught the normal
42 // Macintosh event queue. Most of the stuff in this file will go away.
43 // ¥¥¥Note: The mouse position will always be returned in *local* coordinates,
44 // that is, local to the main game window.
45
46 #include <SDL.h>
47
48 #include "error.h"
49 #include "mouse.h"
50 #include "tickcount.h"
51
52 typedef struct _mouse_state {
53 short x, y;
54 short butts;
55 } mouse_state;
56
57 /*
58 #define DEFAULT_XRATE 16 // Default mouse sensitivity parameters
59 #define DEFAULT_YRATE 8
60 #define DEFAULT_ACCEL 100
61 #define LO_RES_SCREEN_WIDTH 320
62 #define HIRES_XRATE 2
63 #define HIRES_YRATE 2
64
65 // These are global for fast access from interrupt routine & others
66
67 short gMouseCritical; // in critical region?
68 */
69 #define NUM_MOUSEEVENTS 32
70 short mouseQueueSize = NUM_MOUSEEVENTS;
71 volatile short mouseQueueIn; // back of event queue
72 volatile short mouseQueueOut; // front of event queue
73 ss_mouse_event mouseQueue[NUM_MOUSEEVENTS]; // array of events
74
75 short mouseInstantX; // instantaneous mouse xpos (int-based)
76 short mouseInstantY; // instantaneous mouse ypos (int-based)
77 short mouseInstantButts;
78 /*
79 short mouseButtMask; // amt to mask to get buttons.
80 ubyte mouseXshift = 0; // Extra bits of mouse resolution
81 ubyte mouseYshift = 1;
82 */
83 ubyte mouseMask = 0xFF; // mask of events to put in the queue.
84 /*
85 uchar mouseLefty = FALSE; // is the user left-handed?
86 */
87 #define NUM_MOUSE_CALLBACKS 16
88 mouse_callfunc mouseCall[NUM_MOUSE_CALLBACKS];
89 void *mouseCallData[NUM_MOUSE_CALLBACKS];
90 short mouseCalls = 0; // current number of mouse calls.
91 short mouseCallSize = sizeof(mouse_callfunc);
92 /*
93 uchar mouse_installed = FALSE; // was mouse found?
94
95 ulong default_mouse_ticks = 0;
96 ulong volatile *mouse_ticks = &default_mouse_ticks; // Place to get mouse timestamps.
97
98 // MOUSE VELOCITY STUFF
99
100 int mouseVelX = 0, mouseVelY = 0;
101 int mouseVelXmax = 0x7FFFFFFF;
102 int mouseVelYmax = 0x7FFFFFFF;
103 int mouseVelXmin = 0x80000000;
104 int mouseVelYmin = 0x80000000;
105
106 // Macros & defines
107
108 #define MOUSECRITON() (gMouseCritical++)
109 #define MOUSECRITOFF() (gMouseCritical--)
110
111 #define INT_MOUSE 0x33 // mouse software interrupt vector
112
113 #define ERRET 1
114
115
116
117 extern void MouseHandler(void);
118 extern ulong mouseHandlerSize;
119 */
120
121 // extern short gActiveLeft, gActiveTop;
122 // bool gRBtnWasDown = true;
123 extern uchar pKbdGetKeys[16];
124
125 //----------------
126 // Internal Prototypes
127 //----------------
128 static void ReadMouseState(mouse_state *pMouseState);
129
130 #if __profile__
131 #pragma profile off
132 #endif
133 //---------------------------------------------------------------
134 // The following section is the time manager task for handling mouse movement.
135 //---------------------------------------------------------------
136 #pragma require_prototypes off
137
138 // KLC - try calling this from the main timer task.
139 //---------------------------------------------------------------
MousePollProc(void)140 void MousePollProc(void) {
141 // TODO: is this even still needed? if so, can it be replaced by setting mouseInstant* in pump_events() ?
142 // if the callbacks from mouseCall[] are still needed, could they also be called in pump_events() ?
143 // if not, could they be the only thing called here, while mouseInstant* is still set in pump_events() ?
144
145 extern ss_mouse_event latestMouseEvent;
146 mouseInstantButts = latestMouseEvent.buttons;
147
148 if (mouseInstantX != latestMouseEvent.x || mouseInstantY != latestMouseEvent.y) // If different
149 {
150 mouseInstantX = latestMouseEvent.x; // save the position
151 mouseInstantY = latestMouseEvent.y;
152
153 ss_mouse_event e = latestMouseEvent;
154 e.type = MOUSE_MOTION;
155
156 for (uint16_t i = 0; i < mouseCalls; i++)
157 if (mouseCall[i] != NULL)
158 mouseCall[i](&e, mouseCallData[i]);
159
160 if (mouseMask & MOUSE_MOTION) // Add a mouse-moved event
161 { // to the internal queue.
162 short newin = mouseQueueIn, newout = mouseQueueOut;
163 short in = newin;
164 mouseQueue[newin] = e;
165 newin = (newin + 1 < mouseQueueSize) ? newin + 1 : 0;
166 if (newin == mouseQueueOut)
167 newout = (newout + 1 < mouseQueueSize) ? newout + 1 : 0;
168 mouseQueueOut = newout;
169 mouseQueueIn = newin;
170 }
171 }
172
173 /*Point mp;
174 short i;
175 mouse_event e;
176
177 mp = *(Point *)0x830; // Get mouse location from low
178 memory. mp.h -= gActiveLeft;
179 // Convert to "local" screen coordinates. mp.v -= gActiveTop;
180
181 GetKeys((UInt32 *)pKbdGetKeys); // Check keys to see if our
182 simulated
183 // right button is down.
184 if (Button()) // See if the mouse button is
185 down
186 {
187 mouseInstantButts = 1;
188 if ((pKbdGetKeys[0x3A>>3] >> (0x3A & 7)) & 1) // If the option key is down also,
189 mouseInstantButts = 2; // then it's really a right-button
190 click.
191 }
192 if( ((pKbdGetKeys[0x31>>3] >> (0x31 & 7)) & 1) || // If space, enter, or return are down,
193 ((pKbdGetKeys[0x4C>>3] >> (0x4C & 7)) & 1) || // then pretend right-button is down.
194 ((pKbdGetKeys[0x24>>3] >> (0x24 & 7)) & 1) )
195 mouseInstantButts |= 2;
196
197 if (mouseInstantX != mp.h || mouseInstantY != mp.v) // If different
198 {
199 mouseInstantX = mp.h; // save the
200 position mouseInstantY = mp.v;
201
202 e.x = mp.h; // and inform the callback
203 routines e.y = mp.v; e.type = MOUSE_MOTION; e.buttons = mouseInstantButts; for (i = 0; i < mouseCalls; i++)
204 if(mouseCall[i] !=NULL)
205 mouseCall[i](&e,mouseCallData[i]);
206
207 if (mouseMask & MOUSE_MOTION) // Add a mouse-moved
208 event
209 { // to the internal
210 queue. short newin = mouseQueueIn, newout = mouseQueueOut; short in = newin; mouseQueue[newin] = e; newin = (newin + 1
211 < mouseQueueSize) ? newin + 1 : 0; if (newin == mouseQueueOut) newout = (newout + 1 < mouseQueueSize) ? newout + 1 : 0;
212 mouseQueueOut = newout;
213 mouseQueueIn = newin;
214 }
215 }
216 // PrimeTime((QElemPtr)tmTaskPtr, 50); // Check 20 times a second.
217
218 */
219 }
220
221 #pragma require_prototypes on
222 #if __profile__
223 #pragma profile on
224 #endif
225
226 // ---------------------------------------------------------
227 // mouse_shutdown() terminates mouse handler.
228 // ---------------------------------------------------------
229 // For Mac version: do nothing.
230
mouse_shutdown(void)231 errtype mouse_shutdown(void) {
232 /* union REGS regs;
233 struct SREGS segregs;
234
235 Spew(DSRC_MOUSE_Shutdown,("entering mouse_shutdown()\n"));
236
237
238 // Shut down Microsoft mouse driver
239
240 if (mouse_installed)
241 {
242 regs.x.eax = 0x000C;
243 regs.x.ecx = 0;
244 regs.x.edx = 0;
245 segregs.es = 0;
246 segregs.ds = 0;
247 int386x(INT_MOUSE, ®s, ®s, &segregs);
248
249 dpmi_unlock_lin_region(MouseHandler,mouseHandlerSize);
250 } */
251 // RmvTime((QElemPtr)&pMousePollTask); // Stop the mouse polling
252 //task DisposeRoutineDescriptor(pMousePollPtr); // Dispose its UPP
253
254 return OK;
255 }
256
257 // ---------------------------------------------------------
258 // mouse_init() initializes mouse handler. It does the following:
259 //
260 // 1. Microsoft mouse driver initialized
261 // 2. Customizes mouse driver & handler based on display mode
262 // 3. Initializes mouse handler state variables
263 // ---------------------------------------------------------
264 // For Mac version: ignore sizes (mouse is already set up).
265
mouse_init(short mone,short mtwo)266 errtype mouse_init(short mone, short mtwo) {
267 mouse_state mstate;
268 /*
269 union REGS regs;
270 struct SREGS segregs;
271 Spew(DSRC_MOUSE_Init,("Entering mouse_init()\n"));
272
273 // Initialize Microsoft mouse driver
274
275 regs.x.eax = 0x0000;
276 int386(INT_MOUSE, ®s, ®s);
277 mouse_installed = (regs.w.ax != 0);
278
279 // If mouse found, do more initialization
280
281 if (mouse_installed)
282 {
283
284 DBG(DSRC_MOUSE_Init,
285 { if (!mouse_installed)
286 Warning(("mouse_init(): Mouse not installed\n"));
287 })
288 */
289 // Initialize mouse state variables
290
291 extern void sdl_mouse_init(void);
292 sdl_mouse_init();
293
294 mouseQueueIn = 0;
295 mouseQueueOut = 0;
296
297 mouseCalls = 0;
298
299 ReadMouseState(&mstate);
300 mouseInstantX = mstate.x;
301 mouseInstantY = mstate.y;
302 mouseInstantButts = mstate.butts;
303 /*
304 // Set up mouse interrupt handler
305
306 dpmi_lock_lin_region(MouseHandler,mouseHandlerSize);
307
308 regs.x.eax = 0x000C;
309 regs.w.cx = 0xFF; // take all mouse events
310 regs.x.edx = FP_OFF(MouseHandler);
311 segregs.es = FP_SEG(MouseHandler);
312 segregs.ds = segregs.es;
313 int386x(INT_MOUSE, ®s, ®s, &segregs);
314
315 // Do the sensitivity scaling thang.
316 mouse_set_screensize(xsize,ysize);
317 }
318
319 AtExit(mouse_shutdown);
320
321 // Return whether or not mouse found
322
323 return(mouse_installed ? OK : ERR_NODEV);
324 */
325
326 /*
327 pMousePollPtr = NewTimerProc(MousePollProc); // Make a UPP for the TM task
328
329 pMousePollTask.task.tmAddr = pMousePollPtr; // Insert the mouse polling TM task
330 pMousePollTask.task.tmWakeUp = 0;
331 pMousePollTask.task.tmReserved = 0;
332 #ifndef __powerc
333 pMousePollTask.appA5 = SetCurrentA5();
334 #endif
335 InsTime((QElemPtr)&pMousePollTask);
336 PrimeTime((QElemPtr)&pMousePollTask, 50); // Check 20 times a second
337 */
338 return (OK);
339 }
340 /*
341 // ---------------------------------------------------------
342 // mouse_set_screensize() sets the screen size, scaling mouse sensitivity.
343 errtype mouse_set_screensize(short x, short y)
344 {
345 short xrate = DEFAULT_XRATE,yrate = DEFAULT_YRATE,t = DEFAULT_ACCEL;
346 if (x > LO_RES_SCREEN_WIDTH)
347 {
348 xrate = HIRES_XRATE;
349 yrate = HIRES_YRATE;
350 mouseXshift = 3;
351 mouseYshift = 3;
352 }
353 else
354 {
355 xrate /= 2;
356 mouseXshift = 1;
357 mouseYshift = 0;
358 }
359 mouse_set_rate(xrate,yrate,t);
360 mouse_constrain_xy(0,0,x-1,y-1);
361 mouse_put_xy(mouseInstantX,mouseInstantY);
362 return OK;
363 }
364 */
365 /*
366 //---------------------------------------------------------
367 // _mouse_update_vel() updates coordinates based on mouse
368 // velocity. Generates a motion event if there's any change to position.
369
370 void _mouse_update_vel(void)
371 {
372 static ulong last_ticks = 0;
373
374 ulong ticks = *mouse_ticks;
375
376 if (ticks != last_ticks && (mouseVelX != 0 || mouseVelY != 0))
377 {
378 short newx = mouseInstantX;
379 short newy = mouseInstantY;
380 ulong dt = ticks - last_ticks;
381 short dx = (mouseVelX*dt) >> MOUSE_VEL_UNIT_SHF;
382 short dy = (mouseVelY*dt) >> MOUSE_VEL_UNIT_SHF;
383
384 mouse_put_xy(newx+dx,newy+dy);
385 }
386 last_ticks = ticks;
387 }
388 */
389
390 // --------------------------------------------------------
391 // mouse_check_btn checks button state.
392 // res = ptr to result
393 // button = button number 0-2
394 // ---------------------------------------------------------
395 // For Mac version: Basically just return true or false right now.
396 // WH: no use
397 #if 0
398 errtype mouse_check_btn(short button, bool *res) {
399
400 if (button == 1) {
401 *res = SDL_BUTTON(SDL_BUTTON_LEFT);
402 } else if (button == 2) {
403 *res = SDL_BUTTON(SDL_BUTTON_RIGHT);
404 }
405 /* if (!mouse_installed)
406 {
407 Warning(("mouse_get_xy(): mouse not installed.\n"));
408 return ERR_NODEV;
409 }
410 *res = (mouseInstantButts >> button) & 1;
411 Spew(DSRC_MOUSE_CheckBtn,("mouse_check_btn(%d,%x) *res = %d\n",button,res,*res)); */
412 return OK;
413 }
414 #endif
415 // ---------------------------------------------------------
416 // mouse_look_next gets the event in front the event queue,
417 // but does not remove the event from the queue.
418 // res = ptr to event to be filled.
419 // ---------------------------------------------------------
420 // For Mac version: Check the normal Mac event queue for mouse events. The events
421 // looked for depend on the 'mouseMask' setting.
422 // WH: no use
423 #if 0
424 errtype mouse_look_next(ss_mouse_event *res) {
425 printf("mouse_look_next not implemented.\n");
426
427 /*if (OSEventAvail(eventMask, &theEvent)) // If there is an event,
428 {
429 GlobalToLocal(&theEvent.where);
430 res->x = theEvent.where.h; // fill in the mouse_event
431 record. res->y = theEvent.where.v; res->timestamp = theEvent.when;
432 if (theEvent.modifiers & optionKey) // If the option keys is down, send back
433 a
434 { // right-button
435 event. if (theEvent.what == mouseDown) res->type = MOUSE_RDOWN; else if (theEvent.what == mouseUp) res->type =
436 MOUSE_RUP; res->buttons = 2; res->modifiers = 0;
437 }
438 else // Otherwise it's a left-button
439 event.
440 {
441 if (theEvent.what == mouseDown)
442 res->type = MOUSE_LDOWN;
443 else if (theEvent.what == mouseUp)
444 res->type = MOUSE_LUP;
445 res->buttons = 1;
446 res->modifiers = (uchar)(theEvent.modifiers >> 8);
447 }
448 }*/
449
450 // If there's not a mouse click event, check the internal queue for mouse
451 // movement events.
452 /*else if (mouseMask & MOUSE_MOTION)
453 {
454 if (mouseQueueOut == mouseQueueIn) // If no motion events, return an error.
455 return ERR_NODEV;
456 else
457 *res = mouseQueue[mouseQueueOut]; // Return the event.
458 }
459
460 // If there are no events at all, return an error.
461 else
462 return ERR_NODEV;*/
463
464 /*
465 Spew(DSRC_MOUSE_LookNext,("entering mouse_look_next()\n"));
466 if (mouseQueueOut == mouseQueueIn)
467 _mouse_update_vel();
468 if (mouseQueueOut == mouseQueueIn)
469 {
470 Spew(DSRC_MOUSE_LookNext,("mouse_look_next(): Queue Underflow.\n"));
471 return ERR_NODEV;
472 }
473 *res = mouseQueue[mouseQueueOut];
474 */
475 return OK;
476 }
477 #endif
478
479 /*
480 // -------------------------------------------------------
481 //
482 // mouse_generate() adds an event to the back of the
483 // mouse event queue. If this overflows the queue,
484
485 errtype mouse_generate(mouse_event e)
486 {
487 short newin = mouseQueueIn, newout = mouseQueueOut;
488 short in = newin;
489 int i;
490 errtype result = OK;
491 Spew(DSRC_MOUSE_Generate,("Entering mouse_generate()\n"));
492 mouseQueue[newin] = e;
493 newin = (newin + 1 < mouseQueueSize) ? newin + 1 : 0;
494 if (newin == mouseQueueOut)
495 {
496 newout = (newout + 1 < mouseQueueSize) ? newout + 1 : 0;
497 Spew(DSRC_MOUSE_Generate,("mouse_generate(): Queue Overflow.\n"));
498 result = ERR_DUNDERFLOW;
499 }
500
501 mouseQueueOut = newout;
502 mouseQueueIn = newin;
503 mouseInstantX = e.x;
504 mouseInstantY = e.y;
505 mouseInstantButts = e.buttons;
506 for (i = 0; i < mouseCalls; i++)
507 if(mouseCall[i] !=NULL)
508 mouseCall[i](&mouseQueue[in],mouseCallData[i]);
509 return result;
510 }
511 */
512
513 // ------------------------------------------------------
514 //
515 // mouse_set_callback() registers a callback with the interrupt handler
516 // f = func to be called back.
517 // data = data to be given to the func when called
518 // *id = set to a unique id of the callback.
519
mouse_set_callback(mouse_callfunc f,void * data,int * id)520 errtype mouse_set_callback(mouse_callfunc f, void *data, int *id) {
521 // Spew(DSRC_MOUSE_SetCallback,("entering mouse_set_callback(%x,%x,%x)\n",f,data,id));
522 for (*id = 0; *id < mouseCalls; ++*id)
523 if (mouseCall[*id] == NULL)
524 break;
525 if (*id == NUM_MOUSE_CALLBACKS) {
526 // Spew(DSRC_MOUSE_SetCallback,("mouse_set_callback(): Table Overflow.\n"));
527 return ERR_DOVERFLOW;
528 }
529 if (*id == mouseCalls)
530 mouseCalls++;
531 // Spew(DSRC_MOUSE_SetCallback,("mouse_set_callback(): *id = %d, mouseCalls = %d\n",*id,mouseCalls));
532 mouseCall[*id] = f;
533 mouseCallData[*id] = data;
534 return OK;
535 }
536
537 // -------------------------------------------------------
538 //
539 // mouse_unset_callback() un-registers a callback function
540 // id = unique id of function to unset
541
mouse_unset_callback(int id)542 errtype mouse_unset_callback(int id) {
543 // Spew(DSRC_MOUSE_UnsetCallback,("entering mouse_unset_callback(%d)\n",id));
544 if (id >= mouseCalls || id < 0) {
545 // Spew(DSRC_MOUSE_UnsetCallback,("mouse_unset_callback(): id out of range \n"));
546 return ERR_RANGE;
547 }
548 mouseCall[id] = NULL;
549 while (mouseCalls > 0 && mouseCall[mouseCalls - 1] == NULL)
550 mouseCalls--;
551 return OK;
552 }
553
554 // --------------------------------------------------------
555 //
556 // mouse_constrain_xy() defines min/max coords
557 // ¥¥¥ don't do anything for now. Will need to implement some day.
mouse_constrain_xy(short xl,short yl,short xh,short yh)558 errtype mouse_constrain_xy(short xl, short yl, short xh, short yh) {
559 /*
560 union REGS regs;
561 Spew(DSRC_MOUSE_ConstrainXY,("mouse_constrain_xy(%d,%d,%d,%d)\n",xl,yl,xh,yh));
562 if (!mouse_installed)
563 {
564 Warning(("mouse_constrain_xy(): mouse not installed.\n"));
565 return ERR_NODEV;
566 }
567 regs.x.eax = 0x0007;
568 regs.x.ecx = xl << mouseXshift;
569 regs.x.edx = xh << mouseXshift;
570 int386(INT_MOUSE,®s,®s);
571 regs.x.eax = 0x0008;
572 regs.x.ecx = yl << mouseYshift;
573 regs.x.edx = yh << mouseYshift;
574 int386(INT_MOUSE,®s,®s);
575 */
576 return OK;
577 }
578
579 /*
580 // --------------------------------------------------------
581 //
582 // mouse_set_rate() sets mouse rate, doubling threshhold
583
584 errtype mouse_set_rate(short xr, short yr, short thold)
585 {
586 union REGS regs;
587 Spew(DSRC_MOUSE_SetRate,("mouse_set_rate(%d,%d,%d)\n",xr,yr,thold));
588 if (!mouse_installed)
589 {
590 Warning(("mouse_set_rate(): mouse not installed.\n"));
591 return ERR_NODEV;
592 }
593 // if (mouseXshift > 0) xr = xr / mouseXshift; // why are we dividing? Because shifting is too extreme
594 // if (mouseYshift > 0) yr = yr / mouseYshift;
595 regs.x.eax = 0x000F;
596 regs.x.ecx = max(1,xr);
597 regs.x.edx = max(1,yr);
598 int386(INT_MOUSE,®s,®s);
599 regs.x.eax = 0x0013;
600 regs.x.edx = max(1,thold);
601 int386(INT_MOUSE,®s,®s);
602 return OK;
603 }
604
605 // --------------------------------------------------
606 //
607 // mouse_get_rate() gets current sensitivity values
608
609 errtype mouse_get_rate(short* xr, short* yr, short* thold)
610 {
611 union REGS regs;
612 regs.x.eax = 0x001B;
613 int386(INT_MOUSE,®s,®s);
614 *xr = regs.x.ebx;
615 *yr = regs.x.ecx;
616 *thold = regs.x.edx;
617 // if (mouseXshift > 0) *xr *= mouseXshift; // why are we multiplying? Because shifting is too extreme
618 // if (mouseYshift > 0) *yr *= mouseYshift;
619 return OK;
620 }
621
622
623 // --------------------------------------------------------
624 //
625 // mouse_set_timestamp_register() tells the mouse library where to get
626 // timestamps.
627
628 errtype mouse_set_timestamp_register(ulong* tstamp)
629 {
630 mouse_ticks = tstamp;
631 return OK;
632 }
633 */
634
635 // --------------------------------------------------------
636 // mouse_get_time() returns the current mouse timestamp
637 // --------------------------------------------------------
638 // For Mac version: Just return TickCount().
639
mouse_get_time(void)640 uint32_t mouse_get_time(void) {
641 return TickCount();
642 }
643
644 // --------------------------------------------------------
645 // ReadMouseState() reads current state of mouse.
646 //
647 // pMouseState = ptr to mouse state struct, filled in by routine
648 // --------------------------------------------------------
649 // For Mac version: Use Mac routines to get mouse position and state.
650
ReadMouseState(mouse_state * pMouseState)651 static void ReadMouseState(mouse_state *pMouseState) {
652 int mouse_x;
653 int mouse_y;
654
655 uint mouse_state = SDL_GetMouseState(&mouse_x, &mouse_y);
656 pMouseState->x = mouse_x;
657 pMouseState->y = mouse_y;
658 pMouseState->butts = 0;
659
660 if (mouse_state & SDL_BUTTON(SDL_BUTTON_LEFT)) {
661 pMouseState->butts = 1;
662 }
663
664 if (mouse_state & SDL_BUTTON(SDL_BUTTON_RIGHT)) {
665 pMouseState->butts = 2;
666 }
667
668 /* union REGS regs;
669
670 regs.x.eax = 0x0003;
671 int386(INT_MOUSE, ®s, ®s);
672
673 pMouseState->x = regs.w.cx;
674 pMouseState->y = regs.w.dx;
675 pMouseState->butts = regs.w.bx; */
676 }
677
678 /*
679 // ---------------------------------------------------
680 //
681 // mouse_extremes() finds the min and max "virtual" coordinates of the mouse position
682
683 errtype mouse_extremes( short *xmin, short *ymin, short *xmax, short *ymax )
684 {
685 union REGS regs;
686
687 regs.x.eax = 0x31;
688 int386( INT_MOUSE, ®s, ®s );
689
690 *xmin = regs.w.ax >> mouseXshift;
691 *ymin = regs.w.bx >> mouseYshift;
692 *xmax = regs.w.cx >> mouseXshift;
693 *ymax = regs.w.dx >> mouseYshift;
694
695 Spew( DSRC_MOUSE_Extremes, ("mouse_extremes(): <%d %d> to <%d %d>\n", *xmin, *ymin, *xmax, *ymax ));
696
697 return OK;
698 }
699
700
701 // ------------------------------------------------------
702 //
703 // mouse_set_lefty() sets mouse handedness
704
705 #define SHIFTDIFF 1
706
707 static short shifted_button_state(short bstate)
708 {
709 short tmp = (bstate & MOUSE_RBUTTON) >> SHIFTDIFF;
710 tmp |= (bstate & MOUSE_LBUTTON) << SHIFTDIFF;
711 tmp |= bstate & MOUSE_CBUTTON;
712 return tmp;
713 }
714
715 errtype mouse_set_lefty(uchar lefty)
716 {
717 if (lefty == mouseLefty) return ERR_NOEFFECT;
718 mouseInstantButts = shifted_button_state(mouseInstantButts);
719 mouseLefty = lefty;
720 return OK;
721 }
722
723
724
725
726 // ---------------------------------------------------
727 //
728 // mouse_set_velocity_range() sets the range of valid mouse pointer velocities.
729
730 errtype mouse_set_velocity_range(int xl, int yl, int xh, int yh)
731 {
732 mouseVelXmin = xl;
733 mouseVelYmin = yl;
734 mouseVelXmax = xh;
735 mouseVelYmax = yh;
736 return OK;
737 }
738
739 errtype mouse_set_velocity(int x, int y)
740 {
741 mouseVelX = max(mouseVelXmin,min(x,mouseVelXmax));
742 mouseVelY = max(mouseVelYmin,min(y,mouseVelYmax));
743 if (mouseVelX != x || mouseVelY != y)
744 return ERR_RANGE;
745 return OK;
746 }
747
748 errtype mouse_add_velocity(int x, int y)
749 {
750 return mouse_set_velocity(mouseVelX + x, mouseVelY + y);
751 }
752
753 errtype mouse_get_velocity(int* x, int* y)
754 {
755 *x = mouseVelX;
756 *y = mouseVelY;
757 return OK;
758 }
759 */
760