source: trunk/src/sdl/sdl_input.cc @ 493

Last change on this file since 493 was 406, checked in by epyon, 10 years ago
  • code compiles cleanly on maximum warning level
File size: 8.9 KB
Line 
1// Copyright (C) 2014-2015 ChaosForge Ltd
2// http://chaosforge.org/
3//
4// This file is part of Nova libraries.
5// For conditions of distribution and use, see copying.txt file in root folder.
6
7#include "nv/sdl/sdl_input.hh"
8
9#include "nv/lib/sdl.hh"
10#include "nv/core/logging.hh"
11
12using namespace nv;
13
14nv::sdl::input::input()
15{
16        if ( ! SDL_WasInit( SDL_INIT_JOYSTICK ) ) SDL_InitSubSystem( SDL_INIT_JOYSTICK );
17        if ( ! SDL_WasInit( SDL_INIT_GAMECONTROLLER ) ) SDL_InitSubSystem( SDL_INIT_GAMECONTROLLER );
18}
19
20static bool sdl_key_event_to_io_event( const SDL_KeyboardEvent& ke, io_event& kevent )
21{
22        kevent.type        = EV_KEY;
23        kevent.key.pressed = ( ke.state != SDL_RELEASED );
24        kevent.key.ascii   = 0;
25        kevent.key.code    = KEY_NONE;
26
27        uint32 ucode = static_cast<uint32>( ke.keysym.sym );
28
29        // if result is a typable char place it into the structure
30        if (ucode >= 32 && ucode < 128 )
31        {
32                kevent.key.ascii = static_cast<uchar8>( ucode );
33                if (ucode >= 'a' && ucode <= 'z')
34                {
35                        int shifted = !!(ke.keysym.mod & KMOD_SHIFT);
36                        int capslock = !!(ke.keysym.mod & KMOD_CAPS);
37                        if ((shifted ^ capslock) != 0) {
38                                kevent.key.ascii = static_cast<uchar8>( SDL_toupper( static_cast<int>( ucode ) ) );
39                        }
40                }
41        }
42
43        // Get the Key value from the SDL Keyboard event
44        int result = ke.keysym.sym;
45
46        // Check the control and shift states
47        kevent.key.alt     = (ke.keysym.mod & KMOD_ALT ) != 0;
48        kevent.key.control = (ke.keysym.mod & KMOD_CTRL ) != 0;
49        kevent.key.shift   = (ke.keysym.mod & KMOD_SHIFT ) != 0;
50
51        // if result is a typable char from the directly transformable ranges
52        if ( ( result >= KEY_A && result <= KEY_Z ) ||
53                ( result >= KEY_0 && result <= KEY_9 ) ||
54                result == ' ' )
55        {
56                kevent.key.code = static_cast<key_code>(result);
57        }
58
59        // if result is a typable char from the a..z range
60        if ( result >= KEY_A + 32 && result <= KEY_Z + 32 )
61        {
62                kevent.key.code = static_cast<key_code>(result - 32);
63        }
64
65        if ( result >= SDLK_F1 && result <= SDLK_F12 )
66        {
67                kevent.key.code = static_cast<key_code>(result - SDLK_F1 + KEY_F1 );
68        }
69
70        // other recognized codes
71        switch ( result )
72        {
73        case SDLK_BACKSPACE    : kevent.key.code = KEY_BACK; break;
74        case SDLK_TAB          : kevent.key.code = KEY_TAB; break;
75        case SDLK_RETURN       : kevent.key.code = KEY_ENTER; break;
76        case SDLK_PAGEUP       : kevent.key.code = KEY_PGUP; break;
77        case SDLK_PAGEDOWN     : kevent.key.code = KEY_PGDOWN; break;
78        case SDLK_END          : kevent.key.code = KEY_END; break;
79        case SDLK_HOME         : kevent.key.code = KEY_HOME; break;
80        case SDLK_LEFT         : kevent.key.code = KEY_LEFT; break;
81        case SDLK_UP           : kevent.key.code = KEY_UP; break;
82        case SDLK_RIGHT        : kevent.key.code = KEY_RIGHT; break;
83        case SDLK_DOWN         : kevent.key.code = KEY_DOWN; break;
84        case SDLK_DELETE       : kevent.key.code = KEY_DELETE; break;
85        case SDLK_INSERT       : kevent.key.code = KEY_INSERT; break;
86        //case SDLK_KP5          : kevent.key.code = KEY_CENTER; break;
87        case SDLK_ESCAPE       : kevent.key.code = KEY_ESCAPE; break;
88        case SDLK_QUOTE        : kevent.key.code = KEY_QUOTE; break;
89        case SDLK_COMMA        : kevent.key.code = KEY_COMMA; break;
90        case SDLK_MINUS        : kevent.key.code = KEY_MINUS; break;
91        case SDLK_PERIOD       : kevent.key.code = KEY_PERIOD; break;
92        case SDLK_SLASH        : kevent.key.code = KEY_SLASH; break;
93        case SDLK_SEMICOLON    : kevent.key.code = KEY_SCOLON; break;
94        case SDLK_LEFTBRACKET  : kevent.key.code = KEY_LBRACKET; break;
95        case SDLK_BACKSLASH    : kevent.key.code = KEY_BSLASH; break;
96        case SDLK_RIGHTBRACKET : kevent.key.code = KEY_RBRACKET; break;
97        case SDLK_BACKQUOTE    : kevent.key.code = KEY_BQUOTE; break;
98        default : break;
99        }
100
101        kevent.key.native = ke.keysym.scancode;
102
103        // If key was understood by nv, then it's valid, otherwise ignored
104        return kevent.key.ascii != 0 || kevent.key.code != 0;
105}
106
107static bool sdl_mouse_button_to_io_event( const SDL_MouseButtonEvent& mb, io_event& mevent )
108{
109        mevent.type            = EV_MOUSE_BUTTON;
110        mevent.mbutton.button  = MOUSE_NONE;
111        mevent.mbutton.pressed = (mb.state != SDL_RELEASED);
112        mevent.mbutton.x       = static_cast< uint16 >( mb.x );
113        mevent.mbutton.y       = static_cast< uint16 >( mb.y );
114
115        switch ( mb.button )
116        {
117        case SDL_BUTTON_LEFT      : mevent.mbutton.button = MOUSE_LEFT; break;
118        case SDL_BUTTON_MIDDLE    : mevent.mbutton.button = MOUSE_MIDDLE; break;
119        case SDL_BUTTON_RIGHT     : mevent.mbutton.button = MOUSE_RIGHT; break;
120        default : break;
121        }
122
123        return mevent.mbutton.button != MOUSE_NONE;
124}
125
126static bool sdl_mouse_wheel_to_io_event( const SDL_MouseWheelEvent& mm, io_event& mevent )
127{
128        mevent.type          = EV_MOUSE_WHEEL;
129        mevent.mwheel.x      = static_cast< sint32 >( mm.x );
130        mevent.mwheel.y      = static_cast< sint32 >( mm.y );
131        return true;
132}
133
134static bool sdl_mouse_motion_to_io_event( const SDL_MouseMotionEvent& mm, io_event& mevent )
135{
136        mevent.type          = EV_MOUSE_MOVE;
137        mevent.mmove.pressed = (mm.state != SDL_RELEASED);
138        mevent.mmove.x       = static_cast< uint16 >( mm.x );
139        mevent.mmove.y       = static_cast< uint16 >( mm.y );
140        mevent.mmove.rx      = static_cast< sint16 >( mm.xrel );
141        mevent.mmove.ry      = static_cast< sint16 >( mm.yrel );
142        return true;
143}
144
145static bool sdl_pad_button_event_to_io_event( const SDL_ControllerButtonEvent& cb, io_event& cevent )
146{
147        cevent.type            = EV_PAD_BUTTON;
148        cevent.pbutton.id      = cb.which;
149        cevent.pbutton.button  = cb.button;
150        cevent.pbutton.pressed = (cb.type == SDL_PRESSED);
151        return true;
152}
153
154static bool sdl_pad_axis_event_to_io_event( const SDL_ControllerAxisEvent& ca, io_event& cevent )
155{
156        cevent.type          = EV_PAD_AXIS;
157        cevent.paxis.id      = ca.which;
158        cevent.paxis.axis    = ca.axis;
159        cevent.paxis.value   = ca.value;
160        return true;
161}
162
163
164static bool sdl_joy_button_event_to_io_event( const SDL_JoyButtonEvent& jb, io_event& jevent )
165{
166        jevent.type            = EV_JOY_BUTTON;
167        jevent.jbutton.id      = jb.which;
168        jevent.jbutton.button  = jb.button;
169        jevent.jbutton.pressed = (jb.type == SDL_PRESSED);
170        return true;
171}
172
173static bool sdl_joy_axis_event_to_io_event( const SDL_JoyAxisEvent& ja, io_event& jevent )
174{
175        jevent.type          = EV_JOY_AXIS;
176        jevent.jaxis.id      = ja.which;
177        jevent.jaxis.axis    = ja.axis;
178        jevent.jaxis.value   = ja.value;
179        return true;
180}
181
182static bool sdl_joy_hat_event_to_io_event( const SDL_JoyHatEvent& jh, io_event& jevent )
183{
184        jevent.type          = EV_JOY_HAT;
185        jevent.jhat.id       = jh.which;
186        jevent.jhat.hat      = jh.hat;
187        jevent.jhat.value    = jh.value;
188        return true;
189}
190
191static bool sdl_joy_ball_event_to_io_event( const SDL_JoyBallEvent& jb, io_event& jevent )
192{
193        jevent.type          = EV_JOY_HAT;
194        jevent.jball.id      = jb.which;
195        jevent.jball.ball    = jb.ball;
196        jevent.jball.rx      = jb.xrel;
197        jevent.jball.ry      = jb.yrel;
198        return true;
199}
200
201static bool sdl_event_to_io_event( const SDL_Event& e, io_event& ioevent )
202{
203        switch ( e.type )
204        {
205        case SDL_KEYDOWN         : return sdl_key_event_to_io_event( e.key, ioevent );
206        case SDL_KEYUP           : return sdl_key_event_to_io_event( e.key, ioevent );
207        case SDL_MOUSEMOTION     : return sdl_mouse_motion_to_io_event( e.motion, ioevent );
208        case SDL_MOUSEBUTTONDOWN : return sdl_mouse_button_to_io_event( e.button, ioevent );
209        case SDL_MOUSEBUTTONUP   : return sdl_mouse_button_to_io_event( e.button, ioevent );
210        case SDL_MOUSEWHEEL      : return sdl_mouse_wheel_to_io_event( e.wheel, ioevent );
211/* // SDL 2.0 incompatible
212        case SDL_ACTIVEEVENT     :
213                ioevent.type = EV_ACTIVE;
214                ioevent.active.gain = (e.active.gain != 0);
215                return e.active.state == SDL_APPINPUTFOCUS;
216        case SDL_VIDEORESIZE     :
217                ioevent.type     = EV_RESIZE;
218                ioevent.resize.x = e.resize.w;
219                ioevent.resize.y = e.resize.h;
220                return true;
221        case SDL_NOEVENT         : return false;
222        case SDL_VIDEOEXPOSE     : return false;
223*/
224        case SDL_SYSWMEVENT      : ioevent.type = EV_SYSTEM; return true;
225        case SDL_QUIT            : ioevent.type = EV_QUIT;   return true;
226        case SDL_CONTROLLERAXISMOTION : return sdl_pad_axis_event_to_io_event( e.caxis, ioevent );
227        case SDL_CONTROLLERBUTTONDOWN : return sdl_pad_button_event_to_io_event( e.cbutton, ioevent );
228        case SDL_CONTROLLERBUTTONUP   :
229        case SDL_JOYAXISMOTION   : return sdl_joy_axis_event_to_io_event( e.jaxis, ioevent );
230        case SDL_JOYBALLMOTION   : return sdl_joy_ball_event_to_io_event( e.jball, ioevent );
231        case SDL_JOYHATMOTION    : return sdl_joy_hat_event_to_io_event( e.jhat, ioevent );
232        case SDL_JOYBUTTONDOWN   : return sdl_joy_button_event_to_io_event( e.jbutton, ioevent );
233        case SDL_JOYBUTTONUP     : return sdl_joy_button_event_to_io_event( e.jbutton, ioevent );
234        default : return false;
235        }
236}
237
238bool sdl::input::is_event_pending()
239{
240        return SDL_PollEvent( nullptr ) != 0;
241}
242
243bool sdl::input::poll_event( io_event& event )
244{
245        SDL_Event sdl_event;
246        if ( SDL_PollEvent( &sdl_event ) == 0 ) return false;
247        return sdl_event_to_io_event( sdl_event, event );
248}
249
Note: See TracBrowser for help on using the repository browser.