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