aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/made/database.cpp621
-rw-r--r--engines/made/database.h124
-rw-r--r--engines/made/made.cpp10
3 files changed, 402 insertions, 353 deletions
diff --git a/engines/made/database.cpp b/engines/made/database.cpp
index f7fce52b21..4a331d5ca1 100644
--- a/engines/made/database.cpp
+++ b/engines/made/database.cpp
@@ -47,7 +47,79 @@ Object::~Object() {
delete[] _objData;
}
-int Object::loadVersion2(Common::SeekableReadStream &source) {
+const char *Object::getString() {
+ if (getClass() == 0x7FFF)
+ return (const char*)getData();
+ else
+ return NULL;
+}
+
+void Object::setString(const char *str) {
+ if (getClass() == 0x7FFF) {
+ char *objStr = (char*)getData();
+ if (str)
+ strncpy(objStr, str, getSize());
+ else
+ objStr[0] = '\0';
+ }
+}
+
+bool Object::isObject() {
+ return getClass() < 0x7FFE;
+}
+
+bool Object::isVector() {
+ return getClass() == 0x7FFF;
+}
+
+int16 Object::getVectorSize() {
+ if (getClass() == 0x7FFF || getClass() == 0x7FFE) {
+ return getSize();
+ } else if (getClass() < 0x7FFE) {
+ return getCount1() + getCount2();
+ } else {
+ // should never reach here
+ error("Unknown object class");
+ return 0;
+ }
+}
+
+int16 Object::getVectorItem(int16 index) {
+ if (getClass() == 0x7FFF) {
+ byte *vector = (byte*)getData();
+ return vector[index];
+ } else if (getClass() == 0x7FFE) {
+ int16 *vector = (int16*)getData();
+ return READ_LE_UINT16(&vector[index]);
+ } else if (getClass() < 0x7FFE) {
+ int16 *vector = (int16*)getData();
+ return READ_LE_UINT16(&vector[index]);
+ } else {
+ // should never reach here
+ error("Unknown object class");
+ return 0;
+ }
+}
+
+void Object::setVectorItem(int16 index, int16 value) {
+ if (getClass() == 0x7FFF) {
+ byte *vector = (byte*)getData();
+ vector[index] = value;
+ } else if (getClass() <= 0x7FFE) {
+ int16 *vector = (int16*)getData();
+ WRITE_LE_UINT16(&vector[index], value);
+ }
+}
+
+void Object::dump(const char *filename) {
+ /*
+ FILE *o = fopen(filename, "wb");
+ fwrite(_objData, _objSize, 1, o);
+ fclose(o);
+ */
+}
+
+int ObjectV2::load(Common::SeekableReadStream &source) {
if (_freeData && _objData)
delete[] _objData;
@@ -67,22 +139,51 @@ int Object::loadVersion2(Common::SeekableReadStream &source) {
byte count2 = header[3];
_objSize = (count1 + count2) * 2;
}
- _objSize += 6;
+ _objSize += 4;
_objData = new byte[_objSize];
- WRITE_LE_UINT16(_objData, 1);
- memcpy(_objData + 2, header, 4);
- source.read(_objData + 6, _objSize - 6);
+ memcpy(_objData, header, 4);
+ source.read(_objData + 4, _objSize - 4);
- return _objSize - 2;
+ return _objSize;
+
+}
+int ObjectV2::load(byte *source) {
+ // Not implemented/used for version 2 objects
+ return 0;
}
-int Object::saveVersion2(Common::WriteStream &dest) {
- dest.write(_objData + 2, _objSize - 2);
+int ObjectV2::save(Common::WriteStream &dest) {
+ dest.write(_objData, _objSize);
return 0;
}
-int Object::loadVersion3(Common::SeekableReadStream &source) {
+uint16 ObjectV2::getFlags() {
+ return 1;
+}
+
+uint16 ObjectV2::getClass() {
+ return READ_LE_UINT16(_objData);
+}
+
+uint16 ObjectV2::getSize() {
+ return READ_LE_UINT16(_objData + 2);
+}
+
+byte ObjectV2::getCount1() {
+ return _objData[2];
+}
+
+byte ObjectV2::getCount2() {
+ return _objData[3];
+}
+
+byte *ObjectV2::getData() {
+ return _objData + 4;
+}
+
+int ObjectV3::load(Common::SeekableReadStream &source) {
+
_freeData = true;
source.readUint16LE(); // skip flags
uint16 type = source.readUint16LE();
@@ -100,9 +201,10 @@ int Object::loadVersion3(Common::SeekableReadStream &source) {
_objData = new byte[_objSize];
source.read(_objData, _objSize);
return _objSize;
+
}
-int Object::loadVersion3(byte *source) {
+int ObjectV3::load(byte *source) {
_objData = source;
_freeData = false;
if (getClass() < 0x7FFE) {
@@ -114,111 +216,43 @@ int Object::loadVersion3(byte *source) {
return _objSize;
}
-uint16 Object::getFlags() const {
+int ObjectV3::save(Common::WriteStream &dest) {
+ // Not implemented/used for version 3 objects
+ return 0;
+}
+
+uint16 ObjectV3::getFlags() {
return READ_LE_UINT16(_objData);
}
-uint16 Object::getClass() const {
+uint16 ObjectV3::getClass() {
return READ_LE_UINT16(_objData + 2);
}
-uint16 Object::getSize() const {
+uint16 ObjectV3::getSize() {
return READ_LE_UINT16(_objData + 4);
}
-byte Object::getCount1() const {
+byte ObjectV3::getCount1() {
return _objData[4];
}
-byte Object::getCount2() const {
+byte ObjectV3::getCount2() {
return _objData[5];
}
-byte *Object::getData() {
+byte *ObjectV3::getData() {
return _objData + 6;
}
-const char *Object::getString() {
- if (getClass() == 0x7FFF)
- return (const char*)getData();
- else
- return NULL;
-}
-
-void Object::setString(const char *str) {
- if (getClass() == 0x7FFF) {
- char *objStr = (char*)getData();
- if (str)
- strncpy(objStr, str, getSize());
- else
- objStr[0] = '\0';
- }
-}
-
-bool Object::isObject() {
- return getClass() < 0x7FFE;
-}
-
-bool Object::isVector() {
- return getClass() == 0x7FFF;
-}
-
-int16 Object::getVectorSize() {
- if (getClass() == 0x7FFF || getClass() == 0x7FFE) {
- return getSize();
- } else if (getClass() < 0x7FFE) {
- return getCount1() + getCount2();
- } else {
- // should never reach here
- error("Unknown object class");
- return 0;
- }
-}
-
-int16 Object::getVectorItem(int16 index) {
- if (getClass() == 0x7FFF) {
- byte *vector = (byte*)getData();
- return vector[index];
- } else if (getClass() == 0x7FFE) {
- int16 *vector = (int16*)getData();
- return READ_LE_UINT16(&vector[index]);
- } else if (getClass() < 0x7FFE) {
- int16 *vector = (int16*)getData();
- return READ_LE_UINT16(&vector[index]);
- } else {
- // should never reach here
- error("Unknown object class");
- return 0;
- }
-}
-void Object::setVectorItem(int16 index, int16 value) {
- if (getClass() == 0x7FFF) {
- byte *vector = (byte*)getData();
- vector[index] = value;
- } else if (getClass() <= 0x7FFE) {
- int16 *vector = (int16*)getData();
- WRITE_LE_UINT16(&vector[index], value);
- }
-}
-
-void Object::dump(const char *filename) {
- /*
- FILE *o = fopen(filename, "wb");
- fwrite(_objData, _objSize, 1, o);
- fclose(o);
- */
-}
GameDatabase::GameDatabase(MadeEngine *vm) : _vm(vm) {
- _gameText = NULL;
}
GameDatabase::~GameDatabase() {
if (_gameState)
delete[] _gameState;
- if (_gameText)
- delete[] _gameText;
}
void GameDatabase::open(const char *filename) {
@@ -239,19 +273,71 @@ void GameDatabase::openFromRed(const char *redFilename, const char *filename) {
delete fileS;
}
-void GameDatabase::load(Common::SeekableReadStream &sourceS) {
+int16 GameDatabase::getVar(int16 index) {
+ return (int16)READ_LE_UINT16(_gameState + index * 2);
+}
+
+void GameDatabase::setVar(int16 index, int16 value) {
+ WRITE_LE_UINT16(_gameState + index * 2, value);
+}
+
+int16 GameDatabase::getObjectProperty(int16 objectIndex, int16 propertyId) {
+
+ if (objectIndex == 0)
+ return 0;
+
+ int16 propertyFlag;
+ int16 *property = getObjectPropertyPtr(objectIndex, propertyId, propertyFlag);
+
+ if (property) {
+ return (int16)READ_LE_UINT16(property);
+ } else {
+ return 0;
+ }
+
+}
+
+int16 GameDatabase::setObjectProperty(int16 objectIndex, int16 propertyId, int16 value) {
+
+ if (objectIndex == 0)
+ return 0;
+
+ int16 propertyFlag;
+ int16 *property = getObjectPropertyPtr(objectIndex, propertyId, propertyFlag);
- 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);
+ if (property) {
+ if (propertyFlag == 1) {
+ WRITE_LE_UINT16(property, value);
+ } else {
+ warning("GameDatabase::setObjectProperty(%04X, %04X, %04X) Trying to set constant property\n",
+ objectIndex, propertyId, value);
+ }
+ return value;
+ } else {
+ return 0;
}
}
-void GameDatabase::loadVersion2(Common::SeekableReadStream &sourceS) {
+void GameDatabase::dumpObject(int16 index) {
+ Object *obj = getObject(index);
+ char fn[512];
+ sprintf(fn, "obj%04X.0", index);
+ obj->dump(fn);
+}
+
+
+/* GameDatabaseV2 */
+
+GameDatabaseV2::GameDatabaseV2(MadeEngine *vm) : GameDatabase(vm), _gameText(NULL) {
+}
+
+GameDatabaseV2::~GameDatabaseV2() {
+ if (_gameText)
+ delete[] _gameText;
+}
+
+void GameDatabaseV2::load(Common::SeekableReadStream &sourceS) {
// TODO: Read/verifiy header
@@ -285,8 +371,8 @@ void GameDatabase::loadVersion2(Common::SeekableReadStream &sourceS) {
sourceS.seek(objectsOffs);
for (uint32 i = 0; i < objectCount; i++) {
- Object *obj = new Object();
- int objSize = obj->loadVersion2(sourceS);
+ 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);
@@ -294,176 +380,43 @@ void GameDatabase::loadVersion2(Common::SeekableReadStream &sourceS) {
}
-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();
- _gameStateSize = sourceS.readUint32LE();
- 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);
-
- _gameState = new byte[_gameStateSize];
- sourceS.seek(gameStateOffs);
- sourceS.read(_gameState, _gameStateSize);
-
- Common::Array<uint32> objectOffsets;
- sourceS.seek(objectIndexOffs);
- for (uint32 i = 0; i < objectCount; i++)
- objectOffsets.push_back(sourceS.readUint32LE());
-
- for (uint32 i = 0; i < objectCount; i++) {
- Object *obj = new Object();
-
- // 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]);
-
- if (objectOffsets[i] & 1) {
- //debug(2, "-> const %08X\n", objectsOffs + objectOffsets[i] - 1);
- sourceS.seek(objectsOffs + objectOffsets[i] - 1);
- obj->loadVersion3(sourceS);
- } else {
- //debug(2, "-> var\n");
- obj->loadVersion3(_gameState + objectOffsets[i]);
- }
- _objects.push_back(obj);
- }
-
-}
-
-bool GameDatabase::getSavegameDescription(const char *filename, Common::String &description) {
-
- Common::InSaveFile *in;
-
- if (!(in = g_system->getSavefileManager()->openForLoading(filename))) {
- return false;
- }
-
- char desc[64];
-
- in->skip(4); // TODO: Verify marker 'SGAM'
- in->skip(4); // TODO: Verify size
- in->skip(2); // TODO: Verify version
- in->read(desc, 64);
- description = desc;
-
- delete in;
-
- return true;
-
+bool GameDatabaseV2::getSavegameDescription(const char *filename, Common::String &description) {
+ // Not used in version 2 games
+ return false;
}
-int16 GameDatabase::savegame(const char *filename, const char *description, int16 version) {
-
+int16 GameDatabaseV2::savegame(const char *filename, const char *description, int16 version) {
Common::OutSaveFile *out;
int16 result = 0;
-
if (!(out = g_system->getSavefileManager()->openForSaving(filename))) {
warning("Can't create file '%s', game not saved", filename);
return 6;
}
-
- switch (_vm->_engineVersion) {
- case 2:
- result = savegameV2(out, description, version);
- break;
- case 3:
- result = savegameV3(out, description, version);
- break;
- default:
- error("GameDatabase::savegame() Unknown engine version");
- }
-
+ // Variable 0 is not saved
+ out->write(_gameState + 2, _gameStateSize - 2);
+ for (uint i = 0; i < _objects.size(); i++)
+ _objects[i]->save(*out);
delete out;
-
return result;
-
}
-int16 GameDatabase::loadgame(const char *filename, int16 version) {
-
+int16 GameDatabaseV2::loadgame(const char *filename, int16 version) {
Common::InSaveFile *in;
int16 result = 0;
-
if (!(in = g_system->getSavefileManager()->openForLoading(filename))) {
warning("Can't open file '%s', game not loaded", filename);
return 1;
}
-
- switch (_vm->_engineVersion) {
- case 2:
- result = loadgameV2(in, version);
- break;
- case 3:
- result = loadgameV3(in, version);
- break;
- default:
- error("GameDatabase::loadgame() Unknown engine version");
+ // Variable 0 is not loaded
+ in->read(_gameState + 2, _gameStateSize - 2);
+ for (uint i = 0; i < _objects.size(); i++) {
+ _objects[i]->load(*in);
}
-
delete in;
-
return result;
-
-}
-
-int16 GameDatabase::savegameV2(Common::OutSaveFile *out, const char *description, int16 version) {
- // Variable 0 is not saved
- out->write(_gameState + 2, _gameStateSize - 2);
- for (uint i = 0; i < _objects.size(); i++)
- _objects[i]->saveVersion2(*out);
- return 0;
-}
-
-int16 GameDatabase::loadgameV2(Common::InSaveFile *in, int16 version) {
- // Variable 0 is not loaded
- in->read(_gameState + 2, _gameStateSize - 2);
- for (uint i = 0; i < _objects.size(); i++)
- _objects[i]->loadVersion2(*in);
- return 0;
}
-int16 GameDatabase::savegameV3(Common::OutSaveFile *out, const char *description, int16 version) {
- uint32 size = 4 + 4 + 2 + _gameStateSize;
- char desc[64];
- strncpy(desc, description, 64);
- out->writeUint32BE(MKID_BE('SGAM'));
- out->writeUint32LE(size);
- out->writeUint16LE(version);
- out->write(desc, 64);
- out->write(_gameState, _gameStateSize);
- return 0;
-}
-
-int16 GameDatabase::loadgameV3(Common::InSaveFile *in, int16 version) {
- //uint32 expectedSize = 4 + 4 + 2 + _gameStateSize;
- in->skip(4); // TODO: Verify marker 'SGAM'
- in->skip(4); // TODO: Verify size
- in->skip(2); // TODO: Verify version
- in->skip(64); // skip savegame description
- in->read(_gameState, _gameStateSize);
- return 0;
-}
-
-int16 GameDatabase::getVar(int16 index) {
- return (int16)READ_LE_UINT16(_gameState + index * 2);
-}
-
-void GameDatabase::setVar(int16 index, int16 value) {
- WRITE_LE_UINT16(_gameState + index * 2, value);
-}
-
-int16 *GameDatabase::getObjectPropertyPtrV2(int16 objectIndex, int16 propertyId, int16 &propertyFlag) {
+int16 *GameDatabaseV2::getObjectPropertyPtr(int16 objectIndex, int16 propertyId, int16 &propertyFlag) {
Object *obj = getObject(objectIndex);
int16 *prop = (int16*)obj->getData();
@@ -486,14 +439,11 @@ int16 *GameDatabase::getObjectPropertyPtrV2(int16 objectIndex, int16 propertyId,
// Now check in the object hierarchy of the given object
int16 parentObjectIndex = obj->getClass();
if (parentObjectIndex == 0) {
- debug(2, "GameDatabase::getObjectPropertyPtrV2() NULL(1)");
return NULL;
}
while (parentObjectIndex != 0) {
- //debug(2, "parentObjectIndex = %04X\n", parentObjectIndex);
-
obj = getObject(parentObjectIndex);
prop = (int16*)obj->getData();
@@ -525,12 +475,115 @@ int16 *GameDatabase::getObjectPropertyPtrV2(int16 objectIndex, int16 propertyId,
}
- debug(2, "GameDatabase::getObjectPropertyPtrV2() NULL(2)");
return NULL;
}
-int16 *GameDatabase::getObjectPropertyPtrV3(int16 objectIndex, int16 propertyId, int16 &propertyFlag) {
+const char *GameDatabaseV2::getString(uint16 offset) {
+ return (const char*)&_gameText[offset * 4];
+}
+
+
+/* GameDatabaseV3 */
+
+GameDatabaseV3::GameDatabaseV3(MadeEngine *vm) : GameDatabase(vm) {
+}
+
+void GameDatabaseV3::load(Common::SeekableReadStream &sourceS) {
+
+ // TODO: Read/verifiy header
+
+ sourceS.seek(0x1E);
+
+ uint32 objectIndexOffs = sourceS.readUint32LE();
+ uint16 objectCount = sourceS.readUint16LE();
+ uint32 gameStateOffs = sourceS.readUint32LE();
+ _gameStateSize = sourceS.readUint32LE();
+ 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);
+
+ _gameState = new byte[_gameStateSize];
+ sourceS.seek(gameStateOffs);
+ sourceS.read(_gameState, _gameStateSize);
+
+ Common::Array<uint32> objectOffsets;
+ sourceS.seek(objectIndexOffs);
+ for (uint32 i = 0; i < objectCount; i++)
+ objectOffsets.push_back(sourceS.readUint32LE());
+
+ 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);
+ } else {
+ obj->load(_gameState + objectOffsets[i]);
+ }
+ _objects.push_back(obj);
+ }
+
+}
+
+bool GameDatabaseV3::getSavegameDescription(const char *filename, Common::String &description) {
+ Common::InSaveFile *in;
+ char desc[64];
+ if (!(in = g_system->getSavefileManager()->openForLoading(filename))) {
+ return false;
+ }
+ in->skip(4); // TODO: Verify marker 'SGAM'
+ in->skip(4); // TODO: Verify size
+ in->skip(2); // TODO: Verify version
+ in->read(desc, 64);
+ description = desc;
+ delete in;
+ return true;
+}
+
+int16 GameDatabaseV3::savegame(const char *filename, const char *description, int16 version) {
+ Common::OutSaveFile *out;
+ char desc[64];
+ int16 result = 0;
+ uint32 size = 4 + 4 + 2 + _gameStateSize;
+ if (!(out = g_system->getSavefileManager()->openForSaving(filename))) {
+ warning("Can't create file '%s', game not saved", filename);
+ return 6;
+ }
+ strncpy(desc, description, 64);
+ out->writeUint32BE(MKID_BE('SGAM'));
+ out->writeUint32LE(size);
+ out->writeUint16LE(version);
+ out->write(desc, 64);
+ out->write(_gameState, _gameStateSize);
+ delete out;
+ return result;
+}
+
+int16 GameDatabaseV3::loadgame(const char *filename, int16 version) {
+ Common::InSaveFile *in;
+ int16 result = 0;
+ //uint32 expectedSize = 4 + 4 + 2 + _gameStateSize;
+ if (!(in = g_system->getSavefileManager()->openForLoading(filename))) {
+ warning("Can't open file '%s', game not loaded", filename);
+ return 1;
+ }
+ in->skip(4); // TODO: Verify marker 'SGAM'
+ in->skip(4); // TODO: Verify size
+ in->skip(2); // TODO: Verify version
+ in->skip(64); // skip savegame description
+ in->read(_gameState, _gameStateSize);
+ delete in;
+ return result;
+}
+
+int16 *GameDatabaseV3::getObjectPropertyPtr(int16 objectIndex, int16 propertyId, int16 &propertyFlag) {
Object *obj = getObject(objectIndex);
int16 *prop = (int16*)obj->getData();
@@ -558,14 +611,11 @@ int16 *GameDatabase::getObjectPropertyPtrV3(int16 objectIndex, int16 propertyId,
// Now check in the object hierarchy of the given object
int16 parentObjectIndex = obj->getClass();
if (parentObjectIndex == 0) {
- //debug(2, "! NULL(np)\n");
return NULL;
}
while (parentObjectIndex != 0) {
- //debug(2, "parentObjectIndex = %04X\n", parentObjectIndex);
-
obj = getObject(parentObjectIndex);
prop = (int16*)obj->getData();
@@ -607,70 +657,13 @@ int16 *GameDatabase::getObjectPropertyPtrV3(int16 objectIndex, int16 propertyId,
}
- //debug(2, "! NULL(nf)\n");
return NULL;
-
-}
-
-int16 *GameDatabase::getObjectPropertyPtr(int16 objectIndex, int16 propertyId, int16 &propertyFlag) {
- switch (_vm->_engineVersion) {
- case 2:
- return getObjectPropertyPtrV2(objectIndex, propertyId, propertyFlag);
- case 3:
- return getObjectPropertyPtrV3(objectIndex, propertyId, propertyFlag);
- default:
- error("GameDatabase::getObjectPropertyPtr() Unknown engine version");
- return NULL;
- }
-}
-
-int16 GameDatabase::getObjectProperty(int16 objectIndex, int16 propertyId) {
-
- if (objectIndex == 0)
- return 0;
-
- int16 propertyFlag;
- int16 *property = getObjectPropertyPtr(objectIndex, propertyId, propertyFlag);
- if (property) {
- return (int16)READ_LE_UINT16(property);
- } else {
- return 0;
- }
-
}
-int16 GameDatabase::setObjectProperty(int16 objectIndex, int16 propertyId, int16 value) {
-
- if (objectIndex == 0)
- return 0;
-
- int16 propertyFlag;
- int16 *property = getObjectPropertyPtr(objectIndex, propertyId, propertyFlag);
-
- if (property) {
- if (propertyFlag == 1) {
- WRITE_LE_UINT16(property, value);
- } else {
- warning("GameDatabase::setObjectProperty(%04X, %04X, %04X) Trying to set constant property\n",
- objectIndex, propertyId, value);
- }
- return value;
- } else {
- return 0;
- }
-
-}
-
-const char *GameDatabase::getString(uint16 offset) {
- return (const char*)&_gameText[offset * 4];
-}
-
-void GameDatabase::dumpObject(int16 index) {
- Object *obj = getObject(index);
- char fn[512];
- sprintf(fn, "obj%04X.0", index);
- obj->dump(fn);
+const char *GameDatabaseV3::getString(uint16 offset) {
+ // Not used in version 3 games
+ return NULL;
}
} // End of namespace Made
diff --git a/engines/made/database.h b/engines/made/database.h
index 0924200374..49655e41ae 100644
--- a/engines/made/database.h
+++ b/engines/made/database.h
@@ -40,29 +40,25 @@ namespace Made {
class Object {
public:
Object();
- ~Object();
+ virtual ~Object();
+
+ virtual int load(Common::SeekableReadStream &source) = 0;
+ virtual int load(byte *source) = 0;
+ virtual int save(Common::WriteStream &dest) = 0;
+ virtual uint16 getFlags() = 0;
+ virtual uint16 getClass() = 0;
+ virtual uint16 getSize() = 0;
+ virtual byte getCount1() = 0;
+ virtual byte getCount2() = 0;
+ virtual byte *getData() = 0;
+ virtual bool isConstant() = 0;
- int loadVersion2(Common::SeekableReadStream &source);
- int saveVersion2(Common::WriteStream &dest);
-
- int loadVersion3(Common::SeekableReadStream &source);
- int loadVersion3(byte *source);
-
- uint16 getFlags() const;
- uint16 getClass() const;
- uint16 getSize() const;
-
- byte getCount1() const;
- byte getCount2() const;
-
- byte *getData();
const char *getString();
void setString(const char *str);
bool isObject();
bool isVector();
- bool isConstant() const { return !(getFlags() & 1); }
-
+
int16 getVectorSize();
int16 getVectorItem(int16 index);
void setVectorItem(int16 index, int16 value);
@@ -75,20 +71,52 @@ protected:
byte *_objData;
};
+class ObjectV2 : public Object {
+public:
+ int load(Common::SeekableReadStream &source);
+ int load(byte *source);
+ int save(Common::WriteStream &dest);
+ uint16 getFlags();
+ uint16 getClass();
+ uint16 getSize();
+ byte getCount1();
+ byte getCount2();
+ byte *getData();
+
+ bool isConstant() {
+ return false;
+ }
+
+};
+
+class ObjectV3 : public Object {
+public:
+ int load(Common::SeekableReadStream &source);
+ int load(byte *source);
+ int save(Common::WriteStream &dest);
+ uint16 getFlags();
+ uint16 getClass();
+ uint16 getSize();
+ byte getCount1();
+ byte getCount2();
+ byte *getData();
+
+ bool isConstant() {
+ return !(getFlags() & 1);
+ }
+
+};
+
class GameDatabase {
public:
GameDatabase(MadeEngine *vm);
- ~GameDatabase();
+ virtual ~GameDatabase();
void open(const char *filename);
void openFromRed(const char *redFilename, const char *filename);
- bool getSavegameDescription(const char *filename, Common::String &description);
- int16 savegame(const char *filename, const char *description, int16 version);
- int16 loadgame(const char *filename, int16 version);
-
- Object *getObject(int16 index) const {
+ Object *getObject(int16 index) const {
if (index >= 1)
return _objects[index - 1];
else
@@ -101,32 +129,52 @@ public:
int16 getVar(int16 index);
void setVar(int16 index, int16 value);
-
- int16 *getObjectPropertyPtrV2(int16 objectIndex, int16 propertyId, int16 &propertyFlag);
- int16 *getObjectPropertyPtrV3(int16 objectIndex, int16 propertyId, int16 &propertyFlag);
- int16 *getObjectPropertyPtr(int16 objectIndex, int16 propertyId, int16 &propertyFlag);
-
+
+ virtual int16 *getObjectPropertyPtr(int16 objectIndex, int16 propertyId, int16 &propertyFlag) = 0;
+ virtual const char *getString(uint16 offset) = 0;
+ virtual bool getSavegameDescription(const char *filename, Common::String &description) = 0;
+ virtual int16 savegame(const char *filename, const char *description, int16 version) = 0;
+ virtual int16 loadgame(const char *filename, int16 version) = 0;
+
int16 getObjectProperty(int16 objectIndex, int16 propertyId);
int16 setObjectProperty(int16 objectIndex, int16 propertyId, int16 value);
-
- const char *getString(uint16 offset);
void dumpObject(int16 index);
-
+
protected:
MadeEngine *_vm;
Common::Array<Object*> _objects;
byte *_gameState;
uint32 _gameStateSize;
- char *_gameText;
int16 _mainCodeObjectIndex;
+ virtual void load(Common::SeekableReadStream &sourceS) = 0;
+};
+
+class GameDatabaseV2 : public GameDatabase {
+public:
+ GameDatabaseV2(MadeEngine *vm);
+ ~GameDatabaseV2();
+ int16 *getObjectPropertyPtr(int16 objectIndex, int16 propertyId, int16 &propertyFlag);
+ const char *getString(uint16 offset);
+ bool getSavegameDescription(const char *filename, Common::String &description);
+ int16 savegame(const char *filename, const char *description, int16 version);
+ int16 loadgame(const char *filename, int16 version);
+protected:
+ char *_gameText;
+ void load(Common::SeekableReadStream &sourceS);
+};
+
+class GameDatabaseV3 : public GameDatabase {
+public:
+ GameDatabaseV3(MadeEngine *vm);
+ int16 *getObjectPropertyPtr(int16 objectIndex, int16 propertyId, int16 &propertyFlag);
+ const char *getString(uint16 offset);
+ bool getSavegameDescription(const char *filename, Common::String &description);
+ int16 savegame(const char *filename, const char *description, int16 version);
+ int16 loadgame(const char *filename, int16 version);
+protected:
+ char *_gameText;
void load(Common::SeekableReadStream &sourceS);
- void loadVersion2(Common::SeekableReadStream &sourceS);
- void loadVersion3(Common::SeekableReadStream &sourceS);
- int16 savegameV2(Common::OutSaveFile *out, const char *description, int16 version);
- int16 loadgameV2(Common::InSaveFile *in, int16 version);
- int16 savegameV3(Common::OutSaveFile *out, const char *description, int16 version);
- int16 loadgameV3(Common::InSaveFile *in, int16 version);
};
} // End of namespace Made
diff --git a/engines/made/made.cpp b/engines/made/made.cpp
index 92efb881e2..da7ab23f5d 100644
--- a/engines/made/made.cpp
+++ b/engines/made/made.cpp
@@ -86,7 +86,15 @@ MadeEngine::MadeEngine(OSystem *syst, const MadeGameDescription *gameDesc) : Eng
_pmvPlayer = new PmvPlayer(this, _mixer);
_res = new ProjectReader();
_screen = new Screen(this);
- _dat = new GameDatabase(this);
+
+ if (getGameID() == GID_LGOP2 || getGameID() == GID_MANHOLE) {
+ _dat = new GameDatabaseV2(this);
+ } else if (getGameID() == GID_RTZ) {
+ _dat = new GameDatabaseV3(this);
+ } else {
+ error("Unknown GameID");
+ }
+
_script = new ScriptInterpreter(this);
int midiDriver = MidiDriver::detectMusicDriver(MDT_MIDI | MDT_ADLIB | MDT_PREFER_MIDI);