Window.cpp

00001 
00002 //
00003 // SFML - Simple and Fast Multimedia Library
00004 // Copyright (C) 2007 Laurent Gomila (laurent.gom@gmail.com)
00005 //
00006 // This software is provided 'as-is', without any express or implied warranty.
00007 // In no event will the authors be held liable for any damages arising from the use of this software.
00008 //
00009 // Permission is granted to anyone to use this software for any purpose,
00010 // including commercial applications, and to alter it and redistribute it freely,
00011 // subject to the following restrictions:
00012 //
00013 // 1. The origin of this software must not be misrepresented;
00014 //    you must not claim that you wrote the original software.
00015 //    If you use this software in a product, an acknowledgment
00016 //    in the product documentation would be appreciated but is not required.
00017 //
00018 // 2. Altered source versions must be plainly marked as such,
00019 //    and must not be misrepresented as being the original software.
00020 //
00021 // 3. This notice may not be removed or altered from any source distribution.
00022 //
00024 
00026 // Headers
00028 #include <SFML/Window/Window.hpp>
00029 #include <SFML/Window/WindowImpl.hpp>
00030 #include <SFML/System/Sleep.hpp>
00031 #include <iostream>
00032 #include <memory>
00033 
00034 namespace
00035 {
00036     // Create a global dummy window, so that we have a valid OpenGL context at program startup
00037     //
00038     // TODO : provide a way to control the dummy creation / destruction, as the order of
00039     // initialization of globals is completely random across compile units...
00040     //
00041     std::auto_ptr<sf::priv::WindowImpl> DummyWindow(sf::priv::WindowImpl::New());
00042 }
00043 
00044 
00045 namespace sf
00046 {
00051 Window::Window() :
00052 myWindow        (NULL),
00053 myLastFrameTime (0.f),
00054 myIsExternal    (false),
00055 myFramerateLimit(0)
00056 {
00057 
00058 }
00059 
00060 
00064 Window::Window(VideoMode Mode, const std::string& Title, Style WindowStyle, int AntialiasingLevel) :
00065 myWindow        (NULL),
00066 myLastFrameTime (0.f),
00067 myIsExternal    (false),
00068 myFramerateLimit(0)
00069 {
00070     Create(Mode, Title, WindowStyle, AntialiasingLevel);
00071 }
00072 
00073 
00077 Window::Window(WindowHandle Handle, int AntialiasingLevel) :
00078 myWindow        (NULL),
00079 myLastFrameTime (0.f),
00080 myIsExternal    (true),
00081 myFramerateLimit(0)
00082 {
00083     Create(Handle, AntialiasingLevel);
00084 }
00085 
00086 
00090 Window::~Window()
00091 {
00092     // Destroy the window implementation
00093     delete myWindow;
00094 }
00095 
00096 
00100 void Window::Create(VideoMode Mode, const std::string& Title, Style WindowStyle, int AntialiasingLevel)
00101 {
00102     // Check validity of video mode
00103     if ((WindowStyle == Fullscreen) && !Mode.IsValid())
00104     {
00105         std::cerr << "The requested video mode is not available, switching to a valid mode" << std::endl;
00106         Mode = VideoMode::GetMode(0);
00107     }
00108 
00109     Initialize(priv::WindowImpl::New(Mode, Title, WindowStyle, AntialiasingLevel));
00110 }
00111 
00112 
00116 void Window::Create(WindowHandle Handle, int AntialiasingLevel)
00117 {
00118     Initialize(priv::WindowImpl::New(Handle, AntialiasingLevel));
00119 }
00120 
00121 
00125 unsigned int Window::GetWidth() const
00126 {
00127     return myWindow ? myWindow->GetWidth() : 0;
00128 }
00129 
00130 
00134 unsigned int Window::GetHeight() const
00135 {
00136     return myWindow ? myWindow->GetHeight() : 0;
00137 }
00138 
00139 
00143 unsigned int Window::GetDepthBits() const
00144 {
00145     return myWindow ? myWindow->GetDepthBits() : 0;
00146 }
00147 
00148 
00152 unsigned int Window::GetStencilBits() const
00153 {
00154     return myWindow ? myWindow->GetStencilBits() : 0;
00155 }
00156 
00157 
00161 bool Window::GetEvent(Event& EventReceived)
00162 {
00163     // Pop first event of queue, if not empty
00164     if (!myEvents.empty())
00165     {
00166         EventReceived = myEvents.front();
00167         myEvents.pop();
00168 
00169         return true;
00170     }
00171 
00172     return false;
00173 }
00174 
00175 
00179 void Window::UseVerticalSync(bool Enabled)
00180 {
00181     if (SetCurrent())
00182         myWindow->UseVerticalSync(Enabled);
00183 }
00184 
00185 
00189 void Window::ShowMouseCursor(bool Show)
00190 {
00191     if (SetCurrent())
00192         myWindow->ShowMouseCursor(Show);
00193 }
00194 
00195 
00199 void Window::SetPosition(int Left, int Top)
00200 {
00201     if (!myIsExternal)
00202     {
00203         if (SetCurrent())
00204             myWindow->SetPosition(Left, Top);
00205     }
00206     else
00207     {
00208         std::cerr << "Warning : trying to change the position of an external SFML window, which is not allowed" << std::endl;
00209     }
00210 }
00211 
00212 
00216 bool Window::SetCurrent() const
00217 {
00218     if (myWindow)
00219     {
00220         myWindow->SetCurrent();
00221         return true;
00222     }
00223 
00224     return false;
00225 }
00226 
00227 
00231 void Window::Display()
00232 {
00233     // Limit the framerate if needed
00234     if (myFramerateLimit > 0)
00235     {
00236         float FrameTime = 1.f / myFramerateLimit;
00237         if (myClock.GetElapsedTime() < FrameTime)
00238             Sleep(FrameTime - myClock.GetElapsedTime());
00239     }
00240 
00241     // Measure the time elapsed since last frame
00242     myLastFrameTime = myClock.GetElapsedTime();
00243     myClock.Reset();
00244 
00245     if (SetCurrent())
00246     {
00247         // Display the backbuffer on screen
00248         myWindow->Display();
00249 
00250         // Let the window implementation process incoming events
00251         myWindow->ProcessEvents();
00252     }
00253 }
00254 
00255 
00259 const Input& Window::GetInput() const
00260 {
00261     return myInput;
00262 }
00263 
00264 
00268 void Window::SetFramerateLimit(unsigned int Limit)
00269 {
00270     myFramerateLimit = Limit;
00271 }
00272 
00273 
00277 float Window::GetFrameTime() const
00278 {
00279     return myLastFrameTime;
00280 }
00281 
00282 
00286 void Window::OnEvent(const Event& EventReceived)
00287 {
00288     myEvents.push(EventReceived);
00289 }
00290 
00291 
00295 void Window::Initialize(priv::WindowImpl* Window)
00296 {
00297     // Destroy window if already created
00298     if (myWindow)
00299         delete myWindow;
00300 
00301     // Assign new window and listen to its events
00302     myWindow = Window;
00303     myWindow->AddListener(this);
00304 
00305     // Attach input to the window
00306     myWindow->AddListener(&myInput);
00307 
00308     // Disable vertical synchronization and show mouse cursor by default (to get a consistent behavior)
00309     UseVerticalSync(false);
00310     ShowMouseCursor(true);
00311 
00312     // Reset frame time
00313     myClock.Reset();
00314     myLastFrameTime = 0.f;
00315 }
00316 
00317 } // namespace sf