source: trunk/src/gl/gl_window.cc @ 172

Last change on this file since 172 was 172, checked in by epyon, 12 years ago
  • sdl - missing 2.0 sdl_functions
  • lua - compat implementation of lua_upvalueindex
  • position - rectangle single argument constructor made explicit
  • gl_window - fix for SDL 2.0 ascii code of key press
  • lua/glm - coord as a separate class (behaves like ivec2)
File size: 7.8 KB
RevLine 
[38]1// Copyright (C) 2012-2013 Kornel Kisielewicz
2// This file is part of NV Libraries.
3// For conditions of distribution and use, see copyright notice in nv.hh
4
5#include "nv/gl/gl_window.hh"
6
7#include "nv/logging.hh"
8#include "nv/lib/gl.hh"
[170]9#include "nv/lib/sdl.hh"
[38]10
11using namespace nv;
12
[93]13static bool sdl_key_event_to_io_event( const SDL_KeyboardEvent& ke, io_event& kevent )
14{
15        kevent.type        = EV_KEY;
16        kevent.key.pressed = ( ke.state != SDL_RELEASED );
17        kevent.key.ascii   = 0;
18        kevent.key.code    = KEY_NONE;
19
[171]20#if NV_SDL_VERSION == NV_SDL_20
21        uint32 ucode = ke.keysym.sym;
22#else
23        uint32 ucode = ke.keysym.unicode;
24#endif
25
[93]26        // if result is a typable char place it into the structure
[171]27        if (ucode >= 32 && ucode < 128 )
[93]28        {
[171]29                kevent.key.ascii = static_cast<char8>( ucode );
[172]30#if NV_SDL_VERSION == NV_SDL_20
31                if (ucode >= 'a' && ucode <= 'z')
32                {
33                        int shifted = !!(ke.keysym.mod & KMOD_SHIFT);
34                        int capslock = !!(ke.keysym.mod & KMOD_CAPS);
35                        if ((shifted ^ capslock) != 0) {
36                                kevent.key.ascii = SDL_toupper(ucode);
37                        }
38                }
39#endif
[93]40        }
41
42        // Get the Key value from the SDL Keyboard event
43        int result = ke.keysym.sym;
44
45        // Check the control and shift states
46        kevent.key.alt     = (ke.keysym.mod & KMOD_ALT ) != 0;
47        kevent.key.control = (ke.keysym.mod & KMOD_CTRL ) != 0;
48        kevent.key.shift   = (ke.keysym.mod & KMOD_SHIFT ) != 0;
49
50        // if result is a typable char from the directly transformable ranges
51        if ( ( result >= KEY_A && result <= KEY_Z ) ||
52                ( result >= KEY_0 && result <= KEY_9 ) ||
53                result == ' ' )
54        {
55                kevent.key.code = static_cast<key_code>(result);
56        }
57
58        // if result is a typable char from the a..z range
59        if ( result >= KEY_A + 32 && result <= KEY_Z + 32 )
60        {
61                kevent.key.code = static_cast<key_code>(result - 32);
62        }
63
64        if ( result >= SDLK_F1 && result <= SDLK_F12 )
65        {
66                kevent.key.code = static_cast<key_code>(result - SDLK_F1 + KEY_F1 );
67        }
68
69        // other recognized codes
70        switch ( result )
71        {
72        case SDLK_BACKSPACE    : kevent.key.code = KEY_BACK; break;
73        case SDLK_TAB          : kevent.key.code = KEY_TAB; break;
74        case SDLK_RETURN       : kevent.key.code = KEY_ENTER; break;
75        case SDLK_PAGEUP       : kevent.key.code = KEY_PGUP; break;
76        case SDLK_PAGEDOWN     : kevent.key.code = KEY_PGDOWN; break;
77        case SDLK_END          : kevent.key.code = KEY_END; break;
78        case SDLK_HOME         : kevent.key.code = KEY_HOME; break;
79        case SDLK_LEFT         : kevent.key.code = KEY_LEFT; break;
80        case SDLK_UP           : kevent.key.code = KEY_UP; break;
81        case SDLK_RIGHT        : kevent.key.code = KEY_RIGHT; break;
82        case SDLK_DOWN         : kevent.key.code = KEY_DOWN; break;
83        case SDLK_DELETE       : kevent.key.code = KEY_DELETE; break;
84        case SDLK_INSERT       : kevent.key.code = KEY_INSERT; break;
[171]85        //case SDLK_KP5          : kevent.key.code = KEY_CENTER; break;
[93]86        case SDLK_ESCAPE       : kevent.key.code = KEY_ESCAPE; break;
87        case SDLK_QUOTE        : kevent.key.code = KEY_QUOTE; break;
88        case SDLK_COMMA        : kevent.key.code = KEY_COMMA; break;
89        case SDLK_MINUS        : kevent.key.code = KEY_MINUS; break;
90        case SDLK_PERIOD       : kevent.key.code = KEY_PERIOD; break;
91        case SDLK_SLASH        : kevent.key.code = KEY_SLASH; break;
92        case SDLK_SEMICOLON    : kevent.key.code = KEY_SCOLON; break;
93        case SDLK_LEFTBRACKET  : kevent.key.code = KEY_LBRACKET; break;
94        case SDLK_BACKSLASH    : kevent.key.code = KEY_BSLASH; break;
95        case SDLK_RIGHTBRACKET : kevent.key.code = KEY_RBRACKET; break;
96        case SDLK_BACKQUOTE    : kevent.key.code = KEY_BQUOTE; break;
97        default : break;
98        }
99
100        // If key was understood by nv, then it's valid, otherwise ignored
101        return kevent.key.ascii != 0 || kevent.key.code != 0;
102}
103
104static bool sdl_mouse_button_to_io_event( const SDL_MouseButtonEvent& mb, io_event& mevent )
105{
106        mevent.type            = EV_MOUSE_BUTTON;
107        mevent.mbutton.button  = MOUSE_NONE;
108        mevent.mbutton.pressed = (mb.state != SDL_RELEASED);
[171]109        mevent.mbutton.x       = static_cast< uint16 >( mb.x );
110        mevent.mbutton.y       = static_cast< uint16 >( mb.y );
[93]111
112        switch ( mb.button )
113        {
114        case SDL_BUTTON_LEFT      : mevent.mbutton.button = MOUSE_LEFT; break;
115        case SDL_BUTTON_MIDDLE    : mevent.mbutton.button = MOUSE_MIDDLE; break;
116        case SDL_BUTTON_RIGHT     : mevent.mbutton.button = MOUSE_RIGHT; break;
[171]117        //case SDL_BUTTON_WHEELUP   : mevent.mbutton.button = MOUSE_WHEEL_UP; break;
118        //case SDL_BUTTON_WHEELDOWN : mevent.mbutton.button = MOUSE_WHEEL_DOWN; break;
[93]119        default : break;
120        }
121
122        return mevent.mbutton.button != MOUSE_NONE;
123}
124
125static bool sdl_mouse_motion_to_io_event( const SDL_MouseMotionEvent& mm, io_event& mevent )
126{
127        mevent.type          = EV_MOUSE_MOVE;
128        mevent.mmove.pressed = (mm.state != SDL_RELEASED);
[171]129        mevent.mmove.x       = static_cast< uint16 >( mm.x );
130        mevent.mmove.y       = static_cast< uint16 >( mm.y );
[93]131        return true;
132}
133
134static bool sdl_event_to_io_event( const SDL_Event& e, io_event& ioevent )
135{
136        switch ( e.type )
137        {
[98]138        case SDL_KEYDOWN         : return sdl_key_event_to_io_event( e.key, ioevent );
139        case SDL_KEYUP           : return sdl_key_event_to_io_event( e.key, ioevent );
140        case SDL_MOUSEMOTION     : return sdl_mouse_motion_to_io_event( e.motion, ioevent );
141        case SDL_MOUSEBUTTONDOWN : return sdl_mouse_button_to_io_event( e.button, ioevent );
142        case SDL_MOUSEBUTTONUP   : return sdl_mouse_button_to_io_event( e.button, ioevent );
[171]143/* // SDL 2.0 incompatible
[98]144        case SDL_ACTIVEEVENT     :
145                ioevent.type = EV_ACTIVE;
146                ioevent.active.gain = (e.active.gain != 0);
147                return e.active.state == SDL_APPINPUTFOCUS;
148        case SDL_VIDEORESIZE     :
149                ioevent.type     = EV_RESIZE;
150                ioevent.resize.x = e.resize.w;
151                ioevent.resize.y = e.resize.h;
152                return true;
[171]153        case SDL_NOEVENT         : return false;
154        case SDL_VIDEOEXPOSE     : return false;
155*/
[98]156        case SDL_SYSWMEVENT      : ioevent.type = EV_SYSTEM; return true;
157        case SDL_QUIT            : ioevent.type = EV_QUIT;   return true;
158        case SDL_JOYAXISMOTION   : return false;
159        case SDL_JOYBALLMOTION   : return false;
160        case SDL_JOYHATMOTION    : return false;
161        case SDL_JOYBUTTONDOWN   : return false;
162        case SDL_JOYBUTTONUP     : return false;
[93]163        default : return false;
164        }
165}
166
167
[98]168gl_window::gl_window( device* dev, uint16 width, uint16 height )
[171]169        : m_device( dev ), m_width( width ), m_height( height ), m_title("NV Engine"), m_handle( nullptr )
[38]170{
[171]171#if NV_SDL_VERSION == NV_SDL_12
[121]172        uint32 flags = SDL_OPENGL;
[171]173        m_handle = SDL_SetVideoMode( width, height, 32, flags );
174#elif NV_SDL_VERSION == NV_SDL_20
175        uint32 flags = SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN;
176        m_handle = SDL_CreateWindow("Nova Engine", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
177                width, height, flags );
178#endif
179        if ( m_handle == 0 )
[38]180        {
181                NV_LOG( LOG_CRITICAL, "Video mode set failed: " << SDL_GetError( ) );
182                return; // TODO: Error report
183        }
184
[171]185        m_context = new gl_context( m_device, m_handle );
[44]186        m_context->set_viewport( nv::ivec4( 0, 0, m_width, m_height ) );
[38]187}
188
189uint16 gl_window::get_width() const
190{
191        return m_width;
192}
193
194uint16 gl_window::get_height() const
195{
196        return m_height;
197}
198
199string gl_window::get_title() const
200{
201        return m_title;
202}
203
204void gl_window::set_title( const string& title )
205{
[171]206#if NV_SDL_VERSION == NV_SDL_20
207        SDL_SetWindowTitle( static_cast<SDL_Window*>( m_handle ), title.c_str() );
208#else
[38]209        SDL_WM_SetCaption( title.c_str(), title.c_str() );
[171]210#endif
[38]211        m_title = title;
212}
[44]213
[93]214bool gl_window::is_event_pending()
215{
216        return SDL_PollEvent( nullptr ) != 0;
217}
218
219bool gl_window::poll_event( io_event& event )
220{
221        SDL_Event sdl_event;
222        if ( SDL_PollEvent( &sdl_event ) == 0 ) return false;
223        return sdl_event_to_io_event( sdl_event, event );
224}
225
226void gl_window::swap_buffers()
227{
[171]228#if NV_SDL_VERSION == NV_SDL_20
229        SDL_GL_SwapWindow( static_cast<SDL_Window*>( m_handle ) );
230#else
[93]231        SDL_GL_SwapBuffers();
[171]232#endif
[93]233}
234
[44]235gl_window::~gl_window()
236{
237        delete m_context;
[171]238#if NV_SDL_VERSION == NV_SDL_20
239        SDL_DestroyWindow( static_cast<SDL_Window*>( m_handle ) );
240#endif
[44]241}
Note: See TracBrowser for help on using the repository browser.