diff options
| author | Paul Gilbert | 2015-05-31 14:45:10 -0400 | 
|---|---|---|
| committer | Paul Gilbert | 2015-05-31 14:45:10 -0400 | 
| commit | e5296ebf8dd09f603499b1894a33865ec71bb28f (patch) | |
| tree | d7de032efd54dfdb3159cbc778a0c9ce8cd8aa91 /backends/platform/sdl | |
| parent | 673537bad93f0b440172a0cc263ebf19cc95ffc0 (diff) | |
| parent | 141ff4d08dc24b6bb17098bd71801e2a58e6a38f (diff) | |
| download | scummvm-rg350-e5296ebf8dd09f603499b1894a33865ec71bb28f.tar.gz scummvm-rg350-e5296ebf8dd09f603499b1894a33865ec71bb28f.tar.bz2 scummvm-rg350-e5296ebf8dd09f603499b1894a33865ec71bb28f.zip  | |
Merge branch 'master' into phantom
Diffstat (limited to 'backends/platform/sdl')
| -rw-r--r-- | backends/platform/sdl/macosx/macosx.cpp | 7 | ||||
| -rw-r--r-- | backends/platform/sdl/macosx/macosx.h | 1 | ||||
| -rw-r--r-- | backends/platform/sdl/module.mk | 4 | ||||
| -rw-r--r-- | backends/platform/sdl/sdl-sys.h | 117 | ||||
| -rw-r--r-- | backends/platform/sdl/sdl-window.cpp | 223 | ||||
| -rw-r--r-- | backends/platform/sdl/sdl-window.h | 112 | ||||
| -rw-r--r-- | backends/platform/sdl/sdl.cpp | 173 | ||||
| -rw-r--r-- | backends/platform/sdl/sdl.h | 11 | ||||
| -rw-r--r-- | backends/platform/sdl/win32/win32-main.cpp | 2 | ||||
| -rw-r--r-- | backends/platform/sdl/win32/win32-window.cpp | 59 | ||||
| -rw-r--r-- | backends/platform/sdl/win32/win32-window.h | 37 | ||||
| -rw-r--r-- | backends/platform/sdl/win32/win32.cpp | 30 | ||||
| -rw-r--r-- | backends/platform/sdl/win32/win32.h | 1 | 
13 files changed, 638 insertions, 139 deletions
diff --git a/backends/platform/sdl/macosx/macosx.cpp b/backends/platform/sdl/macosx/macosx.cpp index c48076c42f..38a2d7441c 100644 --- a/backends/platform/sdl/macosx/macosx.cpp +++ b/backends/platform/sdl/macosx/macosx.cpp @@ -47,6 +47,9 @@ OSystem_MacOSX::OSystem_MacOSX()  }  void OSystem_MacOSX::init() { +	// Use an iconless window on OS X, as we use a nicer external icon there. +	_window = new SdlIconlessWindow(); +  #if defined(USE_TASKBAR)  	// Initialize taskbar manager  	_taskbarManager = new MacOSXTaskbarManager(); @@ -101,10 +104,6 @@ void OSystem_MacOSX::addSysArchivesToSearchSet(Common::SearchSet &s, int priorit  	}  } -void OSystem_MacOSX::setupIcon() { -	// Don't set icon on OS X, as we use a nicer external icon there. -} -  bool OSystem_MacOSX::hasFeature(Feature f) {  	if (f == kFeatureDisplayLogFile)  		return true; diff --git a/backends/platform/sdl/macosx/macosx.h b/backends/platform/sdl/macosx/macosx.h index 50cef60353..c8b4beaeec 100644 --- a/backends/platform/sdl/macosx/macosx.h +++ b/backends/platform/sdl/macosx/macosx.h @@ -38,7 +38,6 @@ public:  	virtual void init();  	virtual void initBackend();  	virtual void addSysArchivesToSearchSet(Common::SearchSet &s, int priority = 0); -	virtual void setupIcon();  };  #endif diff --git a/backends/platform/sdl/module.mk b/backends/platform/sdl/module.mk index a17a326889..74dd506d31 100644 --- a/backends/platform/sdl/module.mk +++ b/backends/platform/sdl/module.mk @@ -1,7 +1,8 @@  MODULE := backends/platform/sdl  MODULE_OBJS := \ -	sdl.o +	sdl.o \ +	sdl-window.o  ifdef POSIX  MODULE_OBJS += \ @@ -19,6 +20,7 @@ endif  ifdef WIN32  MODULE_OBJS += \  	win32/win32-main.o \ +	win32/win32-window.o \  	win32/win32.o  endif diff --git a/backends/platform/sdl/sdl-sys.h b/backends/platform/sdl/sdl-sys.h index eec3741ed6..67ad84efd3 100644 --- a/backends/platform/sdl/sdl-sys.h +++ b/backends/platform/sdl/sdl-sys.h @@ -52,12 +52,84 @@ typedef struct { int FAKE; } FAKE_FILE;  #define strncasecmp FAKE_strncasecmp  #endif +// HACK: SDL might include windows.h which defines its own ARRAYSIZE. +// However, we want to use the version from common/util.h. Thus, we make sure +// that we actually have this definition after including the SDL headers. +#if defined(ARRAYSIZE) && defined(COMMON_UTIL_H) +#define HACK_REDEFINE_ARRAYSIZE +#undef ARRAYSIZE +#endif + +// HACK to fix compilation with SDL 2.0 in MSVC. +// In SDL 2.0, intrin.h is now included in SDL_cpuinfo.h, which includes +// setjmp.h. SDL_cpuinfo.h is included from SDL.h and SDL_syswm.h. +// Thus, we remove the exceptions for setjmp and longjmp before these two +// includes. Unfortunately, we can't use SDL_VERSION_ATLEAST here, as SDL.h +// hasn't been included yet at this point. +#if !defined(FORBIDDEN_SYMBOL_ALLOW_ALL) && defined(_MSC_VER) +// We unset any fake definitions of setjmp/longjmp here + +#ifndef FORBIDDEN_SYMBOL_EXCEPTION_setjmp +#undef setjmp +#endif + +#ifndef FORBIDDEN_SYMBOL_EXCEPTION_longjmp +#undef longjmp +#endif + +#endif +  #if defined(__SYMBIAN32__)  #include <esdl\SDL.h>  #else  #include <SDL.h>  #endif +#include <SDL_syswm.h> + +// Restore the forbidden exceptions from the hack above +#if !defined(FORBIDDEN_SYMBOL_ALLOW_ALL) && defined(_MSC_VER) + +#ifndef FORBIDDEN_SYMBOL_EXCEPTION_setjmp +#undef setjmp +#define setjmp(a)	FORBIDDEN_SYMBOL_REPLACEMENT +#endif + +#ifndef FORBIDDEN_SYMBOL_EXCEPTION_longjmp +#undef longjmp +#define longjmp(a,b)	FORBIDDEN_SYMBOL_REPLACEMENT +#endif + +#endif + +// SDL_syswm.h will include windows.h on Win32. We need to undefine its +// ARRAYSIZE definition because we supply our own. +#undef ARRAYSIZE + +#ifdef HACK_REDEFINE_ARRAYSIZE +#undef HACK_REDEFINE_ARRAYSIZE +#define ARRAYSIZE(x) ((int)(sizeof(x) / sizeof(x[0]))) +#endif + +// In a moment of brilliance Xlib.h included by SDL_syswm.h #defines the +// following names. In a moment of mental breakdown, which occured upon +// gazing at Xlib.h, LordHoto decided to undefine them to prevent havoc. +#ifdef Status +#undef Status +#endif + +#ifdef Bool +#undef Bool +#endif + +#ifdef True +#undef True +#endif + +#ifdef False +#undef False +#endif +  // Finally forbid FILE again (if it was forbidden to start with)  #if !defined(FORBIDDEN_SYMBOL_ALLOW_ALL) && !defined(FORBIDDEN_SYMBOL_EXCEPTION_FILE)  #undef FILE @@ -74,5 +146,50 @@ typedef struct { int FAKE; } FAKE_FILE;  #define strncasecmp    FORBIDDEN_SYMBOL_REPLACEMENT  #endif +// SDL 2 has major API changes. We redefine constants which got renamed to +// ease the transition. This is sometimes dangerous because the values changed +// too! +#if SDL_VERSION_ATLEAST(2, 0, 0) + +// Type names which changed between SDL 1.2 and SDL 2. +#define SDLKey     SDL_Keycode +#define SDLMod     SDL_Keymod +#define SDL_keysym SDL_Keysym + +// Key code constants which got renamed. +#define SDLK_SCROLLOCK SDLK_SCROLLLOCK +#define SDLK_NUMLOCK   SDLK_NUMLOCKCLEAR +#define SDLK_LSUPER    SDLK_LGUI +#define SDLK_RSUPER    SDLK_RGUI +#define SDLK_PRINT     SDLK_PRINTSCREEN +#define SDLK_COMPOSE   SDLK_APPLICATION +#define SDLK_KP0       SDLK_KP_0 +#define SDLK_KP1       SDLK_KP_1 +#define SDLK_KP2       SDLK_KP_2 +#define SDLK_KP3       SDLK_KP_3 +#define SDLK_KP4       SDLK_KP_4 +#define SDLK_KP5       SDLK_KP_5 +#define SDLK_KP6       SDLK_KP_6 +#define SDLK_KP7       SDLK_KP_7 +#define SDLK_KP8       SDLK_KP_8 +#define SDLK_KP9       SDLK_KP_9 + +// Meta key constants which got renamed. +#define KMOD_META KMOD_GUI + +// SDL surface flags which got removed. +#define SDL_SRCCOLORKEY 0 +#define SDL_SRCALPHA    0 +#define SDL_FULLSCREEN  0x40000000 + +// Compatibility implementations for removed functionality. +int SDL_SetColors(SDL_Surface *surface, SDL_Color *colors, int firstcolor, int ncolors); +int SDL_SetAlpha(SDL_Surface *surface, Uint32 flag, Uint8 alpha); + +#define SDL_SetColorKey SDL_SetColorKey_replacement +int SDL_SetColorKey_replacement(SDL_Surface *surface, Uint32 flag, Uint32 key); + +#endif +  #endif diff --git a/backends/platform/sdl/sdl-window.cpp b/backends/platform/sdl/sdl-window.cpp new file mode 100644 index 0000000000..6d35f77ae0 --- /dev/null +++ b/backends/platform/sdl/sdl-window.cpp @@ -0,0 +1,223 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#define FORBIDDEN_SYMBOL_ALLOW_ALL + +#include "backends/platform/sdl/sdl-window.h" + +#include "common/textconsole.h" + +#include "icons/scummvm.xpm" + +SdlWindow::SdlWindow() +#if SDL_VERSION_ATLEAST(2, 0, 0) +	: _window(nullptr), _inputGrabState(false), _windowCaption("ScummVM") +#endif +	{ +} + +SdlWindow::~SdlWindow() { +#if SDL_VERSION_ATLEAST(2, 0, 0) +	destroyWindow(); +#endif +} + +void SdlWindow::setupIcon() { +	int x, y, w, h, ncols, nbytes, i; +	unsigned int rgba[256]; +	unsigned int *icon; + +	if (sscanf(scummvm_icon[0], "%d %d %d %d", &w, &h, &ncols, &nbytes) != 4) { +		warning("Wrong format of scummvm_icon[0] (%s)", scummvm_icon[0]); + +		return; +	} +	if ((w > 512) || (h > 512) || (ncols > 255) || (nbytes > 1)) { +		warning("Could not load the built-in icon (%d %d %d %d)", w, h, ncols, nbytes); +		return; +	} +	icon = (unsigned int*)malloc(w*h*sizeof(unsigned int)); +	if (!icon) { +		warning("Could not allocate temp storage for the built-in icon"); +		return; +	} + +	for (i = 0; i < ncols; i++) { +		unsigned char code; +		char color[32]; +		memset(color, 0, sizeof(color)); +		unsigned int col; +		if (sscanf(scummvm_icon[1 + i], "%c c %s", &code, color) != 2) { +			warning("Wrong format of scummvm_icon[%d] (%s)", 1 + i, scummvm_icon[1 + i]); +		} +		if (!strcmp(color, "None")) +			col = 0x00000000; +		else if (!strcmp(color, "black")) +			col = 0xFF000000; +		else if (color[0] == '#') { +			if (sscanf(color + 1, "%06x", &col) != 1) { +				warning("Wrong format of color (%s)", color + 1); +			} +			col |= 0xFF000000; +		} else { +			warning("Could not load the built-in icon (%d %s - %s) ", code, color, scummvm_icon[1 + i]); +			free(icon); +			return; +		} + +		rgba[code] = col; +	} +	for (y = 0; y < h; y++) { +		const char *line = scummvm_icon[1 + ncols + y]; +		for (x = 0; x < w; x++) { +			icon[x + w * y] = rgba[(int)line[x]]; +		} +	} + +	SDL_Surface *sdl_surf = SDL_CreateRGBSurfaceFrom(icon, w, h, 32, w * 4, 0xFF0000, 0x00FF00, 0x0000FF, 0xFF000000); +	if (!sdl_surf) { +		warning("SDL_CreateRGBSurfaceFrom(icon) failed"); +	} + +#if SDL_VERSION_ATLEAST(2, 0, 0) +	if (_window) { +		SDL_SetWindowIcon(_window, sdl_surf); +	} +#else +	SDL_WM_SetIcon(sdl_surf, NULL); +#endif + +	SDL_FreeSurface(sdl_surf); +	free(icon); +} + +void SdlWindow::setWindowCaption(const Common::String &caption) { +#if SDL_VERSION_ATLEAST(2, 0, 0) +	_windowCaption = caption; +	if (_window) { +		SDL_SetWindowTitle(_window, caption.c_str()); +	} +#else +	SDL_WM_SetCaption(caption.c_str(), caption.c_str()); +#endif +} + +void SdlWindow::toggleMouseGrab() { +#if SDL_VERSION_ATLEAST(2, 0, 0) +	if (_window) { +		_inputGrabState = !(SDL_GetWindowGrab(_window) == SDL_TRUE); +		SDL_SetWindowGrab(_window, _inputGrabState ? SDL_TRUE : SDL_FALSE); +	} +#else +	if (SDL_WM_GrabInput(SDL_GRAB_QUERY) == SDL_GRAB_OFF) { +		SDL_WM_GrabInput(SDL_GRAB_ON); +	} else { +		SDL_WM_GrabInput(SDL_GRAB_OFF); +	} +#endif +} + +bool SdlWindow::hasMouseFocus() const { +#if SDL_VERSION_ATLEAST(2, 0, 0) +	if (_window) { +		return (SDL_GetWindowFlags(_window) & SDL_WINDOW_MOUSE_FOCUS); +	} else { +		return false; +	} +#else +	return (SDL_GetAppState() & SDL_APPMOUSEFOCUS); +#endif +} + +void SdlWindow::warpMouseInWindow(uint x, uint y) { +#if SDL_VERSION_ATLEAST(2, 0, 0) +	if (_window) { +		SDL_WarpMouseInWindow(_window, x, y); +	} +#else +	SDL_WarpMouse(x, y); +#endif +} + +void SdlWindow::iconifyWindow() { +#if SDL_VERSION_ATLEAST(2, 0, 0) +	if (_window) { +		SDL_MinimizeWindow(_window); +	} +#else +	SDL_WM_IconifyWindow(); +#endif +} + +bool SdlWindow::getSDLWMInformation(SDL_SysWMinfo *info) const { +	SDL_VERSION(&info->version); +#if SDL_VERSION_ATLEAST(2, 0, 0) +	return SDL_GetWindowWMInfo(_window, info); +#else +	return SDL_GetWMInfo(info); +#endif +} + +#if SDL_VERSION_ATLEAST(2, 0, 0) +SDL_Surface *copySDLSurface(SDL_Surface *src) { +	const bool locked = SDL_MUSTLOCK(src) == SDL_TRUE; + +	if (locked) { +		if (SDL_LockSurface(src) != 0) { +			return nullptr; +		} +	} + +	SDL_Surface *res = SDL_CreateRGBSurfaceFrom(src->pixels, +	                       src->w, src->h, src->format->BitsPerPixel, +	                       src->pitch, src->format->Rmask, src->format->Gmask, +	                       src->format->Bmask, src->format->Amask); + +	if (locked) { +		SDL_UnlockSurface(src); +	} + +	return res; +} + +bool SdlWindow::createWindow(int width, int height, uint32 flags) { +	destroyWindow(); + +	if (_inputGrabState) { +		flags |= SDL_WINDOW_INPUT_GRABBED; +	} + +	_window = SDL_CreateWindow(_windowCaption.c_str(), SDL_WINDOWPOS_UNDEFINED, +	                           SDL_WINDOWPOS_UNDEFINED, width, height, flags); +	if (!_window) { +		return false; +	} +	setupIcon(); + +	return true; +} + +void SdlWindow::destroyWindow() { +	SDL_DestroyWindow(_window); +	_window = nullptr; +} +#endif diff --git a/backends/platform/sdl/sdl-window.h b/backends/platform/sdl/sdl-window.h new file mode 100644 index 0000000000..58b898f824 --- /dev/null +++ b/backends/platform/sdl/sdl-window.h @@ -0,0 +1,112 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef BACKENDS_PLATFORM_SDL_WINDOW_H +#define BACKENDS_PLATFORM_SDL_WINDOW_H + +#include "backends/platform/sdl/sdl-sys.h" + +#include "common/str.h" + +class SdlWindow { +public: +	SdlWindow(); +	virtual ~SdlWindow(); + +	/** +	 * Setup the window icon. +	 */ +	virtual void setupIcon(); + +	/** +	 * Change the caption of the window. +	 * +	 * @param caption New window caption in UTF-8 encoding. +	 */ +	void setWindowCaption(const Common::String &caption); + +	/** +	 * Toggle mouse grab state. This decides whether the cursor can leave the +	 * window or not. +	 */ +	void toggleMouseGrab(); + +	/** +	 * Check whether the application has mouse focus. +	 */ +	bool hasMouseFocus() const; + +	/** +	 * Warp the mouse to the specified position in window coordinates. +	 */ +	void warpMouseInWindow(uint x, uint y); + +	/** +	 * Iconifies the window. +	 */ +	void iconifyWindow(); + +	/** +	 * Query platform specific SDL window manager information. +	 * +	 * Since this is an SDL internal structure clients are responsible +	 * for accessing it in a version safe manner. +	 */ +	bool getSDLWMInformation(SDL_SysWMinfo *info) const; + +#if SDL_VERSION_ATLEAST(2, 0, 0) +public: +	/** +	 * @return The window ScummVM has setup with SDL. +	 */ +	SDL_Window *getSDLWindow() const { return _window; } + +	/** +	 * Creates a new SDL window (and destroies the old one). +	 * +	 * @param width   Width of the window. +	 * @param height  Height of the window. +	 * @param flags   SDL flags passed to SDL_CreateWindow +	 * @return true on success, false otherwise +	 */ +	bool createWindow(int width, int height, uint32 flags); + +	/** +	 * Destroies the current SDL window. +	 */ +	void destroyWindow(); + +protected: +	SDL_Window *_window; + +private: +	bool _inputGrabState; +	Common::String _windowCaption; +#endif +}; + +class SdlIconlessWindow : public SdlWindow { +public: +	virtual void setupIcon() {} +}; + +#endif diff --git a/backends/platform/sdl/sdl.cpp b/backends/platform/sdl/sdl.cpp index 41610dc0c7..6d4dede212 100644 --- a/backends/platform/sdl/sdl.cpp +++ b/backends/platform/sdl/sdl.cpp @@ -52,8 +52,6 @@  #include "graphics/cursorman.h"  #endif -#include "icons/scummvm.xpm" -  #include <time.h>	// for getTimeAndDate()  #ifdef USE_DETECTLANG @@ -77,7 +75,8 @@ OSystem_SDL::OSystem_SDL()  	_initedSDL(false),  	_logger(0),  	_mixerManager(0), -	_eventSource(0) { +	_eventSource(0), +	_window(0) {  } @@ -95,6 +94,8 @@ OSystem_SDL::~OSystem_SDL() {  	}  	delete _graphicsManager;  	_graphicsManager = 0; +	delete _window; +	_window = 0;  	delete _eventManager;  	_eventManager = 0;  	delete _eventSource; @@ -126,8 +127,10 @@ void OSystem_SDL::init() {  	// Initialize SDL  	initSDL(); +#if !SDL_VERSION_ATLEAST(2, 0, 0)  	// Enable unicode support if possible  	SDL_EnableUNICODE(1); +#endif  	// Disable OS cursor  	SDL_ShowCursor(SDL_DISABLE); @@ -147,6 +150,9 @@ void OSystem_SDL::init() {  	if (_mutexManager == 0)  		_mutexManager = new SdlMutexManager(); +	if (_window == 0) +		_window = new SdlWindow(); +  #if defined(USE_TASKBAR)  	if (_taskbarManager == 0)  		_taskbarManager = new Common::TaskbarManager(); @@ -158,10 +164,14 @@ void OSystem_SDL::initBackend() {  	// Check if backend has not been initialized  	assert(!_inited); +#if SDL_VERSION_ATLEAST(2, 0, 0) +	const char *sdlDriverName = SDL_GetCurrentVideoDriver(); +#else  	const int maxNameLen = 20;  	char sdlDriverName[maxNameLen];  	sdlDriverName[0] = '\0';  	SDL_VideoDriverName(sdlDriverName, maxNameLen); +#endif  	// Using printf rather than debug() here as debug()/logging  	// is not active by this point.  	debug(1, "Using SDL Video Driver \"%s\"", sdlDriverName); @@ -172,6 +182,13 @@ void OSystem_SDL::initBackend() {  		_eventSource = new SdlEventSource();  #ifdef USE_OPENGL +#if SDL_VERSION_ATLEAST(2, 0, 0) +	SDL_DisplayMode displayMode; +	if (!SDL_GetDesktopDisplayMode(0, &displayMode)) { +		_desktopWidth  = displayMode.w; +		_desktopHeight = displayMode.h; +	} +#else  	// Query the desktop resolution. We simply hope nothing tried to change  	// the resolution so far.  	const SDL_VideoInfo *videoInfo = SDL_GetVideoInfo(); @@ -180,6 +197,7 @@ void OSystem_SDL::initBackend() {  		_desktopHeight = videoInfo->current_h;  	}  #endif +#endif  	if (_graphicsManager == 0) {  #ifdef USE_OPENGL @@ -196,7 +214,7 @@ void OSystem_SDL::initBackend() {  			Common::String gfxMode(ConfMan.get("gfx_mode"));  			for (uint i = _firstGLMode; i < _graphicsModeIds.size(); ++i) {  				if (!scumm_stricmp(_graphicsModes[i].name, gfxMode.c_str())) { -					_graphicsManager = new OpenGLSdlGraphicsManager(_desktopWidth, _desktopHeight, _eventSource); +					_graphicsManager = new OpenGLSdlGraphicsManager(_desktopWidth, _desktopHeight, _eventSource, _window);  					_graphicsMode = i;  					break;  				} @@ -205,7 +223,7 @@ void OSystem_SDL::initBackend() {  #endif  		if (_graphicsManager == 0) { -			_graphicsManager = new SurfaceSdlGraphicsManager(_eventSource); +			_graphicsManager = new SurfaceSdlGraphicsManager(_eventSource, _window);  		}  	} @@ -238,7 +256,7 @@ void OSystem_SDL::initBackend() {  	}  	// Setup a custom program icon. -	setupIcon(); +	_window->setupIcon();  	_inited = true; @@ -314,7 +332,7 @@ void OSystem_SDL::setWindowCaption(const char *caption) {  		}  	} -	SDL_WM_SetCaption(cap.c_str(), cap.c_str()); +	_window->setWindowCaption(cap);  }  void OSystem_SDL::quit() { @@ -390,7 +408,7 @@ Common::String OSystem_SDL::getSystemLanguage() const {  #else // WIN32  	// Activating current locale settings  	const Common::String locale = setlocale(LC_ALL, ""); -  +  	// Restore default C locale to prevent issues with  	// portability of sscanf(), atof(), etc.  	// See bug #3615148 @@ -421,68 +439,6 @@ Common::String OSystem_SDL::getSystemLanguage() const {  #endif // USE_DETECTLANG  } -void OSystem_SDL::setupIcon() { -	int x, y, w, h, ncols, nbytes, i; -	unsigned int rgba[256]; -	unsigned int *icon; - -	if (sscanf(scummvm_icon[0], "%d %d %d %d", &w, &h, &ncols, &nbytes) != 4) { -		warning("Wrong format of scummvm_icon[0] (%s)", scummvm_icon[0]); - -		return; -	} -	if ((w > 512) || (h > 512) || (ncols > 255) || (nbytes > 1)) { -		warning("Could not load the built-in icon (%d %d %d %d)", w, h, ncols, nbytes); -		return; -	} -	icon = (unsigned int*)malloc(w*h*sizeof(unsigned int)); -	if (!icon) { -		warning("Could not allocate temp storage for the built-in icon"); -		return; -	} - -	for (i = 0; i < ncols; i++) { -		unsigned char code; -		char color[32]; -		memset(color, 0, sizeof(color)); -		unsigned int col; -		if (sscanf(scummvm_icon[1 + i], "%c c %s", &code, color) != 2) { -			warning("Wrong format of scummvm_icon[%d] (%s)", 1 + i, scummvm_icon[1 + i]); -		} -		if (!strcmp(color, "None")) -			col = 0x00000000; -		else if (!strcmp(color, "black")) -			col = 0xFF000000; -		else if (color[0] == '#') { -			if (sscanf(color + 1, "%06x", &col) != 1) { -				warning("Wrong format of color (%s)", color + 1); -			} -			col |= 0xFF000000; -		} else { -			warning("Could not load the built-in icon (%d %s - %s) ", code, color, scummvm_icon[1 + i]); -			free(icon); -			return; -		} - -		rgba[code] = col; -	} -	for (y = 0; y < h; y++) { -		const char *line = scummvm_icon[1 + ncols + y]; -		for (x = 0; x < w; x++) { -			icon[x + w * y] = rgba[(int)line[x]]; -		} -	} - -	SDL_Surface *sdl_surf = SDL_CreateRGBSurfaceFrom(icon, w, h, 32, w * 4, 0xFF0000, 0x00FF00, 0x0000FF, 0xFF000000); -	if (!sdl_surf) { -		warning("SDL_CreateRGBSurfaceFrom(icon) failed"); -	} -	SDL_WM_SetIcon(sdl_surf, NULL); -	SDL_FreeSurface(sdl_surf); -	free(icon); -} - -  uint32 OSystem_SDL::getMillis(bool skipRecord) {  	uint32 millis = SDL_GetTicks(); @@ -572,14 +528,8 @@ bool OSystem_SDL::setGraphicsMode(int mode) {  	//  	// This is a probably temporary workaround to fix bugs like #3368143  	// "SDL/OpenGL: Crash when switching renderer backend". -	const int screenWidth = _graphicsManager->getWidth(); -	const int screenHeight = _graphicsManager->getHeight(); -	const bool arState = _graphicsManager->getFeatureState(kFeatureAspectRatioCorrection); -	const bool fullscreen = _graphicsManager->getFeatureState(kFeatureFullscreenMode); -	const bool cursorPalette = _graphicsManager->getFeatureState(kFeatureCursorPalette); -#ifdef USE_RGB_COLOR -	const Graphics::PixelFormat pixelFormat = _graphicsManager->getScreenFormat(); -#endif +	SdlGraphicsManager *sdlGraphicsManager = dynamic_cast<SdlGraphicsManager *>(_graphicsManager); +	SdlGraphicsManager::State state = sdlGraphicsManager->getState();  	bool switchedManager = false; @@ -587,16 +537,16 @@ bool OSystem_SDL::setGraphicsMode(int mode) {  	// manager, delete and create the new mode graphics manager  	if (_graphicsMode >= _firstGLMode && mode < _firstGLMode) {  		debug(1, "switching to plain SDL graphics"); -		dynamic_cast<SdlGraphicsManager *>(_graphicsManager)->deactivateManager(); +		sdlGraphicsManager->deactivateManager();  		delete _graphicsManager; -		_graphicsManager = new SurfaceSdlGraphicsManager(_eventSource); +		_graphicsManager = sdlGraphicsManager = new SurfaceSdlGraphicsManager(_eventSource, _window);  		switchedManager = true;  	} else if (_graphicsMode < _firstGLMode && mode >= _firstGLMode) {  		debug(1, "switching to OpenGL graphics"); -		dynamic_cast<SdlGraphicsManager *>(_graphicsManager)->deactivateManager(); +		sdlGraphicsManager->deactivateManager();  		delete _graphicsManager; -		_graphicsManager = new OpenGLSdlGraphicsManager(_desktopWidth, _desktopHeight, _eventSource); +		_graphicsManager = sdlGraphicsManager = new OpenGLSdlGraphicsManager(_desktopWidth, _desktopHeight, _eventSource, _window);  		switchedManager = true;  	} @@ -604,24 +554,10 @@ bool OSystem_SDL::setGraphicsMode(int mode) {  	_graphicsMode = mode;  	if (switchedManager) { -		dynamic_cast<SdlGraphicsManager *>(_graphicsManager)->activateManager(); +		sdlGraphicsManager->activateManager(); -		_graphicsManager->beginGFXTransaction(); -#ifdef USE_RGB_COLOR -		_graphicsManager->initSize(screenWidth, screenHeight, &pixelFormat); -#else -		_graphicsManager->initSize(screenWidth, screenHeight, 0); -#endif -		_graphicsManager->setFeatureState(kFeatureAspectRatioCorrection, arState); -		_graphicsManager->setFeatureState(kFeatureFullscreenMode, fullscreen); -		_graphicsManager->setFeatureState(kFeatureCursorPalette, cursorPalette); - -		// Worst part about this right now, tell the cursor manager to -		// resetup the cursor + cursor palette if necessarily - -		// First we need to try to setup the old state on the new manager... -		if (_graphicsManager->endGFXTransaction() != kTransactionSuccess) { -			// Oh my god if this failed the client code might just explode. +		// This failing will probably have bad consequences... +		if (!sdlGraphicsManager->setState(state)) {  			return false;  		} @@ -630,7 +566,7 @@ bool OSystem_SDL::setGraphicsMode(int mode) {  		CursorMan.popCursor();  		// Next setup cursor palette if needed -		if (cursorPalette) { +		if (_graphicsManager->getFeatureState(kFeatureCursorPalette)) {  			CursorMan.pushCursorPalette(0, 0, 0);  			CursorMan.popCursorPalette();  		} @@ -660,7 +596,7 @@ void OSystem_SDL::setupGraphicsModes() {  	const OSystem::GraphicsMode *srcMode;  	int defaultMode; -	GraphicsManager *manager = new SurfaceSdlGraphicsManager(_eventSource); +	GraphicsManager *manager = new SurfaceSdlGraphicsManager(_eventSource, _window);  	srcMode = manager->getSupportedGraphicsModes();  	defaultMode = manager->getDefaultGraphicsMode();  	while (srcMode->name) { @@ -674,7 +610,7 @@ void OSystem_SDL::setupGraphicsModes() {  	assert(_defaultSDLMode != -1);  	_firstGLMode = _graphicsModes.size(); -	manager = new OpenGLSdlGraphicsManager(_desktopWidth, _desktopHeight, _eventSource); +	manager = new OpenGLSdlGraphicsManager(_desktopWidth, _desktopHeight, _eventSource, _window);  	srcMode = manager->getSupportedGraphicsModes();  	defaultMode = manager->getDefaultGraphicsMode();  	while (srcMode->name) { @@ -702,5 +638,38 @@ void OSystem_SDL::setupGraphicsModes() {  		mode++;  	}  } +#endif +#if SDL_VERSION_ATLEAST(2, 0, 0) +int SDL_SetColors(SDL_Surface *surface, SDL_Color *colors, int firstcolor, int ncolors) { +	if (surface->format->palette) { +		return !SDL_SetPaletteColors(surface->format->palette, colors, firstcolor, ncolors) ? 1 : 0; +	} else { +		return 0; +	} +} + +int SDL_SetAlpha(SDL_Surface *surface, Uint32 flag, Uint8 alpha) { +	if (SDL_SetSurfaceAlphaMod(surface, alpha)) { +		return -1; +	} + +	if (alpha == 255 || !flag) { +		if (SDL_SetSurfaceBlendMode(surface, SDL_BLENDMODE_NONE)) { +			return -1; +		} +	} else { +		if (SDL_SetSurfaceBlendMode(surface, SDL_BLENDMODE_BLEND)) { +			return -1; +		} +	} + +	return 0; +} + +#undef SDL_SetColorKey +int SDL_SetColorKey_replacement(SDL_Surface *surface, Uint32 flag, Uint32 key) { +	return SDL_SetColorKey(surface, SDL_TRUE, key) ? -1 : 0; +}  #endif + diff --git a/backends/platform/sdl/sdl.h b/backends/platform/sdl/sdl.h index 5dcc269e55..5ee56d0568 100644 --- a/backends/platform/sdl/sdl.h +++ b/backends/platform/sdl/sdl.h @@ -29,6 +29,7 @@  #include "backends/mixer/sdl/sdl-mixer.h"  #include "backends/events/sdl/sdl-events.h"  #include "backends/log/log.h" +#include "backends/platform/sdl/sdl-window.h"  #include "common/array.h" @@ -91,6 +92,11 @@ protected:  	 */  	SdlEventSource *_eventSource; +	/** +	 * The SDL output window. +	 */ +	SdlWindow *_window; +  	virtual Common::EventSource *getDefaultEventSource() { return _eventSource; }  	/** @@ -98,11 +104,6 @@ protected:  	 */  	virtual void initSDL(); -	/** -	 * Setup the window icon. -	 */ -	virtual void setupIcon(); -  	// Logging  	virtual Common::WriteStream *createLogFile() { return 0; }  	Backends::Log::Log *_logger; diff --git a/backends/platform/sdl/win32/win32-main.cpp b/backends/platform/sdl/win32/win32-main.cpp index e5b26c3ff0..c6c15c00e8 100644 --- a/backends/platform/sdl/win32/win32-main.cpp +++ b/backends/platform/sdl/win32/win32-main.cpp @@ -40,7 +40,9 @@  #include "base/main.h"  int __stdcall WinMain(HINSTANCE /*hInst*/, HINSTANCE /*hPrevInst*/,  LPSTR /*lpCmdLine*/, int /*iShowCmd*/) { +#if !SDL_VERSION_ATLEAST(2, 0, 0)  	SDL_SetModuleHandle(GetModuleHandle(NULL)); +#endif  	return main(__argc, __argv);  } diff --git a/backends/platform/sdl/win32/win32-window.cpp b/backends/platform/sdl/win32/win32-window.cpp new file mode 100644 index 0000000000..de10be6b57 --- /dev/null +++ b/backends/platform/sdl/win32/win32-window.cpp @@ -0,0 +1,59 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +// Disable symbol overrides so that we can use system headers. +#define FORBIDDEN_SYMBOL_ALLOW_ALL + +#ifdef WIN32 + +#include "backends/platform/sdl/win32/win32-window.h" + +#define WIN32_LEAN_AND_MEAN +#include <windows.h> +#undef ARRAYSIZE // winnt.h defines ARRAYSIZE, but we want our own one... + +void SdlWindow_Win32::setupIcon() { +	HMODULE handle = GetModuleHandle(NULL); +	HICON   ico    = LoadIcon(handle, MAKEINTRESOURCE(1001 /* IDI_ICON */)); +	if (ico) { +		SDL_SysWMinfo wminfo; +		if (getSDLWMInformation(&wminfo)) { +			// Replace the handle to the icon associated with the window class by our custom icon +#if SDL_VERSION_ATLEAST(2, 0, 0) +			SetClassLongPtr(wminfo.info.win.window, GCLP_HICON, (ULONG_PTR)ico); +#else +			SetClassLongPtr(wminfo.window, GCLP_HICON, (ULONG_PTR)ico); +#endif + +			// Since there wasn't any default icon, we can't use the return value from SetClassLong +			// to check for errors (it would be 0 in both cases: error or no previous value for the +			// icon handle). Instead we check for the last-error code value. +			if (GetLastError() == ERROR_SUCCESS) +				return; +		} +	} + +	// If no icon has been set, fallback to default path +	SdlWindow::setupIcon(); +} + +#endif diff --git a/backends/platform/sdl/win32/win32-window.h b/backends/platform/sdl/win32/win32-window.h new file mode 100644 index 0000000000..3bda697bc7 --- /dev/null +++ b/backends/platform/sdl/win32/win32-window.h @@ -0,0 +1,37 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef BACKENDS_PLATFORM_SDL_WIN32_WIN32_WINDOW_H +#define BACKENDS_PLATFORM_SDL_WIN32_WIN32_WINDOW_H + +#ifdef WIN32 + +#include "backends/platform/sdl/sdl-window.h" + +class SdlWindow_Win32 : public SdlWindow { +public: +	virtual void setupIcon(); +}; + +#endif + +#endif diff --git a/backends/platform/sdl/win32/win32.cpp b/backends/platform/sdl/win32/win32.cpp index 5f860ad32d..0f70c00b40 100644 --- a/backends/platform/sdl/win32/win32.cpp +++ b/backends/platform/sdl/win32/win32.cpp @@ -35,9 +35,8 @@  #include "common/error.h"  #include "common/textconsole.h" -#include <SDL_syswm.h> // For setting the icon -  #include "backends/platform/sdl/win32/win32.h" +#include "backends/platform/sdl/win32/win32-window.h"  #include "backends/saves/windows/windows-saves.h"  #include "backends/fs/windows/windows-fs-factory.h"  #include "backends/taskbar/win32/win32-taskbar.h" @@ -50,9 +49,12 @@ void OSystem_Win32::init() {  	// Initialize File System Factory  	_fsFactory = new WindowsFilesystemFactory(); +	// Create Win32 specific window +	_window = new SdlWindow_Win32(); +  #if defined(USE_TASKBAR)  	// Initialize taskbar manager -	_taskbarManager = new Win32TaskbarManager(); +	_taskbarManager = new Win32TaskbarManager(_window);  #endif  	// Invoke parent implementation of this method @@ -126,28 +128,6 @@ bool OSystem_Win32::displayLogFile() {  	return false;  } -void OSystem_Win32::setupIcon() { -	HMODULE handle = GetModuleHandle(NULL); -	HICON   ico    = LoadIcon(handle, MAKEINTRESOURCE(1001 /* IDI_ICON */)); -	if (ico) { -		SDL_SysWMinfo  wminfo; -		SDL_VERSION(&wminfo.version); -		if (SDL_GetWMInfo(&wminfo)) { -			// Replace the handle to the icon associated with the window class by our custom icon -			SetClassLongPtr(wminfo.window, GCLP_HICON, (ULONG_PTR)ico); - -			// Since there wasn't any default icon, we can't use the return value from SetClassLong -			// to check for errors (it would be 0 in both cases: error or no previous value for the -			// icon handle). Instead we check for the last-error code value. -			if (GetLastError() == ERROR_SUCCESS) -				return; -		} -	} - -	// If no icon has been set, fallback to default path -	OSystem_SDL::setupIcon(); -} -  Common::String OSystem_Win32::getDefaultConfigFileName() {  	char configFile[MAXPATHLEN]; diff --git a/backends/platform/sdl/win32/win32.h b/backends/platform/sdl/win32/win32.h index d72d80bc26..473e78ff0b 100644 --- a/backends/platform/sdl/win32/win32.h +++ b/backends/platform/sdl/win32/win32.h @@ -47,7 +47,6 @@ protected:  	 */  	Common::String _logFilePath; -	virtual void setupIcon();  	virtual Common::String getDefaultConfigFileName();  	virtual Common::WriteStream *createLogFile();  };  | 
