2 /*] Copyright (c) 2009-2010, Charles McGarvey [**************************
3 **] All rights reserved.
7 * Distributable under the terms and conditions of the 2-clause BSD license;
8 * see the file COPYING for a complete text of the license.
10 **************************************************************************/
15 #include "Settings.hh"
23 mDispatch(Dispatch::global())
28 Video::Video(const Attributes
& attribs
) :
30 mDispatch(Dispatch::global())
37 Error error
= Backend::getError();
38 if (error
) error
.raise();
43 setFull(mAttribs
.fullscreen
);
44 setResizable(mAttribs
.resizable
);
45 setOpenGLAttributes();
46 setCaption(mAttribs
.caption
);
48 setCursorVisible(mAttribs
.cursorVisible
);
49 setCursorGrab(mAttribs
.cursorGrab
);
50 setVideoMode(mAttribs
.mode
);
52 if (!gCurrentVideo
) makeCurrent();
55 void Video::recreateContext()
57 SDL_FreeSurface(mContext
);
59 setVideoMode(mAttribs
.mode
);
62 void Video::setOpenGLAttributes()
64 SDL_GL_SetAttribute(SDL_GL_RED_SIZE
,
65 mAttribs
.colorBuffer
[0]);
66 SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE
,
67 mAttribs
.colorBuffer
[1]);
68 SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE
,
69 mAttribs
.colorBuffer
[2]);
70 SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE
,
71 mAttribs
.colorBuffer
[3]);
72 SDL_GL_SetAttribute(SDL_GL_BUFFER_SIZE
,
73 mAttribs
.frameBuffer
);
74 SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER
,
75 mAttribs
.doubleBuffer
);
76 SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE
,
77 mAttribs
.depthBuffer
);
78 SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE
,
79 mAttribs
.stencilBuffer
);
80 SDL_GL_SetAttribute(SDL_GL_ACCUM_RED_SIZE
,
81 mAttribs
.accumBuffer
[0]);
82 SDL_GL_SetAttribute(SDL_GL_ACCUM_GREEN_SIZE
,
83 mAttribs
.accumBuffer
[1]);
84 SDL_GL_SetAttribute(SDL_GL_ACCUM_BLUE_SIZE
,
85 mAttribs
.accumBuffer
[2]);
86 SDL_GL_SetAttribute(SDL_GL_ACCUM_ALPHA_SIZE
,
87 mAttribs
.accumBuffer
[3]);
88 SDL_GL_SetAttribute(SDL_GL_STEREO
,
90 SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS
,
91 mAttribs
.multisampleBuffers
);
92 SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES
,
93 mAttribs
.multisampleSamples
);
94 SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL
,
95 mAttribs
.swapControl
);
96 SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL
,
97 mAttribs
.hardwareOnly
);
103 SDL_FreeSurface(mContext
);
105 if (gCurrentVideo
== this) gCurrentVideo
= 0;
109 void Video::setVideoMode(const int mode
[3])
111 if (mode
!= mAttribs
.mode
|| !mContext
)
113 if (mContext
) SDL_FreeSurface(mContext
);
115 mContext
= SDL_SetVideoMode(mode
[0], mode
[1], mode
[2],
116 SDL_OPENGL
| mFlags
);
120 mAttribs
.mode
[0] = mode
[0];
121 mAttribs
.mode
[1] = mode
[1];
122 mAttribs
.mode
[2] = mode
[2];
124 #if !defined(linux) && !defined(__linux) && !defined(__linux__)
125 logInfo("video context recreated");
126 mDispatch
.dispatch("video.newcontext");
129 else Error(Error::SDL_VIDEOMODE
).raise();
133 Video::Attributes
Video::getAttributes() const
139 void Video::resize(int width
, int height
)
141 int mode
[] = {width
, height
, mAttribs
.mode
[2]};
145 bool Video::iconify()
147 return SDL_WM_IconifyWindow();
151 void Video::setCaption(const std::string
& caption
)
153 mAttribs
.caption
= caption
;
154 SDL_WM_SetCaption(caption
.c_str(), 0);
157 void Video::setIcon()
159 if (mAttribs
.icon
!= "")
161 Image
icon(mAttribs
.icon
);
166 std::string
Video::getCaption() const
168 return mAttribs
.caption
;
171 const std::string
& Video::getIcon() const
173 return mAttribs
.icon
;
177 void Video::setFull(bool full
)
179 if (full
!= isFull() || !mContext
)
183 mFlags
^= SDL_FULLSCREEN
;
185 #if defined(linux) || defined(__linux) || defined(__linux__)
186 if (SDL_WM_ToggleFullScreen(mContext
) == 0)
192 if (full
) mFlags
|= SDL_FULLSCREEN
;
193 else mFlags
&= ~SDL_FULLSCREEN
;
198 void Video::toggleFull()
203 bool Video::isFull() const
205 return mFlags
& SDL_FULLSCREEN
;
209 void Video::setCursorVisible(bool hasCursor
)
211 SDL_ShowCursor(hasCursor
? SDL_ENABLE
: SDL_DISABLE
);
214 void Video::toggleCursorVisible()
216 setCursorVisible(!isCursorVisible());
219 bool Video::isCursorVisible() const
221 return (SDL_ShowCursor(SDL_QUERY
) == SDL_ENABLE
);
225 void Video::setResizable(bool resizable
)
227 if (resizable
!= isResizable() || !mContext
)
231 mFlags
^= SDL_RESIZABLE
;
236 if (resizable
) mFlags
|= SDL_RESIZABLE
;
237 else mFlags
&= ~SDL_RESIZABLE
;
242 void Video::toggleResizable()
244 setResizable(!isResizable());
247 bool Video::isResizable() const
249 return mFlags
& SDL_RESIZABLE
;
253 bool Video::isCursorGrab() const
255 return (SDL_WM_GrabInput(SDL_GRAB_QUERY
) == SDL_GRAB_ON
);
258 void Video::toggleCursorGrab()
260 setCursorGrab(!isCursorGrab());
263 void Video::setCursorGrab(bool cursorGrab
)
265 SDL_WM_GrabInput(cursorGrab
? SDL_GRAB_ON
: SDL_GRAB_OFF
);
271 SDL_GL_SwapBuffers();
275 int Video::getWidth() const
280 int Video::getHeight() const
286 void Video::makeCurrent() const
288 gCurrentVideo
= const_cast<Video
*>(this);
292 void Video::setDispatch(Dispatch
& dispatch
)
294 mDispatch
= dispatch
;
298 Video::Attributes::Attributes()
303 Video::Attributes::Attributes(const Settings
& settings
)
307 std::vector
<int> colors
;
308 settings
.get("colorbuffers", colors
);
309 if (colors
.size() > 0) colorBuffer
[0] = colors
[0];
310 if (colors
.size() > 1) colorBuffer
[1] = colors
[1];
311 if (colors
.size() > 2) colorBuffer
[2] = colors
[2];
312 if (colors
.size() > 3) colorBuffer
[3] = colors
[3];
314 settings
.get("framebuffer", frameBuffer
);
315 settings
.get("doublebuffer", doubleBuffer
);
316 settings
.get("depthbuffer", depthBuffer
);
317 settings
.get("stencilbuffer", stencilBuffer
);
319 std::vector
<int> accum
;
320 settings
.get("accumbuffers", accum
);
321 if (accum
.size() > 0) accumBuffer
[0] = accum
[0];
322 if (accum
.size() > 1) accumBuffer
[1] = accum
[1];
323 if (accum
.size() > 2) accumBuffer
[2] = accum
[2];
324 if (accum
.size() > 3) accumBuffer
[3] = accum
[3];
326 settings
.get("stereo", stereo
);
327 settings
.get("multiesamplebuffers", multisampleBuffers
);
328 settings
.get("multiesamplesamples", multisampleSamples
);
329 settings
.get("swapcontrol", swapControl
);
330 settings
.get("hardwareonly", hardwareOnly
);
332 if (!settings
.get("caption", caption
))
334 caption
= "Untitled";
336 settings
.get("icon", icon
);
338 settings
.get("fullscreen", fullscreen
);
339 settings
.get("resizable", resizable
);
340 settings
.get("showcursor", cursorVisible
);
341 settings
.get("grab", cursorGrab
);
343 std::vector
<int> dimensions
;
344 settings
.get("videomode", dimensions
);
345 if (dimensions
.size() > 1)
347 mode
[0] = dimensions
[0];
348 mode
[1] = dimensions
[1];
350 else if (fullscreen
&& Backend::isInitialized())
352 SDL_Rect
** modes
= SDL_ListModes(NULL
,
353 SDL_FULLSCREEN
| SDL_HWSURFACE
);
355 if (modes
== (SDL_Rect
**)0)
357 Mf::logError("no native video mode");
359 else if (modes
== (SDL_Rect
**)-1)
361 Mf::logWarning("any resolution allowed; "
362 "choosing default 800x600");
368 mode
[0] = (*modes
)->w
;
369 mode
[1] = (*modes
)->h
;
370 Mf::logInfo
<< "choosing native resolution "
371 << mode
[0] << "x" << mode
[1] << std::endl
;
374 if (dimensions
.size() > 2) mode
[2] = dimensions
[2];
377 void Video::Attributes::init()
379 // set some sane GL and window defaults (see SDL_video.c:217)
393 multisampleBuffers
= 0;
394 multisampleSamples
= 0;
396 hardwareOnly
= false;
402 cursorVisible
= true;
407 Video
* Video::gCurrentVideo
= 0; // most recently instantiated instance