aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGregory Montoir2007-12-07 20:45:51 +0000
committerGregory Montoir2007-12-07 20:45:51 +0000
commit126f55fd0ec2cea7e8a397c4ba810d4c562ce3ae (patch)
treeeffa0b7edaa86f4aa68274a733a39873cc606bb3
parent4ae85163b777e4414cafcc13bfef42c6520f5034 (diff)
downloadscummvm-rg350-126f55fd0ec2cea7e8a397c4ba810d4c562ce3ae.tar.gz
scummvm-rg350-126f55fd0ec2cea7e8a397c4ba810d4c562ce3ae.tar.bz2
scummvm-rg350-126f55fd0ec2cea7e8a397c4ba810d4c562ce3ae.zip
backported some changes for OS
- added parsing of VOL.CNF to get the (filename,bundle) mapping (should be more efficient than testing every bundle file) - delphineUnpack allows "inplace unpacking", use this instead of allocating temporary buffers - relation script run count should be set in _localVars[0] - added comments for some "special" script variables svn-id: r29749
-rw-r--r--engines/cine/cine.cpp6
-rw-r--r--engines/cine/cine.h17
-rw-r--r--engines/cine/main_loop.cpp4
-rw-r--r--engines/cine/part.cpp350
-rw-r--r--engines/cine/rel.cpp1
-rw-r--r--engines/cine/rel.h1
-rw-r--r--engines/cine/various.cpp5
7 files changed, 140 insertions, 244 deletions
diff --git a/engines/cine/cine.cpp b/engines/cine/cine.cpp
index 7a8dfac60f..60f3efa1ae 100644
--- a/engines/cine/cine.cpp
+++ b/engines/cine/cine.cpp
@@ -52,6 +52,7 @@ CineEngine *g_cine;
CineEngine::CineEngine(OSystem *syst, const CINEGameDescription *gameDesc) : Engine(syst), _gameDescription(gameDesc) {
Common::addSpecialDebugLevel(kCineDebugScript, "Script", "Script debug level");
+ Common::addSpecialDebugLevel(kCineDebugPart, "Part", "Part debug level");
// Setup mixer
if (!_mixer->isReady()) {
@@ -117,6 +118,10 @@ void CineEngine::initialize() {
animDataTable = (AnimData *)malloc(NUM_MAX_ANIMDATA * sizeof(AnimData));
+ if (g_cine->getGameType() == Cine::GType_OS && g_cine->getPlatform() == Common::kPlatformPC) {
+ readVolCnf();
+ }
+
loadTextData("texte.dat", textDataPtr);
if (g_cine->getGameType() == Cine::GType_OS && !(g_cine->getFeatures() & GF_DEMO)) {
@@ -149,6 +154,7 @@ void CineEngine::initialize() {
relTable[i].obj1Param1 = 0;
relTable[i].obj1Param2 = 0;
relTable[i].obj2Param = 0;
+ relTable[i].runCount = 0;
}
for (i = 0; i < NUM_MAX_ANIMDATA; i++) {
diff --git a/engines/cine/cine.h b/engines/cine/cine.h
index b225f9490a..8d9fdb6f8e 100644
--- a/engines/cine/cine.h
+++ b/engines/cine/cine.h
@@ -30,6 +30,9 @@
#include "common/scummsys.h"
#include "common/file.h"
#include "common/util.h"
+#include "common/str.h"
+#include "common/hashmap.h"
+#include "common/hash-str.h"
#include "engines/engine.h"
@@ -61,6 +64,8 @@ enum CineGameFeatures {
struct CINEGameDescription;
+typedef Common::HashMap<Common::String, const char *, Common::CaseSensitiveString_Hash, Common::CaseSensitiveString_EqualTo> StringPtrHashMap;
+
class CineEngine : public Engine {
protected:
@@ -87,10 +92,14 @@ public:
Common::RandomSource _rnd;
+ Common::StringList _volumeResourceFiles;
+ StringPtrHashMap _volumeEntriesMap;
+
private:
void initialize(void);
bool makeLoad(char *saveName);
void mainLoop(int bootScriptIdx);
+ void readVolCnf();
bool _preLoad;
};
@@ -103,7 +112,10 @@ enum {
VAR_MOUSE_X_MODE = 253,
VAR_MOUSE_X_POS = 249,
VAR_MOUSE_Y_MODE = 251,
- VAR_MOUSE_Y_POS = 250
+ VAR_MOUSE_Y_POS = 250,
+ // OS only
+ VAR_BYPASS_PROTECTION = 255,
+ VAR_LOW_MEMORY = 0
};
enum {
@@ -113,7 +125,8 @@ enum {
};
enum {
- kCineDebugScript = 1 << 0
+ kCineDebugScript = 1 << 0,
+ kCineDebugPart = 1 << 1
};
enum {
diff --git a/engines/cine/main_loop.cpp b/engines/cine/main_loop.cpp
index 1f1622253e..04334e8b98 100644
--- a/engines/cine/main_loop.cpp
+++ b/engines/cine/main_loop.cpp
@@ -230,6 +230,10 @@ void CineEngine::mainLoop(int bootScriptIdx) {
globalVars[VAR_MOUSE_X_POS] = 0;
globalVars[VAR_MOUSE_Y_POS] = 0;
+ if (g_cine->getGameType() == Cine::GType_OS) {
+ globalVars[VAR_BYPASS_PROTECTION] = 0; // set to 1 to bypass the copy protection
+ globalVars[VAR_LOW_MEMORY] = 0; // set to 1 to disable some animations, sounds etc.
+ }
for (i = 0; i < 16; i++) {
c_palette[i] = 0;
diff --git a/engines/cine/part.cpp b/engines/cine/part.cpp
index b862d72b53..18c3a8787e 100644
--- a/engines/cine/part.cpp
+++ b/engines/cine/part.cpp
@@ -23,6 +23,8 @@
*
*/
+#include "common/endian.h"
+
#include "cine/cine.h"
#include "cine/unpack.h"
#include "cine/various.h"
@@ -71,187 +73,6 @@ void closePart(void) {
// TODO
}
-static const char *bundleNamesDOSEN[] = {
- "EGOUBASE",
- "LABYBASE",
- "PROCEGOU",
- "PROCLABY",
- "PROCS00",
- "PROCS01",
- "PROCS02",
- "PROCS03",
- "PROCS04",
- "PROCS06",
- "PROCS07",
- "PROCS08",
- "PROCS10",
- "PROCS12",
- "PROCS13",
- "PROCS15",
- "PROCS16",
- "RSC00",
- "RSC01",
- "RSC02",
- "RSC03",
- "RSC04",
- "RSC05",
- "RSC06",
- "RSC07",
- "RSC08",
- "RSC09",
- "RSC10",
- "RSC11",
- "RSC12",
- "RSC13",
- "RSC14",
- "RSC15",
- "RSC16",
- "RSC17",
- "SONS1",
- "SONS2",
- "SONS3",
- "SONS4",
- "SONS5",
- "SONS6",
- "SONS7",
- "SONS8",
- "SONS9",
- NULL
-};
-
-static const char *bundleNamesDOSUS[] = {
- "EGOUBASE",
- "LABYBASE",
- "PROCEGOU",
- "PROCLABY",
- "PROCS00",
- "PROCS01",
- "PROCS02",
- "PROCS03",
- "PROCS04",
- "PROCS06",
- "PROCS07",
- "PROCS08",
- "PROCS12",
- "PROCS13",
- "PROCS15",
- "PROCS16",
- "RSC00",
- "RSC02",
- "RSC03",
- "RSC04",
- "RSC05",
- "RSC06",
- "RSC07",
- "RSC08",
- "RSC09",
- "RSC10",
- "RSC11",
- "RSC12",
- "RSC13",
- "RSC14",
- "RSC15",
- "RSC16",
- "RSC17",
- "SONS31",
- "SONS32",
- "SONS33",
- "SONS34",
- NULL
-};
-
-static const char *bundleNamesDOSFR[] = {
- "EGOUBASE",
- "LABYBASE",
- "PROCEGOU",
- "PROCLABY",
- "PROCS00",
- "PROCS01",
- "PROCS02",
- "PROCS03",
- "PROCS04",
- "PROCS06",
- "PROCS07",
- "PROCS08",
- "PROCS10",
- "PROCS12",
- "PROCS13",
- "PROCS15",
- "PROCS16",
- "RSC00",
- "RSC01",
- "RSC02",
- "RSC03",
- "RSC04",
- "RSC05",
- "RSC06",
- "RSC07",
- "RSC08",
- "RSC09",
- "RSC10",
- "RSC11",
- "RSC12",
- "RSC13",
- "RSC14",
- "RSC15",
- "RSC16",
- "RSC17",
- "SONS31",
- "SONS32",
- "SONS33",
- "SONS34",
- NULL
-};
-
-static const char *bundleNamesDOSES[] = {
- "EGOUBASE",
- "LABYBASE",
- "PROCS1",
- "PROCS2",
- "PROCS3",
- "PROCS4",
- "PROCS5",
- "PROCS6",
- "SD01A",
- "SD01B",
- "SD01C",
- "SD01D",
- "SD021",
- "SD022",
- "SD03",
- "SDSONS",
- "SDSONS2",
- "SDSONS3",
- "SINTRO2",
- NULL
-};
-
-static const char *bundleNamesDOSInt[] = {
- "EGOUBASE",
- "LABYBASE",
- "PROCS1",
- "PROCS2",
- "PROCS3",
- "PROCS4",
- "PROCS5",
- "PROCS6",
- "SD01A",
- "SD01B",
- "SD01C",
- "SD01D",
- "SD021",
- "SD022",
- "SD03",
- "SDS1",
- "SDS2",
- "SDS3",
- "SDS4",
- "SDS5",
- "SDS6",
- "SINTRO2",
- NULL
-};
-
static const char *bundleNamesAmiga[] = {
"EGOUBASE",
"LABYBASE",
@@ -300,69 +121,120 @@ static const char *bundleNamesAtari[] = {
NULL
};
-int16 findFileInBundle(const char *fileName) {
- uint16 i;
+static void fixVolCnfFileName(char *dst, const uint8 *src) {
+ memcpy(dst, src, 8); src += 8;
+ dst[8] = 0;
+ char *ext = strchr(dst, ' ');
+ if (!ext) {
+ ext = &dst[8];
+ }
+ if (*src == ' ') {
+ *ext = 0;
+ } else {
+ *ext++ = '.';
+ memcpy(ext, src, 3);
+ char *end = strchr(ext, ' ');
+ if (!end) {
+ end = &ext[3];
+ }
+ *end = 0;
+ }
+}
+void CineEngine::readVolCnf() {
+ Common::File f;
+ if (!f.open("vol.cnf")) {
+ error("Unable to open 'vol.cnf'");
+ }
+ f.seek(8, SEEK_SET);
+ uint32 unpackedSize = f.readUint32BE();
+ uint32 packedSize = f.readUint32BE();
+ uint8 *buf = (uint8 *)malloc(unpackedSize);
+ if (!buf) {
+ error("Unable to allocate %d bytes", unpackedSize);
+ }
+ f.read(buf, packedSize);
+ if (packedSize != unpackedSize) {
+ bool b = delphineUnpack(buf, buf, packedSize);
+ if (!b) {
+ error("Error while unpacking 'vol.cnf' data");
+ }
+ }
+ uint8 *p = buf;
+ int resourceFilesCount = READ_BE_UINT16(p); p += 2;
+ int entrySize = READ_BE_UINT16(p); p += 2;
+ for (int i = 0; i < resourceFilesCount; ++i) {
+ char volumeResourceFile[9];
+ memcpy(volumeResourceFile, p, 8);
+ volumeResourceFile[8] = 0;
+ _volumeResourceFiles.push_back(volumeResourceFile);
+ p += entrySize;
+ }
+
+ int volumeEntriesCount = 0;
+ for (int i = 0; i < resourceFilesCount; ++i) {
+ int size = READ_BE_UINT32(p); p += 4;
+ assert((size % 11) == 0);
+ volumeEntriesCount += size / 11;
+ p += size;
+ }
+
+ p = buf + 4 + resourceFilesCount * entrySize;
+ for (int i = 0; i < resourceFilesCount; ++i) {
+ int count = READ_BE_UINT32(p) / 11; p += 4;
+ while (count--) {
+ char volumeEntryName[12];
+ fixVolCnfFileName(volumeEntryName, p);
+ _volumeEntriesMap.setVal(volumeEntryName, _volumeResourceFiles[i].c_str());
+ debugC(5, kCineDebugPart, "Added volume entry name '%s' resource file '%s'\n", volumeEntryName, _volumeResourceFiles[i].c_str());
+ p += 11;
+ }
+ }
+
+ free(buf);
+}
+
+int16 findFileInBundle(const char *fileName) {
if (g_cine->getGameType() == Cine::GType_OS) {
- for (i = 0; i < numElementInPart; i++) {
+ // look first in currently loaded resource file
+ for (int i = 0; i < numElementInPart; i++) {
if (!scumm_stricmp(fileName, partBuffer[i].partName)) {
return i;
}
}
-
- const char **bPtr = 0;
-
+ // not found, open the required resource file
if (g_cine->getPlatform() == Common::kPlatformPC) {
- switch (g_cine->getLanguage()) {
- case Common::EN_GRB:
- bPtr = bundleNamesDOSEN;
- break;
- case Common::EN_USA:
- if (g_cine->getFeatures() & GF_CD)
- bPtr = bundleNamesDOSUS;
- else
- bPtr = bundleNamesDOSInt;
- break;
- case Common::DE_DEU:
- case Common::IT_ITA:
- bPtr = bundleNamesDOSInt;
- break;
- case Common::ES_ESP:
- if (g_cine->getFeatures() & GF_CD)
- bPtr = bundleNamesDOSInt;
- else
- bPtr = bundleNamesDOSES;
- break;
- case Common::FR_FRA:
- bPtr = bundleNamesDOSFR;
- break;
- default:
- break;
+ StringPtrHashMap::const_iterator it = g_cine->_volumeEntriesMap.find(fileName);
+ if (it == g_cine->_volumeEntriesMap.end()) {
+ warning("Unable to find part file for filename '%s'", fileName);
+ return -1;
}
- } else if (g_cine->getPlatform() == Common::kPlatformAmiga) {
- if (g_cine->getFeatures() & GF_DEMO)
- bPtr = bundleNamesAmigaDemo;
- else
- bPtr = bundleNamesAmiga;
- } else if (g_cine->getPlatform() == Common::kPlatformAtariST) {
+ const char *part = (*it)._value;
+ loadPart(part);
+ } else {
+ // special case for Amiga & Atari versions
+ // TODO: handle it like the original interpreter does
+ const char **bPtr = 0;
+ if (g_cine->getPlatform() == Common::kPlatformAmiga) {
+ bPtr = (g_cine->getFeatures() & GF_DEMO) ? bundleNamesAmigaDemo : bundleNamesAmiga;
+ } else if (g_cine->getPlatform() == Common::kPlatformAtariST) {
bPtr = bundleNamesAtari;
- }
-
- while (*bPtr) {
- loadPart(*bPtr);
-
- for (i = 0; i < numElementInPart; i++) {
- if (!scumm_stricmp(fileName, partBuffer[i].partName)) {
- return i;
+ }
+ while (*bPtr) {
+ loadPart(*bPtr);
+ for (int i = 0; i < numElementInPart; i++) {
+ if (!scumm_stricmp(fileName, partBuffer[i].partName)) {
+ return i;
+ }
}
+ bPtr++;
}
- bPtr++;
+ return -1;
}
- } else {
- for (i = 0; i < numElementInPart; i++) {
- if (!scumm_stricmp(fileName, partBuffer[i].partName)) {
- return i;
- }
+ }
+ for (int i = 0; i < numElementInPart; i++) {
+ if (!scumm_stricmp(fileName, partBuffer[i].partName)) {
+ return i;
}
}
return -1;
@@ -376,17 +248,11 @@ void readFromPart(int16 idx, byte *dataPtr) {
}
byte *readBundleFile(int16 foundFileIdx) {
- byte *dataPtr;
-
- dataPtr = (byte *)calloc(partBuffer[foundFileIdx].unpackedSize, 1);
-
+ assert(foundFileIdx >= 0 && foundFileIdx < numElementInPart);
+ byte *dataPtr = (byte *)calloc(partBuffer[foundFileIdx].unpackedSize, 1);
if (partBuffer[foundFileIdx].unpackedSize != partBuffer[foundFileIdx].packedSize) {
- byte *unpackBuffer;
-
- unpackBuffer = (byte *)malloc(partBuffer[foundFileIdx].packedSize);
- readFromPart(foundFileIdx, unpackBuffer);
- delphineUnpack(dataPtr, unpackBuffer, partBuffer[foundFileIdx].packedSize);
- free(unpackBuffer);
+ readFromPart(foundFileIdx, dataPtr);
+ delphineUnpack(dataPtr, dataPtr, partBuffer[foundFileIdx].packedSize);
} else {
readFromPart(foundFileIdx, dataPtr);
}
diff --git a/engines/cine/rel.cpp b/engines/cine/rel.cpp
index 2fed7c2ff3..15697c2cf1 100644
--- a/engines/cine/rel.cpp
+++ b/engines/cine/rel.cpp
@@ -84,6 +84,7 @@ void loadRel(char *pRelName) {
relTable[i].obj1Param1 = READ_BE_UINT16(ptr); ptr += 2;
relTable[i].obj1Param2 = READ_BE_UINT16(ptr); ptr += 2;
relTable[i].obj2Param = READ_BE_UINT16(ptr); ptr += 2;
+ relTable[i].runCount = 0;
}
for (i = 0; i < numEntry; i++) {
diff --git a/engines/cine/rel.h b/engines/cine/rel.h
index dbdab7e8af..3e8332a55e 100644
--- a/engines/cine/rel.h
+++ b/engines/cine/rel.h
@@ -34,6 +34,7 @@ struct RelObjectScript {
uint16 obj1Param1;
uint16 obj1Param2;
uint16 obj2Param;
+ uint16 runCount;
};
#define NUM_MAX_REL 255
diff --git a/engines/cine/various.cpp b/engines/cine/various.cpp
index 378437babf..bb97ba3188 100644
--- a/engines/cine/various.cpp
+++ b/engines/cine/various.cpp
@@ -171,6 +171,11 @@ void runObjectScript(int16 entryIdx) {
pNewElement->scriptPtr = (byte *)relTable[entryIdx].data;
pNewElement->scriptIdx = entryIdx;
+ if (g_cine->getGameType() == Cine::GType_OS) {
+ pNewElement->localVars[0] = relTable[entryIdx].runCount;
+ ++relTable[entryIdx].runCount;
+ }
+
computeScriptStack(pNewElement->scriptPtr, pNewElement->stack, relTable[entryIdx].size);
}