X-Git-Url: https://git.dogcows.com/gitweb?p=chaz%2Fyoink;a=blobdiff_plain;f=src%2FMoof%2FVideo.cc;h=9ca53c1cc46d5cfd3dc5c32963a4ed813dd81107;hp=63970e44389f5b5944eb00092e6e78c07e3e072d;hb=321f005b45580b8c2c14ddc577fb6ca7780a68c5;hpb=fdfba4553433b9b2804c2772c7645211b828c2ea diff --git a/src/Moof/Video.cc b/src/Moof/Video.cc index 63970e4..9ca53c1 100644 --- a/src/Moof/Video.cc +++ b/src/Moof/Video.cc @@ -1,37 +1,18 @@ -/******************************************************************************* - - 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 - -#include "Dispatcher.hh" -#include "Serializable.hh" +/*] Copyright (c) 2009-2010, Charles McGarvey [************************** +**] All rights reserved. +* +* vi:ts=4 sw=4 tw=75 +* +* Distributable under the terms and conditions of the 2-clause BSD license; +* see the file COPYING for a complete text of the license. +* +**************************************************************************/ + +#include "Dispatch.hh" +#include "Error.hh" +#include "Image.hh" +#include "Log.hh" #include "Settings.hh" #include "Video.hh" @@ -41,108 +22,122 @@ namespace Mf { Video::Video() { - init(attribs_); + init(); } -Video::Video(const Attributes& attribs) +Video::Video(const Attributes& attribs) : + mAttribs(attribs) { - init(attribs); + init(); } -Video::Video(const std::string& caption, const std::string& icon) +void Video::init() { - if (attribs_.caption == "Untitled") - { - attribs_.caption = caption; - } - if (attribs_.icon == "") - { - attribs_.icon = icon; - } + Error error = Backend::getError(); + if (error) error.raise(); - init(attribs_); -} - -void Video::init(const Attributes& attribs) -{ - context_ = 0; - flags_ = 0; - attribs_ = attribs; + mContext = 0; + mFlags = 0; - setFull(attribs.fullscreen); - setResizable(attribs.resizable); + setFull(mAttribs.fullscreen); + setResizable(mAttribs.resizable); setOpenGLAttributes(); - setCaption(attribs.caption); + setCaption(mAttribs.caption); setIcon(); - setCursorVisible(attribs.cursorVisible); - setCursorGrab(attribs.cursorGrab); - setVideoMode(attribs.mode); + setCursorVisible(mAttribs.cursorVisible); + setCursorGrab(mAttribs.cursorGrab); + setVideoMode(mAttribs.mode); + + if (!gCurrentVideo) makeCurrent(); } void Video::recreateContext() { - SDL_FreeSurface(context_); - context_ = 0; - setVideoMode(attribs_.mode); - Mf::Dispatcher::getInstance().dispatch("video.context_recreated"); + SDL_FreeSurface(mContext); + mContext = 0; + setVideoMode(mAttribs.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); + SDL_GL_SetAttribute(SDL_GL_RED_SIZE, + mAttribs.colorBuffer[0]); + SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, + mAttribs.colorBuffer[1]); + SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, + mAttribs.colorBuffer[2]); + SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, + mAttribs.colorBuffer[3]); + SDL_GL_SetAttribute(SDL_GL_BUFFER_SIZE, + mAttribs.frameBuffer); + SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, + mAttribs.doubleBuffer); + SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, + mAttribs.depthBuffer); + SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, + mAttribs.stencilBuffer); + SDL_GL_SetAttribute(SDL_GL_ACCUM_RED_SIZE, + mAttribs.accumBuffer[0]); + SDL_GL_SetAttribute(SDL_GL_ACCUM_GREEN_SIZE, + mAttribs.accumBuffer[1]); + SDL_GL_SetAttribute(SDL_GL_ACCUM_BLUE_SIZE, + mAttribs.accumBuffer[2]); + SDL_GL_SetAttribute(SDL_GL_ACCUM_ALPHA_SIZE, + mAttribs.accumBuffer[3]); + SDL_GL_SetAttribute(SDL_GL_STEREO, + mAttribs.stereo); + SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, + mAttribs.multisampleBuffers); + SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, + mAttribs.multisampleSamples); + SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, + mAttribs.swapControl); + SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, + mAttribs.hardwareOnly); } Video::~Video() { - SDL_FreeSurface(context_); + SDL_FreeSurface(mContext); + + if (gCurrentVideo == this) gCurrentVideo = 0; } -void Video::setVideoMode(const long mode[3]) +void Video::setVideoMode(const int mode[3]) { - if (mode != attribs_.mode || !context_) + if (mode != mAttribs.mode || !mContext) { - if (context_) SDL_FreeSurface(context_); + if (mContext) SDL_FreeSurface(mContext); - context_ = SDL_SetVideoMode(mode[0], mode[1], mode[2], - SDL_OPENGL | flags_); + mContext = SDL_SetVideoMode(mode[0], mode[1], mode[2], + SDL_OPENGL | mFlags); - if (context_) + if (mContext) { - attribs_.mode[0] = mode[0]; - attribs_.mode[1] = mode[1]; - attribs_.mode[2] = mode[2]; + mAttribs.mode[0] = mode[0]; + mAttribs.mode[1] = mode[1]; + mAttribs.mode[2] = mode[2]; + +#if !defined(linux) && !defined(__linux) && !defined(__linux__) + logInfo("video context recreated"); + Dispatch::global().dispatch("video.newcontext"); +#endif } - else throw Exception(SDL_GetError()); + else Error(Error::SDL_VIDEOMODE).raise(); } } -Video::Attributes Video::getAttributes() const +Video::Attributes Video::attributes() const { - return attribs_; + return mAttribs; } void Video::resize(int width, int height) { - long mode[] = {width, height, attribs_.mode[2]}; + int mode[] = {width, height, mAttribs.mode[2]}; setVideoMode(mode); } @@ -154,46 +149,47 @@ bool Video::iconify() void Video::setCaption(const std::string& caption) { - attribs_.caption = caption; + mAttribs.caption = caption; SDL_WM_SetCaption(caption.c_str(), 0); } void Video::setIcon() { - if (attribs_.icon != "") + if (mAttribs.icon != "") { - SDL_Surface* icon = IMG_Load(attribs_.icon.c_str()); - if (icon) - { - SDL_WM_SetIcon(icon, 0); - SDL_FreeSurface(icon); - } + Image icon(mAttribs.icon); + icon.setAsIcon(); } } std::string Video::getCaption() const { - return attribs_.caption; + return mAttribs.caption; +} + +const std::string& Video::getIcon() const +{ + return mAttribs.icon; } void Video::setFull(bool full) { - if (full != isFull() || !context_) + if (full != isFull() || !mContext) { - if (context_) + if (mContext) { - flags_ ^= SDL_FULLSCREEN; + mFlags ^= SDL_FULLSCREEN; #if defined(linux) || defined(__linux) || defined(__linux__) - if (SDL_WM_ToggleFullScreen(context_) == 0) + if (SDL_WM_ToggleFullScreen(mContext) == 0) #endif recreateContext(); } else { - if (full) flags_ |= SDL_FULLSCREEN; - else flags_ &= ~SDL_FULLSCREEN; + if (full) mFlags |= SDL_FULLSCREEN; + else mFlags &= ~SDL_FULLSCREEN; } } } @@ -205,7 +201,7 @@ void Video::toggleFull() bool Video::isFull() const { - return flags_ & SDL_FULLSCREEN; + return mFlags & SDL_FULLSCREEN; } @@ -227,17 +223,17 @@ bool Video::isCursorVisible() const void Video::setResizable(bool resizable) { - if (resizable != isResizable() || !context_) + if (resizable != isResizable() || !mContext) { - if (context_) + if (mContext) { - flags_ ^= SDL_RESIZABLE; + mFlags ^= SDL_RESIZABLE; recreateContext(); } else { - if (resizable) flags_ |= SDL_RESIZABLE; - else flags_ &= ~SDL_RESIZABLE; + if (resizable) mFlags |= SDL_RESIZABLE; + else mFlags &= ~SDL_RESIZABLE; } } } @@ -249,7 +245,7 @@ void Video::toggleResizable() bool Video::isResizable() const { - return flags_ & SDL_RESIZABLE; + return mFlags & SDL_RESIZABLE; } @@ -269,21 +265,111 @@ void Video::setCursorGrab(bool cursorGrab) } -void Video::makeActive() +void Video::swap() { - // NOP until the day SDL supports more than only one window. - // Still waiting... + SDL_GL_SwapBuffers(); } -void Video::swap() + +int Video::getWidth() const { - SDL_GL_SwapBuffers(); + return mContext->w; +} + +int Video::getHeight() const +{ + return mContext->h; +} + + +void Video::makeCurrent() const +{ + gCurrentVideo = const_cast(this); } Video::Attributes::Attributes() { - // Set some sane GL and window defaults (see SDL_video.c:217) + init(); +} + +Video::Attributes::Attributes(const Settings& settings) +{ + init(); + + std::vector colors; + settings.get("colorbuffers", colors); + if (colors.size() > 0) colorBuffer[0] = colors[0]; + if (colors.size() > 1) colorBuffer[1] = colors[1]; + if (colors.size() > 2) colorBuffer[2] = colors[2]; + if (colors.size() > 3) colorBuffer[3] = colors[3]; + + settings.get("framebuffer", frameBuffer); + settings.get("doublebuffer", doubleBuffer); + settings.get("depthbuffer", depthBuffer); + settings.get("stencilbuffer", stencilBuffer); + + std::vector accum; + settings.get("accumbuffers", accum); + if (accum.size() > 0) accumBuffer[0] = accum[0]; + if (accum.size() > 1) accumBuffer[1] = accum[1]; + if (accum.size() > 2) accumBuffer[2] = accum[2]; + if (accum.size() > 3) accumBuffer[3] = accum[3]; + + settings.get("stereo", stereo); + settings.get("multiesamplebuffers", multisampleBuffers); + settings.get("multiesamplesamples", multisampleSamples); + settings.get("swapcontrol", swapControl); + settings.get("hardwareonly", hardwareOnly); + + if (!settings.get("caption", caption)) + { + caption = "Untitled"; + } + settings.get("icon", icon); + + settings.get("fullscreen", fullscreen); + settings.get("resizable", resizable); + settings.get("showcursor", cursorVisible); + settings.get("grab", cursorGrab); + + std::vector dimensions; + settings.get("videomode", dimensions); + if (dimensions.size() > 1) + { + mode[0] = dimensions[0]; + mode[1] = dimensions[1]; + } + else if (fullscreen && Backend::isInitialized()) + { + SDL_Rect** modes = SDL_ListModes(NULL, + SDL_FULLSCREEN | SDL_HWSURFACE); + + if (modes == (SDL_Rect**)0) + { + Mf::logError("no native video mode"); + } + else if (modes == (SDL_Rect**)-1) + { + Mf::logWarning("any resolution allowed; " + "choosing default 800x600"); + mode[0] = 800; + mode[1] = 600; + } + else + { + mode[0] = (*modes)->w; + mode[1] = (*modes)->h; + Mf::logInfo << "choosing native resolution " + << mode[0] << "x" << mode[1] << std::endl; + } + } + if (dimensions.size() > 2) mode[2] = dimensions[2]; +} + +void Video::Attributes::init() +{ + // set some sane GL and window defaults (see SDL_video.c:217) colorBuffer[0] = 3; colorBuffer[1] = 3; colorBuffer[2] = 2; @@ -300,7 +386,7 @@ Video::Attributes::Attributes() multisampleBuffers = 0; multisampleSamples = 0; swapControl = false; - hardwareonly = false; + hardwareOnly = false; mode[0] = 640; mode[1] = 480; mode[2] = 0; @@ -308,54 +394,11 @@ Video::Attributes::Attributes() resizable = false; cursorVisible = true; cursorGrab = false; +} - Settings& settings = Settings::getInstance(); - - Serializable::Array colors; - settings.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.get("video.framebuffer", frameBuffer); - settings.get("video.doublebuffer", doubleBuffer); - settings.get("video.depthbuffer", depthBuffer); - settings.get("video.stencilbuffer", stencilBuffer); - - Serializable::Array accum; - settings.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.get("video.stereo", stereo); - settings.get("video.multiesamplebuffers", multisampleBuffers); - settings.get("video.multiesamplesamples", multisampleSamples); - settings.get("video.swapcontrol", swapControl); - settings.get("video.hardwareonly", hardwareonly); - - if (!settings.get("video.caption", caption)) - { - caption = "Untitled"; - } - settings.get("video.icon", icon); - - Serializable::Array dimensions; - settings.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.get("video.fullscreen", fullscreen); - settings.get("video.resizable", resizable); - settings.get("video.showcursor", cursorVisible); - settings.get("input.grab", cursorGrab); -} +Video* Video::gCurrentVideo = 0; // most recently instantiated instance } // namespace Mf -/** vim: set ts=4 sw=4 tw=80: *************************************************/ -