2 * Copyright (C) Volition, Inc. 1999. All rights reserved.
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
10 * $Logfile: /Freespace2/code/Io/Mouse.cpp $
15 * Routines to read the mouse.
18 * Revision 1.7 2003/05/25 02:30:42 taylor
21 * Revision 1.6 2002/07/13 06:46:48 theoddone33
24 * Revision 1.5 2002/06/09 04:41:22 relnev
25 * added copyright header
27 * Revision 1.4 2002/06/02 04:26:34 relnev
30 * Revision 1.3 2002/05/29 06:25:13 theoddone33
31 * Keyboard input, mouse tracking now work
33 * Revision 1.2 2002/05/07 03:16:46 theoddone33
34 * The Great Newline Fix
36 * Revision 1.1.1.1 2002/05/03 03:28:09 root
40 * 4 7/15/99 9:20a Andsager
41 * FS2_DEMO initial checkin
43 * 3 6/02/99 6:18p Dave
44 * Fixed TNT lockup problems! Wheeeee!
46 * 2 10/07/98 10:53a Dave
49 * 1 10/07/98 10:49a Dave
51 * 29 6/10/98 2:52p Hoffoss
52 * Made mouse code use DI by default, but fall back on normal code if that
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.
59 * 27 5/22/98 4:50p Hoffoss
60 * Trying to fix mouse acceleration problem..
62 * 26 5/21/98 12:26p Lawrance
63 * Fixed mouse jerk at mission start while in debug build only.
65 * 25 5/15/98 2:41p Hoffoss
66 * Made mouse default to off (for flying ship) and fixed some new pilot
69 * 24 5/08/98 4:13p Hoffoss
70 * Fixed problem with mouse pointer centering causing lost keypresses.
72 * 23 5/07/98 6:58p Hoffoss
73 * Made changes to mouse code to fix a number of problems.
75 * 22 5/05/98 8:38p Hoffoss
76 * Added sensitivity adjustment to options menu and made it save to pilot
79 * 21 5/05/98 1:03p Hoffoss
80 * Fixed initialization bug.
82 * 20 5/01/98 5:45p Hoffoss
83 * Made further improvements to the mouse code.
85 * 19 5/01/98 3:35p Hoffoss
86 * Made changes to release version of mouse code.
88 * 18 5/01/98 1:14p Hoffoss
89 * Changed mouse usage so directInput is only used for release version.
91 * 17 4/30/98 5:40p Hoffoss
92 * Added mouse as a supported control to fly the ship.
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
99 * 15 4/02/98 5:26p John
101 * 14 1/19/98 6:15p John
102 * Fixed all my Optimized Build compiler warnings
104 * 13 12/04/97 3:47p John
105 * Made joystick move mouse cursor
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
113 * 11 5/12/97 11:41a John
114 * Added range checking to mouse position
116 * 10 4/22/97 5:55p Lawrance
117 * let mouse.cpp decide if mouse has moved
119 * 9 4/22/97 12:29p John
120 * Changed mouse code so that you have to call mouse_init for the mouse
123 * 8 4/22/97 10:56a John
124 * fixed some resource leaks.
126 * 7 3/26/97 10:52a Lawrance
127 * mouse always on in menus, disappears in gameplay after 1 second
129 * 6 3/11/97 1:37p Lawrance
130 * added mouse_up_count(), changed mouse_mark() to mouse_mark_button() &
133 * 5 12/09/96 1:29p Lawrance
134 * adding 3 button support
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.
149 static int mouse_inited = 0;
151 static int mouse_flags;
152 static int mouse_left_pressed = 0;
153 static int mouse_right_pressed = 0;
154 static int mouse_middle_pressed = 0;
155 static int mouse_left_up = 0;
156 static int mouse_right_up = 0;
157 static int mouse_middle_up = 0;
161 // total mouse delta motion each game frame
162 static int Mouse_dx = 0;
163 static int Mouse_dy = 0;
164 static int Mouse_dz = 0;
165 // accumulation of mouse delta motion during each game frame
166 static int Mouse_dx_inc = 0;
167 static int Mouse_dy_inc = 0;
169 int Mouse_sensitivity = 4;
170 int Use_mouse_to_fly = 0;
171 int Mouse_hidden = 0;
172 int Keep_mouse_centered = 0;
174 void mouse_force_pos(int x, int y);
177 int mouse_is_visible()
179 return !Mouse_hidden;
199 Mouse_x = gr_screen.max_w / 2;
200 Mouse_y = gr_screen.max_h / 2;
202 atexit( mouse_close );
206 // ----------------------------------------------------------------------------
207 // mouse_mark_button() is called asynchronously by the OS when a mouse button
208 // goes up or down. The mouse button that is affected is passed via the
211 // parameters: flags ==> mouse button pressed/released
212 // set ==> 1 - button is pressed
213 // 0 - button is released
215 void mouse_mark_button( uint btn, int set)
223 case SDL_BUTTON_LEFT:
224 flags |= MOUSE_LEFT_BUTTON;
227 case SDL_BUTTON_RIGHT:
228 flags |= MOUSE_RIGHT_BUTTON;
231 case SDL_BUTTON_MIDDLE:
232 flags |= MOUSE_MIDDLE_BUTTON;
239 if ( !(mouse_flags & MOUSE_LEFT_BUTTON) ) {
241 if ( (flags & MOUSE_LEFT_BUTTON) && (set == 1) ) {
242 mouse_left_pressed++;
246 if ( (flags & MOUSE_LEFT_BUTTON) && (set == 0) ){
251 if ( !(mouse_flags & MOUSE_RIGHT_BUTTON) ) {
253 if ( (flags & MOUSE_RIGHT_BUTTON) && (set == 1) ){
254 mouse_right_pressed++;
258 if ( (flags & MOUSE_RIGHT_BUTTON) && (set == 0) ){
263 if ( !(mouse_flags & MOUSE_MIDDLE_BUTTON) ) {
265 if ( (flags & MOUSE_MIDDLE_BUTTON) && (set == 1) ){
266 mouse_middle_pressed++;
270 if ( (flags & MOUSE_MIDDLE_BUTTON) && (set == 0) ){
276 mouse_flags |= flags;
278 mouse_flags &= ~flags;
288 Mouse_dx = Mouse_dy = Mouse_dz = 0;
289 Mouse_dx_inc = Mouse_dy_inc = 0;
290 mouse_left_pressed = 0;
291 mouse_right_pressed = 0;
292 mouse_middle_pressed = 0;
296 int mouse_down_count(int n, int reset_count)
303 if ( (n < LOWEST_MOUSE_BUTTON) || (n > HIGHEST_MOUSE_BUTTON) )
307 case MOUSE_LEFT_BUTTON:
308 tmp = mouse_left_pressed;
310 mouse_left_pressed = 0;
314 case MOUSE_RIGHT_BUTTON:
315 tmp = mouse_right_pressed;
317 mouse_right_pressed = 0;
321 case MOUSE_MIDDLE_BUTTON:
322 tmp = mouse_middle_pressed;
324 mouse_middle_pressed = 0;
332 // mouse_up_count() returns the number of times button n has gone from down to up
333 // since the last call
335 // parameters: n - button of mouse (see #define's in mouse.h)
337 int mouse_up_count(int n)
344 if ( (n < LOWEST_MOUSE_BUTTON) || (n > HIGHEST_MOUSE_BUTTON) )
348 case MOUSE_LEFT_BUTTON:
353 case MOUSE_RIGHT_BUTTON:
354 tmp = mouse_right_up;
358 case MOUSE_MIDDLE_BUTTON:
359 tmp = mouse_middle_up;
364 SDL_assert(0); // can't happen
371 // returns 1 if mouse button btn is down, 0 otherwise
373 int mouse_down(int btn)
380 if ( (btn < LOWEST_MOUSE_BUTTON) || (btn > HIGHEST_MOUSE_BUTTON) )
383 if ( mouse_flags & btn )
391 // returns the fraction of time btn has been down since last call
392 // (currently returns 1 if buttons is down, 0 otherwise)
394 float mouse_down_time(int btn)
401 if ( (btn < LOWEST_MOUSE_BUTTON) || (btn > HIGHEST_MOUSE_BUTTON) )
404 if ( mouse_flags & btn )
412 void mouse_get_delta(int *dx, int *dy, int *dz)
422 // Forces the actual windows cursor to be at (x,y). This may be independent of our tracked (x,y) mouse pos.
423 void mouse_force_pos(int x, int y)
425 // only mess with windows's mouse if we are in control of it
426 if ( !os_foreground() ) {
430 int x1 = fl2i(x / gr_screen.viewport_scale_factor_x) + gr_screen.viewport_offset_x;
431 int y1 = fl2i(y / gr_screen.viewport_scale_factor_y) + gr_screen.viewport_offset_y;
433 SDL_WarpMouseInWindow(os_get_window(), x1, y1);
439 static bool Mouse_grabbed = false;
441 void mouse_grab(int grab)
444 if ( !Mouse_grabbed ) {
445 SDL_SetWindowGrab(os_get_window(), SDL_TRUE);
446 SDL_SetRelativeMouseMode(SDL_TRUE);
448 Mouse_grabbed = true;
450 } else if (Mouse_grabbed) {
451 SDL_SetWindowGrab(os_get_window(), SDL_FALSE);
452 SDL_SetRelativeMouseMode(SDL_FALSE);
454 Mouse_grabbed = false;
458 void mouse_eval_deltas()
460 Mouse_dx = Mouse_dx_inc;
461 Mouse_dy = Mouse_dy_inc;
463 Mouse_dx_inc = Mouse_dy_inc = 0;
465 // make sure mouse is bound to window if we're flying with it
466 if (Keep_mouse_centered && Mouse_hidden) {
473 int mouse_get_pos(int *xpos, int *ypos)
475 if ( !mouse_inited ) {
498 void mouse_get_real_pos(int *mx, int *my)
509 void mouse_set_pos(int xpos, int ypos)
511 if ((xpos != Mouse_x) || (ypos != Mouse_y)){
512 mouse_force_pos(xpos, ypos);
516 void mouse_update_pos(int x, int y, int dx, int dy)
518 int x1 = fl2i((x - gr_screen.viewport_offset_x) * gr_screen.viewport_scale_factor_x);
519 int y1 = fl2i((y - gr_screen.viewport_offset_y) * gr_screen.viewport_scale_factor_y);
521 CAP(x1, 0, gr_screen.max_w-1);
522 CAP(y1, 0, gr_screen.max_h-1);