1 /* $Id: mouse.c,v 1.4 2004-08-28 23:17:45 schaffner 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...
20 #define WIN32_LEAN_AND_MEAN
35 // These are to kludge up a bit my slightly broken GCC directx port.
37 #define E_FAIL (HRESULT)0x80004005L
40 #define SUCCEEDED(a) ((HRESULT)(a) >= 0)
46 #ifndef SEVERITY_SUCCESS
47 #define SEVERITY_SUCCESS 0
48 #define SEVERITY_ERROR 1
50 #ifndef FACILITY_WIN32
51 #define FACILITY_WIN32 7
54 #define FIELD_OFFSET(type, field) ((LONG)&(((type *)0)->field))
57 #define ME_CURSOR_MOVED (1<<0)
58 #define ME_LB_P (1<<1)
59 #define ME_LB_R (1<<2)
60 #define ME_RB_P (1<<3)
61 #define ME_RB_R (1<<4)
62 #define ME_MB_P (1<<5)
63 #define ME_MB_R (1<<6)
64 #define ME_OB_P (1<<7)
65 #define ME_OB_R (1<<8)
67 #define ME_Y_C (1<<10)
68 #define ME_Z_C (1<<11)
69 #define ME_P_C (1<<12)
70 #define ME_B_C (1<<13)
71 #define ME_H_C (1<<14)
72 #define ME_O_C (1<<15)
74 typedef struct event_info {
82 ushort device_dependant;
85 typedef struct mouse_info {
89 ubyte pressed[MOUSE_MAX_BUTTONS];
90 fix time_went_down[MOUSE_MAX_BUTTONS];
91 fix time_held_down[MOUSE_MAX_BUTTONS];
92 uint num_downs[MOUSE_MAX_BUTTONS];
93 uint num_ups[MOUSE_MAX_BUTTONS];
94 // ubyte went_down; /* Not in PC version, not needed with 'num_downs' etc */
99 typedef struct cyberman_info {
106 ubyte pitch_descriptor;
107 ubyte roll_descriptor;
108 ubyte yaw_descriptor;
112 static mouse_info Mouse;
114 static int Mouse_installed = 0;
116 int WMMouse_Handler_Ready = 0;
117 int mouse_wparam, mouse_lparam, mouse_msg;
121 //extern ggi_visual_t visual;
122 //extern ggi_directbuffer_t dbuf; // GGI direct acces to screen memory
123 //extern ggi_pixellinearbuffer *plb;
126 static double mouse_x, mouse_y;
127 static double mouse_saved_x, mouse_saved_y; //used when hiding/unhiding to reset the real (displayed) postion
128 double mouse_accel=1.0;
130 void DrawMouse(void);
131 void EraseMouse(void);
132 void MoveMouse(/*int button,*/ int x, int y);
134 #define WIN_WIDTH 640
135 #define WIN_HEIGHT 480
136 #define SCR_WIDTH 640
137 #define SCR_HEIGHT 480
139 LPDIRECTINPUT g_lpdi = NULL;
140 LPDIRECTINPUTDEVICE g_lpdidMouse = NULL;
144 HRESULT ReadMouse (DIDEVICEOBJECTDATA *pdidod)
149 if (g_lpdidMouse == NULL)
152 hr = IDirectInputDevice_GetDeviceData (
159 if (hr == DIERR_INPUTLOST)
161 hr = IDirectInputDevice_Acquire (g_lpdidMouse);
164 hr = IDirectInputDevice_GetDeviceData (
173 if (SUCCEEDED (hr) && cElements != 1)
180 void UpdateMouseState (DIDEVICEOBJECTDATA *pdidod)
182 // fix timeNow = timer_get_fixed_seconds ();
184 ULONG iEvt = pdidod->dwOfs;
192 BOOL bPressed = pdidod->dwData & 0x80;
193 ULONG iButton = (iEvt - DIMOFS_BUTTON0) + MB_LEFT;
196 if (!Mouse.pressed [iButton])
198 Mouse.pressed [iButton] = 1;
199 Mouse.time_went_down [iButton] = Mouse.ctime;
200 Mouse.num_downs [iButton]++;
201 // Mouse.went_down = 1;
203 Mouse.num_downs [iButton] ++;
207 if (Mouse.pressed [iButton])
209 Mouse.pressed [iButton] = 0;
210 Mouse.time_held_down [iButton] += Mouse.ctime - Mouse.time_went_down [iButton];
211 Mouse.num_ups [iButton]++;
212 // Mouse.went_down = 0;
218 mouse_x += (double) ((LONG) pdidod->dwData);
222 mouse_y += (double) ((LONG) pdidod->dwData);
225 break;//hm, handle this?
227 mprintf((0,"unknown mouse event %i\n",iEvt));
228 // exit (iEvt);//not happy.
235 DIDEVICEOBJECTDATA didod;
237 Mouse.ctime = timer_get_fixed_seconds();
239 while (SUCCEEDED (ReadMouse (&didod)))
241 UpdateMouseState (&didod);
250 if (!Mouse_installed)
255 CurTime = timer_get_fixed_seconds();
256 for (i = 0; i < MOUSE_MAX_BUTTONS; i++) {
257 Mouse.pressed[i] = 0;
258 Mouse.time_went_down[i] = CurTime;
259 Mouse.time_held_down[i] = 0;
260 Mouse.num_downs[i] = 0;
261 Mouse.num_ups[i] = 0;
263 // Mouse.went_down = 0; /* mac only */
267 DWORD cElements = INFINITE;
269 IDirectInputDevice_GetDeviceData (
271 sizeof (DIDEVICEOBJECTDATA),
279 void mouse_close(void)
281 // if (Mouse_installed) // DPH: Unnecessary...
282 WMMouse_Handler_Ready=Mouse_installed = 0;
284 if (g_lpdidMouse != NULL)
286 IDirectInputDevice_Unacquire (g_lpdidMouse);
287 IDirectInputDevice_Release (g_lpdidMouse);
292 IDirectInput_Release (g_lpdi);
299 int mouse_init(int unused)
301 if (FindArg("-nomouse"))
304 return Mouse.num_buttons;
309 if (SUCCEEDED (hr = DirectInputCreate (GetModuleHandle (NULL), DIRECTINPUT_VERSION, &g_lpdi, NULL)))
311 if (SUCCEEDED (hr = IDirectInput_CreateDevice (g_lpdi,(void *) &GUID_SysMouse, &g_lpdidMouse, NULL)))
314 dipdw.diph.dwSize = sizeof (DIPROPDWORD);
315 dipdw.diph.dwHeaderSize = sizeof (DIPROPHEADER);
316 dipdw.diph.dwObj = 0;
317 dipdw.diph.dwHow = DIPH_DEVICE;
320 if (SUCCEEDED (hr = IDirectInputDevice_SetDataFormat (g_lpdidMouse, &c_dfDIMouse)) &&
321 //changed on 9/4/99 by Victor Rachels NONEX -> Exclusive
322 SUCCEEDED (hr = IDirectInputDevice_SetCooperativeLevel (g_lpdidMouse, g_hWnd, DISCL_EXCLUSIVE | DISCL_FOREGROUND)) &&
323 //end this section edit -VR
324 SUCCEEDED (hr = IDirectInputDevice_SetProperty (g_lpdidMouse, DIPROP_BUFFERSIZE, &dipdw.diph)) &&
325 SUCCEEDED (hr = IDirectInputDevice_Acquire (g_lpdidMouse)))
330 IDirectInputDevice_Release (g_lpdidMouse);
337 Mouse.num_buttons = 3;
339 WMMouse_Handler_Ready=Mouse_installed = 1;
342 // mouse_set_center();
344 return Mouse.num_buttons;
348 void mouse_center() {
349 mouse_x=mouse_saved_x=WIN_WIDTH/2;
350 mouse_y=mouse_saved_y=WIN_HEIGHT/2;
353 void mouse_get_pos( int *x, int *y)
355 mouse_handler(); //temp
361 void mouse_get_delta( int *dx, int *dy )
363 if (!Mouse_installed) {
367 mouse_handler(); //temp
369 *dx = (int) mouse_x - WIN_WIDTH/2;
370 *dy = (int) mouse_y - WIN_HEIGHT/2;
372 //Now reset the mouse position to the center of the screen
373 mouse_x = (double) WIN_WIDTH/2;
374 mouse_y = (double) WIN_HEIGHT/2;
377 void mouse_get_delta_no_reset( int *dx, int *dy )
379 if (!Mouse_installed) {
383 mouse_handler(); //temp
385 *dx = (int) mouse_x - WIN_WIDTH/2;
386 *dy = (int) mouse_y - WIN_HEIGHT/2;
395 if (!Mouse_installed)
398 mouse_handler(); //temp
400 for (i = 0; i < MOUSE_MAX_BUTTONS; i++) {
401 if (Mouse.pressed[i])
408 /* This should be replaced with mouse_button_down_count(int button) */
409 int mouse_went_down(int button)
413 if (!Mouse_installed)
416 mouse_handler(); //temp
418 if ((button < 0) || (button >= MOUSE_MAX_BUTTONS))
422 count = Mouse.num_downs[button];
423 Mouse.num_downs[button] = 0;
429 // Returns how many times this button has went down since last call.
430 int mouse_button_down_count(int button)
434 if (!Mouse_installed)
437 mouse_handler(); //temp
439 if ((button < 0) || (button >= MOUSE_MAX_BUTTONS))
443 count = Mouse.num_downs[button];
444 Mouse.num_downs[button] = 0;
449 // Returns 1 if this button is currently down
450 int mouse_button_state(int button)
454 if (!Mouse_installed)
457 mouse_handler(); //temp
459 if ((button < 0) || (button >= MOUSE_MAX_BUTTONS))
463 state = Mouse.pressed[button];
468 // Returns how long this button has been down since last call.
469 fix mouse_button_down_time(int button)
473 if (!Mouse_installed)
476 mouse_handler(); //temp
478 if ((button < 0) || (button >= MOUSE_MAX_BUTTONS))
482 if (!Mouse.pressed[button]) {
483 time_down = Mouse.time_held_down[button];
484 Mouse.time_held_down[button] = 0;
486 time = timer_get_fixed_seconds();
487 time_down = time - Mouse.time_held_down[button];
488 Mouse.time_held_down[button] = 0;
495 void mouse_get_cyberman_pos( int *x, int *y )
501 //WHS: I made this :)
513 /* New mouse pointer stuff for GGI/DGA */
514 //#include "cursor.h" /* cursor and mask */
516 typedef struct Sprite {
523 //Sprite mouse_sprite = { cursor_width, cursor_height, cursor_bits, cursor_mask_bits};
525 //byte *behind_mouse;
526 //byte behind_mouse[cursor_width*cursor_height];
534 void EraseMouse(void)
538 //Should add a mode, relative, absolute
541 //void MoveMouse(int mode, int x, int y) {
543 void MoveMouse(int x, int y)