]> icculus.org git repositories - taylor/freespace2.git/blob - src/io/mouse.cpp
Freespace 1 support
[taylor/freespace2.git] / src / io / mouse.cpp
1 /*
2  * Copyright (C) Volition, Inc. 1999.  All rights reserved.
3  *
4  * All source code herein is the property of Volition, Inc. You may not sell 
5  * or otherwise commercially exploit the source or things you created based on
6  * the source.
7  */
8
9 /*
10  * $Logfile: /Freespace2/code/Io/Mouse.cpp $
11  * $Revision$
12  * $Date$
13  * $Author$
14  *
15  * Routines to read the mouse.
16  *
17  * $Log$
18  * Revision 1.7  2003/05/25 02:30:42  taylor
19  * Freespace 1 support
20  *
21  * Revision 1.6  2002/07/13 06:46:48  theoddone33
22  * Warning cleanups
23  *
24  * Revision 1.5  2002/06/09 04:41:22  relnev
25  * added copyright header
26  *
27  * Revision 1.4  2002/06/02 04:26:34  relnev
28  * warning cleanup
29  *
30  * Revision 1.3  2002/05/29 06:25:13  theoddone33
31  * Keyboard input, mouse tracking now work
32  *
33  * Revision 1.2  2002/05/07 03:16:46  theoddone33
34  * The Great Newline Fix
35  *
36  * Revision 1.1.1.1  2002/05/03 03:28:09  root
37  * Initial import.
38  *
39  * 
40  * 4     7/15/99 9:20a Andsager
41  * FS2_DEMO initial checkin
42  * 
43  * 3     6/02/99 6:18p Dave
44  * Fixed TNT lockup problems! Wheeeee!
45  * 
46  * 2     10/07/98 10:53a Dave
47  * Initial checkin.
48  * 
49  * 1     10/07/98 10:49a Dave
50  * 
51  * 29    6/10/98 2:52p Hoffoss
52  * Made mouse code use DI by default, but fall back on normal code if that
53  * fails.
54  * 
55  * 28    5/24/98 1:35p Hoffoss
56  * Fixed bug where  mouse cursor is always recentering with a
57  * mouse_flush() call in debug version.
58  * 
59  * 27    5/22/98 4:50p Hoffoss
60  * Trying to fix mouse acceleration problem..
61  * 
62  * 26    5/21/98 12:26p Lawrance
63  * Fixed mouse jerk at mission start while in debug build only.
64  * 
65  * 25    5/15/98 2:41p Hoffoss
66  * Made mouse default to off (for flying ship) and fixed some new pilot
67  * init bugs.
68  * 
69  * 24    5/08/98 4:13p Hoffoss
70  * Fixed problem with mouse pointer centering causing lost keypresses.
71  * 
72  * 23    5/07/98 6:58p Hoffoss
73  * Made changes to mouse code to fix a number of problems.
74  * 
75  * 22    5/05/98 8:38p Hoffoss
76  * Added sensitivity adjustment to options menu and made it save to pilot
77  * file.
78  * 
79  * 21    5/05/98 1:03p Hoffoss
80  * Fixed initialization bug.
81  * 
82  * 20    5/01/98 5:45p Hoffoss
83  * Made further improvements to the mouse code.
84  * 
85  * 19    5/01/98 3:35p Hoffoss
86  * Made changes to release version of mouse code.
87  * 
88  * 18    5/01/98 1:14p Hoffoss
89  * Changed mouse usage so directInput is only used for release version.
90  * 
91  * 17    4/30/98 5:40p Hoffoss
92  * Added mouse as a supported control to fly the ship.
93  * 
94  * 16    4/29/98 12:13a Lawrance
95  * Add function to check down count of mouse button without reseting the
96  * internal count.  Added hook to reset demo trailer timer when a button
97  * is pressed.
98  * 
99  * 15    4/02/98 5:26p John
100  * 
101  * 14    1/19/98 6:15p John
102  * Fixed all my Optimized Build compiler warnings
103  * 
104  * 13    12/04/97 3:47p John
105  * Made joystick move mouse cursor
106  * 
107  * 12    11/20/97 5:36p Dave
108  * Hooked in a bunch of main hall changes (including sound). Made it
109  * possible to reposition (rewind/ffwd) 
110  * sound buffer pointers. Fixed animation direction change framerate
111  * problem.
112  * 
113  * 11    5/12/97 11:41a John
114  * Added range checking to mouse position
115  * 
116  * 10    4/22/97 5:55p Lawrance
117  * let mouse.cpp decide if mouse has moved
118  * 
119  * 9     4/22/97 12:29p John
120  * Changed mouse code so that you have to call mouse_init for the mouse
121  * stuff to work.
122  * 
123  * 8     4/22/97 10:56a John
124  * fixed some resource leaks.
125  * 
126  * 7     3/26/97 10:52a Lawrance
127  * mouse always on in menus, disappears in gameplay after 1 second
128  * 
129  * 6     3/11/97 1:37p Lawrance
130  * added mouse_up_count(), changed mouse_mark() to mouse_mark_button() &
131  * mouse_mark_move()
132  * 
133  * 5     12/09/96 1:29p Lawrance
134  * adding 3 button support
135  * 
136  * 4     12/03/96 4:19p John
137  * Added some code so that holding down the mouse buttons between menus
138  * doesn't select the next menu.
139  *
140  * $NoKeywords: $
141  */
142
143 #ifndef PLAT_UNIX
144 #include <windows.h>
145 #include <windowsx.h>
146 #endif
147
148 #include "mouse.h"
149 #include "2d.h"
150 #include "osapi.h"
151
152 #define MOUSE_MODE_DI   0
153 #define MOUSE_MODE_WIN  1
154
155 #ifdef NDEBUG
156 LOCAL int Mouse_mode = MOUSE_MODE_DI;
157 #else
158 LOCAL int Mouse_mode = MOUSE_MODE_WIN;
159 #endif
160
161 LOCAL int mouse_inited = 0;
162 #ifndef PLAT_UNIX
163 LOCAL int Di_mouse_inited = 0;
164 #endif
165 LOCAL int Mouse_x;
166 LOCAL int Mouse_y;
167
168 CRITICAL_SECTION mouse_lock;
169
170 // #define USE_DIRECTINPUT
171
172 int mouse_flags;
173 int mouse_left_pressed = 0;
174 int mouse_right_pressed = 0;
175 int mouse_middle_pressed = 0;
176 int mouse_left_up = 0;
177 int mouse_right_up = 0;
178 int mouse_middle_up = 0;
179 int Mouse_dx = 0;
180 int Mouse_dy = 0;
181 int Mouse_dz = 0;
182
183 int Mouse_sensitivity = 4;
184 int Use_mouse_to_fly = 0;
185 int Mouse_hidden = 0;
186 int Keep_mouse_centered = 0;;
187
188 int di_init();
189 void di_cleanup();
190 void mouse_force_pos(int x, int y);
191 void mouse_eval_deltas_di();
192
193 int mouse_is_visible()
194 {
195         return !Mouse_hidden;
196 }
197
198 void mouse_close()
199 {
200         if (!mouse_inited)
201                 return;
202
203 #ifdef USE_DIRECTINPUT
204         di_cleanup();
205 #endif
206         mouse_inited = 0;
207 #ifdef PLAT_UNIX
208         STUB_FUNCTION;
209 #else
210         DeleteCriticalSection( &mouse_lock );
211 #endif
212 }
213
214 void mouse_init()
215 {
216         // Initialize queue
217         if ( mouse_inited ) return;
218         mouse_inited = 1;
219
220 #ifdef PLAT_UNIX
221         STUB_FUNCTION;
222 #else
223         InitializeCriticalSection( &mouse_lock );
224 #endif
225
226         ENTER_CRITICAL_SECTION(&mouse_lock);
227
228         mouse_flags = 0;
229         Mouse_x = gr_screen.max_w / 2;
230         Mouse_y = gr_screen.max_h / 2;
231
232 #ifdef USE_DIRECTINPUT
233         if (!di_init())
234                 Mouse_mode = MOUSE_MODE_WIN;
235 #else
236         Mouse_mode = MOUSE_MODE_WIN;
237 #endif
238
239         LEAVE_CRITICAL_SECTION(&mouse_lock);    
240
241         atexit( mouse_close );
242 }
243
244
245 // ----------------------------------------------------------------------------
246 // mouse_mark_button() is called asynchronously by the OS when a mouse button
247 // goes up or down.  The mouse button that is affected is passed via the 
248 // flags parameter.  
249 //
250 // parameters:   flags ==> mouse button pressed/released
251 //               set   ==> 1 - button is pressed
252 //                         0 - button is released
253
254 void mouse_mark_button( uint flags, int set)
255 {
256         if ( !mouse_inited ) return;
257
258         ENTER_CRITICAL_SECTION(&mouse_lock);
259
260         if ( !(mouse_flags & MOUSE_LEFT_BUTTON) )       {
261
262                 if ( (flags & MOUSE_LEFT_BUTTON) && (set == 1) ) {
263                         mouse_left_pressed++;
264
265 ////////////////////////////
266 /// SOMETHING TERRIBLE IS ABOUT TO HAPPEN.  I FEEL THIS IS NECESSARY FOR THE DEMO, SINCE
267 /// I DON'T WANT TO CALL CRITICAL SECTION CODE EACH FRAME TO CHECK THE LEFT MOUSE BUTTON.
268 /// PLEASE SEE ALAN FOR MORE INFORMATION.
269 ////////////////////////////
270 #if defined(FS2_DEMO) || defined(FS1_DEMO)
271                                         {
272                                         extern void demo_reset_trailer_timer();
273                                         demo_reset_trailer_timer();
274                                         }
275 #endif
276 ////////////////////////////
277 /// IT'S OVER.  SEE, IT WASN'T SO BAD RIGHT?  IT'S IS VERY UGLY LOOKING, I KNOW.
278 ////////////////////////////
279
280                 }
281         }
282         else {
283                 if ( (flags & MOUSE_LEFT_BUTTON) && (set == 0) ){
284                         mouse_left_up++;
285                 }
286         }
287
288         if ( !(mouse_flags & MOUSE_RIGHT_BUTTON) )      {
289
290                 if ( (flags & MOUSE_RIGHT_BUTTON) && (set == 1) ){
291                         mouse_right_pressed++;
292                 }
293         }
294         else {
295                 if ( (flags & MOUSE_RIGHT_BUTTON) && (set == 0) ){
296                         mouse_right_up++;
297                 }
298         }
299
300         if ( !(mouse_flags & MOUSE_MIDDLE_BUTTON) )     {
301
302                 if ( (flags & MOUSE_MIDDLE_BUTTON) && (set == 1) ){
303                         mouse_middle_pressed++;
304                 }
305         }
306         else {
307                 if ( (flags & MOUSE_MIDDLE_BUTTON) && (set == 0) ){
308                         mouse_middle_up++;
309                 }
310         }
311
312         if ( set ){
313                 mouse_flags |= flags;
314         } else {
315                 mouse_flags &= ~flags;
316         }
317
318         LEAVE_CRITICAL_SECTION(&mouse_lock);    
319 }
320
321 void mouse_flush()
322 {
323         if (!mouse_inited)
324                 return;
325
326         mouse_eval_deltas();
327         Mouse_dx = Mouse_dy = Mouse_dz = 0;
328         ENTER_CRITICAL_SECTION(&mouse_lock);
329         mouse_left_pressed = 0;
330         mouse_right_pressed = 0;
331         mouse_middle_pressed = 0;
332         mouse_flags = 0;
333         LEAVE_CRITICAL_SECTION(&mouse_lock);    
334 }
335
336 int mouse_down_count(int n, int reset_count)
337 {
338         int tmp = 0;
339         if ( !mouse_inited ) return 0;
340
341         if ( (n < LOWEST_MOUSE_BUTTON) || (n > HIGHEST_MOUSE_BUTTON)) return 0;
342
343         ENTER_CRITICAL_SECTION(&mouse_lock);
344
345         switch (n) {
346                 case MOUSE_LEFT_BUTTON:
347                         tmp = mouse_left_pressed;
348                         if ( reset_count ) {
349                                 mouse_left_pressed = 0;
350                         }
351                         break;
352
353                 case MOUSE_RIGHT_BUTTON:
354                         tmp = mouse_right_pressed;
355                         if ( reset_count ) {
356                                 mouse_right_pressed = 0;
357                         }
358                         break;
359
360                 case MOUSE_MIDDLE_BUTTON:
361                         tmp = mouse_middle_pressed;
362                         if ( reset_count ) {
363                                 mouse_middle_pressed = 0;
364                         }
365                         break;
366         } // end switch
367
368         LEAVE_CRITICAL_SECTION(&mouse_lock);    
369
370         return tmp;
371 }
372
373 // mouse_up_count() returns the number of times button n has gone from down to up
374 // since the last call
375 //
376 // parameters:  n - button of mouse (see #define's in mouse.h)
377 //
378 int mouse_up_count(int n)
379 {
380         int tmp = 0;
381         if ( !mouse_inited ) return 0;
382
383         if ( (n < LOWEST_MOUSE_BUTTON) || (n > HIGHEST_MOUSE_BUTTON)) return 0;
384
385         ENTER_CRITICAL_SECTION(&mouse_lock);
386
387         switch (n) {
388                 case MOUSE_LEFT_BUTTON:
389                         tmp = mouse_left_up;
390                         mouse_left_up = 0;
391                         break;
392
393                 case MOUSE_RIGHT_BUTTON:
394                         tmp = mouse_right_up;
395                         mouse_right_up = 0;
396                         break;
397
398                 case MOUSE_MIDDLE_BUTTON:
399                         tmp = mouse_middle_up;
400                         mouse_middle_up = 0;
401                         break;
402
403                 default:
404                         Assert(0);      // can't happen
405                         break;
406         } // end switch
407
408         LEAVE_CRITICAL_SECTION(&mouse_lock);    
409
410         return tmp;
411 }
412
413 // returns 1 if mouse button btn is down, 0 otherwise
414
415 int mouse_down(int btn)
416 {
417         int tmp;
418         if ( !mouse_inited ) return 0;
419
420         if ( (btn < LOWEST_MOUSE_BUTTON) || (btn > HIGHEST_MOUSE_BUTTON)) return 0;
421
422
423         ENTER_CRITICAL_SECTION(&mouse_lock);
424
425
426         if ( mouse_flags & btn )
427                 tmp = 1;
428         else
429                 tmp = 0;
430
431         LEAVE_CRITICAL_SECTION(&mouse_lock);    
432
433         return tmp;
434 }
435
436 // returns the fraction of time btn has been down since last call 
437 // (currently returns 1 if buttons is down, 0 otherwise)
438 //
439 float mouse_down_time(int btn)
440 {
441         float tmp;
442         if ( !mouse_inited ) return 0.0f;
443
444         if ( (btn < LOWEST_MOUSE_BUTTON) || (btn > HIGHEST_MOUSE_BUTTON)) return 0.0f;
445
446         ENTER_CRITICAL_SECTION(&mouse_lock);
447
448         if ( mouse_flags & btn )
449                 tmp = 1.0f;
450         else
451                 tmp = 0.0f;
452
453         LEAVE_CRITICAL_SECTION(&mouse_lock);
454
455         return tmp;
456 }
457
458 void mouse_get_delta(int *dx, int *dy, int *dz)
459 {
460         if (dx)
461                 *dx = Mouse_dx;
462         if (dy)
463                 *dy = Mouse_dy;
464         if (dz)
465                 *dz = Mouse_dz;
466 }
467
468 // Forces the actual windows cursor to be at (x,y).  This may be independent of our tracked (x,y) mouse pos.
469 void mouse_force_pos(int x, int y)
470 {
471         if (os_foreground()) {  // only mess with windows's mouse if we are in control of it
472 #ifdef PLAT_UNIX
473                 SDL_WarpMouse(x, y);
474 #else
475                 POINT pnt;
476
477                 pnt.x = x;
478                 pnt.y = y;
479                 ClientToScreen((HWND) os_get_window(), &pnt);
480                 SetCursorPos(pnt.x, pnt.y);
481 #endif
482         }
483 }
484
485 #include "gamesequence.h"
486
487 // change in mouse position since last call
488 void mouse_eval_deltas()
489 {
490         static int old_x = 0;
491         static int old_y = 0;
492         int tmp_x, tmp_y, cx, cy;
493
494         Mouse_dx = Mouse_dy = Mouse_dz = 0;
495         if (!mouse_inited)
496                 return;
497
498         if (Mouse_mode == MOUSE_MODE_DI) {
499                 mouse_eval_deltas_di();
500                 return;
501         }
502
503         cx = gr_screen.max_w / 2;
504         cy = gr_screen.max_h / 2;
505
506         ENTER_CRITICAL_SECTION(&mouse_lock);
507
508 #ifdef PLAT_UNIX
509         SDL_GetMouseState (&tmp_x, &tmp_y);
510 #else
511         POINT pnt;
512         GetCursorPos(&pnt);
513         ScreenToClient((HWND)os_get_window(), &pnt);
514         tmp_x = pnt.x;
515         tmp_y = pnt.y;
516 #endif
517
518         Mouse_dx = tmp_x - old_x;
519         Mouse_dy = tmp_y - old_y;
520         Mouse_dz = 0;
521
522         if (Keep_mouse_centered && Mouse_hidden) {
523                 if (Mouse_dx || Mouse_dy)
524                         mouse_force_pos(cx, cy);
525
526                 old_x = cx;
527                 old_y = cy;
528
529         } else {
530                 old_x = tmp_x;
531                 old_y = tmp_y;
532         }
533
534         LEAVE_CRITICAL_SECTION(&mouse_lock);
535 }
536
537 #ifndef PLAT_UNIX
538 #include "vdinput.h"
539
540 static LPDIRECTINPUT                    Di_mouse_obj = NULL;
541 static LPDIRECTINPUTDEVICE      Di_mouse = NULL;
542 #endif
543
544 void mouse_eval_deltas_di()
545 {
546 #ifdef PLAT_UNIX
547         STUB_FUNCTION;
548 #else
549         int repeat = 1;
550         HRESULT hr = 0;
551         DIMOUSESTATE mouse_state;
552
553         Mouse_dx = Mouse_dy = Mouse_dz = 0;
554         if (!Di_mouse_inited)
555                 return;
556
557         repeat = 1;
558         memset(&mouse_state, 0, sizeof(mouse_state));
559         while (repeat) {
560                 repeat = 0;
561
562                 hr = Di_mouse->GetDeviceState(sizeof(mouse_state), &mouse_state);
563                 if ((hr == DIERR_INPUTLOST) || (hr == DIERR_NOTACQUIRED)) {
564                         // DirectInput is telling us that the input stream has
565                         // been interrupted.  We aren't tracking any state
566                         // between polls, so we don't have any special reset
567                         // that needs to be done.  We just re-acquire and
568                         // try again.
569                         Sleep(500);             // Pause a half second...
570                         hr = Di_mouse->Acquire();
571                         if (SUCCEEDED(hr))
572                                 repeat = 1;
573                 }
574         }
575
576         if (SUCCEEDED(hr)) {
577                 Mouse_dx = (int) mouse_state.lX;
578                 Mouse_dy = (int) mouse_state.lY;
579                 Mouse_dz = (int) mouse_state.lZ;
580
581         } else {
582                 Mouse_dx = Mouse_dy = Mouse_dz = 0;
583         }
584
585         Mouse_x += Mouse_dx;
586         Mouse_y += Mouse_dy;
587
588         if (Mouse_x < 0)
589                 Mouse_x = 0;
590
591         if (Mouse_y < 0)
592                 Mouse_y = 0;
593
594         if (Mouse_x >= gr_screen.max_w)
595                 Mouse_x = gr_screen.max_w - 1;
596
597         if (Mouse_y >= gr_screen.max_h)
598                 Mouse_y = gr_screen.max_h - 1;
599
600         // keep the mouse inside our window so we don't switch applications or anything (debug bug people reported?)
601         // JH: Dang!  This makes the mouse readings in DirectInput act screwy!
602 //      mouse_force_pos(gr_screen.max_w / 2, gr_screen.max_h / 2);
603 #endif
604 }
605
606 int mouse_get_pos(int *xpos, int *ypos)
607 {
608         int flags;
609
610         if (Mouse_mode == MOUSE_MODE_DI) {
611                 if (xpos)
612                         *xpos = Mouse_x;
613
614                 if (ypos)
615                         *ypos = Mouse_y;
616
617                 return mouse_flags;
618         }
619
620         if (!mouse_inited) {
621                 *xpos = *ypos = 0;
622                 return 0;
623         }
624
625 #ifdef PLAT_UNIX
626         flags = SDL_GetMouseState (&Mouse_x, &Mouse_y);
627         // DDOI - FIXME?
628 #else
629         POINT pnt;
630         GetCursorPos(&pnt);
631         ScreenToClient((HWND)os_get_window(), &pnt);
632
633 //      EnterCriticalSection(&mouse_lock);
634
635         flags = mouse_flags;
636         Mouse_x = pnt.x;
637         Mouse_y = pnt.y;
638 #endif
639
640 //      LeaveCriticalSection(&mouse_lock);
641
642         if (Mouse_x < 0){
643                 Mouse_x = 0;
644         }
645
646         if (Mouse_y < 0){
647                 Mouse_y = 0;
648         }
649
650         if (Mouse_x >= gr_screen.max_w){
651                 Mouse_x = gr_screen.max_w - 1;
652         }
653
654         if (Mouse_y >= gr_screen.max_h){
655                 Mouse_y = gr_screen.max_h - 1;
656         }
657         
658         if (xpos){
659                 *xpos = Mouse_x;
660         }
661
662         if (ypos){
663                 *ypos = Mouse_y;
664         }
665
666         return flags;
667 }
668
669 void mouse_get_real_pos(int *mx, int *my)
670 {
671         if (Mouse_mode == MOUSE_MODE_DI) {
672                 *mx = Mouse_x;
673                 *my = Mouse_y;
674                 return;
675         }
676
677 #ifdef PLAT_UNIX
678         SDL_GetMouseState (mx, my);
679 #else
680         POINT pnt;
681         GetCursorPos(&pnt);
682         ScreenToClient((HWND)os_get_window(), &pnt);
683         
684         *mx = pnt.x;
685         *my = pnt.y;
686 #endif
687 }
688
689 void mouse_set_pos(int xpos, int ypos)
690 {
691         if (Mouse_mode == MOUSE_MODE_DI) {
692                 Mouse_x = xpos;
693                 Mouse_y = ypos;
694                 return;
695         }
696
697         if ((xpos != Mouse_x) || (ypos != Mouse_y)){
698                 mouse_force_pos(xpos, ypos);
699         }
700 }
701
702 int di_init()
703 {
704 #ifdef PLAT_UNIX
705         STUB_FUNCTION;
706         return 0;
707 #else
708         HRESULT hr;
709
710         if (Mouse_mode == MOUSE_MODE_WIN){
711                 return 0;
712         }
713
714         Di_mouse_inited = 0;
715         hr = DirectInputCreate(GetModuleHandle(NULL), DIRECTINPUT_VERSION, &Di_mouse_obj, NULL);
716         if (FAILED(hr)) {
717                 hr = DirectInputCreate(GetModuleHandle(NULL), 0x300, &Di_mouse_obj, NULL);
718                 if (FAILED(hr)) {
719                         mprintf(( "DirectInputCreate() failed!\n" ));
720                         return FALSE;
721                 }
722         }
723
724         hr = Di_mouse_obj->CreateDevice(GUID_SysMouse, &Di_mouse, NULL);
725         if (FAILED(hr)) {
726                 mprintf(( "CreateDevice() failed!\n" ));
727                 return FALSE;
728         }
729
730         hr = Di_mouse->SetDataFormat(&c_dfDIMouse);
731         if (FAILED(hr)) {
732                 mprintf(( "SetDataFormat() failed!\n" ));
733                 return FALSE;
734         }
735
736         hr = Di_mouse->SetCooperativeLevel((HWND)os_get_window(), DISCL_NONEXCLUSIVE | DISCL_FOREGROUND);
737         if (FAILED(hr)) {
738                 mprintf(( "SetCooperativeLevel() failed!\n" ));
739                 return FALSE;
740         }
741 /*
742         DIPROPDWORD hdr;
743
744         // Turn on buffering
745         hdr.diph.dwSize = sizeof(DIPROPDWORD); 
746         hdr.diph.dwHeaderSize = sizeof(DIPROPHEADER);
747         hdr.diph.dwObj = 0;             
748         hdr.diph.dwHow = DIPH_DEVICE;   // Apply to entire device
749         hdr.dwData = 16;        //MAX_BUFFERED_KEYBOARD_EVENTS;
750
751         hr = Di_mouse->SetProperty( DIPROP_BUFFERSIZE, &hdr.diph );
752         if (FAILED(hr)) {
753                 mprintf(( "SetProperty DIPROP_BUFFERSIZE failed\n" ));
754                 return FALSE;
755         }
756
757         Di_event = CreateEvent( NULL, FALSE, FALSE, NULL );
758         Assert(Di_event != NULL);
759
760         hr = Di_mouse->SetEventNotification(Di_event);
761         if (FAILED(hr)) {
762                 mprintf(( "SetEventNotification failed\n" ));
763                 return FALSE;
764         }
765 */
766         Di_mouse->Acquire();
767
768         Di_mouse_inited = 1;
769         return TRUE;
770 #endif
771 }
772
773 void di_cleanup()
774 {
775 #ifdef PLAT_UNIX
776         STUB_FUNCTION;
777 #else
778         // Destroy any lingering IDirectInputDevice object.
779         if (Di_mouse) {
780                 // Unacquire the device one last time just in case we got really confused
781                 // and tried to exit while the device is still acquired.
782                 Di_mouse->Unacquire();
783
784                 Di_mouse->Release();
785                 Di_mouse = NULL;
786         }
787
788         // Destroy any lingering IDirectInput object.
789         if (Di_mouse_obj) {
790                 Di_mouse_obj->Release();
791                 Di_mouse_obj = NULL;
792         }
793
794         Di_mouse_inited = 0;
795 #endif
796 }
797