diff options
Diffstat (limited to 'engines/made')
-rw-r--r-- | engines/made/database.cpp | 88 | ||||
-rw-r--r-- | engines/made/database.h | 10 | ||||
-rw-r--r-- | engines/made/detection.cpp | 46 | ||||
-rw-r--r-- | engines/made/made.cpp | 40 | ||||
-rw-r--r-- | engines/made/made.h | 6 |
5 files changed, 141 insertions, 49 deletions
diff --git a/engines/made/database.cpp b/engines/made/database.cpp index d5c45fa1b9..108d1391e5 100644 --- a/engines/made/database.cpp +++ b/engines/made/database.cpp @@ -47,13 +47,9 @@ Object::~Object() { delete[] _objData; } -void Object::load(Common::SeekableReadStream &source) { - +int Object::load(Common::SeekableReadStream &source) { _freeData = true; - - source.readUint16LE(); // skip flags uint16 type = source.readUint16LE(); - if (type == 0x7FFF) { _objSize = source.readUint16LE(); } else if (type == 0x7FFE) { @@ -63,29 +59,23 @@ void Object::load(Common::SeekableReadStream &source) { byte count2 = source.readByte(); _objSize = (count1 + count2) * 2; } - source.seek(-6, SEEK_CUR); - _objSize += 6; - _objData = new byte[_objSize]; source.read(_objData, _objSize); - + return _objSize; } -void Object::load(byte *source) { - +int Object::load(byte *source) { _objData = source; _freeData = false; - if (getClass() < 0x7FFE) { _objSize = (getCount1() + getCount2()) * 2; } else { _objSize = getSize(); } - _objSize += 6; - + return _objSize; } uint16 Object::getFlags() const { @@ -184,7 +174,7 @@ void Object::dump(const char *filename) { */ } -GameDatabase::GameDatabase() { +GameDatabase::GameDatabase(MadeEngine *vm) : _vm(vm) { } GameDatabase::~GameDatabase() { @@ -211,11 +201,60 @@ void GameDatabase::openFromRed(const char *redFilename, const char *filename) { } void GameDatabase::load(Common::SeekableReadStream &sourceS) { + + if (_vm->getGameID() == GID_MANHOLE || _vm->getGameID() == GID_LGOP2) { + debug(2, "loading version 2 dat"); + loadVersion2(sourceS); + } else if (_vm->getGameID() == GID_RTZ) { + debug(2, "loading version 3 dat"); + loadVersion3(sourceS); + } + +} + +void GameDatabase::loadVersion2(Common::SeekableReadStream &sourceS) { // TODO: Read/verifiy header - sourceS.seek(0x1E); + sourceS.seek(0x1C); + + uint32 textStartOffs = sourceS.readUint16LE() * 512; + uint16 objectCount = sourceS.readUint16LE(); + uint16 varObjectCount = sourceS.readUint16LE(); + _gameStateSize = sourceS.readUint16LE() * 2; + sourceS.readUint16LE(); // unknown + uint32 objectsOffs = sourceS.readUint16LE() * 512; + sourceS.readUint16LE(); // unknown + _mainCodeObjectIndex = sourceS.readUint16LE(); + sourceS.readUint16LE(); // unknown + uint32 objectsSize = sourceS.readUint32LE() * 2; + + debug(2, "textStartOffs = %08X; objectCount = %d; varObjectCount = %d; gameStateSize = %d; objectsOffs = %08X; objectsSize = %d\n", textStartOffs, objectCount, varObjectCount, _gameStateSize, objectsOffs, objectsSize); + + _gameState = new byte[_gameStateSize]; + memset(_gameState, 0, _gameStateSize); + + sourceS.seek(objectsOffs); + + for (uint32 i = 0; i < objectCount; i++) { + Object *obj = new Object(); + int objSize = obj->load(sourceS); + objSize = objSize % 2; + // objects are aligned on 2-byte-boundaries, skip unused bytes + sourceS.skip(objSize); + _objects.push_back(obj); + } + printf("ok!\n"); fflush(stdout); + +} + +void GameDatabase::loadVersion3(Common::SeekableReadStream &sourceS) { + + // TODO: Read/verifiy header + + sourceS.seek(0x1E); + uint32 objectIndexOffs = sourceS.readUint32LE(); uint16 objectCount = sourceS.readUint16LE(); uint32 gameStateOffs = sourceS.readUint32LE(); @@ -223,8 +262,8 @@ void GameDatabase::load(Common::SeekableReadStream &sourceS) { uint32 objectsOffs = sourceS.readUint32LE(); uint32 objectsSize = sourceS.readUint32LE(); _mainCodeObjectIndex = sourceS.readUint16LE(); - - //debug(2, "objectIndexOffs = %08X; objectCount = %d; gameStateOffs = %08X; gameStateSize = %d; objectsOffs = %08X; objectsSize = %d\n", objectIndexOffs, objectCount, gameStateOffs, _gameStateSize, objectsOffs, objectsSize); + + debug(2, "objectIndexOffs = %08X; objectCount = %d; gameStateOffs = %08X; gameStateSize = %d; objectsOffs = %08X; objectsSize = %d\n", objectIndexOffs, objectCount, gameStateOffs, _gameStateSize, objectsOffs, objectsSize); _gameState = new byte[_gameStateSize]; sourceS.seek(gameStateOffs); @@ -241,15 +280,16 @@ void GameDatabase::load(Common::SeekableReadStream &sourceS) { // The LSB indicates if it's a constant or variable object. // Constant objects are loaded from disk, while variable objects exist // in the _gameState buffer. - - //debug(2, "obj(%04X) ofs = %08X\n", i, objectOffsets[i]); - + + debug(2, "obj(%04X) ofs = %08X\n", i, objectOffsets[i]); + if (objectOffsets[i] & 1) { - //debug(2, "-> const %08X\n", objectsOffs + objectOffsets[i] - 1); + debug(2, "-> const %08X\n", objectsOffs + objectOffsets[i] - 1); sourceS.seek(objectsOffs + objectOffsets[i] - 1); + sourceS.readUint16LE(); // skip flags obj->load(sourceS); } else { - //debug(2, "-> var\n"); + debug(2, "-> var\n"); obj->load(_gameState + objectOffsets[i]); } _objects.push_back(obj); @@ -348,8 +388,6 @@ int16 *GameDatabase::getObjectPropertyPtr(int16 objectIndex, int16 propertyId, i int16 *propPtr1 = prop + count1; int16 *propPtr2 = prop + count2; - debug(2, "# propertyId = %04X\n", propertyId); - // First see if the property exists in the given object while (count2-- > 0) { if ((READ_LE_UINT16(prop) & 0x3FFF) == propertyId) { diff --git a/engines/made/database.h b/engines/made/database.h index c5d3916e25..adaf91f6d3 100644 --- a/engines/made/database.h +++ b/engines/made/database.h @@ -32,6 +32,7 @@ #include "common/stream.h" #include "common/str.h" +#include "made/made.h" #include "made/redreader.h" namespace Made { @@ -40,8 +41,8 @@ class Object { public: Object(); ~Object(); - void load(Common::SeekableReadStream &source); - void load(byte *source); + int load(Common::SeekableReadStream &source); + int load(byte *source); uint16 getFlags() const; uint16 getClass() const; @@ -73,7 +74,7 @@ protected: class GameDatabase { public: - GameDatabase(); + GameDatabase(MadeEngine *vm); ~GameDatabase(); void open(const char *filename); @@ -102,11 +103,14 @@ public: void dumpObject(int16 index); protected: + MadeEngine *_vm; Common::Array<Object*> _objects; byte *_gameState; uint32 _gameStateSize; int16 _mainCodeObjectIndex; void load(Common::SeekableReadStream &sourceS); + void loadVersion2(Common::SeekableReadStream &sourceS); + void loadVersion3(Common::SeekableReadStream &sourceS); }; } // End of namespace Made diff --git a/engines/made/detection.cpp b/engines/made/detection.cpp index e3bb4cd1dd..cae5e287ee 100644 --- a/engines/made/detection.cpp +++ b/engines/made/detection.cpp @@ -61,8 +61,10 @@ uint16 MadeEngine::getVersion() const { } static const PlainGameDescriptor madeGames[] = { - {"made", "MADE engine game"}, + {"made", "MADE engine game"}, + {"manhole", "The Manhole"}, {"rtz", "Return to Zork"}, + {"lgop2", "Leather Goddesses of Phobos 2"}, {0, 0} }; @@ -83,7 +85,7 @@ static const MadeGameDescription gameDescriptions[] = { Common::kPlatformPC, Common::ADGF_NO_FLAGS }, - 0, + GID_RTZ, 0, GF_CD, 0, @@ -99,7 +101,7 @@ static const MadeGameDescription gameDescriptions[] = { Common::kPlatformPC, Common::ADGF_NO_FLAGS }, - 0, + GID_RTZ, 0, GF_CD_COMPRESSED, 0, @@ -115,7 +117,7 @@ static const MadeGameDescription gameDescriptions[] = { Common::kPlatformPC, Common::ADGF_NO_FLAGS }, - 0, + GID_RTZ, 0, GF_CD_COMPRESSED, 0, @@ -132,7 +134,7 @@ static const MadeGameDescription gameDescriptions[] = { Common::kPlatformPC, Common::ADGF_NO_FLAGS }, - 0, + GID_RTZ, 0, GF_FLOPPY, 0, @@ -148,11 +150,43 @@ static const MadeGameDescription gameDescriptions[] = { Common::kPlatformPC, Common::ADGF_DEMO }, - 0, + GID_RTZ, 0, GF_DEMO, 0, }, + + { + // The Manhole: New and Enhanced + { + "manhole", + "", + AD_ENTRY1("manhole.dat", "cb21e31ed35c963208343bc995225b73"), + Common::EN_ANY, + Common::kPlatformPC, + Common::ADGF_NO_FLAGS + }, + GID_MANHOLE, + 0, + GF_CD, + 0, + }, + + { + // Leather Goddesses of Phobos 2 + { + "lgop2", + "", + AD_ENTRY1("lgop2.dat", "8137996db200ff67e8f172ff106f2e48"), + Common::EN_ANY, + Common::kPlatformPC, + Common::ADGF_NO_FLAGS + }, + GID_LGOP2, + 0, + GF_FLOPPY, + 0, + }, { AD_TABLE_END_MARKER, 0, 0, 0, 0 } }; diff --git a/engines/made/made.cpp b/engines/made/made.cpp index 6eacbd759a..e82b2957cf 100644 --- a/engines/made/made.cpp +++ b/engines/made/made.cpp @@ -86,7 +86,7 @@ MadeEngine::MadeEngine(OSystem *syst, const MadeGameDescription *gameDesc) : Eng _pmvPlayer = new PmvPlayer(this, _mixer); _res = new ProjectReader(); _screen = new Screen(this); - _dat = new GameDatabase(); + _dat = new GameDatabase(this); _script = new ScriptInterpreter(this); int midiDriver = MidiDriver::detectMusicDriver(MDT_MIDI | MDT_ADLIB | MDT_PREFER_MIDI); @@ -159,21 +159,31 @@ int MadeEngine::go() { for (int i = 0; i < ARRAYSIZE(_timers); i++) _timers[i] = -1; - - if (getFeatures() & GF_DEMO) { - _dat->open("demo.dat"); - _res->open("demo.prj"); - } else if (getFeatures() & GF_CD) { - _dat->open("rtzcd.dat"); - _res->open("rtzcd.prj"); - } else if (getFeatures() & GF_CD_COMPRESSED) { - _dat->openFromRed("rtzcd.red", "rtzcd.dat"); - _res->open("rtzcd.prj"); - } else if (getFeatures() & GF_FLOPPY) { - _dat->open("rtz.dat"); - _res->open("rtz.prj"); + + if (getGameID() == GID_RTZ) { + if (getFeatures() & GF_DEMO) { + _dat->open("demo.dat"); + _res->open("demo.prj"); + } else if (getFeatures() & GF_CD) { + _dat->open("rtzcd.dat"); + _res->open("rtzcd.prj"); + } else if (getFeatures() & GF_CD_COMPRESSED) { + _dat->openFromRed("rtzcd.red", "rtzcd.dat"); + _res->open("rtzcd.prj"); + } else if (getFeatures() & GF_FLOPPY) { + _dat->open("rtz.dat"); + _res->open("rtz.prj"); + } else { + error("Unknown RTZ game features"); + } + } else if (getGameID() == GID_MANHOLE) { + _dat->open("manhole.dat"); + _res->open("manhole.prj"); + } else if (getGameID() == GID_LGOP2) { + _dat->open("lgop2.dat"); + _res->open("lgop2.prj"); } else { - error("Unknown game features"); + error ("Unknown MADE game"); } _eventMouseX = _eventMouseY = 0; diff --git a/engines/made/made.h b/engines/made/made.h index ad4cd78660..ea28222492 100644 --- a/engines/made/made.h +++ b/engines/made/made.h @@ -47,6 +47,12 @@ namespace Made { +enum MadeGameID { + GID_RTZ = 0, + GID_MANHOLE = 1, + GID_LGOP2 = 2 +}; + enum MadeGameFeatures { GF_DEMO = 1 << 0, GF_CD = 1 << 1, |