diff options
author | Paul Gilbert | 2014-12-23 15:49:35 +1100 |
---|---|---|
committer | Paul Gilbert | 2014-12-23 15:49:35 +1100 |
commit | d0225f753274d9a04045a14dfe9a1b1b8aeae371 (patch) | |
tree | 3e03af1c569748f9c4a3aa982643d835d7572d75 | |
parent | 7cb18f8e7ac47e8c8c0b738401534ec0b99c2507 (diff) | |
download | scummvm-rg350-d0225f753274d9a04045a14dfe9a1b1b8aeae371.tar.gz scummvm-rg350-d0225f753274d9a04045a14dfe9a1b1b8aeae371.tar.bz2 scummvm-rg350-d0225f753274d9a04045a14dfe9a1b1b8aeae371.zip |
XEEN: Initial commit
-rw-r--r-- | engines/xeen/configure.engine | 3 | ||||
-rw-r--r-- | engines/xeen/debugger.cpp | 56 | ||||
-rw-r--r-- | engines/xeen/debugger.h | 44 | ||||
-rw-r--r-- | engines/xeen/detection.cpp | 183 | ||||
-rw-r--r-- | engines/xeen/detection_tables.h | 48 | ||||
-rw-r--r-- | engines/xeen/module.mk | 13 | ||||
-rw-r--r-- | engines/xeen/xeen.cpp | 209 | ||||
-rw-r--r-- | engines/xeen/xeen.h | 153 |
8 files changed, 709 insertions, 0 deletions
diff --git a/engines/xeen/configure.engine b/engines/xeen/configure.engine new file mode 100644 index 0000000000..489254f269 --- /dev/null +++ b/engines/xeen/configure.engine @@ -0,0 +1,3 @@ +# This file is included from the main "configure" script +# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps] +add_engine xeen "World of Xeen" no diff --git a/engines/xeen/debugger.cpp b/engines/xeen/debugger.cpp new file mode 100644 index 0000000000..0642498749 --- /dev/null +++ b/engines/xeen/debugger.cpp @@ -0,0 +1,56 @@ +/* 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. + * + */ + +#include "common/file.h" +#include "xeen/xeen.h" +#include "xeen/debugger.h" + +namespace Xeen { + +static int strToInt(const char *s) { + if (!*s) + // No string at all + return 0; + else if (toupper(s[strlen(s) - 1]) != 'H') + // Standard decimal string + return atoi(s); + + // Hexadecimal string + uint tmp = 0; + int read = sscanf(s, "%xh", &tmp); + if (read < 1) + error("strToInt failed on string \"%s\"", s); + return (int)tmp; +} + +/*------------------------------------------------------------------------*/ + +Debugger::Debugger(XeenEngine *vm) : GUI::Debugger(), _vm(vm) { + registerCmd("continue", WRAP_METHOD(Debugger, cmdExit)); + registerCmd("scene", WRAP_METHOD(Debugger, Cmd_LoadScene)); +} + +bool Debugger::Cmd_LoadScene(int argc, const char **argv) { + return true; +} + +} // End of namespace Access diff --git a/engines/xeen/debugger.h b/engines/xeen/debugger.h new file mode 100644 index 0000000000..6a1ec12e80 --- /dev/null +++ b/engines/xeen/debugger.h @@ -0,0 +1,44 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef XEEN_DEBUGGER_H +#define XEEN_DEBUGGER_H + +#include "common/scummsys.h" +#include "gui/debugger.h" + +namespace Xeen { + +class XeenEngine; + +class Debugger : public GUI::Debugger { +protected: + XeenEngine *_vm; + + bool Cmd_LoadScene(int argc, const char **argv); +public: + Debugger(XeenEngine *vm); +}; + +} // End of namespace Xeen + +#endif /* XEEN_DEBUGGER_H */ diff --git a/engines/xeen/detection.cpp b/engines/xeen/detection.cpp new file mode 100644 index 0000000000..2b30478808 --- /dev/null +++ b/engines/xeen/detection.cpp @@ -0,0 +1,183 @@ +/* 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. + * + */ + +#include "xeen/xeen.h" + +#include "base/plugins.h" +#include "common/savefile.h" +#include "engines/advancedDetector.h" +#include "common/system.h" + +#define MAX_SAVES 99 + +namespace Xeen { + +struct XeenGameDescription { + ADGameDescription desc; + + int gameID; + uint32 features; +}; + +uint32 XeenEngine::getGameID() const { + return _gameDescription->gameID; +} + +uint32 XeenEngine::getGameFeatures() const { + return _gameDescription->features; +} + +uint32 XeenEngine::getFeatures() const { + return _gameDescription->desc.flags; +} + +Common::Language XeenEngine::getLanguage() const { + return _gameDescription->desc.language; +} + +Common::Platform XeenEngine::getPlatform() const { + return _gameDescription->desc.platform; +} + +} // End of namespace Xeen + +static const PlainGameDescriptor XeenGames[] = { + { "xeen", "Xeen" }, + { "worldofxeen", "World of Xeen" }, + {0, 0} +}; + +#include "xeen/detection_tables.h" + +class XeenMetaEngine : public AdvancedMetaEngine { +public: + XeenMetaEngine() : AdvancedMetaEngine(Xeen::gameDescriptions, sizeof(Xeen::XeenGameDescription), XeenGames) { + _maxScanDepth = 3; + } + + virtual const char *getName() const { + return "Xeen Engine"; + } + + virtual const char *getOriginalCopyright() const { + return "Xeen Engine (c) ???"; + } + + virtual bool hasFeature(MetaEngineFeature f) const; + virtual bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const; + virtual SaveStateList listSaves(const char *target) const; + virtual int getMaximumSaveSlot() const; + virtual void removeSaveState(const char *target, int slot) const; + SaveStateDescriptor querySaveMetaInfos(const char *target, int slot) const; +}; + +bool XeenMetaEngine::hasFeature(MetaEngineFeature f) const { + return + (f == kSupportsListSaves) || + (f == kSupportsLoadingDuringStartup) || + (f == kSupportsDeleteSave) || + (f == kSavesSupportMetaInfo) || + (f == kSavesSupportThumbnail); +} + +bool Xeen::XeenEngine::hasFeature(EngineFeature f) const { + return + (f == kSupportsRTL) || + (f == kSupportsLoadingDuringRuntime) || + (f == kSupportsSavingDuringRuntime); +} + +bool XeenMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const { + const Xeen::XeenGameDescription *gd = (const Xeen::XeenGameDescription *)desc; + *engine = new Xeen::XeenEngine(syst, gd); + return gd != 0; +} + +SaveStateList XeenMetaEngine::listSaves(const char *target) const { + Common::SaveFileManager *saveFileMan = g_system->getSavefileManager(); + Common::StringArray filenames; + Common::String saveDesc; + Common::String pattern = Common::String::format("%s.0??", target); + Xeen::XeenSavegameHeader header; + + filenames = saveFileMan->listSavefiles(pattern); + sort(filenames.begin(), filenames.end()); // Sort to get the files in numerical order + + SaveStateList saveList; + for (Common::StringArray::const_iterator file = filenames.begin(); file != filenames.end(); ++file) { + const char *ext = strrchr(file->c_str(), '.'); + int slot = ext ? atoi(ext + 1) : -1; + + if (slot >= 0 && slot < MAX_SAVES) { + Common::InSaveFile *in = g_system->getSavefileManager()->openForLoading(*file); + + if (in) { + Xeen::XeenEngine::readSavegameHeader(in, header); + saveList.push_back(SaveStateDescriptor(slot, header._saveName)); + + header._thumbnail->free(); + delete header._thumbnail; + delete in; + } + } + } + + return saveList; +} + +int XeenMetaEngine::getMaximumSaveSlot() const { + return MAX_SAVES; +} + +void XeenMetaEngine::removeSaveState(const char *target, int slot) const { + Common::String filename = Common::String::format("%s.%03d", target, slot); + g_system->getSavefileManager()->removeSavefile(filename); +} + +SaveStateDescriptor XeenMetaEngine::querySaveMetaInfos(const char *target, int slot) const { + Common::String filename = Common::String::format("%s.%03d", target, slot); + Common::InSaveFile *f = g_system->getSavefileManager()->openForLoading(filename); + + if (f) { + Xeen::XeenSavegameHeader header; + Xeen::XeenEngine::readSavegameHeader(f, header); + delete f; + + // Create the return descriptor + SaveStateDescriptor desc(slot, header._saveName); + desc.setThumbnail(header._thumbnail); + desc.setSaveDate(header._year, header._month, header._day); + desc.setSaveTime(header._hour, header._minute); + desc.setPlayTime(header._totalFrames * GAME_FRAME_TIME); + + return desc; + } + + return SaveStateDescriptor(); +} + + +#if PLUGIN_ENABLED_DYNAMIC(XEEN) + REGISTER_PLUGIN_DYNAMIC(XEEN, PLUGIN_TYPE_ENGINE, XeenMetaEngine); +#else + REGISTER_PLUGIN_STATIC(XEEN, PLUGIN_TYPE_ENGINE, XeenMetaEngine); +#endif diff --git a/engines/xeen/detection_tables.h b/engines/xeen/detection_tables.h new file mode 100644 index 0000000000..e106abf8cd --- /dev/null +++ b/engines/xeen/detection_tables.h @@ -0,0 +1,48 @@ +/* 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. + * + */ + +namespace Xeen { + +static const XeenGameDescription gameDescriptions[] = { + { + // World of Xeen + { + "worldofxeen", + nullptr, + { + { "xeen.cc", 0, "0cffbab533d9afe140e69ec93096f43e", 13435646 }, + { "dark.cc", 0, "df194483ecea6abc0511637d712ced7c", 11217676 }, + AD_LISTEND + }, + Common::EN_ANY, + Common::kPlatformDOS, + ADGF_NO_FLAGS, + GUIO1(GUIO_NONE) + }, + GType_World, + 0 + }, + + { AD_TABLE_END_MARKER, 0, 0 } +}; + +} // End of namespace Xeen diff --git a/engines/xeen/module.mk b/engines/xeen/module.mk new file mode 100644 index 0000000000..a33b26a988 --- /dev/null +++ b/engines/xeen/module.mk @@ -0,0 +1,13 @@ +MODULE := engines/xeen + +MODULE_OBJS := \ + detection.o \ + xeen.o + +# This module can be built as a plugin +ifeq ($(ENABLE_XEEN), DYNAMIC_PLUGIN) +PLUGIN := 1 +endif + +# Include common rules +include $(srcdir)/rules.mk diff --git a/engines/xeen/xeen.cpp b/engines/xeen/xeen.cpp new file mode 100644 index 0000000000..3fe75e10a0 --- /dev/null +++ b/engines/xeen/xeen.cpp @@ -0,0 +1,209 @@ +/* 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. + * + */ + +#include "common/scummsys.h" +#include "common/config-manager.h" +#include "common/debug-channels.h" +#include "common/events.h" +#include "engines/util.h" +#include "graphics/scaler.h" +#include "graphics/thumbnail.h" +#include "xeen/xeen.h" + +namespace Xeen { + +XeenEngine::XeenEngine(OSystem *syst, const XeenGameDescription *gameDesc) + : _gameDescription(gameDesc), Engine(syst), _randomSource("Xeen") { + _debugger = nullptr; +} + +XeenEngine::~XeenEngine() { + delete _debugger; +} + +void XeenEngine::initialize() { + // Set up debug channels + DebugMan.addDebugChannel(kDebugPath, "Path", "Pathfinding debug level"); + DebugMan.addDebugChannel(kDebugScripts, "scripts", "Game scripts"); + DebugMan.addDebugChannel(kDebugGraphics, "graphics", "Graphics handling"); + DebugMan.addDebugChannel(kDebugSound, "sound", "Sound and Music handling"); + + // Create sub-objects of the engine + _debugger = new Debugger(this); + + // Set graphics mode + initGraphics(320, 200, false); + + // If requested, load a savegame instead of showing the intro + if (ConfMan.hasKey("save_slot")) { + int saveSlot = ConfMan.getInt("save_slot"); + if (saveSlot >= 0 && saveSlot <= 999) + _loadSaveSlot = saveSlot; + } +} + +Common::Error XeenEngine::run() { + initialize(); + + playGame(); + + return Common::kNoError; +} + +int XeenEngine::getRandomNumber(int maxNumber) { + return _randomSource.getRandomNumber(maxNumber); +} + +Common::Error XeenEngine::saveGameState(int slot, const Common::String &desc) { + Common::OutSaveFile *out = g_system->getSavefileManager()->openForSaving( + generateSaveName(slot)); + if (!out) + return Common::kCreatingFileFailed; + + XeenSavegameHeader header; + header._saveName = desc; + writeSavegameHeader(out, header); + + Common::Serializer s(nullptr, out); + synchronize(s); + + out->finalize(); + delete out; + + return Common::kNoError; +} + +Common::Error XeenEngine::loadGameState(int slot) { + Common::InSaveFile *saveFile = g_system->getSavefileManager()->openForLoading( + generateSaveName(slot)); + if (!saveFile) + return Common::kReadingFailed; + + Common::Serializer s(saveFile, nullptr); + + // Load the savaegame header + XeenSavegameHeader header; + if (!readSavegameHeader(saveFile, header)) + error("Invalid savegame"); + + if (header._thumbnail) { + header._thumbnail->free(); + delete header._thumbnail; + } + + // Load most of the savegame data + synchronize(s); + delete saveFile; + + return Common::kNoError; +} + +Common::String XeenEngine::generateSaveName(int slot) { + return Common::String::format("%s.%03d", _targetName.c_str(), slot); +} + +bool XeenEngine::canLoadGameStateCurrently() { + return true; +} + +bool XeenEngine::canSaveGameStateCurrently() { + return true; +} + +void XeenEngine::synchronize(Common::Serializer &s) { + // TODO +} + +const char *const SAVEGAME_STR = "XEEN"; +#define SAVEGAME_STR_SIZE 6 + +bool XeenEngine::readSavegameHeader(Common::InSaveFile *in, XeenSavegameHeader &header) { + char saveIdentBuffer[SAVEGAME_STR_SIZE + 1]; + header._thumbnail = nullptr; + + // Validate the header Id + in->read(saveIdentBuffer, SAVEGAME_STR_SIZE + 1); + if (strncmp(saveIdentBuffer, SAVEGAME_STR, SAVEGAME_STR_SIZE)) + return false; + + header._version = in->readByte(); + if (header._version > XEEN_SAVEGAME_VERSION) + return false; + + // Read in the string + header._saveName.clear(); + char ch; + while ((ch = (char)in->readByte()) != '\0') + header._saveName += ch; + + // Get the thumbnail + header._thumbnail = Graphics::loadThumbnail(*in); + if (!header._thumbnail) + return false; + + // Read in save date/time + header._year = in->readSint16LE(); + header._month = in->readSint16LE(); + header._day = in->readSint16LE(); + header._hour = in->readSint16LE(); + header._minute = in->readSint16LE(); + header._totalFrames = in->readUint32LE(); + + return true; +} + +void XeenEngine::writeSavegameHeader(Common::OutSaveFile *out, XeenSavegameHeader &header) { + // Write out a savegame header + out->write(SAVEGAME_STR, SAVEGAME_STR_SIZE + 1); + + out->writeByte(XEEN_SAVEGAME_VERSION); + + // Write savegame name + out->writeString(header._saveName); + out->writeByte('\0'); + + // Write a thumbnail of the screen +/* + uint8 thumbPalette[768]; + _screen->getPalette(thumbPalette); + Graphics::Surface saveThumb; + ::createThumbnail(&saveThumb, (const byte *)_screen->getPixels(), + _screen->w, _screen->h, thumbPalette); + Graphics::saveThumbnail(*out, saveThumb); + saveThumb.free(); +*/ + // Write out the save date/time + TimeDate td; + g_system->getTimeAndDate(td); + out->writeSint16LE(td.tm_year + 1900); + out->writeSint16LE(td.tm_mon + 1); + out->writeSint16LE(td.tm_mday); + out->writeSint16LE(td.tm_hour); + out->writeSint16LE(td.tm_min); +// out->writeUint32LE(_events->getFrameCounter()); +} + +void XeenEngine::playGame() { + // TODO +} + +} // End of namespace Xeen diff --git a/engines/xeen/xeen.h b/engines/xeen/xeen.h new file mode 100644 index 0000000000..2566c1b1eb --- /dev/null +++ b/engines/xeen/xeen.h @@ -0,0 +1,153 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +#ifndef XEEN_XEEN_H +#define XEEN_XEEN_H + +#include "common/scummsys.h" +#include "common/system.h" +#include "common/error.h" +#include "common/random.h" +#include "common/savefile.h" +#include "common/serializer.h" +#include "common/util.h" +#include "engines/engine.h" +#include "graphics/surface.h" +#include "xeen/debugger.h" + +/** + * This is the namespace of the Xeen engine. + * + * Status of this engine: In Development + * + * Games using this engine: + * - Might & Magic 4: Clouds of Xeen + * - Might & Magic 5: Dark Side of Xeen + * - Might & Magic: World of Xeen + * - Might & Magic: Swords of Xeen + */ +namespace Xeen { + +enum { + GType_Clouds = 1, + GType_Dark = 2, + GType_World = 3, + GType_Swords = 4 +}; + +enum XeenDebugChannels { + kDebugPath = 1 << 0, + kDebugScripts = 1 << 1, + kDebugGraphics = 1 << 2, + kDebugSound = 1 << 3 +}; + +struct XeenGameDescription; + +#define XEEN_SAVEGAME_VERSION 1 +#define GAME_FRAME_TIME 50 + +struct XeenSavegameHeader { + uint8 _version; + Common::String _saveName; + Graphics::Surface *_thumbnail; + int _year, _month, _day; + int _hour, _minute; + int _totalFrames; +}; + +class XeenEngine : public Engine { +private: + const XeenGameDescription *_gameDescription; + Common::RandomSource _randomSource; + int _loadSaveSlot; +private: + void initialize(); + + /** + * Play the game + */ + void playGame(); + + /** + * Synchronize savegame data + */ + void synchronize(Common::Serializer &s); + + /** + * Support method that generates a savegame name + * @param slot Slot number + */ + Common::String generateSaveName(int slot); + + // Engine APIs + virtual Common::Error run(); + virtual bool hasFeature(EngineFeature f) const; +public: + Debugger *_debugger; +public: + XeenEngine(OSystem *syst, const XeenGameDescription *gameDesc); + virtual ~XeenEngine(); + + uint32 getFeatures() const; + Common::Language getLanguage() const; + Common::Platform getPlatform() const; + uint16 getVersion() const; + uint32 getGameID() const; + uint32 getGameFeatures() const; + + int getRandomNumber(int maxNumber); + + /** + * Load a savegame + */ + virtual Common::Error loadGameState(int slot); + + /** + * Save the game + */ + virtual Common::Error saveGameState(int slot, const Common::String &desc); + + /** + * Returns true if a savegame can currently be loaded + */ + bool canLoadGameStateCurrently(); + + /** + * Returns true if the game can currently be saved + */ + bool canSaveGameStateCurrently(); + + /** + * Read in a savegame header + */ + static bool readSavegameHeader(Common::InSaveFile *in, XeenSavegameHeader &header); + + /** + * Write out a savegame header + */ + void writeSavegameHeader(Common::OutSaveFile *out, XeenSavegameHeader &header); +}; + +} // End of namespace Xeen + +#endif /* XEEN_XEEN_H */ |