]> Dogcows Code - chaz/yoink/blobdiff - src/moof/video.cc
the massive refactoring effort
[chaz/yoink] / src / moof / video.cc
diff --git a/src/moof/video.cc b/src/moof/video.cc
new file mode 100644 (file)
index 0000000..32278cc
--- /dev/null
@@ -0,0 +1,394 @@
+
+/*]  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 <stdexcept>
+
+#include "dispatcher.hh"
+#include "image.hh"
+#include "log.hh"
+#include "settings.hh"
+#include "video.hh"
+
+
+namespace moof {
+
+
+video::video(const std::string& caption)
+{
+       video::caption(caption);
+       init();
+}
+
+video::video(const class attributes& attribs) :
+       attributes_(attribs)
+{
+       init();
+}
+
+video::video(const std::string& caption,
+                        const class attributes& attribs) :
+       attributes_(attribs)
+{
+       video::caption(caption);
+       init();
+}
+
+void video::init()
+{
+       context_ = 0;
+       flags_ = 0;
+
+       fullscreen(attributes_.is_fullscreen);
+       resizable(attributes_.is_resizable);
+       set_opengl_attributes();
+       cursor_visible(attributes_.is_cursor_visible);
+       cursor_captured(attributes_.is_cursor_captured);
+       mode(attributes_.mode);
+
+       if (!current_) make_current();
+}
+
+void video::recreate_context()
+{
+       SDL_FreeSurface(context_);
+       context_ = 0;
+       mode(attributes_.mode);
+}
+
+void video::set_opengl_attributes()
+{
+       SDL_GL_SetAttribute(SDL_GL_RED_SIZE,
+                                               attributes_.color_buffer[0]);
+       SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE,
+                                               attributes_.color_buffer[1]);
+       SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE,
+                                               attributes_.color_buffer[2]);
+       SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE,
+                                               attributes_.color_buffer[3]);
+       SDL_GL_SetAttribute(SDL_GL_BUFFER_SIZE,
+                                               attributes_.frame_buffer);
+       SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER,
+                                               attributes_.is_double_buffer);
+       SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE,
+                                               attributes_.depth_buffer);
+       SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE,
+                                               attributes_.stencil_buffer);
+       SDL_GL_SetAttribute(SDL_GL_ACCUM_RED_SIZE,
+                                               attributes_.accumulator_buffer[0]);
+       SDL_GL_SetAttribute(SDL_GL_ACCUM_GREEN_SIZE,
+                                               attributes_.accumulator_buffer[1]);
+       SDL_GL_SetAttribute(SDL_GL_ACCUM_BLUE_SIZE,
+                                               attributes_.accumulator_buffer[2]);
+       SDL_GL_SetAttribute(SDL_GL_ACCUM_ALPHA_SIZE,
+                                               attributes_.accumulator_buffer[3]);
+       SDL_GL_SetAttribute(SDL_GL_STEREO,
+                                               attributes_.is_stereo);
+       SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS,
+                                               attributes_.multisample_buffers);
+       SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES,
+                                               attributes_.multisample_samples);
+       SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL,
+                                               attributes_.is_swap_control);
+       SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL,
+                                               attributes_.is_hardware_only);
+}
+
+
+video::~video()
+{
+       SDL_FreeSurface(context_);
+
+       if (current_ == this) current_ = 0;
+}
+
+
+class video::attributes video::attributes() const
+{
+       return attributes_;
+}
+
+
+void video::mode(const int mode[3])
+{
+       if (mode != attributes_.mode || !context_)
+       {
+               if (context_) SDL_FreeSurface(context_);
+
+               context_ = SDL_SetVideoMode(mode[0], mode[1], mode[2],
+                               SDL_OPENGL | flags_);
+
+               if (context_)
+               {
+                       attributes_.mode[0] = mode[0];
+                       attributes_.mode[1] = mode[1];
+                       attributes_.mode[2] = mode[2];
+
+#if !defined(linux) && !defined(__linux) && !defined(__linux__)
+                       log_info("video context recreated");
+                       dispatcher::global().dispatch("video.newcontext");
+#endif
+               }
+               else
+               {
+                       throw std::runtime_error("bad video mode attempted");
+               }
+       }
+}
+
+
+void video::resize(int width, int height)
+{
+       int mode[] = {width, height, attributes_.mode[2]};
+       video::mode(mode);
+}
+
+bool video::iconify()
+{
+       return SDL_WM_IconifyWindow();
+}
+
+
+void video::caption(const std::string& caption)
+{
+       SDL_WM_SetCaption(caption.c_str(), 0);
+}
+
+std::string video::caption() const
+{
+       char* caption;
+       SDL_WM_GetCaption(&caption, 0);
+       return std::string(caption);
+}
+
+
+void video::fullscreen(bool full)
+{
+       if (full != fullscreen() || !context_)
+       {
+               if (context_)
+               {
+                       flags_ ^= SDL_FULLSCREEN;
+
+#if defined(linux) || defined(__linux) || defined(__linux__)
+                       if (SDL_WM_ToggleFullScreen(context_) == 0)
+#endif
+                       recreate_context();
+               }
+               else
+               {
+                       if (full) flags_ |= SDL_FULLSCREEN;
+                       else flags_ &= ~SDL_FULLSCREEN;
+               }
+       }
+}
+
+bool video::fullscreen() const
+{
+       return flags_ & SDL_FULLSCREEN;
+}
+
+void video::toggle_fullscreen()
+{
+       fullscreen(!fullscreen());
+}
+
+
+void video::resizable(bool is_resizable)
+{
+       if (is_resizable != resizable() || !context_)
+       {
+               if (context_)
+               {
+                       flags_ ^= SDL_RESIZABLE;
+                       recreate_context();
+               }
+               else
+               {
+                       if (is_resizable) flags_ |= SDL_RESIZABLE;
+                       else flags_ &= ~SDL_RESIZABLE;
+               }
+       }
+}
+
+bool video::resizable() const
+{
+       return flags_ & SDL_RESIZABLE;
+}
+
+void video::toggle_resizable()
+{
+       resizable(!resizable());
+}
+
+
+void video::cursor_visible(bool is_cursor_visible)
+{
+       SDL_ShowCursor(is_cursor_visible? SDL_ENABLE : SDL_DISABLE);
+}
+
+bool video::cursor_visible() const
+{
+       return (SDL_ShowCursor(SDL_QUERY) == SDL_ENABLE);
+}
+
+void video::toggle_cursor_visible()
+{
+       cursor_visible(!cursor_visible());
+}
+
+
+bool video::cursor_captured() const
+{
+       return (SDL_WM_GrabInput(SDL_GRAB_QUERY) == SDL_GRAB_ON);
+}
+
+void video::cursor_captured(bool is_cursor_captured)
+{
+       SDL_WM_GrabInput(is_cursor_captured? SDL_GRAB_ON : SDL_GRAB_OFF);
+}
+
+void video::toggle_cursor_captured()
+{
+       cursor_captured(!cursor_captured());
+}
+
+
+void video::swap()
+{
+       SDL_GL_SwapBuffers();
+}
+
+
+int video::width() const
+{
+       return context_->w;
+}
+
+int video::height() const
+{
+       return context_->h;
+}
+
+
+void video::make_current() const
+{
+       current_ = const_cast<video*>(this);
+}
+
+
+video::attributes::attributes()
+{
+       init();
+}
+
+video::attributes::attributes(const settings& settings)
+{
+       init();
+
+       std::vector<int> colors;
+       settings.get("colorbuffers", colors);
+       if (colors.size() > 0) color_buffer[0] = colors[0];
+       if (colors.size() > 1) color_buffer[1] = colors[1];
+       if (colors.size() > 2) color_buffer[2] = colors[2];
+       if (colors.size() > 3) color_buffer[3] = colors[3];
+
+       settings.get("framebuffer", frame_buffer);
+       settings.get("doublebuffer", is_double_buffer);
+       settings.get("depthbuffer", depth_buffer);
+       settings.get("stencilbuffer", stencil_buffer);
+
+       std::vector<int> accum;
+       settings.get("accumbuffers", accum);
+       if (accum.size() > 0) accumulator_buffer[0] = accum[0];
+       if (accum.size() > 1) accumulator_buffer[1] = accum[1];
+       if (accum.size() > 2) accumulator_buffer[2] = accum[2];
+       if (accum.size() > 3) accumulator_buffer[3] = accum[3];
+
+       settings.get("stereo", is_stereo);
+       settings.get("multiesamplebuffers", multisample_buffers);
+       settings.get("multiesamplesamples", multisample_samples);
+       settings.get("swapcontrol", is_swap_control);
+       settings.get("hardwareonly", is_hardware_only);
+
+       settings.get("fullscreen", is_fullscreen);
+       settings.get("resizable", is_resizable);
+       settings.get("showcursor", is_cursor_visible);
+       settings.get("grab", is_cursor_captured);
+
+       std::vector<int> dimensions;
+       settings.get("videomode", dimensions);
+       if (dimensions.size() > 1)
+       {
+               mode[0] = dimensions[0];
+               mode[1] = dimensions[1];
+       }
+       else if (is_fullscreen && backend::is_initialized())
+       {
+               SDL_Rect** modes = SDL_ListModes(NULL,
+                                                                                SDL_FULLSCREEN | SDL_HWSURFACE);
+
+               if (modes == (SDL_Rect**)0)
+               {
+                       log_error("no native video mode");
+               }
+               else if (modes == (SDL_Rect**)-1)
+               {
+                       log_warning("any resolution allowed; "
+                                                  "choosing default 800x600");
+                       mode[0] = 800;
+                       mode[1] = 600;
+               }
+               else
+               {
+                       mode[0] = (*modes)->w;
+                       mode[1] = (*modes)->h;
+                       log_info << "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)
+       color_buffer[0] = 3;
+       color_buffer[1] = 3;
+       color_buffer[2] = 2;
+       color_buffer[3] = 0;
+       frame_buffer = 0;
+       is_double_buffer = true;
+       depth_buffer = 16;
+       stencil_buffer = 0;
+       accumulator_buffer[0] = 0;
+       accumulator_buffer[1] = 0;
+       accumulator_buffer[2] = 0;
+       accumulator_buffer[3] = 0;
+       is_stereo = false;
+       multisample_buffers = 0;
+       multisample_samples = 0;
+       is_swap_control = false;
+       is_hardware_only = false;
+       mode[0] = 640;
+       mode[1] = 480;
+       mode[2] = 0;
+       is_fullscreen = false;
+       is_resizable = false;
+       is_cursor_visible = true;
+       is_cursor_captured = false;
+}
+
+
+video* video::current_ = 0;    // most recently instantiated instance
+
+
+} // namespace moof
+
This page took 0.022098 seconds and 4 git commands to generate.