2 /*] Copyright (c) 2009-2010, Charles McGarvey [**************************
3 **] All rights reserved.
7 * Distributable under the terms and conditions of the 2-clause BSD license;
8 * see the file COPYING for a complete text of the license.
10 **************************************************************************/
14 #include "dispatcher.hh"
17 #include "settings.hh"
24 video::video(const std::string
& caption
)
26 video::caption(caption
);
30 video::video(const class attributes
& attribs
) :
36 video::video(const std::string
& caption
,
37 const class attributes
& attribs
) :
40 video::caption(caption
);
49 fullscreen(attributes_
.is_fullscreen
);
50 resizable(attributes_
.is_resizable
);
51 set_opengl_attributes();
52 cursor_visible(attributes_
.is_cursor_visible
);
53 cursor_captured(attributes_
.is_cursor_captured
);
54 mode(attributes_
.mode
);
56 if (!current_
) make_current();
59 void video::recreate_context()
61 SDL_FreeSurface(context_
);
63 mode(attributes_
.mode
);
66 void video::set_opengl_attributes()
68 SDL_GL_SetAttribute(SDL_GL_RED_SIZE
,
69 attributes_
.color_buffer
[0]);
70 SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE
,
71 attributes_
.color_buffer
[1]);
72 SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE
,
73 attributes_
.color_buffer
[2]);
74 SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE
,
75 attributes_
.color_buffer
[3]);
76 SDL_GL_SetAttribute(SDL_GL_BUFFER_SIZE
,
77 attributes_
.frame_buffer
);
78 SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER
,
79 attributes_
.is_double_buffer
);
80 SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE
,
81 attributes_
.depth_buffer
);
82 SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE
,
83 attributes_
.stencil_buffer
);
84 SDL_GL_SetAttribute(SDL_GL_ACCUM_RED_SIZE
,
85 attributes_
.accumulator_buffer
[0]);
86 SDL_GL_SetAttribute(SDL_GL_ACCUM_GREEN_SIZE
,
87 attributes_
.accumulator_buffer
[1]);
88 SDL_GL_SetAttribute(SDL_GL_ACCUM_BLUE_SIZE
,
89 attributes_
.accumulator_buffer
[2]);
90 SDL_GL_SetAttribute(SDL_GL_ACCUM_ALPHA_SIZE
,
91 attributes_
.accumulator_buffer
[3]);
92 SDL_GL_SetAttribute(SDL_GL_STEREO
,
93 attributes_
.is_stereo
);
94 SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS
,
95 attributes_
.multisample_buffers
);
96 SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES
,
97 attributes_
.multisample_samples
);
98 SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL
,
99 attributes_
.is_swap_control
);
100 SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL
,
101 attributes_
.is_hardware_only
);
107 SDL_FreeSurface(context_
);
109 if (current_
== this) current_
= 0;
113 class video::attributes
video::attributes() const
119 void video::mode(const int mode
[3])
121 if (mode
!= attributes_
.mode
|| !context_
)
123 if (context_
) SDL_FreeSurface(context_
);
125 context_
= SDL_SetVideoMode(mode
[0], mode
[1], mode
[2],
126 SDL_OPENGL
| flags_
);
130 attributes_
.mode
[0] = mode
[0];
131 attributes_
.mode
[1] = mode
[1];
132 attributes_
.mode
[2] = mode
[2];
134 #if !defined(linux) && !defined(__linux) && !defined(__linux__)
135 log_info("video context recreated");
136 dispatcher::global().dispatch("video.newcontext");
141 throw std::runtime_error("bad video mode attempted");
147 void video::resize(int width
, int height
)
149 int mode
[] = {width
, height
, attributes_
.mode
[2]};
153 bool video::iconify()
155 return SDL_WM_IconifyWindow();
159 void video::caption(const std::string
& caption
)
161 SDL_WM_SetCaption(caption
.c_str(), 0);
164 std::string
video::caption() const
167 SDL_WM_GetCaption(&caption
, 0);
168 return std::string(caption
);
172 void video::fullscreen(bool full
)
174 if (full
!= fullscreen() || !context_
)
178 flags_
^= SDL_FULLSCREEN
;
180 #if defined(linux) || defined(__linux) || defined(__linux__)
181 if (SDL_WM_ToggleFullScreen(context_
) == 0)
187 if (full
) flags_
|= SDL_FULLSCREEN
;
188 else flags_
&= ~SDL_FULLSCREEN
;
193 bool video::fullscreen() const
195 return flags_
& SDL_FULLSCREEN
;
198 void video::toggle_fullscreen()
200 fullscreen(!fullscreen());
204 void video::resizable(bool is_resizable
)
206 if (is_resizable
!= resizable() || !context_
)
210 flags_
^= SDL_RESIZABLE
;
215 if (is_resizable
) flags_
|= SDL_RESIZABLE
;
216 else flags_
&= ~SDL_RESIZABLE
;
221 bool video::resizable() const
223 return flags_
& SDL_RESIZABLE
;
226 void video::toggle_resizable()
228 resizable(!resizable());
232 void video::cursor_visible(bool is_cursor_visible
)
234 SDL_ShowCursor(is_cursor_visible
? SDL_ENABLE
: SDL_DISABLE
);
237 bool video::cursor_visible() const
239 return (SDL_ShowCursor(SDL_QUERY
) == SDL_ENABLE
);
242 void video::toggle_cursor_visible()
244 cursor_visible(!cursor_visible());
248 bool video::cursor_captured() const
250 return (SDL_WM_GrabInput(SDL_GRAB_QUERY
) == SDL_GRAB_ON
);
253 void video::cursor_captured(bool is_cursor_captured
)
255 SDL_WM_GrabInput(is_cursor_captured
? SDL_GRAB_ON
: SDL_GRAB_OFF
);
258 void video::toggle_cursor_captured()
260 cursor_captured(!cursor_captured());
266 SDL_GL_SwapBuffers();
270 int video::width() const
275 int video::height() const
281 void video::make_current() const
283 current_
= const_cast<video
*>(this);
287 video::attributes::attributes()
292 video::attributes::attributes(const settings
& settings
)
296 std::vector
<int> colors
;
297 settings
.get("colorbuffers", colors
);
298 if (colors
.size() > 0) color_buffer
[0] = colors
[0];
299 if (colors
.size() > 1) color_buffer
[1] = colors
[1];
300 if (colors
.size() > 2) color_buffer
[2] = colors
[2];
301 if (colors
.size() > 3) color_buffer
[3] = colors
[3];
303 settings
.get("framebuffer", frame_buffer
);
304 settings
.get("doublebuffer", is_double_buffer
);
305 settings
.get("depthbuffer", depth_buffer
);
306 settings
.get("stencilbuffer", stencil_buffer
);
308 std::vector
<int> accum
;
309 settings
.get("accumbuffers", accum
);
310 if (accum
.size() > 0) accumulator_buffer
[0] = accum
[0];
311 if (accum
.size() > 1) accumulator_buffer
[1] = accum
[1];
312 if (accum
.size() > 2) accumulator_buffer
[2] = accum
[2];
313 if (accum
.size() > 3) accumulator_buffer
[3] = accum
[3];
315 settings
.get("stereo", is_stereo
);
316 settings
.get("multiesamplebuffers", multisample_buffers
);
317 settings
.get("multiesamplesamples", multisample_samples
);
318 settings
.get("swapcontrol", is_swap_control
);
319 settings
.get("hardwareonly", is_hardware_only
);
321 settings
.get("fullscreen", is_fullscreen
);
322 settings
.get("resizable", is_resizable
);
323 settings
.get("showcursor", is_cursor_visible
);
324 settings
.get("capturecursor", is_cursor_captured
);
326 std::vector
<int> dimensions
;
327 settings
.get("videomode", dimensions
);
328 if (dimensions
.size() > 1)
330 mode
[0] = dimensions
[0];
331 mode
[1] = dimensions
[1];
333 else if (is_fullscreen
&& backend::is_initialized())
335 SDL_Rect
** modes
= SDL_ListModes(NULL
,
336 SDL_FULLSCREEN
| SDL_HWSURFACE
);
338 if (modes
== (SDL_Rect
**)0)
340 throw std::runtime_error("can't find appropriate video mode");
342 else if (modes
== (SDL_Rect
**)-1)
344 log_warning("any resolution allowed; choosing default 800x600");
350 mode
[0] = (*modes
)->w
;
351 mode
[1] = (*modes
)->h
;
352 log_info
<< "choosing native resolution: "
353 << mode
[0] << "x" << mode
[1] << std::endl
;
356 if (dimensions
.size() > 2) mode
[2] = dimensions
[2];
359 void video::attributes::init()
361 // set some sane GL and window defaults (see SDL_video.c:217)
367 is_double_buffer
= true;
370 accumulator_buffer
[0] = 0;
371 accumulator_buffer
[1] = 0;
372 accumulator_buffer
[2] = 0;
373 accumulator_buffer
[3] = 0;
375 multisample_buffers
= 0;
376 multisample_samples
= 0;
377 is_swap_control
= false;
378 is_hardware_only
= false;
382 is_fullscreen
= false;
383 is_resizable
= false;
384 is_cursor_visible
= true;
385 is_cursor_captured
= false;
389 video
* video::current_
= 0; // most recently instantiated instance