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