enabled mouse control of menus
[btb/d2x.git] / arch / sdl / mouse.c
1 /* $Id: mouse.c,v 1.6 2003-11-25 04:13:04 btb Exp $ */
2 /*
3  *
4  * SDL mouse driver.
5  *
6  *
7  */
8
9 #ifdef HAVE_CONFIG_H
10 #include <conf.h>
11 #endif
12
13 #include <string.h>
14
15 #include <SDL.h>
16
17 #include "fix.h"
18 #include "timer.h"
19 #include "event.h"
20 #include "mouse.h"
21
22 #define MOUSE_MAX_BUTTONS       8
23
24 #define Z_SENSITIVITY 100
25
26 struct mousebutton {
27         ubyte pressed;
28         fix time_went_down;
29         fix time_held_down;
30         uint num_downs;
31         uint num_ups;
32 };
33
34 static struct mouseinfo {
35         struct mousebutton buttons[MOUSE_MAX_BUTTONS];
36         int delta_x, delta_y, delta_z;
37         int x,y,z;
38 } Mouse;
39
40 void d_mouse_init(void)
41 {
42         memset(&Mouse,0,sizeof(Mouse));
43 }
44
45 void mouse_button_handler(SDL_MouseButtonEvent *mbe)
46 {
47         // to bad, SDL buttons use a different mapping as descent expects,
48         // this is at least true and tested for the first three buttons 
49         int button_remap[11] = {
50                 MB_LEFT,
51                 MB_MIDDLE,
52                 MB_RIGHT,
53                 MB_Z_UP,
54                 MB_Z_DOWN,
55                 MB_PITCH_BACKWARD,
56                 MB_PITCH_FORWARD,
57                 MB_BANK_LEFT,
58                 MB_BANK_RIGHT,
59                 MB_HEAD_LEFT,
60                 MB_HEAD_RIGHT
61         };
62
63         int button = button_remap[mbe->button - 1]; // -1 since SDL seems to start counting at 1
64
65         if (mbe->state == SDL_PRESSED) {
66                 Mouse.buttons[button].pressed = 1;
67                 Mouse.buttons[button].time_went_down = timer_get_fixed_seconds();
68                 Mouse.buttons[button].num_downs++;
69
70                 if (button == MB_Z_UP) {
71                         Mouse.delta_z += Z_SENSITIVITY;
72                         Mouse.z += Z_SENSITIVITY;
73                 } else if (button == MB_Z_DOWN) {
74                         Mouse.delta_z -= Z_SENSITIVITY;
75                         Mouse.z -= Z_SENSITIVITY;
76                 }
77         } else {
78                 Mouse.buttons[button].pressed = 0;
79                 Mouse.buttons[button].time_held_down += timer_get_fixed_seconds() - Mouse.buttons[button].time_went_down;
80                 Mouse.buttons[button].num_ups++;
81         }
82 }
83
84 void mouse_motion_handler(SDL_MouseMotionEvent *mme)
85 {
86         Mouse.delta_x += mme->xrel;
87         Mouse.delta_y += mme->yrel;
88         Mouse.x += mme->xrel;
89         Mouse.y += mme->yrel;
90 }
91
92 void mouse_flush()      // clears all mice events...
93 {
94         int i;
95         fix current_time;
96
97         event_poll();
98
99         current_time = timer_get_fixed_seconds();
100         for (i=0; i<MOUSE_MAX_BUTTONS; i++) {
101                 Mouse.buttons[i].pressed=0;
102                 Mouse.buttons[i].time_went_down=current_time;
103                 Mouse.buttons[i].time_held_down=0;
104                 Mouse.buttons[i].num_ups=0;
105                 Mouse.buttons[i].num_downs=0;
106         }
107         Mouse.delta_x = 0;
108         Mouse.delta_y = 0;
109         Mouse.delta_z = 0;
110         Mouse.x = 0;
111         Mouse.y = 0;
112         Mouse.z = 0;
113         SDL_GetMouseState(&Mouse.x, &Mouse.y); // necessary because polling only gives us the delta.
114 }
115
116 //========================================================================
117 void mouse_get_pos( int *x, int *y )
118 {
119         event_poll();
120         *x=Mouse.x;
121         *y=Mouse.y;
122 }
123
124 void mouse_get_delta( int *dx, int *dy )
125 {
126         event_poll();
127         *dx = Mouse.delta_x;
128         *dy = Mouse.delta_y;
129         Mouse.delta_x = 0;
130         Mouse.delta_y = 0;
131 }
132
133 void mouse_get_pos_z( int *x, int *y, int *z )
134 {
135         event_poll();
136         *x=Mouse.x;
137         *y=Mouse.y;
138         *z=Mouse.z;
139 }
140
141 void mouse_get_delta_z( int *dx, int *dy, int *dz )
142 {
143         event_poll();
144         *dx = Mouse.delta_x;
145         *dy = Mouse.delta_y;
146         *dz = Mouse.delta_z;
147         Mouse.delta_x = 0;
148         Mouse.delta_y = 0;
149         Mouse.delta_z = 0;
150 }
151
152 int mouse_get_btns()
153 {
154         int i;
155         uint flag=1;
156         int status = 0;
157
158         event_poll();
159
160         for (i=0; i<MOUSE_MAX_BUTTONS; i++ ) {
161                 if (Mouse.buttons[i].pressed)
162                         status |= flag;
163                 flag <<= 1;
164         }
165
166         return status;
167 }
168
169 void mouse_get_cyberman_pos( int *x, int *y )
170 {
171 }
172
173 // Returns how long this button has been down since last call.
174 fix mouse_button_down_time(int button)
175 {
176         fix time_down, time;
177
178         event_poll();
179
180         if (!Mouse.buttons[button].pressed) {
181                 time_down = Mouse.buttons[button].time_held_down;
182                 Mouse.buttons[button].time_held_down = 0;
183         } else {
184                 time = timer_get_fixed_seconds();
185                 time_down = time - Mouse.buttons[button].time_held_down;
186                 Mouse.buttons[button].time_held_down = time;
187         }
188         return time_down;
189 }
190
191 // Returns how many times this button has went down since last call
192 int mouse_button_down_count(int button)
193 {
194         int count;
195
196         event_poll();
197
198         count = Mouse.buttons[button].num_downs;
199         Mouse.buttons[button].num_downs = 0;
200
201         return count;
202 }
203
204 // Returns 1 if this button is currently down
205 int mouse_button_state(int button)
206 {
207         event_poll();
208         return Mouse.buttons[button].pressed;
209 }