aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/made/database.cpp88
-rw-r--r--engines/made/database.h10
-rw-r--r--engines/made/detection.cpp46
-rw-r--r--engines/made/made.cpp40
-rw-r--r--engines/made/made.h6
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,