]> Dogcows Code - chaz/yoink/blob - src/Moof/Video.cc
8610a7b8be499e1106d741433d98f7beab9cb513
[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 "Serializable.hh"
36 #include "Settings.hh"
37 #include "Video.hh"
38
39
40 namespace Mf {
41
42
43 Video::Video()
44 {
45 init(attribs_);
46 }
47
48 Video::Video(const Attributes& attribs)
49 {
50 init(attribs);
51 }
52
53 Video::Video(const std::string& caption, const std::string& icon)
54 {
55 if (attribs_.caption == "Untitled")
56 {
57 attribs_.caption = caption;
58 }
59 if (attribs_.icon == "")
60 {
61 attribs_.icon = icon;
62 }
63
64 init(attribs_);
65 }
66
67 void Video::init(const Attributes& attribs)
68 {
69 context_ = 0;
70 flags_ = 0;
71 attribs_ = attribs;
72
73 setFull(attribs.fullscreen);
74 setResizable(attribs.resizable);
75 setOpenGLAttributes();
76 setCaption(attribs.caption);
77 setIcon();
78 setCursorVisible(attribs.cursorVisible);
79 setCursorGrab(attribs.cursorGrab);
80 setVideoMode(attribs.mode);
81 }
82
83 void Video::recreateContext()
84 {
85 SDL_FreeSurface(context_);
86 context_ = 0;
87 setVideoMode(attribs_.mode);
88 }
89
90 void Video::setOpenGLAttributes()
91 {
92 SDL_GL_SetAttribute(SDL_GL_RED_SIZE, attribs_.colorBuffer[0]);
93 SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, attribs_.colorBuffer[1]);
94 SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, attribs_.colorBuffer[2]);
95 SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, attribs_.colorBuffer[3]);
96 SDL_GL_SetAttribute(SDL_GL_BUFFER_SIZE, attribs_.frameBuffer);
97 SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, attribs_.doubleBuffer);
98 SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, attribs_.depthBuffer);
99 SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, attribs_.stencilBuffer);
100 SDL_GL_SetAttribute(SDL_GL_ACCUM_RED_SIZE, attribs_.accumBuffer[0]);
101 SDL_GL_SetAttribute(SDL_GL_ACCUM_GREEN_SIZE, attribs_.accumBuffer[1]);
102 SDL_GL_SetAttribute(SDL_GL_ACCUM_BLUE_SIZE, attribs_.accumBuffer[2]);
103 SDL_GL_SetAttribute(SDL_GL_ACCUM_ALPHA_SIZE, attribs_.accumBuffer[3]);
104 SDL_GL_SetAttribute(SDL_GL_STEREO, attribs_.stereo);
105 SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, attribs_.multisampleBuffers);
106 SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, attribs_.multisampleSamples);
107 SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, attribs_.swapControl);
108 SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, attribs_.hardwareonly);
109 }
110
111
112 Video::~Video()
113 {
114 SDL_FreeSurface(context_);
115 }
116
117
118 void Video::setVideoMode(const long mode[3])
119 {
120 if (mode != attribs_.mode || !context_)
121 {
122 if (context_) SDL_FreeSurface(context_);
123
124 context_ = SDL_SetVideoMode(mode[0], mode[1], mode[2],
125 SDL_OPENGL | flags_);
126
127 if (context_)
128 {
129 attribs_.mode[0] = mode[0];
130 attribs_.mode[1] = mode[1];
131 attribs_.mode[2] = mode[2];
132
133 #if defined(_WIN32) || defined (_WIN64) || defined(__WIN32__)
134 // on win32, creating a new context via SDL_SetVideoMode will wipe
135 // out the GL state, so we gotta notify everyone to reload their
136 // state after the change
137 Mf::dispatcher::dispatch("video.context_recreated");
138 logInfo("video context recreated");
139 #endif
140 }
141 else throw Exception(Exception::SDL_ERROR);
142 }
143 }
144
145 Video::Attributes Video::getAttributes() const
146 {
147 return attribs_;
148 }
149
150
151 void Video::resize(int width, int height)
152 {
153 long mode[] = {width, height, attribs_.mode[2]};
154 setVideoMode(mode);
155 }
156
157 bool Video::iconify()
158 {
159 return SDL_WM_IconifyWindow();
160 }
161
162
163 void Video::setCaption(const std::string& caption)
164 {
165 attribs_.caption = caption;
166 SDL_WM_SetCaption(caption.c_str(), 0);
167 }
168
169 void Video::setIcon()
170 {
171 if (attribs_.icon != "")
172 {
173 SDL_Surface* icon = IMG_Load(attribs_.icon.c_str());
174 if (icon)
175 {
176 SDL_WM_SetIcon(icon, 0);
177 SDL_FreeSurface(icon);
178 }
179 }
180 }
181
182 std::string Video::getCaption() const
183 {
184 return attribs_.caption;
185 }
186
187
188 void Video::setFull(bool full)
189 {
190 if (full != isFull() || !context_)
191 {
192 if (context_)
193 {
194 flags_ ^= SDL_FULLSCREEN;
195
196 #if defined(linux) || defined(__linux) || defined(__linux__)
197 if (SDL_WM_ToggleFullScreen(context_) == 0)
198 #endif
199 recreateContext();
200 }
201 else
202 {
203 if (full) flags_ |= SDL_FULLSCREEN;
204 else flags_ &= ~SDL_FULLSCREEN;
205 }
206 }
207 }
208
209 void Video::toggleFull()
210 {
211 setFull(!isFull());
212 }
213
214 bool Video::isFull() const
215 {
216 return flags_ & SDL_FULLSCREEN;
217 }
218
219
220 void Video::setCursorVisible(bool hasCursor)
221 {
222 SDL_ShowCursor(hasCursor? SDL_ENABLE : SDL_DISABLE);
223 }
224
225 void Video::toggleCursorVisible()
226 {
227 setCursorVisible(!isCursorVisible());
228 }
229
230 bool Video::isCursorVisible() const
231 {
232 return (SDL_ShowCursor(SDL_QUERY) == SDL_ENABLE);
233 }
234
235
236 void Video::setResizable(bool resizable)
237 {
238 if (resizable != isResizable() || !context_)
239 {
240 if (context_)
241 {
242 flags_ ^= SDL_RESIZABLE;
243 recreateContext();
244 }
245 else
246 {
247 if (resizable) flags_ |= SDL_RESIZABLE;
248 else flags_ &= ~SDL_RESIZABLE;
249 }
250 }
251 }
252
253 void Video::toggleResizable()
254 {
255 setResizable(!isResizable());
256 }
257
258 bool Video::isResizable() const
259 {
260 return flags_ & SDL_RESIZABLE;
261 }
262
263
264 bool Video::isCursorGrab() const
265 {
266 return (SDL_WM_GrabInput(SDL_GRAB_QUERY) == SDL_GRAB_ON);
267 }
268
269 void Video::toggleCursorGrab()
270 {
271 setCursorGrab(!isCursorGrab());
272 }
273
274 void Video::setCursorGrab(bool cursorGrab)
275 {
276 SDL_WM_GrabInput(cursorGrab? SDL_GRAB_ON : SDL_GRAB_OFF);
277 }
278
279
280 void Video::makeActive()
281 {
282 // NOP until the day SDL supports more than only one window.
283 // Still waiting...
284 }
285
286 void Video::swap()
287 {
288 SDL_GL_SwapBuffers();
289 }
290
291
292 Video::Attributes::Attributes()
293 {
294 // Set some sane GL and window defaults (see SDL_video.c:217)
295 colorBuffer[0] = 3;
296 colorBuffer[1] = 3;
297 colorBuffer[2] = 2;
298 colorBuffer[3] = 0;
299 frameBuffer = 0;
300 doubleBuffer = true;
301 depthBuffer = 16;
302 stencilBuffer = 0;
303 accumBuffer[0] = 0;
304 accumBuffer[1] = 0;
305 accumBuffer[2] = 0;
306 accumBuffer[3] = 0;
307 stereo = false;
308 multisampleBuffers = 0;
309 multisampleSamples = 0;
310 swapControl = false;
311 hardwareonly = false;
312 mode[0] = 640;
313 mode[1] = 480;
314 mode[2] = 0;
315 fullscreen = false;
316 resizable = false;
317 cursorVisible = true;
318 cursorGrab = false;
319
320 Settings& settings = Settings::getInstance();
321
322 Serializable::Array colors;
323 settings.get("video.colorbuffers", colors);
324 if (colors.size() > 0) colors[0]->get(colorBuffer[0]);
325 if (colors.size() > 1) colors[1]->get(colorBuffer[1]);
326 if (colors.size() > 2) colors[2]->get(colorBuffer[2]);
327 if (colors.size() > 3) colors[3]->get(colorBuffer[3]);
328
329 settings.get("video.framebuffer", frameBuffer);
330 settings.get("video.doublebuffer", doubleBuffer);
331 settings.get("video.depthbuffer", depthBuffer);
332 settings.get("video.stencilbuffer", stencilBuffer);
333
334 Serializable::Array accum;
335 settings.get("video.accumbuffers", accum);
336 if (accum.size() > 0) accum[0]->get(accumBuffer[0]);
337 if (accum.size() > 1) accum[1]->get(accumBuffer[1]);
338 if (accum.size() > 2) accum[2]->get(accumBuffer[2]);
339 if (accum.size() > 3) accum[3]->get(accumBuffer[3]);
340
341 settings.get("video.stereo", stereo);
342 settings.get("video.multiesamplebuffers", multisampleBuffers);
343 settings.get("video.multiesamplesamples", multisampleSamples);
344 settings.get("video.swapcontrol", swapControl);
345 settings.get("video.hardwareonly", hardwareonly);
346
347 if (!settings.get("video.caption", caption))
348 {
349 caption = "Untitled";
350 }
351 settings.get("video.icon", icon);
352
353 Serializable::Array dimensions;
354 settings.get("video.mode", dimensions);
355 if (dimensions.size() > 0) dimensions[0]->get(mode[0]);
356 if (dimensions.size() > 1) dimensions[1]->get(mode[1]);
357 if (dimensions.size() > 2) dimensions[2]->get(mode[2]);
358
359 settings.get("video.fullscreen", fullscreen);
360 settings.get("video.resizable", resizable);
361 settings.get("video.showcursor", cursorVisible);
362 settings.get("input.grab", cursorGrab);
363 }
364
365
366 } // namespace Mf
367
368 /** vim: set ts=4 sw=4 tw=80: *************************************************/
369
This page took 0.047659 seconds and 4 git commands to generate.