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.
14 * $Source: /cvs/cvsroot/d2x/arch/win32/mouse.c,v $
17 * $Date: 2004-05-19 02:18:19 $
19 * Functions to access Mouse and Cyberman...
21 * $Log: not supported by cvs2svn $
22 * Revision 1.1.1.1 2001/01/19 03:30:15 bradleyb
25 * Revision 1.5 1999/10/15 05:27:48 donut
26 * include to fix undef'd err
28 * Revision 1.4 1999/10/14 03:08:10 donut
29 * changed exit to mprintf on unknown mouse event
31 * Revision 1.3 1999/10/09 05:03:57 donut
32 * fixed win32 exit on mouse move
34 * Revision 1.2 1999/09/05 04:19:19 sekmu
35 * made mouse exclusive for windows
37 * Revision 1.1.1.1 1999/06/14 22:00:37 donut
38 * Import of d1x 1.37 source.
40 * Revision 1.8 1996/02/21 13:57:36 allender
41 * cursor device manager stuff added here so as not to
42 * rely on InterfaceLib anymore
44 * Revision 1.7 1995/10/17 15:42:21 allender
45 * new mouse function to determine single button press
47 * Revision 1.6 1995/10/03 11:27:31 allender
48 * fixed up hotspot problems with the mouse on multiple monitors
50 * Revision 1.5 1995/07/13 11:27:08 allender
51 * trap button checks at MAX_MOUSE_BUTTONS
53 * Revision 1.4 1995/06/25 21:56:53 allender
54 * added events include
56 * Revision 1.3 1995/05/11 17:06:38 allender
57 * fixed up mouse routines
59 * Revision 1.2 1995/05/11 13:05:53 allender
60 * of mouse handler code
62 * Revision 1.1 1995/05/05 09:54:45 allender
65 * Revision 1.9 1995/01/14 19:19:52 john
66 * Fixed signed short error cmp with -1 that caused mouse
67 * to break under Watcom 10.0
69 * Revision 1.8 1994/12/27 12:38:23 john
70 * Made mouse use temporary dos buffer instead of
75 * Revision 1.7 1994/12/05 23:54:53 john
76 * Fixed bug with mouse_get_delta only returning positive numbers..
78 * Revision 1.6 1994/11/18 23:18:18 john
79 * Changed some shorts to ints.
81 * Revision 1.5 1994/09/13 12:34:02 john
82 * Added functions to get down count and state.
84 * Revision 1.4 1994/08/29 20:52:19 john
85 * Added better cyberman support; also, joystick calibration
86 * value return funcctiionn,
88 * Revision 1.3 1994/08/24 18:54:32 john
89 * *** empty log message ***
91 * Revision 1.2 1994/08/24 18:53:46 john
92 * Made Cyberman read like normal mouse; added dpmi module; moved
93 * mouse from assembly to c. Made mouse buttons return time_down.
95 * Revision 1.1 1994/08/24 13:56:37 john
101 #define WIN32_LEAN_AND_MEAN
115 // These are to kludge up a bit my slightly broken GCC directx port.
117 #define E_FAIL (HRESULT)0x80004005L
120 #define SUCCEEDED(a) ((HRESULT)(a) >= 0)
126 #ifndef SEVERITY_SUCCESS
127 #define SEVERITY_SUCCESS 0
128 #define SEVERITY_ERROR 1
130 #ifndef FACILITY_WIN32
131 #define FACILITY_WIN32 7
134 #define FIELD_OFFSET(type, field) ((LONG)&(((type *)0)->field))
137 #define ME_CURSOR_MOVED (1<<0)
138 #define ME_LB_P (1<<1)
139 #define ME_LB_R (1<<2)
140 #define ME_RB_P (1<<3)
141 #define ME_RB_R (1<<4)
142 #define ME_MB_P (1<<5)
143 #define ME_MB_R (1<<6)
144 #define ME_OB_P (1<<7)
145 #define ME_OB_R (1<<8)
146 #define ME_X_C (1<<9)
147 #define ME_Y_C (1<<10)
148 #define ME_Z_C (1<<11)
149 #define ME_P_C (1<<12)
150 #define ME_B_C (1<<13)
151 #define ME_H_C (1<<14)
152 #define ME_O_C (1<<15)
154 typedef struct event_info {
161 ushort button_status;
162 ushort device_dependant;
165 typedef struct mouse_info {
169 ubyte pressed[MOUSE_MAX_BUTTONS];
170 fix time_went_down[MOUSE_MAX_BUTTONS];
171 fix time_held_down[MOUSE_MAX_BUTTONS];
172 uint num_downs[MOUSE_MAX_BUTTONS];
173 uint num_ups[MOUSE_MAX_BUTTONS];
174 // ubyte went_down; /* Not in PC version, not needed with 'num_downs' etc */
176 ushort button_status;
179 typedef struct cyberman_info {
186 ubyte pitch_descriptor;
187 ubyte roll_descriptor;
188 ubyte yaw_descriptor;
192 static mouse_info Mouse;
194 static int Mouse_installed = 0;
196 int WMMouse_Handler_Ready = 0;
197 int mouse_wparam, mouse_lparam, mouse_msg;
201 //extern ggi_visual_t visual;
202 //extern ggi_directbuffer_t dbuf; // GGI direct acces to screen memory
203 //extern ggi_pixellinearbuffer *plb;
206 static double mouse_x, mouse_y;
207 static double mouse_saved_x, mouse_saved_y; //used when hiding/unhiding to reset the real (displayed) postion
208 double mouse_accel=1.0;
210 void DrawMouse(void);
211 void EraseMouse(void);
212 void MoveMouse(/*int button,*/ int x, int y);
214 #define WIN_WIDTH 640
215 #define WIN_HEIGHT 480
216 #define SCR_WIDTH 640
217 #define SCR_HEIGHT 480
219 LPDIRECTINPUT g_lpdi;
220 LPDIRECTINPUTDEVICE g_lpdidMouse;
224 HRESULT ReadMouse (DIDEVICEOBJECTDATA *pdidod)
229 if (g_lpdidMouse == NULL)
232 hr = IDirectInputDevice_GetDeviceData (
239 if (hr == DIERR_INPUTLOST)
241 hr = IDirectInputDevice_Acquire (g_lpdidMouse);
244 hr = IDirectInputDevice_GetDeviceData (
253 if (SUCCEEDED (hr) && cElements != 1)
260 void UpdateMouseState (DIDEVICEOBJECTDATA *pdidod)
262 // fix timeNow = timer_get_fixed_seconds ();
264 ULONG iEvt = pdidod->dwOfs;
272 BOOL bPressed = pdidod->dwData & 0x80;
273 ULONG iButton = (iEvt - DIMOFS_BUTTON0) + MB_LEFT;
276 if (!Mouse.pressed [iButton])
278 Mouse.pressed [iButton] = 1;
279 Mouse.time_went_down [iButton] = Mouse.ctime;
280 Mouse.num_downs [iButton]++;
281 // Mouse.went_down = 1;
283 Mouse.num_downs [iButton] ++;
287 if (Mouse.pressed [iButton])
289 Mouse.pressed [iButton] = 0;
290 Mouse.time_held_down [iButton] += Mouse.ctime - Mouse.time_went_down [iButton];
291 Mouse.num_ups [iButton]++;
292 // Mouse.went_down = 0;
298 mouse_x += (double) ((LONG) pdidod->dwData);
302 mouse_y += (double) ((LONG) pdidod->dwData);
305 break;//hm, handle this?
307 mprintf((0,"unknown mouse event %i\n",iEvt));
308 // exit (iEvt);//not happy.
315 DIDEVICEOBJECTDATA didod;
317 Mouse.ctime = timer_get_fixed_seconds();
319 while (SUCCEEDED (ReadMouse (&didod)))
321 UpdateMouseState (&didod);
330 if (!Mouse_installed)
335 CurTime = timer_get_fixed_seconds();
336 for (i = 0; i < MOUSE_MAX_BUTTONS; i++) {
337 Mouse.pressed[i] = 0;
338 Mouse.time_went_down[i] = CurTime;
339 Mouse.time_held_down[i] = 0;
340 Mouse.num_downs[i] = 0;
341 Mouse.num_ups[i] = 0;
343 // Mouse.went_down = 0; /* mac only */
347 DWORD cElements = INFINITE;
349 IDirectInputDevice_GetDeviceData (
351 sizeof (DIDEVICEOBJECTDATA),
359 void mouse_close(void)
361 // if (Mouse_installed) // DPH: Unnecessary...
362 WMMouse_Handler_Ready=Mouse_installed = 0;
364 if (g_lpdidMouse != NULL)
366 IDirectInputDevice_Unacquire (g_lpdidMouse);
367 IDirectInputDevice_Release (g_lpdidMouse);
372 IDirectInput_Release (g_lpdi);
379 int mouse_init(int unused)
382 return Mouse.num_buttons;
387 if (SUCCEEDED (hr = DirectInputCreate (GetModuleHandle (NULL), DIRECTINPUT_VERSION, &g_lpdi, NULL)))
389 if (SUCCEEDED (hr = IDirectInput_CreateDevice (g_lpdi,(void *) &GUID_SysMouse, &g_lpdidMouse, NULL)))
392 dipdw.diph.dwSize = sizeof (DIPROPDWORD);
393 dipdw.diph.dwHeaderSize = sizeof (DIPROPHEADER);
394 dipdw.diph.dwObj = 0;
395 dipdw.diph.dwHow = DIPH_DEVICE;
398 if (SUCCEEDED (hr = IDirectInputDevice_SetDataFormat (g_lpdidMouse, &c_dfDIMouse)) &&
399 //changed on 9/4/99 by Victor Rachels NONEX -> Exclusive
400 SUCCEEDED (hr = IDirectInputDevice_SetCooperativeLevel (g_lpdidMouse, g_hWnd, DISCL_EXCLUSIVE | DISCL_FOREGROUND)) &&
401 //end this section edit -VR
402 SUCCEEDED (hr = IDirectInputDevice_SetProperty (g_lpdidMouse, DIPROP_BUFFERSIZE, &dipdw.diph)) &&
403 SUCCEEDED (hr = IDirectInputDevice_Acquire (g_lpdidMouse)))
408 IDirectInputDevice_Release (g_lpdidMouse);
415 Mouse.num_buttons = 3;
417 WMMouse_Handler_Ready=Mouse_installed = 1;
420 // mouse_set_center();
422 return Mouse.num_buttons;
426 void mouse_center() {
427 mouse_x=mouse_saved_x=WIN_WIDTH/2;
428 mouse_y=mouse_saved_y=WIN_HEIGHT/2;
431 void mouse_get_pos( int *x, int *y)
433 mouse_handler(); //temp
439 void mouse_get_delta( int *dx, int *dy )
441 if (!Mouse_installed) {
445 mouse_handler(); //temp
447 *dx = (int) mouse_x - WIN_WIDTH/2;
448 *dy = (int) mouse_y - WIN_HEIGHT/2;
450 //Now reset the mouse position to the center of the screen
451 mouse_x = (double) WIN_WIDTH/2;
452 mouse_y = (double) WIN_HEIGHT/2;
455 void mouse_get_delta_no_reset( int *dx, int *dy )
457 if (!Mouse_installed) {
461 mouse_handler(); //temp
463 *dx = (int) mouse_x - WIN_WIDTH/2;
464 *dy = (int) mouse_y - WIN_HEIGHT/2;
473 if (!Mouse_installed)
476 mouse_handler(); //temp
478 for (i = 0; i < MOUSE_MAX_BUTTONS; i++) {
479 if (Mouse.pressed[i])
486 /* This should be replaced with mouse_button_down_count(int button) */
487 int mouse_went_down(int button)
491 if (!Mouse_installed)
494 mouse_handler(); //temp
496 if ((button < 0) || (button >= MOUSE_MAX_BUTTONS))
500 count = Mouse.num_downs[button];
501 Mouse.num_downs[button] = 0;
507 // Returns how many times this button has went down since last call.
508 int mouse_button_down_count(int button)
512 if (!Mouse_installed)
515 mouse_handler(); //temp
517 if ((button < 0) || (button >= MOUSE_MAX_BUTTONS))
521 count = Mouse.num_downs[button];
522 Mouse.num_downs[button] = 0;
527 // Returns 1 if this button is currently down
528 int mouse_button_state(int button)
532 if (!Mouse_installed)
535 mouse_handler(); //temp
537 if ((button < 0) || (button >= MOUSE_MAX_BUTTONS))
541 state = Mouse.pressed[button];
546 // Returns how long this button has been down since last call.
547 fix mouse_button_down_time(int button)
551 if (!Mouse_installed)
554 mouse_handler(); //temp
556 if ((button < 0) || (button >= MOUSE_MAX_BUTTONS))
560 if (!Mouse.pressed[button]) {
561 time_down = Mouse.time_held_down[button];
562 Mouse.time_held_down[button] = 0;
564 time = timer_get_fixed_seconds();
565 time_down = time - Mouse.time_held_down[button];
566 Mouse.time_held_down[button] = 0;
573 void mouse_get_cyberman_pos( int *x, int *y )
579 //WHS: I made this :)
591 /* New mouse pointer stuff for GGI/DGA */
592 //#include "cursor.h" /* cursor and mask */
594 typedef struct Sprite {
601 //Sprite mouse_sprite = { cursor_width, cursor_height, cursor_bits, cursor_mask_bits};
603 //byte *behind_mouse;
604 //byte behind_mouse[cursor_width*cursor_height];
612 void EraseMouse(void)
616 //Should add a mode, relative, absolute
619 //void MoveMouse(int mode, int x, int y) {
621 void MoveMouse(int x, int y)