source: abuse/trunk/src/sdlport/event.cpp @ 643

Last change on this file since 643 was 643, checked in by Sam Hocevar, 11 years ago

imlib: refactor Event and EventHandler?.

File size: 14.4 KB
Line 
1/*
2 *  Abuse - dark 2D side-scrolling platform game
3 *  Copyright (c) 2001 Anthony Kruize <trandor@labyrinth.net.au>
4 *  Copyright (c) 2005-2011 Sam Hocevar <sam@hocevar.net>
5 *
6 *  This program is free software; you can redistribute it and/or modify
7 *  it under the terms of the GNU General Public License as published by
8 *  the Free Software Foundation; either version 2 of the License, or
9 *  (at your option) any later version.
10 *
11 *  This program is distributed in the hope that it will be useful,
12 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 *  GNU General Public License for more details.
15 *
16 *  You should have received a copy of the GNU General Public License
17 *  along with this program; if not, write to the Free Software Foundation,
18 *  Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
19 */
20
21#if defined HAVE_CONFIG_H
22#   include "config.h"
23#endif
24
25#include <SDL.h>
26
27#include "common.h"
28
29#include "image.h"
30#include "palette.h"
31#include "video.h"
32#include "mouse.h"
33#include "event.h"
34#include "timing.h"
35#include "sprite.h"
36#include "game.h"
37
38extern int get_key_binding(char const *dir, int i);
39extern int mouse_xscale, mouse_yscale;
40short mouse_buttons[5] = { 0, 0, 0, 0, 0 };
41
42// Pre-declarations
43void handle_mouse(Event &ev);
44
45//
46// Constructor
47//
48EventHandler::EventHandler(image *screen, palette *pal)
49{
50    CHECK(screen && pal);
51    mouse = new JCMouse(screen, pal);
52    mhere = mouse->exists();
53    last_keystat = get_key_flags();
54    ewaiting = 0;
55
56    // Ignore activate events
57    SDL_EventState(SDL_ACTIVEEVENT, SDL_IGNORE);
58}
59
60//
61// get_key_flags()
62// Return the flag for the key modifiers
63//
64int EventHandler::get_key_flags()
65{
66    SDLMod key_flag;
67
68    key_flag = SDL_GetModState();
69
70    return ((key_flag & KMOD_SHIFT) != 0) << 3 |
71           ((key_flag & KMOD_CTRL) != 0) << 2 |
72           ((key_flag & KMOD_ALT) != 0) << 1;
73}
74
75//
76// event_waiting()
77// Are there any events in the queue?
78//
79int EventHandler::event_waiting()
80{
81    if(ewaiting)
82    {
83        return 1;
84    }
85    if(SDL_PollEvent(NULL))
86    {
87        ewaiting = 1;
88    }
89    return ewaiting;
90}
91
92//
93// get_event()
94// Get and handle waiting events
95//
96void EventHandler::Get(Event &ev)
97{
98    Event *ep;
99    while(!ewaiting)
100    {
101        event_waiting();
102
103        if (!ewaiting)
104        {
105            // Sleep for 1 millisecond if there are no events
106            Timer tmp; tmp.WaitMs(1);
107        }
108    }
109
110    ep = (Event *)m_events.first();
111    if(ep)
112    {
113        ev = *ep;
114        m_events.unlink(ep);
115        delete ep;
116        ewaiting = m_events.first() != NULL;
117    }
118    else
119    {
120        // NOTE : that the mouse status should be known
121        // even if another event has occurred.
122        ev.mouse_move.x = mouse->x();
123        ev.mouse_move.y = mouse->y();
124        ev.mouse_button = mouse->button();
125
126        // Gather events
127        SDL_Event Event;
128        if(SDL_PollEvent(&Event))
129        {
130            // always sort the mouse out
131            handle_mouse(ev);
132            mouse->update(ev.mouse_move.x, ev.mouse_move.y, ev.mouse_button);
133
134            switch(Event.type)
135            {
136                case SDL_QUIT:
137                {
138                    exit(0);
139                    break;
140                }
141                case SDL_MOUSEBUTTONUP:
142                {
143                    switch(Event.button.button)
144                    {
145                        case 4:        // Mouse wheel goes up...
146                        {
147                            ev.key = get_key_binding("b4", 0);
148                            ev.type = EV_KEYRELEASE;
149                            break;
150                        }
151                        case 5:        // Mouse wheel goes down...
152                        {
153                            ev.key = get_key_binding("b3", 0);
154                            ev.type = EV_KEYRELEASE;
155                            break;
156                        }
157                    }
158                    break;
159                }
160                case SDL_MOUSEBUTTONDOWN:
161                {
162                    switch(Event.button.button)
163                    {
164                        case 4:        // Mouse wheel goes up...
165                        {
166                            ev.key = get_key_binding("b4", 0);
167                            ev.type = EV_KEY;
168                            break;
169                        }
170                        case 5:        // Mouse wheel goes down...
171                        {
172                            ev.key = get_key_binding("b3", 0);
173                            ev.type = EV_KEY;
174                            break;
175                        }
176                    }
177                    break;
178                }
179                case SDL_KEYDOWN:
180                case SDL_KEYUP:
181                {
182                    // Default to EV_SPURIOUS
183                    ev.key = EV_SPURIOUS;
184                    if(Event.type == SDL_KEYDOWN)
185                    {
186                        ev.type = EV_KEY;
187                    }
188                    else
189                    {
190                        ev.type = EV_KEYRELEASE;
191                    }
192                    switch(Event.key.keysym.sym)
193                    {
194                        case SDLK_DOWN:            ev.key = JK_DOWN; break;
195                        case SDLK_UP:            ev.key = JK_UP; break;
196                        case SDLK_LEFT:            ev.key = JK_LEFT; break;
197                        case SDLK_RIGHT:        ev.key = JK_RIGHT; break;
198                        case SDLK_LCTRL:        ev.key = JK_CTRL_L; break;
199                        case SDLK_RCTRL:        ev.key = JK_CTRL_R; break;
200                        case SDLK_LALT:            ev.key = JK_ALT_L; break;
201                        case SDLK_RALT:            ev.key = JK_ALT_R; break;
202                        case SDLK_LSHIFT:        ev.key = JK_SHIFT_L; break;
203                        case SDLK_RSHIFT:        ev.key = JK_SHIFT_R; break;
204                        case SDLK_NUMLOCK:        ev.key = JK_NUM_LOCK; break;
205                        case SDLK_HOME:            ev.key = JK_HOME; break;
206                        case SDLK_END:            ev.key = JK_END; break;
207                        case SDLK_BACKSPACE:    ev.key = JK_BACKSPACE; break;
208                        case SDLK_TAB:            ev.key = JK_TAB; break;
209                        case SDLK_RETURN:        ev.key = JK_ENTER; break;
210                        case SDLK_SPACE:        ev.key = JK_SPACE; break;
211                        case SDLK_CAPSLOCK:        ev.key = JK_CAPS; break;
212                        case SDLK_ESCAPE:        ev.key = JK_ESC; break;
213                        case SDLK_F1:            ev.key = JK_F1; break;
214                        case SDLK_F2:            ev.key = JK_F2; break;
215                        case SDLK_F3:            ev.key = JK_F3; break;
216                        case SDLK_F4:            ev.key = JK_F4; break;
217                        case SDLK_F5:            ev.key = JK_F5; break;
218                        case SDLK_F6:            ev.key = JK_F6; break;
219                        case SDLK_F7:            ev.key = JK_F7; break;
220                        case SDLK_F8:            ev.key = JK_F8; break;
221                        case SDLK_F9:            ev.key = JK_F9; break;
222                        case SDLK_F10:            ev.key = JK_F10; break;
223                        case SDLK_INSERT:        ev.key = JK_INSERT; break;
224                        case SDLK_KP0:            ev.key = JK_INSERT; break;
225                        case SDLK_PAGEUP:        ev.key = JK_PAGEUP; break;
226                        case SDLK_PAGEDOWN:        ev.key = JK_PAGEDOWN; break;
227                        case SDLK_KP8:            ev.key = JK_UP; break;
228                        case SDLK_KP2:            ev.key = JK_DOWN; break;
229                        case SDLK_KP4:            ev.key = JK_LEFT; break;
230                        case SDLK_KP6:            ev.key = JK_RIGHT; break;
231                        case SDLK_F11:
232                        {
233                            // Only handle key down
234                            if(ev.type == EV_KEY)
235                            {
236                                // Toggle fullscreen
237                                SDL_WM_ToggleFullScreen(SDL_GetVideoSurface());
238                            }
239                            ev.key = EV_SPURIOUS;
240                            break;
241                        }
242                        case SDLK_F12:
243                        {
244                            // Only handle key down
245                            if(ev.type == EV_KEY)
246                            {
247                                // Toggle grab mouse
248                                if(SDL_WM_GrabInput(SDL_GRAB_QUERY) == SDL_GRAB_ON)
249                                {
250                                    the_game->show_help("Grab Mouse: OFF\n");
251                                    SDL_WM_GrabInput(SDL_GRAB_OFF);
252                                }
253                                else
254                                {
255                                    the_game->show_help("Grab Mouse: ON\n");
256                                    SDL_WM_GrabInput(SDL_GRAB_ON);
257                                }
258                            }
259                            ev.key = EV_SPURIOUS;
260                            break;
261                        }
262                        case SDLK_PRINT:    // print-screen key
263                        {
264                            // Only handle key down
265                            if(ev.type == EV_KEY)
266                            {
267                                // Grab a screenshot
268                                SDL_SaveBMP(SDL_GetVideoSurface(), "screenshot.bmp");
269                                the_game->show_help("Screenshot saved to: screenshot.bmp.\n");
270                            }
271                            ev.key = EV_SPURIOUS;
272                            break;
273                        }
274                        default:
275                        {
276                            ev.key = (int)Event.key.keysym.sym;
277                            // Need to handle the case of shift being pressed
278                            // There has to be a better way
279                            if((Event.key.keysym.mod & KMOD_SHIFT) != 0)
280                            {
281                                if(Event.key.keysym.sym >= SDLK_a &&
282                                    Event.key.keysym.sym <= SDLK_z)
283                                {
284                                    ev.key -= 32;
285                                }
286                                else if(Event.key.keysym.sym >= SDLK_1 &&
287                                         Event.key.keysym.sym <= SDLK_5)
288                                {
289                                    ev.key -= 16;
290                                }
291                                else
292                                {
293                                    switch(Event.key.keysym.sym)
294                                    {
295                                        case SDLK_6:
296                                            ev.key = SDLK_CARET; break;
297                                        case SDLK_7:
298                                        case SDLK_9:
299                                        case SDLK_0:
300                                            ev.key -= 17; break;
301                                        case SDLK_8:
302                                            ev.key = SDLK_ASTERISK; break;
303                                        case SDLK_MINUS:
304                                            ev.key = SDLK_UNDERSCORE; break;
305                                        case SDLK_EQUALS:
306                                            ev.key = SDLK_PLUS; break;
307                                        case SDLK_COMMA:
308                                            ev.key = SDLK_LESS; break;
309                                        case SDLK_PERIOD:
310                                            ev.key = SDLK_GREATER; break;
311                                        case SDLK_SLASH:
312                                            ev.key = SDLK_QUESTION; break;
313                                        case SDLK_SEMICOLON:
314                                            ev.key = SDLK_COLON; break;
315                                        case SDLK_QUOTE:
316                                            ev.key = SDLK_QUOTEDBL; break;
317                                        default:
318                                            break;
319                                    }
320                                }
321                            }
322                        }
323                    }
324                    break;
325                }
326            }
327        }
328        // No more events
329        ewaiting = 0;
330    }
331}
332
333//
334// Handle mouse motion and button presses
335// We don't handle the mousewheel here as
336// SDL_GetMouseState doesn't seem to be
337// able to detect that.
338//
339void handle_mouse(Event &ev)
340{
341    Uint8 buttons;
342    int x, y;
343
344    // always sort the mouse out
345    buttons = SDL_GetMouseState(&x, &y);
346    x = Min((x << 16) / mouse_xscale, main_screen->Size().x - 1);
347    y = Min((y << 16) / mouse_yscale, main_screen->Size().y - 1);
348    ev.mouse_move.x = x;
349    ev.mouse_move.y = y;
350    ev.type = EV_MOUSE_MOVE;
351
352    // Left button
353    if((buttons & SDL_BUTTON(1)) && !mouse_buttons[1])
354    {
355        ev.type = EV_MOUSE_BUTTON;
356        mouse_buttons[1] = !mouse_buttons[1];
357        ev.mouse_button |= LEFT_BUTTON;
358    }
359    else if(!(buttons & SDL_BUTTON(1)) && mouse_buttons[1])
360    {
361        ev.type = EV_MOUSE_BUTTON;
362        mouse_buttons[1] = !mouse_buttons[1];
363        ev.mouse_button &= (0xff - LEFT_BUTTON);
364    }
365
366    // Middle button
367    if((buttons & SDL_BUTTON(2)) && !mouse_buttons[2])
368    {
369        ev.type = EV_MOUSE_BUTTON;
370        mouse_buttons[2] = !mouse_buttons[2];
371        ev.mouse_button |= LEFT_BUTTON;
372        ev.mouse_button |= RIGHT_BUTTON;
373    }
374    else if(!(buttons & SDL_BUTTON(2)) && mouse_buttons[2])
375    {
376        ev.type = EV_MOUSE_BUTTON;
377        mouse_buttons[2] = !mouse_buttons[2];
378        ev.mouse_button &= (0xff - LEFT_BUTTON);
379        ev.mouse_button &= (0xff - RIGHT_BUTTON);
380    }
381
382    // Right button
383    if((buttons & SDL_BUTTON(3)) && !mouse_buttons[3])
384    {
385        ev.type = EV_MOUSE_BUTTON;
386        mouse_buttons[3] = !mouse_buttons[3];
387        ev.mouse_button |= RIGHT_BUTTON;
388    }
389    else if(!(buttons & SDL_BUTTON(3)) && mouse_buttons[3])
390    {
391        ev.type = EV_MOUSE_BUTTON;
392        mouse_buttons[3] = !mouse_buttons[3];
393        ev.mouse_button &= (0xff - RIGHT_BUTTON);
394    }
395}
Note: See TracBrowser for help on using the repository browser.