X-Git-Url: https://git.dogcows.com/gitweb?a=blobdiff_plain;f=src%2Fvideo.cc;fp=src%2Fvideo.cc;h=715c407cd7e3803968b5e113523b3a364ea4334b;hb=79b5f738f2e38acb60cda7e09f54802933a17105;hp=0000000000000000000000000000000000000000;hpb=a891a2dcbbb63d9e771da6efff00a33da614e737;p=chaz%2Fyoink diff --git a/src/video.cc b/src/video.cc new file mode 100644 index 0000000..715c407 --- /dev/null +++ b/src/video.cc @@ -0,0 +1,347 @@ + +/******************************************************************************* + + Copyright (c) 2009, Charles McGarvey + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +*******************************************************************************/ + +#include + +#include "serializable.hh" +#include "settings.hh" + +#include "video.hh" + + +namespace dc { + + +video::video() +{ + std::string caption; + if (settings::instance().get("video.caption", caption)) + { + init(attribs_, caption); + } + else + { + init(attribs_, "Untitled"); + } +} + +video::video(const attributes& attribs, const std::string& caption) +{ + init(attribs, caption); +} + +video::video(const attributes& attribs) +{ + std::string caption; + if (settings::instance().get("video.caption", caption)) + { + init(attribs, caption); + } + else + { + init(attribs, "Untitled"); + } +} + +video::video(const std::string& caption) +{ + init(attribs_, caption); +} + +void video::init(const attributes& attribs, const std::string& caption) +{ + context_ = 0; + flags_ = 0; + attribs_ = attribs; + + setFull(attribs.fullscreen); + setResizable(attribs.resizable); + setOpenGLAttributes(); + setCaption(caption); + setCursorVisible(attribs.cursorVisible); + setCursorGrab(attribs.cursorGrab); + setVideoMode(attribs.mode); +} + +void video::recreateContext() +{ + SDL_FreeSurface(context_); + context_ = 0; + setVideoMode(attribs_.mode); +} + +void video::setOpenGLAttributes() +{ + SDL_GL_SetAttribute(SDL_GL_RED_SIZE, attribs_.colorBuffer[0]); + SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, attribs_.colorBuffer[1]); + SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, attribs_.colorBuffer[2]); + SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, attribs_.colorBuffer[3]); + SDL_GL_SetAttribute(SDL_GL_BUFFER_SIZE, attribs_.frameBuffer); + SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, attribs_.doubleBuffer); + SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, attribs_.depthBuffer); + SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, attribs_.stencilBuffer); + SDL_GL_SetAttribute(SDL_GL_ACCUM_RED_SIZE, attribs_.accumBuffer[0]); + SDL_GL_SetAttribute(SDL_GL_ACCUM_GREEN_SIZE, attribs_.accumBuffer[1]); + SDL_GL_SetAttribute(SDL_GL_ACCUM_BLUE_SIZE, attribs_.accumBuffer[2]); + SDL_GL_SetAttribute(SDL_GL_ACCUM_ALPHA_SIZE, attribs_.accumBuffer[3]); + SDL_GL_SetAttribute(SDL_GL_STEREO, attribs_.stereo); + SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, attribs_.multisampleBuffers); + SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, attribs_.multisampleSamples); + SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, attribs_.swapControl); + SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, attribs_.hardwareonly); +} + + +video::~video() +{ + SDL_FreeSurface(context_); +} + + +void video::setVideoMode(const long mode[3]) +{ + if (mode != attribs_.mode || !context_) + { + if (context_) SDL_FreeSurface(context_); + + context_ = SDL_SetVideoMode(mode[0], mode[1], mode[2], + SDL_OPENGL | flags_); + + if (context_) + { + attribs_.mode[0] = mode[0]; + attribs_.mode[1] = mode[1]; + attribs_.mode[2] = mode[2]; + } + else throw std::runtime_error(SDL_GetError()); + } +} + +video::attributes video::getAttributes() const +{ + return attribs_; +} + + +void video::resize(int width, int height) +{ + long mode[] = {width, height, attribs_.mode[2]}; + setVideoMode(mode); +} + +bool video::iconify() +{ + return SDL_WM_IconifyWindow(); +} + + +void video::setCaption(const std::string& caption) +{ + SDL_WM_SetCaption(caption.c_str(), 0); +} + +std::string video::getCaption() const +{ + char* str; + SDL_WM_GetCaption(&str, 0); + return std::string(str); +} + + +void video::setFull(bool full) +{ + if (full != isFull() || !context_) + { + if (context_) + { + flags_ ^= SDL_FULLSCREEN; + +#if defined(linux) || defined(__linux) || defined(__linux__) + if (SDL_WM_ToggleFullScreen(context_) == 0) +#endif + recreateContext(); + } + else + { + if (full) flags_ |= SDL_FULLSCREEN; + else flags_ &= ~SDL_FULLSCREEN; + } + } +} + +void video::toggleFull() +{ + setFull(!isFull()); +} + +bool video::isFull() const +{ + return flags_ & SDL_FULLSCREEN; +} + + +void video::setCursorVisible(bool hasCursor) +{ + SDL_ShowCursor(hasCursor? SDL_ENABLE : SDL_DISABLE); +} + +void video::toggleCursorVisible() +{ + setCursorVisible(!isCursorVisible()); +} + +bool video::isCursorVisible() const +{ + return (SDL_ShowCursor(SDL_QUERY) == SDL_ENABLE); +} + + +void video::setResizable(bool resizable) +{ + if (resizable != isResizable() || !context_) + { + if (context_) + { + flags_ ^= SDL_RESIZABLE; + recreateContext(); + } + else + { + if (resizable) flags_ |= SDL_RESIZABLE; + else flags_ &= ~SDL_RESIZABLE; + } + } +} + +void video::toggleResizable() +{ + setResizable(!isResizable()); +} + +bool video::isResizable() const +{ + return flags_ & SDL_RESIZABLE; +} + + +bool video::isCursorGrab() const +{ + return (SDL_WM_GrabInput(SDL_GRAB_QUERY) == SDL_GRAB_ON); +} + +void video::toggleCursorGrab() +{ + setCursorGrab(!isCursorGrab()); +} + +void video::setCursorGrab(bool cursorGrab) +{ + SDL_WM_GrabInput(cursorGrab? SDL_GRAB_ON : SDL_GRAB_OFF); +} + + +void video::makeActive() +{ + // NOP until the day SDL supports more than only one window. + // Still waiting... +} + +void video::swap() +{ + SDL_GL_SwapBuffers(); +} + + +video::attributes::attributes() +{ + // Set some sane GL and window defaults (see SDL_video.c:217) + colorBuffer[0] = 3; + colorBuffer[1] = 3; + colorBuffer[2] = 2; + colorBuffer[3] = 0; + frameBuffer = 0; + doubleBuffer = true; + depthBuffer = 16; + stencilBuffer = 0; + accumBuffer[0] = 0; + accumBuffer[1] = 0; + accumBuffer[2] = 0; + accumBuffer[3] = 0; + stereo = false; + multisampleBuffers = 0; + multisampleSamples = 0; + swapControl = false; + hardwareonly = false; + mode[0] = 640; + mode[1] = 480; + mode[2] = 0; + fullscreen = false; + resizable = false; + cursorVisible = true; + cursorGrab = false; + + std::vector colors; + settings::instance().get("video.colorbuffers", colors); + if (colors.size() > 0) colors[0]->get(colorBuffer[0]); + if (colors.size() > 1) colors[1]->get(colorBuffer[1]); + if (colors.size() > 2) colors[2]->get(colorBuffer[2]); + if (colors.size() > 3) colors[3]->get(colorBuffer[3]); + + settings::instance().get("video.framebuffer", frameBuffer); + settings::instance().get("video.doublebuffer", doubleBuffer); + settings::instance().get("video.depthbuffer", depthBuffer); + settings::instance().get("video.stencilbuffer", stencilBuffer); + + std::vector accum; + settings::instance().get("video.accumbuffers", accum); + if (accum.size() > 0) accum[0]->get(accumBuffer[0]); + if (accum.size() > 1) accum[1]->get(accumBuffer[1]); + if (accum.size() > 2) accum[2]->get(accumBuffer[2]); + if (accum.size() > 3) accum[3]->get(accumBuffer[3]); + + settings::instance().get("video.stereo", stereo); + settings::instance().get("video.multiesamplebuffers", multisampleBuffers); + settings::instance().get("video.multiesamplesamples", multisampleSamples); + settings::instance().get("video.swapcontrol", swapControl); + settings::instance().get("video.hardwareonly", hardwareonly); + + std::vector dimensions; + settings::instance().get("video.mode", dimensions); + if (dimensions.size() > 0) dimensions[0]->get(mode[0]); + if (dimensions.size() > 1) dimensions[1]->get(mode[1]); + if (dimensions.size() > 2) dimensions[2]->get(mode[2]); + + settings::instance().get("video.fullscreen", fullscreen); + settings::instance().get("video.resizable", resizable); + settings::instance().get("video.cursor", cursorVisible); + settings::instance().get("video.grab", cursorGrab); +} + + +} // namespace dc +