]> Dogcows Code - chaz/yoink/blob - src/Moof/Video.cc
62addb406dc804b7a31644ef586b3a43b3dd1dce
[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 "Dispatch.hh"
30 #include "Error.hh"
31 #include "Image.hh"
32 #include "Log.hh"
33 #include "Settings.hh"
34 #include "Video.hh"
35
36
37 namespace Mf {
38
39
40 Video::Video()
41 {
42 init(mAttribs);
43 }
44
45 Video::Video(const Attributes& attribs)
46 {
47 init(attribs);
48 }
49
50 Video::Video(const std::string& caption, const std::string& icon)
51 {
52 if (mAttribs.caption == "Untitled")
53 {
54 mAttribs.caption = caption;
55 }
56 if (mAttribs.icon == "")
57 {
58 mAttribs.icon = icon;
59 }
60
61 init(mAttribs);
62 }
63
64 void Video::init(const Attributes& attribs)
65 {
66 mContext = 0;
67 mFlags = 0;
68 mAttribs = attribs;
69
70 setFull(attribs.fullscreen);
71 setResizable(attribs.resizable);
72 setOpenGLAttributes();
73 setCaption(attribs.caption);
74 setIcon();
75 setCursorVisible(attribs.cursorVisible);
76 setCursorGrab(attribs.cursorGrab);
77 setVideoMode(attribs.mode);
78
79 video = this;
80 }
81
82 void Video::recreateContext()
83 {
84 SDL_FreeSurface(mContext);
85 mContext = 0;
86 setVideoMode(mAttribs.mode);
87 }
88
89 void Video::setOpenGLAttributes()
90 {
91 SDL_GL_SetAttribute(SDL_GL_RED_SIZE, mAttribs.colorBuffer[0]);
92 SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, mAttribs.colorBuffer[1]);
93 SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, mAttribs.colorBuffer[2]);
94 SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, mAttribs.colorBuffer[3]);
95 SDL_GL_SetAttribute(SDL_GL_BUFFER_SIZE, mAttribs.frameBuffer);
96 SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, mAttribs.doubleBuffer);
97 SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, mAttribs.depthBuffer);
98 SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, mAttribs.stencilBuffer);
99 SDL_GL_SetAttribute(SDL_GL_ACCUM_RED_SIZE, mAttribs.accumBuffer[0]);
100 SDL_GL_SetAttribute(SDL_GL_ACCUM_GREEN_SIZE, mAttribs.accumBuffer[1]);
101 SDL_GL_SetAttribute(SDL_GL_ACCUM_BLUE_SIZE, mAttribs.accumBuffer[2]);
102 SDL_GL_SetAttribute(SDL_GL_ACCUM_ALPHA_SIZE, mAttribs.accumBuffer[3]);
103 SDL_GL_SetAttribute(SDL_GL_STEREO, mAttribs.stereo);
104 SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, mAttribs.multisampleBuffers);
105 SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, mAttribs.multisampleSamples);
106 SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, mAttribs.swapControl);
107 SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, mAttribs.hardwareonly);
108 }
109
110
111 Video::~Video()
112 {
113 SDL_FreeSurface(mContext);
114
115 if (video == this) video = 0;
116 }
117
118
119 void Video::setVideoMode(const long mode[3])
120 {
121 if (mode != mAttribs.mode || !mContext)
122 {
123 if (mContext) SDL_FreeSurface(mContext);
124
125 mContext = SDL_SetVideoMode(mode[0], mode[1], mode[2],
126 SDL_OPENGL | mFlags);
127
128 if (mContext)
129 {
130 mAttribs.mode[0] = mode[0];
131 mAttribs.mode[1] = mode[1];
132 mAttribs.mode[2] = mode[2];
133
134 #if !defined(linux) && !defined(__linux) && !defined(__linux__)
135 logInfo("video context recreated");
136 core.dispatch("video.newcontext");
137 #endif
138 }
139 else Error(Error::SDL_VIDEOMODE).raise();
140 }
141 }
142
143 Video::Attributes Video::getAttributes() const
144 {
145 return mAttribs;
146 }
147
148
149 void Video::resize(int width, int height)
150 {
151 long mode[] = {width, height, mAttribs.mode[2]};
152 setVideoMode(mode);
153 }
154
155 bool Video::iconify()
156 {
157 return SDL_WM_IconifyWindow();
158 }
159
160
161 void Video::setCaption(const std::string& caption)
162 {
163 mAttribs.caption = caption;
164 SDL_WM_SetCaption(caption.c_str(), 0);
165 }
166
167 void Video::setIcon()
168 {
169 if (mAttribs.icon != "")
170 {
171 Image icon(mAttribs.icon);
172 icon.setAsIcon();
173 }
174 }
175
176 std::string Video::getCaption() const
177 {
178 return mAttribs.caption;
179 }
180
181 const std::string& Video::getIcon() const
182 {
183 return mAttribs.icon;
184 }
185
186
187 void Video::setFull(bool full)
188 {
189 if (full != isFull() || !mContext)
190 {
191 if (mContext)
192 {
193 mFlags ^= SDL_FULLSCREEN;
194
195 #if defined(linux) || defined(__linux) || defined(__linux__)
196 if (SDL_WM_ToggleFullScreen(mContext) == 0)
197 #endif
198 recreateContext();
199 }
200 else
201 {
202 if (full) mFlags |= SDL_FULLSCREEN;
203 else mFlags &= ~SDL_FULLSCREEN;
204 }
205 }
206 }
207
208 void Video::toggleFull()
209 {
210 setFull(!isFull());
211 }
212
213 bool Video::isFull() const
214 {
215 return mFlags & 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() || !mContext)
238 {
239 if (mContext)
240 {
241 mFlags ^= SDL_RESIZABLE;
242 recreateContext();
243 }
244 else
245 {
246 if (resizable) mFlags |= SDL_RESIZABLE;
247 else mFlags &= ~SDL_RESIZABLE;
248 }
249 }
250 }
251
252 void Video::toggleResizable()
253 {
254 setResizable(!isResizable());
255 }
256
257 bool Video::isResizable() const
258 {
259 return mFlags & 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::swap()
280 {
281 SDL_GL_SwapBuffers();
282 }
283
284
285 int Video::getWidth() const
286 {
287 return mContext->w;
288 }
289
290 int Video::getHeight() const
291 {
292 return mContext->h;
293 }
294
295
296 Video::Attributes::Attributes()
297 {
298 // set some sane GL and window defaults (see SDL_video.c:217)
299 colorBuffer[0] = 3;
300 colorBuffer[1] = 3;
301 colorBuffer[2] = 2;
302 colorBuffer[3] = 0;
303 frameBuffer = 0;
304 doubleBuffer = true;
305 depthBuffer = 16;
306 stencilBuffer = 0;
307 accumBuffer[0] = 0;
308 accumBuffer[1] = 0;
309 accumBuffer[2] = 0;
310 accumBuffer[3] = 0;
311 stereo = false;
312 multisampleBuffers = 0;
313 multisampleSamples = 0;
314 swapControl = false;
315 hardwareonly = false;
316 mode[0] = 640;
317 mode[1] = 480;
318 mode[2] = 0;
319 fullscreen = false;
320 resizable = false;
321 cursorVisible = true;
322 cursorGrab = false;
323
324 std::vector<long> colors;
325 settings.get("colorbuffers", colors);
326 if (colors.size() > 0) colorBuffer[0] = colors[0];
327 if (colors.size() > 1) colorBuffer[1] = colors[1];
328 if (colors.size() > 2) colorBuffer[2] = colors[2];
329 if (colors.size() > 3) colorBuffer[3] = colors[3];
330
331 settings.get("framebuffer", frameBuffer);
332 settings.get("doublebuffer", doubleBuffer);
333 settings.get("depthbuffer", depthBuffer);
334 settings.get("stencilbuffer", stencilBuffer);
335
336 std::vector<long> accum;
337 settings.get("accumbuffers", accum);
338 if (accum.size() > 0) accumBuffer[0] = accum[0];
339 if (accum.size() > 1) accumBuffer[1] = accum[1];
340 if (accum.size() > 2) accumBuffer[2] = accum[2];
341 if (accum.size() > 3) accumBuffer[3] = accum[3];
342
343 settings.get("stereo", stereo);
344 settings.get("multiesamplebuffers", multisampleBuffers);
345 settings.get("multiesamplesamples", multisampleSamples);
346 settings.get("swapcontrol", swapControl);
347 settings.get("hardwareonly", hardwareonly);
348
349 if (!settings.get("caption", caption))
350 {
351 caption = "Untitled";
352 }
353 settings.get("icon", icon);
354
355 settings.get("fullscreen", fullscreen);
356 settings.get("resizable", resizable);
357 settings.get("showcursor", cursorVisible);
358 settings.get("grab", cursorGrab);
359
360 std::vector<long> dimensions;
361 settings.get("videomode", dimensions);
362 if (dimensions.size() > 1)
363 {
364 mode[0] = dimensions[0];
365 mode[1] = dimensions[1];
366 }
367 else if (fullscreen)
368 {
369 SDL_Rect** modes = SDL_ListModes(NULL, SDL_FULLSCREEN | SDL_HWSURFACE);
370
371 if (modes == (SDL_Rect**)0)
372 {
373 Mf::logError("no native video mode");
374 }
375 else if (modes == (SDL_Rect**)-1)
376 {
377 Mf::logWarning("any resolution allowed; choosing default 800x600");
378 mode[0] = 800;
379 mode[1] = 600;
380 }
381 else
382 {
383 mode[0] = (*modes)->w;
384 mode[1] = (*modes)->h;
385 Mf::logInfo << "choosing native resolution "
386 << mode[0] << "x" << mode[1] << std::endl;
387 }
388 }
389 if (dimensions.size() > 2) mode[2] = dimensions[2];
390 }
391
392
393 Video* video = 0;
394
395
396 } // namespace Mf
397
398 /** vim: set ts=4 sw=4 tw=80: *************************************************/
399
This page took 0.045963 seconds and 3 git commands to generate.