diff options
Diffstat (limited to 'engines')
-rwxr-xr-x | engines/sword25/kernel/filesystemutil.h | 151 | ||||
-rwxr-xr-x | engines/sword25/main.cpp | 212 | ||||
-rw-r--r-- | engines/sword25/module.mk | 3 | ||||
-rw-r--r-- | engines/sword25/sword25.cpp | 110 | ||||
-rw-r--r-- | engines/sword25/sword25.h | 1 |
5 files changed, 166 insertions, 311 deletions
diff --git a/engines/sword25/kernel/filesystemutil.h b/engines/sword25/kernel/filesystemutil.h index 1835698d14..2c650e2af2 100755 --- a/engines/sword25/kernel/filesystemutil.h +++ b/engines/sword25/kernel/filesystemutil.h @@ -1,29 +1,33 @@ -// ----------------------------------------------------------------------------- -// This file is part of Broken Sword 2.5 -// Copyright (c) Malte Thiesen, Daniel Queteschiner and Michael Elsdörfer -// -// Broken Sword 2.5 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. -// -// Broken Sword 2.5 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 Broken Sword 2.5; if not, write to the Free Software -// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -// ----------------------------------------------------------------------------- +/* 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. -/* - Die Klasse BS_FileSystemUtil stellt einen Wrapper für dateisystemspezifische Operationen dar, die nicht über die C/C++ Bibliotheken - abgedeckt werden. + * 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. - Jede unterstützte Plattform muss dieses Interface implementieren und die Singleton-Methode BS_FileSystemUtil::GetInstance() - implementieren. -*/ + * 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$ + * + * + * 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 @@ -32,71 +36,62 @@ // Includes // ----------------------------------------------------------------------------- +#include "common/str.h" #include "sword25/kernel/common.h" #include "sword25/kernel/bs_stdint.h" -#include "sword25/kernel/memlog_off.h" -#include <string> -#include <vector> -#include <ctime> -#include "sword25/kernel/memlog_on.h" - // ----------------------------------------------------------------------------- -// Klassendefinition +// Class definitions // ----------------------------------------------------------------------------- class BS_FileSystemUtil { public: - static BS_FileSystemUtil & GetInstance(); + static BS_FileSystemUtil &GetInstance(); virtual ~BS_FileSystemUtil() {}; - /* - Diese Funktion gibt den Namen des Verzeichnisses zurück, in dem sämtliche Benutzerdaten gespeichert werden sollen. - - Dieses sind z.B. Screenshots, Spielstände, Konfigurationsdateien, Logdateien, ... - Unter Windows Vista ist dieses beispielsweise: C:\Users\Malte\Documents\Broken Sword 2.5 - Falls dieses Verzeichnis noch nicht existiert, wird es automatisch erstellt. - - @return Gibt den Namen des Verzeichnisses für Benutzerdaten zurück. - */ - virtual std::string GetUserdataDirectory() = 0; - /* - @return Gibt den Pfadtrenner zurück (z.B. \ unter Windows und / unter Linux). - */ - virtual std::string GetPathSeparator() = 0; - /* - @param Filename der Pfad zu einer Datei. - @return Gibt die Größe der angegebenen Datei zurück. Falls die Größe nicht bestimmt werden konnte, oder die Datei nicht existiert wird -1 zurückgegeben. - */ - virtual uint64_t GetFileSize(const std::string & Filename) = 0; - /* - @param Filename der Pfad zu einer Datei. - @return Gibt den Zeitstempel des Zeitpunktes zurück an dem die Datei zuletzt verändert wurde. Bei einem Fehler wird 0 zurückgegeben. - */ - virtual time_t GetFileTime(const std::string & Filename) = 0; - /* - @param Filename der Pfad zu einer Datei. - @return Gibt true zurück, wenn die Datei existiert. - */ - virtual bool FileExists(const std::string & Filename) = 0; - /* - Diese Funktion erstellt einen Verzeichnis mit sämtlichen Unterverzeichnissen. - - Wenn des Parameter "\b\c\d\e" ist und der Pfad "\b\c" bereits existiert, werden die Verzeichnisse - "d" und "e" erstellt. - - @param DirectoryName der Name des zu erstellenden Verzeichnisses. - @return Gibt true zurück, wenn die Verzeichnisse erstellt werden konnten, ansonsten false. - */ - virtual bool CreateDirectory(const std::string & DirectoryName) = 0; - /* - Erstellt eine Liste aller Dateinamen in einem Verzeichnis. - - @param Directory das zu durchsuchende Verzeichnis. - @return Gibt einen vector mit allen gefundenen Dateinamen zurück. - */ - virtual std::vector<std::string> GetFilesInDirectory(const std::string & Path) = 0; + /** + * 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 uint64_t GetFileSize(const Common::String &Filename) = 0; + /** + * @param Filename The path to a file. + * @return Returns the timestamp of the specified file. On error it returns 0 + */ + virtual time_t 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; + /** + * Creates a list of filenames in a given directory. + * @param Directory The directory to search + * @return Returns a vector containing all of the found filenames + */ + virtual Common::StringArray GetFilesInDirectory(const Common::String &Path) = 0; }; #endif diff --git a/engines/sword25/main.cpp b/engines/sword25/main.cpp deleted file mode 100755 index ae9b3d0a2d..0000000000 --- a/engines/sword25/main.cpp +++ /dev/null @@ -1,212 +0,0 @@ -// ----------------------------------------------------------------------------- -// This file is part of Broken Sword 2.5 -// Copyright (c) Malte Thiesen, Daniel Queteschiner and Michael Elsdörfer -// -// Broken Sword 2.5 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. -// -// Broken Sword 2.5 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 Broken Sword 2.5; if not, write to the Free Software -// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -// ----------------------------------------------------------------------------- - -// ----------------------------------------------------------------------------- -// Includes -// ----------------------------------------------------------------------------- - -#include <string> -#include <vector> -#include <algorithm> -#include <iostream> -using namespace std; - -#include "sword25/kernel/common.h" -#include "sword25/kernel/kernel.h" -#include "sword25/kernel/filesystemutil.h" -#include "sword25/script/script.h" -#include "sword25/package/packagemanager.h" - -#define BS_LOG_PREFIX "MAIN" - -// ----------------------------------------------------------------------------- - -namespace -{ - const char * const PACKAGE_MANAGER = "physfs"; - const char * const DEFAULT_SCRIPT_FILE = "/system/boot.lua"; - const char * const MOUNT_DIR_PARAMETER = "-mount-dir"; - - // ------------------------------------------------------------------------- - - void LogToStdout(const char * Message) - { - printf("%s", Message); - } - - // ------------------------------------------------------------------------- - - bool LoadPackages() - { - BS_PackageManager * PackageManagerPtr = reinterpret_cast<BS_PackageManager *>(BS_Kernel::GetInstance()->GetService("package")); - BS_ASSERT(PackageManagerPtr); - - // Das Hauptpaket laden. - if (!PackageManagerPtr->LoadPackage("data.b25c", "/")) return false; - - // Den Inhalt des Programmverzeichnisses bestimmen und alphabetisch sortieren. - vector<string> Filenames = BS_FileSystemUtil::GetInstance().GetFilesInDirectory("."); - sort(Filenames.begin(), Filenames.end()); - - // Alle Patch-Pakete identifizieren und mounten. - // Die Dateinamen der Patch-Pakete besitzen die Form: patch???.b25c, wobei die Fragezeichen Platzhalter für Ziffern sind. - // Da die Dateinamen sortiert wurden, werden Patches mit niedrigen Zahlen vor Patches mit hohen Zahlen gemounted. - // Dies ist wichtig, da neu gemountete Pakete vorhandene Dateien im virtuellen Dateisystem überschreiben, wenn sie - // gleichnamige Dateien beinhalten. - for (vector<string>::const_iterator it = Filenames.begin(); it != Filenames.end(); ++it) - { - const string & CurFilename = *it; - - // Ist aktuelle Datei ein Patch-Paket? - static const string PatchPattern = "patch???.b25c"; - if (CurFilename.size() == PatchPattern.size()) - { - // Pattern Zeichen für Zeichen mit dem Dateinamen vergleichen. - string::const_iterator PatchPatternIt = PatchPattern.begin(); - string::const_iterator CurFilenameIt = CurFilename.begin(); - for (; PatchPatternIt != PatchPattern.end(); ++PatchPatternIt, ++CurFilenameIt) - { - if (*PatchPatternIt == '?') - { - if (*CurFilenameIt < '0' || *CurFilenameIt > '9') break; - } - else - { - if (*PatchPatternIt != *CurFilenameIt) break; - } - } - - if (PatchPatternIt == PatchPattern.end()) - { - // Pattern stimmt, Datei muss gemountet werden. - if (!PackageManagerPtr->LoadPackage(CurFilename, "/")) return false; - } - } - } - - // Alle Sprach-Pakete identifizieren und mounten. - // Die Dateinamen der Sprach-Pakete besitzen die Form: lang_*.b25c (z.B. lang_de.b25c). - for (vector<string>::const_iterator it = Filenames.begin(); it != Filenames.end(); ++it) - { - const string & CurFilename = *it; - - static const string Prefix = "lang_"; - static const string Suffix = ".b25c"; - - if ((CurFilename.size() >= Prefix.size() && string(CurFilename.begin(), CurFilename.begin() + Prefix.size()) == Prefix) && // Präfix testen. - (CurFilename.size() >= Suffix.size() && string(CurFilename.end() - Suffix.size(), CurFilename.end()) == Suffix) && // Suffix testen. - (CurFilename.size() > Prefix.size() + Suffix.size())) // Sicherstellen, dass der Dateiname weitere Buchstaben zwischen Präfix und Suffix besitzt. - { - // Pattern stimmt, Datei muss gemountet werden. - if (!PackageManagerPtr->LoadPackage(CurFilename, "/")) return false; - } - } - - return true; - } -} - -// ----------------------------------------------------------------------------- - -bool AppStart(const vector<string> & CommandLineParameters) -{ - // Alle Lognachrichten werden auch auf die Standardausgabe ausgegeben. - BS_Log::RegisterLogListener(LogToStdout); - - // Kernel initialisieren. - if (!BS_Kernel::GetInstance()->GetInitSuccess()) - { - BS_LOG_ERRORLN("Kernel initialization failed."); - return false; - } - - // Package-Manager starten, damit die Packfiles geladen werden können. - BS_PackageManager * PackageManagerPtr = static_cast<BS_PackageManager *>(BS_Kernel::GetInstance()->NewService("package", PACKAGE_MANAGER)); - if (!PackageManagerPtr) - { - BS_LOG_ERRORLN("Packagemanager initialization failed."); - return false; - } - - // Packages laden oder das aktuelle Verzeichnis mounten, wenn das über Kommandozeile angefordert wurde. - if (find(CommandLineParameters.begin(), CommandLineParameters.end(), MOUNT_DIR_PARAMETER) != CommandLineParameters.end()) - { - if (!PackageManagerPtr->LoadDirectoryAsPackage(".", "/")) return false; - } - else - { - if (!LoadPackages()) return false; - } - - // Einen Pointer auf den Skript-Engine holen. - BS_ScriptEngine * ScriptPtr = static_cast<BS_ScriptEngine *>(BS_Kernel::GetInstance()->GetService("script")); - if (!ScriptPtr) - { - BS_LOG_ERRORLN("Skript intialization failed."); - return false; - } - - // Die Kommandozeilen-Parameter der Skriptumgebung zugänglich machen. - ScriptPtr->SetCommandLine(CommandLineParameters); - - return true; -} - -// ----------------------------------------------------------------------------- - -bool AppEnd() -{ - // Den Kernel herunterfahren und alle Subsysteme deinitialisieren. - BS_Kernel::DeleteInstance(); - - return true; -} - -// ----------------------------------------------------------------------------- - -bool AppMain() -{ - // Das Hauptskript starten. Dieses Skript lädt alle anderen Skripte und startet das eigentliche Spiel. - BS_ScriptEngine * ScriptPtr = static_cast<BS_ScriptEngine *>(BS_Kernel::GetInstance()->GetService("script")); - BS_ASSERT(ScriptPtr); - ScriptPtr->ExecuteFile(DEFAULT_SCRIPT_FILE); - - return true; -} - -bool main2(int argc, char ** argv) -{ - // Engine initialisieren. - vector<string> CommandLineParameters; - for (int i = 0; i < argc; ++i) CommandLineParameters.push_back(string(argv[i])); - if (!AppStart(CommandLineParameters)) - { - warning("A fatal error occured during engine startup."); - AppEnd(); - return 1; - } - - // Engine starten. - bool RunSuccess = AppMain(); - - // Engine deinitialisieren. - bool DeinitSuccess = AppEnd(); - - return (RunSuccess && DeinitSuccess) ? 0 : 1; -} diff --git a/engines/sword25/module.mk b/engines/sword25/module.mk index 30c5966803..3a853c9bc2 100644 --- a/engines/sword25/module.mk +++ b/engines/sword25/module.mk @@ -1,7 +1,8 @@ MODULE := engines/sword25 MODULE_OBJS := \ - main.o \ + detection.o \ + sword25.o \ fmv/movieplayer.o \ fmv/movieplayer_script.o \ fmv/oggtheora/audiobuffer.o \ diff --git a/engines/sword25/sword25.cpp b/engines/sword25/sword25.cpp index 305cbc402f..a301ac833f 100644 --- a/engines/sword25/sword25.cpp +++ b/engines/sword25/sword25.cpp @@ -27,12 +27,20 @@ #include "engines/util.h" #include "sword25/sword25.h" -#include "kernel/kernel.h" +#include "sword25/kernel/filesystemutil.h" +#include "sword25/kernel/kernel.h" +#include "sword25/package/packagemanager.h" +#include "sword25/script/script.h" namespace Sword25 { #define BS_LOG_PREFIX "MAIN" +const char * const PACKAGE_MANAGER = "physfs"; +const char * const DEFAULT_SCRIPT_FILE = "/system/boot.lua"; +const char * const MOUNT_DIR_PARAMETER = "-mount-dir"; + + void LogToStdout(const char *Message) { warning(Message); } @@ -63,54 +71,54 @@ Common::Error Sword25Engine::run() { } bool Sword25Engine::AppStart(const Common::StringArray &CommandParameters) { - // Alle Lognachrichten werden auch auf die Standardausgabe ausgegeben. + // All log messages will be sent to StdOut BS_Log::RegisterLogListener(LogToStdout); - // Kernel initialisieren. - if (!BS_Kernel::GetInstance()->GetInitSuccess()) - { + // Kernel initialisation + if (!BS_Kernel::GetInstance()->GetInitSuccess()) { BS_LOG_ERRORLN("Kernel initialization failed."); return false; } -/* + // Package-Manager starten, damit die Packfiles geladen werden können. - BS_PackageManager * PackageManagerPtr = static_cast<BS_PackageManager *>(BS_Kernel::GetInstance()->NewService("package", PACKAGE_MANAGER)); - if (!PackageManagerPtr) - { + BS_PackageManager *PackageManagerPtr = static_cast<BS_PackageManager *>(BS_Kernel::GetInstance()->NewService("package", PACKAGE_MANAGER)); + if (!PackageManagerPtr) { BS_LOG_ERRORLN("Packagemanager initialization failed."); return false; } // Packages laden oder das aktuelle Verzeichnis mounten, wenn das über Kommandozeile angefordert wurde. - if (find(CommandLineParameters.begin(), CommandLineParameters.end(), MOUNT_DIR_PARAMETER) != CommandLineParameters.end()) - { + if (find(CommandParameters.begin(), CommandParameters.end(), MOUNT_DIR_PARAMETER) != CommandParameters.end()) { if (!PackageManagerPtr->LoadDirectoryAsPackage(".", "/")) return false; - } - else - { + } else { if (!LoadPackages()) return false; } // Einen Pointer auf den Skript-Engine holen. - BS_ScriptEngine * ScriptPtr = static_cast<BS_ScriptEngine *>(BS_Kernel::GetInstance()->GetService("script")); - if (!ScriptPtr) - { + BS_ScriptEngine *ScriptPtr = static_cast<BS_ScriptEngine *>(BS_Kernel::GetInstance()->GetService("script")); + if (!ScriptPtr) { BS_LOG_ERRORLN("Skript intialization failed."); return false; } // Die Kommandozeilen-Parameter der Skriptumgebung zugänglich machen. - ScriptPtr->SetCommandLine(CommandLineParameters); -*/ + ScriptPtr->SetCommandLine(CommandParameters); return true; } bool Sword25Engine::AppMain() { - return false; + // The main script start. This script loads all the other scripts and starts the actual game. + BS_ScriptEngine * ScriptPtr = static_cast<BS_ScriptEngine *>(BS_Kernel::GetInstance()->GetService("script")); + BS_ASSERT(ScriptPtr); + ScriptPtr->ExecuteFile(DEFAULT_SCRIPT_FILE); + + return true; } bool Sword25Engine::AppEnd() { + // The kernel is shutdown, and un-initialises all subsystems + BS_Kernel::DeleteInstance(); // Free the log file if it was used BS_Log::_CloseLog(); @@ -118,4 +126,66 @@ bool Sword25Engine::AppEnd() { return false; } +bool Sword25Engine::LoadPackages() { + BS_PackageManager *PackageManagerPtr = reinterpret_cast<BS_PackageManager *>(BS_Kernel::GetInstance()->GetService("package")); + BS_ASSERT(PackageManagerPtr); + + // Load the main package + if (!PackageManagerPtr->LoadPackage("data.b25c", "/")) return false; + + // Get the contents of the main program directory and sort them alphabetically + Common::StringArray Filenames = BS_FileSystemUtil::GetInstance().GetFilesInDirectory("."); + Common::sort(Filenames.begin(), Filenames.end()); + + // Identity all patch packages + // The filename of patch packages must have the form patch??.b25c, with the question marks + // are placeholders for numbers. + // Since the filenames have been sorted, patches are mounted with low numbers first, through + // to ones with high numbers. This is important, because newly mount packages overwrite + // existing files in the virtual file system, if they include files with the same name. + for (Common::StringArray::const_iterator it = Filenames.begin(); it != Filenames.end(); ++it) { + const Common::String &CurFilename = *it; + + // Is the current file a patch package? + static const Common::String PatchPattern = "patch???.b25c"; + if (CurFilename.size() == PatchPattern.size()) { + // Check the file against the patch pattern character by character + Common::String::const_iterator PatchPatternIt = PatchPattern.begin(); + Common::String::const_iterator CurFilenameIt = CurFilename.begin(); + for (; PatchPatternIt != PatchPattern.end(); ++PatchPatternIt, ++CurFilenameIt) { + if (*PatchPatternIt == '?') { + if (*CurFilenameIt < '0' || *CurFilenameIt > '9') break; + } else { + if (*PatchPatternIt != *CurFilenameIt) break; + } + } + + if (PatchPatternIt == PatchPattern.end()) { + // The pattern fits, so the file should be mounted + if (!PackageManagerPtr->LoadPackage(CurFilename, "/")) return false; + } + } + } + + // Identity and mount all language packages + // The filename of the packages have the form lang_*.b25c (eg. lang_de.b25c) + for (Common::StringArray::const_iterator it = Filenames.begin(); it != Filenames.end(); ++it) { + const Common::String &CurFilename = *it; + + static const Common::String Prefix = "lang_"; + static const Common::String Suffix = ".b25c"; + + // Make sure the filename prefix and suffix has characters between them + if ((CurFilename.size() >= Prefix.size() && Common::String(CurFilename.begin(), CurFilename.begin() + Prefix.size()) == Prefix) && // Prefix test + (CurFilename.size() >= Suffix.size() && Common::String(CurFilename.end() - Suffix.size(), CurFilename.end()) == Suffix) && // Suffix test + (CurFilename.size() > Prefix.size() + Suffix.size())) + { + // Pattern matches - the file should be mounted + if (!PackageManagerPtr->LoadPackage(CurFilename, "/")) return false; + } + } + + return true; +} + } // End of namespace Sword25 diff --git a/engines/sword25/sword25.h b/engines/sword25/sword25.h index c440a5f58f..5b29a750f2 100644 --- a/engines/sword25/sword25.h +++ b/engines/sword25/sword25.h @@ -55,6 +55,7 @@ private: bool AppMain(); bool AppEnd(); + bool LoadPackages(); protected: virtual Common::Error run(); void shutdown(); |