aboutsummaryrefslogtreecommitdiff
path: root/engines/sword25/sword25.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'engines/sword25/sword25.cpp')
-rw-r--r--engines/sword25/sword25.cpp110
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