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