]> Dogcows Code - chaz/yoink/blob - src/moof/video.cc
aa49b03c249b9d2927d0b43e52adfd5a8a8b357b
[chaz/yoink] / src / moof / video.cc
1
2 /*] Copyright (c) 2009-2010, Charles McGarvey [**************************
3 **] All rights reserved.
4 *
5 * vi:ts=4 sw=4 tw=75
6 *
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.
9 *
10 **************************************************************************/
11
12 #include <stdexcept>
13
14 #include "dispatcher.hh"
15 #include "image.hh"
16 #include "log.hh"
17 #include "settings.hh"
18 #include "video.hh"
19
20
21 namespace moof {
22
23
24 video::video(const std::string& caption)
25 {
26 video::caption(caption);
27 init();
28 }
29
30 video::video(const class attributes& attribs) :
31 attributes_(attribs)
32 {
33 init();
34 }
35
36 video::video(const std::string& caption,
37 const class attributes& attribs) :
38 attributes_(attribs)
39 {
40 video::caption(caption);
41 init();
42 }
43
44 void video::init()
45 {
46 context_ = 0;
47 flags_ = 0;
48
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);
55
56 if (!current_) make_current();
57 }
58
59 void video::recreate_context()
60 {
61 SDL_FreeSurface(context_);
62 context_ = 0;
63 mode(attributes_.mode);
64 }
65
66 void video::set_opengl_attributes()
67 {
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);
102 }
103
104
105 video::~video()
106 {
107 SDL_FreeSurface(context_);
108
109 if (current_ == this) current_ = 0;
110 }
111
112
113 class video::attributes video::attributes() const
114 {
115 return attributes_;
116 }
117
118
119 void video::mode(const int mode[3])
120 {
121 if (mode != attributes_.mode || !context_)
122 {
123 if (context_) SDL_FreeSurface(context_);
124
125 context_ = SDL_SetVideoMode(mode[0], mode[1], mode[2],
126 SDL_OPENGL | flags_);
127
128 if (context_)
129 {
130 attributes_.mode[0] = mode[0];
131 attributes_.mode[1] = mode[1];
132 attributes_.mode[2] = mode[2];
133
134 #if !defined(linux) && !defined(__linux) && !defined(__linux__)
135 log_info("video context recreated");
136 dispatcher::global().dispatch("video.newcontext");
137 #endif
138 }
139 else
140 {
141 throw std::runtime_error("bad video mode attempted");
142 }
143 }
144 }
145
146
147 void video::resize(int width, int height)
148 {
149 int mode[] = {width, height, attributes_.mode[2]};
150 video::mode(mode);
151 }
152
153 bool video::iconify()
154 {
155 return SDL_WM_IconifyWindow();
156 }
157
158
159 void video::caption(const std::string& caption)
160 {
161 SDL_WM_SetCaption(caption.c_str(), 0);
162 }
163
164 std::string video::caption() const
165 {
166 char* caption;
167 SDL_WM_GetCaption(&caption, 0);
168 return std::string(caption);
169 }
170
171
172 void video::fullscreen(bool full)
173 {
174 if (full != fullscreen() || !context_)
175 {
176 if (context_)
177 {
178 flags_ ^= SDL_FULLSCREEN;
179
180 #if defined(linux) || defined(__linux) || defined(__linux__)
181 if (SDL_WM_ToggleFullScreen(context_) == 0)
182 #endif
183 recreate_context();
184 }
185 else
186 {
187 if (full) flags_ |= SDL_FULLSCREEN;
188 else flags_ &= ~SDL_FULLSCREEN;
189 }
190 }
191 }
192
193 bool video::fullscreen() const
194 {
195 return flags_ & SDL_FULLSCREEN;
196 }
197
198 void video::toggle_fullscreen()
199 {
200 fullscreen(!fullscreen());
201 }
202
203
204 void video::resizable(bool is_resizable)
205 {
206 if (is_resizable != resizable() || !context_)
207 {
208 if (context_)
209 {
210 flags_ ^= SDL_RESIZABLE;
211 recreate_context();
212 }
213 else
214 {
215 if (is_resizable) flags_ |= SDL_RESIZABLE;
216 else flags_ &= ~SDL_RESIZABLE;
217 }
218 }
219 }
220
221 bool video::resizable() const
222 {
223 return flags_ & SDL_RESIZABLE;
224 }
225
226 void video::toggle_resizable()
227 {
228 resizable(!resizable());
229 }
230
231
232 void video::cursor_visible(bool is_cursor_visible)
233 {
234 SDL_ShowCursor(is_cursor_visible? SDL_ENABLE : SDL_DISABLE);
235 }
236
237 bool video::cursor_visible() const
238 {
239 return (SDL_ShowCursor(SDL_QUERY) == SDL_ENABLE);
240 }
241
242 void video::toggle_cursor_visible()
243 {
244 cursor_visible(!cursor_visible());
245 }
246
247
248 bool video::cursor_captured() const
249 {
250 return (SDL_WM_GrabInput(SDL_GRAB_QUERY) == SDL_GRAB_ON);
251 }
252
253 void video::cursor_captured(bool is_cursor_captured)
254 {
255 SDL_WM_GrabInput(is_cursor_captured? SDL_GRAB_ON : SDL_GRAB_OFF);
256 }
257
258 void video::toggle_cursor_captured()
259 {
260 cursor_captured(!cursor_captured());
261 }
262
263
264 void video::swap()
265 {
266 SDL_GL_SwapBuffers();
267 }
268
269
270 int video::width() const
271 {
272 return context_->w;
273 }
274
275 int video::height() const
276 {
277 return context_->h;
278 }
279
280
281 void video::make_current() const
282 {
283 current_ = const_cast<video*>(this);
284 }
285
286
287 video::attributes::attributes()
288 {
289 init();
290 }
291
292 video::attributes::attributes(const settings& settings)
293 {
294 init();
295
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];
302
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);
307
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];
314
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);
320
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);
325
326 std::vector<int> dimensions;
327 settings.get("videomode", dimensions);
328 if (dimensions.size() > 1)
329 {
330 mode[0] = dimensions[0];
331 mode[1] = dimensions[1];
332 }
333 else if (is_fullscreen && backend::is_initialized())
334 {
335 SDL_Rect** modes = SDL_ListModes(NULL,
336 SDL_FULLSCREEN | SDL_HWSURFACE);
337
338 if (modes == (SDL_Rect**)0)
339 {
340 throw std::runtime_error("can't find appropriate video mode");
341 }
342 else if (modes == (SDL_Rect**)-1)
343 {
344 log_warning("any resolution allowed; choosing default 800x600");
345 mode[0] = 800;
346 mode[1] = 600;
347 }
348 else
349 {
350 mode[0] = (*modes)->w;
351 mode[1] = (*modes)->h;
352 log_info << "choosing native resolution: "
353 << mode[0] << "x" << mode[1] << std::endl;
354 }
355 }
356 if (dimensions.size() > 2) mode[2] = dimensions[2];
357 }
358
359 void video::attributes::init()
360 {
361 // set some sane GL and window defaults (see SDL_video.c:217)
362 color_buffer[0] = 3;
363 color_buffer[1] = 3;
364 color_buffer[2] = 2;
365 color_buffer[3] = 0;
366 frame_buffer = 0;
367 is_double_buffer = true;
368 depth_buffer = 16;
369 stencil_buffer = 0;
370 accumulator_buffer[0] = 0;
371 accumulator_buffer[1] = 0;
372 accumulator_buffer[2] = 0;
373 accumulator_buffer[3] = 0;
374 is_stereo = false;
375 multisample_buffers = 0;
376 multisample_samples = 0;
377 is_swap_control = false;
378 is_hardware_only = false;
379 mode[0] = 640;
380 mode[1] = 480;
381 mode[2] = 0;
382 is_fullscreen = false;
383 is_resizable = false;
384 is_cursor_visible = true;
385 is_cursor_captured = false;
386 }
387
388
389 video* video::current_ = 0; // most recently instantiated instance
390
391
392 } // namespace moof
393
This page took 0.045722 seconds and 3 git commands to generate.