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