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

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

style: remove trailing spaces, fix copyright statements.

File size: 15.1 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#include "config.h"
22
23#include <SDL.h>
24
25#include "system.h"
26#include "image.h"
27#include "palette.h"
28#include "video.h"
29#include "macs.h"
30#include "mouse.h"
31#include "event.h"
32#include "timing.h"
33#include "sprite.h"
34#include "game.h"
35
36extern int get_key_binding( char const *dir, int i );
37extern int mouse_xscale, mouse_yscale;
38short mouse_buttons[5] = { 0, 0, 0, 0, 0 };
39
40// Pre-declarations
41void handle_mouse( event &ev );
42
43//
44// Constructor
45//
46event_handler::event_handler( image *screen, palette *pal )
47{
48    CHECK( screen && pal );
49    mouse = new JCMouse( screen, pal );
50    mhere = mouse->exsist();
51    last_keystat = get_key_flags();
52    ewaiting = 0;
53
54    // Ignore activate events
55    SDL_EventState( SDL_ACTIVEEVENT, SDL_IGNORE );
56}
57
58//
59// Destructor
60//
61event_handler::~event_handler()
62{
63    delete mouse;
64}
65
66//
67// flush_screen()
68// Redraw the screen
69//
70void event_handler::flush_screen()
71{
72    update_dirty( screen );
73}
74
75//
76// get_key_flags()
77// Return the flag for the key modifiers
78//
79int event_handler::get_key_flags()
80{
81    SDLMod key_flag;
82
83    key_flag = SDL_GetModState();
84
85    return ( ( key_flag & KMOD_SHIFT ) != 0 ) << 3 |
86           ( ( key_flag & KMOD_CTRL ) != 0 ) << 2 |
87           ( ( key_flag & KMOD_ALT ) != 0 ) << 1;
88}
89
90//
91// event_waiting()
92// Are there any events in the queue?
93//
94int event_handler::event_waiting()
95{
96    if( ewaiting )
97    {
98        return 1;
99    }
100    if( SDL_PollEvent( NULL ) )
101    {
102        ewaiting = 1;
103    }
104    return ewaiting;
105}
106
107//
108// add_redraw()
109// Add a redraw rectangle.
110//
111void event_handler::add_redraw( int X1, int Y1, int X2, int Y2, void *Start )
112{
113    event *ev;
114    ev = new event;
115    ev->type = EV_REDRAW;
116    ev->redraw.x1 = X1;
117    ev->redraw.x2 = X2;
118    ev->redraw.y1 = Y1;
119    ev->redraw.y2 = Y2;
120    ev->redraw.start = Start;
121    events.add_end( (linked_node *)ev );
122}
123
124//
125// get_event()
126// Get and handle waiting events
127//
128void event_handler::get_event( event &ev )
129{
130    event *ep;
131    while( !ewaiting )
132    {
133        event_waiting();
134
135        if (!ewaiting)
136            milli_wait( 1 );    // Sleep for 1 millisecond if there are no events
137    }
138
139    ep = (event *)events.first();
140    if( ep )
141    {
142        ev = *ep;
143        events.unlink( (linked_node *)ep );
144        delete ep;
145        ewaiting = events.first() != NULL;
146    }
147    else
148    {
149        // NOTE : that the mouse status should be known
150        // even if another event has occurred.
151        ev.mouse_move.x = mouse->x();
152        ev.mouse_move.y = mouse->y();
153        ev.mouse_button = mouse->button();
154
155        // Gather events
156        SDL_Event event;
157        if( SDL_PollEvent( &event ) )
158        {
159            // always sort the mouse out
160            handle_mouse( ev );
161            mouse->update( ev.mouse_move.x, ev.mouse_move.y, ev.mouse_button );
162
163            switch( event.type )
164            {
165                case SDL_QUIT:
166                {
167                    exit(0);
168                    break;
169                }
170                case SDL_MOUSEBUTTONUP:
171                {
172                    switch( event.button.button )
173                    {
174                        case 4:        // Mouse wheel goes up...
175                        {
176                            ev.key = get_key_binding( "b4", 0 );
177                            ev.type = EV_KEYRELEASE;
178                            break;
179                        }
180                        case 5:        // Mouse wheel goes down...
181                        {
182                            ev.key = get_key_binding( "b3", 0 );
183                            ev.type = EV_KEYRELEASE;
184                            break;
185                        }
186                    }
187                    break;
188                }
189                case SDL_MOUSEBUTTONDOWN:
190                {
191                    switch( event.button.button )
192                    {
193                        case 4:        // Mouse wheel goes up...
194                        {
195                            ev.key = get_key_binding( "b4", 0 );
196                            ev.type = EV_KEY;
197                            break;
198                        }
199                        case 5:        // Mouse wheel goes down...
200                        {
201                            ev.key = get_key_binding( "b3", 0 );
202                            ev.type = EV_KEY;
203                            break;
204                        }
205                    }
206                    break;
207                }
208                case SDL_KEYDOWN:
209                case SDL_KEYUP:
210                {
211                    // Default to EV_SPURIOUS
212                    ev.key = EV_SPURIOUS;
213                    if( event.type == SDL_KEYDOWN )
214                    {
215                        ev.type = EV_KEY;
216                    }
217                    else
218                    {
219                        ev.type = EV_KEYRELEASE;
220                    }
221                    switch( event.key.keysym.sym )
222                    {
223                        case SDLK_DOWN:            ev.key = JK_DOWN; break;
224                        case SDLK_UP:            ev.key = JK_UP; break;
225                        case SDLK_LEFT:            ev.key = JK_LEFT; break;
226                        case SDLK_RIGHT:        ev.key = JK_RIGHT; break;
227                        case SDLK_LCTRL:        ev.key = JK_CTRL_L; break;
228                        case SDLK_RCTRL:        ev.key = JK_CTRL_R; break;
229                        case SDLK_LALT:            ev.key = JK_ALT_L; break;
230                        case SDLK_RALT:            ev.key = JK_ALT_R; break;
231                        case SDLK_LSHIFT:        ev.key = JK_SHIFT_L; break;
232                        case SDLK_RSHIFT:        ev.key = JK_SHIFT_R; break;
233                        case SDLK_NUMLOCK:        ev.key = JK_NUM_LOCK; break;
234                        case SDLK_HOME:            ev.key = JK_HOME; break;
235                        case SDLK_END:            ev.key = JK_END; break;
236                        case SDLK_BACKSPACE:    ev.key = JK_BACKSPACE; break;
237                        case SDLK_TAB:            ev.key = JK_TAB; break;
238                        case SDLK_RETURN:        ev.key = JK_ENTER; break;
239                        case SDLK_SPACE:        ev.key = JK_SPACE; break;
240                        case SDLK_CAPSLOCK:        ev.key = JK_CAPS; break;
241                        case SDLK_ESCAPE:        ev.key = JK_ESC; break;
242                        case SDLK_F1:            ev.key = JK_F1; break;
243                        case SDLK_F2:            ev.key = JK_F2; break;
244                        case SDLK_F3:            ev.key = JK_F3; break;
245                        case SDLK_F4:            ev.key = JK_F4; break;
246                        case SDLK_F5:            ev.key = JK_F5; break;
247                        case SDLK_F6:            ev.key = JK_F6; break;
248                        case SDLK_F7:            ev.key = JK_F7; break;
249                        case SDLK_F8:            ev.key = JK_F8; break;
250                        case SDLK_F9:            ev.key = JK_F9; break;
251                        case SDLK_F10:            ev.key = JK_F10; break;
252                        case SDLK_INSERT:        ev.key = JK_INSERT; break;
253                        case SDLK_KP0:            ev.key = JK_INSERT; break;
254                        case SDLK_PAGEUP:        ev.key = JK_PAGEUP; break;
255                        case SDLK_PAGEDOWN:        ev.key = JK_PAGEDOWN; break;
256                        case SDLK_KP8:            ev.key = JK_UP; break;
257                        case SDLK_KP2:            ev.key = JK_DOWN; break;
258                        case SDLK_KP4:            ev.key = JK_LEFT; break;
259                        case SDLK_KP6:            ev.key = JK_RIGHT; break;
260                        case SDLK_F11:
261                        {
262                            // Only handle key down
263                            if( ev.type == EV_KEY )
264                            {
265                                // Toggle fullscreen
266                                SDL_WM_ToggleFullScreen( SDL_GetVideoSurface() );
267                            }
268                            ev.key = EV_SPURIOUS;
269                            break;
270                        }
271                        case SDLK_F12:
272                        {
273                            // Only handle key down
274                            if( ev.type == EV_KEY )
275                            {
276                                // Toggle grab mouse
277                                if( SDL_WM_GrabInput( SDL_GRAB_QUERY ) == SDL_GRAB_ON )
278                                {
279                                    the_game->show_help( "Grab Mouse: OFF\n" );
280                                    SDL_WM_GrabInput( SDL_GRAB_OFF );
281                                }
282                                else
283                                {
284                                    the_game->show_help( "Grab Mouse: ON\n" );
285                                    SDL_WM_GrabInput( SDL_GRAB_ON );
286                                }
287                            }
288                            ev.key = EV_SPURIOUS;
289                            break;
290                        }
291                        case SDLK_PRINT:    // print-screen key
292                        {
293                            // Only handle key down
294                            if( ev.type == EV_KEY )
295                            {
296                                // Grab a screenshot
297                                SDL_SaveBMP( SDL_GetVideoSurface(), "screenshot.bmp" );
298                                the_game->show_help( "Screenshot saved to: screenshot.bmp.\n" );
299                            }
300                            ev.key = EV_SPURIOUS;
301                            break;
302                        }
303                        default:
304                        {
305                            ev.key = (int)event.key.keysym.sym;
306                            // Need to handle the case of shift being pressed
307                            // There has to be a better way
308                            if( (event.key.keysym.mod & KMOD_SHIFT) != 0 )
309                            {
310                                if( event.key.keysym.sym >= SDLK_a &&
311                                    event.key.keysym.sym <= SDLK_z )
312                                {
313                                    ev.key -= 32;
314                                }
315                                else if( event.key.keysym.sym >= SDLK_1 &&
316                                         event.key.keysym.sym <= SDLK_5 )
317                                {
318                                    ev.key -= 16;
319                                }
320                                else
321                                {
322                                    switch( event.key.keysym.sym )
323                                    {
324                                        case SDLK_6:
325                                            ev.key = SDLK_CARET; break;
326                                        case SDLK_7:
327                                        case SDLK_9:
328                                        case SDLK_0:
329                                            ev.key -= 17; break;
330                                        case SDLK_8:
331                                            ev.key = SDLK_ASTERISK; break;
332                                        case SDLK_MINUS:
333                                            ev.key = SDLK_UNDERSCORE; break;
334                                        case SDLK_EQUALS:
335                                            ev.key = SDLK_PLUS; break;
336                                        case SDLK_COMMA:
337                                            ev.key = SDLK_LESS; break;
338                                        case SDLK_PERIOD:
339                                            ev.key = SDLK_GREATER; break;
340                                        case SDLK_SLASH:
341                                            ev.key = SDLK_QUESTION; break;
342                                        case SDLK_SEMICOLON:
343                                            ev.key = SDLK_COLON; break;
344                                        case SDLK_QUOTE:
345                                            ev.key = SDLK_QUOTEDBL; break;
346                                        default:
347                                            break;
348                                    }
349                                }
350                            }
351                        }
352                    }
353                    break;
354                }
355            }
356        }
357        // No more events
358        ewaiting = 0;
359    }
360}
361
362//
363// Handle mouse motion and button presses
364// We don't handle the mousewheel here as
365// SDL_GetMouseState doesn't seem to be
366// able to detect that.
367//
368void handle_mouse( event &ev )
369{
370    Uint8 buttons;
371    int x, y;
372
373    // always sort the mouse out
374    buttons = SDL_GetMouseState( &x, &y );
375    x = (x << 16) / mouse_xscale;
376    y = (y << 16) / mouse_yscale;
377    if( x > screen->width() - 1 )
378    {
379        x = screen->width() - 1;
380    }
381    if( y > screen->height() - 1 )
382    {
383        y = screen->height() - 1;
384    }
385    ev.mouse_move.x = x;
386    ev.mouse_move.y = y;
387    ev.type = EV_MOUSE_MOVE;
388
389    // Left button
390    if( (buttons & SDL_BUTTON(1)) && !mouse_buttons[1] )
391    {
392        ev.type = EV_MOUSE_BUTTON;
393        mouse_buttons[1] = !mouse_buttons[1];
394        ev.mouse_button |= LEFT_BUTTON;
395    }
396    else if( !(buttons & SDL_BUTTON(1)) && mouse_buttons[1] )
397    {
398        ev.type = EV_MOUSE_BUTTON;
399        mouse_buttons[1] = !mouse_buttons[1];
400        ev.mouse_button &= ( 0xff - LEFT_BUTTON );
401    }
402
403    // Middle button
404    if( (buttons & SDL_BUTTON(2)) && !mouse_buttons[2] )
405    {
406        ev.type = EV_MOUSE_BUTTON;
407        mouse_buttons[2] = !mouse_buttons[2];
408        ev.mouse_button |= LEFT_BUTTON;
409        ev.mouse_button |= RIGHT_BUTTON;
410    }
411    else if( !(buttons & SDL_BUTTON(2)) && mouse_buttons[2] )
412    {
413        ev.type = EV_MOUSE_BUTTON;
414        mouse_buttons[2] = !mouse_buttons[2];
415        ev.mouse_button &= ( 0xff - LEFT_BUTTON );
416        ev.mouse_button &= ( 0xff - RIGHT_BUTTON );
417    }
418
419    // Right button
420    if( (buttons & SDL_BUTTON(3)) && !mouse_buttons[3] )
421    {
422        ev.type = EV_MOUSE_BUTTON;
423        mouse_buttons[3] = !mouse_buttons[3];
424        ev.mouse_button |= RIGHT_BUTTON;
425    }
426    else if( !(buttons & SDL_BUTTON(3)) && mouse_buttons[3] )
427    {
428        ev.type = EV_MOUSE_BUTTON;
429        mouse_buttons[3] = !mouse_buttons[3];
430        ev.mouse_button &= ( 0xff - RIGHT_BUTTON );
431    }
432}
Note: See TracBrowser for help on using the repository browser.