mirror of
https://github.com/love2d/love.git
synced 2026-08-17 11:00:31 +02:00
Create love.window, abstract SDL out of love.graphics
This commit is contained in:
@@ -23,6 +23,7 @@
|
|||||||
#include <common/Vector.h>
|
#include <common/Vector.h>
|
||||||
|
|
||||||
#include "Graphics.h"
|
#include "Graphics.h"
|
||||||
|
#include <window/sdl/Window.h>
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
@@ -39,17 +40,7 @@ namespace opengl
|
|||||||
Graphics::Graphics()
|
Graphics::Graphics()
|
||||||
: currentFont(0), currentImageFilter(), lineWidth(1), matrixLimit(0), userMatrices(0)
|
: currentFont(0), currentImageFilter(), lineWidth(1), matrixLimit(0), userMatrices(0)
|
||||||
{
|
{
|
||||||
// Indicates that there is no screen
|
currentWindow = love::window::sdl::Window::getSingleton();
|
||||||
// created yet.
|
|
||||||
currentMode.width = 0;
|
|
||||||
currentMode.height = 0;
|
|
||||||
currentMode.fullscreen = 0;
|
|
||||||
|
|
||||||
// Window should be centered.
|
|
||||||
SDL_putenv(const_cast<char *>("SDL_VIDEO_CENTERED=center"));
|
|
||||||
|
|
||||||
if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0)
|
|
||||||
throw Exception(SDL_GetError());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Graphics::~Graphics()
|
Graphics::~Graphics()
|
||||||
@@ -57,7 +48,7 @@ namespace opengl
|
|||||||
if (currentFont != 0)
|
if (currentFont != 0)
|
||||||
currentFont->release();
|
currentFont->release();
|
||||||
|
|
||||||
SDL_QuitSubSystem(SDL_INIT_VIDEO);
|
currentWindow->release();
|
||||||
}
|
}
|
||||||
|
|
||||||
const char * Graphics::getName() const
|
const char * Graphics::getName() const
|
||||||
@@ -67,12 +58,7 @@ namespace opengl
|
|||||||
|
|
||||||
bool Graphics::checkMode(int width, int height, bool fullscreen)
|
bool Graphics::checkMode(int width, int height, bool fullscreen)
|
||||||
{
|
{
|
||||||
Uint32 sdlflags = fullscreen ? (SDL_OPENGL | SDL_FULLSCREEN) : SDL_OPENGL;
|
return currentWindow->checkWindowSize(width, height, fullscreen);
|
||||||
|
|
||||||
// Check if mode is supported
|
|
||||||
int bpp = SDL_VideoModeOK(width, height, 32, sdlflags);
|
|
||||||
|
|
||||||
return (bpp >= 16);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DisplayState Graphics::saveState()
|
DisplayState Graphics::saveState()
|
||||||
@@ -104,10 +90,6 @@ namespace opengl
|
|||||||
if (s.scissor)
|
if (s.scissor)
|
||||||
glGetIntegerv(GL_SCISSOR_BOX, s.scissorBox);
|
glGetIntegerv(GL_SCISSOR_BOX, s.scissorBox);
|
||||||
|
|
||||||
char *cap = 0;
|
|
||||||
SDL_WM_GetCaption(&cap, 0);
|
|
||||||
s.caption = cap;
|
|
||||||
s.mouseVisible = (SDL_ShowCursor(SDL_QUERY) == SDL_ENABLE) ? true : false;
|
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -123,9 +105,6 @@ namespace opengl
|
|||||||
setScissor(s.scissorBox[0], s.scissorBox[1], s.scissorBox[2], s.scissorBox[3]);
|
setScissor(s.scissorBox[0], s.scissorBox[1], s.scissorBox[2], s.scissorBox[3]);
|
||||||
else
|
else
|
||||||
setScissor();
|
setScissor();
|
||||||
|
|
||||||
setCaption(s.caption.c_str());
|
|
||||||
SDL_ShowCursor(s.mouseVisible ? SDL_ENABLE : SDL_DISABLE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Graphics::setMode(int width, int height, bool fullscreen, bool vsync, int fsaa)
|
bool Graphics::setMode(int width, int height, bool fullscreen, bool vsync, int fsaa)
|
||||||
@@ -140,95 +119,7 @@ namespace opengl
|
|||||||
// the display mode change.
|
// the display mode change.
|
||||||
Volatile::unloadAll();
|
Volatile::unloadAll();
|
||||||
|
|
||||||
// Get caption.
|
currentWindow->setWindow(width, height, fullscreen, vsync, fsaa);
|
||||||
|
|
||||||
// We need to restart the subsystem for two reasons:
|
|
||||||
// 1) Special case for fullscreen -> windowed. Windows XP did not
|
|
||||||
// work well with "normal" display mode change in this case.
|
|
||||||
// The application window does leave fullscreen, but the desktop
|
|
||||||
// resolution does not revert to the correct one. Restarting the
|
|
||||||
// SDL video subsystem does the trick, though.
|
|
||||||
// 2) Restart the event system (for whatever reason the event system
|
|
||||||
// started and stopped with SDL_INIT_VIDEO, see:
|
|
||||||
// http://sdl.beuc.net/sdl.wiki/Introduction_to_Events)
|
|
||||||
// because the mouse position will not be able to exceed
|
|
||||||
// the previous' video mode window size (i.e. alway
|
|
||||||
// love.mouse.getX() < 800 when switching from 800x600 to a
|
|
||||||
// higher resolution)
|
|
||||||
SDL_QuitSubSystem(SDL_INIT_VIDEO);
|
|
||||||
if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0)
|
|
||||||
{
|
|
||||||
std::cout << "Could not init SDL_VIDEO: " << SDL_GetError() << std::endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set caption.
|
|
||||||
|
|
||||||
// Set GL attributes
|
|
||||||
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
|
|
||||||
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
|
|
||||||
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
|
|
||||||
SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
|
|
||||||
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
|
|
||||||
SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, (vsync ? 1 : 0));
|
|
||||||
SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 1);
|
|
||||||
|
|
||||||
// FSAA
|
|
||||||
if (fsaa > 0)
|
|
||||||
{
|
|
||||||
SDL_GL_SetAttribute( SDL_GL_MULTISAMPLEBUFFERS, 1 ) ;
|
|
||||||
SDL_GL_SetAttribute( SDL_GL_MULTISAMPLESAMPLES, fsaa ) ;
|
|
||||||
glEnable(GL_MULTISAMPLE);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fullscreen?
|
|
||||||
Uint32 sdlflags = fullscreen ? (SDL_OPENGL | SDL_FULLSCREEN) : SDL_OPENGL;
|
|
||||||
|
|
||||||
if (!isCreated())
|
|
||||||
setCaption("");
|
|
||||||
|
|
||||||
// Have SDL set the video mode.
|
|
||||||
if (SDL_SetVideoMode(width, height, 32, sdlflags ) == 0)
|
|
||||||
{
|
|
||||||
bool failed = true;
|
|
||||||
if (fsaa > 0)
|
|
||||||
{
|
|
||||||
// FSAA might have failed, disable it and try again
|
|
||||||
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 0);
|
|
||||||
failed = SDL_SetVideoMode(width, height, 32, sdlflags ) == 0;
|
|
||||||
if (failed)
|
|
||||||
{
|
|
||||||
// There might be no FSAA at all
|
|
||||||
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 0);
|
|
||||||
failed = SDL_SetVideoMode(width, height, 32, sdlflags ) == 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (failed)
|
|
||||||
{
|
|
||||||
std::cerr << "Could not set video mode: " << SDL_GetError() << std::endl;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (width == 0 || height == 0)
|
|
||||||
{
|
|
||||||
const SDL_VideoInfo* videoinfo = SDL_GetVideoInfo();
|
|
||||||
width = videoinfo->current_w;
|
|
||||||
height = videoinfo->current_h;
|
|
||||||
}
|
|
||||||
|
|
||||||
GLint buffers;
|
|
||||||
GLint samples;
|
|
||||||
|
|
||||||
glGetIntegerv( GL_SAMPLE_BUFFERS_ARB, & buffers ) ;
|
|
||||||
glGetIntegerv( GL_SAMPLES_ARB, & samples ) ;
|
|
||||||
|
|
||||||
// Don't fail because of this, but issue a warning.
|
|
||||||
if ( (! buffers && fsaa) || (samples != fsaa))
|
|
||||||
{
|
|
||||||
std::cerr << "Warning, quality setting failed! (Result: buffers: " << buffers << ", samples: " << samples << ")" << std::endl;
|
|
||||||
fsaa = !buffers ? 0 : samples;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Okay, setup OpenGL.
|
// Okay, setup OpenGL.
|
||||||
|
|
||||||
@@ -263,18 +154,6 @@ namespace opengl
|
|||||||
// Set pixel row alignment
|
// Set pixel row alignment
|
||||||
glPixelStorei(GL_UNPACK_ALIGNMENT, 2);
|
glPixelStorei(GL_UNPACK_ALIGNMENT, 2);
|
||||||
|
|
||||||
// Get the actual vsync status
|
|
||||||
int real_vsync;
|
|
||||||
SDL_GL_GetAttribute(SDL_GL_SWAP_CONTROL, &real_vsync);
|
|
||||||
|
|
||||||
// Set the new display mode as the current display mode.
|
|
||||||
currentMode.width = width;
|
|
||||||
currentMode.height = height;
|
|
||||||
currentMode.colorDepth = 32;
|
|
||||||
currentMode.fsaa = fsaa;
|
|
||||||
currentMode.fullscreen = fullscreen;
|
|
||||||
currentMode.vsync = (real_vsync != 0);
|
|
||||||
|
|
||||||
// Reload all volatile objects.
|
// Reload all volatile objects.
|
||||||
if (!Volatile::loadAll())
|
if (!Volatile::loadAll())
|
||||||
std::cerr << "Could not reload all volatile objects." << std::endl;
|
std::cerr << "Could not reload all volatile objects." << std::endl;
|
||||||
@@ -290,23 +169,17 @@ namespace opengl
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Graphics::getMode(int *width, int *height, bool *fullscreen, bool *vsync, int *fsaa)
|
void Graphics::getMode(int &width, int &height, bool &fullscreen, bool &vsync, int &fsaa)
|
||||||
{
|
{
|
||||||
*width = currentMode.width;
|
currentWindow->getWindow(width, height, fullscreen, vsync, fsaa);
|
||||||
*height = currentMode.height;
|
|
||||||
*fullscreen = currentMode.fullscreen;
|
|
||||||
*vsync = currentMode.vsync;
|
|
||||||
*fsaa = currentMode.fsaa;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Graphics::toggleFullscreen()
|
bool Graphics::toggleFullscreen()
|
||||||
{
|
{
|
||||||
// Try to do the change.
|
int width, height, fsaa;
|
||||||
return setMode(currentMode.width,
|
bool fullscreen, vsync;
|
||||||
currentMode.height,
|
currentWindow->getWindow(width, height, fullscreen, vsync, fsaa);
|
||||||
!currentMode.fullscreen,
|
return currentWindow->setWindow(width, height, !fullscreen, vsync, fsaa);
|
||||||
currentMode.vsync,
|
|
||||||
currentMode.fsaa);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -327,101 +200,82 @@ namespace opengl
|
|||||||
|
|
||||||
void Graphics::present()
|
void Graphics::present()
|
||||||
{
|
{
|
||||||
SDL_GL_SwapBuffers();
|
currentWindow->swapBuffers();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Graphics::setIcon(Image * image)
|
void Graphics::setIcon(Image * image)
|
||||||
{
|
{
|
||||||
Uint32 rmask, gmask, bmask, amask;
|
currentWindow->setIcon(image->getData());
|
||||||
#ifdef LOVE_BIG_ENDIAN
|
|
||||||
rmask = 0xFF000000;
|
|
||||||
gmask = 0x00FF0000;
|
|
||||||
bmask = 0x0000FF00;
|
|
||||||
amask = 0x000000FF;
|
|
||||||
#else
|
|
||||||
rmask = 0x000000FF;
|
|
||||||
gmask = 0x0000FF00;
|
|
||||||
bmask = 0x00FF0000;
|
|
||||||
amask = 0xFF000000;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int w = static_cast<int>(image->getWidth());
|
|
||||||
int h = static_cast<int>(image->getHeight());
|
|
||||||
int pitch = static_cast<int>(image->getWidth() * 4);
|
|
||||||
|
|
||||||
SDL_Surface * icon = SDL_CreateRGBSurfaceFrom(image->getData()->getData(), w, h, 32, pitch, rmask, gmask, bmask, amask);
|
|
||||||
SDL_WM_SetIcon(icon, NULL);
|
|
||||||
SDL_FreeSurface(icon);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Graphics::setCaption(const char * caption)
|
void Graphics::setCaption(const char * caption)
|
||||||
{
|
{
|
||||||
SDL_WM_SetCaption(caption, 0);
|
std::string title(caption);
|
||||||
|
currentWindow->setWindowTitle(title);
|
||||||
}
|
}
|
||||||
|
|
||||||
int Graphics::getCaption(lua_State * L)
|
int Graphics::getCaption(lua_State * L)
|
||||||
{
|
{
|
||||||
char * title = 0;
|
std::string title = currentWindow->getWindowTitle();
|
||||||
SDL_WM_GetCaption(&title, 0);
|
lua_pushstring(L, title.c_str());
|
||||||
lua_pushstring(L, title);
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Graphics::getWidth()
|
int Graphics::getWidth()
|
||||||
{
|
{
|
||||||
return currentMode.width;
|
return currentWindow->getWidth();
|
||||||
}
|
}
|
||||||
|
|
||||||
int Graphics::getHeight()
|
int Graphics::getHeight()
|
||||||
{
|
{
|
||||||
return currentMode.height;
|
return currentWindow->getHeight();
|
||||||
}
|
}
|
||||||
|
|
||||||
int Graphics::getRenderHeight()
|
int Graphics::getRenderHeight()
|
||||||
{
|
{
|
||||||
if (Canvas::current)
|
if (Canvas::current)
|
||||||
return Canvas::current->getHeight();
|
return Canvas::current->getHeight();
|
||||||
return currentMode.height;
|
return getHeight();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Graphics::isCreated()
|
bool Graphics::isCreated()
|
||||||
{
|
{
|
||||||
return (currentMode.width > 0) || (currentMode.height > 0);
|
return currentWindow->isCreated();
|
||||||
}
|
}
|
||||||
|
|
||||||
int Graphics::getModes(lua_State * L)
|
int Graphics::getModes(lua_State * L)
|
||||||
{
|
{
|
||||||
SDL_Rect ** modes = SDL_ListModes(0, SDL_OPENGL | SDL_FULLSCREEN);
|
int n;
|
||||||
|
love::window::Window::WindowSize ** modes = currentWindow->getFullscreenSizes(n);
|
||||||
|
|
||||||
if (modes == (SDL_Rect **)0 || modes == (SDL_Rect **)-1)
|
if (modes == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
int index = 1;
|
|
||||||
|
|
||||||
lua_newtable(L);
|
lua_newtable(L);
|
||||||
|
|
||||||
for (int i=0;modes[i];++i)
|
for (int i = 0; i < n ; i++)
|
||||||
{
|
{
|
||||||
lua_pushinteger(L, index);
|
lua_pushinteger(L, i+1);
|
||||||
lua_newtable(L);
|
lua_newtable(L);
|
||||||
|
|
||||||
// Inner table attribs.
|
// Inner table attribs.
|
||||||
|
|
||||||
lua_pushstring(L, "width");
|
lua_pushstring(L, "width");
|
||||||
lua_pushinteger(L, modes[i]->w);
|
lua_pushinteger(L, modes[i]->width);
|
||||||
lua_settable(L, -3);
|
lua_settable(L, -3);
|
||||||
|
|
||||||
lua_pushstring(L, "height");
|
lua_pushstring(L, "height");
|
||||||
lua_pushinteger(L, modes[i]->h);
|
lua_pushinteger(L, modes[i]->height);
|
||||||
lua_settable(L, -3);
|
lua_settable(L, -3);
|
||||||
|
|
||||||
// Inner table attribs end.
|
// Inner table attribs end.
|
||||||
|
|
||||||
lua_settable(L, -3);
|
lua_settable(L, -3);
|
||||||
|
|
||||||
index++;
|
delete modes[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
delete[] modes;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1139,7 +993,7 @@ namespace opengl
|
|||||||
|
|
||||||
bool Graphics::hasFocus()
|
bool Graphics::hasFocus()
|
||||||
{
|
{
|
||||||
return (SDL_GetAppState() & SDL_APPINPUTFOCUS) != 0;
|
return currentWindow->hasFocus();
|
||||||
}
|
}
|
||||||
} // opengl
|
} // opengl
|
||||||
} // graphics
|
} // graphics
|
||||||
|
|||||||
@@ -25,8 +25,7 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
// SDL
|
// OpenGL
|
||||||
#include <SDL.h>
|
|
||||||
#include "GLee.h"
|
#include "GLee.h"
|
||||||
|
|
||||||
// LOVE
|
// LOVE
|
||||||
@@ -36,6 +35,8 @@
|
|||||||
#include <image/Image.h>
|
#include <image/Image.h>
|
||||||
#include <image/ImageData.h>
|
#include <image/ImageData.h>
|
||||||
|
|
||||||
|
#include <window/Window.h>
|
||||||
|
|
||||||
#include "Font.h"
|
#include "Font.h"
|
||||||
#include "Image.h"
|
#include "Image.h"
|
||||||
#include "Quad.h"
|
#include "Quad.h"
|
||||||
@@ -51,15 +52,6 @@ namespace graphics
|
|||||||
namespace opengl
|
namespace opengl
|
||||||
{
|
{
|
||||||
|
|
||||||
struct DisplayMode
|
|
||||||
{
|
|
||||||
int width, height; // The size of the screen.
|
|
||||||
int colorDepth; // The color depth of the display mode.
|
|
||||||
bool fullscreen; // Fullscreen (true), or windowed (false).
|
|
||||||
bool vsync; // Vsync enabled (true), or disabled (false).
|
|
||||||
int fsaa; // 0 for no FSAA, otherwise 1, 2 or 4.
|
|
||||||
};
|
|
||||||
|
|
||||||
// During display mode changing, certain
|
// During display mode changing, certain
|
||||||
// variables about the OpenGL context are
|
// variables about the OpenGL context are
|
||||||
// lost.
|
// lost.
|
||||||
@@ -114,7 +106,7 @@ namespace opengl
|
|||||||
|
|
||||||
Font * currentFont;
|
Font * currentFont;
|
||||||
Image::Filter currentImageFilter;
|
Image::Filter currentImageFilter;
|
||||||
DisplayMode currentMode;
|
love::window::Window *currentWindow;
|
||||||
|
|
||||||
float lineWidth;
|
float lineWidth;
|
||||||
GLint matrixLimit;
|
GLint matrixLimit;
|
||||||
@@ -161,7 +153,7 @@ namespace opengl
|
|||||||
* @param vsync Pointer to a boolean for the vsync status.
|
* @param vsync Pointer to a boolean for the vsync status.
|
||||||
* @param fsaa Pointer to an integer for the current number of full scene anti-aliasing buffers.
|
* @param fsaa Pointer to an integer for the current number of full scene anti-aliasing buffers.
|
||||||
**/
|
**/
|
||||||
void getMode(int * width, int * height, bool * fullscreen, bool * vsync, int * fsaa);
|
void getMode(int & width, int & height, bool & fullscreen, bool & vsync, int & fsaa);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Toggles fullscreen. Note that this also needs to reload the
|
* Toggles fullscreen. Note that this also needs to reload the
|
||||||
|
|||||||
@@ -22,7 +22,7 @@
|
|||||||
|
|
||||||
#include <common/math.h>
|
#include <common/math.h>
|
||||||
|
|
||||||
#include <SDL_opengl.h>
|
#include <GL/gl.h>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
|
||||||
|
|||||||
@@ -36,7 +36,7 @@
|
|||||||
|
|
||||||
// OpenGL
|
// OpenGL
|
||||||
#include "GLee.h"
|
#include "GLee.h"
|
||||||
#include <SDL/SDL_opengl.h>
|
#include <GL/gl.h>
|
||||||
|
|
||||||
namespace love
|
namespace love
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -27,7 +27,7 @@
|
|||||||
|
|
||||||
// OpenGL
|
// OpenGL
|
||||||
#include "GLee.h"
|
#include "GLee.h"
|
||||||
#include <SDL/SDL_opengl.h>
|
#include <GL/gl.h>
|
||||||
|
|
||||||
namespace love
|
namespace love
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ namespace opengl
|
|||||||
{
|
{
|
||||||
int w, h, fsaa;
|
int w, h, fsaa;
|
||||||
bool fs, vsync;
|
bool fs, vsync;
|
||||||
instance->getMode(&w, &h, &fs, &vsync, &fsaa);
|
instance->getMode(w, h, fs, vsync, fsaa);
|
||||||
lua_pushnumber(L, w);
|
lua_pushnumber(L, w);
|
||||||
lua_pushnumber(L, h);
|
lua_pushnumber(L, h);
|
||||||
lua_pushboolean(L, fs);
|
lua_pushboolean(L, fs);
|
||||||
|
|||||||
@@ -0,0 +1,40 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2006-2011 LOVE Development Team
|
||||||
|
*
|
||||||
|
* This software is provided 'as-is', without any express or implied
|
||||||
|
* warranty. In no event will the authors be held liable for any damages
|
||||||
|
* arising from the use of this software.
|
||||||
|
*
|
||||||
|
* Permission is granted to anyone to use this software for any purpose,
|
||||||
|
* including commercial applications, and to alter it and redistribute it
|
||||||
|
* freely, subject to the following restrictions:
|
||||||
|
*
|
||||||
|
* 1. The origin of this software must not be misrepresented; you must not
|
||||||
|
* claim that you wrote the original software. If you use this software
|
||||||
|
* in a product, an acknowledgment in the product documentation would be
|
||||||
|
* appreciated but is not required.
|
||||||
|
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||||
|
* misrepresented as being the original software.
|
||||||
|
* 3. This notice may not be removed or altered from any source distribution.
|
||||||
|
**/
|
||||||
|
|
||||||
|
// LOVE
|
||||||
|
#include "Window.h"
|
||||||
|
|
||||||
|
namespace love
|
||||||
|
{
|
||||||
|
namespace window
|
||||||
|
{
|
||||||
|
Window *Window::singleton = NULL;
|
||||||
|
|
||||||
|
Window::~Window()
|
||||||
|
{
|
||||||
|
if (singleton == this)
|
||||||
|
singleton = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Window::swapBuffers()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
} // window
|
||||||
|
} // love
|
||||||
@@ -0,0 +1,78 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2006-2011 LOVE Development Team
|
||||||
|
*
|
||||||
|
* This software is provided 'as-is', without any express or implied
|
||||||
|
* warranty. In no event will the authors be held liable for any damages
|
||||||
|
* arising from the use of this software.
|
||||||
|
*
|
||||||
|
* Permission is granted to anyone to use this software for any purpose,
|
||||||
|
* including commercial applications, and to alter it and redistribute it
|
||||||
|
* freely, subject to the following restrictions:
|
||||||
|
*
|
||||||
|
* 1. The origin of this software must not be misrepresented; you must not
|
||||||
|
* claim that you wrote the original software. If you use this software
|
||||||
|
* in a product, an acknowledgment in the product documentation would be
|
||||||
|
* appreciated but is not required.
|
||||||
|
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||||
|
* misrepresented as being the original software.
|
||||||
|
* 3. This notice may not be removed or altered from any source distribution.
|
||||||
|
**/
|
||||||
|
|
||||||
|
#ifndef LOVE_WINDOW_WINDOW_H
|
||||||
|
#define LOVE_WINDOW_WINDOW_H
|
||||||
|
|
||||||
|
// STL
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
// LOVE
|
||||||
|
#include <common/Module.h>
|
||||||
|
#include <image/ImageData.h>
|
||||||
|
|
||||||
|
namespace love
|
||||||
|
{
|
||||||
|
namespace window
|
||||||
|
{
|
||||||
|
class Window : public Module
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
static Window *singleton;
|
||||||
|
|
||||||
|
public:
|
||||||
|
struct WindowSize
|
||||||
|
{
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
};
|
||||||
|
|
||||||
|
virtual ~Window();
|
||||||
|
|
||||||
|
virtual bool setWindow(int width = 800, int height = 600, bool fullscreen = false, bool vsync = true, int fsaa = 0) = 0;
|
||||||
|
virtual void getWindow(int &width, int &height, bool &fullscreen, bool &vsync, int &fsaa) = 0;
|
||||||
|
|
||||||
|
virtual bool checkWindowSize(int width, int height, bool fullscreen) = 0;
|
||||||
|
virtual WindowSize **getFullscreenSizes(int &n) = 0;
|
||||||
|
|
||||||
|
virtual int getWidth() = 0;
|
||||||
|
virtual int getHeight() = 0;
|
||||||
|
|
||||||
|
virtual bool isCreated() = 0;
|
||||||
|
|
||||||
|
virtual void setWindowTitle(std::string &title) = 0;
|
||||||
|
virtual std::string getWindowTitle() = 0;
|
||||||
|
|
||||||
|
virtual bool setIcon(love::image::ImageData *imgd) = 0;
|
||||||
|
|
||||||
|
// default no-op implementation
|
||||||
|
virtual void swapBuffers();
|
||||||
|
|
||||||
|
virtual bool hasFocus() = 0;
|
||||||
|
virtual void setMouseVisible(bool visible) = 0;
|
||||||
|
virtual bool getMouseVisible() = 0;
|
||||||
|
|
||||||
|
//virtual static Window *getSingleton() = 0;
|
||||||
|
// No virtual statics, of course, but you are supposed to implement this static.
|
||||||
|
}; // Window
|
||||||
|
} // window
|
||||||
|
} // love
|
||||||
|
|
||||||
|
#endif // LOVE_WINDOW_WINDOW_H
|
||||||
@@ -0,0 +1,303 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2006-2011 LOVE Development Team
|
||||||
|
*
|
||||||
|
* This software is provided 'as-is', without any express or implied
|
||||||
|
* warranty. In no event will the authors be held liable for any damages
|
||||||
|
* arising from the use of this software.
|
||||||
|
*
|
||||||
|
* Permission is granted to anyone to use this software for any purpose,
|
||||||
|
* including commercial applications, and to alter it and redistribute it
|
||||||
|
* freely, subject to the following restrictions:
|
||||||
|
*
|
||||||
|
* 1. The origin of this software must not be misrepresented; you must not
|
||||||
|
* claim that you wrote the original software. If you use this software
|
||||||
|
* in a product, an acknowledgment in the product documentation would be
|
||||||
|
* appreciated but is not required.
|
||||||
|
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||||
|
* misrepresented as being the original software.
|
||||||
|
* 3. This notice may not be removed or altered from any source distribution.
|
||||||
|
**/
|
||||||
|
|
||||||
|
// STL
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
// SDL
|
||||||
|
#include <SDL.h>
|
||||||
|
|
||||||
|
// OpenGL
|
||||||
|
#include <SDL/SDL_opengl.h>
|
||||||
|
|
||||||
|
// LOVE
|
||||||
|
#include <common/config.h>
|
||||||
|
#include "Window.h"
|
||||||
|
|
||||||
|
namespace love
|
||||||
|
{
|
||||||
|
namespace window
|
||||||
|
{
|
||||||
|
namespace sdl
|
||||||
|
{
|
||||||
|
Window::Window()
|
||||||
|
: windowTitle(""), created(false), mouseVisible(true)
|
||||||
|
{
|
||||||
|
// Window should be centered.
|
||||||
|
SDL_putenv(const_cast<char *>("SDL_VIDEO_CENTERED=center"));
|
||||||
|
|
||||||
|
if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0)
|
||||||
|
throw Exception(SDL_GetError());
|
||||||
|
}
|
||||||
|
|
||||||
|
Window::~Window()
|
||||||
|
{
|
||||||
|
SDL_QuitSubSystem(SDL_INIT_VIDEO);
|
||||||
|
}
|
||||||
|
|
||||||
|
Window::_currentMode::_currentMode()
|
||||||
|
: width(800), height(600), fullscreen(false), vsync(true), fsaa(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Window::setWindow(int width, int height, bool fullscreen, bool vsync, int fsaa)
|
||||||
|
{
|
||||||
|
bool mouseVisible = getMouseVisible();
|
||||||
|
|
||||||
|
// We need to restart the subsystem for two reasons:
|
||||||
|
// 1) Special case for fullscreen -> windowed. Windows XP did not
|
||||||
|
// work well with "normal" display mode change in this case.
|
||||||
|
// The application window does leave fullscreen, but the desktop
|
||||||
|
// resolution does not revert to the correct one. Restarting the
|
||||||
|
// SDL video subsystem does the trick, though.
|
||||||
|
// 2) Restart the event system (for whatever reason the event system
|
||||||
|
// started and stopped with SDL_INIT_VIDEO, see:
|
||||||
|
// http://sdl.beuc.net/sdl.wiki/Introduction_to_Events)
|
||||||
|
// because the mouse position will not be able to exceed
|
||||||
|
// the previous' video mode window size (i.e. alway
|
||||||
|
// love.mouse.getX() < 800 when switching from 800x600 to a
|
||||||
|
// higher resolution)
|
||||||
|
SDL_QuitSubSystem(SDL_INIT_VIDEO);
|
||||||
|
if (SDL_InitSubSystem(SDL_INIT_VIDEO) < 0)
|
||||||
|
{
|
||||||
|
std::cout << "Could not init SDL_VIDEO: " << SDL_GetError() << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set caption.
|
||||||
|
setWindowTitle(windowTitle);
|
||||||
|
setMouseVisible(mouseVisible);
|
||||||
|
|
||||||
|
// Set GL attributes
|
||||||
|
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
|
||||||
|
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
|
||||||
|
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
|
||||||
|
SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 8);
|
||||||
|
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
|
||||||
|
SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, (vsync ? 1 : 0));
|
||||||
|
SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 1);
|
||||||
|
|
||||||
|
// FSAA
|
||||||
|
if (fsaa > 0)
|
||||||
|
{
|
||||||
|
SDL_GL_SetAttribute( SDL_GL_MULTISAMPLEBUFFERS, 1 ) ;
|
||||||
|
SDL_GL_SetAttribute( SDL_GL_MULTISAMPLESAMPLES, fsaa ) ;
|
||||||
|
glEnable(GL_MULTISAMPLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fullscreen?
|
||||||
|
Uint32 sdlflags = fullscreen ? (SDL_OPENGL | SDL_FULLSCREEN) : SDL_OPENGL;
|
||||||
|
|
||||||
|
// Have SDL set the video mode.
|
||||||
|
if (SDL_SetVideoMode(width, height, 32, sdlflags ) == 0)
|
||||||
|
{
|
||||||
|
bool failed = true;
|
||||||
|
if (fsaa > 0)
|
||||||
|
{
|
||||||
|
// FSAA might have failed, disable it and try again
|
||||||
|
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 0);
|
||||||
|
failed = SDL_SetVideoMode(width, height, 32, sdlflags ) == 0;
|
||||||
|
if (failed)
|
||||||
|
{
|
||||||
|
// There might be no FSAA at all
|
||||||
|
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 0);
|
||||||
|
failed = SDL_SetVideoMode(width, height, 32, sdlflags ) == 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (failed)
|
||||||
|
{
|
||||||
|
std::cerr << "Could not set video mode: " << SDL_GetError() << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
created = true;
|
||||||
|
|
||||||
|
if (width == 0 || height == 0)
|
||||||
|
{
|
||||||
|
const SDL_VideoInfo* videoinfo = SDL_GetVideoInfo();
|
||||||
|
width = videoinfo->current_w;
|
||||||
|
height = videoinfo->current_h;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLint buffers;
|
||||||
|
GLint samples;
|
||||||
|
|
||||||
|
glGetIntegerv( GL_SAMPLE_BUFFERS_ARB, & buffers ) ;
|
||||||
|
glGetIntegerv( GL_SAMPLES_ARB, & samples ) ;
|
||||||
|
|
||||||
|
// Don't fail because of this, but issue a warning.
|
||||||
|
if ( (! buffers && fsaa) || (samples != fsaa))
|
||||||
|
{
|
||||||
|
std::cerr << "Warning, quality setting failed! (Result: buffers: " << buffers << ", samples: " << samples << ")" << std::endl;
|
||||||
|
fsaa = !buffers ? 0 : samples;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the actual vsync status
|
||||||
|
int real_vsync;
|
||||||
|
SDL_GL_GetAttribute(SDL_GL_SWAP_CONTROL, &real_vsync);
|
||||||
|
|
||||||
|
// Set the new display mode as the current display mode.
|
||||||
|
currentMode.width = width;
|
||||||
|
currentMode.height = height;
|
||||||
|
currentMode.fsaa = fsaa;
|
||||||
|
currentMode.fullscreen = fullscreen;
|
||||||
|
currentMode.vsync = (real_vsync != 0);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Window::getWindow(int &width, int &height, bool &fullscreen, bool &vsync, int &fsaa)
|
||||||
|
{
|
||||||
|
width = currentMode.width;
|
||||||
|
height = currentMode.height;
|
||||||
|
fullscreen = currentMode.fullscreen;
|
||||||
|
vsync = currentMode.vsync;
|
||||||
|
fsaa = currentMode.fsaa;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Window::checkWindowSize(int width, int height, bool fullscreen)
|
||||||
|
{
|
||||||
|
Uint32 sdlflags = fullscreen ? (SDL_OPENGL | SDL_FULLSCREEN) : SDL_OPENGL;
|
||||||
|
|
||||||
|
// Check if mode is supported
|
||||||
|
int bpp = SDL_VideoModeOK(width, height, 32, sdlflags);
|
||||||
|
|
||||||
|
return (bpp >= 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef Window::WindowSize WindowSize;
|
||||||
|
|
||||||
|
WindowSize **Window::getFullscreenSizes(int &n)
|
||||||
|
{
|
||||||
|
SDL_Rect ** modes = SDL_ListModes(0, SDL_OPENGL | SDL_FULLSCREEN);
|
||||||
|
|
||||||
|
if (modes == (SDL_Rect **)0 || modes == (SDL_Rect **)-1)
|
||||||
|
{
|
||||||
|
n = 0;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
n = 0;
|
||||||
|
for (int i = 0; modes[i]; i++)
|
||||||
|
n++;
|
||||||
|
|
||||||
|
WindowSize **sizes = new WindowSize*[n];
|
||||||
|
|
||||||
|
for (int i = 0; i < n; i++)
|
||||||
|
{
|
||||||
|
sizes[i] = new WindowSize;
|
||||||
|
sizes[i]->width = modes[i]->w;
|
||||||
|
sizes[i]->height = modes[i]->h;
|
||||||
|
}
|
||||||
|
return sizes;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Window::getWidth()
|
||||||
|
{
|
||||||
|
return currentMode.width;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Window::getHeight()
|
||||||
|
{
|
||||||
|
return currentMode.height;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Window::isCreated()
|
||||||
|
{
|
||||||
|
return created;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Window::setWindowTitle(std::string &title)
|
||||||
|
{
|
||||||
|
windowTitle = title;
|
||||||
|
SDL_WM_SetCaption(windowTitle.c_str(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Window::getWindowTitle()
|
||||||
|
{
|
||||||
|
// not a reference
|
||||||
|
// because we want this untouched
|
||||||
|
// const std::string& might be an option
|
||||||
|
return windowTitle;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Window::setIcon(love::image::ImageData *imgd)
|
||||||
|
{
|
||||||
|
Uint32 rmask, gmask, bmask, amask;
|
||||||
|
#ifdef LOVE_BIG_ENDIAN
|
||||||
|
rmask = 0xFF000000;
|
||||||
|
gmask = 0x00FF0000;
|
||||||
|
bmask = 0x0000FF00;
|
||||||
|
amask = 0x000000FF;
|
||||||
|
#else
|
||||||
|
rmask = 0x000000FF;
|
||||||
|
gmask = 0x0000FF00;
|
||||||
|
bmask = 0x00FF0000;
|
||||||
|
amask = 0xFF000000;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int w = static_cast<int>(imgd->getWidth());
|
||||||
|
int h = static_cast<int>(imgd->getHeight());
|
||||||
|
int pitch = static_cast<int>(imgd->getWidth() * 4);
|
||||||
|
|
||||||
|
SDL_Surface * icon = SDL_CreateRGBSurfaceFrom(imgd->getData(), w, h, 32, pitch, rmask, gmask, bmask, amask);
|
||||||
|
SDL_WM_SetIcon(icon, NULL);
|
||||||
|
SDL_FreeSurface(icon);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Window::swapBuffers()
|
||||||
|
{
|
||||||
|
SDL_GL_SwapBuffers();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Window::hasFocus()
|
||||||
|
{
|
||||||
|
return (SDL_GetAppState() & SDL_APPINPUTFOCUS) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Window::setMouseVisible(bool visible)
|
||||||
|
{
|
||||||
|
SDL_ShowCursor(visible ? SDL_ENABLE : SDL_DISABLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Window::getMouseVisible()
|
||||||
|
{
|
||||||
|
return (SDL_ShowCursor(SDL_QUERY) == SDL_ENABLE) ? true : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
love::window::Window *Window::getSingleton()
|
||||||
|
{
|
||||||
|
if (!singleton)
|
||||||
|
singleton = new Window();
|
||||||
|
else
|
||||||
|
singleton->retain();
|
||||||
|
|
||||||
|
return singleton;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *Window::getName() const
|
||||||
|
{
|
||||||
|
return "love.window.sdl";
|
||||||
|
}
|
||||||
|
} // sdl
|
||||||
|
} // window
|
||||||
|
} // love
|
||||||
@@ -0,0 +1,82 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2006-2011 LOVE Development Team
|
||||||
|
*
|
||||||
|
* This software is provided 'as-is', without any express or implied
|
||||||
|
* warranty. In no event will the authors be held liable for any damages
|
||||||
|
* arising from the use of this software.
|
||||||
|
*
|
||||||
|
* Permission is granted to anyone to use this software for any purpose,
|
||||||
|
* including commercial applications, and to alter it and redistribute it
|
||||||
|
* freely, subject to the following restrictions:
|
||||||
|
*
|
||||||
|
* 1. The origin of this software must not be misrepresented; you must not
|
||||||
|
* claim that you wrote the original software. If you use this software
|
||||||
|
* in a product, an acknowledgment in the product documentation would be
|
||||||
|
* appreciated but is not required.
|
||||||
|
* 2. Altered source versions must be plainly marked as such, and must not be
|
||||||
|
* misrepresented as being the original software.
|
||||||
|
* 3. This notice may not be removed or altered from any source distribution.
|
||||||
|
**/
|
||||||
|
|
||||||
|
#ifndef LOVE_WINDOW_SDL_WINDOW_H
|
||||||
|
#define LOVE_WINDOW_SDL_WINDOW_H
|
||||||
|
|
||||||
|
// LOVE
|
||||||
|
#include <window/Window.h>
|
||||||
|
|
||||||
|
namespace love
|
||||||
|
{
|
||||||
|
namespace window
|
||||||
|
{
|
||||||
|
namespace sdl
|
||||||
|
{
|
||||||
|
class Window : public love::window::Window
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
std::string windowTitle;
|
||||||
|
struct _currentMode{
|
||||||
|
_currentMode();
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
bool fullscreen;
|
||||||
|
bool vsync;
|
||||||
|
int fsaa;
|
||||||
|
} currentMode;
|
||||||
|
bool created;
|
||||||
|
bool mouseVisible;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Window();
|
||||||
|
~Window();
|
||||||
|
|
||||||
|
bool setWindow(int width = 800, int height = 600, bool fullscreen = false, bool vsync = true, int fsaa = 0);
|
||||||
|
void getWindow(int &width, int &height, bool &fullscreen, bool &vsync, int &fsaa);
|
||||||
|
|
||||||
|
bool checkWindowSize(int width, int height, bool fullscreen);
|
||||||
|
WindowSize **getFullscreenSizes(int &n);
|
||||||
|
|
||||||
|
int getWidth();
|
||||||
|
int getHeight();
|
||||||
|
|
||||||
|
bool isCreated();
|
||||||
|
|
||||||
|
void setWindowTitle(std::string &title);
|
||||||
|
std::string getWindowTitle();
|
||||||
|
|
||||||
|
bool setIcon(love::image::ImageData *imgd);
|
||||||
|
|
||||||
|
void swapBuffers();
|
||||||
|
|
||||||
|
bool hasFocus();
|
||||||
|
void setMouseVisible(bool visible);
|
||||||
|
bool getMouseVisible();
|
||||||
|
|
||||||
|
static love::window::Window *getSingleton();
|
||||||
|
|
||||||
|
const char *getName() const;
|
||||||
|
}; // Window
|
||||||
|
} // sdl
|
||||||
|
} // window
|
||||||
|
} // love
|
||||||
|
|
||||||
|
#endif // LOVE_WINDOW_WINDOW_H
|
||||||
Reference in New Issue
Block a user