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

Last change on this file was 682, checked in by Sam Hocevar, 12 years ago

core: rename vec2i to ivec2 and update matrix.h from Lol Engine.

File size: 10.0 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 "event.h"
33#include "timing.h"
34#include "sprite.h"
35#include "game.h"
36
37extern int get_key_binding(char const *dir, int i);
38extern int mouse_xscale, mouse_yscale;
39short mouse_buttons[5] = { 0, 0, 0, 0, 0 };
40
41void EventHandler::SysInit()
42{
43    // Ignore activate events
44    SDL_EventState(SDL_ACTIVEEVENT, SDL_IGNORE);
45}
46
47void EventHandler::SysWarpMouse(ivec2 pos)
48{
49    SDL_WarpMouse(pos.x, pos.y);
50}
51
52//
53// IsPending()
54// Are there any events in the queue?
55//
56int EventHandler::IsPending()
57{
58    if (!m_pending && SDL_PollEvent(NULL))
59        m_pending = 1;
60
61    return m_pending;
62}
63
64//
65// Get and handle waiting events
66//
67void EventHandler::SysEvent(Event &ev)
68{
69    // No more events
70    m_pending = 0;
71
72    // NOTE : that the mouse status should be known
73    // even if another event has occurred.
74    ev.mouse_move.x = m_pos.x;
75    ev.mouse_move.y = m_pos.y;
76    ev.mouse_button = m_button;
77
78    // Gather next event
79    SDL_Event sdlev;
80    if (!SDL_PollEvent(&sdlev))
81        return; // This should not happen
82
83    // Sort the mouse out
84    int x, y;
85    uint8_t buttons = SDL_GetMouseState(&x, &y);
86    x = Min((x << 16) / mouse_xscale, main_screen->Size().x - 1);
87    y = Min((y << 16) / mouse_yscale, main_screen->Size().y - 1);
88    ev.mouse_move.x = x;
89    ev.mouse_move.y = y;
90    ev.type = EV_MOUSE_MOVE;
91
92    // Left button
93    if((buttons & SDL_BUTTON(1)) && !mouse_buttons[1])
94    {
95        ev.type = EV_MOUSE_BUTTON;
96        mouse_buttons[1] = !mouse_buttons[1];
97        ev.mouse_button |= LEFT_BUTTON;
98    }
99    else if(!(buttons & SDL_BUTTON(1)) && mouse_buttons[1])
100    {
101        ev.type = EV_MOUSE_BUTTON;
102        mouse_buttons[1] = !mouse_buttons[1];
103        ev.mouse_button &= (0xff - LEFT_BUTTON);
104    }
105
106    // Middle button
107    if((buttons & SDL_BUTTON(2)) && !mouse_buttons[2])
108    {
109        ev.type = EV_MOUSE_BUTTON;
110        mouse_buttons[2] = !mouse_buttons[2];
111        ev.mouse_button |= LEFT_BUTTON;
112        ev.mouse_button |= RIGHT_BUTTON;
113    }
114    else if(!(buttons & SDL_BUTTON(2)) && mouse_buttons[2])
115    {
116        ev.type = EV_MOUSE_BUTTON;
117        mouse_buttons[2] = !mouse_buttons[2];
118        ev.mouse_button &= (0xff - LEFT_BUTTON);
119        ev.mouse_button &= (0xff - RIGHT_BUTTON);
120    }
121
122    // Right button
123    if((buttons & SDL_BUTTON(3)) && !mouse_buttons[3])
124    {
125        ev.type = EV_MOUSE_BUTTON;
126        mouse_buttons[3] = !mouse_buttons[3];
127        ev.mouse_button |= RIGHT_BUTTON;
128    }
129    else if(!(buttons & SDL_BUTTON(3)) && mouse_buttons[3])
130    {
131        ev.type = EV_MOUSE_BUTTON;
132        mouse_buttons[3] = !mouse_buttons[3];
133        ev.mouse_button &= (0xff - RIGHT_BUTTON);
134    }
135    m_pos = ivec2(ev.mouse_move.x, ev.mouse_move.y);
136    m_button = ev.mouse_button;
137
138    // Sort out other kinds of events
139    switch(sdlev.type)
140    {
141    case SDL_QUIT:
142        exit(0);
143        break;
144    case SDL_MOUSEBUTTONUP:
145        switch(sdlev.button.button)
146        {
147        case 4:        // Mouse wheel goes up...
148            ev.key = get_key_binding("b4", 0);
149            ev.type = EV_KEYRELEASE;
150            break;
151        case 5:        // Mouse wheel goes down...
152            ev.key = get_key_binding("b3", 0);
153            ev.type = EV_KEYRELEASE;
154            break;
155        }
156        break;
157    case SDL_MOUSEBUTTONDOWN:
158        switch(sdlev.button.button)
159        {
160        case 4:        // Mouse wheel goes up...
161            ev.key = get_key_binding("b4", 0);
162            ev.type = EV_KEY;
163            break;
164        case 5:        // Mouse wheel goes down...
165            ev.key = get_key_binding("b3", 0);
166            ev.type = EV_KEY;
167            break;
168        }
169        break;
170    case SDL_KEYDOWN:
171    case SDL_KEYUP:
172        // Default to EV_SPURIOUS
173        ev.key = EV_SPURIOUS;
174        if(sdlev.type == SDL_KEYDOWN)
175        {
176            ev.type = EV_KEY;
177        }
178        else
179        {
180            ev.type = EV_KEYRELEASE;
181        }
182        switch(sdlev.key.keysym.sym)
183        {
184        case SDLK_DOWN:         ev.key = JK_DOWN; break;
185        case SDLK_UP:           ev.key = JK_UP; break;
186        case SDLK_LEFT:         ev.key = JK_LEFT; break;
187        case SDLK_RIGHT:        ev.key = JK_RIGHT; break;
188        case SDLK_LCTRL:        ev.key = JK_CTRL_L; break;
189        case SDLK_RCTRL:        ev.key = JK_CTRL_R; break;
190        case SDLK_LALT:         ev.key = JK_ALT_L; break;
191        case SDLK_RALT:         ev.key = JK_ALT_R; break;
192        case SDLK_LSHIFT:       ev.key = JK_SHIFT_L; break;
193        case SDLK_RSHIFT:       ev.key = JK_SHIFT_R; break;
194        case SDLK_NUMLOCK:      ev.key = JK_NUM_LOCK; break;
195        case SDLK_HOME:         ev.key = JK_HOME; break;
196        case SDLK_END:          ev.key = JK_END; break;
197        case SDLK_BACKSPACE:    ev.key = JK_BACKSPACE; break;
198        case SDLK_TAB:          ev.key = JK_TAB; break;
199        case SDLK_RETURN:       ev.key = JK_ENTER; break;
200        case SDLK_SPACE:        ev.key = JK_SPACE; break;
201        case SDLK_CAPSLOCK:     ev.key = JK_CAPS; break;
202        case SDLK_ESCAPE:       ev.key = JK_ESC; break;
203        case SDLK_F1:           ev.key = JK_F1; break;
204        case SDLK_F2:           ev.key = JK_F2; break;
205        case SDLK_F3:           ev.key = JK_F3; break;
206        case SDLK_F4:           ev.key = JK_F4; break;
207        case SDLK_F5:           ev.key = JK_F5; break;
208        case SDLK_F6:           ev.key = JK_F6; break;
209        case SDLK_F7:           ev.key = JK_F7; break;
210        case SDLK_F8:           ev.key = JK_F8; break;
211        case SDLK_F9:           ev.key = JK_F9; break;
212        case SDLK_F10:          ev.key = JK_F10; break;
213        case SDLK_INSERT:       ev.key = JK_INSERT; break;
214        case SDLK_KP0:          ev.key = JK_INSERT; break;
215        case SDLK_PAGEUP:       ev.key = JK_PAGEUP; break;
216        case SDLK_PAGEDOWN:     ev.key = JK_PAGEDOWN; break;
217        case SDLK_KP8:          ev.key = JK_UP; break;
218        case SDLK_KP2:          ev.key = JK_DOWN; break;
219        case SDLK_KP4:          ev.key = JK_LEFT; break;
220        case SDLK_KP6:          ev.key = JK_RIGHT; break;
221        case SDLK_F11:
222            // Only handle key down
223            if(ev.type == EV_KEY)
224            {
225                // Toggle fullscreen
226                SDL_WM_ToggleFullScreen(SDL_GetVideoSurface());
227            }
228            ev.key = EV_SPURIOUS;
229            break;
230        case SDLK_F12:
231            // Only handle key down
232            if(ev.type == EV_KEY)
233            {
234                // Toggle grab mouse
235                if(SDL_WM_GrabInput(SDL_GRAB_QUERY) == SDL_GRAB_ON)
236                {
237                    the_game->show_help("Grab Mouse: OFF\n");
238                    SDL_WM_GrabInput(SDL_GRAB_OFF);
239                }
240                else
241                {
242                    the_game->show_help("Grab Mouse: ON\n");
243                    SDL_WM_GrabInput(SDL_GRAB_ON);
244                }
245            }
246            ev.key = EV_SPURIOUS;
247            break;
248        case SDLK_PRINT:    // print-screen key
249            // Only handle key down
250            if(ev.type == EV_KEY)
251            {
252                // Grab a screenshot
253                SDL_SaveBMP(SDL_GetVideoSurface(), "screenshot.bmp");
254                the_game->show_help("Screenshot saved to: screenshot.bmp.\n");
255            }
256            ev.key = EV_SPURIOUS;
257            break;
258        default:
259            ev.key = (int)sdlev.key.keysym.sym;
260            // Need to handle the case of shift being pressed
261            // There has to be a better way
262            if((sdlev.key.keysym.mod & KMOD_SHIFT) != 0)
263            {
264                if(sdlev.key.keysym.sym >= SDLK_a &&
265                    sdlev.key.keysym.sym <= SDLK_z)
266                {
267                    ev.key -= 32;
268                }
269                else if(sdlev.key.keysym.sym >= SDLK_1 &&
270                         sdlev.key.keysym.sym <= SDLK_5)
271                {
272                    ev.key -= 16;
273                }
274                else
275                {
276                    switch(sdlev.key.keysym.sym)
277                    {
278                    case SDLK_6:
279                        ev.key = SDLK_CARET; break;
280                    case SDLK_7:
281                    case SDLK_9:
282                    case SDLK_0:
283                        ev.key -= 17; break;
284                    case SDLK_8:
285                        ev.key = SDLK_ASTERISK; break;
286                    case SDLK_MINUS:
287                        ev.key = SDLK_UNDERSCORE; break;
288                    case SDLK_EQUALS:
289                        ev.key = SDLK_PLUS; break;
290                    case SDLK_COMMA:
291                        ev.key = SDLK_LESS; break;
292                    case SDLK_PERIOD:
293                        ev.key = SDLK_GREATER; break;
294                    case SDLK_SLASH:
295                        ev.key = SDLK_QUESTION; break;
296                    case SDLK_SEMICOLON:
297                        ev.key = SDLK_COLON; break;
298                    case SDLK_QUOTE:
299                        ev.key = SDLK_QUOTEDBL; break;
300                    default:
301                        break;
302                    }
303                }
304            }
305            break;
306        }
307    }
308}
309
Note: See TracBrowser for help on using the repository browser.