]> Dogcows Code - chaz/yoink/blobdiff - src/Moof/Video.cc
new win32 deps script; using pkgconfig for openal
[chaz/yoink] / src / Moof / Video.cc
index c49bb1e41124de28f0dfa1769ae4547c5d0f6377..9ca53c1cc46d5cfd3dc5c32963a4ed813dd81107 100644 (file)
@@ -1,36 +1,17 @@
 
-/*******************************************************************************
-
- 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 <stdexcept>
-
-#include <SDL/SDL_image.h>
-
-#include "Dispatcher.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,42 +22,33 @@ namespace Mf {
 
 Video::Video()
 {
-       init(mAttribs);
+       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 (mAttribs.caption == "Untitled")
-       {
-               mAttribs.caption = caption;
-       }
-       if (mAttribs.icon == "")
-       {
-               mAttribs.icon = icon;
-       }
-
-       init(mAttribs);
-}
+       Error error = Backend::getError();
+       if (error) error.raise();
 
-void Video::init(const Attributes& attribs)
-{
        mContext = 0;
        mFlags = 0;
-       mAttribs = attribs;
 
-       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()
@@ -88,33 +60,52 @@ void Video::recreateContext()
 
 void Video::setOpenGLAttributes()
 {
-       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);
+       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(mContext);
+
+       if (gCurrentVideo == this) gCurrentVideo = 0;
 }
 
 
-void Video::setVideoMode(const long mode[3])
+void Video::setVideoMode(const int mode[3])
 {
        if (mode != mAttribs.mode || !mContext)
        {
@@ -129,19 +120,16 @@ void Video::setVideoMode(const long mode[3])
                        mAttribs.mode[1] = mode[1];
                        mAttribs.mode[2] = mode[2];
 
-#if defined(_WIN32) || defined (_WIN64) || defined(__WIN32__)
-                       // on win32, creating a new context via SDL_SetVideoMode will wipe
-                       // out the GL state, so we gotta notify everyone to reload their
-                       // state after the change
-                       Mf::dispatcher::dispatch("video.context_recreated");
+#if !defined(linux) && !defined(__linux) && !defined(__linux__)
                        logInfo("video context recreated");
+                       Dispatch::global().dispatch("video.newcontext");
 #endif
                }
-               else throw Exception(Exception::SDL_ERROR);
+               else Error(Error::SDL_VIDEOMODE).raise();
        }
 }
 
-Video::Attributes Video::getAttributes() const
+Video::Attributes Video::attributes() const
 {
        return mAttribs;
 }
@@ -149,7 +137,7 @@ Video::Attributes Video::getAttributes() const
 
 void Video::resize(int width, int height)
 {
-       long mode[] = {width, height, mAttribs.mode[2]};
+       int mode[] = {width, height, mAttribs.mode[2]};
        setVideoMode(mode);
 }
 
@@ -169,12 +157,8 @@ void Video::setIcon()
 {
        if (mAttribs.icon != "")
        {
-               SDL_Surface* icon = IMG_Load(mAttribs.icon.c_str());
-               if (icon)
-               {
-                       SDL_WM_SetIcon(icon, 0);
-                       SDL_FreeSurface(icon);
-               }
+               Image icon(mAttribs.icon);
+               icon.setAsIcon();
        }
 }
 
@@ -183,6 +167,11 @@ std::string Video::getCaption() const
        return mAttribs.caption;
 }
 
+const std::string& Video::getIcon() const
+{
+       return mAttribs.icon;
+}
+
 
 void Video::setFull(bool full)
 {
@@ -276,12 +265,6 @@ void Video::setCursorGrab(bool cursorGrab)
 }
 
 
-void Video::makeActive()
-{
-       // NOP until the day SDL supports more than only one window.
-       // Still waiting...
-}
-
 void Video::swap()
 {
        SDL_GL_SwapBuffers();
@@ -299,37 +282,22 @@ int Video::getHeight() const
 }
 
 
+void Video::makeCurrent() const
+{
+       gCurrentVideo = const_cast<Video*>(this);
+}
+
+
 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;
+       init();
+}
 
-       Settings& settings = Settings::getInstance();
+Video::Attributes::Attributes(const Settings& settings)
+{
+       init();
 
-       std::vector<long> colors;
+       std::vector<int> colors;
        settings.get("colorbuffers", colors);
        if (colors.size() > 0) colorBuffer[0] = colors[0];
        if (colors.size() > 1) colorBuffer[1] = colors[1];
@@ -341,7 +309,7 @@ Video::Attributes::Attributes()
        settings.get("depthbuffer", depthBuffer);
        settings.get("stencilbuffer", stencilBuffer);
 
-       std::vector<long> accum;
+       std::vector<int> accum;
        settings.get("accumbuffers", accum);
        if (accum.size() > 0) accumBuffer[0] = accum[0];
        if (accum.size() > 1) accumBuffer[1] = accum[1];
@@ -352,7 +320,7 @@ Video::Attributes::Attributes()
        settings.get("multiesamplebuffers", multisampleBuffers);
        settings.get("multiesamplesamples", multisampleSamples);
        settings.get("swapcontrol", swapControl);
-       settings.get("hardwareonly", hardwareonly);
+       settings.get("hardwareonly", hardwareOnly);
 
        if (!settings.get("caption", caption))
        {
@@ -360,23 +328,77 @@ Video::Attributes::Attributes()
        }
        settings.get("icon", icon);
 
-       std::vector<long> dimensions;
+       settings.get("fullscreen", fullscreen);
+       settings.get("resizable", resizable);
+       settings.get("showcursor", cursorVisible);
+       settings.get("grab", cursorGrab);
+
+       std::vector<int> 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];
+}
 
-       settings.get("fullscreen", fullscreen);
-       settings.get("resizable", resizable);
-       settings.get("showcursor", cursorVisible);
-       settings.get("grab", cursorGrab);
+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;
+       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;
 }
 
 
-} // namespace Mf
+Video* Video::gCurrentVideo = 0;       // most recently instantiated instance
 
-/** vim: set ts=4 sw=4 tw=80: *************************************************/
+
+} // namespace Mf
 
This page took 0.026731 seconds and 4 git commands to generate.