2 /*******************************************************************************
4 Copyright (c) 2009, Charles McGarvey
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions are met:
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.
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.
27 *******************************************************************************/
31 #include <SDL/SDL_image.h>
33 #include "Dispatcher.hh"
35 #include "Serializable.hh"
36 #include "Settings.hh"
48 Video::Video(const Attributes
& attribs
)
53 Video::Video(const std::string
& caption
, const std::string
& icon
)
55 if (attribs_
.caption
== "Untitled")
57 attribs_
.caption
= caption
;
59 if (attribs_
.icon
== "")
67 void Video::init(const Attributes
& attribs
)
73 setFull(attribs
.fullscreen
);
74 setResizable(attribs
.resizable
);
75 setOpenGLAttributes();
76 setCaption(attribs
.caption
);
78 setCursorVisible(attribs
.cursorVisible
);
79 setCursorGrab(attribs
.cursorGrab
);
80 setVideoMode(attribs
.mode
);
83 void Video::recreateContext()
85 SDL_FreeSurface(context_
);
87 setVideoMode(attribs_
.mode
);
90 void Video::setOpenGLAttributes()
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
);
114 SDL_FreeSurface(context_
);
118 void Video::setVideoMode(const long mode
[3])
120 if (mode
!= attribs_
.mode
|| !context_
)
122 if (context_
) SDL_FreeSurface(context_
);
124 context_
= SDL_SetVideoMode(mode
[0], mode
[1], mode
[2],
125 SDL_OPENGL
| flags_
);
129 attribs_
.mode
[0] = mode
[0];
130 attribs_
.mode
[1] = mode
[1];
131 attribs_
.mode
[2] = mode
[2];
133 #if defined(_WIN32) || defined (_WIN64) || defined(__WIN32__)
134 // on win32, creating a new context via SDL_SetVideoMode will wipe
135 // out the GL state, so we gotta notify everyone to reload their
136 // state after the change
137 Mf::dispatcher::dispatch("video.context_recreated");
138 logInfo("video context recreated");
141 else throw Exception(SDL_GetError());
145 Video::Attributes
Video::getAttributes() const
151 void Video::resize(int width
, int height
)
153 long mode
[] = {width
, height
, attribs_
.mode
[2]};
157 bool Video::iconify()
159 return SDL_WM_IconifyWindow();
163 void Video::setCaption(const std::string
& caption
)
165 attribs_
.caption
= caption
;
166 SDL_WM_SetCaption(caption
.c_str(), 0);
169 void Video::setIcon()
171 if (attribs_
.icon
!= "")
173 SDL_Surface
* icon
= IMG_Load(attribs_
.icon
.c_str());
176 SDL_WM_SetIcon(icon
, 0);
177 SDL_FreeSurface(icon
);
182 std::string
Video::getCaption() const
184 return attribs_
.caption
;
188 void Video::setFull(bool full
)
190 if (full
!= isFull() || !context_
)
194 flags_
^= SDL_FULLSCREEN
;
196 #if defined(linux) || defined(__linux) || defined(__linux__)
197 if (SDL_WM_ToggleFullScreen(context_
) == 0)
203 if (full
) flags_
|= SDL_FULLSCREEN
;
204 else flags_
&= ~SDL_FULLSCREEN
;
209 void Video::toggleFull()
214 bool Video::isFull() const
216 return flags_
& SDL_FULLSCREEN
;
220 void Video::setCursorVisible(bool hasCursor
)
222 SDL_ShowCursor(hasCursor
? SDL_ENABLE
: SDL_DISABLE
);
225 void Video::toggleCursorVisible()
227 setCursorVisible(!isCursorVisible());
230 bool Video::isCursorVisible() const
232 return (SDL_ShowCursor(SDL_QUERY
) == SDL_ENABLE
);
236 void Video::setResizable(bool resizable
)
238 if (resizable
!= isResizable() || !context_
)
242 flags_
^= SDL_RESIZABLE
;
247 if (resizable
) flags_
|= SDL_RESIZABLE
;
248 else flags_
&= ~SDL_RESIZABLE
;
253 void Video::toggleResizable()
255 setResizable(!isResizable());
258 bool Video::isResizable() const
260 return flags_
& SDL_RESIZABLE
;
264 bool Video::isCursorGrab() const
266 return (SDL_WM_GrabInput(SDL_GRAB_QUERY
) == SDL_GRAB_ON
);
269 void Video::toggleCursorGrab()
271 setCursorGrab(!isCursorGrab());
274 void Video::setCursorGrab(bool cursorGrab
)
276 SDL_WM_GrabInput(cursorGrab
? SDL_GRAB_ON
: SDL_GRAB_OFF
);
280 void Video::makeActive()
282 // NOP until the day SDL supports more than only one window.
288 SDL_GL_SwapBuffers();
292 Video::Attributes::Attributes()
294 // Set some sane GL and window defaults (see SDL_video.c:217)
308 multisampleBuffers
= 0;
309 multisampleSamples
= 0;
311 hardwareonly
= false;
317 cursorVisible
= true;
320 Settings
& settings
= Settings::getInstance();
322 Serializable::Array colors
;
323 settings
.get("video.colorbuffers", colors
);
324 if (colors
.size() > 0) colors
[0]->get(colorBuffer
[0]);
325 if (colors
.size() > 1) colors
[1]->get(colorBuffer
[1]);
326 if (colors
.size() > 2) colors
[2]->get(colorBuffer
[2]);
327 if (colors
.size() > 3) colors
[3]->get(colorBuffer
[3]);
329 settings
.get("video.framebuffer", frameBuffer
);
330 settings
.get("video.doublebuffer", doubleBuffer
);
331 settings
.get("video.depthbuffer", depthBuffer
);
332 settings
.get("video.stencilbuffer", stencilBuffer
);
334 Serializable::Array accum
;
335 settings
.get("video.accumbuffers", accum
);
336 if (accum
.size() > 0) accum
[0]->get(accumBuffer
[0]);
337 if (accum
.size() > 1) accum
[1]->get(accumBuffer
[1]);
338 if (accum
.size() > 2) accum
[2]->get(accumBuffer
[2]);
339 if (accum
.size() > 3) accum
[3]->get(accumBuffer
[3]);
341 settings
.get("video.stereo", stereo
);
342 settings
.get("video.multiesamplebuffers", multisampleBuffers
);
343 settings
.get("video.multiesamplesamples", multisampleSamples
);
344 settings
.get("video.swapcontrol", swapControl
);
345 settings
.get("video.hardwareonly", hardwareonly
);
347 if (!settings
.get("video.caption", caption
))
349 caption
= "Untitled";
351 settings
.get("video.icon", icon
);
353 Serializable::Array dimensions
;
354 settings
.get("video.mode", dimensions
);
355 if (dimensions
.size() > 0) dimensions
[0]->get(mode
[0]);
356 if (dimensions
.size() > 1) dimensions
[1]->get(mode
[1]);
357 if (dimensions
.size() > 2) dimensions
[2]->get(mode
[2]);
359 settings
.get("video.fullscreen", fullscreen
);
360 settings
.get("video.resizable", resizable
);
361 settings
.get("video.showcursor", cursorVisible
);
362 settings
.get("input.grab", cursorGrab
);
368 /** vim: set ts=4 sw=4 tw=80: *************************************************/