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

Last change on this file since 338 was 338, checked in by epyon, 11 years ago
  • io_events for controllers
File size: 8.8 KB
Line 
1// Copyright (C) 2014 ChaosForge Ltd
2// http://chaosforge.org/
3//
4// This file is part of NV Libraries.
5// For conditions of distribution and use, see copyright notice in nv.hh
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 = (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<char8>( 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 = (char8)SDL_toupper((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        // If key was understood by nv, then it's valid, otherwise ignored
102        return kevent.key.ascii != 0 || kevent.key.code != 0;
103}
104
105static bool sdl_mouse_button_to_io_event( const SDL_MouseButtonEvent& mb, io_event& mevent )
106{
107        mevent.type            = EV_MOUSE_BUTTON;
108        mevent.mbutton.button  = MOUSE_NONE;
109        mevent.mbutton.pressed = (mb.state != SDL_RELEASED);
110        mevent.mbutton.x       = static_cast< uint16 >( mb.x );
111        mevent.mbutton.y       = static_cast< uint16 >( mb.y );
112
113        switch ( mb.button )
114        {
115        case SDL_BUTTON_LEFT      : mevent.mbutton.button = MOUSE_LEFT; break;
116        case SDL_BUTTON_MIDDLE    : mevent.mbutton.button = MOUSE_MIDDLE; break;
117        case SDL_BUTTON_RIGHT     : mevent.mbutton.button = MOUSE_RIGHT; break;
118        default : break;
119        }
120
121        return mevent.mbutton.button != MOUSE_NONE;
122}
123
124static bool sdl_mouse_wheel_to_io_event( const SDL_MouseWheelEvent& mm, io_event& mevent )
125{
126        mevent.type          = EV_MOUSE_WHEEL;
127        mevent.mwheel.x      = static_cast< sint32 >( mm.x );
128        mevent.mwheel.y      = static_cast< sint32 >( mm.y );
129        return true;
130}
131
132static bool sdl_mouse_motion_to_io_event( const SDL_MouseMotionEvent& mm, io_event& mevent )
133{
134        mevent.type          = EV_MOUSE_MOVE;
135        mevent.mmove.pressed = (mm.state != SDL_RELEASED);
136        mevent.mmove.x       = static_cast< uint16 >( mm.x );
137        mevent.mmove.y       = static_cast< uint16 >( mm.y );
138        mevent.mmove.rx      = static_cast< sint16 >( mm.xrel );
139        mevent.mmove.ry      = static_cast< sint16 >( mm.yrel );
140        return true;
141}
142
143static bool sdl_pad_button_event_to_io_event( const SDL_ControllerButtonEvent& cb, io_event& cevent )
144{
145        cevent.type            = EV_PAD_BUTTON;
146        cevent.pbutton.id      = cb.which;
147        cevent.pbutton.button  = cb.button;
148        cevent.pbutton.pressed = (cb.type == SDL_PRESSED);
149        return true;
150}
151
152static bool sdl_pad_axis_event_to_io_event( const SDL_ControllerAxisEvent& ca, io_event& cevent )
153{
154        cevent.type          = EV_PAD_AXIS;
155        cevent.paxis.id      = ca.which;
156        cevent.paxis.axis    = ca.axis;
157        cevent.paxis.value   = ca.value;
158        return true;
159}
160
161
162static bool sdl_joy_button_event_to_io_event( const SDL_JoyButtonEvent& jb, io_event& jevent )
163{
164        jevent.type            = EV_JOY_BUTTON;
165        jevent.jbutton.id      = jb.which;
166        jevent.jbutton.button  = jb.button;
167        jevent.jbutton.pressed = (jb.type == SDL_PRESSED);
168        return true;
169}
170
171static bool sdl_joy_axis_event_to_io_event( const SDL_JoyAxisEvent& ja, io_event& jevent )
172{
173        jevent.type          = EV_JOY_AXIS;
174        jevent.jaxis.id      = ja.which;
175        jevent.jaxis.axis    = ja.axis;
176        jevent.jaxis.value   = ja.value;
177        return true;
178}
179
180static bool sdl_joy_hat_event_to_io_event( const SDL_JoyHatEvent& jh, io_event& jevent )
181{
182        jevent.type          = EV_JOY_HAT;
183        jevent.jhat.id       = jh.which;
184        jevent.jhat.hat      = jh.hat;
185        jevent.jhat.value    = jh.value;
186        return true;
187}
188
189static bool sdl_joy_ball_event_to_io_event( const SDL_JoyBallEvent& jb, io_event& jevent )
190{
191        jevent.type          = EV_JOY_HAT;
192        jevent.jball.id      = jb.which;
193        jevent.jball.ball    = jb.ball;
194        jevent.jball.rx      = jb.xrel;
195        jevent.jball.ry      = jb.yrel;
196        return true;
197}
198
199static bool sdl_event_to_io_event( const SDL_Event& e, io_event& ioevent )
200{
201        switch ( e.type )
202        {
203        case SDL_KEYDOWN         : return sdl_key_event_to_io_event( e.key, ioevent );
204        case SDL_KEYUP           : return sdl_key_event_to_io_event( e.key, ioevent );
205        case SDL_MOUSEMOTION     : return sdl_mouse_motion_to_io_event( e.motion, ioevent );
206        case SDL_MOUSEBUTTONDOWN : return sdl_mouse_button_to_io_event( e.button, ioevent );
207        case SDL_MOUSEBUTTONUP   : return sdl_mouse_button_to_io_event( e.button, ioevent );
208        case SDL_MOUSEWHEEL      : return sdl_mouse_wheel_to_io_event( e.wheel, ioevent );
209/* // SDL 2.0 incompatible
210        case SDL_ACTIVEEVENT     :
211                ioevent.type = EV_ACTIVE;
212                ioevent.active.gain = (e.active.gain != 0);
213                return e.active.state == SDL_APPINPUTFOCUS;
214        case SDL_VIDEORESIZE     :
215                ioevent.type     = EV_RESIZE;
216                ioevent.resize.x = e.resize.w;
217                ioevent.resize.y = e.resize.h;
218                return true;
219        case SDL_NOEVENT         : return false;
220        case SDL_VIDEOEXPOSE     : return false;
221*/
222        case SDL_SYSWMEVENT      : ioevent.type = EV_SYSTEM; return true;
223        case SDL_QUIT            : ioevent.type = EV_QUIT;   return true;
224        case SDL_CONTROLLERAXISMOTION : return sdl_pad_axis_event_to_io_event( e.caxis, ioevent );
225        case SDL_CONTROLLERBUTTONDOWN : return sdl_pad_button_event_to_io_event( e.cbutton, ioevent );
226        case SDL_CONTROLLERBUTTONUP   :
227        case SDL_JOYAXISMOTION   : return sdl_joy_axis_event_to_io_event( e.jaxis, ioevent );
228        case SDL_JOYBALLMOTION   : return sdl_joy_ball_event_to_io_event( e.jball, ioevent );
229        case SDL_JOYHATMOTION    : return sdl_joy_hat_event_to_io_event( e.jhat, ioevent );
230        case SDL_JOYBUTTONDOWN   : return sdl_joy_button_event_to_io_event( e.jbutton, ioevent );
231        case SDL_JOYBUTTONUP     : return sdl_joy_button_event_to_io_event( e.jbutton, ioevent );
232        default : return false;
233        }
234}
235
236bool sdl::input::is_event_pending()
237{
238        return SDL_PollEvent( nullptr ) != 0;
239}
240
241bool sdl::input::poll_event( io_event& event )
242{
243        SDL_Event sdl_event;
244        if ( SDL_PollEvent( &sdl_event ) == 0 ) return false;
245        return sdl_event_to_io_event( sdl_event, event );
246}
247
Note: See TracBrowser for help on using the repository browser.