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 *******************************************************************************/
29 #include <SDL/SDL_image.h>
31 #include "Dispatch.hh"
33 #include "Exception.hh"
35 #include "Settings.hh"
47 Video::Video(const Attributes
& attribs
)
52 Video::Video(const std::string
& caption
, const std::string
& icon
)
54 if (mAttribs
.caption
== "Untitled")
56 mAttribs
.caption
= caption
;
58 if (mAttribs
.icon
== "")
66 void Video::init(const Attributes
& attribs
)
68 // make sure the engine is initialized before setting up the video
69 Engine::getInstance();
75 setFull(attribs
.fullscreen
);
76 setResizable(attribs
.resizable
);
77 setOpenGLAttributes();
78 setCaption(attribs
.caption
);
80 setCursorVisible(attribs
.cursorVisible
);
81 setCursorGrab(attribs
.cursorGrab
);
82 setVideoMode(attribs
.mode
);
85 void Video::recreateContext()
87 SDL_FreeSurface(mContext
);
89 setVideoMode(mAttribs
.mode
);
92 void Video::setOpenGLAttributes()
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
);
116 SDL_FreeSurface(mContext
);
120 void Video::setVideoMode(const long mode
[3])
122 if (mode
!= mAttribs
.mode
|| !mContext
)
124 if (mContext
) SDL_FreeSurface(mContext
);
126 mContext
= SDL_SetVideoMode(mode
[0], mode
[1], mode
[2],
127 SDL_OPENGL
| mFlags
);
131 mAttribs
.mode
[0] = mode
[0];
132 mAttribs
.mode
[1] = mode
[1];
133 mAttribs
.mode
[2] = mode
[2];
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");
141 logInfo("video context recreated");
144 else throw Exception(ErrorCode::SDL_VIDEOMODE
);
148 Video::Attributes
Video::getAttributes() const
154 void Video::resize(int width
, int height
)
156 long mode
[] = {width
, height
, mAttribs
.mode
[2]};
160 bool Video::iconify()
162 return SDL_WM_IconifyWindow();
166 void Video::setCaption(const std::string
& caption
)
168 mAttribs
.caption
= caption
;
169 SDL_WM_SetCaption(caption
.c_str(), 0);
172 void Video::setIcon()
174 if (mAttribs
.icon
!= "")
176 SDL_Surface
* icon
= IMG_Load(mAttribs
.icon
.c_str());
179 SDL_WM_SetIcon(icon
, 0);
180 SDL_FreeSurface(icon
);
185 std::string
Video::getCaption() const
187 return mAttribs
.caption
;
190 const std::string
& Video::getIcon() const
192 return mAttribs
.icon
;
196 void Video::setFull(bool full
)
198 if (full
!= isFull() || !mContext
)
202 mFlags
^= SDL_FULLSCREEN
;
204 #if defined(linux) || defined(__linux) || defined(__linux__)
205 if (SDL_WM_ToggleFullScreen(mContext
) == 0)
211 if (full
) mFlags
|= SDL_FULLSCREEN
;
212 else mFlags
&= ~SDL_FULLSCREEN
;
217 void Video::toggleFull()
222 bool Video::isFull() const
224 return mFlags
& SDL_FULLSCREEN
;
228 void Video::setCursorVisible(bool hasCursor
)
230 SDL_ShowCursor(hasCursor
? SDL_ENABLE
: SDL_DISABLE
);
233 void Video::toggleCursorVisible()
235 setCursorVisible(!isCursorVisible());
238 bool Video::isCursorVisible() const
240 return (SDL_ShowCursor(SDL_QUERY
) == SDL_ENABLE
);
244 void Video::setResizable(bool resizable
)
246 if (resizable
!= isResizable() || !mContext
)
250 mFlags
^= SDL_RESIZABLE
;
255 if (resizable
) mFlags
|= SDL_RESIZABLE
;
256 else mFlags
&= ~SDL_RESIZABLE
;
261 void Video::toggleResizable()
263 setResizable(!isResizable());
266 bool Video::isResizable() const
268 return mFlags
& SDL_RESIZABLE
;
272 bool Video::isCursorGrab() const
274 return (SDL_WM_GrabInput(SDL_GRAB_QUERY
) == SDL_GRAB_ON
);
277 void Video::toggleCursorGrab()
279 setCursorGrab(!isCursorGrab());
282 void Video::setCursorGrab(bool cursorGrab
)
284 SDL_WM_GrabInput(cursorGrab
? SDL_GRAB_ON
: SDL_GRAB_OFF
);
290 SDL_GL_SwapBuffers();
294 int Video::getWidth() const
299 int Video::getHeight() const
305 Video::Attributes::Attributes()
307 // Set some sane GL and window defaults (see SDL_video.c:217)
321 multisampleBuffers
= 0;
322 multisampleSamples
= 0;
324 hardwareonly
= false;
330 cursorVisible
= true;
333 Settings
& settings
= Settings::getInstance();
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];
342 settings
.get("framebuffer", frameBuffer
);
343 settings
.get("doublebuffer", doubleBuffer
);
344 settings
.get("depthbuffer", depthBuffer
);
345 settings
.get("stencilbuffer", stencilBuffer
);
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];
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
);
360 if (!settings
.get("caption", caption
))
362 caption
= "Untitled";
364 settings
.get("icon", icon
);
366 std::vector
<long> dimensions
;
367 settings
.get("videomode", dimensions
);
368 if (dimensions
.size() > 1)
370 mode
[0] = dimensions
[0];
371 mode
[1] = dimensions
[1];
373 if (dimensions
.size() > 2) mode
[2] = dimensions
[2];
375 settings
.get("fullscreen", fullscreen
);
376 settings
.get("resizable", resizable
);
377 settings
.get("showcursor", cursorVisible
);
378 settings
.get("grab", cursorGrab
);
384 /** vim: set ts=4 sw=4 tw=80: *************************************************/