diff options
author | Max Horn | 2005-04-03 15:06:08 +0000 |
---|---|---|
committer | Max Horn | 2005-04-03 15:06:08 +0000 |
commit | b507231f7135f0af2a27b047f1982685736e0e7b (patch) | |
tree | 433e1dca1aa39631e819bad11fd2a08aa0aa1dc8 | |
parent | f63b35381b4b8e50cefb08103498dc195e38c29b (diff) | |
download | scummvm-rg350-b507231f7135f0af2a27b047f1982685736e0e7b.tar.gz scummvm-rg350-b507231f7135f0af2a27b047f1982685736e0e7b.tar.bz2 scummvm-rg350-b507231f7135f0af2a27b047f1982685736e0e7b.zip |
ScummEngine_v4 used to be a subclass of ScummEngine_v3, now it is the other way around; added a new class ScummEngine_v3old, for GF_OLD_BUNDLE games; took advantage of the new inheritance structure and turned various methods into virtual methods which then are overriden in subclasses
svn-id: r17346
-rw-r--r-- | scumm/intern.h | 23 | ||||
-rw-r--r-- | scumm/object.cpp | 6 | ||||
-rw-r--r-- | scumm/resource_v3.cpp | 211 | ||||
-rw-r--r-- | scumm/resource_v4.cpp | 133 | ||||
-rw-r--r-- | scumm/scumm.cpp | 378 | ||||
-rw-r--r-- | scumm/scumm.h | 6 |
6 files changed, 424 insertions, 333 deletions
diff --git a/scumm/intern.h b/scumm/intern.h index eb0a816e2d..944276c7ae 100644 --- a/scumm/intern.h +++ b/scumm/intern.h @@ -187,13 +187,14 @@ protected: void o5_walkActorToObject(); }; -class ScummEngine_v3 : public ScummEngine_v5 { +class ScummEngine_v4 : public ScummEngine_v5 { public: - ScummEngine_v3(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16]) : ScummEngine_v5(detector, syst, gs, md5sum) {} + ScummEngine_v4(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16]); protected: void readIndexFile(); void loadCharset(int no); + void loadRoomObjects(); void readMAXS(); void readGlobalObjects(); @@ -201,15 +202,25 @@ protected: void setupRoomObject(ObjectData *od, const byte *room, const byte *searchptr = NULL); }; -class ScummEngine_v4 : public ScummEngine_v3 { +class ScummEngine_v3 : public ScummEngine_v4 { public: - ScummEngine_v4(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16]) : ScummEngine_v3(detector, syst, gs, md5sum) {} + ScummEngine_v3(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16]); protected: void loadCharset(int no); }; -class ScummEngine_v2 : public ScummEngine_v3 { +class ScummEngine_v3old : public ScummEngine_v3 { +public: + ScummEngine_v3old(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16]); + +protected: + void readIndexFile(); + void initRoomSubBlocks(); + void loadRoomObjects(); +}; + +class ScummEngine_v2 : public ScummEngine_v3old { protected: void readIndexFile(); void readClassicIndexFile(); // V1 @@ -226,7 +237,7 @@ protected: const OpcodeEntryV2 *_opcodesV2; public: - ScummEngine_v2(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16]) : ScummEngine_v3(detector, syst, gs, md5sum) {} + ScummEngine_v2(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16]); virtual void scummInit(); diff --git a/scumm/object.cpp b/scumm/object.cpp index 3535b38fc2..262a5c5793 100644 --- a/scumm/object.cpp +++ b/scumm/object.cpp @@ -625,7 +625,7 @@ void ScummEngine::loadRoomObjects() { CHECK_HEAP } -void ScummEngine::loadRoomObjectsOldBundle() { +void ScummEngine_v3old::loadRoomObjects() { int i; ObjectData *od; const byte *room, *ptr; @@ -665,7 +665,7 @@ void ScummEngine::loadRoomObjectsOldBundle() { CHECK_HEAP } -void ScummEngine::loadRoomObjectsSmall() { +void ScummEngine_v4::loadRoomObjects() { int i, j; ObjectData *od; const byte *ptr; @@ -725,7 +725,7 @@ void ScummEngine::loadRoomObjectsSmall() { CHECK_HEAP } -void ScummEngine_v3::setupRoomObject(ObjectData *od, const byte *room, const byte *searchptr) { +void ScummEngine_v4::setupRoomObject(ObjectData *od, const byte *room, const byte *searchptr) { assert(room); const byte *ptr = room + od->OBCDoffset; diff --git a/scumm/resource_v3.cpp b/scumm/resource_v3.cpp index 5a81c0820e..31a1f7a4e7 100644 --- a/scumm/resource_v3.cpp +++ b/scumm/resource_v3.cpp @@ -23,145 +23,48 @@ #include "stdafx.h" #include "scumm/scumm.h" #include "scumm/intern.h" -#include "scumm/resource.h" namespace Scumm { -void ScummEngine_v3::readIndexFile() { - if (_features & GF_OLD_BUNDLE) { - int magic = 0; - debug(9, "readIndexFile()"); - - closeRoom(); - openRoom(0); - - magic = _fileHandle->readUint16LE(); - if (magic != 0x0100) - warning("The magic id doesn't match (0x%X)", magic); - - _numGlobalObjects = _fileHandle->readUint16LE(); - _fileHandle->seek(_numGlobalObjects * 4, SEEK_CUR); - _numRooms = _fileHandle->readByte(); - _fileHandle->seek(_numRooms * 3, SEEK_CUR); - _numCostumes = _fileHandle->readByte(); - _fileHandle->seek(_numCostumes * 3, SEEK_CUR); - _numScripts = _fileHandle->readByte(); - _fileHandle->seek(_numScripts * 3, SEEK_CUR); - _numSounds = _fileHandle->readByte(); - - _fileHandle->clearIOFailed(); - _fileHandle->seek(0, SEEK_SET); - - readMAXS(); - - // Jamieson630: palManipulate variable initialization - _palManipCounter = 0; - _palManipPalette = 0; // Will allocate when needed - _palManipIntermediatePal = 0; // Will allocate when needed - - _fileHandle->readUint16LE(); /* version magic number */ - readGlobalObjects(); - readResTypeList(rtRoom, MKID('ROOM'), "room"); - readResTypeList(rtCostume, MKID('COST'), "costume"); - readResTypeList(rtScript, MKID('SCRP'), "script"); - readResTypeList(rtSound, MKID('SOUN'), "sound"); - - closeRoom(); - } else { - uint16 blocktype; - uint32 itemsize; - int numblock = 0; - - debug(9, "readIndexFile()"); - - closeRoom(); - openRoom(0); - - while (!_fileHandle->eof()) { - itemsize = _fileHandle->readUint32LE(); - blocktype = _fileHandle->readUint16LE(); - if (_fileHandle->ioFailed()) - break; - - switch (blocktype) { - case 0x4E52: // 'NR' - _fileHandle->readUint16LE(); - break; - case 0x5230: // 'R0' - _numRooms = _fileHandle->readUint16LE(); - break; - case 0x5330: // 'S0' - _numScripts = _fileHandle->readUint16LE(); - break; - case 0x4E30: // 'N0' - _numSounds = _fileHandle->readUint16LE(); - break; - case 0x4330: // 'C0' - _numCostumes = _fileHandle->readUint16LE(); - break; - case 0x4F30: // 'O0' - _numGlobalObjects = _fileHandle->readUint16LE(); - break; - } - _fileHandle->seek(itemsize - 8, SEEK_CUR); - } - - _fileHandle->clearIOFailed(); - _fileHandle->seek(0, SEEK_SET); - - readMAXS(); - - // Jamieson630: palManipulate variable initialization - _palManipCounter = 0; - _palManipPalette = 0; // Will allocate when needed - _palManipIntermediatePal = 0; // Will allocate when needed - - while (1) { - itemsize = _fileHandle->readUint32LE(); - - if (_fileHandle->ioFailed()) - break; - - blocktype = _fileHandle->readUint16LE(); - - numblock++; - - switch (blocktype) { - - case 0x4E52: // 'NR' - _fileHandle->seek(itemsize - 6, SEEK_CUR); - break; - - case 0x5230: // 'R0' - readResTypeList(rtRoom, MKID('ROOM'), "room"); - break; - - case 0x5330: // 'S0' - readResTypeList(rtScript, MKID('SCRP'), "script"); - break; - - case 0x4E30: // 'N0' - readResTypeList(rtSound, MKID('SOUN'), "sound"); - break; - - case 0x4330: // 'C0' - readResTypeList(rtCostume, MKID('COST'), "costume"); - break; - - case 0x4F30: // 'O0' - readGlobalObjects(); - break; - - default: - // FIXME: this is a little hack because Indy3 FM-TOWNS has - // 32 extra bytes of unknown meaning appended to 00.LFL - if (!(_gameId == GID_INDY3 && _features & GF_FMTOWNS)) - error("Bad ID %c%c found in directory!", blocktype & 0xFF, blocktype >> 8); - return; - } - } - closeRoom(); - } +void ScummEngine_v3old::readIndexFile() { + int magic = 0; + debug(9, "readIndexFile()"); + + closeRoom(); + openRoom(0); + + magic = _fileHandle->readUint16LE(); + if (magic != 0x0100) + warning("The magic id doesn't match (0x%X)", magic); + + _numGlobalObjects = _fileHandle->readUint16LE(); + _fileHandle->seek(_numGlobalObjects * 4, SEEK_CUR); + _numRooms = _fileHandle->readByte(); + _fileHandle->seek(_numRooms * 3, SEEK_CUR); + _numCostumes = _fileHandle->readByte(); + _fileHandle->seek(_numCostumes * 3, SEEK_CUR); + _numScripts = _fileHandle->readByte(); + _fileHandle->seek(_numScripts * 3, SEEK_CUR); + _numSounds = _fileHandle->readByte(); + + _fileHandle->clearIOFailed(); + _fileHandle->seek(0, SEEK_SET); + + readMAXS(); + + // Jamieson630: palManipulate variable initialization + _palManipCounter = 0; + _palManipPalette = 0; // Will allocate when needed + _palManipIntermediatePal = 0; // Will allocate when needed + + _fileHandle->readUint16LE(); /* version magic number */ + readGlobalObjects(); + readResTypeList(rtRoom, MKID('ROOM'), "room"); + readResTypeList(rtCostume, MKID('COST'), "costume"); + readResTypeList(rtScript, MKID('SCRP'), "script"); + readResTypeList(rtSound, MKID('SOUN'), "sound"); + + closeRoom(); } void ScummEngine_v3::loadCharset(int no) { @@ -191,40 +94,4 @@ void ScummEngine_v3::loadCharset(int no) { file.close(); } -void ScummEngine_v3::readMAXS() { - // FIXME - I'm not sure for those values yet, they will have to be rechecked - - _numVariables = 800; // 800 - _numBitVariables = 4096; // 2048 - _numLocalObjects = 200; // 200 - _numArray = 50; - _numVerbs = 100; - _numNewNames = 50; - _objectRoomTable = NULL; - _numCharsets = 9; // 9 - _numInventory = 80; // 80 - _numGlobalScripts = 200; - _numFlObject = 50; - - _shadowPaletteSize = 256; - - _shadowPalette = (byte *) calloc(_shadowPaletteSize, 1); // FIXME - needs to be removed later - allocateArrays(); -} - -void ScummEngine_v3::readGlobalObjects() { - int num = _fileHandle->readUint16LE(); - assert(num == _numGlobalObjects); - for (int i = 0; i != num; i++) { - uint32 bits = _fileHandle->readByte(); - byte tmp; - bits |= _fileHandle->readByte() << 8; - bits |= _fileHandle->readByte() << 16; - _classData[i] = bits; - tmp = _fileHandle->readByte(); - _objectOwnerTable[i] = tmp & OF_OWNER_MASK; - _objectStateTable[i] = tmp >> OF_STATE_SHL; - } -} - } // End of namespace Scumm diff --git a/scumm/resource_v4.cpp b/scumm/resource_v4.cpp index be05f9c2d8..d40b2e87ca 100644 --- a/scumm/resource_v4.cpp +++ b/scumm/resource_v4.cpp @@ -23,9 +23,106 @@ #include "stdafx.h" #include "scumm/scumm.h" #include "scumm/intern.h" +#include "scumm/resource.h" namespace Scumm { +void ScummEngine_v4::readIndexFile() { + uint16 blocktype; + uint32 itemsize; + int numblock = 0; + + debug(9, "readIndexFile()"); + + closeRoom(); + openRoom(0); + + while (!_fileHandle->eof()) { + itemsize = _fileHandle->readUint32LE(); + blocktype = _fileHandle->readUint16LE(); + if (_fileHandle->ioFailed()) + break; + + switch (blocktype) { + case 0x4E52: // 'NR' + _fileHandle->readUint16LE(); + break; + case 0x5230: // 'R0' + _numRooms = _fileHandle->readUint16LE(); + break; + case 0x5330: // 'S0' + _numScripts = _fileHandle->readUint16LE(); + break; + case 0x4E30: // 'N0' + _numSounds = _fileHandle->readUint16LE(); + break; + case 0x4330: // 'C0' + _numCostumes = _fileHandle->readUint16LE(); + break; + case 0x4F30: // 'O0' + _numGlobalObjects = _fileHandle->readUint16LE(); + break; + } + _fileHandle->seek(itemsize - 8, SEEK_CUR); + } + + _fileHandle->clearIOFailed(); + _fileHandle->seek(0, SEEK_SET); + + readMAXS(); + + // Jamieson630: palManipulate variable initialization + _palManipCounter = 0; + _palManipPalette = 0; // Will allocate when needed + _palManipIntermediatePal = 0; // Will allocate when needed + + while (1) { + itemsize = _fileHandle->readUint32LE(); + + if (_fileHandle->ioFailed()) + break; + + blocktype = _fileHandle->readUint16LE(); + + numblock++; + + switch (blocktype) { + + case 0x4E52: // 'NR' + _fileHandle->seek(itemsize - 6, SEEK_CUR); + break; + + case 0x5230: // 'R0' + readResTypeList(rtRoom, MKID('ROOM'), "room"); + break; + + case 0x5330: // 'S0' + readResTypeList(rtScript, MKID('SCRP'), "script"); + break; + + case 0x4E30: // 'N0' + readResTypeList(rtSound, MKID('SOUN'), "sound"); + break; + + case 0x4330: // 'C0' + readResTypeList(rtCostume, MKID('COST'), "costume"); + break; + + case 0x4F30: // 'O0' + readGlobalObjects(); + break; + + default: + // FIXME: this is a little hack because Indy3 FM-TOWNS has + // 32 extra bytes of unknown meaning appended to 00.LFL + if (!(_gameId == GID_INDY3 && _features & GF_FMTOWNS)) + error("Bad ID %c%c found in directory!", blocktype & 0xFF, blocktype >> 8); + return; + } + } + closeRoom(); +} + void ScummEngine_v4::loadCharset(int no) { uint32 size; memset(_charsetData, 0, sizeof(_charsetData)); @@ -41,4 +138,40 @@ void ScummEngine_v4::loadCharset(int no) { closeRoom(); } +void ScummEngine_v4::readMAXS() { + // FIXME - I'm not sure for those values yet, they will have to be rechecked + + _numVariables = 800; // 800 + _numBitVariables = 4096; // 2048 + _numLocalObjects = 200; // 200 + _numArray = 50; + _numVerbs = 100; + _numNewNames = 50; + _objectRoomTable = NULL; + _numCharsets = 9; // 9 + _numInventory = 80; // 80 + _numGlobalScripts = 200; + _numFlObject = 50; + + _shadowPaletteSize = 256; + + _shadowPalette = (byte *) calloc(_shadowPaletteSize, 1); // FIXME - needs to be removed later + allocateArrays(); +} + +void ScummEngine_v4::readGlobalObjects() { + int num = _fileHandle->readUint16LE(); + assert(num == _numGlobalObjects); + for (int i = 0; i != num; i++) { + uint32 bits = _fileHandle->readByte(); + byte tmp; + bits |= _fileHandle->readByte() << 8; + bits |= _fileHandle->readByte() << 16; + _classData[i] = bits; + tmp = _fileHandle->readByte(); + _objectOwnerTable[i] = tmp & OF_OWNER_MASK; + _objectStateTable[i] = tmp >> OF_STATE_SHL; + } +} + } // End of namespace Scumm diff --git a/scumm/scumm.cpp b/scumm/scumm.cpp index 7f3d81c2d6..6d19ea5a64 100644 --- a/scumm/scumm.cpp +++ b/scumm/scumm.cpp @@ -754,7 +754,7 @@ ScummEngine::ScummEngine(GameDetector *detector, OSystem *syst, const ScummGameS _numObjectsInRoom = 0; _userPut = 0; _userState = 0; - _resourceHeaderSize = 0; + _resourceHeaderSize = 8; _saveLoadFlag = 0; _saveLoadSlot = 0; _lastSaveTime = 0; @@ -1198,6 +1198,24 @@ ScummEngine::~ScummEngine() { delete _debugger; } +ScummEngine_v4::ScummEngine_v4(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16]) + : ScummEngine_v5(detector, syst, gs, md5sum) { + _resourceHeaderSize = 6; +} + +ScummEngine_v3::ScummEngine_v3(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16]) + : ScummEngine_v4(detector, syst, gs, md5sum) { +} + +ScummEngine_v3old::ScummEngine_v3old(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16]) + : ScummEngine_v3(detector, syst, gs, md5sum) { + _resourceHeaderSize = 4; +} + +ScummEngine_v2::ScummEngine_v2(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16]) + : ScummEngine_v3old(detector, syst, gs, md5sum) { +} + ScummEngine_v6::ScummEngine_v6(GameDetector *detector, OSystem *syst, const ScummGameSettings &gs, uint8 md5sum[16]) : ScummEngine(detector, syst, gs, md5sum) { VAR_VIDEONAME = 0xFF; @@ -1346,13 +1364,6 @@ int ScummEngine::init(GameDetector &detector) { _bootParam = -1; } - if (_features & GF_OLD_BUNDLE) - _resourceHeaderSize = 4; - else if (_features & GF_SMALL_HEADER) - _resourceHeaderSize = 6; - else - _resourceHeaderSize = 8; - readIndexFile(); scummInit(); @@ -2207,12 +2218,7 @@ void ScummEngine::startScene(int room, Actor *a, int objectNr) { initRoomSubBlocks(); - if (_features & GF_OLD_BUNDLE) - loadRoomObjectsOldBundle(); - else if (_features & GF_SMALL_HEADER) - loadRoomObjectsSmall(); - else - loadRoomObjects(); + loadRoomObjects(); if (VAR_ROOM_WIDTH != 0xFF && VAR_ROOM_HEIGHT != 0xFF) { @@ -2297,33 +2303,12 @@ void ScummEngine::initRoomSubBlocks() { if (!roomptr || !roomResPtr) error("Room %d: data not found (" __FILE__ ":%d)", _roomResource, __LINE__); - // Reset room color for V1 zak - if (_version == 1) - _roomPalette[0] = 0; - // // Determine the room dimensions (width/height) // - if (_features & GF_OLD_BUNDLE) - rmhd = (const RoomHeader *)(roomptr + 4); - else - rmhd = (const RoomHeader *)findResourceData(MKID('RMHD'), roomptr); + rmhd = (const RoomHeader *)findResourceData(MKID('RMHD'), roomptr); - if (_version == 1) { - if (_features & GF_NES) { - _roomWidth = READ_LE_UINT16(roomptr + 4) * 8; - - // HACK: To let our code work normal with narrow rooms we - // adjust width. It will render garbage on right edge but we do - // not render it anyway - if (_roomWidth < 32 * 8) - _roomWidth = 32 * 8; - _roomHeight = READ_LE_UINT16(roomptr + 6) * 8; - } else { - _roomWidth = roomptr[4] * 8; - _roomHeight = roomptr[5] * 8; - } - } else if (_version == 8) { + if (_version == 8) { _roomWidth = READ_LE_UINT32(&(rmhd->v8.width)); _roomHeight = READ_LE_UINT32(&(rmhd->v8.height)); } else if (_version == 7) { @@ -2337,11 +2322,7 @@ void ScummEngine::initRoomSubBlocks() { // // Find the room image data // - if (_version == 1) { - _IM00_offs = 0; - } else if (_features & GF_OLD_BUNDLE) { - _IM00_offs = READ_LE_UINT16(roomptr + 0x0A); - } else if (_version == 8) { + if (_version == 8) { _IM00_offs = getObjectImage(roomptr, 1) - roomptr; } else if (_features & GF_SMALL_HEADER) { _IM00_offs = findResourceData(MKID('IM00'), roomptr) - roomptr; @@ -2356,44 +2337,20 @@ void ScummEngine::initRoomSubBlocks() { // // Look for an exit script // - int EXCD_len = -1; - if (_version <= 2) { - _EXCD_offs = READ_LE_UINT16(roomptr + 0x18); - EXCD_len = READ_LE_UINT16(roomptr + 0x1A) - _EXCD_offs + _resourceHeaderSize; // HACK - } else if (_features & GF_OLD_BUNDLE) { - _EXCD_offs = READ_LE_UINT16(roomptr + 0x19); - EXCD_len = READ_LE_UINT16(roomptr + 0x1B) - _EXCD_offs + _resourceHeaderSize; // HACK - } else { - ptr = findResourceData(MKID('EXCD'), roomResPtr); - if (ptr) - _EXCD_offs = ptr - roomResPtr; - } + ptr = findResourceData(MKID('EXCD'), roomResPtr); + if (ptr) + _EXCD_offs = ptr - roomResPtr; if (_dumpScripts && _EXCD_offs) - dumpResource("exit-", _roomResource, roomResPtr + _EXCD_offs - _resourceHeaderSize, EXCD_len); + dumpResource("exit-", _roomResource, roomResPtr + _EXCD_offs - _resourceHeaderSize, -1); // // Look for an entry script // - int ENCD_len = -1; - if (_version <= 2) { - _ENCD_offs = READ_LE_UINT16(roomptr + 0x1A); - ENCD_len = READ_LE_UINT16(roomptr) - _ENCD_offs + _resourceHeaderSize; // HACK - } else if (_features & GF_OLD_BUNDLE) { - _ENCD_offs = READ_LE_UINT16(roomptr + 0x1B); - // FIXME - the following is a hack which assumes that immediately after - // the entry script the first local script follows. - int num_objects = *(roomResPtr + 20); - int num_sounds = *(roomResPtr + 23); - int num_scripts = *(roomResPtr + 24); - ptr = roomptr + 29 + num_objects * 4 + num_sounds + num_scripts; - ENCD_len = READ_LE_UINT16(ptr + 1) - _ENCD_offs + _resourceHeaderSize; // HACK - } else { - ptr = findResourceData(MKID('ENCD'), roomResPtr); - if (ptr) - _ENCD_offs = ptr - roomResPtr; - } + ptr = findResourceData(MKID('ENCD'), roomResPtr); + if (ptr) + _ENCD_offs = ptr - roomResPtr; if (_dumpScripts && _ENCD_offs) - dumpResource("entry-", _roomResource, roomResPtr + _ENCD_offs - _resourceHeaderSize, ENCD_len); + dumpResource("entry-", _roomResource, roomResPtr + _ENCD_offs - _resourceHeaderSize, -1); // // Load box data @@ -2401,18 +2358,11 @@ void ScummEngine::initRoomSubBlocks() { res.nukeResource(rtMatrix, 1); res.nukeResource(rtMatrix, 2); if (_features & GF_SMALL_HEADER) { - if (_version <= 2) - ptr = roomptr + *(roomptr + 0x15); - else if (_features & GF_OLD_BUNDLE) - ptr = roomptr + READ_LE_UINT16(roomptr + 0x15); - else - ptr = findResourceData(MKID('BOXD'), roomptr); + ptr = findResourceData(MKID('BOXD'), roomptr); if (ptr) { byte numOfBoxes = *ptr; int size; - if (_version <= 2) - size = numOfBoxes * SIZEOF_BOX_V2 + 1; - else if (_version == 3) + if (_version == 3) size = numOfBoxes * SIZEOF_BOX_V3 + 1; else size = numOfBoxes * SIZEOF_BOX + 1; @@ -2420,14 +2370,8 @@ void ScummEngine::initRoomSubBlocks() { createResource(rtMatrix, 2, size); memcpy(getResourceAddress(rtMatrix, 2), ptr, size); ptr += size; - if (_version <= 2) { - size = numOfBoxes * (numOfBoxes + 1); - } else if (_features & GF_OLD_BUNDLE) - // FIXME. This is an evil HACK!!! - size = (READ_LE_UINT16(roomptr + 0x0A) - READ_LE_UINT16(roomptr + 0x15)) - size; - else - size = getResourceDataSize(ptr - size - _resourceHeaderSize) - size; + size = getResourceDataSize(ptr - size - _resourceHeaderSize) - size; if (size > 0) { // do this :) createResource(rtMatrix, 1, size); memcpy(getResourceAddress(rtMatrix, 1), ptr, size); @@ -2460,10 +2404,7 @@ void ScummEngine::initRoomSubBlocks() { for (i = 1; i < res.num[rtScaleTable]; i++) res.nukeResource(rtScaleTable, i); - if (_features & GF_OLD_BUNDLE) - ptr = 0; - else - ptr = findResourceData(MKID('SCAL'), roomptr); + ptr = findResourceData(MKID('SCAL'), roomptr); if (ptr) { int s1, s2, y1, y2; if (_version == 8) { @@ -2499,46 +2440,7 @@ void ScummEngine::initRoomSubBlocks() { memset(_localScriptOffsets, 0, sizeof(_localScriptOffsets)); - if (_features & GF_OLD_BUNDLE) { - int num_objects = *(roomResPtr + 20); - int num_sounds; - int num_scripts; - - if (_version <= 2) { - num_sounds = *(roomResPtr + 22); - num_scripts = *(roomResPtr + 23); - ptr = roomptr + 28 + num_objects * 4; - while (num_sounds--) - loadResource(rtSound, *ptr++); - while (num_scripts--) - loadResource(rtScript, *ptr++); - } else if (_version == 3) { - num_sounds = *(roomResPtr + 23); - num_scripts = *(roomResPtr + 24); - ptr = roomptr + 29 + num_objects * 4 + num_sounds + num_scripts; - while (*ptr) { - int id = *ptr; - - _localScriptOffsets[id - _numGlobalScripts] = READ_LE_UINT16(ptr + 1); - ptr += 3; - - if (_dumpScripts) { - char buf[32]; - sprintf(buf, "room-%d-", _roomResource); - - // HACK: to determine the sizes of the local scripts, we assume that - // a) their order in the data file is the same as in the index - // b) the last script at the same time is the last item in the room "header" - int len = - (int)_localScriptOffsets[id - _numGlobalScripts] + _resourceHeaderSize; - if (*ptr) - len += READ_LE_UINT16(ptr + 1); - else - len += READ_LE_UINT16(roomResPtr); - dumpResource(buf, id, roomResPtr + _localScriptOffsets[id - _numGlobalScripts] - _resourceHeaderSize, len); - } - } - } - } else if (_features & GF_SMALL_HEADER) { + if (_features & GF_SMALL_HEADER) { ResourceIterator localScriptIterator(searchptr, true); while ((ptr = localScriptIterator.findNext(MKID('LSCR'))) != NULL) { int id = 0; @@ -2617,14 +2519,9 @@ void ScummEngine::initRoomSubBlocks() { } // Locate the EGA palette (currently unused). - if (_features & GF_OLD_BUNDLE) - ptr = 0; - else - ptr = findResourceData(MKID('EPAL'), roomptr); - - if (ptr) { + ptr = findResourceData(MKID('EPAL'), roomptr); + if (ptr) _EPAL_offs = ptr - roomptr; - } // Locate the standard room palette (for V3-V5 games). // TODO: We used to use findResourceSmall instead of findResourceData; @@ -2637,10 +2534,7 @@ void ScummEngine::initRoomSubBlocks() { // // Of course this would break savegame compatibility unless extra code // were added to the save/load system to cope with this. - if (_features & GF_OLD_BUNDLE) - ptr = 0; - else - ptr = findResourceData(MKID('CLUT'), roomptr); + ptr = findResourceData(MKID('CLUT'), roomptr); if (ptr) { if ((_features & GF_SMALL_HEADER) && ptr) @@ -2668,8 +2562,6 @@ void ScummEngine::initRoomSubBlocks() { // Transparent color if (_version == 8) gdi._transparentColor = (byte)READ_LE_UINT32(&(rmhd->v8.transparency)); - else if (_features & GF_OLD_BUNDLE) - gdi._transparentColor = 255; else { ptr = findResourceData(MKID('TRNS'), roomptr); if (ptr) @@ -2704,6 +2596,193 @@ void ScummEngine::initRoomSubBlocks() { initBGBuffers(_roomHeight); } +void ScummEngine_v3old::initRoomSubBlocks() { + int i; + const byte *ptr; + byte *roomptr, *searchptr = 0; + const RoomHeader *rmhd; + + _ENCD_offs = 0; + _EXCD_offs = 0; + _EPAL_offs = 0; + _CLUT_offs = 0; + _PALS_offs = 0; + + memset(_extraBoxFlags, 0, sizeof(_extraBoxFlags)); + + // Determine the room and room script base address + roomptr = getResourceAddress(rtRoom, _roomResource); + if (!roomptr) + error("Room %d: data not found (" __FILE__ ":%d)", _roomResource, __LINE__); + + // Reset room color for V1 zak + if (_version == 1) + _roomPalette[0] = 0; + + // + // Determine the room dimensions (width/height) + // + rmhd = (const RoomHeader *)(roomptr + 4); + + if (_version == 1) { + if (_features & GF_NES) { + _roomWidth = READ_LE_UINT16(roomptr + 4) * 8; + + // HACK: To let our code work normal with narrow rooms we + // adjust width. It will render garbage on right edge but we do + // not render it anyway + if (_roomWidth < 32 * 8) + _roomWidth = 32 * 8; + _roomHeight = READ_LE_UINT16(roomptr + 6) * 8; + } else { + _roomWidth = roomptr[4] * 8; + _roomHeight = roomptr[5] * 8; + } + } else { + _roomWidth = READ_LE_UINT16(&(rmhd->old.width)); + _roomHeight = READ_LE_UINT16(&(rmhd->old.height)); + } + + // + // Find the room image data + // + if (_version == 1) { + _IM00_offs = 0; + } else { + _IM00_offs = READ_LE_UINT16(roomptr + 0x0A); + } + gdi.roomChanged(roomptr, _IM00_offs); + + // + // Look for an exit script + // + int EXCD_len = -1; + if (_version <= 2) { + _EXCD_offs = READ_LE_UINT16(roomptr + 0x18); + EXCD_len = READ_LE_UINT16(roomptr + 0x1A) - _EXCD_offs + _resourceHeaderSize; // HACK + } else { + _EXCD_offs = READ_LE_UINT16(roomptr + 0x19); + EXCD_len = READ_LE_UINT16(roomptr + 0x1B) - _EXCD_offs + _resourceHeaderSize; // HACK + } + if (_dumpScripts && _EXCD_offs) + dumpResource("exit-", _roomResource, roomptr + _EXCD_offs - _resourceHeaderSize, EXCD_len); + + // + // Look for an entry script + // + int ENCD_len = -1; + if (_version <= 2) { + _ENCD_offs = READ_LE_UINT16(roomptr + 0x1A); + ENCD_len = READ_LE_UINT16(roomptr) - _ENCD_offs + _resourceHeaderSize; // HACK + } else { + _ENCD_offs = READ_LE_UINT16(roomptr + 0x1B); + // FIXME - the following is a hack which assumes that immediately after + // the entry script the first local script follows. + int num_objects = *(roomptr + 20); + int num_sounds = *(roomptr + 23); + int num_scripts = *(roomptr + 24); + ptr = roomptr + 29 + num_objects * 4 + num_sounds + num_scripts; + ENCD_len = READ_LE_UINT16(ptr + 1) - _ENCD_offs + _resourceHeaderSize; // HACK + } + if (_dumpScripts && _ENCD_offs) + dumpResource("entry-", _roomResource, roomptr + _ENCD_offs - _resourceHeaderSize, ENCD_len); + + // + // Load box data + // + res.nukeResource(rtMatrix, 1); + res.nukeResource(rtMatrix, 2); + + if (_version <= 2) + ptr = roomptr + *(roomptr + 0x15); + else + ptr = roomptr + READ_LE_UINT16(roomptr + 0x15); + if (ptr) { + byte numOfBoxes = *ptr; + int size; + if (_version <= 2) + size = numOfBoxes * SIZEOF_BOX_V2 + 1; + else + size = numOfBoxes * SIZEOF_BOX_V3 + 1; + + createResource(rtMatrix, 2, size); + memcpy(getResourceAddress(rtMatrix, 2), ptr, size); + ptr += size; + if (_version <= 2) { + size = numOfBoxes * (numOfBoxes + 1); + } else { + // FIXME. This is an evil HACK!!! + size = (READ_LE_UINT16(roomptr + 0x0A) - READ_LE_UINT16(roomptr + 0x15)) - size; + } + + if (size > 0) { // do this :) + createResource(rtMatrix, 1, size); + memcpy(getResourceAddress(rtMatrix, 1), ptr, size); + } + + } + + // + // No scale data in old bundle games + // + for (i = 1; i < res.num[rtScaleTable]; i++) + res.nukeResource(rtScaleTable, i); + + // + // Setup local scripts + // + + // Determine the room script base address + roomptr = getResourceAddress(rtRoom, _roomResource); + searchptr = roomptr; + + memset(_localScriptOffsets, 0, sizeof(_localScriptOffsets)); + + int num_objects = *(roomptr + 20); + int num_sounds; + int num_scripts; + + if (_version <= 2) { + num_sounds = *(roomptr + 22); + num_scripts = *(roomptr + 23); + ptr = roomptr + 28 + num_objects * 4; + while (num_sounds--) + loadResource(rtSound, *ptr++); + while (num_scripts--) + loadResource(rtScript, *ptr++); + } else /* if (_version == 3) */ { + num_sounds = *(roomptr + 23); + num_scripts = *(roomptr + 24); + ptr = roomptr + 29 + num_objects * 4 + num_sounds + num_scripts; + while (*ptr) { + int id = *ptr; + + _localScriptOffsets[id - _numGlobalScripts] = READ_LE_UINT16(ptr + 1); + ptr += 3; + + if (_dumpScripts) { + char buf[32]; + sprintf(buf, "room-%d-", _roomResource); + + // HACK: to determine the sizes of the local scripts, we assume that + // a) their order in the data file is the same as in the index + // b) the last script at the same time is the last item in the room "header" + int len = - (int)_localScriptOffsets[id - _numGlobalScripts] + _resourceHeaderSize; + if (*ptr) + len += READ_LE_UINT16(ptr + 1); + else + len += READ_LE_UINT16(roomptr); + dumpResource(buf, id, roomptr + _localScriptOffsets[id - _numGlobalScripts] - _resourceHeaderSize, len); + } + } + } + + // Transparent color + gdi._transparentColor = 255; + + initBGBuffers(_roomHeight); +} + void ScummEngine::pauseGame() { pauseDialog(); } @@ -3193,7 +3272,10 @@ Engine *Engine_SCUMM_create(GameDetector *detector, OSystem *syst) { engine = new ScummEngine_v2(detector, syst, game, md5sum); break; case 3: - engine = new ScummEngine_v3(detector, syst, game, md5sum); + if (game.features & GF_OLD_BUNDLE) + engine = new ScummEngine_v3old(detector, syst, game, md5sum); + else + engine = new ScummEngine_v3(detector, syst, game, md5sum); break; case 4: engine = new ScummEngine_v4(detector, syst, game, md5sum); diff --git a/scumm/scumm.h b/scumm/scumm.h index 6806f2039d..cca3416350 100644 --- a/scumm/scumm.h +++ b/scumm/scumm.h @@ -689,11 +689,9 @@ protected: void convertADResource(int type, int index, byte *ptr, int size); int readSoundResourceSmallHeader(int type, int index); bool isResourceInUse(int type, int i) const; - void initRoomSubBlocks(); + virtual void initRoomSubBlocks(); void clearRoomObjects(); - void loadRoomObjects(); - void loadRoomObjectsSmall(); - void loadRoomObjectsOldBundle(); + virtual void loadRoomObjects(); virtual void readArrayFromIndexFile(); virtual void readMAXS(int blockSize); |