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

Last change on this file since 88 was 88, checked in by Sam Hocevar, 11 years ago
  • Remove a few duplicate extern declarations. They belong to header files.
File size: 10.3 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 occured.
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.