aboutsummaryrefslogtreecommitdiff
path: root/backends/platform/sdl
diff options
context:
space:
mode:
Diffstat (limited to 'backends/platform/sdl')
-rw-r--r--backends/platform/sdl/amigaos/amigaos-main.cpp35
-rw-r--r--backends/platform/sdl/amigaos/amigaos.mk11
-rw-r--r--backends/platform/sdl/macosx/appmenu_osx.mm25
-rw-r--r--backends/platform/sdl/macosx/macosx.cpp14
-rw-r--r--backends/platform/sdl/macosx/macosx.h6
-rw-r--r--backends/platform/sdl/module.mk4
-rw-r--r--backends/platform/sdl/posix/posix-main.cpp2
-rw-r--r--backends/platform/sdl/posix/posix.cpp150
-rw-r--r--backends/platform/sdl/posix/posix.h6
-rw-r--r--backends/platform/sdl/ps3/ps3.cpp9
-rw-r--r--backends/platform/sdl/raspberrypi/README.RASPBERRYPI77
-rw-r--r--backends/platform/sdl/sdl-sys.h147
-rw-r--r--backends/platform/sdl/sdl-window.cpp223
-rw-r--r--backends/platform/sdl/sdl-window.h112
-rw-r--r--backends/platform/sdl/sdl.cpp248
-rw-r--r--backends/platform/sdl/sdl.h20
-rw-r--r--backends/platform/sdl/win32/win32-main.cpp12
-rw-r--r--backends/platform/sdl/win32/win32-window.cpp59
-rw-r--r--backends/platform/sdl/win32/win32-window.h37
-rw-r--r--backends/platform/sdl/win32/win32.cpp41
-rw-r--r--backends/platform/sdl/win32/win32.h5
21 files changed, 1034 insertions, 209 deletions
diff --git a/backends/platform/sdl/amigaos/amigaos-main.cpp b/backends/platform/sdl/amigaos/amigaos-main.cpp
index 65da6bbf85..7bbf8d1fff 100644
--- a/backends/platform/sdl/amigaos/amigaos-main.cpp
+++ b/backends/platform/sdl/amigaos/amigaos-main.cpp
@@ -24,13 +24,44 @@
#if defined(__amigaos4__)
+#include "backends/fs/amigaos4/amigaos4-fs.h"
#include "backends/platform/sdl/amigaos/amigaos.h"
#include "backends/plugins/sdl/sdl-provider.h"
#include "base/main.h"
int main(int argc, char *argv[]) {
- // Set up a stack cookie to avoid crashes due to too few stack set by users
+ // The following will gather the application name and add the install path
+ // to a variable in AmigaOS4's ENV(ARC) system. It will be placed in AppPaths
+ // so that ScummVM can become AmiUpdate aware
+ const char *const appname = "ScummVM";
+
+ BPTR lock;
+ APTR oldwin;
+
+ // Obtain a lock to the home directory
+ if ((lock = IDOS->GetProgramDir())) {
+ TEXT progpath[2048];
+ TEXT apppath[1024] = "AppPaths";
+
+ if (IDOS->DevNameFromLock(lock,
+ progpath,
+ sizeof(progpath),
+ DN_FULLPATH)) {
+
+ // Stop any "Insert volume..." type requesters
+ oldwin = IDOS->SetProcWindow((APTR)-1);
+
+ // Finally, set the variable to the path the executable was run from
+ IDOS->AddPart( apppath, appname, 1024);
+ IDOS->SetVar( apppath, progpath, -1, GVF_GLOBAL_ONLY|GVF_SAVE_VAR );
+
+ // Turn system requesters back on
+ IDOS->SetProcWindow( oldwin );
+ }
+ }
+
+ // Set up a stack cookie to avoid crashes from a stack set too low
static const char *stack_cookie __attribute__((used)) = "$STACK: 600000";
// Create our OSystem instance
@@ -44,7 +75,7 @@ int main(int argc, char *argv[]) {
PluginManager::instance().addPluginProvider(new SDLPluginProvider());
#endif
- // Invoke the actual ScummVM main entry point:
+ // Invoke the actual ScummVM main entry point
int res = scummvm_main(argc, argv);
// Free OSystem
diff --git a/backends/platform/sdl/amigaos/amigaos.mk b/backends/platform/sdl/amigaos/amigaos.mk
index 5cec9c1588..15a2e9f93f 100644
--- a/backends/platform/sdl/amigaos/amigaos.mk
+++ b/backends/platform/sdl/amigaos/amigaos.mk
@@ -10,4 +10,15 @@ amigaosdist: $(EXECUTABLE)
ifdef DIST_FILES_ENGINEDATA
cp $(DIST_FILES_ENGINEDATA) $(AMIGAOSPATH)/extras/
endif
+ cat ${srcdir}/README | sed -f ${srcdir}/dists/amiga/convertRM.sed > README.conv
+# AmigaOS's shell is not happy with indented comments, thus don't do it.
+# AREXX seems to have problems when ${srcdir} is '.'. It will break with a
+# "Program not found" error. Therefore we copy the script to the cwd and
+# remove it again, once it has finished.
+ cp ${srcdir}/dists/amiga/RM2AG.rx .
+ rx RM2AG.rx README.conv
+ cp README.guide $(AMIGAOSPATH)
+ rm RM2AG.rx
+ rm README.conv
+ rm README.guide
cp $(DIST_FILES_DOCS) $(AMIGAOSPATH)
diff --git a/backends/platform/sdl/macosx/appmenu_osx.mm b/backends/platform/sdl/macosx/appmenu_osx.mm
index d083fb8483..feea40bc06 100644
--- a/backends/platform/sdl/macosx/appmenu_osx.mm
+++ b/backends/platform/sdl/macosx/appmenu_osx.mm
@@ -28,12 +28,22 @@
#include <Cocoa/Cocoa.h>
-// Apple removed setAppleMenu from the header files in 10.4,
-// but as the method still exists we declare it ourselves here.
+// Apple added setAppleMenu in 10.5 and removed it in 10.6.
+// But as the method still exists we declare it ourselves here.
// Yes, this works :)
@interface NSApplication(MissingFunction)
- (void)setAppleMenu:(NSMenu *)menu;
@end
+// However maybe we should conditionally use it depending on the system on which we run ScummVM (and not
+// the one on which we compile) to only do it on OS X 10.5.
+// Here is the relevant bit from the release notes for 10.6:
+// In Leopard and earlier, apps that tried to construct a menu bar without a nib would get an undesirable
+// stubby application menu that could not be removed. To work around this problem on Leopard, you can call
+// the undocumented setAppleMenu: method and pass it the application menu, like so:
+// [NSApp setAppleMenu:[[[NSApp mainMenu] itemAtIndex:0] submenu]];
+// In SnowLeopard, this workaround is unnecessary and should not be used. Under SnowLeopard, the first menu
+// is always identified as the application menu.
+
NSString *constructNSStringFromCString(const char *rawCString, CFStringEncoding stringEncoding) {
return (NSString *)CFStringCreateWithCString(NULL, rawCString, stringEncoding);
@@ -46,13 +56,14 @@ void replaceApplicationMenuItems() {
NSMenu *windowMenu;
NSMenuItem *menuItem;
- // For some reason [[NSApp mainMenu] removeAllItems] doesn't work and crashes, so we need
- // to remove the SDL generated menus one by one
- [[NSApp mainMenu] removeItemAtIndex:0]; // Remove application menu
- [[NSApp mainMenu] removeItemAtIndex:0]; // Remove "Windows" menu
+ // We cannot use [[NSApp mainMenu] removeAllItems] as removeAllItems was added in OS X 10.6
+ // So remove the SDL generated menus one by one instead.
+ while ([[NSApp mainMenu] numberOfItems] > 0) {
+ [[NSApp mainMenu] removeItemAtIndex:0];
+ }
// Create new application menu
- appleMenu = [[NSMenu alloc] initWithTitle:@""];
+ appleMenu = [[NSMenu alloc] initWithTitle:@"ScummVM"];
NSString *nsString = NULL;
diff --git a/backends/platform/sdl/macosx/macosx.cpp b/backends/platform/sdl/macosx/macosx.cpp
index c48076c42f..7652c0d833 100644
--- a/backends/platform/sdl/macosx/macosx.cpp
+++ b/backends/platform/sdl/macosx/macosx.cpp
@@ -27,9 +27,10 @@
#ifdef MACOSX
-#include "backends/platform/sdl/macosx/macosx.h"
+#include "backends/audiocd/macosx/macosx-audiocd.h"
#include "backends/mixer/doublebuffersdl/doublebuffersdl-mixer.h"
#include "backends/platform/sdl/macosx/appmenu_osx.h"
+#include "backends/platform/sdl/macosx/macosx.h"
#include "backends/updates/macosx/macosx-updates.h"
#include "backends/taskbar/macosx/macosx-taskbar.h"
@@ -47,6 +48,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 +105,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;
@@ -171,4 +171,8 @@ Common::String OSystem_MacOSX::getSystemLanguage() const {
#endif // USE_DETECTLANG
}
+AudioCDManager *OSystem_MacOSX::createAudioCDManager() {
+ return createMacOSXAudioCDManager();
+}
+
#endif
diff --git a/backends/platform/sdl/macosx/macosx.h b/backends/platform/sdl/macosx/macosx.h
index 50cef60353..6905284a5f 100644
--- a/backends/platform/sdl/macosx/macosx.h
+++ b/backends/platform/sdl/macosx/macosx.h
@@ -38,7 +38,11 @@ public:
virtual void init();
virtual void initBackend();
virtual void addSysArchivesToSearchSet(Common::SearchSet &s, int priority = 0);
- virtual void setupIcon();
+
+protected:
+ // Override createAudioCDManager() to get our Mac-specific
+ // version.
+ virtual AudioCDManager *createAudioCDManager();
};
#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/posix/posix-main.cpp b/backends/platform/sdl/posix/posix-main.cpp
index d07db11b0c..5deebb0ae3 100644
--- a/backends/platform/sdl/posix/posix-main.cpp
+++ b/backends/platform/sdl/posix/posix-main.cpp
@@ -22,7 +22,7 @@
#include "common/scummsys.h"
-#if defined(POSIX) && !defined(MACOSX) && !defined(SAMSUNGTV) && !defined(MAEMO) && !defined(WEBOS) && !defined(LINUXMOTO) && !defined(GPH_DEVICE) && !defined(GP2X) && !defined(DINGUX) && !defined(OPENPANDORA) && !defined(PLAYSTATION3)
+#if defined(POSIX) && !defined(MACOSX) && !defined(SAMSUNGTV) && !defined(MAEMO) && !defined(WEBOS) && !defined(LINUXMOTO) && !defined(GPH_DEVICE) && !defined(GP2X) && !defined(DINGUX) && !defined(OPENPANDORA) && !defined(PLAYSTATION3) && !defined(ANDROIDSDL)
#include "backends/platform/sdl/posix/posix.h"
#include "backends/plugins/sdl/sdl-provider.h"
diff --git a/backends/platform/sdl/posix/posix.cpp b/backends/platform/sdl/posix/posix.cpp
index a711c3a96b..0d5f39736a 100644
--- a/backends/platform/sdl/posix/posix.cpp
+++ b/backends/platform/sdl/posix/posix.cpp
@@ -33,14 +33,18 @@
#include "backends/platform/sdl/posix/posix.h"
#include "backends/saves/posix/posix-saves.h"
#include "backends/fs/posix/posix-fs-factory.h"
+#include "backends/fs/posix/posix-fs.h"
#include "backends/taskbar/unity/unity-taskbar.h"
+#ifdef USE_LINUXCD
+#include "backends/audiocd/linux/linux-audiocd.h"
+#endif
+
#include <errno.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <unistd.h>
-
OSystem_POSIX::OSystem_POSIX(Common::String baseConfigName)
:
_baseConfigName(baseConfigName) {
@@ -82,11 +86,54 @@ bool OSystem_POSIX::hasFeature(Feature f) {
Common::String OSystem_POSIX::getDefaultConfigFileName() {
Common::String configFile;
- // On POSIX type systems, by default we store the config file inside
- // to the HOME directory of the user.
- const char *home = getenv("HOME");
- if (home != NULL && (strlen(home) + 1 + _baseConfigName.size()) < MAXPATHLEN) {
- configFile = Common::String::format("%s/%s", home, _baseConfigName.c_str());
+ Common::String prefix;
+#ifdef MACOSX
+ prefix = getenv("HOME");
+#elif !defined(SAMSUNGTV)
+ const char *envVar;
+ // Our old configuration file path for POSIX systems was ~/.scummvmrc.
+ // If that file exists, we still use it.
+ envVar = getenv("HOME");
+ if (envVar && *envVar) {
+ configFile = envVar;
+ configFile += '/';
+ configFile += ".scummvmrc";
+
+ if (configFile.size() < MAXPATHLEN) {
+ struct stat sb;
+ if (stat(configFile.c_str(), &sb) == 0) {
+ return configFile;
+ }
+ }
+ }
+
+ // On POSIX systems we follow the XDG Base Directory Specification for
+ // where to store files. The version we based our code upon can be found
+ // over here: http://standards.freedesktop.org/basedir-spec/basedir-spec-0.8.html
+ envVar = getenv("XDG_CONFIG_HOME");
+ if (!envVar || !*envVar) {
+ envVar = getenv("HOME");
+ if (!envVar) {
+ return 0;
+ }
+
+ if (Posix::assureDirectoryExists(".config", envVar)) {
+ prefix = envVar;
+ prefix += "/.config";
+ }
+ } else {
+ prefix = envVar;
+ }
+
+ if (!prefix.empty() && Posix::assureDirectoryExists("scummvm", prefix.c_str())) {
+ prefix += "/scummvm";
+ }
+#endif
+
+ if (!prefix.empty() && (prefix.size() + 1 + _baseConfigName.size()) < MAXPATHLEN) {
+ configFile = prefix;
+ configFile += '/';
+ configFile += _baseConfigName;
} else {
configFile = _baseConfigName;
}
@@ -94,63 +141,66 @@ Common::String OSystem_POSIX::getDefaultConfigFileName() {
return configFile;
}
+void OSystem_POSIX::addSysArchivesToSearchSet(Common::SearchSet &s, int priority) {
+#ifdef DATA_PATH
+ const char *snap = getenv("SNAP");
+ if (snap) {
+ Common::String dataPath = Common::String(snap) + DATA_PATH;
+ Common::FSNode dataNode(dataPath);
+ if (dataNode.exists() && dataNode.isDirectory()) {
+ // This is the same priority which is used for the data path (below),
+ // but we insert this one first, so it will be searched first.
+ s.add(dataPath, new Common::FSDirectory(dataNode, 4), priority);
+ }
+ }
+#endif
+
+ // For now, we always add the data path, just in case SNAP doesn't make sense.
+ OSystem_SDL::addSysArchivesToSearchSet(s, priority);
+}
+
Common::WriteStream *OSystem_POSIX::createLogFile() {
// Start out by resetting _logFilePath, so that in case
// of a failure, we know that no log file is open.
_logFilePath.clear();
- const char *home = getenv("HOME");
- if (home == NULL)
+ const char *prefix = nullptr;
+ Common::String logFile;
+#ifdef MACOSX
+ prefix = getenv("HOME");
+ if (prefix == nullptr) {
return 0;
+ }
- Common::String logFile(home);
-#ifdef MACOSX
- logFile += "/Library";
-#else
- logFile += "/.scummvm";
-#endif
-#ifdef SAMSUNGTV
+ logFile = "Library/Logs";
+#elif SAMSUNGTV
+ prefix = nullptr;
logFile = "/mtd_ram";
-#endif
-
- struct stat sb;
-
- // Check whether the dir exists
- if (stat(logFile.c_str(), &sb) == -1) {
- // The dir does not exist, or stat failed for some other reason.
- if (errno != ENOENT)
+#else
+ // On POSIX systems we follow the XDG Base Directory Specification for
+ // where to store files. The version we based our code upon can be found
+ // over here: http://standards.freedesktop.org/basedir-spec/basedir-spec-0.8.html
+ prefix = getenv("XDG_CACHE_HOME");
+ if (prefix == nullptr || !*prefix) {
+ prefix = getenv("HOME");
+ if (prefix == nullptr) {
return 0;
+ }
- // If the problem was that the path pointed to nothing, try
- // to create the dir.
- if (mkdir(logFile.c_str(), 0755) != 0)
- return 0;
- } else if (!S_ISDIR(sb.st_mode)) {
- // Path is no directory. Oops
- return 0;
+ logFile = ".cache/";
}
-#ifdef MACOSX
- logFile += "/Logs";
-#else
- logFile += "/logs";
+ logFile += "scummvm/logs";
#endif
- // Check whether the dir exists
- if (stat(logFile.c_str(), &sb) == -1) {
- // The dir does not exist, or stat failed for some other reason.
- if (errno != ENOENT)
- return 0;
-
- // If the problem was that the path pointed to nothing, try
- // to create the dir.
- if (mkdir(logFile.c_str(), 0755) != 0)
- return 0;
- } else if (!S_ISDIR(sb.st_mode)) {
- // Path is no directory. Oops
+ if (!Posix::assureDirectoryExists(logFile, prefix)) {
return 0;
}
+ if (prefix) {
+ logFile = Common::String::format("%s/%s", prefix, logFile.c_str());
+ }
+
logFile += "/scummvm.log";
Common::FSNode file(logFile);
@@ -212,4 +262,12 @@ bool OSystem_POSIX::displayLogFile() {
}
+AudioCDManager *OSystem_POSIX::createAudioCDManager() {
+#ifdef USE_LINUXCD
+ return createLinuxAudioCDManager();
+#else
+ return OSystem_SDL::createAudioCDManager();
+#endif
+}
+
#endif
diff --git a/backends/platform/sdl/posix/posix.h b/backends/platform/sdl/posix/posix.h
index 01a01528cd..050463c273 100644
--- a/backends/platform/sdl/posix/posix.h
+++ b/backends/platform/sdl/posix/posix.h
@@ -28,7 +28,7 @@
class OSystem_POSIX : public OSystem_SDL {
public:
// Let the subclasses be able to change _baseConfigName in the constructor
- OSystem_POSIX(Common::String baseConfigName = ".scummvmrc");
+ OSystem_POSIX(Common::String baseConfigName = "scummvm.ini");
virtual ~OSystem_POSIX() {}
virtual bool hasFeature(Feature f);
@@ -38,6 +38,8 @@ public:
virtual void init();
virtual void initBackend();
+ virtual void addSysArchivesToSearchSet(Common::SearchSet &s, int priority = 0);
+
protected:
/**
* Base string for creating the default path and filename for the
@@ -59,6 +61,8 @@ protected:
virtual Common::String getDefaultConfigFileName();
virtual Common::WriteStream *createLogFile();
+
+ virtual AudioCDManager *createAudioCDManager();
};
#endif
diff --git a/backends/platform/sdl/ps3/ps3.cpp b/backends/platform/sdl/ps3/ps3.cpp
index f111379794..0bb8300014 100644
--- a/backends/platform/sdl/ps3/ps3.cpp
+++ b/backends/platform/sdl/ps3/ps3.cpp
@@ -31,7 +31,6 @@
#include "backends/saves/default/default-saves.h"
#include "backends/fs/ps3/ps3-fs-factory.h"
#include "backends/events/ps3sdl/ps3sdl-events.h"
-#include "backends/mixer/sdl13/sdl13-mixer.h"
#include <dirent.h>
#include <sys/stat.h>
@@ -68,14 +67,6 @@ void OSystem_PS3::initBackend() {
if (_savefileManager == 0)
_savefileManager = new DefaultSaveFileManager(PREFIX "/saves");
- // Create the mixer manager
- if (_mixer == 0) {
- _mixerManager = new Sdl13MixerManager();
-
- // Setup and start mixer
- _mixerManager->init();
- }
-
// Event source
if (_eventSource == 0)
_eventSource = new PS3SdlEventSource();
diff --git a/backends/platform/sdl/raspberrypi/README.RASPBERRYPI b/backends/platform/sdl/raspberrypi/README.RASPBERRYPI
new file mode 100644
index 0000000000..ab0e674c31
--- /dev/null
+++ b/backends/platform/sdl/raspberrypi/README.RASPBERRYPI
@@ -0,0 +1,77 @@
+ScummVM-RASPBERRYPI README
+==============================================================================
+
+Notes
+============
+
+This version of ScummVM uses SDL2 hardware accelerated graphics, be it
+plain SDL2 which in turn uses dispmanx/gles2 or by using gles1 via an
+SDL2-configured GLES1 context.
+
+Requirements
+============
+- Raspberry Pi 1 or 2 microcomputer.
+- Raspbian (Debian) installed on SD card. Other distros may be supported if
+ they include the VideoCore runtime libraries that Raspbian includes.
+-An attached keyboard and mouse, or alternatively joystick.
+
+Controls
+============
+
+The standard ScummVM keyboard and mouse controls are used as in any other
+GNU/Linux based system.
+Use the --joystick parameter if you want to use a joystick instead of the
+intended mouse for playing the games (not recommended).
+
+Installation from binaries
+==============================
+
+We have at least three methods to get the binaries into the Raspbian SD:
+
+1) Since Debian (Raspbian) includes an ssh service by default, I recommend
+keeping the SD card on the Raspberry Pi, and using scp to copy the package over
+to your home directory in the Debian filesystem.
+
+scp scummvm-rpi_<version>.zip pi@<raspberrypi_ip>:/home/pi
+
+2) If your RaspberryPi has internet access, you can simply use wget to
+download the package to your home folder:
+
+cd ~/
+wget <package_link>
+
+3) You could also connect the Raspbian SD card to your main PC and, after
+mounting it (or being automounted as it would be in most desktop GNU/Linux
+systems), copy the package file manually to your home directory.
+How to mount an SD and copy files to it is beyond the scope of this README.
+
+Once we have the package file in our home directory using one of the three
+aforementioned methods, we would need to uncompress it:
+
+unzip scummvm-rpi_<version>.zip
+
+As a result, a directory containing the scummvm along with this README will be
+created.
+We can run it by simply changing to our scummvm directory and executing the
+scummvm file.
+
+cd scummvm-rpi
+./scummvm
+
+I recommend copying the games to /home/pi/scummvm-rpi. Adding the games via the menu
+works as in any other system ScummVM runs on.
+
+Building from sources
+==============================
+
+Recommended method is building by cross-compiling on a GNU/Linux X86-based computer.
+You can find concise instructions for this on the ScummVM wiki:
+
+http://wiki.scummvm.org/index.php/Compiling_ScummVM/RPI
+
+The configure script is disabling scalers because we prefer dispmanx for that, which
+makes scalers unnecessary on a CPU limited platform like this, timestamps because most people
+doesn't have an RTC on the Raspberry Pi, and event recorder to save SD card write cycles.
+All these are automatically disabled when we crosscompile by passing "--host=raspberrypi".
+
+Enjoy!
diff --git a/backends/platform/sdl/sdl-sys.h b/backends/platform/sdl/sdl-sys.h
index eec3741ed6..551605a4b4 100644
--- a/backends/platform/sdl/sdl-sys.h
+++ b/backends/platform/sdl/sdl-sys.h
@@ -52,12 +52,99 @@ typedef struct { int FAKE; } FAKE_FILE;
#define strncasecmp FAKE_strncasecmp
#endif
+#if !defined(FORBIDDEN_SYMBOL_ALLOW_ALL) && !defined(FORBIDDEN_SYMBOL_EXCEPTION_exit)
+#undef exit
+#define exit FAKE_exit
+#endif
+
+#if !defined(FORBIDDEN_SYMBOL_ALLOW_ALL) && !defined(FORBIDDEN_SYMBOL_EXCEPTION_abort)
+#undef abort
+#define abort FAKE_abort
+#endif
+
+#if !defined(FORBIDDEN_SYMBOL_ALLOW_ALL) && !defined(FORBIDDEN_SYMBOL_EXCEPTION_system)
+#undef system
+#define system FAKE_system
+#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 occurred 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 +161,65 @@ typedef struct { int FAKE; } FAKE_FILE;
#define strncasecmp FORBIDDEN_SYMBOL_REPLACEMENT
#endif
+#if !defined(FORBIDDEN_SYMBOL_ALLOW_ALL) && !defined(FORBIDDEN_SYMBOL_EXCEPTION_exit)
+#undef exit
+#define exit(a) FORBIDDEN_SYMBOL_REPLACEMENT
+#endif
+
+#if !defined(FORBIDDEN_SYMBOL_ALLOW_ALL) && !defined(FORBIDDEN_SYMBOL_EXCEPTION_abort)
+#undef abort
+#define abort() FORBIDDEN_SYMBOL_REPLACEMENT
+#endif
+
+#if !defined(FORBIDDEN_SYMBOL_ALLOW_ALL) && !defined(FORBIDDEN_SYMBOL_EXCEPTION_system)
+#undef system
+#define system(a) 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..6862bb349f 100644
--- a/backends/platform/sdl/sdl.cpp
+++ b/backends/platform/sdl/sdl.cpp
@@ -36,8 +36,8 @@
#include "backends/saves/default/default-saves.h"
-// Audio CD support was removed with SDL 1.3
-#if SDL_VERSION_ATLEAST(1, 3, 0)
+// Audio CD support was removed with SDL 2.0
+#if SDL_VERSION_ATLEAST(2, 0, 0)
#include "backends/audiocd/default/default-audiocd.h"
#else
#include "backends/audiocd/sdl/sdl-audiocd.h"
@@ -52,8 +52,6 @@
#include "graphics/cursorman.h"
#endif
-#include "icons/scummvm.xpm"
-
#include <time.h> // for getTimeAndDate()
#ifdef USE_DETECTLANG
@@ -62,6 +60,15 @@
#endif // !WIN32
#endif
+#ifdef USE_SDL_NET
+#include <SDL/SDL_net.h>
+#endif
+
+#if SDL_VERSION_ATLEAST(2, 0, 0)
+#include <SDL2/SDL.h>
+#include <SDL2/SDL_clipboard.h>
+#endif
+
OSystem_SDL::OSystem_SDL()
:
#ifdef USE_OPENGL
@@ -75,9 +82,13 @@ OSystem_SDL::OSystem_SDL()
#endif
_inited(false),
_initedSDL(false),
+#ifdef USE_SDL_NET
+ _initedSDLnet(false),
+#endif
_logger(0),
_mixerManager(0),
- _eventSource(0) {
+ _eventSource(0),
+ _window(0) {
}
@@ -95,6 +106,8 @@ OSystem_SDL::~OSystem_SDL() {
}
delete _graphicsManager;
_graphicsManager = 0;
+ delete _window;
+ _window = 0;
delete _eventManager;
_eventManager = 0;
delete _eventSource;
@@ -119,6 +132,10 @@ OSystem_SDL::~OSystem_SDL() {
delete _logger;
_logger = 0;
+#ifdef USE_SDL_NET
+ if (_initedSDLnet) SDLNet_Quit();
+#endif
+
SDL_Quit();
}
@@ -126,8 +143,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 +166,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();
@@ -154,14 +176,25 @@ void OSystem_SDL::init() {
}
+bool OSystem_SDL::hasFeature(Feature f) {
+#if SDL_VERSION_ATLEAST(2, 0, 0)
+ if (f == kFeatureClipboardSupport) return true;
+#endif
+ return ModularBackend::hasFeature(f);
+}
+
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 +205,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 +220,7 @@ void OSystem_SDL::initBackend() {
_desktopHeight = videoInfo->current_h;
}
#endif
+#endif
if (_graphicsManager == 0) {
#ifdef USE_OPENGL
@@ -196,7 +237,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 +246,7 @@ void OSystem_SDL::initBackend() {
#endif
if (_graphicsManager == 0) {
- _graphicsManager = new SurfaceSdlGraphicsManager(_eventSource);
+ _graphicsManager = new SurfaceSdlGraphicsManager(_eventSource, _window);
}
}
@@ -227,18 +268,10 @@ void OSystem_SDL::initBackend() {
_timerManager = new SdlTimerManager();
#endif
- if (_audiocdManager == 0) {
- // Audio CD support was removed with SDL 1.3
-#if SDL_VERSION_ATLEAST(1, 3, 0)
- _audiocdManager = new DefaultAudioCDManager();
-#else
- _audiocdManager = new SdlAudioCDManager();
-#endif
-
- }
+ _audiocdManager = createAudioCDManager();
// Setup a custom program icon.
- setupIcon();
+ _window->setupIcon();
_inited = true;
@@ -284,6 +317,17 @@ void OSystem_SDL::initSDL() {
_initedSDL = true;
}
+
+#ifdef USE_SDL_NET
+ // Check if SDL_net has not been initialized
+ if (!_initedSDLnet) {
+ // Initialize SDL_net
+ if (SDLNet_Init() == -1)
+ error("Could not initialize SDL_net: %s", SDLNet_GetError());
+
+ _initedSDLnet = true;
+ }
+#endif
}
void OSystem_SDL::addSysArchivesToSearchSet(Common::SearchSet &s, int priority) {
@@ -314,7 +358,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 +465,26 @@ 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;
- }
+bool OSystem_SDL::hasTextInClipboard() {
+#if SDL_VERSION_ATLEAST(2, 0, 0)
+ return SDL_HasClipboardText() == SDL_TRUE;
+#else
+ return false;
+#endif
+}
- 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]];
- }
- }
+Common::String OSystem_SDL::getTextFromClipboard() {
+ if (!hasTextInClipboard()) return "";
- 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);
+#if SDL_VERSION_ATLEAST(2, 0, 0)
+ char *text = SDL_GetClipboardText();
+ if (text == nullptr) return "";
+ return text;
+#else
+ return "";
+#endif
}
-
uint32 OSystem_SDL::getMillis(bool skipRecord) {
uint32 millis = SDL_GetTicks();
@@ -535,6 +537,23 @@ Common::TimerManager *OSystem_SDL::getTimerManager() {
#endif
}
+AudioCDManager *OSystem_SDL::createAudioCDManager() {
+ // Audio CD support was removed with SDL 2.0
+#if SDL_VERSION_ATLEAST(2, 0, 0)
+ return new DefaultAudioCDManager();
+#else
+ return new SdlAudioCDManager();
+#endif
+}
+
+Common::SaveFileManager *OSystem_SDL::getSavefileManager() {
+#ifdef ENABLE_EVENTRECORDER
+ return g_eventRec.getSaveManager(_savefileManager);
+#else
+ return _savefileManager;
+#endif
+}
+
#ifdef USE_OPENGL
const OSystem::GraphicsMode *OSystem_SDL::getSupportedGraphicsModes() const {
@@ -572,14 +591,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 +600,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 +617,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 +629,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 +659,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 +673,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 +701,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..17b4e9b001 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"
@@ -54,6 +55,8 @@ public:
*/
virtual SdlMixerManager *getMixerManager();
+ virtual bool hasFeature(Feature f);
+
// Override functions from ModularBackend and OSystem
virtual void initBackend();
#if defined(USE_TASKBAR)
@@ -68,6 +71,10 @@ public:
virtual Common::String getSystemLanguage() const;
+ // Clipboard
+ virtual bool hasTextInClipboard();
+ virtual Common::String getTextFromClipboard();
+
virtual void setWindowCaption(const char *caption);
virtual void addSysArchivesToSearchSet(Common::SearchSet &s, int priority = 0);
virtual uint32 getMillis(bool skipRecord = false);
@@ -75,10 +82,14 @@ public:
virtual void getTimeAndDate(TimeDate &td) const;
virtual Audio::Mixer *getMixer();
virtual Common::TimerManager *getTimerManager();
+ virtual Common::SaveFileManager *getSavefileManager();
protected:
bool _inited;
bool _initedSDL;
+#ifdef USE_SDL_NET
+ bool _initedSDLnet;
+#endif
/**
* Mixer manager that configures and setups SDL for
@@ -91,6 +102,11 @@ protected:
*/
SdlEventSource *_eventSource;
+ /**
+ * The SDL output window.
+ */
+ SdlWindow *_window;
+
virtual Common::EventSource *getDefaultEventSource() { return _eventSource; }
/**
@@ -99,9 +115,9 @@ protected:
virtual void initSDL();
/**
- * Setup the window icon.
+ * Create the audio CD manager
*/
- virtual void setupIcon();
+ virtual AudioCDManager *createAudioCDManager();
// Logging
virtual Common::WriteStream *createLogFile() { return 0; }
diff --git a/backends/platform/sdl/win32/win32-main.cpp b/backends/platform/sdl/win32/win32-main.cpp
index e5b26c3ff0..4864347d81 100644
--- a/backends/platform/sdl/win32/win32-main.cpp
+++ b/backends/platform/sdl/win32/win32-main.cpp
@@ -40,8 +40,20 @@
#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
+// HACK: MinGW-w64 based toolchains neither feature _argc nor _argv. The 32 bit
+// incarnation only defines __MINGW32__. This leads to build breakage due to
+// missing declarations. Luckily MinGW-w64 based toolchains define
+// __MINGW64_VERSION_foo macros inside _mingw.h, which is included from all
+// system headers. Thus we abuse that to detect them.
+#if defined(__GNUC__) && defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR)
+ 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..fcc0849624 100644
--- a/backends/platform/sdl/win32/win32.cpp
+++ b/backends/platform/sdl/win32/win32.cpp
@@ -35,12 +35,13 @@
#include "common/error.h"
#include "common/textconsole.h"
-#include <SDL_syswm.h> // For setting the icon
-
+#include "backends/audiocd/win32/win32-audiocd.h"
#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"
+#include "backends/updates/win32/win32-updates.h"
#include "common/memstream.h"
@@ -50,9 +51,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
@@ -79,6 +83,11 @@ void OSystem_Win32::initBackend() {
if (_savefileManager == 0)
_savefileManager = new WindowsSaveFileManager();
+#if defined(USE_SPARKLE)
+ // Initialize updates manager
+ _updateManager = new Win32UpdateManager();
+#endif
+
// Invoke parent implementation of this method
OSystem_SDL::initBackend();
}
@@ -126,28 +135,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];
@@ -338,4 +325,8 @@ void OSystem_Win32::addSysArchivesToSearchSet(Common::SearchSet &s, int priority
OSystem_SDL::addSysArchivesToSearchSet(s, priority);
}
+AudioCDManager *OSystem_Win32::createAudioCDManager() {
+ return createWin32AudioCDManager();
+}
+
#endif
diff --git a/backends/platform/sdl/win32/win32.h b/backends/platform/sdl/win32/win32.h
index d72d80bc26..ca0843e834 100644
--- a/backends/platform/sdl/win32/win32.h
+++ b/backends/platform/sdl/win32/win32.h
@@ -47,9 +47,12 @@ protected:
*/
Common::String _logFilePath;
- virtual void setupIcon();
virtual Common::String getDefaultConfigFileName();
virtual Common::WriteStream *createLogFile();
+
+ // Override createAudioCDManager() to get our Mac-specific
+ // version.
+ virtual AudioCDManager *createAudioCDManager();
};
#endif