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

Last change on this file since 2 was 2, checked in by Sam Hocevar, 14 years ago
  • imported original 0.7.0 tarball
File size: 9.9 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                                        if( the_game->state == RUN_STATE )
153                                        {
154                                                // We're in the actual game so just confirm the user
155                                                // wishes to quit and exit the game.
156                                                if( confirm_quit() )
157                                                {
158                                                        the_game->end_session();
159                                                }
160                                        }
161                                        else
162                                        {
163                                                // We're at the menu screen so simluate the user
164                                                // pressing the ESC key.
165                                                ev.type = EV_KEY;
166                                                ev.key = JK_ESC;
167                                        }
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                                                                        }
347                                                                }
348                                                        }
349                                                }
350                                        }
351                                        break;
352                                }
353                        }
354                }
355                // No more events
356                ewaiting = 0;
357        }
358}
359
360//
361// Handle mouse motion and button presses
362// We don't handle the mousewheel here as
363// SDL_GetMouseState doesn't seem to be
364// able to detect that.
365//
366void handle_mouse( event &ev )
367{
368        Uint8 buttons;
369        int x, y;
370
371        // always sort the mouse out
372        buttons = SDL_GetMouseState( &x, &y );
373        x = (x << 16) / mouse_xscale;
374        y = (y << 16) / mouse_yscale;
375        if( x > 319 )
376        {
377                x = 319;
378        }
379        if( y > 199 )
380        {
381                y = 199;
382        }
383        ev.mouse_move.x = x;
384        ev.mouse_move.y = y;
385        ev.type = EV_MOUSE_MOVE;
386
387        // Left button
388        if( (buttons & SDL_BUTTON(1)) && !mouse_buttons[1] )
389        {
390                ev.type = EV_MOUSE_BUTTON;
391                mouse_buttons[1] = !mouse_buttons[1];
392                ev.mouse_button |= LEFT_BUTTON;
393        }
394        else if( !(buttons & SDL_BUTTON(1)) && mouse_buttons[1] )
395        {
396                ev.type = EV_MOUSE_BUTTON;
397                mouse_buttons[1] = !mouse_buttons[1];
398                ev.mouse_button &= ( 0xff - LEFT_BUTTON );
399        }
400
401        // Middle button
402        if( (buttons & SDL_BUTTON(2)) && !mouse_buttons[2] )
403        {
404                ev.type = EV_MOUSE_BUTTON;
405                mouse_buttons[2] = !mouse_buttons[2];
406                ev.mouse_button |= LEFT_BUTTON;
407                ev.mouse_button |= RIGHT_BUTTON;
408        }
409        else if( !(buttons & SDL_BUTTON(2)) && mouse_buttons[2] )
410        {
411                ev.type = EV_MOUSE_BUTTON;
412                mouse_buttons[2] = !mouse_buttons[2];
413                ev.mouse_button &= ( 0xff - LEFT_BUTTON );
414                ev.mouse_button &= ( 0xff - RIGHT_BUTTON );
415        }
416
417        // Right button
418        if( (buttons & SDL_BUTTON(3)) && !mouse_buttons[3] )
419        {
420                ev.type = EV_MOUSE_BUTTON;
421                mouse_buttons[3] = !mouse_buttons[3];
422                ev.mouse_button |= RIGHT_BUTTON;
423        }
424        else if( !(buttons & SDL_BUTTON(3)) && mouse_buttons[3] )
425        {
426                ev.type = EV_MOUSE_BUTTON;
427                mouse_buttons[3] = !mouse_buttons[3];
428                ev.mouse_button &= ( 0xff - RIGHT_BUTTON );
429        }
430}
Note: See TracBrowser for help on using the repository browser.