1 /* $Id: mouse.c,v 1.3 2004-05-20 19:02:58 btb Exp $ */
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.
16 * Functions to access Mouse and Cyberman...
19 * Revision 1.8 1996/02/21 13:57:36 allender
20 * cursor device manager stuff added here so as not to
21 * rely on InterfaceLib anymore
23 * Revision 1.7 1995/10/17 15:42:21 allender
24 * new mouse function to determine single button press
26 * Revision 1.6 1995/10/03 11:27:31 allender
27 * fixed up hotspot problems with the mouse on multiple monitors
29 * Revision 1.5 1995/07/13 11:27:08 allender
30 * trap button checks at MAX_MOUSE_BUTTONS
32 * Revision 1.4 1995/06/25 21:56:53 allender
33 * added events include
35 * Revision 1.3 1995/05/11 17:06:38 allender
36 * fixed up mouse routines
38 * Revision 1.2 1995/05/11 13:05:53 allender
39 * of mouse handler code
41 * Revision 1.1 1995/05/05 09:54:45 allender
44 * Revision 1.9 1995/01/14 19:19:52 john
45 * Fixed signed short error cmp with -1 that caused mouse
46 * to break under Watcom 10.0
48 * Revision 1.8 1994/12/27 12:38:23 john
49 * Made mouse use temporary dos buffer instead of
53 * Revision 1.7 1994/12/05 23:54:53 john
54 * Fixed bug with mouse_get_delta only returning positive numbers..
56 * Revision 1.6 1994/11/18 23:18:18 john
57 * Changed some shorts to ints.
59 * Revision 1.5 1994/09/13 12:34:02 john
60 * Added functions to get down count and state.
62 * Revision 1.4 1994/08/29 20:52:19 john
63 * Added better cyberman support; also, joystick calibration
64 * value return funcctiionn,
66 * Revision 1.3 1994/08/24 18:54:32 john
67 * *** empty log message ***
69 * Revision 1.2 1994/08/24 18:53:46 john
70 * Made Cyberman read like normal mouse; added dpmi module; moved
71 * mouse from assembly to c. Made mouse buttons return time_down.
73 * Revision 1.1 1994/08/24 13:56:37 john
79 #define WIN32_LEAN_AND_MEAN
94 // These are to kludge up a bit my slightly broken GCC directx port.
96 #define E_FAIL (HRESULT)0x80004005L
99 #define SUCCEEDED(a) ((HRESULT)(a) >= 0)
105 #ifndef SEVERITY_SUCCESS
106 #define SEVERITY_SUCCESS 0
107 #define SEVERITY_ERROR 1
109 #ifndef FACILITY_WIN32
110 #define FACILITY_WIN32 7
113 #define FIELD_OFFSET(type, field) ((LONG)&(((type *)0)->field))
116 #define ME_CURSOR_MOVED (1<<0)
117 #define ME_LB_P (1<<1)
118 #define ME_LB_R (1<<2)
119 #define ME_RB_P (1<<3)
120 #define ME_RB_R (1<<4)
121 #define ME_MB_P (1<<5)
122 #define ME_MB_R (1<<6)
123 #define ME_OB_P (1<<7)
124 #define ME_OB_R (1<<8)
125 #define ME_X_C (1<<9)
126 #define ME_Y_C (1<<10)
127 #define ME_Z_C (1<<11)
128 #define ME_P_C (1<<12)
129 #define ME_B_C (1<<13)
130 #define ME_H_C (1<<14)
131 #define ME_O_C (1<<15)
133 typedef struct event_info {
140 ushort button_status;
141 ushort device_dependant;
144 typedef struct mouse_info {
148 ubyte pressed[MOUSE_MAX_BUTTONS];
149 fix time_went_down[MOUSE_MAX_BUTTONS];
150 fix time_held_down[MOUSE_MAX_BUTTONS];
151 uint num_downs[MOUSE_MAX_BUTTONS];
152 uint num_ups[MOUSE_MAX_BUTTONS];
153 // ubyte went_down; /* Not in PC version, not needed with 'num_downs' etc */
155 ushort button_status;
158 typedef struct cyberman_info {
165 ubyte pitch_descriptor;
166 ubyte roll_descriptor;
167 ubyte yaw_descriptor;
171 static mouse_info Mouse;
173 static int Mouse_installed = 0;
175 int WMMouse_Handler_Ready = 0;
176 int mouse_wparam, mouse_lparam, mouse_msg;
180 //extern ggi_visual_t visual;
181 //extern ggi_directbuffer_t dbuf; // GGI direct acces to screen memory
182 //extern ggi_pixellinearbuffer *plb;
185 static double mouse_x, mouse_y;
186 static double mouse_saved_x, mouse_saved_y; //used when hiding/unhiding to reset the real (displayed) postion
187 double mouse_accel=1.0;
189 void DrawMouse(void);
190 void EraseMouse(void);
191 void MoveMouse(/*int button,*/ int x, int y);
193 #define WIN_WIDTH 640
194 #define WIN_HEIGHT 480
195 #define SCR_WIDTH 640
196 #define SCR_HEIGHT 480
198 LPDIRECTINPUT g_lpdi = NULL;
199 LPDIRECTINPUTDEVICE g_lpdidMouse = NULL;
203 HRESULT ReadMouse (DIDEVICEOBJECTDATA *pdidod)
208 if (g_lpdidMouse == NULL)
211 hr = IDirectInputDevice_GetDeviceData (
218 if (hr == DIERR_INPUTLOST)
220 hr = IDirectInputDevice_Acquire (g_lpdidMouse);
223 hr = IDirectInputDevice_GetDeviceData (
232 if (SUCCEEDED (hr) && cElements != 1)
239 void UpdateMouseState (DIDEVICEOBJECTDATA *pdidod)
241 // fix timeNow = timer_get_fixed_seconds ();
243 ULONG iEvt = pdidod->dwOfs;
251 BOOL bPressed = pdidod->dwData & 0x80;
252 ULONG iButton = (iEvt - DIMOFS_BUTTON0) + MB_LEFT;
255 if (!Mouse.pressed [iButton])
257 Mouse.pressed [iButton] = 1;
258 Mouse.time_went_down [iButton] = Mouse.ctime;
259 Mouse.num_downs [iButton]++;
260 // Mouse.went_down = 1;
262 Mouse.num_downs [iButton] ++;
266 if (Mouse.pressed [iButton])
268 Mouse.pressed [iButton] = 0;
269 Mouse.time_held_down [iButton] += Mouse.ctime - Mouse.time_went_down [iButton];
270 Mouse.num_ups [iButton]++;
271 // Mouse.went_down = 0;
277 mouse_x += (double) ((LONG) pdidod->dwData);
281 mouse_y += (double) ((LONG) pdidod->dwData);
284 break;//hm, handle this?
286 mprintf((0,"unknown mouse event %i\n",iEvt));
287 // exit (iEvt);//not happy.
294 DIDEVICEOBJECTDATA didod;
296 Mouse.ctime = timer_get_fixed_seconds();
298 while (SUCCEEDED (ReadMouse (&didod)))
300 UpdateMouseState (&didod);
309 if (!Mouse_installed)
314 CurTime = timer_get_fixed_seconds();
315 for (i = 0; i < MOUSE_MAX_BUTTONS; i++) {
316 Mouse.pressed[i] = 0;
317 Mouse.time_went_down[i] = CurTime;
318 Mouse.time_held_down[i] = 0;
319 Mouse.num_downs[i] = 0;
320 Mouse.num_ups[i] = 0;
322 // Mouse.went_down = 0; /* mac only */
326 DWORD cElements = INFINITE;
328 IDirectInputDevice_GetDeviceData (
330 sizeof (DIDEVICEOBJECTDATA),
338 void mouse_close(void)
340 // if (Mouse_installed) // DPH: Unnecessary...
341 WMMouse_Handler_Ready=Mouse_installed = 0;
343 if (g_lpdidMouse != NULL)
345 IDirectInputDevice_Unacquire (g_lpdidMouse);
346 IDirectInputDevice_Release (g_lpdidMouse);
351 IDirectInput_Release (g_lpdi);
358 int mouse_init(int unused)
360 if (FindArg("-nomouse"))
363 return Mouse.num_buttons;
368 if (SUCCEEDED (hr = DirectInputCreate (GetModuleHandle (NULL), DIRECTINPUT_VERSION, &g_lpdi, NULL)))
370 if (SUCCEEDED (hr = IDirectInput_CreateDevice (g_lpdi,(void *) &GUID_SysMouse, &g_lpdidMouse, NULL)))
373 dipdw.diph.dwSize = sizeof (DIPROPDWORD);
374 dipdw.diph.dwHeaderSize = sizeof (DIPROPHEADER);
375 dipdw.diph.dwObj = 0;
376 dipdw.diph.dwHow = DIPH_DEVICE;
379 if (SUCCEEDED (hr = IDirectInputDevice_SetDataFormat (g_lpdidMouse, &c_dfDIMouse)) &&
380 //changed on 9/4/99 by Victor Rachels NONEX -> Exclusive
381 SUCCEEDED (hr = IDirectInputDevice_SetCooperativeLevel (g_lpdidMouse, g_hWnd, DISCL_EXCLUSIVE | DISCL_FOREGROUND)) &&
382 //end this section edit -VR
383 SUCCEEDED (hr = IDirectInputDevice_SetProperty (g_lpdidMouse, DIPROP_BUFFERSIZE, &dipdw.diph)) &&
384 SUCCEEDED (hr = IDirectInputDevice_Acquire (g_lpdidMouse)))
389 IDirectInputDevice_Release (g_lpdidMouse);
396 Mouse.num_buttons = 3;
398 WMMouse_Handler_Ready=Mouse_installed = 1;
401 // mouse_set_center();
403 return Mouse.num_buttons;
407 void mouse_center() {
408 mouse_x=mouse_saved_x=WIN_WIDTH/2;
409 mouse_y=mouse_saved_y=WIN_HEIGHT/2;
412 void mouse_get_pos( int *x, int *y)
414 mouse_handler(); //temp
420 void mouse_get_delta( int *dx, int *dy )
422 if (!Mouse_installed) {
426 mouse_handler(); //temp
428 *dx = (int) mouse_x - WIN_WIDTH/2;
429 *dy = (int) mouse_y - WIN_HEIGHT/2;
431 //Now reset the mouse position to the center of the screen
432 mouse_x = (double) WIN_WIDTH/2;
433 mouse_y = (double) WIN_HEIGHT/2;
436 void mouse_get_delta_no_reset( int *dx, int *dy )
438 if (!Mouse_installed) {
442 mouse_handler(); //temp
444 *dx = (int) mouse_x - WIN_WIDTH/2;
445 *dy = (int) mouse_y - WIN_HEIGHT/2;
454 if (!Mouse_installed)
457 mouse_handler(); //temp
459 for (i = 0; i < MOUSE_MAX_BUTTONS; i++) {
460 if (Mouse.pressed[i])
467 /* This should be replaced with mouse_button_down_count(int button) */
468 int mouse_went_down(int button)
472 if (!Mouse_installed)
475 mouse_handler(); //temp
477 if ((button < 0) || (button >= MOUSE_MAX_BUTTONS))
481 count = Mouse.num_downs[button];
482 Mouse.num_downs[button] = 0;
488 // Returns how many times this button has went down since last call.
489 int mouse_button_down_count(int button)
493 if (!Mouse_installed)
496 mouse_handler(); //temp
498 if ((button < 0) || (button >= MOUSE_MAX_BUTTONS))
502 count = Mouse.num_downs[button];
503 Mouse.num_downs[button] = 0;
508 // Returns 1 if this button is currently down
509 int mouse_button_state(int button)
513 if (!Mouse_installed)
516 mouse_handler(); //temp
518 if ((button < 0) || (button >= MOUSE_MAX_BUTTONS))
522 state = Mouse.pressed[button];
527 // Returns how long this button has been down since last call.
528 fix mouse_button_down_time(int button)
532 if (!Mouse_installed)
535 mouse_handler(); //temp
537 if ((button < 0) || (button >= MOUSE_MAX_BUTTONS))
541 if (!Mouse.pressed[button]) {
542 time_down = Mouse.time_held_down[button];
543 Mouse.time_held_down[button] = 0;
545 time = timer_get_fixed_seconds();
546 time_down = time - Mouse.time_held_down[button];
547 Mouse.time_held_down[button] = 0;
554 void mouse_get_cyberman_pos( int *x, int *y )
560 //WHS: I made this :)
572 /* New mouse pointer stuff for GGI/DGA */
573 //#include "cursor.h" /* cursor and mask */
575 typedef struct Sprite {
582 //Sprite mouse_sprite = { cursor_width, cursor_height, cursor_bits, cursor_mask_bits};
584 //byte *behind_mouse;
585 //byte behind_mouse[cursor_width*cursor_height];
593 void EraseMouse(void)
597 //Should add a mode, relative, absolute
600 //void MoveMouse(int mode, int x, int y) {
602 void MoveMouse(int x, int y)