aboutsummaryrefslogtreecommitdiff
path: root/engines/sword25/kernel
diff options
context:
space:
mode:
authorJohannes Schickel2010-10-13 03:57:44 +0000
committerJohannes Schickel2010-10-13 03:57:44 +0000
commit75e8452b6e6a2bf4fb2f588aa00b428a60d873b5 (patch)
treef29541d55309487a94bd1d38e8b53bb3dde9aec6 /engines/sword25/kernel
parent48ee83b88957dab86bc763e9ef21a70179fa8679 (diff)
parente9f50882ea5b6beeefa994040be9d3bab6a1f107 (diff)
downloadscummvm-rg350-75e8452b6e6a2bf4fb2f588aa00b428a60d873b5.tar.gz
scummvm-rg350-75e8452b6e6a2bf4fb2f588aa00b428a60d873b5.tar.bz2
scummvm-rg350-75e8452b6e6a2bf4fb2f588aa00b428a60d873b5.zip
OPENGL: Merged from trunk, from rev 52105 to 53396.
This includes an rather hacky attempt to merge all the recent gp2x backend changes into the branch. I suppose the gp2x backend and probably all new backends, i.e. gph, dingux etc., might not compile anymore. Since I have no way of testing those it would be nice if porters could look into getting those up to speed in this branch. svn-id: r53399
Diffstat (limited to 'engines/sword25/kernel')
-rw-r--r--engines/sword25/kernel/bs_stdint.h54
-rw-r--r--engines/sword25/kernel/callbackregistry.cpp131
-rw-r--r--engines/sword25/kernel/callbackregistry.h93
-rw-r--r--engines/sword25/kernel/common.h60
-rw-r--r--engines/sword25/kernel/filesystemutil.cpp152
-rw-r--r--engines/sword25/kernel/filesystemutil.h114
-rw-r--r--engines/sword25/kernel/inputpersistenceblock.cpp182
-rw-r--r--engines/sword25/kernel/inputpersistenceblock.h90
-rw-r--r--engines/sword25/kernel/kernel.cpp454
-rw-r--r--engines/sword25/kernel/kernel.h370
-rw-r--r--engines/sword25/kernel/kernel_script.cpp739
-rw-r--r--engines/sword25/kernel/log.cpp214
-rw-r--r--engines/sword25/kernel/log.h147
-rw-r--r--engines/sword25/kernel/objectregistry.h175
-rw-r--r--engines/sword25/kernel/outputpersistenceblock.cpp131
-rw-r--r--engines/sword25/kernel/outputpersistenceblock.h78
-rw-r--r--engines/sword25/kernel/persistable.h53
-rw-r--r--engines/sword25/kernel/persistenceblock.h133
-rw-r--r--engines/sword25/kernel/persistenceservice.cpp465
-rw-r--r--engines/sword25/kernel/persistenceservice.h84
-rw-r--r--engines/sword25/kernel/resmanager.cpp336
-rw-r--r--engines/sword25/kernel/resmanager.h193
-rw-r--r--engines/sword25/kernel/resource.cpp60
-rw-r--r--engines/sword25/kernel/resource.h118
-rw-r--r--engines/sword25/kernel/resservice.h75
-rw-r--r--engines/sword25/kernel/scummvmwindow.cpp297
-rw-r--r--engines/sword25/kernel/scummvmwindow.h85
-rw-r--r--engines/sword25/kernel/service.h75
-rw-r--r--engines/sword25/kernel/service_ids.h80
-rw-r--r--engines/sword25/kernel/string.h111
-rw-r--r--engines/sword25/kernel/window.cpp69
-rw-r--r--engines/sword25/kernel/window.h177
32 files changed, 5595 insertions, 0 deletions
diff --git a/engines/sword25/kernel/bs_stdint.h b/engines/sword25/kernel/bs_stdint.h
new file mode 100644
index 0000000000..c1970bff3e
--- /dev/null
+++ b/engines/sword25/kernel/bs_stdint.h
@@ -0,0 +1,54 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+/*
+ * This code is based on Broken Sword 2.5 engine
+ *
+ * Copyright (c) Malte Thiesen, Daniel Queteschiner and Michael Elsdoerfer
+ *
+ * Licensed under GNU GPL v2
+ *
+ */
+
+// TODO: Properly replace all game occurances that use these types with proper ScummVM types, and remove this file
+
+#ifndef SWORD25_STDINT_H
+#define SWORD25_STDINT_H
+
+#include "common/scummsys.h"
+
+typedef uint8 uint8_t;
+typedef uint16 uint16_t;
+typedef uint32 uint32_t;
+typedef int8 int8_t;
+typedef int16 int16_t;
+typedef int32 int32_t;
+
+typedef unsigned long long uint64_t;
+typedef signed long long int64_t;
+typedef unsigned long long uint64;
+typedef signed long long int64;
+
+#endif
diff --git a/engines/sword25/kernel/callbackregistry.cpp b/engines/sword25/kernel/callbackregistry.cpp
new file mode 100644
index 0000000000..32b2597334
--- /dev/null
+++ b/engines/sword25/kernel/callbackregistry.cpp
@@ -0,0 +1,131 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+/*
+ * This code is based on Broken Sword 2.5 engine
+ *
+ * Copyright (c) Malte Thiesen, Daniel Queteschiner and Michael Elsdoerfer
+ *
+ * Licensed under GNU GPL v2
+ *
+ */
+
+// Alle Callbackfunktionen die von Objekten gerufen werden, die persistiert werden können, müssen hier registriert werden.
+// Beim Speichern wird statt des Pointers der Bezeichner gespeichert. Beim Laden wird der Bezeichner wieder in einen Pointer umgewandelt.
+// Diese Klasse führt also so etwas ähnliches wie eine Importtabelle für Callback-Funktionen.
+//
+// Dieses Vorgehen hat mehrere Vorteile:
+// 1. Die Speicherstände sind plattformunabhängig. Es werden keine Pointer auf Funktionen gespeichert, sondern nur Namen von Callbackfunktionen.
+// Diese können beim Laden über diese Klasse in systemabhängige Pointer umgewandelt werden.
+// 2. Speicherstände können auch nach einem Engineupdate weiterhin benutzt werden. Beim Erstellen einer neun Binary verschieben sich häufig die
+// Funktionen. Eine Callbackfunktion könnte sich also nach einem Update an einer anderen Stelle befinden als davor. Wenn im Spielstand der
+// Pointer gespeichert war, stürtzt das Programm beim Äufrufen dieser Callbackfunktion ab. Durch das Auflösungverfahren wird beim Laden der
+// Callbackbezeichner in den neuen Funktionspointer umgewandelt und der Aufruf kann erfolgen.
+
+// -----------------------------------------------------------------------------
+// Logging
+// -----------------------------------------------------------------------------
+
+#define BS_LOG_PREFIX "CALLBACKREGISTRY"
+
+// -----------------------------------------------------------------------------
+// Includes
+// -----------------------------------------------------------------------------
+
+#include "sword25/kernel/callbackregistry.h"
+
+namespace Sword25 {
+
+// -----------------------------------------------------------------------------
+
+bool CallbackRegistry::registerCallbackFunction(const Common::String &name, CallbackPtr ptr) {
+ if (name == "") {
+ BS_LOG_ERRORLN("The empty string is not allowed as a callback function name.");
+ return false;
+ }
+
+ if (findPtrByName(name) != 0) {
+ BS_LOG_ERRORLN("There is already a callback function with the name \"%s\".", name.c_str());
+ return false;
+ }
+ if (findNameByPtr(ptr) != "") {
+ BS_LOG_ERRORLN("There is already a callback function with the pointer 0x%x.", ptr);
+ return false;
+ }
+
+ storeCallbackFunction(name, ptr);
+
+ return true;
+}
+
+// -----------------------------------------------------------------------------
+
+CallbackPtr CallbackRegistry::resolveCallbackFunction(const Common::String &name) const {
+ CallbackPtr result = findPtrByName(name);
+
+ if (!result) {
+ BS_LOG_ERRORLN("There is no callback function with the name \"%s\".", name.c_str());
+ }
+
+ return result;
+}
+
+// -----------------------------------------------------------------------------
+
+Common::String CallbackRegistry::resolveCallbackPointer(CallbackPtr ptr) const {
+ const Common::String &result = findNameByPtr(ptr);
+
+ if (result == "") {
+ BS_LOG_ERRORLN("There is no callback function with the pointer 0x%x.", ptr);
+ }
+
+ return result;
+}
+
+// -----------------------------------------------------------------------------
+
+CallbackPtr CallbackRegistry::findPtrByName(const Common::String &name) const {
+ // Eintrag in der Map finden und den Pointer zurückgeben.
+ NameToPtrMap::const_iterator it = _nameToPtrMap.find(name);
+ return it == _nameToPtrMap.end() ? 0 : it->_value;
+}
+
+// -----------------------------------------------------------------------------
+
+Common::String CallbackRegistry::findNameByPtr(CallbackPtr ptr) const {
+ // Eintrag in der Map finden und den Namen zurückgeben.
+ PtrToNameMap::const_iterator it = _ptrToNameMap.find(ptr);
+ return it == _ptrToNameMap.end() ? "" : it->_value;
+}
+
+// -----------------------------------------------------------------------------
+
+void CallbackRegistry::storeCallbackFunction(const Common::String &name, CallbackPtr ptr) {
+ // Callback-Funktion in beide Maps eintragen.
+ _nameToPtrMap[name] = ptr;
+ _ptrToNameMap[ptr] = name;
+}
+
+} // End of namespace Sword25
diff --git a/engines/sword25/kernel/callbackregistry.h b/engines/sword25/kernel/callbackregistry.h
new file mode 100644
index 0000000000..c5076d22f5
--- /dev/null
+++ b/engines/sword25/kernel/callbackregistry.h
@@ -0,0 +1,93 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+/*
+ * This code is based on Broken Sword 2.5 engine
+ *
+ * Copyright (c) Malte Thiesen, Daniel Queteschiner and Michael Elsdoerfer
+ *
+ * Licensed under GNU GPL v2
+ *
+ */
+
+#ifndef SWORD25_CALLBACK_REGISTRY_H
+#define SWORD25_CALLBACK_REGISTRY_H
+
+// -----------------------------------------------------------------------------
+// Includes
+// -----------------------------------------------------------------------------
+
+#include "common/scummsys.h"
+#include "common/str.h"
+#include "common/hash-str.h"
+#include "common/hashmap.h"
+#include "sword25/kernel/bs_stdint.h"
+#include "sword25/kernel/common.h"
+
+namespace Sword25 {
+
+// -----------------------------------------------------------------------------
+// Klassendeklaration
+// -----------------------------------------------------------------------------
+
+typedef void (*CallbackPtr)(int command);
+
+class CallbackRegistry {
+public:
+ static CallbackRegistry &getInstance() {
+ static CallbackRegistry _instance;
+ return _instance;
+ }
+
+ bool registerCallbackFunction(const Common::String &name, CallbackPtr ptr);
+ CallbackPtr resolveCallbackFunction(const Common::String &name) const;
+ Common::String resolveCallbackPointer(CallbackPtr ptr) const;
+
+private:
+ typedef Common::HashMap<Common::String, CallbackPtr, Common::CaseSensitiveString_Hash, Common::CaseSensitiveString_EqualTo> NameToPtrMap;
+ NameToPtrMap _nameToPtrMap;
+
+ struct CallbackPtr_EqualTo {
+ bool operator()(CallbackPtr x, CallbackPtr y) const {
+ return x == y;
+ }
+ };
+ struct CallbackPtr_Hash {
+ uint operator()(CallbackPtr x) const {
+ return static_cast<uint>((int64)x % ((int64)1 << sizeof(uint)));
+ }
+ };
+
+ typedef Common::HashMap<CallbackPtr, Common::String, CallbackPtr_Hash, CallbackPtr_EqualTo> PtrToNameMap;
+ PtrToNameMap _ptrToNameMap;
+
+ CallbackPtr findPtrByName(const Common::String &name) const;
+ Common::String findNameByPtr(CallbackPtr ptr) const;
+ void storeCallbackFunction(const Common::String &name, CallbackPtr ptr);
+};
+
+} // End of namespace Sword25
+
+#endif
diff --git a/engines/sword25/kernel/common.h b/engines/sword25/kernel/common.h
new file mode 100644
index 0000000000..7b11fe901f
--- /dev/null
+++ b/engines/sword25/kernel/common.h
@@ -0,0 +1,60 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+/*
+ * This code is based on Broken Sword 2.5 engine
+ *
+ * Copyright (c) Malte Thiesen, Daniel Queteschiner and Michael Elsdoerfer
+ *
+ * Licensed under GNU GPL v2
+ *
+ */
+
+/*
+ * common.h
+ * -----------
+ * This file contains functions or macros that are used across the entire project.
+ * It is therefore extremely important that this header file be referenced in all
+ * the other header files in the project.
+ *
+ * Autor: Malte Thiesen
+ */
+
+#ifndef SWORD25_COMMON_H
+#define SWORD25_COMMON_H
+
+// Global constants
+#define DEBUG
+
+#define BS_ACTIVATE_LOGGING // When defined, logging is activated
+
+// Engine Includes
+#include "sword25/kernel/log.h"
+
+#include "common/debug.h"
+
+#define BS_ASSERT(EXP) assert(EXP)
+
+#endif
diff --git a/engines/sword25/kernel/filesystemutil.cpp b/engines/sword25/kernel/filesystemutil.cpp
new file mode 100644
index 0000000000..853e6b247f
--- /dev/null
+++ b/engines/sword25/kernel/filesystemutil.cpp
@@ -0,0 +1,152 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+/*
+ * This code is based on Broken Sword 2.5 engine
+ *
+ * Copyright (c) Malte Thiesen, Daniel Queteschiner and Michael Elsdoerfer
+ *
+ * Licensed under GNU GPL v2
+ *
+ */
+
+// -----------------------------------------------------------------------------
+// Includes
+// -----------------------------------------------------------------------------
+
+#include "common/config-manager.h"
+#include "common/fs.h"
+#include "common/savefile.h"
+#include "common/system.h"
+#include "sword25/kernel/filesystemutil.h"
+#include "sword25/kernel/persistenceservice.h"
+
+namespace Sword25 {
+
+#define BS_LOG_PREFIX "FILESYSTEMUTIL"
+
+// -----------------------------------------------------------------------------
+// Constants and utility functions
+// -----------------------------------------------------------------------------
+
+Common::String GetAbsolutePath(const Common::String &Path) {
+ Common::FSNode node(Path);
+
+ if (!node.exists()) {
+ // An error has occurred finding the node
+ // We can do nothing at this pointer than return an empty string
+ BS_LOG_ERRORLN("A call to GetAbsolutePath failed.");
+ return "";
+ }
+
+ // Return the result
+ return node.getPath();
+}
+
+// -----------------------------------------------------------------------------
+// Class definitions
+// -----------------------------------------------------------------------------
+
+class BS_FileSystemUtilScummVM : public FileSystemUtil {
+public:
+ virtual Common::String GetUserdataDirectory() {
+ Common::String path = ConfMan.get("savepath");
+
+ if (path.empty()) {
+ error("No save path has been defined");
+ return "";
+ }
+
+ // Return the path
+ return path;
+ }
+
+ virtual Common::String GetPathSeparator() {
+ return Common::String("/");
+ }
+
+ virtual int64 GetFileSize(const Common::String &Filename) {
+ Common::FSNode node(Filename);
+
+ // If the file does not exist, return -1 as a result
+ if (!node.exists())
+ return -1;
+
+ // Get the size of the file and return it
+ Common::File f;
+ f.open(node);
+ uint32 size = f.size();
+ f.close();
+
+ return size;
+ }
+
+ virtual TimeDate GetFileTime(const Common::String &Filename) {
+ // TODO: There isn't any way in ScummVM to get a file's modified date/time. We will need to check
+ // what code makes use of it. If it's only the save game code, for example, we may be able to
+ // encode the date/time inside the savegame files themselves.
+ TimeDate result;
+ g_system->getTimeAndDate(result);
+ return result;
+ }
+
+ virtual bool FileExists(const Common::String &Filename) {
+ Common::File f;
+ if (f.exists(Filename))
+ return true;
+
+ // Check if the file exists in the save folder
+ Common::FSNode folder(PersistenceService::GetSavegameDirectory());
+ Common::FSNode fileNode = folder.getChild(FileSystemUtil::GetInstance().GetPathFilename(Filename));
+ return fileNode.exists();
+ }
+
+ virtual bool CreateDirectory(const Common::String &DirectoryName) {
+ // ScummVM doesn't support creating folders, so this is only a stub
+ BS_LOG_ERRORLN("CreateDirectory method called");
+ return false;
+ }
+
+ virtual Common::String GetPathFilename(const Common::String &Path) {
+ for (int i = Path.size() - 1; i >= 0; --i) {
+ if ((Path[i] == '/') || (Path[i] == '\\')) {
+ return Common::String(&Path.c_str()[i + 1]);
+ }
+ }
+
+ return Path;
+ }
+};
+
+// -----------------------------------------------------------------------------
+// Singleton method of parent class
+// -----------------------------------------------------------------------------
+
+FileSystemUtil &FileSystemUtil::GetInstance() {
+ static BS_FileSystemUtilScummVM Instance;
+ return Instance;
+}
+
+} // End of namespace Sword25
diff --git a/engines/sword25/kernel/filesystemutil.h b/engines/sword25/kernel/filesystemutil.h
new file mode 100644
index 0000000000..43ce7c908e
--- /dev/null
+++ b/engines/sword25/kernel/filesystemutil.h
@@ -0,0 +1,114 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+/*
+ * This code is based on Broken Sword 2.5 engine
+ *
+ * Copyright (c) Malte Thiesen, Daniel Queteschiner and Michael Elsdoerfer
+ *
+ * Licensed under GNU GPL v2
+ *
+ */
+
+/*
+ *
+ * The class BS_FileSystemUtil represents a wrapper for file system specific
+ * operations that do not have equivalents in the C/C++ libraries.
+ *
+ * Each supported platform must implement this interface, and the method
+ * BS_FileSystemUtil Singleton::getInstance()
+ */
+
+#ifndef SWORD25_FILESYSTEMUTIL_H
+#define SWORD25_FILESYSTEMUTIL_H
+
+// -----------------------------------------------------------------------------
+// Includes
+// -----------------------------------------------------------------------------
+
+#include "common/system.h"
+#include "common/str.h"
+#include "common/str-array.h"
+#include "sword25/kernel/common.h"
+#include "sword25/kernel/bs_stdint.h"
+
+namespace Sword25 {
+
+// -----------------------------------------------------------------------------
+// Class definitions
+// -----------------------------------------------------------------------------
+
+class FileSystemUtil {
+public:
+ static FileSystemUtil &GetInstance();
+ virtual ~FileSystemUtil() {};
+
+ /**
+ * This function returns the name of the directory in which all user data is to be stored.
+ *
+ * These are for example Screenshots, game saves, configuration files, log files, ...
+ * @return Returns the name of the directory for user data.
+ */
+ virtual Common::String GetUserdataDirectory() = 0;
+ /**
+ * @return Returns the path seperator
+ */
+ virtual Common::String GetPathSeparator() = 0;
+ /**
+ * @param Filename The path to a file.
+ * @return Returns the size of the specified file. If the size could not be
+ * determined, or the file does not exist, returns -1
+ */
+ virtual int64 GetFileSize(const Common::String &Filename) = 0;
+ /**
+ * @param Filename The path to a file.
+ * @return Returns the timestamp of the specified file.
+ */
+ virtual TimeDate GetFileTime(const Common::String &Filename) = 0;
+ /**
+ * @param Filename The path to a file.
+ * @return Returns true if the file exists.
+ */
+ virtual bool FileExists(const Common::String &Filename) = 0;
+ /**
+ * This function creates a directory
+ *
+ * If the parameter is "\b\c\d\e" is passed, and "\b\c" already exists, then folder 'd'
+ * will be created, and subdirectory 'e' under it.
+ * @param DirectoryName The name of the directory to be created
+ * @return Returns true if the folder(s) could be created, otherwise false.
+ */
+ virtual bool CreateDirectory(const Common::String &DirectoryName) = 0;
+ /**
+ * Gets the filename from a path and filename
+ * @param Filename The full path and filename
+ * @return Returns just the filename
+ */
+ virtual Common::String GetPathFilename(const Common::String &Path) = 0;
+};
+
+} // End of namespace Sword25
+
+#endif
diff --git a/engines/sword25/kernel/inputpersistenceblock.cpp b/engines/sword25/kernel/inputpersistenceblock.cpp
new file mode 100644
index 0000000000..b51b1037a7
--- /dev/null
+++ b/engines/sword25/kernel/inputpersistenceblock.cpp
@@ -0,0 +1,182 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+/*
+ * This code is based on Broken Sword 2.5 engine
+ *
+ * Copyright (c) Malte Thiesen, Daniel Queteschiner and Michael Elsdoerfer
+ *
+ * Licensed under GNU GPL v2
+ *
+ */
+
+#define BS_LOG_PREFIX "INPUTPERSISTENCEBLOCK"
+
+// -----------------------------------------------------------------------------
+// Includes
+// -----------------------------------------------------------------------------
+
+#include "sword25/kernel/inputpersistenceblock.h"
+
+namespace Sword25 {
+
+// -----------------------------------------------------------------------------
+// Constructor / Destructor
+// -----------------------------------------------------------------------------
+
+InputPersistenceBlock::InputPersistenceBlock(const void *Data, uint DataLength) :
+ m_Data(static_cast<const byte *>(Data), DataLength),
+ m_ErrorState(NONE) {
+ m_Iter = m_Data.begin();
+}
+
+// -----------------------------------------------------------------------------
+
+InputPersistenceBlock::~InputPersistenceBlock() {
+ if (m_Iter != m_Data.end()) BS_LOG_WARNINGLN("Persistence block was not read to the end.");
+}
+
+// -----------------------------------------------------------------------------
+// Reading
+// -----------------------------------------------------------------------------
+
+void InputPersistenceBlock::read(int16 &Value) {
+ signed int v;
+ read(v);
+ Value = static_cast<int16>(v);
+}
+
+// -----------------------------------------------------------------------------
+
+void InputPersistenceBlock::read(signed int &Value) {
+ if (CheckMarker(SINT_MARKER)) {
+ RawRead(&Value, sizeof(signed int));
+ Value = ConvertEndianessFromStorageToSystem(Value);
+ } else {
+ Value = 0;
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void InputPersistenceBlock::read(uint &Value) {
+ if (CheckMarker(UINT_MARKER)) {
+ RawRead(&Value, sizeof(uint));
+ Value = ConvertEndianessFromStorageToSystem(Value);
+ } else {
+ Value = 0;
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void InputPersistenceBlock::read(float &Value) {
+ if (CheckMarker(FLOAT_MARKER)) {
+ RawRead(&Value, sizeof(float));
+ Value = ConvertEndianessFromStorageToSystem(Value);
+ } else {
+ Value = 0.0f;
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void InputPersistenceBlock::read(bool &Value) {
+ if (CheckMarker(BOOL_MARKER)) {
+ uint UIntBool;
+ RawRead(&UIntBool, sizeof(float));
+ UIntBool = ConvertEndianessFromStorageToSystem(UIntBool);
+ Value = UIntBool == 0 ? false : true;
+ } else {
+ Value = 0.0f;
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void InputPersistenceBlock::read(Common::String &Value) {
+ Value = "";
+
+ if (CheckMarker(STRING_MARKER)) {
+ uint Size;
+ read(Size);
+
+ if (CheckBlockSize(Size)) {
+ Value = Common::String(reinterpret_cast<const char *>(&*m_Iter), Size);
+ m_Iter += Size;
+ }
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void InputPersistenceBlock::read(Common::Array<byte> &Value) {
+ if (CheckMarker(BLOCK_MARKER)) {
+ uint Size;
+ read(Size);
+
+ if (CheckBlockSize(Size)) {
+ Value = Common::Array<byte>(m_Iter, Size);
+ m_Iter += Size;
+ }
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+void InputPersistenceBlock::RawRead(void *DestPtr, size_t Size) {
+ if (CheckBlockSize(Size)) {
+ memcpy(DestPtr, &*m_Iter, Size);
+ m_Iter += Size;
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+bool InputPersistenceBlock::CheckBlockSize(int Size) {
+ if (m_Data.end() - m_Iter >= Size) {
+ return true;
+ } else {
+ m_ErrorState = END_OF_DATA;
+ BS_LOG_ERRORLN("Unexpected end of persistence block.");
+ return false;
+ }
+}
+
+// -----------------------------------------------------------------------------
+
+bool InputPersistenceBlock::CheckMarker(byte Marker) {
+ if (!isGood() || !CheckBlockSize(1)) return false;
+
+ if (*m_Iter++ == Marker) {
+ return true;
+ } else {
+ m_ErrorState = OUT_OF_SYNC;
+ BS_LOG_ERRORLN("Wrong type marker found in persistence block.");
+ return false;
+ }
+}
+
+} // End of namespace Sword25
diff --git a/engines/sword25/kernel/inputpersistenceblock.h b/engines/sword25/kernel/inputpersistenceblock.h
new file mode 100644
index 0000000000..a6978e5899
--- /dev/null
+++ b/engines/sword25/kernel/inputpersistenceblock.h
@@ -0,0 +1,90 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+/*
+ * This code is based on Broken Sword 2.5 engine
+ *
+ * Copyright (c) Malte Thiesen, Daniel Queteschiner and Michael Elsdoerfer
+ *
+ * Licensed under GNU GPL v2
+ *
+ */
+
+#ifndef SWORD25_INPUTPERSISTENCEBLOCK_H
+#define SWORD25_INPUTPERSISTENCEBLOCK_H
+
+// -----------------------------------------------------------------------------
+// Includes
+// -----------------------------------------------------------------------------
+
+#include "common/array.h"
+#include "sword25/kernel/common.h"
+#include "sword25/kernel/persistenceblock.h"
+
+namespace Sword25 {
+
+// -----------------------------------------------------------------------------
+// Class declaration
+// -----------------------------------------------------------------------------
+
+class InputPersistenceBlock : public PersistenceBlock {
+public:
+ enum ErrorState {
+ NONE,
+ END_OF_DATA,
+ OUT_OF_SYNC
+ };
+
+ InputPersistenceBlock(const void *Data, uint DataLength);
+ virtual ~InputPersistenceBlock();
+
+ void read(int16 &Value);
+ void read(signed int &Value);
+ void read(uint &Value);
+ void read(float &Value);
+ void read(bool &Value);
+ void read(Common::String &Value);
+ void read(Common::Array<byte> &Value);
+
+ bool isGood() const {
+ return m_ErrorState == NONE;
+ }
+ ErrorState GetErrorState() const {
+ return m_ErrorState;
+ }
+
+private:
+ bool CheckMarker(byte Marker);
+ bool CheckBlockSize(int Size);
+ void RawRead(void *DestPtr, size_t Size);
+
+ Common::Array<byte> m_Data;
+ Common::Array<byte>::const_iterator m_Iter;
+ ErrorState m_ErrorState;
+};
+
+} // End of namespace Sword25
+
+#endif
diff --git a/engines/sword25/kernel/kernel.cpp b/engines/sword25/kernel/kernel.cpp
new file mode 100644
index 0000000000..3e7e7f125f
--- /dev/null
+++ b/engines/sword25/kernel/kernel.cpp
@@ -0,0 +1,454 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+/*
+ * This code is based on Broken Sword 2.5 engine
+ *
+ * Copyright (c) Malte Thiesen, Daniel Queteschiner and Michael Elsdoerfer
+ *
+ * Licensed under GNU GPL v2
+ *
+ */
+
+#include "common/system.h"
+#include "sword25/gfx/graphicengine.h"
+#include "sword25/fmv/movieplayer.h"
+#include "sword25/input/inputengine.h"
+#include "sword25/kernel/kernel.h"
+#include "sword25/kernel/persistenceservice.h"
+#include "sword25/kernel/service_ids.h"
+#include "sword25/package/packagemanager.h"
+#include "sword25/script/script.h"
+#include "sword25/sfx/soundengine.h"
+
+namespace Sword25 {
+
+#define BS_LOG_PREFIX "KERNEL"
+
+Kernel *Kernel::_Instance = 0;
+
+Kernel::Kernel() :
+ _pWindow(NULL),
+ _Running(false),
+ _pResourceManager(NULL),
+ _InitSuccess(false) {
+
+ // Log that the kernel is beign created
+ BS_LOGLN("created.");
+
+ // Read the BS_SERVICE_TABLE and prepare kernel structures
+ for (uint i = 0; i < BS_SERVICE_COUNT; i++) {
+ // Is the superclass already registered?
+ Superclass *pCurSuperclass = NULL;
+ Common::Array<Superclass *>::iterator Iter;
+ for (Iter = _SuperclassList.begin(); Iter != _SuperclassList.end(); ++Iter)
+ if ((*Iter)->GetIdentifier() == BS_SERVICE_TABLE[i].SuperclassIdentifier) {
+ pCurSuperclass = *Iter;
+ break;
+ }
+
+ // If the superclass isn't already registered, then add it in
+ if (!pCurSuperclass)
+ _SuperclassList.push_back(new Superclass(this, BS_SERVICE_TABLE[i].SuperclassIdentifier));
+ }
+
+ // Create window object
+ _pWindow = Window::CreateBSWindow(0, 0, 0, 0, false);
+ if (!_pWindow) {
+ BS_LOG_ERRORLN("Failed to create the window.");
+ } else
+ BS_LOGLN("Window created.");
+
+ // Create the resource manager
+ _pResourceManager = new ResourceManager(this);
+
+ // Initialise the script engine
+ ScriptEngine *pScript = static_cast<ScriptEngine *>(NewService("script", "lua"));
+ if (!pScript || !pScript->init()) {
+ _InitSuccess = false;
+ return;
+ }
+
+ // Register kernel script bindings
+ if (!_RegisterScriptBindings()) {
+ BS_LOG_ERRORLN("Script bindings could not be registered.");
+ _InitSuccess = false;
+ return;
+ }
+ BS_LOGLN("Script bindings registered.");
+
+ _InitSuccess = true;
+}
+
+Kernel::~Kernel() {
+ // Services are de-registered in reverse order of creation
+ while (!_ServiceCreationOrder.empty()) {
+ Superclass *superclass = GetSuperclassByIdentifier(_ServiceCreationOrder.top());
+ if (superclass) superclass->DisconnectService();
+ _ServiceCreationOrder.pop();
+ }
+
+ // Empty the Superclass list
+ while (_SuperclassList.size()) {
+ delete _SuperclassList.back();
+ _SuperclassList.pop_back();
+ }
+
+ // Release the window object
+ delete _pWindow;
+ BS_LOGLN("Window destroyed.");
+
+ // Resource-Manager freigeben
+ delete _pResourceManager;
+
+ BS_LOGLN("destroyed.");
+}
+
+// Service Methoden
+// ----------------
+
+Kernel::Superclass::Superclass(Kernel *pKernel, const Common::String &Identifier) :
+ _pKernel(pKernel),
+ _Identifier(Identifier),
+ _ServiceCount(0),
+ _ActiveService(NULL) {
+ for (uint i = 0; i < BS_SERVICE_COUNT; i++)
+ if (BS_SERVICE_TABLE[i].SuperclassIdentifier == _Identifier)
+ _ServiceCount++;
+}
+
+Kernel::Superclass::~Superclass() {
+ DisconnectService();
+}
+
+/**
+ * Gets the identifier of a service with a given superclass.
+ * The number of services in a superclass can be learned with GetServiceCount().
+ * @param SuperclassIdentifier The name of the superclass
+ * z.B: "sfx", "gfx", "package" ...
+ * @param Number die Nummer des Services, dessen Bezeichner man erfahren will.<br>
+ * Hierbei ist zu beachten, dass der erste Service die Nummer 0 erhält. Number muss also eine Zahl zwischen
+ * 0 und GetServiceCount() - 1 sein.
+ */
+Common::String Kernel::Superclass::GetServiceIdentifier(uint Number) {
+ if (Number > _ServiceCount) return NULL;
+
+ uint CurServiceOrd = 0;
+ for (uint i = 0; i < BS_SERVICE_COUNT; i++) {
+ if (BS_SERVICE_TABLE[i].SuperclassIdentifier == _Identifier) {
+ if (Number == CurServiceOrd)
+ return BS_SERVICE_TABLE[i].ServiceIdentifier;
+ else
+ CurServiceOrd++;
+ }
+ }
+
+ return Common::String("");
+}
+
+/**
+ * Creates a new service with the given identifier. Returns a pointer to the service, or null if the
+ * service could not be created
+ * Note: All services must be registered in service_ids.h, otherwise they cannot be created here
+ * @param SuperclassIdentifier The name of the superclass of the service
+ * z.B: "sfx", "gfx", "package" ...
+ * @param ServiceIdentifier The name of the service
+ * For the superclass "sfx" an example could be "Fmod" or "directsound"
+ */
+Service *Kernel::Superclass::NewService(const Common::String &ServiceIdentifier) {
+ for (uint i = 0; i < BS_SERVICE_COUNT; i++)
+ if (BS_SERVICE_TABLE[i].SuperclassIdentifier == _Identifier &&
+ BS_SERVICE_TABLE[i].ServiceIdentifier == ServiceIdentifier) {
+ Service *NewService_ = BS_SERVICE_TABLE[i].CreateMethod(_pKernel);
+
+ if (NewService_) {
+ DisconnectService();
+ BS_LOGLN("Service '%s' created from superclass '%s'.", ServiceIdentifier.c_str(), _Identifier.c_str());
+ _ActiveService = NewService_;
+ _ActiveServiceName = BS_SERVICE_TABLE[i].ServiceIdentifier;
+ return _ActiveService;
+ } else {
+ BS_LOG_ERRORLN("Failed to create service '%s' from superclass '%s'.", ServiceIdentifier.c_str(), _Identifier.c_str());
+ return NULL;
+ }
+ }
+
+ BS_LOG_ERRORLN("Service '%s' is not avaliable from superclass '%s'.", ServiceIdentifier.c_str(), _Identifier.c_str());
+ return NULL;
+}
+
+/**
+ * Ends the current service of a superclass. Returns true on success, and false if the superclass
+ * does not exist or if not service was active
+ * @param SuperclassIdentfier The name of the superclass which is to be disconnected
+ * z.B: "sfx", "gfx", "package" ...
+ */
+bool Kernel::Superclass::DisconnectService() {
+ if (_ActiveService) {
+ delete _ActiveService;
+ _ActiveService = 0;
+ BS_LOGLN("Active service '%s' disconnected from superclass '%s'.", _ActiveServiceName.c_str(), _Identifier.c_str());
+ return true;
+ }
+
+ return false;
+}
+
+Kernel::Superclass *Kernel::GetSuperclassByIdentifier(const Common::String &Identifier) {
+ Common::Array<Superclass *>::iterator Iter;
+ for (Iter = _SuperclassList.begin(); Iter != _SuperclassList.end(); ++Iter) {
+ if ((*Iter)->GetIdentifier() == Identifier)
+ return *Iter;
+ }
+
+ // BS_LOG_ERRORLN("Superclass '%s' does not exist.", Identifier.c_str());
+ return NULL;
+}
+
+/**
+ * Returns the number of register superclasses
+ */
+uint Kernel::GetSuperclassCount() {
+ return _SuperclassList.size();
+}
+
+/**
+ * Returns the name of a superclass with the specified index.
+ * Note: The number of superclasses can be retrieved using GetSuperclassCount
+ * @param Number The number of the superclass to return the identifier for.
+ * It should be noted that the number should be between 0 und GetSuperclassCount() - 1.
+ */
+Common::String Kernel::GetSuperclassIdentifier(uint Number) {
+ if (Number > _SuperclassList.size()) return NULL;
+
+ uint CurSuperclassOrd = 0;
+ Common::Array<Superclass *>::iterator Iter;
+ for (Iter = _SuperclassList.begin(); Iter != _SuperclassList.end(); ++Iter) {
+ if (CurSuperclassOrd == Number)
+ return ((*Iter)->GetIdentifier());
+
+ CurSuperclassOrd++;
+ }
+
+ return Common::String("");
+}
+
+/**
+ * Returns the number of services registered with a given superclass
+ * @param SuperclassIdentifier The name of the superclass
+ * z.B: "sfx", "gfx", "package" ...
+ */
+uint Kernel::GetServiceCount(const Common::String &SuperclassIdentifier) {
+ Superclass *pSuperclass;
+ if (!(pSuperclass = GetSuperclassByIdentifier(SuperclassIdentifier)))
+ return 0;
+
+ return pSuperclass->GetServiceCount();
+
+}
+
+/**
+ * Gets the identifier of a service with a given superclass.
+ * The number of services in a superclass can be learned with GetServiceCount().
+ * @param SuperclassIdentifier The name of the superclass
+ * z.B: "sfx", "gfx", "package" ...
+ * @param Number die Nummer des Services, dessen Bezeichner man erfahren will.<br>
+ * Hierbei ist zu beachten, dass der erste Service die Nummer 0 erhält. Number muss also eine Zahl zwischen
+ * 0 und GetServiceCount() - 1 sein.
+ */
+Common::String Kernel::GetServiceIdentifier(const Common::String &SuperclassIdentifier, uint Number) {
+ Superclass *pSuperclass;
+ if (!(pSuperclass = GetSuperclassByIdentifier(SuperclassIdentifier))) return NULL;
+
+ return (pSuperclass->GetServiceIdentifier(Number));
+}
+
+/**
+ * Creates a new service with the given identifier. Returns a pointer to the service, or null if the
+ * service could not be created
+ * Note: All services must be registered in service_ids.h, otherwise they cannot be created here
+ * @param SuperclassIdentifier The name of the superclass of the service
+ * z.B: "sfx", "gfx", "package" ...
+ * @param ServiceIdentifier The name of the service
+ * For the superclass "sfx" an example could be "Fmod" or "directsound"
+ */
+Service *Kernel::NewService(const Common::String &SuperclassIdentifier, const Common::String &ServiceIdentifier) {
+ Superclass *pSuperclass;
+ if (!(pSuperclass = GetSuperclassByIdentifier(SuperclassIdentifier))) return NULL;
+
+ // Die Reihenfolge merken, in der Services erstellt werden, damit sie später in umgekehrter Reihenfolge entladen werden können.
+ _ServiceCreationOrder.push(SuperclassIdentifier);
+
+ return pSuperclass->NewService(ServiceIdentifier);
+}
+
+/**
+ * Ends the current service of a superclass. Returns true on success, and false if the superclass
+ * does not exist or if not service was active
+ * @param SuperclassIdentfier The name of the superclass which is to be disconnected
+ * z.B: "sfx", "gfx", "package" ...
+ */
+bool Kernel::DisconnectService(const Common::String &SuperclassIdentifier) {
+ Superclass *pSuperclass;
+ if (!(pSuperclass = GetSuperclassByIdentifier(SuperclassIdentifier))) return false;
+
+ return pSuperclass->DisconnectService();
+}
+
+/**
+ * Returns a pointer to the currently active service object of a superclass
+ * @param SuperclassIdentfier The name of the superclass
+ * z.B: "sfx", "gfx", "package" ...
+ */
+Service *Kernel::GetService(const Common::String &SuperclassIdentifier) {
+ Superclass *pSuperclass;
+ if (!(pSuperclass = GetSuperclassByIdentifier(SuperclassIdentifier))) return NULL;
+
+ return (pSuperclass->GetActiveService());
+}
+
+/**
+ * Returns the name of the currentl active service object of a superclass.
+ * If an error occurs, then an empty string is returned
+ * @param SuperclassIdentfier The name of the superclass
+ * z.B: "sfx", "gfx", "package" ...
+ */
+Common::String Kernel::GetActiveServiceIdentifier(const Common::String &SuperclassIdentifier) {
+ Superclass *pSuperclass = GetSuperclassByIdentifier(SuperclassIdentifier);
+ if (!pSuperclass) return Common::String("");
+
+ return (pSuperclass->GetActiveServiceName());
+}
+
+// -----------------------------------------------------------------------------
+
+/**
+ * Returns a random number
+ * @param Min The minimum allowed value
+ * @param Max The maximum allowed value
+ */
+int Kernel::GetRandomNumber(int Min, int Max) {
+ BS_ASSERT(Min <= Max);
+
+ return Min + _rnd.getRandomNumber(Max - Min + 1);
+}
+
+/**
+ * Returns the elapsed time since startup in milliseconds
+ */
+uint Kernel::GetMilliTicks() {
+ return g_system->getMillis();
+}
+
+/**
+ * Returns the elapsed time since the system start in microseconds.
+ * This method should be used only if GetMilliTick() for the desired application is inaccurate.
+ */
+uint64 Kernel::GetMicroTicks() {
+ return g_system->getMillis() * 1000;
+}
+
+// Other methods
+// -----------------
+
+/**
+ * Returns how much memory is being used
+ */
+size_t Kernel::GetUsedMemory() {
+ return 0;
+
+#ifdef SCUMMVM_DISABLED_CODE
+ PROCESS_MEMORY_COUNTERS pmc;
+ pmc.cb = sizeof(pmc);
+ if (GetProcessMemoryInfo(GetCurrentProcess(), &pmc, sizeof(pmc))) {
+ return pmc.WorkingSetSize;
+ } else {
+ BS_LOG_ERRORLN("Call to GetProcessMemoryInfo() failed. Error code: %d", GetLastError());
+ return 0;
+ }
+#endif
+}
+
+// -----------------------------------------------------------------------------
+
+/**
+ * Returns a pointer to the active Gfx Service, or NULL if no Gfx service is active
+ */
+GraphicEngine *Kernel::GetGfx() {
+ return static_cast<GraphicEngine *>(GetService("gfx"));
+}
+
+// -----------------------------------------------------------------------------
+
+/**
+ * Returns a pointer to the active Sfx Service, or NULL if no Sfx service is active
+ */
+SoundEngine *Kernel::GetSfx() {
+ return static_cast<SoundEngine *>(GetService("sfx"));
+}
+
+// -----------------------------------------------------------------------------
+
+/**
+ * Returns a pointer to the active input service, or NULL if no input service is active
+ */
+InputEngine *Kernel::GetInput() {
+ return static_cast<InputEngine *>(GetService("input"));
+}
+
+// -----------------------------------------------------------------------------
+
+/**
+ * Returns a pointer to the active package manager, or NULL if no manager is active
+ */
+PackageManager *Kernel::GetPackage() {
+ return static_cast<PackageManager *>(GetService("package"));
+}
+
+// -----------------------------------------------------------------------------
+
+/**
+ * Returns a pointer to the script engine, or NULL if it is not active
+ */
+ScriptEngine *Kernel::GetScript() {
+ return static_cast<ScriptEngine *>(GetService("script"));
+}
+
+// -----------------------------------------------------------------------------
+
+/**
+ * Returns a pointer to the movie player, or NULL if it is not active
+ */
+MoviePlayer *Kernel::GetFMV() {
+ return static_cast<MoviePlayer *>(GetService("fmv"));
+}
+
+// -----------------------------------------------------------------------------
+
+void Kernel::Sleep(uint Msecs) const {
+ g_system->delayMillis(Msecs);
+}
+
+} // End of namespace Sword25
diff --git a/engines/sword25/kernel/kernel.h b/engines/sword25/kernel/kernel.h
new file mode 100644
index 0000000000..55a64c783f
--- /dev/null
+++ b/engines/sword25/kernel/kernel.h
@@ -0,0 +1,370 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+/*
+ * This code is based on Broken Sword 2.5 engine
+ *
+ * Copyright (c) Malte Thiesen, Daniel Queteschiner and Michael Elsdoerfer
+ *
+ * Licensed under GNU GPL v2
+ *
+ */
+
+/*
+ * BS_Kernel
+ * ---------
+ * This is the main class of the engine.
+ * This class creates and manages all other Engine elements: the sound engine, graphics engine ...
+ * It is not necessary to release all the items individually, this is performed by the Kernel class.
+ *
+ * Autor: Malte Thiesen
+ */
+
+#ifndef SWORD25_KERNEL_H
+#define SWORD25_KERNEL_H
+
+// Includes
+#include "common/scummsys.h"
+#include "common/random.h"
+#include "common/stack.h"
+#include "common/util.h"
+#include "engines/engine.h"
+
+#include "sword25/kernel/common.h"
+#include "sword25/kernel/bs_stdint.h"
+#include "sword25/kernel/window.h"
+#include "sword25/kernel/resmanager.h"
+
+namespace Sword25 {
+
+// Class definitions
+class Service;
+class GraphicEngine;
+class ScriptEngine;
+class SoundEngine;
+class InputEngine;
+class PackageManager;
+class MoviePlayer;
+
+/**
+ * This is the main engine class
+ *
+ * This class creates and manages all other engine components such as sound engine, graphics engine ...
+ * It is not necessary to release all the items individually, this is performed by the Kernel class.
+*/
+class Kernel {
+public:
+ // Window methods
+ // ----------------
+
+ /**
+ * Returns a pointer to the window object
+ */
+ Window *GetWindow() {
+ return _pWindow;
+ }
+
+ // Service Methods
+ // ---------------
+
+ /**
+ * Creates a new service with the given identifier. Returns a pointer to the service, or null if the
+ * service could not be created
+ * Note: All services must be registered in service_ids.h, otherwise they cannot be created here
+ * @param SuperclassIdentifier The name of the superclass of the service
+ * z.B: "sfx", "gfx", "package" ...
+ * @param ServiceIdentifier The name of the service
+ * For the superclass "sfx" an example could be "Fmod" or "directsound"
+ */
+ Service *NewService(const Common::String &SuperclassIdentifier, const Common::String &ServiceIdentifier);
+
+ /**
+ * Ends the current service of a superclass. Returns true on success, and false if the superclass
+ * does not exist or if not service was active
+ * @param SuperclassIdentfier The name of the superclass which is to be disconnected
+ * z.B: "sfx", "gfx", "package" ...
+ */
+ bool DisconnectService(const Common::String &SuperclassIdentifier);
+
+ /**
+ * Returns a pointer to the currently active service object of a superclass
+ * @param SuperclassIdentfier The name of the superclass
+ * z.B: "sfx", "gfx", "package" ...
+ */
+ Service *GetService(const Common::String &SuperclassIdentifier);
+
+ /**
+ * Returns the name of the currentl active service object of a superclass.
+ * If an error occurs, then an empty string is returned
+ * @param SuperclassIdentfier The name of the superclass
+ * z.B: "sfx", "gfx", "package" ...
+ */
+ Common::String GetActiveServiceIdentifier(const Common::String &SuperclassIdentifier);
+
+ /**
+ * Returns the number of register superclasses
+ */
+ uint GetSuperclassCount();
+
+ /**
+ * Returns the name of a superclass with the specified index.
+ * Note: The number of superclasses can be retrieved using GetSuperclassCount
+ * @param Number The number of the superclass to return the identifier for.
+ * It should be noted that the number should be between 0 und GetSuperclassCount() - 1.
+ */
+ Common::String GetSuperclassIdentifier(uint Number);
+
+ /**
+ * Returns the number of services registered with a given superclass
+ * @param SuperclassIdentifier The name of the superclass
+ * z.B: "sfx", "gfx", "package" ...
+ */
+ uint GetServiceCount(const Common::String &SuperclassIdentifier);
+
+ /**
+ * Gets the identifier of a service with a given superclass.
+ * The number of services in a superclass can be learned with GetServiceCount().
+ * @param SuperclassIdentifier The name of the superclass
+ * z.B: "sfx", "gfx", "package" ...
+ * @param Number die Nummer des Services, dessen Bezeichner man erfahren will.<br>
+ * Hierbei ist zu beachten, dass der erste Service die Nummer 0 erhält. Number muss also eine Zahl zwischen
+ * 0 und GetServiceCount() - 1 sein.
+ */
+ Common::String GetServiceIdentifier(const Common::String &SuperclassIdentifier, uint Number);
+
+ /**
+ * Returns the elapsed time since startup in milliseconds
+ */
+ uint GetMilliTicks();
+
+ /**
+ * Returns the elapsed time since the system start in microseconds.
+ * This method should be used only if GetMilliTick() for the desired application is inaccurate.
+ */
+ uint64 GetMicroTicks();
+
+ /**
+ * Specifies whether the kernel was successfully initialised
+ */
+ bool GetInitSuccess() {
+ return _InitSuccess;
+ }
+ /**
+ * Returns a pointer to the BS_ResourceManager
+ */
+ ResourceManager *GetResourceManager() {
+ return _pResourceManager;
+ }
+ /**
+ * Returns how much memory is being used
+ */
+ size_t GetUsedMemory();
+ /**
+ * Returns a random number
+ * @param Min The minimum allowed value
+ * @param Max The maximum allowed value
+ */
+ int GetRandomNumber(int Min, int Max);
+ /**
+ * Returns a pointer to the active Gfx Service, or NULL if no Gfx service is active
+ */
+ GraphicEngine *GetGfx();
+ /**
+ * Returns a pointer to the active Sfx Service, or NULL if no Sfx service is active
+ */
+ SoundEngine *GetSfx();
+ /**
+ * Returns a pointer to the active input service, or NULL if no input service is active
+ */
+ InputEngine *GetInput();
+ /**
+ * Returns a pointer to the active package manager, or NULL if no manager is active
+ */
+ PackageManager *GetPackage();
+ /**
+ * Returns a pointer to the script engine, or NULL if it is not active
+ */
+ ScriptEngine *GetScript();
+ /**
+ * Returns a pointer to the movie player, or NULL if it is not active
+ */
+ MoviePlayer *GetFMV();
+
+ /**
+ * Pauses for the specified amount of time
+ * @param Msecs The amount of time in milliseconds
+ */
+ void Sleep(uint Msecs) const;
+
+ /**
+ * Returns the singleton instance for the kernel
+ */
+ static Kernel *GetInstance() {
+ if (!_Instance) _Instance = new Kernel();
+ return _Instance;
+ }
+
+ /**
+ * Destroys the kernel instance
+ * This method should only be called when the game is ended. No subsequent calls to any kernel
+ * methods should be done after calling this method.
+ */
+ static void DeleteInstance() {
+ if (_Instance) {
+ delete _Instance;
+ _Instance = NULL;
+ }
+ }
+
+ /**
+ * Raises an error. This method is used in crashing testing.
+ */
+ void Crash() const {
+ error("BS_Kernel::Crash");
+ }
+
+private:
+ // -----------------------------------------------------------------------------
+ // Constructor / destructor
+ // Private singleton methods
+ // -----------------------------------------------------------------------------
+
+ Kernel();
+ virtual ~Kernel();
+
+ // -----------------------------------------------------------------------------
+ // Singleton instance
+ // -----------------------------------------------------------------------------
+ static Kernel *_Instance;
+
+ // Superclass class
+ // ----------------
+ class Superclass {
+ private:
+ Kernel *_pKernel;
+ uint _ServiceCount;
+ Common::String _Identifier;
+ Service *_ActiveService;
+ Common::String _ActiveServiceName;
+
+ public:
+ Superclass(Kernel *pKernel, const Common::String &Identifier);
+ ~Superclass();
+
+ uint GetServiceCount() const {
+ return _ServiceCount;
+ }
+ Common::String GetIdentifier() const {
+ return _Identifier;
+ }
+ Service *GetActiveService() const {
+ return _ActiveService;
+ }
+ Common::String GetActiveServiceName() const {
+ return _ActiveServiceName;
+ }
+ Common::String GetServiceIdentifier(uint Number);
+ Service *NewService(const Common::String &ServiceIdentifier);
+ bool DisconnectService();
+ };
+
+ Common::Array<Superclass *> _SuperclassList;
+ Common::Stack<Common::String> _ServiceCreationOrder;
+ Superclass *GetSuperclassByIdentifier(const Common::String &Identifier);
+
+ bool _InitSuccess; // Specifies whether the engine was set up correctly
+ bool _Running; // Specifies whether the application should keep running on the next main loop iteration
+
+ // Active window
+ // -------------
+ Window *_pWindow;
+
+ // Random number generator
+ // -----------------------
+ Common::RandomSource _rnd;
+
+ /*
+ // Features variables and methods
+ // ----------------------------------
+ enum _CPU_FEATURES_BITMASKS
+ {
+ _MMX_BITMASK = (1 << 23),
+ _SSE_BITMASK = (1 << 25),
+ _SSE2_BITMASK = (1 << 26),
+ _3DNOW_BITMASK = (1 << 30),
+ _3DNOWEXT_BITMASK = (1 << 31)
+ };
+
+ bool _DetectCPU();
+
+ bool _MMXPresent;
+ bool _SSEPresent;
+ bool _SSE2Present;
+ bool _3DNowPresent;
+ bool _3DNowExtPresent;
+ CPU_TYPES _CPUType;
+ Common::String _CPUVendorID;
+ */
+
+ // Resourcemanager
+ // ---------------
+ ResourceManager *_pResourceManager;
+
+ bool _RegisterScriptBindings();
+};
+
+/**
+ * This is only a small class that manages the data of a service. It is a little ugly, I know,
+ * but with Common::String a simple struct could not be used.
+ */
+class BS_ServiceInfo {
+public:
+ BS_ServiceInfo(const Common::String &SuperclassIdentifier_, const Common::String &ServiceIdentifier_,
+ Service*(*CreateMethod_)(Kernel *)) {
+ this->SuperclassIdentifier = SuperclassIdentifier_;
+ this->ServiceIdentifier = ServiceIdentifier_;
+ this->CreateMethod = CreateMethod_;
+ };
+
+ Common::String SuperclassIdentifier;
+ Common::String ServiceIdentifier;
+ Service*(*CreateMethod)(Kernel *);
+};
+
+template<class T>
+void ReverseArray(Common::Array<T> &Arr) {
+ if (Arr.size() < 2)
+ return;
+
+ for (uint i = 0; i <= (Arr.size() / 2 - 1); ++i) {
+ T temp = Arr[i];
+ Arr[i] = Arr[Arr.size() - i - 1];
+ Arr[Arr.size() - i - 1] = temp;
+ }
+}
+
+} // End of namespace Sword25
+
+#endif
diff --git a/engines/sword25/kernel/kernel_script.cpp b/engines/sword25/kernel/kernel_script.cpp
new file mode 100644
index 0000000000..1b87dfdc6e
--- /dev/null
+++ b/engines/sword25/kernel/kernel_script.cpp
@@ -0,0 +1,739 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+/*
+ * This code is based on Broken Sword 2.5 engine
+ *
+ * Copyright (c) Malte Thiesen, Daniel Queteschiner and Michael Elsdoerfer
+ *
+ * Licensed under GNU GPL v2
+ *
+ */
+
+// -----------------------------------------------------------------------------
+// Includes
+// -----------------------------------------------------------------------------
+
+#include "sword25/kernel/common.h"
+#include "sword25/kernel/kernel.h"
+#include "sword25/kernel/filesystemutil.h"
+#include "sword25/kernel/window.h"
+#include "sword25/kernel/resmanager.h"
+#include "sword25/kernel/persistenceservice.h"
+#include "sword25/script/script.h"
+#include "sword25/script/luabindhelper.h"
+
+namespace Sword25 {
+
+// -----------------------------------------------------------------------------
+
+static int DisconnectService(lua_State *L) {
+ Kernel *pKernel = Kernel::GetInstance();
+ BS_ASSERT(pKernel);
+
+ lua_pushboolean(L, pKernel->DisconnectService(luaL_checkstring(L, 1)));
+
+ return 1;
+}
+
+// -----------------------------------------------------------------------------
+
+static int GetActiveServiceIdentifier(lua_State *L) {
+ Kernel *pKernel = Kernel::GetInstance();
+ BS_ASSERT(pKernel);
+
+ lua_pushstring(L, pKernel->GetActiveServiceIdentifier(luaL_checkstring(L, 1)).c_str());
+
+ return 1;
+}
+
+// -----------------------------------------------------------------------------
+
+static int GetSuperclassCount(lua_State *L) {
+ Kernel *pKernel = Kernel::GetInstance();
+ BS_ASSERT(pKernel);
+
+ lua_pushnumber(L, pKernel->GetSuperclassCount());
+
+ return 1;
+}
+
+// -----------------------------------------------------------------------------
+
+static int GetSuperclassIdentifier(lua_State *L) {
+ Kernel *pKernel = Kernel::GetInstance();
+ BS_ASSERT(pKernel);
+
+ lua_pushstring(L, pKernel->GetSuperclassIdentifier(
+ static_cast<uint>(luaL_checknumber(L, 1))).c_str());
+
+ return 1;
+}
+
+// -----------------------------------------------------------------------------
+
+static int GetServiceCount(lua_State *L) {
+ Kernel *pKernel = Kernel::GetInstance();
+ BS_ASSERT(pKernel);
+
+ lua_pushnumber(L, pKernel->GetServiceCount(luaL_checkstring(L, 1)));
+
+ return 1;
+}
+
+// -----------------------------------------------------------------------------
+
+static int GetServiceIdentifier(lua_State *L) {
+ Kernel *pKernel = Kernel::GetInstance();
+ BS_ASSERT(pKernel);
+
+ lua_pushstring(L, pKernel->GetServiceIdentifier(luaL_checkstring(L, 1),
+ static_cast<uint>(luaL_checknumber(L, 2))).c_str());
+
+ return 1;
+}
+
+// -----------------------------------------------------------------------------
+
+static int GetMilliTicks(lua_State *L) {
+ Kernel *pKernel = Kernel::GetInstance();
+ BS_ASSERT(pKernel);
+
+ lua_pushnumber(L, pKernel->GetMilliTicks());
+
+ return 1;
+}
+
+// -----------------------------------------------------------------------------
+
+static int GetTimer(lua_State *L) {
+ Kernel *pKernel = Kernel::GetInstance();
+ BS_ASSERT(pKernel);
+
+ lua_pushnumber(L, static_cast<lua_Number>(pKernel->GetMicroTicks()) / 1000000.0);
+
+ return 1;
+}
+
+// -----------------------------------------------------------------------------
+
+static int StartService(lua_State *L) {
+ Kernel *pKernel = Kernel::GetInstance();
+ BS_ASSERT(pKernel);
+
+ lua_pushbooleancpp(L, pKernel->NewService(luaL_checkstring(L, 1), luaL_checkstring(L, 2)) != NULL);
+
+ return 1;
+}
+
+// -----------------------------------------------------------------------------
+
+static int Sleep(lua_State *L) {
+ Kernel *pKernel = Kernel::GetInstance();
+ BS_ASSERT(pKernel);
+ pKernel->Sleep(static_cast<uint>(luaL_checknumber(L, 1) * 1000));
+ return 0;
+}
+
+// -----------------------------------------------------------------------------
+
+static int Crash(lua_State *L) {
+ Kernel *pKernel = Kernel::GetInstance();
+ BS_ASSERT(pKernel);
+ pKernel->Crash();
+ return 0;
+}
+
+// -----------------------------------------------------------------------------
+
+static int ExecuteFile(lua_State *L) {
+ Kernel *pKernel = Kernel::GetInstance();
+ BS_ASSERT(pKernel);
+ ScriptEngine *pSE = static_cast<ScriptEngine *>(pKernel->GetService("script"));
+ BS_ASSERT(pSE);
+
+ lua_pushbooleancpp(L, pSE->executeFile(luaL_checkstring(L, 1)));
+
+ return 0;
+}
+
+// -----------------------------------------------------------------------------
+
+static int GetUserdataDirectory(lua_State *L) {
+ lua_pushstring(L, FileSystemUtil::GetInstance().GetUserdataDirectory().c_str());
+ return 1;
+}
+
+// -----------------------------------------------------------------------------
+
+static int GetPathSeparator(lua_State *L) {
+ lua_pushstring(L, FileSystemUtil::GetInstance().GetPathSeparator().c_str());
+ return 1;
+}
+
+// -----------------------------------------------------------------------------
+
+static int FileExists(lua_State *L) {
+ lua_pushbooleancpp(L, FileSystemUtil::GetInstance().FileExists(luaL_checkstring(L, 1)));
+ return 1;
+}
+
+// -----------------------------------------------------------------------------
+
+static int CreateDirectory(lua_State *L) {
+ lua_pushbooleancpp(L, FileSystemUtil::GetInstance().CreateDirectory(luaL_checkstring(L, 1)));
+ return 1;
+}
+
+// -----------------------------------------------------------------------------
+
+static int GetWinCode(lua_State *L) {
+ lua_pushstring(L, "ScummVM");
+ return 1;
+}
+
+// -----------------------------------------------------------------------------
+
+static int GetSubversionRevision(lua_State *L) {
+ // ScummVM is 1337
+ lua_pushnumber(L, 1337);
+ return 1;
+}
+
+// -----------------------------------------------------------------------------
+
+static int GetUsedMemory(lua_State *L) {
+ lua_pushnumber(L, Kernel::GetInstance()->GetUsedMemory());
+ return 1;
+}
+
+// -----------------------------------------------------------------------------
+
+static const char *KERNEL_LIBRARY_NAME = "Kernel";
+
+static const luaL_reg KERNEL_FUNCTIONS[] = {
+ {"DisconnectService", DisconnectService},
+ {"GetActiveServiceIdentifier", GetActiveServiceIdentifier},
+ {"GetSuperclassCount", GetSuperclassCount},
+ {"GetSuperclassIdentifier", GetSuperclassIdentifier},
+ {"GetServiceCount", GetServiceCount},
+ {"GetServiceIdentifier", GetServiceIdentifier},
+ {"GetMilliTicks", GetMilliTicks},
+ {"GetTimer", GetTimer},
+ {"StartService", StartService},
+ {"Sleep", Sleep},
+ {"Crash", Crash},
+ {"ExecuteFile", ExecuteFile},
+ {"GetUserdataDirectory", GetUserdataDirectory},
+ {"GetPathSeparator", GetPathSeparator},
+ {"FileExists", FileExists},
+ {"CreateDirectory", CreateDirectory},
+ {"GetWinCode", GetWinCode},
+ {"GetSubversionRevision", GetSubversionRevision},
+ {"GetUsedMemory", GetUsedMemory},
+ {0, 0}
+};
+
+// -----------------------------------------------------------------------------
+
+static int IsVisible(lua_State *L) {
+ Kernel *pKernel = Kernel::GetInstance();
+ BS_ASSERT(pKernel);
+ Window *pWindow = pKernel->GetWindow();
+ BS_ASSERT(pWindow);
+
+ lua_pushbooleancpp(L, pWindow->IsVisible());
+
+ return 1;
+}
+
+// -----------------------------------------------------------------------------
+
+static int SetVisible(lua_State *L) {
+ Kernel *pKernel = Kernel::GetInstance();
+ BS_ASSERT(pKernel);
+ Window *pWindow = pKernel->GetWindow();
+ BS_ASSERT(pWindow);
+
+ pWindow->SetVisible(lua_tobooleancpp(L, 1));
+
+ return 0;
+}
+
+// -----------------------------------------------------------------------------
+
+static int GetX(lua_State *L) {
+ Kernel *pKernel = Kernel::GetInstance();
+ BS_ASSERT(pKernel);
+ Window *pWindow = pKernel->GetWindow();
+ BS_ASSERT(pWindow);
+
+ lua_pushnumber(L, pWindow->GetX());
+
+ return 1;
+}
+
+// -----------------------------------------------------------------------------
+
+static int GetY(lua_State *L) {
+ Kernel *pKernel = Kernel::GetInstance();
+ BS_ASSERT(pKernel);
+ Window *pWindow = pKernel->GetWindow();
+ BS_ASSERT(pWindow);
+
+ lua_pushnumber(L, pWindow->GetY());
+
+ return 1;
+}
+
+// -----------------------------------------------------------------------------
+
+static int SetX(lua_State *L) {
+ Kernel *pKernel = Kernel::GetInstance();
+ BS_ASSERT(pKernel);
+ Window *pWindow = pKernel->GetWindow();
+ BS_ASSERT(pWindow);
+
+ pWindow->SetX(static_cast<int>(luaL_checknumber(L, 1)));
+
+ return 0;
+}
+
+// -----------------------------------------------------------------------------
+
+static int SetY(lua_State *L) {
+ Kernel *pKernel = Kernel::GetInstance();
+ BS_ASSERT(pKernel);
+ Window *pWindow = pKernel->GetWindow();
+ BS_ASSERT(pWindow);
+
+ pWindow->SetY(static_cast<int>(luaL_checknumber(L, 1)));
+
+ return 0;
+}
+
+// -----------------------------------------------------------------------------
+
+static int GetClientX(lua_State *L) {
+ Kernel *pKernel = Kernel::GetInstance();
+ BS_ASSERT(pKernel);
+ Window *pWindow = pKernel->GetWindow();
+ BS_ASSERT(pWindow);
+
+ lua_pushnumber(L, pWindow->GetClientX());
+
+ return 1;
+}
+
+// -----------------------------------------------------------------------------
+
+static int GetClientY(lua_State *L) {
+ Kernel *pKernel = Kernel::GetInstance();
+ BS_ASSERT(pKernel);
+ Window *pWindow = pKernel->GetWindow();
+ BS_ASSERT(pWindow);
+
+ lua_pushnumber(L, pWindow->GetClientY());
+
+ return 1;
+}
+
+// -----------------------------------------------------------------------------
+
+static int GetWidth(lua_State *L) {
+ Kernel *pKernel = Kernel::GetInstance();
+ BS_ASSERT(pKernel);
+ Window *pWindow = pKernel->GetWindow();
+ BS_ASSERT(pWindow);
+
+ lua_pushnumber(L, pWindow->GetWidth());
+
+ return 1;
+}
+
+// -----------------------------------------------------------------------------
+
+static int GetHeight(lua_State *L) {
+ Kernel *pKernel = Kernel::GetInstance();
+ BS_ASSERT(pKernel);
+ Window *pWindow = pKernel->GetWindow();
+ BS_ASSERT(pWindow);
+
+ lua_pushnumber(L, pWindow->GetHeight());
+
+ return 1;
+}
+
+// -----------------------------------------------------------------------------
+
+static int SetWidth(lua_State *L) {
+ Kernel *pKernel = Kernel::GetInstance();
+ BS_ASSERT(pKernel);
+ Window *pWindow = pKernel->GetWindow();
+ BS_ASSERT(pWindow);
+
+ pWindow->SetWidth(static_cast<int>(luaL_checknumber(L, 1)));
+
+ return 0;
+}
+
+// -----------------------------------------------------------------------------
+
+static int SetHeight(lua_State *L) {
+ Kernel *pKernel = Kernel::GetInstance();
+ BS_ASSERT(pKernel);
+ Window *pWindow = pKernel->GetWindow();
+ BS_ASSERT(pWindow);
+
+ pWindow->SetHeight(static_cast<int>(luaL_checknumber(L, 1)));
+
+ return 0;
+}
+
+// -----------------------------------------------------------------------------
+
+static int GetTitle(lua_State *L) {
+ Kernel *pKernel = Kernel::GetInstance();
+ BS_ASSERT(pKernel);
+ Window *pWindow = pKernel->GetWindow();
+ BS_ASSERT(pWindow);
+
+ lua_pushstring(L, pWindow->GetTitle().c_str());
+
+ return 1;
+}
+
+// -----------------------------------------------------------------------------
+
+static int SetTitle(lua_State *L) {
+ Kernel *pKernel = Kernel::GetInstance();
+ BS_ASSERT(pKernel);
+ Window *pWindow = pKernel->GetWindow();
+ BS_ASSERT(pWindow);
+
+ pWindow->SetTitle(luaL_checkstring(L, 1));
+
+ return 0;
+}
+
+// -----------------------------------------------------------------------------
+
+static int ProcessMessages(lua_State *L) {
+ Kernel *pKernel = Kernel::GetInstance();
+ BS_ASSERT(pKernel);
+ Window *pWindow = pKernel->GetWindow();
+ BS_ASSERT(pWindow);
+
+ lua_pushbooleancpp(L, pWindow->ProcessMessages());
+
+ return 1;
+}
+
+// -----------------------------------------------------------------------------
+
+static int CloseWanted(lua_State *L) {
+ Kernel *pKernel = Kernel::GetInstance();
+ BS_ASSERT(pKernel);
+ Window *pWindow = pKernel->GetWindow();
+ BS_ASSERT(pWindow);
+
+ lua_pushbooleancpp(L, pWindow->CloseWanted());
+
+ return 1;
+}
+
+// -----------------------------------------------------------------------------
+
+static int WaitForFocus(lua_State *L) {
+ Kernel *pKernel = Kernel::GetInstance();
+ BS_ASSERT(pKernel);
+ Window *pWindow = pKernel->GetWindow();
+ BS_ASSERT(pWindow);
+
+ lua_pushbooleancpp(L, pWindow->WaitForFocus());
+
+ return 1;
+}
+
+// -----------------------------------------------------------------------------
+
+static int HasFocus(lua_State *L) {
+ Kernel *pKernel = Kernel::GetInstance();
+ BS_ASSERT(pKernel);
+ Window *pWindow = pKernel->GetWindow();
+ BS_ASSERT(pWindow);
+
+ lua_pushbooleancpp(L, pWindow->HasFocus());
+
+ return 1;
+}
+
+// -----------------------------------------------------------------------------
+
+static const char *WINDOW_LIBRARY_NAME = "Window";
+
+static const luaL_reg WINDOW_FUNCTIONS[] = {
+ {"IsVisible", IsVisible},
+ {"SetVisible", SetVisible},
+ {"GetX", GetX},
+ {"SetX", SetX},
+ {"GetY", GetY},
+ {"SetY", SetY},
+ {"GetClientX", GetClientX},
+ {"GetClientY", GetClientY},
+ {"GetWidth", GetWidth},
+ {"GetHeight", GetHeight},
+ {"SetWidth", SetWidth},
+ {"SetHeight", SetHeight},
+ {"GetTitle", GetTitle},
+ {"SetTitle", SetTitle},
+ {"ProcessMessages", ProcessMessages},
+ {"CloseWanted", CloseWanted},
+ {"WaitForFocus", WaitForFocus},
+ {"HasFocus", HasFocus},
+ {0, 0}
+};
+
+// -----------------------------------------------------------------------------
+
+static int PrecacheResource(lua_State *L) {
+ Kernel *pKernel = Kernel::GetInstance();
+ BS_ASSERT(pKernel);
+ ResourceManager *pResource = pKernel->GetResourceManager();
+ BS_ASSERT(pResource);
+
+ lua_pushbooleancpp(L, pResource->PrecacheResource(luaL_checkstring(L, 1)));
+
+ return 1;
+}
+
+// -----------------------------------------------------------------------------
+
+static int ForcePrecacheResource(lua_State *L) {
+ Kernel *pKernel = Kernel::GetInstance();
+ BS_ASSERT(pKernel);
+ ResourceManager *pResource = pKernel->GetResourceManager();
+ BS_ASSERT(pResource);
+
+ lua_pushbooleancpp(L, pResource->PrecacheResource(luaL_checkstring(L, 1), true));
+
+ return 1;
+}
+
+// -----------------------------------------------------------------------------
+
+static int GetMaxMemoryUsage(lua_State *L) {
+ Kernel *pKernel = Kernel::GetInstance();
+ BS_ASSERT(pKernel);
+ ResourceManager *pResource = pKernel->GetResourceManager();
+ BS_ASSERT(pResource);
+
+ lua_pushnumber(L, pResource->GetMaxMemoryUsage());
+
+ return 1;
+}
+
+// -----------------------------------------------------------------------------
+
+static int SetMaxMemoryUsage(lua_State *L) {
+ Kernel *pKernel = Kernel::GetInstance();
+ BS_ASSERT(pKernel);
+ ResourceManager *pResource = pKernel->GetResourceManager();
+ BS_ASSERT(pResource);
+
+ pResource->SetMaxMemoryUsage(static_cast<uint>(lua_tonumber(L, 1)));
+
+ return 0;
+}
+
+// -----------------------------------------------------------------------------
+
+static int EmptyCache(lua_State *L) {
+ Kernel *pKernel = Kernel::GetInstance();
+ BS_ASSERT(pKernel);
+ ResourceManager *pResource = pKernel->GetResourceManager();
+ BS_ASSERT(pResource);
+
+ pResource->EmptyCache();
+
+ return 0;
+}
+
+// -----------------------------------------------------------------------------
+
+static int IsLogCacheMiss(lua_State *L) {
+ Kernel *pKernel = Kernel::GetInstance();
+ BS_ASSERT(pKernel);
+ ResourceManager *pResource = pKernel->GetResourceManager();
+ BS_ASSERT(pResource);
+
+ lua_pushbooleancpp(L, pResource->IsLogCacheMiss());
+
+ return 1;
+}
+
+// -----------------------------------------------------------------------------
+
+static int SetLogCacheMiss(lua_State *L) {
+ Kernel *pKernel = Kernel::GetInstance();
+ BS_ASSERT(pKernel);
+ ResourceManager *pResource = pKernel->GetResourceManager();
+ BS_ASSERT(pResource);
+
+ pResource->SetLogCacheMiss(lua_tobooleancpp(L, 1));
+
+ return 0;
+}
+
+// -----------------------------------------------------------------------------
+
+static int DumpLockedResources(lua_State *L) {
+ Kernel *pKernel = Kernel::GetInstance();
+ BS_ASSERT(pKernel);
+ ResourceManager *pResource = pKernel->GetResourceManager();
+ BS_ASSERT(pResource);
+
+ pResource->DumpLockedResources();
+
+ return 0;
+}
+
+// -----------------------------------------------------------------------------
+
+static const char *RESOURCE_LIBRARY_NAME = "Resource";
+
+static const luaL_reg RESOURCE_FUNCTIONS[] = {
+ {"PrecacheResource", PrecacheResource},
+ {"ForcePrecacheResource", ForcePrecacheResource},
+ {"GetMaxMemoryUsage", GetMaxMemoryUsage},
+ {"SetMaxMemoryUsage", SetMaxMemoryUsage},
+ {"EmptyCache", EmptyCache},
+ {"IsLogCacheMiss", IsLogCacheMiss},
+ {"SetLogCacheMiss", SetLogCacheMiss},
+ {"DumpLockedResources", DumpLockedResources},
+ {0, 0}
+};
+
+// -----------------------------------------------------------------------------
+
+static int ReloadSlots(lua_State *L) {
+ PersistenceService::GetInstance().ReloadSlots();
+ lua_pushnil(L);
+ return 1;
+}
+
+// -----------------------------------------------------------------------------
+
+static int GetSlotCount(lua_State *L) {
+ lua_pushnumber(L, PersistenceService::GetInstance().GetSlotCount());
+ return 1;
+}
+
+// -----------------------------------------------------------------------------
+
+static int IsSlotOccupied(lua_State *L) {
+ lua_pushbooleancpp(L, PersistenceService::GetInstance().IsSlotOccupied(
+ static_cast<uint>(luaL_checknumber(L, 1)) - 1));
+ return 1;
+}
+
+// -----------------------------------------------------------------------------
+
+static int GetSavegameDirectory(lua_State *L) {
+ lua_pushstring(L, PersistenceService::GetInstance().GetSavegameDirectory().c_str());
+ return 1;
+}
+
+// -----------------------------------------------------------------------------
+
+static int IsSavegameCompatible(lua_State *L) {
+ lua_pushbooleancpp(L, PersistenceService::GetInstance().IsSavegameCompatible(
+ static_cast<uint>(luaL_checknumber(L, 1)) - 1));
+ return 1;
+}
+
+// -----------------------------------------------------------------------------
+
+static int GetSavegameDescription(lua_State *L) {
+ lua_pushstring(L, PersistenceService::GetInstance().GetSavegameDescription(
+ static_cast<uint>(luaL_checknumber(L, 1)) - 1).c_str());
+ return 1;
+}
+
+// -----------------------------------------------------------------------------
+
+static int GetSavegameFilename(lua_State *L) {
+ lua_pushstring(L, PersistenceService::GetInstance().GetSavegameFilename(static_cast<uint>(luaL_checknumber(L, 1)) - 1).c_str());
+ return 1;
+}
+
+// -----------------------------------------------------------------------------
+
+static int LoadGame(lua_State *L) {
+ lua_pushbooleancpp(L, PersistenceService::GetInstance().LoadGame(static_cast<uint>(luaL_checknumber(L, 1)) - 1));
+ return 1;
+}
+
+// -----------------------------------------------------------------------------
+
+static int SaveGame(lua_State *L) {
+ lua_pushbooleancpp(L, PersistenceService::GetInstance().SaveGame(static_cast<uint>(luaL_checknumber(L, 1)) - 1, luaL_checkstring(L, 2)));
+ return 1;
+}
+
+// -----------------------------------------------------------------------------
+
+static const char *PERSISTENCE_LIBRARY_NAME = "Persistence";
+
+static const luaL_reg PERSISTENCE_FUNCTIONS[] = {
+ {"ReloadSlots", ReloadSlots},
+ {"GetSlotCount", GetSlotCount},
+ {"IsSlotOccupied", IsSlotOccupied},
+ {"GetSavegameDirectory", GetSavegameDirectory},
+ {"IsSavegameCompatible", IsSavegameCompatible},
+ {"GetSavegameDescription", GetSavegameDescription},
+ {"GetSavegameFilename", GetSavegameFilename},
+ {"LoadGame", LoadGame},
+ {"SaveGame", SaveGame},
+ {0, 0}
+};
+
+// -----------------------------------------------------------------------------
+
+bool Kernel::_RegisterScriptBindings() {
+ ScriptEngine *pScript = static_cast<ScriptEngine *>(GetService("script"));
+ BS_ASSERT(pScript);
+ lua_State *L = static_cast<lua_State *>(pScript->getScriptObject());
+ BS_ASSERT(L);
+
+ if (!LuaBindhelper::addFunctionsToLib(L, KERNEL_LIBRARY_NAME, KERNEL_FUNCTIONS)) return false;
+ if (!LuaBindhelper::addFunctionsToLib(L, WINDOW_LIBRARY_NAME, WINDOW_FUNCTIONS)) return false;
+ if (!LuaBindhelper::addFunctionsToLib(L, RESOURCE_LIBRARY_NAME, RESOURCE_FUNCTIONS)) return false;
+ if (!LuaBindhelper::addFunctionsToLib(L, PERSISTENCE_LIBRARY_NAME, PERSISTENCE_FUNCTIONS)) return false;
+
+ return true;
+}
+
+} // End of namespace Sword25
diff --git a/engines/sword25/kernel/log.cpp b/engines/sword25/kernel/log.cpp
new file mode 100644
index 0000000000..259c02449f
--- /dev/null
+++ b/engines/sword25/kernel/log.cpp
@@ -0,0 +1,214 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+/*
+ * This code is based on Broken Sword 2.5 engine
+ *
+ * Copyright (c) Malte Thiesen, Daniel Queteschiner and Michael Elsdoerfer
+ *
+ * Licensed under GNU GPL v2
+ *
+ */
+
+#include "sword25/kernel/log.h"
+#include "base/version.h"
+#include "common/config-manager.h"
+#include "common/fs.h"
+
+namespace Sword25 {
+
+// Constants
+static const char *BF_LOG_FILENAME = "log.txt";
+static const size_t LOG_BUFFERSIZE = 1024 * 16;
+
+// Logging will take place only when it's activated
+#ifdef BS_ACTIVATE_LOGGING
+
+Common::WriteStream *BS_Log::_LogFile = NULL;
+bool BS_Log::_LineBegin = true;
+const char *BS_Log::_Prefix = NULL;
+const char *BS_Log::_File = NULL;
+int BS_Log::_Line = 0;
+bool BS_Log::_AutoNewline = false;
+Common::Array<BS_Log::LOG_LISTENER_CALLBACK> BS_Log::_LogListener;
+
+bool BS_Log::_CreateLog() {
+ // Open the log file
+ Common::FSNode dataDir(ConfMan.get("path"));
+ Common::FSNode file = dataDir.getChild(BF_LOG_FILENAME);
+
+ // Open the file for saving
+ _LogFile = file.createWriteStream();
+
+ if (_LogFile) {
+ // Add a title into the log file
+ Log("Broken Sword 2.5 Engine - Build: %s - %s - VersionID: %s\n", __DATE__, __TIME__, gScummVMFullVersion);
+ Log("-----------------------------------------------------------------------------------------------------\n");
+
+ return true;
+ }
+
+ // Log file could not be created
+ return false;
+}
+
+void BS_Log::_CloseLog() {
+ delete _LogFile;
+ _LogFile = NULL;
+}
+
+void BS_Log::Log(const char *Format, ...) {
+ char Message[LOG_BUFFERSIZE];
+
+ // Create the message
+ va_list ArgList;
+ va_start(ArgList, Format);
+ vsnprintf(Message, sizeof(Message), Format, ArgList);
+
+ // Log the message
+ _WriteLog(Message);
+
+ _FlushLog();
+}
+
+void BS_Log::LogPrefix(const char *Prefix, const char *Format, ...) {
+ char Message[LOG_BUFFERSIZE];
+ char ExtFormat[LOG_BUFFERSIZE];
+
+ // If the issue has ceased at the beginning of a new line, the new issue to begin with the prefix
+ ExtFormat[0] = 0;
+ if (_LineBegin) {
+ snprintf(ExtFormat, sizeof(ExtFormat), "%s%s: ", ExtFormat, Prefix);
+ _LineBegin = false;
+ }
+ // Format String pass line by line and each line with the initial prefix
+ for (;;) {
+ const char *NextLine = strstr(Format, "\n");
+ if (!NextLine || *(NextLine + strlen("\n")) == 0) {
+ snprintf(ExtFormat, sizeof(ExtFormat), "%s%s", ExtFormat, Format);
+ if (NextLine) _LineBegin = true;
+ break;
+ } else {
+ strncat(ExtFormat, Format, (NextLine - Format) + strlen("\n"));
+ snprintf(ExtFormat, sizeof(ExtFormat), "%s%s: ", ExtFormat, Prefix);
+ }
+
+ Format = NextLine + strlen("\n");
+ }
+
+ // Create message
+ va_list ArgList;
+ va_start(ArgList, Format);
+ vsnprintf(Message, sizeof(Message), ExtFormat, ArgList);
+
+ // Log the message
+ _WriteLog(Message);
+
+ _FlushLog();
+}
+
+void BS_Log::LogDecorated(const char *Format, ...) {
+ // Nachricht erzeugen
+ char Message[LOG_BUFFERSIZE];
+ va_list ArgList;
+ va_start(ArgList, Format);
+ vsnprintf(Message, sizeof(Message), Format, ArgList);
+
+ // Zweiten Prefix erzeugen, falls gewünscht
+ char SecondaryPrefix[1024];
+ if (_File && _Line)
+ snprintf(SecondaryPrefix, sizeof(SecondaryPrefix), "(file: %s, line: %d) - ", _File, _Line);
+
+ // Nachricht zeilenweise ausgeben und an jeden Zeilenanfang das Präfix setzen
+ char *MessageWalker = Message;
+ for (;;) {
+ char *NextLine = strstr(MessageWalker, "\n");
+ if (NextLine) {
+ *NextLine = 0;
+ if (_LineBegin) {
+ _WriteLog(_Prefix);
+ if (_File && _Line)
+ _WriteLog(SecondaryPrefix);
+ }
+ _WriteLog(MessageWalker);
+ _WriteLog("\n");
+ MessageWalker = NextLine + sizeof("\n") - 1;
+ _LineBegin = true;
+ } else {
+ if (_LineBegin) {
+ _WriteLog(_Prefix);
+ if (_File && _Line)
+ _WriteLog(SecondaryPrefix);
+ }
+ _WriteLog(MessageWalker);
+ _LineBegin = false;
+ break;
+ }
+ }
+
+ // Falls gewünscht, wird ans Ende der Nachricht automatisch ein Newline angehängt.
+ if (_AutoNewline) {
+ _WriteLog("\n");
+ _LineBegin = true;
+ }
+
+ // Pseudoparameter zurücksetzen
+ _Prefix = NULL;
+ _File = 0;
+ _Line = 0;
+ _AutoNewline = false;
+
+ _FlushLog();
+}
+
+int BS_Log::_WriteLog(const char *Message) {
+ if (!_LogFile) if (!_CreateLog()) return false;
+
+ Common::Array<LOG_LISTENER_CALLBACK>::iterator Iter = _LogListener.begin();
+ for (; Iter != _LogListener.end(); ++Iter)
+ (*Iter)(Message);
+
+ _LogFile->writeString(Message);
+
+ return true;
+}
+
+void BS_Log::_FlushLog() {
+ _LogFile->flush();
+}
+
+void (*BS_LogPtr)(const char *, ...) = BS_Log::Log;
+
+void BS_Log_C(const char *Message) {
+ BS_LogPtr(Message);
+}
+
+#else
+
+void BS_Log_C(const char *Message) {};
+
+#endif
+
+} // End of namespace Sword25
diff --git a/engines/sword25/kernel/log.h b/engines/sword25/kernel/log.h
new file mode 100644
index 0000000000..1fe9ff4ed6
--- /dev/null
+++ b/engines/sword25/kernel/log.h
@@ -0,0 +1,147 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+/*
+ * This code is based on Broken Sword 2.5 engine
+ *
+ * Copyright (c) Malte Thiesen, Daniel Queteschiner and Michael Elsdoerfer
+ *
+ * Licensed under GNU GPL v2
+ *
+ */
+
+#ifndef SWORD25_LOG_H
+#define SWORD25_LOG_H
+
+// Includes
+#include "common/array.h"
+#include "common/file.h"
+#include "sword25/kernel/common.h"
+
+namespace Sword25 {
+
+// Logging soll nur stattfinden wenn es aktiviert ist
+#ifdef BS_ACTIVATE_LOGGING
+
+// Logging-Makros
+#define BS_LOG BS_Log::SetPrefix(BS_LOG_PREFIX ": "), BS_Log::LogDecorated
+#define BS_LOGLN BS_Log::SetPrefix(BS_LOG_PREFIX ": "), BS_Log::SetAutoNewline(true), BS_Log::LogDecorated
+#define BS_LOG_WARNING BS_Log::SetPrefix(BS_LOG_PREFIX ": WARNING - "), BS_Log::LogDecorated
+#define BS_LOG_WARNINGLN BS_Log::SetPrefix(BS_LOG_PREFIX ": WARNING - "), BS_Log::SetAutoNewline(true), BS_Log::LogDecorated
+#define BS_LOG_ERROR BS_Log::SetPrefix(BS_LOG_PREFIX ": ERROR - "), BS_Log::LogDecorated
+#define BS_LOG_ERRORLN BS_Log::SetPrefix(BS_LOG_PREFIX ": ERROR - "), BS_Log::SetAutoNewline(true), BS_Log::LogDecorated
+#define BS_LOG_EXTERROR BS_Log::SetPrefix(BS_LOG_PREFIX ": ERROR "), BS_Log::SetFile(__FILE__), BS_Log::SetLine(__LINE__), BS_Log::LogDecorated
+#define BS_LOG_EXTERRORLN BS_Log::SetPrefix(BS_LOG_PREFIX ": ERROR "), BS_Log::SetFile(__FILE__), BS_Log::SetLine(__LINE__), BS_Log::SetAutoNewline(true), BS_Log::LogDecorated
+
+// Die Version der Logging-Klasse mit aktiviertem Logging
+class BS_Log {
+public:
+ static void Clear();
+ static void Log(const char *Format, ...);
+ static void LogPrefix(const char *Prefix, const char *Format, ...);
+ static void LogDecorated(const char *Format, ...);
+
+ static void SetPrefix(const char *Prefix) {
+ _Prefix = Prefix;
+ }
+ static void SetFile(const char *File) {
+ _File = File;
+ }
+ static void SetLine(int Line) {
+ _Line = Line;
+ }
+ static void SetAutoNewline(bool AutoNewline) {
+ _AutoNewline = AutoNewline;
+ }
+
+ typedef void (*LOG_LISTENER_CALLBACK)(const char *);
+ static void RegisterLogListener(LOG_LISTENER_CALLBACK Callback) {
+ _LogListener.push_back(Callback);
+ }
+ static bool IsListenerRegistered(LOG_LISTENER_CALLBACK Callback) {
+ Common::Array<LOG_LISTENER_CALLBACK>::iterator i;
+ for (i = _LogListener.begin(); i != _LogListener.end(); ++i) {
+ if (**i == Callback)
+ return true;
+ }
+ return false;
+ }
+ static void _CloseLog();
+
+private:
+ static Common::WriteStream *_LogFile;
+ static bool _LineBegin;
+ static const char *_Prefix;
+ static const char *_File;
+ static int _Line;
+ static bool _AutoNewline;
+ static Common::Array<LOG_LISTENER_CALLBACK> _LogListener;
+
+ static bool _CreateLog();
+
+ static int _WriteLog(const char *Message);
+ static void _FlushLog();
+};
+
+// Auxiliary function that allows to log C functions (needed for Lua).
+#define BS_Log_C error
+
+
+#else
+
+// Logging-Macros
+#define BS_LOG
+#define BS_LOGLN
+#define BS_LOG_WARNING
+#define BS_LOG_WARNINGLN
+#define BS_LOG_ERROR
+#define BS_LOG_ERRORLN
+#define BS_LOG_EXTERROR
+#define BS_LOG_EXTERRORLN
+
+// The version of the logging class with logging disabled
+class BS_Log {
+public:
+ // This version implements all the various methods as empty stubs
+ static void Log(const char *Text, ...) {};
+ static void LogPrefix(const char *Prefix, const char *Format, ...) {};
+ static void LogDecorated(const char *Format, ...) {};
+
+ static void SetPrefix(const char *Prefix) {};
+ static void SetFile(const char *File) {};
+ static void SetLine(int Line) {};
+ static void SetAutoNewline(bool AutoNewline) {};
+
+ typedef void (*LOG_LISTENER_CALLBACK)(const char *);
+ static void RegisterLogListener(LOG_LISTENER_CALLBACK Callback) {};
+};
+
+#define BS_Log_C error
+
+#endif
+
+} // End of namespace Sword25
+
+#endif
diff --git a/engines/sword25/kernel/objectregistry.h b/engines/sword25/kernel/objectregistry.h
new file mode 100644
index 0000000000..dc702f2d75
--- /dev/null
+++ b/engines/sword25/kernel/objectregistry.h
@@ -0,0 +1,175 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+/*
+ * This code is based on Broken Sword 2.5 engine
+ *
+ * Copyright (c) Malte Thiesen, Daniel Queteschiner and Michael Elsdoerfer
+ *
+ * Licensed under GNU GPL v2
+ *
+ */
+
+#ifndef SWORD25_OBJECTREGISTRY_H
+#define SWORD25_OBJECTREGISTRY_H
+
+#include "common/func.h"
+#include "common/hashmap.h"
+#include "sword25/kernel/bs_stdint.h"
+#include "sword25/kernel/common.h"
+
+namespace Sword25 {
+
+template<typename T>
+class ObjectRegistry {
+public:
+ ObjectRegistry() : _nextHandle(1) {}
+ virtual ~ObjectRegistry() {}
+
+ uint registerObject(T *objectPtr) {
+ // Null-Pointer können nicht registriert werden.
+ if (objectPtr == 0) {
+ logErrorLn("Cannot register a null pointer.");
+ return 0;
+ }
+
+ // Falls das Objekt bereits registriert wurde, wird eine Warnung ausgeben und das Handle zurückgeben.
+ uint handle = findHandleByPtr(objectPtr);
+ if (handle != 0) {
+ logWarningLn("Tried to register a object that was already registered.");
+ return handle;
+ }
+ // Ansonsten wird das Objekt in beide Maps eingetragen und das neue Handle zurückgeben.
+ else {
+ _handle2PtrMap[_nextHandle] = objectPtr;
+ _ptr2HandleMap[objectPtr] = _nextHandle;
+
+ return _nextHandle++;
+ }
+ }
+
+ uint registerObject(T *objectPtr, uint handle) {
+ // Null-Pointer und Null-Handle können nicht registriert werden.
+ if (objectPtr == 0 || handle == 0) {
+ logErrorLn("Cannot register a null pointer or a null handle.");
+ return 0;
+ }
+
+ // Falls das Objekt bereits registriert wurde, wird ein Fehler ausgegeben und 0 zurückgeben.
+ uint handleTest = findHandleByPtr(objectPtr);
+ if (handleTest != 0) {
+ logErrorLn("Tried to register a object that was already registered.");
+ return 0;
+ }
+ // Falls das Handle bereits vergeben ist, wird ein Fehler ausgegeben und 0 zurückgegeben.
+ else if (findPtrByHandle(handle) != 0) {
+ logErrorLn("Tried to register a handle that is already taken.");
+ return 0;
+ }
+ // Ansonsten wird das Objekt in beide Maps eingetragen und das gewünschte Handle zurückgeben.
+ else {
+ _handle2PtrMap[handle] = objectPtr;
+ _ptr2HandleMap[objectPtr] = handle;
+
+ // Falls das vergebene Handle größer oder gleich dem nächsten automatische vergebenen Handle ist, wird das nächste automatisch
+ // vergebene Handle erhöht.
+ if (handle >= _nextHandle)
+ _nextHandle = handle + 1;
+
+ return handle;
+ }
+ }
+
+ void deregisterObject(T *objectPtr) {
+ uint handle = findHandleByPtr(objectPtr);
+
+ if (handle != 0) {
+ // Registriertes Objekt aus beiden Maps entfernen.
+ _handle2PtrMap.erase(findHandleByPtr(objectPtr));
+ _ptr2HandleMap.erase(objectPtr);
+ } else {
+ logWarningLn("Tried to remove a object that was not registered.");
+ }
+ }
+
+ T *resolveHandle(uint handle) {
+ // Zum Handle gehöriges Objekt in der Hash-Map finden.
+ T *objectPtr = findPtrByHandle(handle);
+
+ // Pointer zurückgeben. Im Fehlerfall ist dieser 0.
+ return objectPtr;
+ }
+
+ uint resolvePtr(T *objectPtr) {
+ // Zum Pointer gehöriges Handle in der Hash-Map finden.
+ uint handle = findHandleByPtr(objectPtr);
+
+ // Handle zurückgeben. Im Fehlerfall ist dieses 0.
+ return handle;
+ }
+
+protected:
+ // FIXME: I'm not entirely sure my current hash function is legitimate
+ struct ClassPointer_EqualTo {
+ bool operator()(const T *x, const T *y) const {
+ return x == y;
+ }
+ };
+ struct ClassPointer_Hash {
+ uint operator()(const T *x) const {
+ return static_cast<uint>((int64)x % ((int64)1 << sizeof(uint)));
+ }
+ };
+
+ typedef Common::HashMap<uint, T *> HANDLE2PTR_MAP;
+ typedef Common::HashMap<T *, uint, ClassPointer_Hash, ClassPointer_EqualTo> PTR2HANDLE_MAP;
+
+ HANDLE2PTR_MAP _handle2PtrMap;
+ PTR2HANDLE_MAP _ptr2HandleMap;
+ uint _nextHandle;
+
+ T *findPtrByHandle(uint handle) {
+ // Zum Handle gehörigen Pointer finden.
+ typename HANDLE2PTR_MAP::const_iterator it = _handle2PtrMap.find(handle);
+
+ // Pointer zurückgeben, oder, falls keiner gefunden wurde, 0 zurückgeben.
+ return (it != _handle2PtrMap.end()) ? it->_value : 0;
+ }
+
+ uint findHandleByPtr(T *objectPtr) {
+ // Zum Pointer gehöriges Handle finden.
+ typename PTR2HANDLE_MAP::const_iterator it = _ptr2HandleMap.find(objectPtr);
+
+ // Handle zurückgeben, oder, falls keines gefunden wurde, 0 zurückgeben.
+ return (it != _ptr2HandleMap.end()) ? it->_value : 0;
+ }
+
+ virtual void logErrorLn(const char *message) const = 0;
+ virtual void logWarningLn(const char *message) const = 0;
+};
+
+} // End of namespace Sword25
+
+#endif
diff --git a/engines/sword25/kernel/outputpersistenceblock.cpp b/engines/sword25/kernel/outputpersistenceblock.cpp
new file mode 100644
index 0000000000..438fa7b222
--- /dev/null
+++ b/engines/sword25/kernel/outputpersistenceblock.cpp
@@ -0,0 +1,131 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+/*
+ * This code is based on Broken Sword 2.5 engine
+ *
+ * Copyright (c) Malte Thiesen, Daniel Queteschiner and Michael Elsdoerfer
+ *
+ * Licensed under GNU GPL v2
+ *
+ */
+
+#define BS_LOG_PREFIX "OUTPUTPERSISTENCEBLOCK"
+
+// -----------------------------------------------------------------------------
+// Includes
+// -----------------------------------------------------------------------------
+
+#include "sword25/kernel/outputpersistenceblock.h"
+
+// -----------------------------------------------------------------------------
+// Constants
+// -----------------------------------------------------------------------------
+
+namespace {
+const uint INITIAL_BUFFER_SIZE = 1024 * 64;
+}
+
+namespace Sword25 {
+
+// -----------------------------------------------------------------------------
+// Construction / Destruction
+// -----------------------------------------------------------------------------
+
+OutputPersistenceBlock::OutputPersistenceBlock() {
+ m_Data.reserve(INITIAL_BUFFER_SIZE);
+}
+
+// -----------------------------------------------------------------------------
+// Writing
+// -----------------------------------------------------------------------------
+
+void OutputPersistenceBlock::write(signed int Value) {
+ WriteMarker(SINT_MARKER);
+ Value = ConvertEndianessFromSystemToStorage(Value);
+ RawWrite(&Value, sizeof(Value));
+}
+
+// -----------------------------------------------------------------------------
+
+void OutputPersistenceBlock::write(uint Value) {
+ WriteMarker(UINT_MARKER);
+ Value = ConvertEndianessFromSystemToStorage(Value);
+ RawWrite(&Value, sizeof(Value));
+}
+
+// -----------------------------------------------------------------------------
+
+void OutputPersistenceBlock::write(float Value) {
+ WriteMarker(FLOAT_MARKER);
+ Value = ConvertEndianessFromSystemToStorage(Value);
+ RawWrite(&Value, sizeof(Value));
+}
+
+// -----------------------------------------------------------------------------
+
+void OutputPersistenceBlock::write(bool Value) {
+ WriteMarker(BOOL_MARKER);
+
+ uint UIntBool = Value ? 1 : 0;
+ UIntBool = ConvertEndianessFromSystemToStorage(UIntBool);
+ RawWrite(&UIntBool, sizeof(UIntBool));
+}
+
+// -----------------------------------------------------------------------------
+
+void OutputPersistenceBlock::write(const Common::String &String) {
+ WriteMarker(STRING_MARKER);
+
+ write(String.size());
+ RawWrite(String.c_str(), String.size());
+}
+
+// -----------------------------------------------------------------------------
+
+void OutputPersistenceBlock::write(const void *BufferPtr, size_t Size) {
+ WriteMarker(BLOCK_MARKER);
+
+ write(Size);
+ RawWrite(BufferPtr, Size);
+}
+
+// -----------------------------------------------------------------------------
+
+void OutputPersistenceBlock::WriteMarker(byte Marker) {
+ m_Data.push_back(Marker);
+}
+
+// -----------------------------------------------------------------------------
+
+void OutputPersistenceBlock::RawWrite(const void *DataPtr, size_t Size) {
+ if (Size > 0) {
+ uint OldSize = m_Data.size();
+ m_Data.resize(OldSize + Size);
+ memcpy(&m_Data[OldSize], DataPtr, Size);
+ }
+}
+
+} // End of namespace Sword25
diff --git a/engines/sword25/kernel/outputpersistenceblock.h b/engines/sword25/kernel/outputpersistenceblock.h
new file mode 100644
index 0000000000..154dbc9763
--- /dev/null
+++ b/engines/sword25/kernel/outputpersistenceblock.h
@@ -0,0 +1,78 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+/*
+ * This code is based on Broken Sword 2.5 engine
+ *
+ * Copyright (c) Malte Thiesen, Daniel Queteschiner and Michael Elsdoerfer
+ *
+ * Licensed under GNU GPL v2
+ *
+ */
+
+#ifndef SWORD25_OUTPUTPERSISTENCEBLOCK_H
+#define SWORD25_OUTPUTPERSISTENCEBLOCK_H
+
+// -----------------------------------------------------------------------------
+// Includes
+// -----------------------------------------------------------------------------
+
+#include "sword25/kernel/common.h"
+#include "sword25/kernel/persistenceblock.h"
+
+namespace Sword25 {
+
+// -----------------------------------------------------------------------------
+// Class declaration
+// -----------------------------------------------------------------------------
+
+class OutputPersistenceBlock : public PersistenceBlock {
+public:
+ OutputPersistenceBlock();
+
+ void write(signed int Value);
+ void write(uint Value);
+ void write(float Value);
+ void write(bool Value);
+ void write(const Common::String &String);
+ void write(const void *BufferPtr, size_t Size);
+
+ const void *GetData() const {
+ return &m_Data[0];
+ }
+ uint GetDataSize() const {
+ return m_Data.size();
+ }
+
+private:
+ void WriteMarker(byte Marker);
+ void RawWrite(const void *DataPtr, size_t Size);
+
+ Common::Array<byte> m_Data;
+};
+
+} // End of namespace Sword25
+
+#endif
diff --git a/engines/sword25/kernel/persistable.h b/engines/sword25/kernel/persistable.h
new file mode 100644
index 0000000000..fc314688d5
--- /dev/null
+++ b/engines/sword25/kernel/persistable.h
@@ -0,0 +1,53 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+/*
+ * This code is based on Broken Sword 2.5 engine
+ *
+ * Copyright (c) Malte Thiesen, Daniel Queteschiner and Michael Elsdoerfer
+ *
+ * Licensed under GNU GPL v2
+ *
+ */
+
+#ifndef SWORD25_PERSISTABLE_H
+#define SWORD25_PERSISTABLE_H
+
+namespace Sword25 {
+
+class OutputPersistenceBlock;
+class InputPersistenceBlock;
+
+class Persistable {
+public:
+ virtual ~Persistable() {};
+
+ virtual bool persist(OutputPersistenceBlock &writer) = 0;
+ virtual bool unpersist(InputPersistenceBlock &reader) = 0;
+};
+
+} // End of namespace Sword25
+
+#endif
diff --git a/engines/sword25/kernel/persistenceblock.h b/engines/sword25/kernel/persistenceblock.h
new file mode 100644
index 0000000000..1f043aa68a
--- /dev/null
+++ b/engines/sword25/kernel/persistenceblock.h
@@ -0,0 +1,133 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+/*
+ * This code is based on Broken Sword 2.5 engine
+ *
+ * Copyright (c) Malte Thiesen, Daniel Queteschiner and Michael Elsdoerfer
+ *
+ * Licensed under GNU GPL v2
+ *
+ */
+
+#ifndef SWORD25_PERSISTENCEBLOCK_H
+#define SWORD25_PERSISTENCEBLOCK_H
+
+// -----------------------------------------------------------------------------
+// Includes
+// -----------------------------------------------------------------------------
+
+#include "sword25/kernel/common.h"
+
+namespace Sword25 {
+
+// -----------------------------------------------------------------------------
+// Class definition
+// -----------------------------------------------------------------------------
+
+class PersistenceBlock {
+public:
+ static uint GetSInt32Size() {
+ return sizeof(signed int) + sizeof(byte);
+ }
+ static uint GetUInt32Size() {
+ return sizeof(uint) + sizeof(byte);
+ }
+ static uint GetFloat32Size() {
+ return sizeof(float) + sizeof(byte);
+ }
+ static uint GetBoolSize() {
+ return sizeof(byte) + sizeof(byte);
+ }
+ static uint GetStringSize(const Common::String &String) {
+ return static_cast<uint>(sizeof(uint) + String.size() + sizeof(byte));
+ }
+
+protected:
+ enum {
+ SINT_MARKER,
+ UINT_MARKER,
+ FLOAT_MARKER,
+ STRING_MARKER,
+ BOOL_MARKER,
+ BLOCK_MARKER
+ };
+
+ // -----------------------------------------------------------------------------
+ // Endianess Conversions
+ // -----------------------------------------------------------------------------
+ //
+ // Everything is stored in Little Endian
+ // Big Endian Systems will need to be byte swapped during both saving and reading of saved values
+ //
+
+ template<typename T>
+ static T ConvertEndianessFromSystemToStorage(T Value) {
+ if (IsBigEndian()) ReverseByteOrder(&Value);
+ return Value;
+ }
+
+ template<typename T>
+ static T ConvertEndianessFromStorageToSystem(T Value) {
+ if (IsBigEndian()) ReverseByteOrder(&Value);
+ return Value;
+ }
+
+private:
+ static bool IsBigEndian() {
+ uint Dummy = 1;
+ byte *DummyPtr = reinterpret_cast<byte *>(&Dummy);
+ return DummyPtr[0] == 0;
+ }
+
+ template<typename T>
+ static void Swap(T &One, T &Two) {
+ T Temp = One;
+ One = Two;
+ Two = Temp;
+ }
+
+ static void ReverseByteOrder(void *Ptr) {
+ // Reverses the byte order of the 32-bit word pointed to by Ptr
+ byte *CharPtr = static_cast<byte *>(Ptr);
+ Swap(CharPtr[0], CharPtr[3]);
+ Swap(CharPtr[1], CharPtr[2]);
+ }
+};
+
+// -----------------------------------------------------------------------------
+// Compile time asserts
+// -----------------------------------------------------------------------------
+
+#define CTASSERT(ex) typedef char ctassert_type[(ex) ? 1 : -1]
+CTASSERT(sizeof(byte) == 1);
+CTASSERT(sizeof(signed int) == 4);
+CTASSERT(sizeof(uint) == 4);
+CTASSERT(sizeof(float) == 4);
+#undef CTASSERT
+
+} // End of namespace Sword25
+
+#endif
diff --git a/engines/sword25/kernel/persistenceservice.cpp b/engines/sword25/kernel/persistenceservice.cpp
new file mode 100644
index 0000000000..871bc37e2a
--- /dev/null
+++ b/engines/sword25/kernel/persistenceservice.cpp
@@ -0,0 +1,465 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+/*
+ * This code is based on Broken Sword 2.5 engine
+ *
+ * Copyright (c) Malte Thiesen, Daniel Queteschiner and Michael Elsdoerfer
+ *
+ * Licensed under GNU GPL v2
+ *
+ */
+
+// -----------------------------------------------------------------------------
+// Includes
+// -----------------------------------------------------------------------------
+
+#include "common/fs.h"
+#include "common/savefile.h"
+#include "sword25/kernel/kernel.h"
+#include "sword25/kernel/persistenceservice.h"
+#include "sword25/kernel/inputpersistenceblock.h"
+#include "sword25/kernel/outputpersistenceblock.h"
+#include "sword25/kernel/filesystemutil.h"
+#include "sword25/gfx/graphicengine.h"
+#include "sword25/sfx/soundengine.h"
+#include "sword25/input/inputengine.h"
+#include "sword25/math/regionregistry.h"
+#include "sword25/script/script.h"
+#include <zlib.h>
+
+#define BS_LOG_PREFIX "PERSISTENCESERVICE"
+
+// -----------------------------------------------------------------------------
+// Constants and utility functions
+// -----------------------------------------------------------------------------
+
+namespace Sword25 {
+const char *SAVEGAME_EXTENSION = ".b25s";
+const char *SAVEGAME_DIRECTORY = "saves";
+const char *FILE_MARKER = "BS25SAVEGAME";
+const uint SLOT_COUNT = 18;
+const uint FILE_COPY_BUFFER_SIZE = 1024 * 10;
+const char *VERSIONID = "SCUMMVM1";
+
+// -------------------------------------------------------------------------
+
+Common::String GenerateSavegameFilename(uint slotID) {
+ char buffer[10];
+ sprintf(buffer, "%d%s", slotID, SAVEGAME_EXTENSION);
+ return Common::String(buffer);
+}
+
+// -------------------------------------------------------------------------
+
+Common::String GenerateSavegamePath(uint SlotID) {
+ Common::FSNode folder(PersistenceService::GetSavegameDirectory());
+
+ return folder.getChild(GenerateSavegameFilename(SlotID)).getPath();
+}
+
+// -------------------------------------------------------------------------
+
+Common::String FormatTimestamp(TimeDate Time) {
+ // In the original BS2.5 engine, this used a local object to show the date/time as as a string.
+ // For now in ScummVM it's being hardcoded to 'dd-MON-yyyy hh:mm:ss'
+ Common::String monthList[12] = {
+ "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
+ };
+ char buffer[100];
+ snprintf(buffer, 100, "%.2d-%s-%.4d %.2d:%.2d:%.2d",
+ Time.tm_mday, monthList[Time.tm_mon].c_str(), 1900 + Time.tm_year,
+ Time.tm_hour, Time.tm_min, Time.tm_sec
+ );
+
+ return Common::String(buffer);
+}
+
+// -------------------------------------------------------------------------
+
+Common::String LoadString(Common::InSaveFile *In, uint MaxSize = 999) {
+ Common::String Result;
+
+ char ch = (char)In->readByte();
+ while ((ch != '\0') && (ch != ' ')) {
+ Result += ch;
+ if (Result.size() >= MaxSize) break;
+ ch = (char)In->readByte();
+ }
+
+ return Result;
+}
+
+}
+
+namespace Sword25 {
+
+// -----------------------------------------------------------------------------
+// Private Implementation
+// -----------------------------------------------------------------------------
+
+struct SavegameInformation {
+ bool IsOccupied;
+ bool IsCompatible;
+ Common::String Description;
+ Common::String Filename;
+ uint GamedataLength;
+ uint GamedataOffset;
+ uint GamedataUncompressedLength;
+
+ SavegameInformation() {
+ Clear();
+ }
+
+ void Clear() {
+ IsOccupied = false;
+ IsCompatible = false;
+ Description = "";
+ Filename = "";
+ GamedataLength = 0;
+ GamedataOffset = 0;
+ GamedataUncompressedLength = 0;
+ }
+};
+
+struct PersistenceService::Impl {
+ SavegameInformation m_SavegameInformations[SLOT_COUNT];
+
+ // -----------------------------------------------------------------------------
+
+ Impl() {
+ ReloadSlots();
+ }
+
+ // -----------------------------------------------------------------------------
+
+ void ReloadSlots() {
+ // Über alle Spielstanddateien iterieren und deren Infos einlesen.
+ for (uint i = 0; i < SLOT_COUNT; ++i) {
+ ReadSlotSavegameInformation(i);
+ }
+ }
+
+ void ReadSlotSavegameInformation(uint SlotID) {
+ // Aktuelle Slotinformationen in den Ausgangszustand versetzen, er wird im Folgenden neu gefüllt.
+ SavegameInformation &CurSavegameInfo = m_SavegameInformations[SlotID];
+ CurSavegameInfo.Clear();
+
+ // Den Dateinamen für den Spielstand des Slots generieren.
+ Common::String Filename = GenerateSavegameFilename(SlotID);
+
+ // Try to open the savegame for loading
+ Common::SaveFileManager *sfm = g_system->getSavefileManager();
+ Common::InSaveFile *File = sfm->openForLoading(Filename);
+
+ if (File) {
+ // Read in the header
+ Common::String StoredMarker = LoadString(File);
+ Common::String StoredVersionID = LoadString(File);
+ Common::String gameDataLength = LoadString(File);
+ CurSavegameInfo.GamedataLength = atoi(gameDataLength.c_str());
+ Common::String gamedataUncompressedLength = LoadString(File);
+ CurSavegameInfo.GamedataUncompressedLength = atoi(gamedataUncompressedLength.c_str());
+
+ // If the header can be read in and is detected to be valid, we will have a valid file
+ if (StoredMarker == FILE_MARKER) {
+ // Der Slot wird als belegt markiert.
+ CurSavegameInfo.IsOccupied = true;
+ // Speichern, ob der Spielstand kompatibel mit der aktuellen Engine-Version ist.
+ CurSavegameInfo.IsCompatible = (StoredVersionID == Common::String(VERSIONID));
+ // Dateinamen des Spielstandes speichern.
+ CurSavegameInfo.Filename = GenerateSavegameFilename(SlotID);
+ // Die Beschreibung des Spielstandes besteht aus einer textuellen Darstellung des Änderungsdatums der Spielstanddatei.
+ CurSavegameInfo.Description = FormatTimestamp(FileSystemUtil::GetInstance().GetFileTime(Filename));
+ // Den Offset zu den gespeicherten Spieldaten innerhalb der Datei speichern.
+ // Dieses entspricht der aktuellen Position, da nach der letzten Headerinformation noch ein Leerzeichen als trenner folgt.
+ CurSavegameInfo.GamedataOffset = static_cast<uint>(File->pos());
+ }
+
+ delete File;
+ }
+ }
+};
+
+// -----------------------------------------------------------------------------
+// Construction / Destruction
+// -----------------------------------------------------------------------------
+
+PersistenceService &PersistenceService::GetInstance() {
+ static PersistenceService Instance;
+ return Instance;
+}
+
+// -----------------------------------------------------------------------------
+
+PersistenceService::PersistenceService() : m_impl(new Impl) {
+}
+
+// -----------------------------------------------------------------------------
+
+PersistenceService::~PersistenceService() {
+ delete m_impl;
+}
+
+// -----------------------------------------------------------------------------
+// Implementation
+// -----------------------------------------------------------------------------
+
+void PersistenceService::ReloadSlots() {
+ m_impl->ReloadSlots();
+}
+
+// -----------------------------------------------------------------------------
+
+uint PersistenceService::GetSlotCount() {
+ return SLOT_COUNT;
+}
+
+// -----------------------------------------------------------------------------
+
+Common::String PersistenceService::GetSavegameDirectory() {
+ Common::FSNode node(FileSystemUtil::GetInstance().GetUserdataDirectory());
+ Common::FSNode childNode = node.getChild(SAVEGAME_DIRECTORY);
+
+ // Try and return the path using the savegame subfolder. But if doesn't exist, fall back on the data directory
+ if (childNode.exists())
+ return childNode.getPath();
+
+ return node.getPath();
+}
+
+// -----------------------------------------------------------------------------
+
+namespace {
+bool CheckSlotID(uint SlotID) {
+ // Überprüfen, ob die Slot-ID zulässig ist.
+ if (SlotID >= SLOT_COUNT) {
+ BS_LOG_ERRORLN("Tried to access an invalid slot (%d). Only slot ids from 0 to %d are allowed.", SlotID, SLOT_COUNT - 1);
+ return false;
+ } else {
+ return true;
+ }
+}
+}
+
+// -----------------------------------------------------------------------------
+
+bool PersistenceService::IsSlotOccupied(uint SlotID) {
+ if (!CheckSlotID(SlotID)) return false;
+ return m_impl->m_SavegameInformations[SlotID].IsOccupied;
+}
+
+// -----------------------------------------------------------------------------
+
+bool PersistenceService::IsSavegameCompatible(uint SlotID) {
+ if (!CheckSlotID(SlotID)) return false;
+ return m_impl->m_SavegameInformations[SlotID].IsCompatible;
+}
+
+// -----------------------------------------------------------------------------
+
+Common::String &PersistenceService::GetSavegameDescription(uint SlotID) {
+ static Common::String EmptyString;
+ if (!CheckSlotID(SlotID)) return EmptyString;
+ return m_impl->m_SavegameInformations[SlotID].Description;
+}
+
+// -----------------------------------------------------------------------------
+
+Common::String &PersistenceService::GetSavegameFilename(uint SlotID) {
+ static Common::String EmptyString;
+ if (!CheckSlotID(SlotID)) return EmptyString;
+ return m_impl->m_SavegameInformations[SlotID].Filename;
+}
+
+// -----------------------------------------------------------------------------
+
+bool PersistenceService::SaveGame(uint SlotID, const Common::String &ScreenshotFilename) {
+ // Überprüfen, ob die Slot-ID zulässig ist.
+ if (SlotID >= SLOT_COUNT) {
+ BS_LOG_ERRORLN("Tried to save to an invalid slot (%d). Only slot ids form 0 to %d are allowed.", SlotID, SLOT_COUNT - 1);
+ return false;
+ }
+
+ // Dateinamen erzeugen.
+ Common::String Filename = GenerateSavegameFilename(SlotID);
+
+ // Sicherstellen, dass das Verzeichnis für die Spielstanddateien existiert.
+ FileSystemUtil::GetInstance().CreateDirectory(GetSavegameDirectory());
+
+ // Spielstanddatei öffnen und die Headerdaten schreiben.
+ Common::SaveFileManager *sfm = g_system->getSavefileManager();
+ Common::OutSaveFile *File = sfm->openForSaving(Filename);
+
+ File->writeString(FILE_MARKER);
+ File->writeByte(' ');
+ File->writeString(VERSIONID);
+ File->writeByte(' ');
+
+ if (File->err()) {
+ error("Unable to write header data to savegame file \"%s\".", Filename.c_str());
+ }
+
+ // Alle notwendigen Module persistieren.
+ OutputPersistenceBlock Writer;
+ bool Success = true;
+ Success &= Kernel::GetInstance()->GetScript()->persist(Writer);
+ Success &= RegionRegistry::getInstance().persist(Writer);
+ Success &= Kernel::GetInstance()->GetGfx()->persist(Writer);
+ Success &= Kernel::GetInstance()->GetSfx()->persist(Writer);
+ Success &= Kernel::GetInstance()->GetInput()->persist(Writer);
+ if (!Success) {
+ error("Unable to persist modules for savegame file \"%s\".", Filename.c_str());
+ }
+
+ // Daten komprimieren.
+ uLongf CompressedLength = Writer.GetDataSize() + (Writer.GetDataSize() + 500) / 1000 + 12;
+ Bytef *CompressionBuffer = new Bytef[CompressedLength];
+
+ if (compress2(&CompressionBuffer[0], &CompressedLength, reinterpret_cast<const Bytef *>(Writer.GetData()), Writer.GetDataSize(), 6) != Z_OK) {
+ error("Unable to compress savegame data in savegame file \"%s\".", Filename.c_str());
+ }
+
+ // Länge der komprimierten Daten und der unkomprimierten Daten in die Datei schreiben.
+ char sBuffer[10];
+ snprintf(sBuffer, 10, "%ld", CompressedLength);
+ File->writeString(sBuffer);
+ File->writeByte(' ');
+ snprintf(sBuffer, 10, "%u", Writer.GetDataSize());
+ File->writeString(sBuffer);
+ File->writeByte(' ');
+
+ // Komprimierte Daten in die Datei schreiben.
+ File->write(reinterpret_cast<char *>(&CompressionBuffer[0]), CompressedLength);
+ if (File->err()) {
+ error("Unable to write game data to savegame file \"%s\".", Filename.c_str());
+ }
+
+ // Get the screenshot
+ Common::MemoryReadStream *thumbnail = (static_cast<GraphicEngine *>(
+ Kernel::GetInstance()->GetService("gfx")))->getThumbnail();
+
+ if (thumbnail) {
+ byte *Buffer = new Byte[FILE_COPY_BUFFER_SIZE];
+ while (!thumbnail->eos()) {
+ int bytesRead = thumbnail->read(&Buffer[0], FILE_COPY_BUFFER_SIZE);
+ File->write(&Buffer[0], bytesRead);
+ }
+
+ delete[] Buffer;
+ } else {
+ BS_LOG_WARNINGLN("The screenshot file \"%s\" does not exist. Savegame is written without a screenshot.", Filename.c_str());
+ }
+
+ // Savegameinformationen für diesen Slot aktualisieren.
+ m_impl->ReadSlotSavegameInformation(SlotID);
+
+ File->finalize();
+ delete File;
+ delete[] CompressionBuffer;
+
+ // Erfolg signalisieren.
+ return true;
+}
+
+// -----------------------------------------------------------------------------
+
+bool PersistenceService::LoadGame(uint SlotID) {
+ Common::SaveFileManager *sfm = g_system->getSavefileManager();
+ Common::InSaveFile *File;
+
+ // Überprüfen, ob die Slot-ID zulässig ist.
+ if (SlotID >= SLOT_COUNT) {
+ BS_LOG_ERRORLN("Tried to load from an invalid slot (%d). Only slot ids form 0 to %d are allowed.", SlotID, SLOT_COUNT - 1);
+ return false;
+ }
+
+ SavegameInformation &CurSavegameInfo = m_impl->m_SavegameInformations[SlotID];
+
+ // Überprüfen, ob der Slot belegt ist.
+ if (!CurSavegameInfo.IsOccupied) {
+ BS_LOG_ERRORLN("Tried to load from an empty slot (%d).", SlotID);
+ return false;
+ }
+
+ // Überprüfen, ob der Spielstand im angegebenen Slot mit der aktuellen Engine-Version kompatibel ist.
+ // Im Debug-Modus wird dieser Test übersprungen. Für das Testen ist es hinderlich auf die Einhaltung dieser strengen Bedingung zu bestehen,
+ // da sich die Versions-ID bei jeder Codeänderung mitändert.
+#ifndef DEBUG
+ if (!CurSavegameInfo.IsCompatible) {
+ BS_LOG_ERRORLN("Tried to load a savegame (%d) that is not compatible with this engine version.", SlotID);
+ return false;
+ }
+#endif
+
+ byte *CompressedDataBuffer = new byte[CurSavegameInfo.GamedataLength];
+ byte *UncompressedDataBuffer = new Bytef[CurSavegameInfo.GamedataUncompressedLength];
+
+ File = sfm->openForLoading(GenerateSavegameFilename(SlotID));
+
+ File->seek(CurSavegameInfo.GamedataOffset);
+ File->read(reinterpret_cast<char *>(&CompressedDataBuffer[0]), CurSavegameInfo.GamedataLength);
+ if (File->err()) {
+ BS_LOG_ERRORLN("Unable to load the gamedata from the savegame file \"%s\".", CurSavegameInfo.Filename.c_str());
+ delete[] CompressedDataBuffer;
+ delete[] UncompressedDataBuffer;
+ return false;
+ }
+
+ // Spieldaten dekomprimieren.
+ uLongf UncompressedBufferSize = CurSavegameInfo.GamedataUncompressedLength;
+ if (uncompress(reinterpret_cast<Bytef *>(&UncompressedDataBuffer[0]), &UncompressedBufferSize,
+ reinterpret_cast<Bytef *>(&CompressedDataBuffer[0]), CurSavegameInfo.GamedataLength) != Z_OK) {
+ BS_LOG_ERRORLN("Unable to decompress the gamedata from savegame file \"%s\".", CurSavegameInfo.Filename.c_str());
+ delete[] UncompressedDataBuffer;
+ delete[] CompressedDataBuffer;
+ delete File;
+ return false;
+ }
+
+ InputPersistenceBlock Reader(&UncompressedDataBuffer[0], CurSavegameInfo.GamedataUncompressedLength);
+
+ // Einzelne Engine-Module depersistieren.
+ bool Success = true;
+ Success &= Kernel::GetInstance()->GetScript()->unpersist(Reader);
+ // Muss unbedingt nach Script passieren. Da sonst die bereits wiederhergestellten Regions per Garbage-Collection gekillt werden.
+ Success &= RegionRegistry::getInstance().unpersist(Reader);
+ Success &= Kernel::GetInstance()->GetGfx()->unpersist(Reader);
+ Success &= Kernel::GetInstance()->GetSfx()->unpersist(Reader);
+ Success &= Kernel::GetInstance()->GetInput()->unpersist(Reader);
+
+ delete[] CompressedDataBuffer;
+ delete[] UncompressedDataBuffer;
+ delete File;
+
+ if (!Success) {
+ BS_LOG_ERRORLN("Unable to unpersist the gamedata from savegame file \"%s\".", CurSavegameInfo.Filename.c_str());
+ return false;
+ }
+
+ return true;
+}
+
+} // End of namespace Sword25
diff --git a/engines/sword25/kernel/persistenceservice.h b/engines/sword25/kernel/persistenceservice.h
new file mode 100644
index 0000000000..d14185eac2
--- /dev/null
+++ b/engines/sword25/kernel/persistenceservice.h
@@ -0,0 +1,84 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+/*
+ * This code is based on Broken Sword 2.5 engine
+ *
+ * Copyright (c) Malte Thiesen, Daniel Queteschiner and Michael Elsdoerfer
+ *
+ * Licensed under GNU GPL v2
+ *
+ */
+
+#ifndef SWORD25_PERSISTENCESERVICE_H
+#define SWORD25_PERSISTENCESERVICE_H
+
+// -----------------------------------------------------------------------------
+// Includes
+// -----------------------------------------------------------------------------
+
+#include "sword25/kernel/common.h"
+
+namespace Sword25 {
+
+// -----------------------------------------------------------------------------
+// Class declaration
+// -----------------------------------------------------------------------------
+
+class PersistenceService {
+public:
+ PersistenceService();
+ virtual ~PersistenceService();
+
+ // -----------------------------------------------------------------------------
+ // Singleton Method
+ // -----------------------------------------------------------------------------
+
+ static PersistenceService &GetInstance();
+
+ // -----------------------------------------------------------------------------
+ // Interface
+ // -----------------------------------------------------------------------------
+
+ static uint GetSlotCount();
+ static Common::String GetSavegameDirectory();
+
+ void ReloadSlots();
+ bool IsSlotOccupied(uint SlotID);
+ bool IsSavegameCompatible(uint SlotID);
+ Common::String &GetSavegameDescription(uint SlotID);
+ Common::String &GetSavegameFilename(uint SlotID);
+
+ bool SaveGame(uint SlotID, const Common::String &ScreenshotFilename);
+ bool LoadGame(uint SlotID);
+
+private:
+ struct Impl;
+ Impl *m_impl;
+};
+
+} // End of namespace Sword25
+
+#endif
diff --git a/engines/sword25/kernel/resmanager.cpp b/engines/sword25/kernel/resmanager.cpp
new file mode 100644
index 0000000000..9e80f32f8d
--- /dev/null
+++ b/engines/sword25/kernel/resmanager.cpp
@@ -0,0 +1,336 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+/*
+ * This code is based on Broken Sword 2.5 engine
+ *
+ * Copyright (c) Malte Thiesen, Daniel Queteschiner and Michael Elsdoerfer
+ *
+ * Licensed under GNU GPL v2
+ *
+ */
+
+#include "sword25/kernel/resmanager.h"
+
+#include "sword25/kernel/resource.h"
+#include "sword25/kernel/resservice.h"
+#include "sword25/kernel/string.h"
+#include "sword25/package/packagemanager.h"
+
+namespace Sword25 {
+
+#define BS_LOG_PREFIX "RESOURCEMANAGER"
+
+ResourceManager::~ResourceManager() {
+ // Clear all unlocked resources
+ EmptyCache();
+
+ // All remaining resources are not released, so print warnings and release
+ Common::List<Resource *>::iterator Iter = m_Resources.begin();
+ for (; Iter != m_Resources.end(); ++Iter) {
+ BS_LOG_WARNINGLN("Resource \"%s\" was not released.", (*Iter)->getFileName().c_str());
+
+ // Set the lock count to zero
+ while ((*Iter)->GetLockCount() > 0) {
+ (*Iter)->release();
+ };
+
+ // Delete the resource
+ delete(*Iter);
+ }
+}
+
+/**
+ * Returns a resource by it's ordinal index. Returns NULL if any error occurs
+ * Note: This method is not optimised for speed and should be used only for debugging purposes
+ * @param Ord Ordinal number of the resource. Must be between 0 and GetResourceCount() - 1.
+ */
+Resource *ResourceManager::GetResourceByOrdinal(int Ord) const {
+ // Überprüfen ob der Index Ord innerhald der Listengrenzen liegt.
+ if (Ord < 0 || Ord >= GetResourceCount()) {
+ BS_LOG_ERRORLN("Resource ordinal (%d) out of bounds (0 - %d).", Ord, GetResourceCount() - 1);
+ return NULL;
+ }
+
+ // Liste durchlaufen und die Resource mit dem gewünschten Index zurückgeben.
+ int CurOrd = 0;
+ Common::List<Resource *>::const_iterator Iter = m_Resources.begin();
+ for (; Iter != m_Resources.end(); ++Iter, ++CurOrd) {
+ if (CurOrd == Ord)
+ return (*Iter);
+ }
+
+ // Die Ausführung sollte nie an diesem Punkt ankommen.
+ BS_LOG_EXTERRORLN("Execution reached unexpected point.");
+ return NULL;
+}
+
+/**
+ * Registers a RegisterResourceService. This method is the constructor of
+ * BS_ResourceService, and thus helps all resource services in the ResourceManager list
+ * @param pService Which service
+ */
+bool ResourceManager::RegisterResourceService(ResourceService *pService) {
+ if (!pService) {
+ BS_LOG_ERRORLN("Can't register NULL resource service.");
+ return false;
+ }
+
+ m_ResourceServices.push_back(pService);
+
+ return true;
+}
+
+/**
+ * Deletes resources as necessary until the specified memory limit is not being exceeded.
+ */
+void ResourceManager::DeleteResourcesIfNecessary() {
+ // If enough memory is available, or no resources are loaded, then the function can immediately end
+ if (m_KernelPtr->GetUsedMemory() < m_MaxMemoryUsage || m_Resources.empty()) return;
+
+ // Keep deleting resources until the memory usage of the process falls below the set maximum limit.
+ // The list is processed backwards in order to first release those resources who have been
+ // not been accessed for the longest
+ Common::List<Resource *>::iterator Iter = m_Resources.end();
+ do {
+ --Iter;
+
+ // The resource may be released only if it isn't locked
+ if ((*Iter)->GetLockCount() == 0) Iter = DeleteResource(*Iter);
+ } while (Iter != m_Resources.begin() && m_KernelPtr->GetUsedMemory() > m_MaxMemoryUsage);
+}
+
+/**
+ * Releases all resources that are not locked.
+ **/
+void ResourceManager::EmptyCache() {
+ // Scan through the resource list
+ Common::List<Resource *>::iterator Iter = m_Resources.begin();
+ while (Iter != m_Resources.end()) {
+ if ((*Iter)->GetLockCount() == 0) {
+ // Delete the resource
+ Iter = DeleteResource(*Iter);
+ } else
+ ++Iter;
+ }
+}
+
+/**
+ * Returns a requested resource. If any error occurs, returns NULL
+ * @param FileName Filename of resource
+ */
+Resource *ResourceManager::RequestResource(const Common::String &FileName) {
+ // Get the absolute path to the file
+ Common::String UniqueFileName = GetUniqueFileName(FileName);
+ if (UniqueFileName == "")
+ return NULL;
+
+ // Determine whether the resource is already loaded
+ // If the resource is found, it will be placed at the head of the resource list and returned
+ {
+ Resource *pResource = GetResource(UniqueFileName);
+ if (pResource) {
+ MoveToFront(pResource);
+ (pResource)->AddReference();
+ return pResource;
+ }
+ }
+
+ // The resource was not found, therefore, must not be loaded yet
+ if (m_LogCacheMiss) BS_LOG_WARNINGLN("\"%s\" was not precached.", UniqueFileName.c_str());
+
+ Resource *pResource;
+ if ((pResource = loadResource(UniqueFileName))) {
+ pResource->AddReference();
+ return pResource;
+ }
+
+ return NULL;
+}
+
+/**
+ * Loads a resource into the cache
+ * @param FileName The filename of the resource to be cached
+ * @param ForceReload Indicates whether the file should be reloaded if it's already in the cache.
+ * This is useful for files that may have changed in the interim
+ */
+bool ResourceManager::PrecacheResource(const Common::String &FileName, bool ForceReload) {
+ // Get the absolute path to the file
+ Common::String UniqueFileName = GetUniqueFileName(FileName);
+ if (UniqueFileName == "")
+ return false;
+
+ Resource *ResourcePtr = GetResource(UniqueFileName);
+
+ if (ForceReload && ResourcePtr) {
+ if (ResourcePtr->GetLockCount()) {
+ BS_LOG_ERRORLN("Could not force precaching of \"%s\". The resource is locked.", FileName.c_str());
+ return false;
+ } else {
+ DeleteResource(ResourcePtr);
+ ResourcePtr = 0;
+ }
+ }
+
+ if (!ResourcePtr && loadResource(UniqueFileName) == NULL) {
+ BS_LOG_ERRORLN("Could not precache \"%s\",", FileName.c_str());
+ return false;
+ }
+
+ return true;
+}
+
+/**
+ * Moves a resource to the top of the resource list
+ * @param pResource The resource
+ */
+void ResourceManager::MoveToFront(Resource *pResource) {
+ // Erase the resource from it's current position
+ m_Resources.erase(pResource->_iterator);
+ // Re-add the resource at the front of the list
+ m_Resources.push_front(pResource);
+ // Reset the resource iterator to the repositioned item
+ pResource->_iterator = m_Resources.begin();
+}
+
+/**
+ * Loads a resource and updates the m_UsedMemory total
+ *
+ * The resource must not already be loaded
+ * @param FileName The unique filename of the resource to be loaded
+ */
+Resource *ResourceManager::loadResource(const Common::String &fileName) {
+ // ResourceService finden, der die Resource laden kann.
+ for (uint i = 0; i < m_ResourceServices.size(); ++i) {
+ if (m_ResourceServices[i]->canLoadResource(fileName)) {
+ // If more memory is desired, memory must be released
+ DeleteResourcesIfNecessary();
+
+ // Load the resource
+ Resource *pResource;
+ if (!(pResource = m_ResourceServices[i]->loadResource(fileName))) {
+ BS_LOG_ERRORLN("Responsible service could not load resource \"%s\".", fileName.c_str());
+ return NULL;
+ }
+
+ // Add the resource to the front of the list
+ m_Resources.push_front(pResource);
+ pResource->_iterator = m_Resources.begin();
+
+ // Also store the resource in the hash table for quick lookup
+ m_ResourceHashTable[pResource->GetFileNameHash() % HASH_TABLE_BUCKETS].push_front(pResource);
+
+ return pResource;
+ }
+ }
+
+ BS_LOG_ERRORLN("Could not find a service that can load \"%s\".", fileName.c_str());
+ return NULL;
+}
+
+/**
+ * Returns the full path of a given resource filename.
+ * It will return an empty string if a path could not be created.
+*/
+Common::String ResourceManager::GetUniqueFileName(const Common::String &FileName) const {
+ // Get a pointer to the package manager
+ PackageManager *pPackage = (PackageManager *)m_KernelPtr->GetService("package");
+ if (!pPackage) {
+ BS_LOG_ERRORLN("Could not get package manager.");
+ return Common::String("");
+ }
+
+ // Absoluten Pfad der Datei bekommen und somit die Eindeutigkeit des Dateinamens sicherstellen
+ Common::String UniqueFileName = pPackage->getAbsolutePath(FileName);
+ if (UniqueFileName == "")
+ BS_LOG_ERRORLN("Could not create absolute file name for \"%s\".", FileName.c_str());
+
+ return UniqueFileName;
+}
+
+/**
+ * Deletes a resource, removes it from the lists, and updates m_UsedMemory
+ */
+Common::List<Resource *>::iterator ResourceManager::DeleteResource(Resource *pResource) {
+ // Remove the resource from the hash table
+ m_ResourceHashTable[pResource->GetFileNameHash() % HASH_TABLE_BUCKETS].remove(pResource);
+
+ Resource *pDummy = pResource;
+
+ // Delete the resource from the resource list
+ Common::List<Resource *>::iterator Result = m_Resources.erase(pResource->_iterator);
+
+ // Delete the resource
+ delete(pDummy);
+
+ // Return the iterator
+ return Result;
+}
+
+/**
+ * Returns a pointer to a loaded resource. If any error occurs, NULL will be returned.
+ * @param UniqueFileName The absolute path and filename
+ * Gibt einen Pointer auf die angeforderte Resource zurück, oder NULL, wenn die Resourcen nicht geladen ist.
+ */
+Resource *ResourceManager::GetResource(const Common::String &UniqueFileName) const {
+ // Determine whether the resource is already loaded
+ const Common::List<Resource *>& HashBucket = m_ResourceHashTable[
+ BS_String::GetHash(UniqueFileName) % HASH_TABLE_BUCKETS];
+ {
+ Common::List<Resource *>::const_iterator Iter = HashBucket.begin();
+ for (; Iter != HashBucket.end(); ++Iter) {
+ // Wenn die Resource gefunden wurde wird sie zurückgegeben.
+ if ((*Iter)->getFileName() == UniqueFileName)
+ return *Iter;
+ }
+ }
+
+ // Resource wurde nicht gefunden, ist also nicht geladen
+ return NULL;
+}
+
+/**
+ * Writes the names of all currently locked resources to the log file
+ */
+void ResourceManager::DumpLockedResources() {
+ for (Common::List<Resource *>::iterator Iter = m_Resources.begin(); Iter != m_Resources.end(); ++Iter) {
+ if ((*Iter)->GetLockCount() > 0) {
+ BS_LOGLN("%s", (*Iter)->getFileName().c_str());
+ }
+ }
+}
+
+/**
+ * Specifies the maximum amount of memory the engine is allowed to use.
+ * If this value is exceeded, resources will be unloaded to make room. This value is meant
+ * as a guideline, and not as a fixed boundary. It is not guaranteed not to be exceeded;
+ * the whole game engine may still use more memory than any amount specified.
+ */
+void ResourceManager::SetMaxMemoryUsage(uint MaxMemoryUsage) {
+ m_MaxMemoryUsage = MaxMemoryUsage;
+ DeleteResourcesIfNecessary();
+}
+
+} // End of namespace Sword25
diff --git a/engines/sword25/kernel/resmanager.h b/engines/sword25/kernel/resmanager.h
new file mode 100644
index 0000000000..578f121fec
--- /dev/null
+++ b/engines/sword25/kernel/resmanager.h
@@ -0,0 +1,193 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+/*
+ * This code is based on Broken Sword 2.5 engine
+ *
+ * Copyright (c) Malte Thiesen, Daniel Queteschiner and Michael Elsdoerfer
+ *
+ * Licensed under GNU GPL v2
+ *
+ */
+
+#ifndef SWORD25_RESOURCEMANAGER_H
+#define SWORD25_RESOURCEMANAGER_H
+
+// Includes
+#include "common/list.h"
+
+#include "sword25/kernel/common.h"
+
+namespace Sword25 {
+
+// Class definitions
+class ResourceService;
+class Resource;
+class Kernel;
+
+class ResourceManager {
+ friend class Kernel;
+
+public:
+ /**
+ * Returns a requested resource. If any error occurs, returns NULL
+ * @param FileName Filename of resource
+ */
+ Resource *RequestResource(const Common::String &FileName);
+
+ /**
+ * Loads a resource into the cache
+ * @param FileName The filename of the resource to be cached
+ * @param ForceReload Indicates whether the file should be reloaded if it's already in the cache.
+ * This is useful for files that may have changed in the interim
+ */
+ bool PrecacheResource(const Common::String &FileName, bool ForceReload = false);
+
+ /**
+ * Returns the number of loaded resources
+ */
+ int GetResourceCount() const {
+ return static_cast<int>(m_Resources.size());
+ }
+
+ /**
+ * Returns a resource by it's ordinal index. Returns NULL if any error occurs
+ * Note: This method is not optimised for speed and should be used only for debugging purposes
+ * @param Ord Ordinal number of the resource. Must be between 0 and GetResourceCount() - 1.
+ */
+ Resource *GetResourceByOrdinal(int Ord) const;
+
+ /**
+ * Registers a RegisterResourceService. This method is the constructor of
+ * BS_ResourceService, and thus helps all resource services in the ResourceManager list
+ * @param pService Which service
+ */
+ bool RegisterResourceService(ResourceService *pService);
+
+ /**
+ * Releases all resources that are not locked.
+ **/
+ void EmptyCache();
+
+ /**
+ * Returns the maximum memory the kernel has used
+ */
+ int GetMaxMemoryUsage() const {
+ return m_MaxMemoryUsage;
+ }
+
+ /**
+ * Specifies the maximum amount of memory the engine is allowed to use.
+ * If this value is exceeded, resources will be unloaded to make room. This value is meant
+ * as a guideline, and not as a fixed boundary. It is not guaranteed not to be exceeded;
+ * the whole game engine may still use more memory than any amount specified.
+ */
+ void SetMaxMemoryUsage(uint MaxMemoryUsage);
+
+ /**
+ * Specifies whether a warning is written to the log when a cache miss occurs.
+ * THe default value is "false".
+ */
+ bool IsLogCacheMiss() const {
+ return m_LogCacheMiss;
+ }
+
+ /**
+ * Sets whether warnings are written to the log if a cache miss occurs.
+ * @param Flag If "true", then future warnings will be logged
+ */
+ void SetLogCacheMiss(bool Flag) {
+ m_LogCacheMiss = Flag;
+ }
+
+ /**
+ * Writes the names of all currently locked resources to the log file
+ */
+ void DumpLockedResources();
+
+private:
+ /**
+ * Creates a new resource manager
+ * Only the BS_Kernel class can generate copies this class. Thus, the constructor is private
+ */
+ ResourceManager(Kernel *pKernel) :
+ m_KernelPtr(pKernel),
+ m_MaxMemoryUsage(100000000),
+ m_LogCacheMiss(false)
+ {};
+ virtual ~ResourceManager();
+
+ enum {
+ HASH_TABLE_BUCKETS = 256
+ };
+
+ /**
+ * Moves a resource to the top of the resource list
+ * @param pResource The resource
+ */
+ void MoveToFront(Resource *pResource);
+
+ /**
+ * Loads a resource and updates the m_UsedMemory total
+ *
+ * The resource must not already be loaded
+ * @param FileName The unique filename of the resource to be loaded
+ */
+ Resource *loadResource(const Common::String &fileName);
+
+ /**
+ * Returns the full path of a given resource filename.
+ * It will return an empty string if a path could not be created.
+ */
+ Common::String GetUniqueFileName(const Common::String &FileName) const;
+
+ /**
+ * Deletes a resource, removes it from the lists, and updates m_UsedMemory
+ */
+ Common::List<Resource *>::iterator DeleteResource(Resource *pResource);
+
+ /**
+ * Returns a pointer to a loaded resource. If any error occurs, NULL will be returned.
+ * @param UniqueFileName The absolute path and filename
+ * Gibt einen Pointer auf die angeforderte Resource zurück, oder NULL, wenn die Resourcen nicht geladen ist.
+ */
+ Resource *GetResource(const Common::String &UniqueFileName) const;
+
+ /**
+ * Deletes resources as necessary until the specified memory limit is not being exceeded.
+ */
+ void DeleteResourcesIfNecessary();
+
+ Kernel *m_KernelPtr;
+ uint m_MaxMemoryUsage;
+ Common::Array<ResourceService *> m_ResourceServices;
+ Common::List<Resource *> m_Resources;
+ Common::List<Resource *> m_ResourceHashTable[HASH_TABLE_BUCKETS];
+ bool m_LogCacheMiss;
+};
+
+} // End of namespace Sword25
+
+#endif
diff --git a/engines/sword25/kernel/resource.cpp b/engines/sword25/kernel/resource.cpp
new file mode 100644
index 0000000000..f6f4f13f68
--- /dev/null
+++ b/engines/sword25/kernel/resource.cpp
@@ -0,0 +1,60 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+/*
+ * This code is based on Broken Sword 2.5 engine
+ *
+ * Copyright (c) Malte Thiesen, Daniel Queteschiner and Michael Elsdoerfer
+ *
+ * Licensed under GNU GPL v2
+ *
+ */
+
+#include "sword25/kernel/resource.h"
+#include "sword25/kernel/string.h"
+#include "sword25/kernel/kernel.h"
+#include "sword25/package/packagemanager.h"
+
+namespace Sword25 {
+
+#define BS_LOG_PREFIX "RESOURCE"
+
+Resource::Resource(const Common::String &fileName, RESOURCE_TYPES type) :
+ _type(type),
+ _refCount(0) {
+ BS_ASSERT(Kernel::GetInstance()->GetService("package"));
+
+ _fileName = static_cast<PackageManager *>(Kernel::GetInstance()->GetService("package"))->getAbsolutePath(fileName);
+ _fileNameHash = BS_String::GetHash(fileName);
+}
+
+void Resource::release() {
+ if (_refCount) {
+ --_refCount;
+ } else
+ BS_LOG_WARNINGLN("Released unlocked resource \"%s\".", _fileName.c_str());
+}
+
+} // End of namespace Sword25
diff --git a/engines/sword25/kernel/resource.h b/engines/sword25/kernel/resource.h
new file mode 100644
index 0000000000..2a4d197138
--- /dev/null
+++ b/engines/sword25/kernel/resource.h
@@ -0,0 +1,118 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+/*
+ * This code is based on Broken Sword 2.5 engine
+ *
+ * Copyright (c) Malte Thiesen, Daniel Queteschiner and Michael Elsdoerfer
+ *
+ * Licensed under GNU GPL v2
+ *
+ */
+
+#ifndef SWORD25_RESOURCE_H
+#define SWORD25_RESOURCE_H
+
+#include "common/list.h"
+#include "common/str.h"
+#include "sword25/kernel/common.h"
+
+namespace Sword25 {
+
+class Kernel;
+class ResourceManager;
+
+class Resource {
+ friend class ResourceManager;
+
+public:
+ enum RESOURCE_TYPES {
+ TYPE_UNKNOWN,
+ TYPE_BITMAP,
+ TYPE_ANIMATION,
+ TYPE_SOUND,
+ TYPE_FONT
+ };
+
+ Resource(const Common::String &uniqueFileName, RESOURCE_TYPES type);
+
+ /**
+ * Prevents the resource from being released.
+ * @remarks This method allows a resource to be locked multiple times.
+ **/
+ void AddReference() {
+ ++_refCount;
+ }
+
+ /**
+ * Cancels a previous lock
+ * @remarks The resource can still be released more times than it was 'locked', although it is
+ * not recommended.
+ **/
+ void release();
+
+ /**
+ * Returns the current lock count for the resource
+ * @return The current lock count
+ **/
+ int GetLockCount() const {
+ return _refCount;
+ }
+
+ /**
+ * Returns the absolute path of the given resource
+ */
+ const Common::String &getFileName() const {
+ return _fileName;
+ }
+
+ /**
+ * Returns the hash of the filename of a resource
+ */
+ uint GetFileNameHash() const {
+ return _fileNameHash;
+ }
+
+ /**
+ * Returns a resource's type
+ */
+ uint GetType() const {
+ return _type;
+ }
+
+protected:
+ virtual ~Resource() {};
+
+private:
+ Common::String _fileName; ///< The absolute filename
+ uint _fileNameHash; ///< The hash value of the filename
+ uint _refCount; ///< The number of locks
+ uint _type; ///< The type of the resource
+ Common::List<Resource *>::iterator _iterator; ///< Points to the resource position in the LRU list
+};
+
+} // End of namespace Sword25
+
+#endif
diff --git a/engines/sword25/kernel/resservice.h b/engines/sword25/kernel/resservice.h
new file mode 100644
index 0000000000..d5961d52ae
--- /dev/null
+++ b/engines/sword25/kernel/resservice.h
@@ -0,0 +1,75 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+/*
+ * This code is based on Broken Sword 2.5 engine
+ *
+ * Copyright (c) Malte Thiesen, Daniel Queteschiner and Michael Elsdoerfer
+ *
+ * Licensed under GNU GPL v2
+ *
+ */
+
+#ifndef SWORD25_RESOURCESERVICE_H
+#define SWORD25_RESOURCESERVICE_H
+
+// Includes
+#include "sword25/kernel/common.h"
+#include "sword25/kernel/service.h"
+#include "sword25/kernel/kernel.h"
+#include "sword25/kernel/resmanager.h"
+
+namespace Sword25 {
+
+class Resource;
+
+class ResourceService : public Service {
+public:
+ ResourceService(Kernel *pKernel) : Service(pKernel) {
+ ResourceManager *pResource = pKernel->GetResourceManager();
+ pResource->RegisterResourceService(this);
+ }
+
+ virtual ~ResourceService() {}
+
+
+ /**
+ * Loads a resource
+ * @return Returns the resource if successful, otherwise NULL
+ */
+ virtual Resource *loadResource(const Common::String &fileName) = 0;
+
+ /**
+ * Checks whether the given name can be loaded by the resource service
+ * @param FileName Dateiname
+ * @return Returns true if the resource can be loaded.
+ */
+ virtual bool canLoadResource(const Common::String &fileName) = 0;
+
+};
+
+} // End of namespace Sword25
+
+#endif
diff --git a/engines/sword25/kernel/scummvmwindow.cpp b/engines/sword25/kernel/scummvmwindow.cpp
new file mode 100644
index 0000000000..35fd27a05c
--- /dev/null
+++ b/engines/sword25/kernel/scummvmwindow.cpp
@@ -0,0 +1,297 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+/*
+ * This code is based on Broken Sword 2.5 engine
+ *
+ * Copyright (c) Malte Thiesen, Daniel Queteschiner and Michael Elsdoerfer
+ *
+ * Licensed under GNU GPL v2
+ *
+ */
+
+#include "common/system.h"
+#include "engines/util.h"
+#include "graphics/pixelformat.h"
+#include "sword25/kernel/scummvmwindow.h"
+#include "sword25/kernel/kernel.h"
+#include "sword25/input/inputengine.h"
+
+#define BS_LOG_PREFIX "WIN32WINDOW"
+
+namespace Sword25 {
+
+bool ScummVMWindow::_ClassRegistered = false;
+
+// Constructor / Destructor
+// ------------------------
+ScummVMWindow::ScummVMWindow(int X, int Y, int Width, int Height, bool Visible) {
+ // Presume that init will fail
+ _InitSuccess = false;
+
+ // We don't support any window creation except at the origin 0,0
+ assert(X == 0);
+ assert(Y == 0);
+
+ if (!_ClassRegistered) {
+ // Nothing here currently
+
+ _ClassRegistered = true;
+ }
+
+ // Fenstersichtbarkeit setzen
+ SetVisible(Visible);
+
+ // Indicate success
+ _InitSuccess = true;
+ _WindowAlive = true;
+ _CloseWanted = false;
+}
+
+ScummVMWindow::~ScummVMWindow() {
+}
+
+// Get Methods
+// ------------
+int ScummVMWindow::GetX() {
+ return 0;
+}
+
+int ScummVMWindow::GetY() {
+ return 0;
+}
+
+int ScummVMWindow::GetClientX() {
+ return 0;
+}
+
+int ScummVMWindow::GetClientY() {
+ return 0;
+}
+
+int ScummVMWindow::GetWidth() {
+ return g_system->getWidth();
+}
+
+int ScummVMWindow::GetHeight() {
+ return g_system->getHeight();
+}
+
+Common::String ScummVMWindow::GetTitle() {
+ return Common::String("");
+}
+
+bool ScummVMWindow::IsVisible() {
+ return true;
+}
+
+bool ScummVMWindow::HasFocus() {
+ // FIXME: Is there a way to tell if ScummVM has the focus in Windowed mode?
+ return true;
+}
+
+uint ScummVMWindow::GetWindowHandle() {
+ return 0;
+}
+
+void ScummVMWindow::SetWindowAlive(bool v) {
+ _WindowAlive = v;
+}
+
+
+// Set Methods
+// ------------
+
+void ScummVMWindow::SetX(int X) {
+ // No implementation
+}
+
+void ScummVMWindow::SetY(int Y) {
+ // No implementation
+}
+
+void ScummVMWindow::SetWidth(int Width) {
+ // No implementation
+}
+
+void ScummVMWindow::SetHeight(int Height) {
+ // No implementation
+}
+
+void ScummVMWindow::SetVisible(bool Visible) {
+ // No implementation
+}
+
+void ScummVMWindow::SetTitle(const Common::String &Title) {
+ // No implementation
+}
+
+bool ScummVMWindow::ProcessMessages() {
+ // All messages are handled separately in the input manager. The only thing we
+ // need to do here is to keep returning whether the window/game is still alive
+ return _WindowAlive;
+}
+
+bool ScummVMWindow::WaitForFocus() {
+ // No implementation
+ return true;
+}
+
+// FIXME: Special keys detected here need to be moved into the Input Engine
+/*
+// Die WindowProc aller Fenster der Klasse
+LRESULT CALLBACK BS_ScummVMWindow::WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ switch(uMsg)
+ {
+ case WM_PAINT:
+ ValidateRect(hwnd, NULL);
+ break;
+
+ case WM_DESTROY:
+ // Das Fenster wird zerstört
+ PostQuitMessage(0);
+ break;
+
+ case WM_CLOSE:
+ {
+ BS_Window * WindowPtr = BS_Kernel::GetInstance()->GetWindow();
+ if (WindowPtr) {
+ WindowPtr->SetCloseWanted(true);
+ }
+ break;
+ }
+
+ case WM_KEYDOWN:
+ {
+ // Tastendrücke, die für das Inputmodul interessant sind, werden diesem gemeldet.
+ BS_InputEngine * InputPtr = BS_Kernel::GetInstance()->GetInput();
+
+ if (InputPtr)
+ {
+ switch (wParam)
+ {
+ case VK_RETURN:
+ InputPtr->ReportCommand(BS_InputEngine::KEY_COMMAND_ENTER);
+ break;
+
+ case VK_LEFT:
+ InputPtr->ReportCommand(BS_InputEngine::KEY_COMMAND_LEFT);
+ break;
+
+ case VK_RIGHT:
+ InputPtr->ReportCommand(BS_InputEngine::KEY_COMMAND_RIGHT);
+ break;
+
+ case VK_HOME:
+ InputPtr->ReportCommand(BS_InputEngine::KEY_COMMAND_HOME);
+ break;
+
+ case VK_END:
+ InputPtr->ReportCommand(BS_InputEngine::KEY_COMMAND_END);
+ break;
+
+ case VK_BACK:
+ InputPtr->ReportCommand(BS_InputEngine::KEY_COMMAND_BACKSPACE);
+ break;
+
+ case VK_TAB:
+ InputPtr->ReportCommand(BS_InputEngine::KEY_COMMAND_TAB);
+ break;
+
+ case VK_INSERT:
+ InputPtr->ReportCommand(BS_InputEngine::KEY_COMMAND_INSERT);
+ break;
+
+ case VK_DELETE:
+ InputPtr->ReportCommand(BS_InputEngine::KEY_COMMAND_DELETE);
+ break;
+ }
+ }
+ break;
+ }
+
+ case WM_KEYUP:
+ case WM_SYSKEYUP:
+ // Alle Tastendrücke werden ignoriert, damit Windows per DefWindowProc() nicht darauf
+ // reagieren kann und damit unerwartete Seiteneffekte auslöst.
+ // Zum Beispiel würden ALT und F10 Tastendrücke das "Menü" aktivieren und somit den Message-Loop zum Stillstand bringen.
+ break;
+
+ case WM_SYSCOMMAND:
+ // Verhindern, dass der Bildschirmschoner aktiviert wird, während das Spiel läuft
+ if (wParam != SC_SCREENSAVE) return DefWindowProc(hwnd,uMsg,wParam,lParam);
+ break;
+
+ case WM_CHAR:
+ {
+ byte theChar = static_cast<byte>(wParam & 0xff);
+
+ // Alle Zeichen, die keine Steuerzeichen sind, werden als Buchstaben dem Input-Service mitgeteilt.
+ if (theChar >= 32)
+ {
+ BS_InputEngine * InputPtr = BS_Kernel::GetInstance()->GetInput();
+ if (InputPtr) InputPtr->ReportCharacter(theChar);
+ }
+ }
+ break;
+
+ case WM_SETCURSOR:
+ {
+ // Der Systemcursor wird in der Client-Area des Fensters nicht angezeigt, jedoch in der nicht Client-Area, damit der Benutzer das Fenster wie gewohnt
+ // schließen und verschieben kann.
+
+ // Koordinaten des Cursors in der Client-Area berechnen.
+ POINT pt;
+ GetCursorPos(&pt);
+ ScreenToClient(hwnd, &pt);
+
+ // Feststellen, ob sich der Cursor in der Client-Area befindet.
+ // Get client rect
+ RECT rc;
+ GetClientRect(hwnd, &rc);
+
+ // See if cursor is in client area
+ if(PtInRect(&rc, pt))
+ // In der Client-Area keinen Cursor anzeigen.
+ SetCursor(NULL);
+ else
+ // Ausserhalb der Client-Area den Cursor anzeigen.
+ SetCursor(LoadCursor(NULL, IDC_ARROW));
+
+ return TRUE;
+ }
+ break;
+
+ default:
+ // Um alle anderen Vorkommnisse kümmert sich Windows
+ return DefWindowProc(hwnd,uMsg,wParam,lParam);
+ }
+
+ return 0;
+}
+*/
+
+} // End of namespace Sword25
diff --git a/engines/sword25/kernel/scummvmwindow.h b/engines/sword25/kernel/scummvmwindow.h
new file mode 100644
index 0000000000..2b5f514b7d
--- /dev/null
+++ b/engines/sword25/kernel/scummvmwindow.h
@@ -0,0 +1,85 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+/*
+ * This code is based on Broken Sword 2.5 engine
+ *
+ * Copyright (c) Malte Thiesen, Daniel Queteschiner and Michael Elsdoerfer
+ *
+ * Licensed under GNU GPL v2
+ *
+ */
+
+/*
+ BS_ScummVMWindow
+ ----------------
+ Implementation of the BS_Window Interfaces for ScummVM
+*/
+
+#ifndef SWORD25_SCUMMVMWINDOW_H
+#define SWORD25_SCUMMVMWINDOW_H
+
+// Includes
+#include "sword25/kernel/common.h"
+#include "sword25/kernel/window.h"
+
+namespace Sword25 {
+
+// Class definition
+class ScummVMWindow : public Window {
+public:
+ ScummVMWindow(int X, int Y, int Width, int Height, bool Visible);
+ virtual ~ScummVMWindow();
+
+ bool IsVisible();
+ void SetVisible(bool Visible);
+ int GetX();
+ void SetX(int X);
+ int GetY();
+ void SetY(int X);
+ int GetClientX();
+ int GetClientY();
+ int GetWidth();
+ void SetWidth(int Width);
+ int GetHeight();
+ void SetHeight(int Height);
+ Common::String GetTitle();
+ void SetWindowAlive(bool v);
+ void SetTitle(const Common::String &Title);
+ bool HasFocus();
+ uint GetWindowHandle();
+ bool WaitForFocus();
+ bool ProcessMessages();
+
+private:
+ static bool _ClassRegistered;
+ bool _WindowAlive;
+ int _ClientXDelta;
+ int _ClientYDelta;
+};
+
+} // End of namespace Sword25
+
+#endif
diff --git a/engines/sword25/kernel/service.h b/engines/sword25/kernel/service.h
new file mode 100644
index 0000000000..addcf50a08
--- /dev/null
+++ b/engines/sword25/kernel/service.h
@@ -0,0 +1,75 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+/*
+ * This code is based on Broken Sword 2.5 engine
+ *
+ * Copyright (c) Malte Thiesen, Daniel Queteschiner and Michael Elsdoerfer
+ *
+ * Licensed under GNU GPL v2
+ *
+ */
+
+/*
+ * BS_Service
+ * -------------
+ * This is the base class for all engine services.
+ * A serivce is an essential part of the engine, ex. the graphics system.
+ * This was intended to allow, for example, different plug in modules for
+ * different kinds of hardware and/or systems.
+ * The services are created at runtime via the kernel method NewService and NEVER with new.
+ *
+ * Autor: Malte Thiesen
+*/
+
+#ifndef SWORD25_SERVICE_H
+#define SWORD25_SERVICE_H
+
+// Includes
+#include "sword25/kernel/common.h"
+
+namespace Sword25 {
+
+// Klassendefinition
+class Kernel;
+
+class Service {
+private:
+ Kernel *_pKernel;
+
+protected:
+ Service(Kernel *pKernel) : _pKernel(pKernel) {};
+
+ Kernel *GetKernel() const {
+ return _pKernel;
+ }
+
+public:
+ virtual ~Service() {};
+};
+
+} // End of namespace Sword25
+
+#endif
diff --git a/engines/sword25/kernel/service_ids.h b/engines/sword25/kernel/service_ids.h
new file mode 100644
index 0000000000..5ffd83d743
--- /dev/null
+++ b/engines/sword25/kernel/service_ids.h
@@ -0,0 +1,80 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+/*
+ * This code is based on Broken Sword 2.5 engine
+ *
+ * Copyright (c) Malte Thiesen, Daniel Queteschiner and Michael Elsdoerfer
+ *
+ * Licensed under GNU GPL v2
+ *
+ */
+
+/*
+ * service_ids.h
+ * -------------
+ * This file lists all the services.
+ * EVERY new service needs to be entered here, otherwise it cannot be instantiated
+ * by pKernel->NewService(..)
+ *
+ * Autor: Malte Thiesen
+ */
+
+#ifndef SWORD25_SERVICE_IDS
+#define SWORD25_SERVICE_IDS
+
+#include "sword25/kernel/common.h"
+
+namespace Sword25 {
+
+Service *GraphicEngine_CreateObject(Kernel *pKernel);
+Service *PackageManager_CreateObject(Kernel *pKernel);
+Service *InputEngine_CreateObject(Kernel *pKernel);
+Service *SoundEngine_CreateObject(Kernel *pKernel);
+Service *LuaScriptEngine_CreateObject(Kernel *pKernel);
+Service *Geometry_CreateObject(Kernel *pKernel);
+Service *OggTheora_CreateObject(Kernel *pKernel);
+
+// Services are recorded in this table
+const BS_ServiceInfo BS_SERVICE_TABLE[] = {
+ // The first two parameters are the name of the superclass and service
+ // The third parameter is the static method of the class that creates an object
+ // of the class and returns it
+ // Example:
+ // BS_ServiceInfo("Superclass", "Service", CreateMethod)
+ BS_ServiceInfo("gfx", "opengl", GraphicEngine_CreateObject),
+ BS_ServiceInfo("package", "archiveFS", PackageManager_CreateObject),
+ BS_ServiceInfo("input", "winapi", InputEngine_CreateObject),
+ BS_ServiceInfo("sfx", "fmodex", SoundEngine_CreateObject),
+ BS_ServiceInfo("script", "lua", LuaScriptEngine_CreateObject),
+ BS_ServiceInfo("geometry", "std", Geometry_CreateObject),
+ BS_ServiceInfo("fmv", "oggtheora", OggTheora_CreateObject),
+};
+
+const uint BS_SERVICE_COUNT = sizeof(BS_SERVICE_TABLE) / sizeof(BS_ServiceInfo);
+
+} // End of namespace Sword25
+
+#endif
diff --git a/engines/sword25/kernel/string.h b/engines/sword25/kernel/string.h
new file mode 100644
index 0000000000..b701e2312b
--- /dev/null
+++ b/engines/sword25/kernel/string.h
@@ -0,0 +1,111 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+/*
+ * This code is based on Broken Sword 2.5 engine
+ *
+ * Copyright (c) Malte Thiesen, Daniel Queteschiner and Michael Elsdoerfer
+ *
+ * Licensed under GNU GPL v2
+ *
+ */
+
+#ifndef SWORD25_STRING
+#define SWORD25_STRING
+
+#include "common/str.h"
+
+namespace BS_String {
+
+inline uint GetHash(const Common::String &Str) {
+ uint Result = 0;
+
+ for (uint i = 0; i < Str.size(); i++)
+ Result = ((Result << 5) - Result) + Str[i];
+
+ return Result;
+}
+
+inline bool ToInt(const Common::String &Str, int &Result) {
+ Common::String::const_iterator Iter = Str.begin();
+
+ // Skip whitespaces
+ while (*Iter && (*Iter == ' ' || *Iter == '\t')) {
+ ++Iter;
+ }
+ if (Iter == Str.end()) return false;
+
+ // Read sign, if available
+ bool IsNegative = false;
+ if (*Iter == '-') {
+ IsNegative = true;
+ ++Iter;
+ } else if (*Iter == '+')
+ ++Iter;
+
+ // Skip whitespaces
+ while (*Iter && (*Iter == ' ' || *Iter == '\t')) {
+ ++Iter;
+ }
+ if (Iter == Str.end()) return false;
+
+ // Convert string to integer
+ Result = 0;
+ while (Iter != Str.end()) {
+ if (*Iter < '0' || *Iter > '9') {
+ while (*Iter && (*Iter == ' ' || *Iter == '\t')) {
+ ++Iter;
+ }
+ if (Iter != Str.end()) return false;
+ break;
+ }
+ Result = (Result * 10) + (*Iter - '0');
+ ++Iter;
+ }
+
+ if (IsNegative) Result = -Result;
+
+ return true;
+}
+
+inline bool ToBool(const Common::String &Str, bool &Result) {
+ if (Str == "true" || Str == "TRUE") {
+ Result = true;
+ return true;
+ } else if (Str == "false" || Str == "FALSE") {
+ Result = false;
+ return true;
+ }
+
+ return false;
+}
+
+inline void ToLower(Common::String &Str) {
+ Str.toLowercase();
+}
+
+} // End of namespace BS_String
+
+#endif
diff --git a/engines/sword25/kernel/window.cpp b/engines/sword25/kernel/window.cpp
new file mode 100644
index 0000000000..8d2dc309e7
--- /dev/null
+++ b/engines/sword25/kernel/window.cpp
@@ -0,0 +1,69 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+/*
+ * This code is based on Broken Sword 2.5 engine
+ *
+ * Copyright (c) Malte Thiesen, Daniel Queteschiner and Michael Elsdoerfer
+ *
+ * Licensed under GNU GPL v2
+ *
+ */
+
+#include "sword25/kernel/window.h"
+
+// Alle Implementationen von BS_Window müssen hier eingetragen werden
+#include "sword25/kernel/scummvmwindow.h"
+
+namespace Sword25 {
+
+// Erstellt ein Fenster des GUI des aktuellen Betriebssystems
+Window *Window::CreateBSWindow(int X, int Y, int Width, int Height, bool Visible) {
+ // Fenster erstellen
+ Window *pWindow = (Window *) new ScummVMWindow(X, Y, Width, Height, Visible);
+
+ // Falls das Fenster erfolgreich initialisiert wurde, wird ein Pointer auf das Fensterobjekt
+ // zurückgegeben
+ if (pWindow->_InitSuccess)
+ return pWindow;
+
+ // Ansonsten wird das Fensterobjekt zerstört und NULL zurückgegeben
+ delete pWindow;
+ return NULL;
+}
+
+// Gibt True zurück wenn das Fenster WM_CLOSE empfangen hat -
+// solange, bis RejectClose() aufgerufen wurde.
+bool Window::CloseWanted() {
+ bool result = _CloseWanted;
+ _CloseWanted = false;
+ return result;
+}
+
+void Window::SetCloseWanted(bool Wanted) {
+ _CloseWanted = Wanted;
+}
+
+} // End of namespace Sword25
diff --git a/engines/sword25/kernel/window.h b/engines/sword25/kernel/window.h
new file mode 100644
index 0000000000..aee23087cb
--- /dev/null
+++ b/engines/sword25/kernel/window.h
@@ -0,0 +1,177 @@
+/* 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.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+/*
+ * This code is based on Broken Sword 2.5 engine
+ *
+ * Copyright (c) Malte Thiesen, Daniel Queteschiner and Michael Elsdoerfer
+ *
+ * Licensed under GNU GPL v2
+ *
+ */
+
+/*
+ * BS_Window
+ * ---------
+ * Simple window class interface. This is being encapsulated in a class for
+ * reasons of portability.
+ *
+ * Autor: Malte Thiesen
+ */
+
+#ifndef SWORD25_WINDOW_H
+#define SWORD25_WINDOW_H
+
+// Includes
+#include "sword25/kernel/common.h"
+
+namespace Sword25 {
+
+// Class definitions
+
+/**
+ * A simple window class interface
+ *
+ * Windows are exclusively created by BS_Window::CreateBSWindow().
+ * BS_Windows selects the correct class for the environment.
+ */
+class Window {
+protected:
+ bool _InitSuccess;
+ bool _CloseWanted;
+
+public:
+ virtual ~Window() {};
+
+ /**
+ * Returns the visibility of the window.
+ */
+ virtual bool IsVisible() = 0;
+
+ /**
+ * Sets the visibility of the window
+ * @param Visible Specifies whether the window should be visible or hidden
+ */
+ virtual void SetVisible(bool Visible) = 0;
+ /**
+ * Returns the X position of the window
+ */
+ virtual int GetX() = 0;
+ /**
+ * Sets the X position of the window
+ * @paramX The new X position for the window, or -1 for centre aligned
+ */
+ virtual void SetX(int X) = 0;
+ /**
+ * Gets the Y position of the window
+ */
+ virtual int GetY() = 0;
+ /**
+ * Sets the Y position of the window
+ * @param Y The new Y position for the window, or -1 for centre aligned
+ */
+ virtual void SetY(int X) = 0;
+ /**
+ * Returns the X position of the window's client area
+ */
+ virtual int GetClientX() = 0;
+ /**
+ * Returns the Y position of the window's client area
+ */
+ virtual int GetClientY() = 0;
+ /**
+ * Returns the width of the window without the frame
+ */
+ virtual int GetWidth() = 0;
+ /**
+ * Sets the width of the window without the frame
+ */
+ virtual void SetWidth(int Width) = 0;
+ /**
+ * Gets the height of the window without the frame
+ */
+ virtual int GetHeight() = 0;
+ /**
+ * Sets the height of the window without the frame
+ */
+ virtual void SetHeight(int Height) = 0;
+ /**
+ * Returns the title of the window
+ */
+ virtual Common::String GetTitle() = 0;
+ /**
+ * Sets the title of the window
+ * @param Title The new window title
+ */
+ virtual void SetTitle(const Common::String &Title) = 0;
+ /**
+ * Handle the processing of any pending window messages. This method should be called
+ * during the main loop.
+ */
+ virtual bool ProcessMessages() = 0;
+ /**
+ * Pauses the applicaiton until the window has focus, or has been closed.
+ * Returns false if the window was closed.
+ */
+ virtual bool WaitForFocus() = 0;
+ /**
+ * Returns true if the window has focus, false otherwise.
+ */
+ virtual bool HasFocus() = 0;
+ /**
+ * Returns the system handle that represents the window. Note that any use of the handle
+ * will not be portable code.
+ */
+ virtual uint GetWindowHandle() = 0;
+
+ virtual void SetWindowAlive(bool v) = 0;
+
+ /**
+ * Specifies whether the window is wanted to be closed. This is used together with CloseWanted()
+ * to allow scripts to query when the main window should be closed, or the user is asking it to close
+ **/
+ void SetCloseWanted(bool Wanted);
+ /**
+ * Returns the previous value set in a call to SetCloseWanted.
+ * Note that calling this also resets the value back to false, until such time as the SetCloseWanted()
+ * method is called again.
+ **/
+ bool CloseWanted();
+
+ /**
+ * Creates a new window instance. Returns a pointer to the window, or NULL if the creation failed.
+ * Note: It is the responsibility of the client to free the pointer when done with it.
+ * @param X The X position of the window, or -1 for centre horizontal alignment
+ * @param Y The Y position of the window, or -1 for centre vertical alignment
+ * @param Width The width of the window without the frame
+ * @param Height The height of the window without the frame
+ * @param Visible Specifies whether window should be visible
+ */
+ static Window *CreateBSWindow(int X, int Y, int Width, int Height, bool Visible);
+};
+
+} // End of namespace Sword25
+
+#endif