aboutsummaryrefslogtreecommitdiff
path: root/scumm
diff options
context:
space:
mode:
authorMax Horn2005-04-03 15:06:08 +0000
committerMax Horn2005-04-03 15:06:08 +0000
commitb507231f7135f0af2a27b047f1982685736e0e7b (patch)
tree433e1dca1aa39631e819bad11fd2a08aa0aa1dc8 /scumm
parentf63b35381b4b8e50cefb08103498dc195e38c29b (diff)
downloadscummvm-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
Diffstat (limited to 'scumm')
-rw-r--r--scumm/intern.h23
-rw-r--r--scumm/object.cpp6
-rw-r--r--scumm/resource_v3.cpp211
-rw-r--r--scumm/resource_v4.cpp133
-rw-r--r--scumm/scumm.cpp378
-rw-r--r--scumm/scumm.h6
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);