]> Dogcows Code - chaz/yoink/blob - src/Moof/Video.cc
8de161aa085daca5f087500869eb4067f329b34d
[chaz/yoink] / src / Moof / Video.cc
1
2 /*******************************************************************************
3
4 Copyright (c) 2009, Charles McGarvey
5 All rights reserved.
6
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions are met:
9
10 * Redistributions of source code must retain the above copyright notice,
11 this list of conditions and the following disclaimer.
12 * Redistributions in binary form must reproduce the above copyright notice,
13 this list of conditions and the following disclaimer in the documentation
14 and/or other materials provided with the distribution.
15
16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
20 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
27 *******************************************************************************/
28
29 #include <stdexcept>
30
31 #include <SDL/SDL_image.h>
32
33 #include "Dispatcher.hh"
34 #include "Log.hh"
35 #include "Settings.hh"
36 #include "Video.hh"
37
38
39 namespace Mf {
40
41
42 Video::Video()
43 {
44 init(attribs_);
45 }
46
47 Video::Video(const Attributes& attribs)
48 {
49 init(attribs);
50 }
51
52 Video::Video(const std::string& caption, const std::string& icon)
53 {
54 if (attribs_.caption == "Untitled")
55 {
56 attribs_.caption = caption;
57 }
58 if (attribs_.icon == "")
59 {
60 attribs_.icon = icon;
61 }
62
63 init(attribs_);
64 }
65
66 void Video::init(const Attributes& attribs)
67 {
68 context_ = 0;
69 flags_ = 0;
70 attribs_ = attribs;
71
72 setFull(attribs.fullscreen);
73 setResizable(attribs.resizable);
74 setOpenGLAttributes();
75 setCaption(attribs.caption);
76 setIcon();
77 setCursorVisible(attribs.cursorVisible);
78 setCursorGrab(attribs.cursorGrab);
79 setVideoMode(attribs.mode);
80 }
81
82 void Video::recreateContext()
83 {
84 SDL_FreeSurface(context_);
85 context_ = 0;
86 setVideoMode(attribs_.mode);
87 }
88
89 void Video::setOpenGLAttributes()
90 {
91 SDL_GL_SetAttribute(SDL_GL_RED_SIZE, attribs_.colorBuffer[0]);
92 SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, attribs_.colorBuffer[1]);
93 SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, attribs_.colorBuffer[2]);
94 SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, attribs_.colorBuffer[3]);
95 SDL_GL_SetAttribute(SDL_GL_BUFFER_SIZE, attribs_.frameBuffer);
96 SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, attribs_.doubleBuffer);
97 SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, attribs_.depthBuffer);
98 SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, attribs_.stencilBuffer);
99 SDL_GL_SetAttribute(SDL_GL_ACCUM_RED_SIZE, attribs_.accumBuffer[0]);
100 SDL_GL_SetAttribute(SDL_GL_ACCUM_GREEN_SIZE, attribs_.accumBuffer[1]);
101 SDL_GL_SetAttribute(SDL_GL_ACCUM_BLUE_SIZE, attribs_.accumBuffer[2]);
102 SDL_GL_SetAttribute(SDL_GL_ACCUM_ALPHA_SIZE, attribs_.accumBuffer[3]);
103 SDL_GL_SetAttribute(SDL_GL_STEREO, attribs_.stereo);
104 SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, attribs_.multisampleBuffers);
105 SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, attribs_.multisampleSamples);
106 SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, attribs_.swapControl);
107 SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, attribs_.hardwareonly);
108 }
109
110
111 Video::~Video()
112 {
113 SDL_FreeSurface(context_);
114 }
115
116
117 void Video::setVideoMode(const long mode[3])
118 {
119 if (mode != attribs_.mode || !context_)
120 {
121 if (context_) SDL_FreeSurface(context_);
122
123 context_ = SDL_SetVideoMode(mode[0], mode[1], mode[2],
124 SDL_OPENGL | flags_);
125
126 if (context_)
127 {
128 attribs_.mode[0] = mode[0];
129 attribs_.mode[1] = mode[1];
130 attribs_.mode[2] = mode[2];
131
132 #if defined(_WIN32) || defined (_WIN64) || defined(__WIN32__)
133 // on win32, creating a new context via SDL_SetVideoMode will wipe
134 // out the GL state, so we gotta notify everyone to reload their
135 // state after the change
136 Mf::dispatcher::dispatch("video.context_recreated");
137 logInfo("video context recreated");
138 #endif
139 }
140 else throw Exception(Exception::SDL_ERROR);
141 }
142 }
143
144 Video::Attributes Video::getAttributes() const
145 {
146 return attribs_;
147 }
148
149
150 void Video::resize(int width, int height)
151 {
152 long mode[] = {width, height, attribs_.mode[2]};
153 setVideoMode(mode);
154 }
155
156 bool Video::iconify()
157 {
158 return SDL_WM_IconifyWindow();
159 }
160
161
162 void Video::setCaption(const std::string& caption)
163 {
164 attribs_.caption = caption;
165 SDL_WM_SetCaption(caption.c_str(), 0);
166 }
167
168 void Video::setIcon()
169 {
170 if (attribs_.icon != "")
171 {
172 SDL_Surface* icon = IMG_Load(attribs_.icon.c_str());
173 if (icon)
174 {
175 SDL_WM_SetIcon(icon, 0);
176 SDL_FreeSurface(icon);
177 }
178 }
179 }
180
181 std::string Video::getCaption() const
182 {
183 return attribs_.caption;
184 }
185
186
187 void Video::setFull(bool full)
188 {
189 if (full != isFull() || !context_)
190 {
191 if (context_)
192 {
193 flags_ ^= SDL_FULLSCREEN;
194
195 #if defined(linux) || defined(__linux) || defined(__linux__)
196 if (SDL_WM_ToggleFullScreen(context_) == 0)
197 #endif
198 recreateContext();
199 }
200 else
201 {
202 if (full) flags_ |= SDL_FULLSCREEN;
203 else flags_ &= ~SDL_FULLSCREEN;
204 }
205 }
206 }
207
208 void Video::toggleFull()
209 {
210 setFull(!isFull());
211 }
212
213 bool Video::isFull() const
214 {
215 return flags_ & SDL_FULLSCREEN;
216 }
217
218
219 void Video::setCursorVisible(bool hasCursor)
220 {
221 SDL_ShowCursor(hasCursor? SDL_ENABLE : SDL_DISABLE);
222 }
223
224 void Video::toggleCursorVisible()
225 {
226 setCursorVisible(!isCursorVisible());
227 }
228
229 bool Video::isCursorVisible() const
230 {
231 return (SDL_ShowCursor(SDL_QUERY) == SDL_ENABLE);
232 }
233
234
235 void Video::setResizable(bool resizable)
236 {
237 if (resizable != isResizable() || !context_)
238 {
239 if (context_)
240 {
241 flags_ ^= SDL_RESIZABLE;
242 recreateContext();
243 }
244 else
245 {
246 if (resizable) flags_ |= SDL_RESIZABLE;
247 else flags_ &= ~SDL_RESIZABLE;
248 }
249 }
250 }
251
252 void Video::toggleResizable()
253 {
254 setResizable(!isResizable());
255 }
256
257 bool Video::isResizable() const
258 {
259 return flags_ & SDL_RESIZABLE;
260 }
261
262
263 bool Video::isCursorGrab() const
264 {
265 return (SDL_WM_GrabInput(SDL_GRAB_QUERY) == SDL_GRAB_ON);
266 }
267
268 void Video::toggleCursorGrab()
269 {
270 setCursorGrab(!isCursorGrab());
271 }
272
273 void Video::setCursorGrab(bool cursorGrab)
274 {
275 SDL_WM_GrabInput(cursorGrab? SDL_GRAB_ON : SDL_GRAB_OFF);
276 }
277
278
279 void Video::makeActive()
280 {
281 // NOP until the day SDL supports more than only one window.
282 // Still waiting...
283 }
284
285 void Video::swap()
286 {
287 SDL_GL_SwapBuffers();
288 }
289
290
291 int Video::getWidth() const
292 {
293 return context_->w;
294 }
295
296 int Video::getHeight() const
297 {
298 return context_->h;
299 }
300
301
302 Video::Attributes::Attributes()
303 {
304 // Set some sane GL and window defaults (see SDL_video.c:217)
305 colorBuffer[0] = 3;
306 colorBuffer[1] = 3;
307 colorBuffer[2] = 2;
308 colorBuffer[3] = 0;
309 frameBuffer = 0;
310 doubleBuffer = true;
311 depthBuffer = 16;
312 stencilBuffer = 0;
313 accumBuffer[0] = 0;
314 accumBuffer[1] = 0;
315 accumBuffer[2] = 0;
316 accumBuffer[3] = 0;
317 stereo = false;
318 multisampleBuffers = 0;
319 multisampleSamples = 0;
320 swapControl = false;
321 hardwareonly = false;
322 mode[0] = 640;
323 mode[1] = 480;
324 mode[2] = 0;
325 fullscreen = false;
326 resizable = false;
327 cursorVisible = true;
328 cursorGrab = false;
329
330 Settings& settings = Settings::getInstance();
331
332 std::vector<long> colors;
333 settings.get("colorbuffers", colors);
334 if (colors.size() > 0) colorBuffer[0] = colors[0];
335 if (colors.size() > 1) colorBuffer[1] = colors[1];
336 if (colors.size() > 2) colorBuffer[2] = colors[2];
337 if (colors.size() > 3) colorBuffer[3] = colors[3];
338
339 settings.get("framebuffer", frameBuffer);
340 settings.get("doublebuffer", doubleBuffer);
341 settings.get("depthbuffer", depthBuffer);
342 settings.get("stencilbuffer", stencilBuffer);
343
344 std::vector<long> accum;
345 settings.get("accumbuffers", accum);
346 if (accum.size() > 0) accumBuffer[0] = accum[0];
347 if (accum.size() > 1) accumBuffer[1] = accum[1];
348 if (accum.size() > 2) accumBuffer[2] = accum[2];
349 if (accum.size() > 3) accumBuffer[3] = accum[3];
350
351 settings.get("stereo", stereo);
352 settings.get("multiesamplebuffers", multisampleBuffers);
353 settings.get("multiesamplesamples", multisampleSamples);
354 settings.get("swapcontrol", swapControl);
355 settings.get("hardwareonly", hardwareonly);
356
357 if (!settings.get("caption", caption))
358 {
359 caption = "Untitled";
360 }
361 settings.get("icon", icon);
362
363 std::vector<long> dimensions;
364 settings.get("videomode", dimensions);
365 if (dimensions.size() > 1)
366 {
367 mode[0] = dimensions[0];
368 mode[1] = dimensions[1];
369 }
370 if (dimensions.size() > 2) mode[2] = dimensions[2];
371
372 settings.get("fullscreen", fullscreen);
373 settings.get("resizable", resizable);
374 settings.get("showcursor", cursorVisible);
375 settings.get("grab", cursorGrab);
376 }
377
378
379 } // namespace Mf
380
381 /** vim: set ts=4 sw=4 tw=80: *************************************************/
382
This page took 0.052722 seconds and 3 git commands to generate.