aboutsummaryrefslogtreecommitdiff
path: root/engines/made/database.cpp
diff options
context:
space:
mode:
authorBenjamin Haisch2009-01-22 13:04:29 +0000
committerBenjamin Haisch2009-01-22 13:04:29 +0000
commit5b8105afb3a345cfd66efa795726329f509572c3 (patch)
tree4ff90316c9dee6be8bda8a0c3f8413ab5d8178a5 /engines/made/database.cpp
parentd5d7175691ea3cde7aa941886e3197763c1398c6 (diff)
downloadscummvm-rg350-5b8105afb3a345cfd66efa795726329f509572c3.tar.gz
scummvm-rg350-5b8105afb3a345cfd66efa795726329f509572c3.tar.bz2
scummvm-rg350-5b8105afb3a345cfd66efa795726329f509572c3.zip
- Added support for The Manhole EGA version
- Support for 'chunked' picture resources and EGA pictures - Improved the mouth sync in RtZ (still not perfect, though) - Removed obsolete TODOs - Fixed sfPlayMovie to return if the movie playback was aborted or not; this is used by RtZ to determine if it should display the credits screen after the intro movie svn-id: r35997
Diffstat (limited to 'engines/made/database.cpp')
-rw-r--r--engines/made/database.cpp94
1 files changed, 70 insertions, 24 deletions
diff --git a/engines/made/database.cpp b/engines/made/database.cpp
index d8f9800ef6..f541047ca9 100644
--- a/engines/made/database.cpp
+++ b/engines/made/database.cpp
@@ -179,6 +179,13 @@ byte *ObjectV2::getData() {
return _objData + 4;
}
+int ObjectV1::load(Common::SeekableReadStream &source) {
+ ObjectV2::load(source);
+ // Manhole EGA has the two property counts reversed
+ SWAP(_objData[2], _objData[3]);
+ return _objSize;
+}
+
int ObjectV3::load(Common::SeekableReadStream &source) {
_freeData = true;
@@ -382,23 +389,37 @@ void GameDatabaseV2::load(Common::SeekableReadStream &sourceS) {
if (strncmp(header, "ADVSYS", 6))
warning ("Unexpected database header, expected ADVSYS");
- /*uint32 unk = */sourceS.readUint16LE();
+ uint32 textOffs, objectsOffs, objectsSize, textSize;
+ uint16 objectCount, varObjectCount;
+
+ sourceS.readUint16LE(); // skip sub-version
+ sourceS.skip(18); // skip program name
+
+ if (version == 40) {
+ sourceS.readUint16LE(); // skip unused
+ objectCount = sourceS.readUint16LE();
+ _gameStateSize = sourceS.readUint16LE() * 2;
+ objectsOffs = sourceS.readUint16LE() * 512;
+ textOffs = sourceS.readUint16LE() * 512;
+ _mainCodeObjectIndex = sourceS.readUint16LE();
+ varObjectCount = 0; // unused in V1
+ objectsSize = 0; // unused in V1
+ } else if (version == 54) {
+ textOffs = sourceS.readUint16LE() * 512;
+ objectCount = sourceS.readUint16LE();
+ varObjectCount = sourceS.readUint16LE();
+ _gameStateSize = sourceS.readUint16LE() * 2;
+ sourceS.readUint16LE(); // unknown
+ objectsOffs = sourceS.readUint16LE() * 512;
+ sourceS.readUint16LE(); // unknown
+ _mainCodeObjectIndex = sourceS.readUint16LE();
+ sourceS.readUint16LE(); // unknown
+ objectsSize = sourceS.readUint32LE() * 2;
+ }
- sourceS.skip(18);
+ textSize = objectsOffs - textOffs;
- uint32 textOffs = 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;
- uint32 textSize = objectsOffs - textOffs;
-
- debug(2, "textOffs = %08X; textSize = %08X; objectCount = %d; varObjectCount = %d; gameStateSize = %d; objectsOffs = %08X; objectsSize = %d\n", textOffs, textSize, objectCount, varObjectCount, _gameStateSize, objectsOffs, objectsSize);
+ debug(0, "textOffs = %08X; textSize = %08X; objectCount = %d; varObjectCount = %d; gameStateSize = %d; objectsOffs = %08X; objectsSize = %d; _mainCodeObjectIndex = %04X\n", textOffs, textSize, objectCount, varObjectCount, _gameStateSize, objectsOffs, objectsSize, _mainCodeObjectIndex);
_gameState = new byte[_gameStateSize + 2];
memset(_gameState, 0, _gameStateSize + 2);
@@ -410,15 +431,35 @@ void GameDatabaseV2::load(Common::SeekableReadStream &sourceS) {
// "Decrypt" the text data
for (uint32 i = 0; i < textSize; i++)
_gameText[i] += 0x1E;
-
+
sourceS.seek(objectsOffs);
- for (uint32 i = 0; i < objectCount; i++) {
- Object *obj = new ObjectV2();
- int objSize = obj->load(sourceS);
- // objects are aligned on 2-byte-boundaries, skip unused bytes
- sourceS.skip(objSize % 2);
- _objects.push_back(obj);
+ if (version == 40) {
+ // Initialize the object array
+ for (uint32 i = 0; i < objectCount; i++)
+ _objects.push_back(NULL);
+ // Read two "sections" of objects
+ // It seems the first section is data while the second one is code.
+ // The interpreter however doesn't care which section the objects come from.
+ for (int section = 0; section < 2; section++) {
+ while (!sourceS.eos()) {
+ int16 objIndex = sourceS.readUint16LE();
+ debug("objIndex = %04X; section = %d", objIndex, section);
+ if (objIndex == 0)
+ break;
+ Object *obj = new ObjectV1();
+ obj->load(sourceS);
+ _objects[objIndex - 1] = obj;
+ }
+ }
+ } else if (version == 54) {
+ for (uint32 i = 0; i < objectCount; i++) {
+ Object *obj = new ObjectV2();
+ int objSize = obj->load(sourceS);
+ // Objects are aligned on 2-byte-boundaries, skip unused bytes
+ sourceS.skip(objSize % 2);
+ _objects.push_back(obj);
+ }
}
}
@@ -464,7 +505,11 @@ int16 GameDatabaseV2::loadgame(const char *filename, int16 version) {
}
int16 *GameDatabaseV2::findObjectProperty(int16 objectIndex, int16 propertyId, int16 &propertyFlag) {
+
Object *obj = getObject(objectIndex);
+ if (obj->getClass() >= 0x7FFE) {
+ error("GameDatabaseV2::findObjectProperty(%04X, %04X) Not an object", objectIndex, propertyId);
+ }
int16 *prop = (int16*)obj->getData();
byte count1 = obj->getCount1();
@@ -568,11 +613,9 @@ void GameDatabaseV3::load(Common::SeekableReadStream &sourceS) {
for (uint32 i = 0; i < objectCount; i++) {
Object *obj = new ObjectV3();
-
// 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.
-
if (objectOffsets[i] & 1) {
sourceS.seek(objectsOffs + objectOffsets[i] - 1);
obj->load(sourceS);
@@ -682,6 +725,9 @@ int16 GameDatabaseV3::loadgame(const char *filename, int16 version) {
int16 *GameDatabaseV3::findObjectProperty(int16 objectIndex, int16 propertyId, int16 &propertyFlag) {
Object *obj = getObject(objectIndex);
+ if (obj->getClass() >= 0x7FFE) {
+ error("GameDatabaseV2::findObjectProperty(%04X, %04X) Not an object", objectIndex, propertyId);
+ }
int16 *prop = (int16*)obj->getData();
byte count1 = obj->getCount1();