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