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

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