]> icculus.org git repositories - btb/d2x.git/blob - arch/win32/mouse.c
remove rcs tags
[btb/d2x.git] / arch / win32 / 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  * Functions to access Mouse and Cyberman...
16  *
17  */
18
19 #define WIN32_LEAN_AND_MEAN
20 #include <dinput.h>
21
22
23 #include <stdlib.h>
24 #include <stdio.h>
25 #include <string.h>
26
27 #include "error.h"
28 #include "fix.h"
29 #include "mouse.h"
30 #include "mono.h"
31 #include "timer.h"
32 #include "args.h"
33
34 // These are to kludge up a bit my slightly broken GCC directx port.
35 #ifndef E_FAIL
36 #define E_FAIL (HRESULT)0x80004005L
37 #endif
38 #ifndef SUCCEEDED
39 #define SUCCEEDED(a) ((HRESULT)(a) >= 0)
40 #endif
41 #ifndef S_OK
42 #define S_OK 0
43 #define S_FALSE 1
44 #endif
45 #ifndef SEVERITY_SUCCESS
46 #define SEVERITY_SUCCESS    0
47 #define SEVERITY_ERROR      1
48 #endif
49 #ifndef FACILITY_WIN32
50 #define FACILITY_WIN32                   7
51 #endif
52 #ifndef FIELD_OFFSET
53 #define FIELD_OFFSET(type, field)    ((LONG)&(((type *)0)->field))
54 #endif
55
56 #define ME_CURSOR_MOVED (1<<0)
57 #define ME_LB_P                 (1<<1)
58 #define ME_LB_R                 (1<<2)
59 #define ME_RB_P                 (1<<3)
60 #define ME_RB_R                 (1<<4)
61 #define ME_MB_P                 (1<<5)
62 #define ME_MB_R                 (1<<6)
63 #define ME_OB_P                 (1<<7)
64 #define ME_OB_R                 (1<<8)
65 #define ME_X_C                  (1<<9)
66 #define ME_Y_C                  (1<<10)
67 #define ME_Z_C                  (1<<11)
68 #define ME_P_C                  (1<<12)
69 #define ME_B_C                  (1<<13)
70 #define ME_H_C                  (1<<14)
71 #define ME_O_C                  (1<<15)
72
73 typedef struct event_info {
74         short x;
75         short y;
76         short z;
77         short pitch;
78         short bank;
79         short heading;
80         ushort button_status;
81         ushort device_dependant;
82 } event_info;
83
84 typedef struct mouse_info {
85         fix             ctime;
86         ubyte   cyberman;
87         int             num_buttons;
88         ubyte   pressed[MOUSE_MAX_BUTTONS];
89         fix             time_went_down[MOUSE_MAX_BUTTONS];
90         fix             time_held_down[MOUSE_MAX_BUTTONS];
91         uint    num_downs[MOUSE_MAX_BUTTONS];
92         uint    num_ups[MOUSE_MAX_BUTTONS];
93         //      ubyte   went_down; /* Not in PC version, not needed with 'num_downs' etc */
94         event_info *x_info;
95         ushort  button_status;
96 } mouse_info;
97
98 typedef struct cyberman_info {
99         ubyte device_type;
100         ubyte major_version;
101         ubyte minor_version;
102         ubyte x_descriptor;
103         ubyte y_descriptor;
104         ubyte z_descriptor;
105         ubyte pitch_descriptor;
106         ubyte roll_descriptor;
107         ubyte yaw_descriptor;
108         ubyte reserved;
109 } cyberman_info;
110
111 static mouse_info Mouse;
112
113 static int Mouse_installed = 0;
114
115 int WMMouse_Handler_Ready = 0;
116 int mouse_wparam, mouse_lparam, mouse_msg;
117
118
119 //GGI data:
120 //extern  ggi_visual_t          visual;
121 //extern  ggi_directbuffer_t            dbuf;   // GGI direct acces to screen memory
122 //extern  ggi_pixellinearbuffer *plb;
123
124 //Mouse globals
125 static double mouse_x, mouse_y;
126 static double mouse_saved_x, mouse_saved_y; //used when hiding/unhiding to reset the real (displayed) postion
127 double mouse_accel=1.0;
128
129 void DrawMouse(void);
130 void EraseMouse(void);
131 void MoveMouse(/*int button,*/ int x, int y);
132
133 #define WIN_WIDTH 640
134 #define WIN_HEIGHT 480
135 #define SCR_WIDTH 640
136 #define SCR_HEIGHT 480
137
138 LPDIRECTINPUT g_lpdi = NULL;
139 LPDIRECTINPUTDEVICE g_lpdidMouse = NULL;
140 extern HWND g_hWnd;
141
142
143 HRESULT ReadMouse (DIDEVICEOBJECTDATA *pdidod)
144 {
145         DWORD cElements = 1;
146         HRESULT hr;
147
148         if (g_lpdidMouse == NULL)
149                 return E_FAIL;
150
151         hr = IDirectInputDevice_GetDeviceData (
152                 g_lpdidMouse,
153                 sizeof (*pdidod),
154                 pdidod,
155                 &cElements,
156                 0);
157
158         if (hr == DIERR_INPUTLOST)
159         {
160                 hr = IDirectInputDevice_Acquire (g_lpdidMouse);
161                 if (SUCCEEDED (hr))
162                 {
163                         hr = IDirectInputDevice_GetDeviceData (
164                                 g_lpdidMouse,
165                                 sizeof (*pdidod),
166                                 pdidod,
167                                 &cElements,
168                                 0);
169                 }
170         }
171
172         if (SUCCEEDED (hr) && cElements != 1)
173                 hr = E_FAIL;
174
175         return hr;
176 }
177
178
179 void UpdateMouseState (DIDEVICEOBJECTDATA *pdidod)
180 {
181 //        fix timeNow = timer_get_fixed_seconds ();
182
183         ULONG iEvt = pdidod->dwOfs;
184         switch (iEvt)
185         {
186                 case DIMOFS_BUTTON0:
187                 case DIMOFS_BUTTON1:
188                 case DIMOFS_BUTTON2:
189                 case DIMOFS_BUTTON3:
190                 {
191                         BOOL bPressed = pdidod->dwData & 0x80;
192                         ULONG iButton = (iEvt - DIMOFS_BUTTON0) + MB_LEFT;
193                         if (bPressed)
194                         {
195                                 if (!Mouse.pressed [iButton])
196                                 {
197                                         Mouse.pressed [iButton] = 1;
198                                         Mouse.time_went_down [iButton] = Mouse.ctime;
199                                         Mouse.num_downs [iButton]++;
200                                         //                      Mouse.went_down = 1;
201                                 }
202                                 Mouse.num_downs [iButton] ++;
203                         }
204                         else
205                         {
206                                 if (Mouse.pressed [iButton])
207                                 {
208                                         Mouse.pressed [iButton] = 0;
209                                         Mouse.time_held_down [iButton] += Mouse.ctime - Mouse.time_went_down [iButton];
210                                         Mouse.num_ups [iButton]++;
211                                         //                      Mouse.went_down = 0;
212                                 }
213                         }
214                         break;
215                 }
216                 case DIMOFS_X:
217                         mouse_x += (double) ((LONG) pdidod->dwData);
218                         break;
219
220                 case DIMOFS_Y:
221                         mouse_y += (double) ((LONG) pdidod->dwData);
222                         break;
223                 case DIMOFS_Z:
224                         break;//hm, handle this?
225                 default:
226                         mprintf((0,"unknown mouse event %i\n",iEvt));
227 //                      exit (iEvt);//not happy.
228                         break;
229         }
230 }
231
232 void mouse_handler()
233 {
234         DIDEVICEOBJECTDATA didod;
235
236         Mouse.ctime = timer_get_fixed_seconds();
237
238         while (SUCCEEDED (ReadMouse (&didod)))
239         {
240                 UpdateMouseState (&didod);
241         }
242 }
243
244 void mouse_flush()
245 {
246         int i;
247         fix CurTime;
248         
249         if (!Mouse_installed)
250                 return;
251
252         mouse_handler();
253         //      _disable();
254         CurTime = timer_get_fixed_seconds();
255         for (i = 0; i < MOUSE_MAX_BUTTONS; i++) {
256                 Mouse.pressed[i] = 0;
257                 Mouse.time_went_down[i] = CurTime;
258                 Mouse.time_held_down[i] = 0;
259                 Mouse.num_downs[i] = 0;
260                 Mouse.num_ups[i] = 0;
261         }
262         //      Mouse.went_down = 0; /* mac only */
263         //      _enable();
264
265         {
266                 DWORD cElements = INFINITE;
267 //                HRESULT hr =
268                 IDirectInputDevice_GetDeviceData (
269                         g_lpdidMouse,
270                         sizeof (DIDEVICEOBJECTDATA),
271                         NULL,
272                         &cElements,
273                         0);
274         }
275 }
276
277
278 void mouse_close(void)
279 {
280         //      if (Mouse_installed)   // DPH: Unnecessary...
281         WMMouse_Handler_Ready=Mouse_installed = 0;
282
283         if (g_lpdidMouse != NULL)
284         {
285                 IDirectInputDevice_Unacquire (g_lpdidMouse);
286                 IDirectInputDevice_Release (g_lpdidMouse);
287                 g_lpdidMouse = NULL;
288         }
289         if (g_lpdi != NULL)
290         {
291                 IDirectInput_Release (g_lpdi);
292                 g_lpdi = NULL;
293         }
294 }
295
296
297
298 int mouse_init(int unused)
299 {
300         if (FindArg("-nomouse"))
301                 return 0;
302         if (Mouse_installed)
303                 return Mouse.num_buttons;
304         
305         {
306                 HRESULT hr;
307
308                 if (SUCCEEDED (hr = DirectInputCreate (GetModuleHandle (NULL), DIRECTINPUT_VERSION, &g_lpdi, NULL)))
309                 {
310                         if (SUCCEEDED (hr = IDirectInput_CreateDevice (g_lpdi,(void *) &GUID_SysMouse, &g_lpdidMouse, NULL)))
311                         {
312                                 DIPROPDWORD dipdw;
313                                 dipdw.diph.dwSize = sizeof (DIPROPDWORD);
314                                 dipdw.diph.dwHeaderSize = sizeof (DIPROPHEADER);
315                                 dipdw.diph.dwObj = 0;
316                                 dipdw.diph.dwHow = DIPH_DEVICE;
317                                 dipdw.dwData = 40;
318
319                                 if (SUCCEEDED (hr = IDirectInputDevice_SetDataFormat (g_lpdidMouse, &c_dfDIMouse)) &&
320                                         //changed on 9/4/99 by Victor Rachels NONEX -> Exclusive
321                                         SUCCEEDED (hr = IDirectInputDevice_SetCooperativeLevel (g_lpdidMouse, g_hWnd, DISCL_EXCLUSIVE | DISCL_FOREGROUND)) &&
322                                         //end this section edit -VR
323                                         SUCCEEDED (hr = IDirectInputDevice_SetProperty (g_lpdidMouse, DIPROP_BUFFERSIZE, &dipdw.diph)) &&
324                                         SUCCEEDED (hr = IDirectInputDevice_Acquire (g_lpdidMouse)))
325                                 {
326                                 }
327                                 else
328                                 {
329                                         IDirectInputDevice_Release (g_lpdidMouse);
330                                         g_lpdidMouse = NULL;
331                                         return 0;
332                                 }
333                         }
334                 }
335         }
336         Mouse.num_buttons = 3;
337         
338         WMMouse_Handler_Ready=Mouse_installed = 1;
339         atexit(mouse_close);
340         mouse_flush();
341         //      mouse_set_center();
342         
343         return Mouse.num_buttons;
344 }
345
346 //WHS: added this
347 void mouse_center() {
348         mouse_x=mouse_saved_x=WIN_WIDTH/2;
349         mouse_y=mouse_saved_y=WIN_HEIGHT/2;
350 }
351
352 void mouse_get_pos( int *x, int *y)
353 {
354         mouse_handler(); //temp
355         
356         *x=(int) mouse_x;
357         *y=(int) mouse_y;
358 }
359
360 void mouse_get_delta( int *dx, int *dy )
361 {
362         if (!Mouse_installed) {
363                 *dx = *dy = 0;
364                 return;
365         }
366         mouse_handler(); //temp
367         
368         *dx = (int) mouse_x - WIN_WIDTH/2;
369         *dy = (int) mouse_y - WIN_HEIGHT/2;
370         
371         //Now reset the mouse position to the center of the screen
372         mouse_x = (double) WIN_WIDTH/2;
373         mouse_y = (double) WIN_HEIGHT/2;
374 }
375
376 void mouse_get_delta_no_reset( int *dx, int *dy )
377 {
378         if (!Mouse_installed) {
379                 *dx = *dy = 0;
380                 return;
381         }
382         mouse_handler(); //temp
383         
384         *dx = (int) mouse_x - WIN_WIDTH/2;
385         *dy = (int) mouse_y - WIN_HEIGHT/2;
386 }
387
388 int mouse_get_btns()
389 {
390         int  i;
391         uint flag=1;
392         int  status = 0;
393         
394         if (!Mouse_installed)
395                 return 0;
396
397         mouse_handler(); //temp
398         
399         for (i = 0; i < MOUSE_MAX_BUTTONS; i++) {
400                 if (Mouse.pressed[i])
401                         status |= flag;
402                 flag <<= 1;
403         }
404         return status;
405 }
406
407 /* This should be replaced with mouse_button_down_count(int button)     */
408 int mouse_went_down(int button)
409 {
410         int count;
411         
412         if (!Mouse_installed)
413                 return 0;
414
415         mouse_handler(); //temp
416         
417         if ((button < 0) || (button >= MOUSE_MAX_BUTTONS))
418                 return 0;
419         
420         //      _disable();             
421         count = Mouse.num_downs[button];
422         Mouse.num_downs[button] = 0;
423         
424         //      _enable();
425         return count;
426 }
427
428 // Returns how many times this button has went down since last call.
429 int mouse_button_down_count(int button) 
430 {
431         int count;
432         
433         if (!Mouse_installed)
434                 return 0;
435         
436         mouse_handler(); //temp
437         
438         if ((button < 0) || (button >= MOUSE_MAX_BUTTONS))
439                 return 0;
440         
441         //      _disable();
442         count = Mouse.num_downs[button];
443         Mouse.num_downs[button] = 0;
444         //      _enable();
445         return count;
446 }
447
448 // Returns 1 if this button is currently down
449 int mouse_button_state(int button)
450 {
451         int state;
452         
453         if (!Mouse_installed)
454                 return 0;
455         
456         mouse_handler(); //temp
457         
458         if ((button < 0) || (button >= MOUSE_MAX_BUTTONS))
459                 return 0;
460         
461         //      _disable();
462         state = Mouse.pressed[button];
463         //      _enable();
464         return state;
465 }
466
467 // Returns how long this button has been down since last call.
468 fix mouse_button_down_time(int button)  
469 {
470         fix time_down, time;
471         
472         if (!Mouse_installed)
473                 return 0;
474
475         mouse_handler(); //temp
476         
477         if ((button < 0) || (button >= MOUSE_MAX_BUTTONS))
478                 return 0;
479         
480         //      _disable();
481         if (!Mouse.pressed[button]) {
482                 time_down = Mouse.time_held_down[button];
483                 Mouse.time_held_down[button] = 0;
484         } else {
485                 time = timer_get_fixed_seconds();
486                 time_down = time - Mouse.time_held_down[button];
487                 Mouse.time_held_down[button] = 0;
488         }
489         //      _enable();
490         
491         return time_down;
492 }
493
494 void mouse_get_cyberman_pos( int *x, int *y )
495 {
496 }
497
498
499
500 //WHS: I made this :)
501 void hide_cursor()
502 {
503         ShowCursor(FALSE);
504 }
505
506 void show_cursor()
507 {
508         ShowCursor(TRUE);
509 }
510
511
512 /* New mouse pointer stuff for GGI/DGA */
513 //#include "cursor.h" /* cursor and mask */
514
515 typedef struct Sprite {
516         ushort width;
517         ushort height;
518         byte *pixels;
519         byte *mask;
520 } Sprite;
521
522 //Sprite mouse_sprite = { cursor_width, cursor_height, cursor_bits, cursor_mask_bits};
523
524 //byte *behind_mouse;
525 //byte behind_mouse[cursor_width*cursor_height];
526
527
528 void DrawMouse(void)
529 {
530 }
531
532
533 void EraseMouse(void)
534 {
535 }
536
537 //Should add a mode, relative, absolute
538 #define MOVE_REL 0
539 #define MOVE_ABS 1
540 //void MoveMouse(int mode, int x, int y) {
541
542 void MoveMouse(int x, int y)
543 {
544 }