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

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