diff options
author | vanfanel | 2015-11-11 17:56:12 +0100 |
---|---|---|
committer | vanfanel | 2015-11-11 17:56:12 +0100 |
commit | 99739a13fe844c807d3cdd87e67e207e888fd48a (patch) | |
tree | 6afbf4763326277efbf528f0bb9e587bf7a01788 /backends/platform/sdl | |
parent | 37e157a11c3fc731dfdcf6ec6b6a5a448550219b (diff) | |
parent | 7e44493fe8877a3c6a65f83b9ed84a5f59169005 (diff) | |
download | scummvm-rg350-99739a13fe844c807d3cdd87e67e207e888fd48a.tar.gz scummvm-rg350-99739a13fe844c807d3cdd87e67e207e888fd48a.tar.bz2 scummvm-rg350-99739a13fe844c807d3cdd87e67e207e888fd48a.zip |
Merge branch 'master' into dispmanx
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 | 171 | ||||
-rw-r--r-- | backends/platform/sdl/sdl.h | 11 | ||||
-rw-r--r-- | backends/platform/sdl/win32/win32-main.cpp | 7 | ||||
-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, 642 insertions, 138 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 04911f8a20..65d12dceed 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 4dc5929dab..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() { @@ -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..c6339f0c8c 100644 --- a/backends/platform/sdl/win32/win32-main.cpp +++ b/backends/platform/sdl/win32/win32-main.cpp @@ -40,8 +40,15 @@ #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 +// HACK: __argc, __argv are broken and return zero when using mingwrt 4.0+ on MinGW +#if defined(__GNUC__) && defined(__MINGW32__) && !defined(__MINGW64__) + return main(_argc, _argv); +#else return main(__argc, __argv); +#endif } int main(int argc, char *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(); }; |