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

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