diff options
Diffstat (limited to 'engines/sword25/sword25.cpp')
-rw-r--r-- | engines/sword25/sword25.cpp | 110 |
1 files changed, 90 insertions, 20 deletions
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 |