]> icculus.org git repositories - btb/d2x.git/blob - arch/win32/mouse.c
use the orientation parameter of g3_draw_bitmap
[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 "dxxerror.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 //Mouse globals
120 static double mouse_x, mouse_y;
121 static double mouse_saved_x, mouse_saved_y; //used when hiding/unhiding to reset the real (displayed) postion
122 double mouse_accel=1.0;
123
124 void DrawMouse(void);
125 void EraseMouse(void);
126 void MoveMouse(/*int button,*/ int x, int y);
127
128 #define WIN_WIDTH 640
129 #define WIN_HEIGHT 480
130 #define SCR_WIDTH 640
131 #define SCR_HEIGHT 480
132
133 LPDIRECTINPUT g_lpdi = NULL;
134 LPDIRECTINPUTDEVICE g_lpdidMouse = NULL;
135 extern HWND g_hWnd;
136
137
138 HRESULT ReadMouse (DIDEVICEOBJECTDATA *pdidod)
139 {
140         DWORD cElements = 1;
141         HRESULT hr;
142
143         if (g_lpdidMouse == NULL)
144                 return E_FAIL;
145
146         hr = IDirectInputDevice_GetDeviceData (
147                 g_lpdidMouse,
148                 sizeof (*pdidod),
149                 pdidod,
150                 &cElements,
151                 0);
152
153         if (hr == DIERR_INPUTLOST)
154         {
155                 hr = IDirectInputDevice_Acquire (g_lpdidMouse);
156                 if (SUCCEEDED (hr))
157                 {
158                         hr = IDirectInputDevice_GetDeviceData (
159                                 g_lpdidMouse,
160                                 sizeof (*pdidod),
161                                 pdidod,
162                                 &cElements,
163                                 0);
164                 }
165         }
166
167         if (SUCCEEDED (hr) && cElements != 1)
168                 hr = E_FAIL;
169
170         return hr;
171 }
172
173
174 void UpdateMouseState (DIDEVICEOBJECTDATA *pdidod)
175 {
176 //        fix timeNow = timer_get_fixed_seconds ();
177
178         ULONG iEvt = pdidod->dwOfs;
179         switch (iEvt)
180         {
181                 case DIMOFS_BUTTON0:
182                 case DIMOFS_BUTTON1:
183                 case DIMOFS_BUTTON2:
184                 case DIMOFS_BUTTON3:
185                 {
186                         BOOL bPressed = pdidod->dwData & 0x80;
187                         ULONG iButton = (iEvt - DIMOFS_BUTTON0) + MB_LEFT;
188                         if (bPressed)
189                         {
190                                 if (!Mouse.pressed [iButton])
191                                 {
192                                         Mouse.pressed [iButton] = 1;
193                                         Mouse.time_went_down [iButton] = Mouse.ctime;
194                                         Mouse.num_downs [iButton]++;
195                                         //                      Mouse.went_down = 1;
196                                 }
197                                 Mouse.num_downs [iButton] ++;
198                         }
199                         else
200                         {
201                                 if (Mouse.pressed [iButton])
202                                 {
203                                         Mouse.pressed [iButton] = 0;
204                                         Mouse.time_held_down [iButton] += Mouse.ctime - Mouse.time_went_down [iButton];
205                                         Mouse.num_ups [iButton]++;
206                                         //                      Mouse.went_down = 0;
207                                 }
208                         }
209                         break;
210                 }
211                 case DIMOFS_X:
212                         mouse_x += (double) ((LONG) pdidod->dwData);
213                         break;
214
215                 case DIMOFS_Y:
216                         mouse_y += (double) ((LONG) pdidod->dwData);
217                         break;
218                 case DIMOFS_Z:
219                         break;//hm, handle this?
220                 default:
221                         mprintf((0,"unknown mouse event %i\n",iEvt));
222 //                      exit (iEvt);//not happy.
223                         break;
224         }
225 }
226
227 void mouse_handler()
228 {
229         DIDEVICEOBJECTDATA didod;
230
231         Mouse.ctime = timer_get_fixed_seconds();
232
233         while (SUCCEEDED (ReadMouse (&didod)))
234         {
235                 UpdateMouseState (&didod);
236         }
237 }
238
239 void mouse_flush()
240 {
241         int i;
242         fix CurTime;
243         
244         if (!Mouse_installed)
245                 return;
246
247         mouse_handler();
248         //      _disable();
249         CurTime = timer_get_fixed_seconds();
250         for (i = 0; i < MOUSE_MAX_BUTTONS; i++) {
251                 Mouse.pressed[i] = 0;
252                 Mouse.time_went_down[i] = CurTime;
253                 Mouse.time_held_down[i] = 0;
254                 Mouse.num_downs[i] = 0;
255                 Mouse.num_ups[i] = 0;
256         }
257         //      Mouse.went_down = 0; /* mac only */
258         //      _enable();
259
260         {
261                 DWORD cElements = INFINITE;
262 //                HRESULT hr =
263                 IDirectInputDevice_GetDeviceData (
264                         g_lpdidMouse,
265                         sizeof (DIDEVICEOBJECTDATA),
266                         NULL,
267                         &cElements,
268                         0);
269         }
270 }
271
272
273 void mouse_close(void)
274 {
275         //      if (Mouse_installed)   // DPH: Unnecessary...
276         WMMouse_Handler_Ready=Mouse_installed = 0;
277
278         if (g_lpdidMouse != NULL)
279         {
280                 IDirectInputDevice_Unacquire (g_lpdidMouse);
281                 IDirectInputDevice_Release (g_lpdidMouse);
282                 g_lpdidMouse = NULL;
283         }
284         if (g_lpdi != NULL)
285         {
286                 IDirectInput_Release (g_lpdi);
287                 g_lpdi = NULL;
288         }
289 }
290
291
292
293 int mouse_init(int unused)
294 {
295         if (FindArg("-nomouse"))
296                 return 0;
297         if (Mouse_installed)
298                 return Mouse.num_buttons;
299         
300         {
301                 HRESULT hr;
302
303                 if (SUCCEEDED (hr = DirectInputCreate (GetModuleHandle (NULL), DIRECTINPUT_VERSION, &g_lpdi, NULL)))
304                 {
305                         if (SUCCEEDED (hr = IDirectInput_CreateDevice (g_lpdi,(void *) &GUID_SysMouse, &g_lpdidMouse, NULL)))
306                         {
307                                 DIPROPDWORD dipdw;
308                                 dipdw.diph.dwSize = sizeof (DIPROPDWORD);
309                                 dipdw.diph.dwHeaderSize = sizeof (DIPROPHEADER);
310                                 dipdw.diph.dwObj = 0;
311                                 dipdw.diph.dwHow = DIPH_DEVICE;
312                                 dipdw.dwData = 40;
313
314                                 if (SUCCEEDED (hr = IDirectInputDevice_SetDataFormat (g_lpdidMouse, &c_dfDIMouse)) &&
315                                         //changed on 9/4/99 by Victor Rachels NONEX -> Exclusive
316                                         SUCCEEDED (hr = IDirectInputDevice_SetCooperativeLevel (g_lpdidMouse, g_hWnd, DISCL_EXCLUSIVE | DISCL_FOREGROUND)) &&
317                                         //end this section edit -VR
318                                         SUCCEEDED (hr = IDirectInputDevice_SetProperty (g_lpdidMouse, DIPROP_BUFFERSIZE, &dipdw.diph)) &&
319                                         SUCCEEDED (hr = IDirectInputDevice_Acquire (g_lpdidMouse)))
320                                 {
321                                 }
322                                 else
323                                 {
324                                         IDirectInputDevice_Release (g_lpdidMouse);
325                                         g_lpdidMouse = NULL;
326                                         return 0;
327                                 }
328                         }
329                 }
330         }
331         Mouse.num_buttons = 3;
332         
333         WMMouse_Handler_Ready=Mouse_installed = 1;
334         atexit(mouse_close);
335         mouse_flush();
336         //      mouse_set_center();
337         
338         return Mouse.num_buttons;
339 }
340
341 //WHS: added this
342 void mouse_center() {
343         mouse_x=mouse_saved_x=WIN_WIDTH/2;
344         mouse_y=mouse_saved_y=WIN_HEIGHT/2;
345 }
346
347 void mouse_get_pos( int *x, int *y)
348 {
349         mouse_handler(); //temp
350         
351         *x=(int) mouse_x;
352         *y=(int) mouse_y;
353 }
354
355 void mouse_get_delta( int *dx, int *dy )
356 {
357         if (!Mouse_installed) {
358                 *dx = *dy = 0;
359                 return;
360         }
361         mouse_handler(); //temp
362         
363         *dx = (int) mouse_x - WIN_WIDTH/2;
364         *dy = (int) mouse_y - WIN_HEIGHT/2;
365         
366         //Now reset the mouse position to the center of the screen
367         mouse_x = (double) WIN_WIDTH/2;
368         mouse_y = (double) WIN_HEIGHT/2;
369 }
370
371 void mouse_get_delta_no_reset( int *dx, int *dy )
372 {
373         if (!Mouse_installed) {
374                 *dx = *dy = 0;
375                 return;
376         }
377         mouse_handler(); //temp
378         
379         *dx = (int) mouse_x - WIN_WIDTH/2;
380         *dy = (int) mouse_y - WIN_HEIGHT/2;
381 }
382
383 int mouse_get_btns()
384 {
385         int  i;
386         uint flag=1;
387         int  status = 0;
388         
389         if (!Mouse_installed)
390                 return 0;
391
392         mouse_handler(); //temp
393         
394         for (i = 0; i < MOUSE_MAX_BUTTONS; i++) {
395                 if (Mouse.pressed[i])
396                         status |= flag;
397                 flag <<= 1;
398         }
399         return status;
400 }
401
402 /* This should be replaced with mouse_button_down_count(int button)     */
403 int mouse_went_down(int button)
404 {
405         int count;
406         
407         if (!Mouse_installed)
408                 return 0;
409
410         mouse_handler(); //temp
411         
412         if ((button < 0) || (button >= MOUSE_MAX_BUTTONS))
413                 return 0;
414         
415         //      _disable();             
416         count = Mouse.num_downs[button];
417         Mouse.num_downs[button] = 0;
418         
419         //      _enable();
420         return count;
421 }
422
423 // Returns how many times this button has went down since last call.
424 int mouse_button_down_count(int button) 
425 {
426         int count;
427         
428         if (!Mouse_installed)
429                 return 0;
430         
431         mouse_handler(); //temp
432         
433         if ((button < 0) || (button >= MOUSE_MAX_BUTTONS))
434                 return 0;
435         
436         //      _disable();
437         count = Mouse.num_downs[button];
438         Mouse.num_downs[button] = 0;
439         //      _enable();
440         return count;
441 }
442
443 // Returns 1 if this button is currently down
444 int mouse_button_state(int button)
445 {
446         int state;
447         
448         if (!Mouse_installed)
449                 return 0;
450         
451         mouse_handler(); //temp
452         
453         if ((button < 0) || (button >= MOUSE_MAX_BUTTONS))
454                 return 0;
455         
456         //      _disable();
457         state = Mouse.pressed[button];
458         //      _enable();
459         return state;
460 }
461
462 // Returns how long this button has been down since last call.
463 fix mouse_button_down_time(int button)  
464 {
465         fix time_down, time;
466         
467         if (!Mouse_installed)
468                 return 0;
469
470         mouse_handler(); //temp
471         
472         if ((button < 0) || (button >= MOUSE_MAX_BUTTONS))
473                 return 0;
474         
475         //      _disable();
476         if (!Mouse.pressed[button]) {
477                 time_down = Mouse.time_held_down[button];
478                 Mouse.time_held_down[button] = 0;
479         } else {
480                 time = timer_get_fixed_seconds();
481                 time_down = time - Mouse.time_held_down[button];
482                 Mouse.time_held_down[button] = 0;
483         }
484         //      _enable();
485         
486         return time_down;
487 }
488
489 void mouse_get_cyberman_pos( int *x, int *y )
490 {
491 }
492
493
494
495 //WHS: I made this :)
496 void hide_cursor()
497 {
498         ShowCursor(FALSE);
499 }
500
501 void show_cursor()
502 {
503         ShowCursor(TRUE);
504 }
505
506
507 //#include "cursor.h" /* cursor and mask */
508
509 typedef struct Sprite {
510         ushort width;
511         ushort height;
512         byte *pixels;
513         byte *mask;
514 } Sprite;
515
516 //Sprite mouse_sprite = { cursor_width, cursor_height, cursor_bits, cursor_mask_bits};
517
518 //byte *behind_mouse;
519 //byte behind_mouse[cursor_width*cursor_height];
520
521
522 void DrawMouse(void)
523 {
524 }
525
526
527 void EraseMouse(void)
528 {
529 }
530
531 //Should add a mode, relative, absolute
532 #define MOVE_REL 0
533 #define MOVE_ABS 1
534 //void MoveMouse(int mode, int x, int y) {
535
536 void MoveMouse(int x, int y)
537 {
538 }