diff options
-rw-r--r-- | engines/made/database.cpp | 123 | ||||
-rw-r--r-- | engines/made/database.h | 7 | ||||
-rw-r--r-- | engines/made/script.cpp | 19 |
3 files changed, 109 insertions, 40 deletions
diff --git a/engines/made/database.cpp b/engines/made/database.cpp index 4862d4706d..f7fce52b21 100644 --- a/engines/made/database.cpp +++ b/engines/made/database.cpp @@ -39,7 +39,7 @@ namespace Made { < 0x7FFE object */ -Object::Object() { +Object::Object() : _objData(NULL), _freeData(false) { } Object::~Object() { @@ -48,23 +48,38 @@ Object::~Object() { } int Object::loadVersion2(Common::SeekableReadStream &source) { + + if (_freeData && _objData) + delete[] _objData; + _freeData = true; - uint16 type = source.readUint16LE(); + + byte header[4]; + source.read(header, 4); + + uint16 type = READ_LE_UINT16(header); if (type == 0x7FFF) { - _objSize = source.readUint16LE(); + _objSize = READ_LE_UINT16(header + 2); } else if (type == 0x7FFE) { - _objSize = source.readUint16LE() * 2; + _objSize = READ_LE_UINT16(header + 2) * 2; } else if (type < 0x7FFE) { - byte count1 = source.readByte(); - byte count2 = source.readByte(); + byte count1 = header[2]; + byte count2 = header[3]; _objSize = (count1 + count2) * 2; } - source.seek(-4, SEEK_CUR); _objSize += 6; _objData = new byte[_objSize]; WRITE_LE_UINT16(_objData, 1); - source.read(_objData + 2, _objSize - 2); + memcpy(_objData + 2, header, 4); + source.read(_objData + 6, _objSize - 6); + return _objSize - 2; + +} + +int Object::saveVersion2(Common::WriteStream &dest) { + dest.write(_objData + 2, _objSize - 2); + return 0; } int Object::loadVersion3(Common::SeekableReadStream &source) { @@ -273,8 +288,7 @@ void GameDatabase::loadVersion2(Common::SeekableReadStream &sourceS) { Object *obj = new Object(); int objSize = obj->loadVersion2(sourceS); // objects are aligned on 2-byte-boundaries, skip unused bytes - objSize = objSize % 2; - sourceS.skip(objSize); + sourceS.skip(objSize % 2); _objects.push_back(obj); } @@ -312,14 +326,14 @@ void GameDatabase::loadVersion3(Common::SeekableReadStream &sourceS) { // 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); obj->loadVersion3(sourceS); } else { - debug(2, "-> var\n"); + //debug(2, "-> var\n"); obj->loadVersion3(_gameState + objectOffsets[i]); } _objects.push_back(obj); @@ -343,8 +357,6 @@ bool GameDatabase::getSavegameDescription(const char *filename, Common::String & in->read(desc, 64); description = desc; - //printf("description = %s\n", description.c_str()); fflush(stdout); - delete in; return true; @@ -354,50 +366,93 @@ bool GameDatabase::getSavegameDescription(const char *filename, Common::String & int16 GameDatabase::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; } - 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); + 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"); + } delete out; - return 0; + return result; } int16 GameDatabase::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; } - //uint32 expectedSize = 4 + 4 + 2 + _gameStateSize; + switch (_vm->_engineVersion) { + case 2: + result = loadgameV2(in, version); + break; + case 3: + result = loadgameV3(in, version); + break; + default: + error("GameDatabase::loadgame() Unknown engine version"); + } + + 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); - - delete in; - return 0; - } int16 GameDatabase::getVar(int16 index) { @@ -431,7 +486,7 @@ 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, "! NULL(np)\n"); + debug(2, "GameDatabase::getObjectPropertyPtrV2() NULL(1)"); return NULL; } @@ -470,7 +525,7 @@ int16 *GameDatabase::getObjectPropertyPtrV2(int16 objectIndex, int16 propertyId, } - //debug(2, "! NULL(nf)\n"); + debug(2, "GameDatabase::getObjectPropertyPtrV2() NULL(2)"); return NULL; } @@ -597,7 +652,7 @@ int16 GameDatabase::setObjectProperty(int16 objectIndex, int16 propertyId, int16 if (propertyFlag == 1) { WRITE_LE_UINT16(property, value); } else { - debug(2, "GameDatabase::setObjectProperty(%04X, %04X, %04X) Trying to set constant property\n", + warning("GameDatabase::setObjectProperty(%04X, %04X, %04X) Trying to set constant property\n", objectIndex, propertyId, value); } return value; diff --git a/engines/made/database.h b/engines/made/database.h index b92bd8f2dd..50e37d6936 100644 --- a/engines/made/database.h +++ b/engines/made/database.h @@ -41,7 +41,10 @@ class Object { public: Object(); ~Object(); + int loadVersion2(Common::SeekableReadStream &source); + int saveVersion2(Common::WriteStream &dest); + int loadVersion3(Common::SeekableReadStream &source); int loadVersion3(byte *source); @@ -118,6 +121,10 @@ protected: 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/script.cpp b/engines/made/script.cpp index 6e896d94be..ad1411281c 100644 --- a/engines/made/script.cpp +++ b/engines/made/script.cpp @@ -476,12 +476,19 @@ void ScriptInterpreter::cmd_yorn() { } void ScriptInterpreter::cmd_save() { - warning("Unimplemented command: cmd_save"); - _stack.setTop(0); + int16 result = 0; + int16 stringOfs = _stack.top(); + const char *filename = _vm->_dat->getString(stringOfs); + result = _vm->_dat->savegame(filename, "", 0); + _stack.setTop(result); } void ScriptInterpreter::cmd_restore() { - warning("Unimplemented command: cmd_restore"); + int16 result = 0; + int16 stringOfs = _stack.top(); + const char *filename = _vm->_dat->getString(stringOfs); + result = _vm->_dat->loadgame(filename, 0); + _stack.setTop(result); } void ScriptInterpreter::cmd_arg() { @@ -594,12 +601,12 @@ void ScriptInterpreter::cmd_extend() { int16 *argv = _stack.getStackPtr(); //debug(4, "func = %d (%s); argc = %d", func, extendFuncNames[func], argc); - debug(4, "func = %d; argc = %d", func, argc); + debug(2, "func = %d; argc = %d", func, argc); for (int i = 0; i < argc; i++) - debug(4, "argv[%02d] = %04X (%d)", i, argv[i], argv[i]); + debug(2, "argv[%02d] = %04X (%d)", i, argv[i], argv[i]); int16 result = _functions->callFunction(func, argc, argv); - debug(4, "result = %04X (%d)", result, result); + debug(2, "result = %04X (%d)", result, result); _stack.free(argc); |