From 3fdc69941108f98bde114b3528c56c720630cbdb Mon Sep 17 00:00:00 2001 From: Florian Kagerer Date: Mon, 11 Aug 2008 14:47:50 +0000 Subject: LOL: add support for floppy installer files (startup will fail nonethelesse since we have different pak file names) svn-id: r33777 --- engines/kyra/detection.cpp | 28 +++++++++++++++++--- engines/kyra/lol.cpp | 7 +++-- engines/kyra/resource.cpp | 64 ++++++++++++++++++++++++++++++++++++---------- 3 files changed, 80 insertions(+), 19 deletions(-) (limited to 'engines') diff --git a/engines/kyra/detection.cpp b/engines/kyra/detection.cpp index f8aa44be63..160a60d6f4 100644 --- a/engines/kyra/detection.cpp +++ b/engines/kyra/detection.cpp @@ -67,11 +67,14 @@ namespace { #define KYRA3_CD_FAN_FLAGS(x, y) FLAGS_FAN(x, y, false, false, true, false, true, false, Kyra::GI_KYRA3) #define LOL_CD_FLAGS FLAGS(false, false, true, false, false, false, Kyra::GI_LOL) +#define LOL_FLOPPY_FLAGS FLAGS(false, false, false, false, false, false, Kyra::GI_LOL) +#define LOL_FLOPPY_CMP_FLAGS FLAGS(false, false, false, false, false, true, Kyra::GI_LOL) #define LOL_PC98_FLAGS FLAGS(false, false, false, false, false, false, Kyra::GI_LOL) #define LOL_PC98_SJIS_FLAGS FLAGS(false, false, false, true, false, false, Kyra::GI_LOL) #define LOL_DEMO_FLAGS FLAGS(true, false, false, false, false, false, Kyra::GI_KYRA2) const KYRAGameDescription adGameDescs[] = { + /* disable these targets until they get supported { { "kyra1", @@ -83,6 +86,7 @@ const KYRAGameDescription adGameDescs[] = { }, KYRA1_FLOPPY_CMP_FLAGS }, + { { "kyra1", @@ -94,6 +98,8 @@ const KYRAGameDescription adGameDescs[] = { }, KYRA1_FLOPPY_CMP_FLAGS }, + */ + { { "kyra1", @@ -696,7 +702,7 @@ const KYRAGameDescription adGameDescs[] = { KYRA3_CD_FAN_FLAGS(Common::ES_ESP, Common::EN_ANY) }, - // Itlian fan translation, see fr#2003504 "KYRA: add support for Italian version of Kyrandia 2&3" + // Italian fan translation, see fr#2003504 "KYRA: add support for Italian version of Kyrandia 2&3" { { "kyra3", @@ -839,8 +845,24 @@ const KYRAGameDescription adGameDescs[] = { }, LOL_CD_FLAGS }, - - /*{ + + { + { + "lol", + 0, + { + { "WESTWOOD.1", 0, "3c61cb7de5b2ec452f5851f5075207ee", -1 }, + { 0, 0, 0, 0 } + }, + Common::DE_DEU, + Common::kPlatformPC, + Common::ADGF_NO_FLAGS + }, + LOL_FLOPPY_CMP_FLAGS + }, + + /* disable these targets until they get supported + { { "lol", 0, diff --git a/engines/kyra/lol.cpp b/engines/kyra/lol.cpp index a3ad01ce50..6624dd91ea 100644 --- a/engines/kyra/lol.cpp +++ b/engines/kyra/lol.cpp @@ -259,11 +259,14 @@ void LoLEngine::setupPrologueData(bool load) { "xxx/intro9.pak" }; - char filename[32]; + char filepath[32]; + char *filename = filepath; for (uint i = 0; i < ARRAYSIZE(fileList); ++i) { strcpy(filename, fileList[i]); memcpy(filename, _languageExt[_lang], 3); - + if (!_flags.isTalkie) + filename += 4; + if (load) { if (!_res->loadPakFile(filename)) error("Couldn't load file: '%s'", filename); diff --git a/engines/kyra/resource.cpp b/engines/kyra/resource.cpp index 91150ad354..d3b66ba6c6 100644 --- a/engines/kyra/resource.cpp +++ b/engines/kyra/resource.cpp @@ -103,6 +103,9 @@ bool Resource::reset() { return true; } else if (_vm->game() == GI_LOL) { + if (_vm->gameFlags().useInstallerPackage) + tryLoadCompFiles(); + return true; } @@ -1257,10 +1260,17 @@ uint8 FileExpander::calcCmdAndIndex(const uint8 *tbl, int16 ¶) { class CompLoaderInsHof : public CompArchiveLoader { public: - bool checkForFiles() const; - bool loadFile(CompFileMap &loadTo) const; + CompLoaderInsHof() { + _fileExtP = "%03d"; + _checkFile1 = "WESTWOOD.001"; + _checkFile2 = "WESTWOOD.002"; + _containerOffset = 6; + } -private: + virtual bool checkForFiles() const; + virtual bool loadFile(CompFileMap &loadTo) const; + +protected: struct Archive { Common::String filename; uint32 firstFile; @@ -1269,10 +1279,25 @@ private: uint32 endOffset; uint32 totalSize; }; + + const char *_fileExtP; + const char *_checkFile1; + const char *_checkFile2; + uint8 _containerOffset; +}; + +class CompLoaderInsLol : public CompLoaderInsHof { +public: + CompLoaderInsLol() { + _fileExtP = "%d"; + _checkFile1 = "WESTWOOD.1"; + _checkFile2 = "WESTWOOD.2"; + _containerOffset = 0; + } }; bool CompLoaderInsHof::checkForFiles() const { - return (Common::File::exists("WESTWOOD.001") && Common::File::exists("WESTWOOD.002")); + return (Common::File::exists(_checkFile1) && Common::File::exists(_checkFile2)); } bool CompLoaderInsHof::loadFile(CompFileMap &loadTo) const { @@ -1294,7 +1319,7 @@ bool CompLoaderInsHof::loadFile(CompFileMap &loadTo) const { Common::List archives; for (int8 currentFile = 1; currentFile; currentFile++) { - sprintf(filenameExt, "%03d", currentFile); + sprintf(filenameExt, _fileExtP, currentFile); filenameTemp = filenameBase + Common::String(filenameExt); if (!tmpFile.open(filenameTemp)) { @@ -1310,9 +1335,9 @@ bool CompLoaderInsHof::loadFile(CompFileMap &loadTo) const { if (startFile) { size -= 4; if (fileId == currentFile) { - size -= 6; - pos += 6; - tmpFile.seek(6, SEEK_CUR); + size -= _containerOffset; + pos += _containerOffset; + tmpFile.seek(_containerOffset, SEEK_CUR); } else { size = size + 1 - pos; } @@ -1356,6 +1381,7 @@ bool CompLoaderInsHof::loadFile(CompFileMap &loadTo) const { uint8 *outbuffer = 0; uint32 inPart1 = 0; uint32 inPart2 = 0; + uint8 compressionType = 0; Common::String entryStr; pos = 0; @@ -1367,7 +1393,7 @@ bool CompLoaderInsHof::loadFile(CompFileMap &loadTo) const { for (Common::List::iterator a = archives.begin(); a != archives.end(); ++a) { startFile = true; for (uint32 i = a->firstFile; i != (a->lastFile + 1); i++) { - sprintf(filenameExt, "%03d", i); + sprintf(filenameExt, _fileExtP, i); filenameTemp = a->filename + Common::String(filenameExt); if (!tmpFile.open(filenameTemp)) { @@ -1390,7 +1416,12 @@ bool CompLoaderInsHof::loadFile(CompFileMap &loadTo) const { tmpFile.seek(1); tmpFile.read(inbuffer + inPart1, inPart2); inPart2 = 0; - exp.process(outbuffer, inbuffer, outsize, insize); + + if (compressionType > 0) + exp.process(outbuffer, inbuffer, outsize, insize); + else + memcpy(outbuffer, inbuffer, outsize); + delete[] inbuffer; inbuffer = 0; newEntry.data = outbuffer; @@ -1419,7 +1450,7 @@ bool CompLoaderInsHof::loadFile(CompFileMap &loadTo) const { } } - sprintf(filenameExt, "%03d", i + 1); + sprintf(filenameExt, _fileExtP, i + 1); filenameTemp = a->filename + Common::String(filenameExt); Common::File tmpFile2; @@ -1435,8 +1466,7 @@ bool CompLoaderInsHof::loadFile(CompFileMap &loadTo) const { uint32 id = READ_LE_UINT32(hdr); if (id == 0x04034B50) { - if (hdr[8] != 8) - error("compression type not implemented"); + compressionType = hdr[8]; insize = READ_LE_UINT32(hdr + 18); outsize = READ_LE_UINT32(hdr + 22); @@ -1464,7 +1494,12 @@ bool CompLoaderInsHof::loadFile(CompFileMap &loadTo) const { } else { tmpFile.read(inbuffer, insize); inPart2 = 0; - exp.process(outbuffer, inbuffer, outsize, insize); + + if (compressionType > 0) + exp.process(outbuffer, inbuffer, outsize, insize); + else + memcpy(outbuffer, inbuffer, outsize); + delete[] inbuffer; inbuffer = 0; newEntry.data = outbuffer; @@ -1498,6 +1533,7 @@ void Resource::initializeLoaders() { _loaders.push_back(LoaderList::value_type(new ResLoaderTlk())); _compLoaders.push_back(CompLoaderList::value_type(new CompLoaderInsHof())); + _compLoaders.push_back(CompLoaderList::value_type(new CompLoaderInsLol())); } const ResArchiveLoader *Resource::getLoader(ResFileEntry::kType type) const { -- cgit v1.2.3 From 02c9cb35f4e190891a4d59a2f335b817a9147334 Mon Sep 17 00:00:00 2001 From: Kari Salminen Date: Mon, 11 Aug 2008 20:09:03 +0000 Subject: Changed readBundleFile to unpack data in-place and added debugging messages to the function. svn-id: r33781 --- engines/cine/part.cpp | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) (limited to 'engines') diff --git a/engines/cine/part.cpp b/engines/cine/part.cpp index d605bdd623..d2fecfc554 100644 --- a/engines/cine/part.cpp +++ b/engines/cine/part.cpp @@ -221,17 +221,21 @@ void readFromPart(int16 idx, byte *dataPtr) { byte *readBundleFile(int16 foundFileIdx) { assert(foundFileIdx >= 0 && foundFileIdx < numElementInPart); + bool error = false; byte *dataPtr = (byte *)calloc(partBuffer[foundFileIdx].unpackedSize, 1); - if (partBuffer[foundFileIdx].unpackedSize != partBuffer[foundFileIdx].packedSize) { - byte *unpackBuffer = (byte *)malloc(partBuffer[foundFileIdx].packedSize); - readFromPart(foundFileIdx, unpackBuffer); + readFromPart(foundFileIdx, dataPtr); + if (partBuffer[foundFileIdx].unpackedSize > partBuffer[foundFileIdx].packedSize) { CineUnpacker cineUnpacker; - if (!cineUnpacker.unpack(unpackBuffer, partBuffer[foundFileIdx].packedSize, dataPtr, partBuffer[foundFileIdx].unpackedSize)) { - warning("Error unpacking '%s' from bundle file '%s'", partBuffer[foundFileIdx].partName, currentPartName); - } - free(unpackBuffer); - } else { - readFromPart(foundFileIdx, dataPtr); + error = !cineUnpacker.unpack(dataPtr, partBuffer[foundFileIdx].packedSize, dataPtr, partBuffer[foundFileIdx].unpackedSize); + } else if (partBuffer[foundFileIdx].unpackedSize < partBuffer[foundFileIdx].packedSize) { + // Unpacked size of a file should never be less than its packed size + error = true; + } else { // partBuffer[foundFileIdx].unpackedSize == partBuffer[foundFileIdx].packedSize + debugC(5, kCineDebugPart, "Loaded non-compressed file '%s' from bundle file '%s'", partBuffer[foundFileIdx].partName, currentPartName); + } + + if (error) { + warning("Error unpacking '%s' from bundle file '%s'", partBuffer[foundFileIdx].partName, currentPartName); } return dataPtr; -- cgit v1.2.3 From c1462dda14e45e14f9070047d62f7b26130525b1 Mon Sep 17 00:00:00 2001 From: Kari Salminen Date: Mon, 11 Aug 2008 20:18:33 +0000 Subject: Added a safeguard to readBundleFile so it shouldn't corrupt memory even if the input says the data's unpacked size is less than its packed size (This shouldn't ever happen with non-corrupted data). svn-id: r33782 --- engines/cine/part.cpp | 6 +++--- engines/cine/part.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'engines') diff --git a/engines/cine/part.cpp b/engines/cine/part.cpp index d2fecfc554..c1159a2012 100644 --- a/engines/cine/part.cpp +++ b/engines/cine/part.cpp @@ -212,18 +212,18 @@ int16 findFileInBundle(const char *fileName) { return -1; } -void readFromPart(int16 idx, byte *dataPtr) { +void readFromPart(int16 idx, byte *dataPtr, uint32 maxSize) { setMouseCursor(MOUSE_CURSOR_DISK); g_cine->_partFileHandle.seek(partBuffer[idx].offset, SEEK_SET); - g_cine->_partFileHandle.read(dataPtr, partBuffer[idx].packedSize); + g_cine->_partFileHandle.read(dataPtr, MIN(partBuffer[idx].packedSize, maxSize)); } byte *readBundleFile(int16 foundFileIdx) { assert(foundFileIdx >= 0 && foundFileIdx < numElementInPart); bool error = false; byte *dataPtr = (byte *)calloc(partBuffer[foundFileIdx].unpackedSize, 1); - readFromPart(foundFileIdx, dataPtr); + readFromPart(foundFileIdx, dataPtr, partBuffer[foundFileIdx].unpackedSize); if (partBuffer[foundFileIdx].unpackedSize > partBuffer[foundFileIdx].packedSize) { CineUnpacker cineUnpacker; error = !cineUnpacker.unpack(dataPtr, partBuffer[foundFileIdx].packedSize, dataPtr, partBuffer[foundFileIdx].unpackedSize); diff --git a/engines/cine/part.h b/engines/cine/part.h index 72dc944db3..a654a1aebc 100644 --- a/engines/cine/part.h +++ b/engines/cine/part.h @@ -44,7 +44,7 @@ void closePart(void); int16 findFileInBundle(const char *fileName); -void readFromPart(int16 idx, byte *dataPtr); +void readFromPart(int16 idx, byte *dataPtr, uint32 maxSize); byte *readBundleFile(int16 foundFileIdx); byte *readBundleSoundFile(const char *entryName, uint32 *size = 0); -- cgit v1.2.3 From 2d5a140725194f8a44d98091b510469f5889275a Mon Sep 17 00:00:00 2001 From: Kari Salminen Date: Mon, 11 Aug 2008 20:41:13 +0000 Subject: Changed partBuffer from a pointer to a Common::Array. Removed numElementInPart variable as it's now equivalent with partBuffer.size(). svn-id: r33783 --- engines/cine/cine.cpp | 5 +++-- engines/cine/part.cpp | 20 +++++++++----------- engines/cine/part.h | 2 +- 3 files changed, 13 insertions(+), 14 deletions(-) (limited to 'engines') diff --git a/engines/cine/cine.cpp b/engines/cine/cine.cpp index 6c5069038a..fad6cf3f6a 100644 --- a/engines/cine/cine.cpp +++ b/engines/cine/cine.cpp @@ -75,7 +75,6 @@ CineEngine::~CineEngine() { Common::clearAllSpecialDebugLevels(); free(palPtr); - free(partBuffer); free(textDataPtr); } @@ -154,7 +153,9 @@ void CineEngine::initialize() { collisionPage = new byte[320 * 200]; textDataPtr = (byte *)malloc(8000); - partBuffer = (PartBuffer *)malloc(NUM_MAX_PARTDATA * sizeof(PartBuffer)); + // Clear part buffer as there's nothing loaded into it yet. + // Its size will change when loading data into it with the loadPart function. + partBuffer.clear(); if (g_cine->getGameType() == Cine::GType_OS) { readVolCnf(); diff --git a/engines/cine/part.cpp b/engines/cine/part.cpp index c1159a2012..df530b77f2 100644 --- a/engines/cine/part.cpp +++ b/engines/cine/part.cpp @@ -31,13 +31,10 @@ namespace Cine { -uint16 numElementInPart; - -PartBuffer *partBuffer; +Common::Array partBuffer; void loadPart(const char *partName) { - memset(partBuffer, 0, sizeof(PartBuffer) * NUM_MAX_PARTDATA); - numElementInPart = 0; + partBuffer.clear(); g_cine->_partFileHandle.close(); @@ -48,13 +45,14 @@ void loadPart(const char *partName) { setMouseCursor(MOUSE_CURSOR_DISK); - numElementInPart = g_cine->_partFileHandle.readUint16BE(); + uint16 numElementInPart = g_cine->_partFileHandle.readUint16BE(); + partBuffer.resize(numElementInPart); g_cine->_partFileHandle.readUint16BE(); // entry size if (currentPartName != partName) strcpy(currentPartName, partName); - for (uint16 i = 0; i < numElementInPart; i++) { + for (uint16 i = 0; i < partBuffer.size(); i++) { g_cine->_partFileHandle.read(partBuffer[i].partName, 14); partBuffer[i].offset = g_cine->_partFileHandle.readUint32BE(); partBuffer[i].packedSize = g_cine->_partFileHandle.readUint32BE(); @@ -190,7 +188,7 @@ void CineEngine::readVolCnf() { int16 findFileInBundle(const char *fileName) { if (g_cine->getGameType() == Cine::GType_OS) { // look first in currently loaded resource file - for (int i = 0; i < numElementInPart; i++) { + for (uint i = 0; i < partBuffer.size(); i++) { if (!scumm_stricmp(fileName, partBuffer[i].partName)) { return i; } @@ -204,7 +202,7 @@ int16 findFileInBundle(const char *fileName) { const char *part = (*it)._value; loadPart(part); } - for (int i = 0; i < numElementInPart; i++) { + for (uint i = 0; i < partBuffer.size(); i++) { if (!scumm_stricmp(fileName, partBuffer[i].partName)) { return i; } @@ -220,7 +218,7 @@ void readFromPart(int16 idx, byte *dataPtr, uint32 maxSize) { } byte *readBundleFile(int16 foundFileIdx) { - assert(foundFileIdx >= 0 && foundFileIdx < numElementInPart); + assert(foundFileIdx >= 0 && foundFileIdx < (int32)partBuffer.size()); bool error = false; byte *dataPtr = (byte *)calloc(partBuffer[foundFileIdx].unpackedSize, 1); readFromPart(foundFileIdx, dataPtr, partBuffer[foundFileIdx].unpackedSize); @@ -304,7 +302,7 @@ void dumpBundle(const char *fileName) { strcpy(tmpPart, currentPartName); loadPart(fileName); - for (int i = 0; i < numElementInPart; i++) { + for (uint i = 0; i < partBuffer.size(); i++) { byte *data = readBundleFile(i); debug(0, "%s", partBuffer[i].partName); diff --git a/engines/cine/part.h b/engines/cine/part.h index a654a1aebc..dc9d1db537 100644 --- a/engines/cine/part.h +++ b/engines/cine/part.h @@ -37,7 +37,7 @@ struct PartBuffer { #define NUM_MAX_PARTDATA 255 -extern PartBuffer *partBuffer; +extern Common::Array partBuffer; void loadPart(const char *partName); void closePart(void); -- cgit v1.2.3 From d6dde4b85f3f32fe0f602270b9223eaa299db91c Mon Sep 17 00:00:00 2001 From: Kari Salminen Date: Mon, 11 Aug 2008 21:26:41 +0000 Subject: Removed textDataPtr pointer as it's not used beyond the loadTextData function. Reworked loadTextData a bit so there are no two loops for the same thing (Also renamed some of the local variables). svn-id: r33784 --- engines/cine/cine.cpp | 4 +-- engines/cine/texte.cpp | 68 +++++++++++++++++++------------------------------- engines/cine/texte.h | 4 +-- 3 files changed, 28 insertions(+), 48 deletions(-) (limited to 'engines') diff --git a/engines/cine/cine.cpp b/engines/cine/cine.cpp index fad6cf3f6a..cf33b2c186 100644 --- a/engines/cine/cine.cpp +++ b/engines/cine/cine.cpp @@ -75,7 +75,6 @@ CineEngine::~CineEngine() { Common::clearAllSpecialDebugLevels(); free(palPtr); - free(textDataPtr); } int CineEngine::init() { @@ -151,7 +150,6 @@ void CineEngine::initialize() { } collisionPage = new byte[320 * 200]; - textDataPtr = (byte *)malloc(8000); // Clear part buffer as there's nothing loaded into it yet. // Its size will change when loading data into it with the loadPart function. @@ -161,7 +159,7 @@ void CineEngine::initialize() { readVolCnf(); } - loadTextData("texte.dat", textDataPtr); + loadTextData("texte.dat"); if (g_cine->getGameType() == Cine::GType_OS && !(g_cine->getFeatures() & GF_DEMO)) { loadPoldatDat("poldat.dat"); diff --git a/engines/cine/texte.cpp b/engines/cine/texte.cpp index e4fd334926..618e37d1ce 100644 --- a/engines/cine/texte.cpp +++ b/engines/cine/texte.cpp @@ -29,8 +29,6 @@ namespace Cine { -byte *textDataPtr; - const char **failureMessages; const CommandeType *defaultActionCommand; const CommandeType *systemMenu; @@ -40,54 +38,40 @@ const char *commandPrepositionOn; void generateMask(const byte *sprite, byte *mask, uint16 size, byte transparency); -void loadTextData(const char *pFileName, byte *pDestinationBuffer) { - Common::File pFileHandle; - uint16 entrySize; - uint16 numEntry; - uint16 i; - byte *tempBuffer; - uint16 dataSize; - - assert(pFileName); - assert(pDestinationBuffer); - - if (!pFileHandle.open(pFileName)) - error("loadTextData(): Cannot open file %s", pFileName); +void loadTextData(const char *filename) { + Common::File fileHandle; + assert(filename); - entrySize = pFileHandle.readUint16BE(); - numEntry = pFileHandle.readUint16BE(); + if (!fileHandle.open(filename)) + error("loadTextData(): Cannot open file %s", filename); - dataSize = numEntry * entrySize; - pFileHandle.read(pDestinationBuffer, numEntry * entrySize); + uint entrySize = fileHandle.readUint16BE(); + uint numEntry = fileHandle.readUint16BE(); - tempBuffer = pDestinationBuffer; + uint sourceSize = numEntry * entrySize; + Common::Array source; + source.resize(sourceSize); + fileHandle.read(source.begin(), sourceSize); + const int fontHeight = 8; + const int fontWidth = (g_cine->getGameType() == Cine::GType_FW) ? 16 : 8; + uint numCharacters; + uint bytesPerCharacter; if (g_cine->getGameType() == Cine::GType_FW) { - int numCharacters; - if (g_cine->getFeatures() & GF_ALT_FONT) { - numCharacters = 85; - } else { - numCharacters = 78; - } - - dataSize = dataSize / numCharacters; - - loadRelatedPalette(pFileName); - - for (i = 0; i < numCharacters; i++) { - gfxConvertSpriteToRaw(g_cine->_textHandler.textTable[i][0], tempBuffer, 16, 8); - generateMask(g_cine->_textHandler.textTable[i][0], g_cine->_textHandler.textTable[i][1], 16 * 8, 0); - tempBuffer += dataSize; - } + numCharacters = (g_cine->getFeatures() & GF_ALT_FONT) ? 85 : 78; + bytesPerCharacter = sourceSize / numCharacters; // TODO: Check if this could be replaced with fontWidth * fontHeight + loadRelatedPalette(filename); } else { - for (i = 0; i < 90; i++) { - gfxConvertSpriteToRaw(g_cine->_textHandler.textTable[i][0], tempBuffer, 8, 8); - generateMask(g_cine->_textHandler.textTable[i][0], g_cine->_textHandler.textTable[i][1], 8 * 8, 0); - tempBuffer += 0x40; - } + numCharacters = 90; + bytesPerCharacter = fontWidth * fontHeight; + } + + for (uint i = 0; i < numCharacters; i++) { + gfxConvertSpriteToRaw(g_cine->_textHandler.textTable[i][0], &source[i * bytesPerCharacter], fontWidth, fontHeight); + generateMask(g_cine->_textHandler.textTable[i][0], g_cine->_textHandler.textTable[i][1], fontWidth * fontHeight, 0); } - pFileHandle.close(); + fileHandle.close(); } const CharacterEntry *fontParamTable; diff --git a/engines/cine/texte.h b/engines/cine/texte.h index f471c3c49e..7fec52cffc 100644 --- a/engines/cine/texte.h +++ b/engines/cine/texte.h @@ -33,8 +33,6 @@ namespace Cine { typedef char CommandeType[20]; -extern byte *textDataPtr; - struct TextHandler { byte textTable[256][2][16 * 8]; }; @@ -53,7 +51,7 @@ struct CharacterEntry { extern const CharacterEntry *fontParamTable; -void loadTextData(const char *pFileName, byte *pDestinationBuffer); +void loadTextData(const char *filename); void loadErrmessDat(const char *fname); void freeErrmessDat(void); void loadPoldatDat(const char *fname); -- cgit v1.2.3 From 8aaba9d38e8a0c2259cf7617bb1b07c725a49b0b Mon Sep 17 00:00:00 2001 From: Kari Salminen Date: Mon, 11 Aug 2008 21:45:47 +0000 Subject: Changed palPtr from a pointer to a Common::Array named palArray. Removed palEntriesCount variable as it's now equivalent to palArray.size(). svn-id: r33785 --- engines/cine/cine.cpp | 2 -- engines/cine/pal.cpp | 36 +++++++++++++----------------------- engines/cine/pal.h | 2 +- 3 files changed, 14 insertions(+), 26 deletions(-) (limited to 'engines') diff --git a/engines/cine/cine.cpp b/engines/cine/cine.cpp index cf33b2c186..5e0506c286 100644 --- a/engines/cine/cine.cpp +++ b/engines/cine/cine.cpp @@ -73,8 +73,6 @@ CineEngine::~CineEngine() { freeErrmessDat(); } Common::clearAllSpecialDebugLevels(); - - free(palPtr); } int CineEngine::init() { diff --git a/engines/cine/pal.cpp b/engines/cine/pal.cpp index 3e6f5adf40..7f6307c640 100644 --- a/engines/cine/pal.cpp +++ b/engines/cine/pal.cpp @@ -28,10 +28,7 @@ namespace Cine { -uint16 palEntriesCount; - -PalEntry *palPtr = NULL; - +Common::Array palArray; static byte paletteBuffer1[16]; static byte paletteBuffer2[16]; @@ -41,27 +38,20 @@ void loadPal(const char *fileName) { removeExtention(buffer, fileName); strcat(buffer, ".PAL"); - - if (palPtr) { - free(palPtr); - palPtr = NULL; - } - - palEntriesCount = 0; + palArray.clear(); Common::File palFileHandle; if (!palFileHandle.open(buffer)) error("loadPal(): Cannot open file %s", fileName); - palEntriesCount = palFileHandle.readUint16LE(); + uint16 palEntriesCount = palFileHandle.readUint16LE(); palFileHandle.readUint16LE(); // entry size - palPtr = (PalEntry *)malloc(palEntriesCount * sizeof(PalEntry)); - assert(palPtr); - for (int i = 0; i < palEntriesCount; ++i) { - palFileHandle.read(palPtr[i].name, 10); - palFileHandle.read(palPtr[i].pal1, 16); - palFileHandle.read(palPtr[i].pal2, 16); + palArray.resize(palEntriesCount); + for (uint i = 0; i < palArray.size(); ++i) { + palFileHandle.read(palArray[i].name, 10); + palFileHandle.read(palArray[i].pal1, 16); + palFileHandle.read(palArray[i].pal2, 16); } palFileHandle.close(); } @@ -81,8 +71,8 @@ int16 findPaletteFromName(const char *fileName) { position++; } - for (i = 0; i < palEntriesCount; i++) { - if (!strcmp(buffer, palPtr[i].name)) { + for (i = 0; i < palArray.size(); i++) { + if (!strcmp(buffer, palArray[i].name)) { return i; } } @@ -105,9 +95,9 @@ void loadRelatedPalette(const char *fileName) { paletteBuffer1[i] = paletteBuffer2[i] = (i << 4) + i; } } else { - assert(paletteIndex < palEntriesCount); - memcpy(paletteBuffer1, palPtr[paletteIndex].pal1, 16); - memcpy(paletteBuffer2, palPtr[paletteIndex].pal2, 16); + assert(paletteIndex < (int32)palArray.size()); + memcpy(paletteBuffer1, palArray[paletteIndex].pal1, 16); + memcpy(paletteBuffer2, palArray[paletteIndex].pal2, 16); } } diff --git a/engines/cine/pal.h b/engines/cine/pal.h index 768cf0d27d..819680973c 100644 --- a/engines/cine/pal.h +++ b/engines/cine/pal.h @@ -34,7 +34,7 @@ struct PalEntry { byte pal2[16]; }; -extern PalEntry *palPtr; +extern Common::Array palArray; void loadPal(const char *fileName); -- cgit v1.2.3 From 36e0d2eab8bc920d337d8e6f1436e057049ffac6 Mon Sep 17 00:00:00 2001 From: Kari Salminen Date: Mon, 11 Aug 2008 22:26:25 +0000 Subject: Moved fontParamTable inside TextHandler struct and made it a constant size as that's what it is (No need for using malloc & free anymore). Previously we would've tried to free an array that wasn't heap-allocated in freePoldatDat (Freeing fontParamTable_standard or fontParamTable_alt), that's fixed. svn-id: r33786 --- engines/cine/cine.cpp | 1 - engines/cine/gfx.cpp | 8 ++++---- engines/cine/texte.cpp | 29 ++++++++++------------------- engines/cine/texte.h | 19 ++++++++++--------- 4 files changed, 24 insertions(+), 33 deletions(-) (limited to 'engines') diff --git a/engines/cine/cine.cpp b/engines/cine/cine.cpp index 5e0506c286..9eb751835e 100644 --- a/engines/cine/cine.cpp +++ b/engines/cine/cine.cpp @@ -69,7 +69,6 @@ CineEngine::CineEngine(OSystem *syst, const CINEGameDescription *gameDesc) : Eng CineEngine::~CineEngine() { if (g_cine->getGameType() == Cine::GType_OS) { - freePoldatDat(); freeErrmessDat(); } Common::clearAllSpecialDebugLevels(); diff --git a/engines/cine/gfx.cpp b/engines/cine/gfx.cpp index c6c5faf464..5d66be5e27 100644 --- a/engines/cine/gfx.cpp +++ b/engines/cine/gfx.cpp @@ -366,8 +366,8 @@ int FWRenderer::drawChar(char character, int x, int y) { if (character == ' ') { x += 5; - } else if ((width = fontParamTable[(unsigned char)character].characterWidth)) { - idx = fontParamTable[(unsigned char)character].characterIdx; + } else if ((width = g_cine->_textHandler.fontParamTable[(unsigned char)character].characterWidth)) { + idx = g_cine->_textHandler.fontParamTable[(unsigned char)character].characterIdx; drawSpriteRaw(g_cine->_textHandler.textTable[idx][0], g_cine->_textHandler.textTable[idx][1], 16, 8, _backBuffer, x, y); x += width + 1; } @@ -1023,8 +1023,8 @@ int OSRenderer::drawChar(char character, int x, int y) { if (character == ' ') { x += 5; - } else if ((width = fontParamTable[(unsigned char)character].characterWidth)) { - idx = fontParamTable[(unsigned char)character].characterIdx; + } else if ((width = g_cine->_textHandler.fontParamTable[(unsigned char)character].characterWidth)) { + idx = g_cine->_textHandler.fontParamTable[(unsigned char)character].characterIdx; drawSpriteRaw2(g_cine->_textHandler.textTable[idx][0], 0, 16, 8, _backBuffer, x, y); x += width + 1; } diff --git a/engines/cine/texte.cpp b/engines/cine/texte.cpp index 618e37d1ce..6369a2eff4 100644 --- a/engines/cine/texte.cpp +++ b/engines/cine/texte.cpp @@ -74,9 +74,7 @@ void loadTextData(const char *filename) { fileHandle.close(); } -const CharacterEntry *fontParamTable; - -const CharacterEntry fontParamTable_standard[256] = { +static const CharacterEntry fontParamTable_standard[NUM_FONT_CHARS] = { { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, @@ -113,7 +111,7 @@ const CharacterEntry fontParamTable_standard[256] = { { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0} }; -const CharacterEntry fontParamTable_alt[256] = { +static const CharacterEntry fontParamTable_alt[NUM_FONT_CHARS] = { { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, { 0, 0}, @@ -537,9 +535,11 @@ void initLanguage(Common::Language lang) { } if (g_cine->getFeatures() & GF_ALT_FONT) { - fontParamTable = fontParamTable_alt; + // Copy alternative font parameter table to the current font parameter table + Common::copy(fontParamTable_alt, fontParamTable_alt + NUM_FONT_CHARS, g_cine->_textHandler.fontParamTable); } else { - fontParamTable = fontParamTable_standard; + // Copy standard font parameter to the current font parameter table + Common::copy(fontParamTable_standard, fontParamTable_standard + NUM_FONT_CHARS, g_cine->_textHandler.fontParamTable); } } @@ -574,25 +574,16 @@ void loadPoldatDat(const char *fname) { in.open(fname); if (in.isOpen()) { - CharacterEntry *ptr = (CharacterEntry *)malloc(sizeof(CharacterEntry) * 256); - - for (int i = 0; i < 256; i++) { - ptr[i].characterIdx = (int)in.readByte(); - ptr[i].characterWidth = (int)in.readByte(); + for (int i = 0; i < NUM_FONT_CHARS; i++) { + g_cine->_textHandler.fontParamTable[i].characterIdx = in.readByte(); + g_cine->_textHandler.fontParamTable[i].characterWidth = in.readByte(); } - fontParamTable = ptr; - in.close(); } else { error("Cannot open file %s for reading", fname); } } -void freePoldatDat() { - free(const_cast(fontParamTable)); - fontParamTable = 0; -} - /*! \brief Fit a substring of text into one line of fixed width text box * \param str Text to fit * \param maxWidth Text box width @@ -617,7 +608,7 @@ int fitLine(const char *str, int maxWidth, int &words, int &width) { bkpWidth = width; bkpLen = i + 1; } else { - charWidth = fontParamTable[(unsigned char)str[i]].characterWidth + 1; + charWidth = g_cine->_textHandler.fontParamTable[(unsigned char)str[i]].characterWidth + 1; width += charWidth; } diff --git a/engines/cine/texte.h b/engines/cine/texte.h index 7fec52cffc..03d0c5faec 100644 --- a/engines/cine/texte.h +++ b/engines/cine/texte.h @@ -33,8 +33,17 @@ namespace Cine { typedef char CommandeType[20]; +// Number of characters in a font +#define NUM_FONT_CHARS 256 + +struct CharacterEntry { + byte characterIdx; + byte characterWidth; +}; + struct TextHandler { - byte textTable[256][2][16 * 8]; + byte textTable[NUM_FONT_CHARS][2][16 * 8]; + CharacterEntry fontParamTable[NUM_FONT_CHARS]; }; extern const char **failureMessages; @@ -44,18 +53,10 @@ extern const CommandeType *confirmMenu; extern const char **otherMessages; extern const char *commandPrepositionOn; -struct CharacterEntry { - byte characterIdx; - byte characterWidth; -}; - -extern const CharacterEntry *fontParamTable; - void loadTextData(const char *filename); void loadErrmessDat(const char *fname); void freeErrmessDat(void); void loadPoldatDat(const char *fname); -void freePoldatDat(void); int fitLine(const char *ptr, int maxWidth, int &words, int &width); -- cgit v1.2.3 From 88ec480cef8d637c2fd69b8197ab3c7de39ede8b Mon Sep 17 00:00:00 2001 From: Kari Salminen Date: Mon, 11 Aug 2008 23:01:32 +0000 Subject: Implemented drawMessage changes for Operation Stealth's timed cutscenes (Negative colors are used for timed text boxes that are totally transparent, only the text is drawn). svn-id: r33790 --- engines/cine/gfx.cpp | 20 ++++++++++++++------ engines/cine/gfx.h | 2 +- 2 files changed, 15 insertions(+), 7 deletions(-) (limited to 'engines') diff --git a/engines/cine/gfx.cpp b/engines/cine/gfx.cpp index 5d66be5e27..bb11cea5dc 100644 --- a/engines/cine/gfx.cpp +++ b/engines/cine/gfx.cpp @@ -225,14 +225,18 @@ void FWRenderer::drawCommand() { * \param x Top left message box corner coordinate * \param y Top left message box corner coordinate * \param width Message box width - * \param color Message box background color + * \param color Message box background color (Or if negative draws only the text) + * \note Negative colors are used in Operation Stealth's timed cutscenes + * (e.g. when first meeting The Movement for the Liberation of Santa Paragua). */ -void FWRenderer::drawMessage(const char *str, int x, int y, int width, byte color) { +void FWRenderer::drawMessage(const char *str, int x, int y, int width, int color) { int i, tx, ty, tw; int line = 0, words = 0, cw = 0; int space = 0, extraSpace = 0; - drawPlainBox(x, y, width, 4, color); + if (color >= 0) { + drawPlainBox(x, y, width, 4, color); + } tx = x + 4; ty = str[0] ? y - 5 : y + 4; tw = width - 8; @@ -252,7 +256,9 @@ void FWRenderer::drawMessage(const char *str, int x, int y, int width, byte colo } ty += 9; - drawPlainBox(x, ty, width, 9, color); + if (color >= 0) { + drawPlainBox(x, ty, width, 9, color); + } tx = x + 4; } @@ -269,8 +275,10 @@ void FWRenderer::drawMessage(const char *str, int x, int y, int width, byte colo } ty += 9; - drawPlainBox(x, ty, width, 4, color); - drawDoubleBorder(x, y, width, ty - y + 4, 2); + if (color >= 0) { + drawPlainBox(x, ty, width, 4, color); + drawDoubleBorder(x, y, width, ty - y + 4, 2); + } } /*! \brief Draw rectangle on screen diff --git a/engines/cine/gfx.h b/engines/cine/gfx.h index 078954e3b9..22545abf0b 100644 --- a/engines/cine/gfx.h +++ b/engines/cine/gfx.h @@ -68,7 +68,7 @@ protected: virtual void drawSprite(const objectStruct &obj); void drawCommand(); - void drawMessage(const char *str, int x, int y, int width, byte color); + void drawMessage(const char *str, int x, int y, int width, int color); void drawPlainBox(int x, int y, int width, int height, byte color); void drawBorder(int x, int y, int width, int height, byte color); void drawDoubleBorder(int x, int y, int width, int height, byte color); -- cgit v1.2.3 From 96a1ca17090eb17157707a9e989eec3ebb7c94fc Mon Sep 17 00:00:00 2001 From: Kari Salminen Date: Mon, 11 Aug 2008 23:20:10 +0000 Subject: Made Operation Stealth's action failure messages use a background color set by the opcode 0x49 'o1_setDefaultMenuBgColor'. Should fix the 'text hard to read' problems. svn-id: r33792 --- engines/cine/gfx.cpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'engines') diff --git a/engines/cine/gfx.cpp b/engines/cine/gfx.cpp index bb11cea5dc..2df4c54bb3 100644 --- a/engines/cine/gfx.cpp +++ b/engines/cine/gfx.cpp @@ -1104,6 +1104,20 @@ void OSRenderer::renderOverlay(const Common::List::iterator &it) { } break; + // action failure message + case 3: { + int idx = it->objIdx * 4 + g_cine->_rnd.getRandomNumber(3); + int len = strlen(failureMessages[idx]); + _messageLen += len; + int width = 6 * len + 20; + width = width > 300 ? 300 : width; + + // The used color here differs from Future Wars + drawMessage(failureMessages[idx], (320 - width) / 2, 80, width, _messageBg); + waitForPlayerClick = 1; + break; + } + // bitmap case 4: if (objectTable[it->objIdx].frame >= 0) { -- cgit v1.2.3 From c935a09ef53a594f408d3279cd30c783bade9ed1 Mon Sep 17 00:00:00 2001 From: Kari Salminen Date: Tue, 12 Aug 2008 00:13:27 +0000 Subject: Changed commandBuffer from a char[80] to Common::String and made FWRenderer::setCommand use a Common::String. Hopefully this might help with the command buffer overflow stuff, although this isn't a fix for the problem behind it, just a bandaid. svn-id: r33793 --- engines/cine/gfx.cpp | 2 +- engines/cine/gfx.h | 2 +- engines/cine/main_loop.cpp | 2 +- engines/cine/various.cpp | 63 +++++++++++++++++++++++++++------------------- engines/cine/various.h | 5 +++- 5 files changed, 44 insertions(+), 30 deletions(-) (limited to 'engines') diff --git a/engines/cine/gfx.cpp b/engines/cine/gfx.cpp index 2df4c54bb3..f0149043f9 100644 --- a/engines/cine/gfx.cpp +++ b/engines/cine/gfx.cpp @@ -530,7 +530,7 @@ void FWRenderer::blit() { /*! \brief Set player command string * \param cmd New command string */ -void FWRenderer::setCommand(const char *cmd) { +void FWRenderer::setCommand(Common::String cmd) { _cmd = cmd; } diff --git a/engines/cine/gfx.h b/engines/cine/gfx.h index 22545abf0b..ccd955db8f 100644 --- a/engines/cine/gfx.h +++ b/engines/cine/gfx.h @@ -94,7 +94,7 @@ public: void drawFrame(); void blit(); - void setCommand(const char *cmd); + void setCommand(Common::String cmd); virtual void incrustMask(const objectStruct &obj, uint8 color = 0); virtual void incrustSprite(const objectStruct &obj); diff --git a/engines/cine/main_loop.cpp b/engines/cine/main_loop.cpp index 684e33f9c0..17240f9ef8 100644 --- a/engines/cine/main_loop.cpp +++ b/engines/cine/main_loop.cpp @@ -284,7 +284,7 @@ void CineEngine::mainLoop(int bootScriptIdx) { menuCommandLen = 0; playerCommand = -1; - strcpy(commandBuffer, ""); + commandBuffer = ""; globalVars[VAR_MOUSE_X_POS] = 0; globalVars[VAR_MOUSE_Y_POS] = 0; diff --git a/engines/cine/various.cpp b/engines/cine/various.cpp index a8660d7fdc..07f524852a 100644 --- a/engines/cine/various.cpp +++ b/engines/cine/various.cpp @@ -78,7 +78,7 @@ byte _danKeysPressed; int16 playerCommand; -char commandBuffer[80]; +Common::String commandBuffer; char currentPrcName[20]; char currentRelName[20]; char currentObjectName[20]; @@ -318,6 +318,18 @@ void saveCommandVariables(Common::OutSaveFile &out) { } } +/*! \brief Save the 80 bytes long command buffer padded to that length with zeroes. */ +void saveCommandBuffer(Common::OutSaveFile &out) { + // Let's make sure there's space for the trailing zero + // (That's why we subtract one from the maximum command buffer size here). + uint32 size = MIN(commandBuffer.size(), kMaxCommandBufferSize - 1); + out.write(commandBuffer.c_str(), size); + // Write the rest as zeroes (Here we also write the string's trailing zero) + for (uint i = 0; i < kMaxCommandBufferSize - size; i++) { + out.writeByte(0); + } +} + void saveAnimDataTable(Common::OutSaveFile &out) { out.writeUint16BE(NUM_MAX_ANIMDATA); // Entry count out.writeUint16BE(0x1E); // Entry size @@ -635,7 +647,7 @@ void CineEngine::resetEngine() { playerCommand = -1; isDrawCommandEnabled = 0; - strcpy(commandBuffer, ""); + commandBuffer = ""; globalVars[VAR_MOUSE_X_POS] = 0; globalVars[VAR_MOUSE_Y_POS] = 0; @@ -836,7 +848,10 @@ bool CineEngine::loadTempSaveOS(Common::SeekableReadStream &in) { globalVars.load(in, NUM_MAX_VAR); loadZoneData(in); loadCommandVariables(in); - in.read(commandBuffer, 0x50); + char tempCommandBuffer[kMaxCommandBufferSize]; + in.read(tempCommandBuffer, kMaxCommandBufferSize); + commandBuffer = tempCommandBuffer; + renderer->setCommand(commandBuffer); loadZoneQuery(in); // TODO: Use the loaded string (Current music name (String, 13 bytes)). @@ -973,7 +988,9 @@ bool CineEngine::loadPlainSaveFW(Common::SeekableReadStream &in, CineSaveGameFor loadCommandVariables(in); // At 0x22A9 (i.e. 0x22A1 + 4 * 2): - in.read(commandBuffer, 0x50); + char tempCommandBuffer[kMaxCommandBufferSize]; + in.read(tempCommandBuffer, kMaxCommandBufferSize); + commandBuffer = tempCommandBuffer; renderer->setCommand(commandBuffer); // At 0x22F9 (i.e. 0x22A9 + 0x50): @@ -1121,7 +1138,7 @@ void CineEngine::makeSaveFW(Common::OutSaveFile &out) { globalVars.save(out, NUM_MAX_VAR); saveZoneData(out); saveCommandVariables(out); - out.write(commandBuffer, 0x50); + saveCommandBuffer(out); out.writeUint16BE(renderer->_cmdY); out.writeUint16BE(bgVar0); @@ -1336,7 +1353,7 @@ void CineEngine::makeSaveOS(Common::OutSaveFile &out) { globalVars.save(out, NUM_MAX_VAR); saveZoneData(out); saveCommandVariables(out); - out.write(commandBuffer, 0x50); + saveCommandBuffer(out); saveZoneQuery(out); // FIXME: Save a proper name here, saving an empty string currently. @@ -1462,9 +1479,9 @@ void makeCommandLine(void) { commandVar2 = -10; if (playerCommand != -1) { - strcpy(commandBuffer, defaultActionCommand[playerCommand]); + commandBuffer = defaultActionCommand[playerCommand]; } else { - strcpy(commandBuffer, ""); + commandBuffer = ""; } if ((playerCommand != -1) && (choiceResultTable[playerCommand] == 2)) { // need object selection ? @@ -1480,7 +1497,7 @@ void makeCommandLine(void) { if (si < 0) { playerCommand = -1; - strcpy(commandBuffer, ""); + commandBuffer = ""; } else { if (g_cine->getGameType() == Cine::GType_OS) { if (si >= 8000) { @@ -1493,11 +1510,10 @@ void makeCommandLine(void) { commandVar3[0] = si; commandVar1 = 1; - - strcat(commandBuffer, " "); - strcat(commandBuffer, objectTable[commandVar3[0]].name); - strcat(commandBuffer, " "); - strcat(commandBuffer, commandPrepositionOn); + commandBuffer += " "; + commandBuffer += objectTable[commandVar3[0]].name; + commandBuffer += " "; + commandBuffer += commandPrepositionOn; } } else { if (playerCommand == 2) { @@ -1505,7 +1521,7 @@ void makeCommandLine(void) { processInventory(x, y + 8); playerCommand = -1; commandVar1 = 0; - strcpy(commandBuffer, ""); + commandBuffer = ""; } } @@ -1761,8 +1777,9 @@ uint16 executePlayerInput(void) { commandVar3[commandVar1] = si; commandVar1++; - strcat(commandBuffer, " "); - strcat(commandBuffer, objectTable[si].name); + commandBuffer += " "; + commandBuffer += objectTable[si].name; + isDrawCommandEnabled = 1; @@ -1784,8 +1801,8 @@ uint16 executePlayerInput(void) { playerCommand = -1; commandVar1 = 0; - strcpy(commandBuffer, ""); - renderer->setCommand(""); + commandBuffer = ""; + renderer->setCommand(commandBuffer); } } else { globalVars[VAR_MOUSE_X_POS] = mouseX; @@ -1806,13 +1823,7 @@ uint16 executePlayerInput(void) { if (commandVar2 != objIdx) { if (objIdx != -1) { - char command[256]; - - strcpy(command, commandBuffer); - strcat(command, " "); - strcat(command, objectTable[objIdx].name); - - renderer->setCommand(command); + renderer->setCommand(commandBuffer + " " + objectTable[objIdx].name); } else { isDrawCommandEnabled = 1; } diff --git a/engines/cine/various.h b/engines/cine/various.h index c38017ceaa..0ee77c1b47 100644 --- a/engines/cine/various.h +++ b/engines/cine/various.h @@ -33,6 +33,9 @@ namespace Cine { +// Maximum size of the command buffer including the trailing zero +#define kMaxCommandBufferSize 80 + void initLanguage(Common::Language lang); int16 makeMenuChoice(const CommandeType commandList[], uint16 height, uint16 X, uint16 Y, uint16 width, bool recheckValue = false); @@ -85,7 +88,7 @@ extern byte _danKeysPressed; extern int16 playerCommand; -extern char commandBuffer[80]; +extern Common::String commandBuffer; extern char currentPrcName[20]; extern char currentRelName[20]; -- cgit v1.2.3 From 811e4b3128de561289a19806c854ea05a9ab96b5 Mon Sep 17 00:00:00 2001 From: Kari Salminen Date: Tue, 12 Aug 2008 14:44:44 +0000 Subject: Implemented Operation Stealth specific parts of processInventory and added another mouse button waiting loop into the function's end (It's in both Future Wars and Operation Stealth). Fixes inventory showing in Operation Stealth. svn-id: r33795 --- engines/cine/various.cpp | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) (limited to 'engines') diff --git a/engines/cine/various.cpp b/engines/cine/various.cpp index 07f524852a..6da2931c8a 100644 --- a/engines/cine/various.cpp +++ b/engines/cine/various.cpp @@ -1416,19 +1416,38 @@ void drawDoubleMessageBox(int16 x, int16 y, int16 width, int16 currentY, int16 c } void processInventory(int16 x, int16 y) { - int16 listSize = buildObjectListCommand(-2); uint16 button; + int menuWidth; + int listSize; + int commandParam; + + if (g_cine->getGameType() == Cine::GType_FW) { + menuWidth = 140; + commandParam = -2; + } else { // Operation Stealth + menuWidth = 160; + commandParam = -3; + } + + listSize = buildObjectListCommand(commandParam); if (!listSize) return; - renderer->drawMenu(objectListCommand, listSize, x, y, 140, -1); + renderer->drawMenu(objectListCommand, listSize, x, y, menuWidth, -1); renderer->blit(); do { manageEvents(); getMouseData(mouseUpdateStatus, &button, &dummyU16, &dummyU16); } while (!button); + + do { + manageEvents(); + getMouseData(mouseUpdateStatus, &button, &dummyU16, &dummyU16); + } while (button); + + // TODO: Both Future Wars and Operation Stealth call showMouse, drawMouse or something similar here. } int16 buildObjectListCommand(int16 param) { -- cgit v1.2.3 From eb9633ee1e085df0ce7fc747a5ee58891c2aa986 Mon Sep 17 00:00:00 2001 From: Kari Salminen Date: Tue, 12 Aug 2008 19:33:17 +0000 Subject: Implemented Operation Stealth's makeCommandLine. svn-id: r33805 --- engines/cine/texte.cpp | 87 ++++++++++++++++++++++++++++++++++++++---------- engines/cine/texte.h | 3 +- engines/cine/various.cpp | 55 +++++++++++++++++++----------- 3 files changed, 106 insertions(+), 39 deletions(-) (limited to 'engines') diff --git a/engines/cine/texte.cpp b/engines/cine/texte.cpp index 6369a2eff4..a7533c30a9 100644 --- a/engines/cine/texte.cpp +++ b/engines/cine/texte.cpp @@ -34,7 +34,8 @@ const CommandeType *defaultActionCommand; const CommandeType *systemMenu; const CommandeType *confirmMenu; const char **otherMessages; -const char *commandPrepositionOn; +const char *defaultCommandPreposition; +const char **commandPrepositionTable; void generateMask(const byte *sprite, byte *mask, uint16 size, byte transparency); @@ -190,6 +191,16 @@ void initLanguage(Common::Language lang) { "NOACTION" }; + static const char *commandPrepositionTable_EN[] = { + "", // EXAMINE + "", // TAKE + "", // INVENTORY + "on", // USE + "", // OPERATE + "to", // SPEAK + "" // NOACTION + }; + static const CommandeType systemMenu_EN[] = { "Pause", "Restart Game", @@ -206,8 +217,7 @@ void initLanguage(Common::Language lang) { "Loading | %s", "Loading canceled ...", "No baclup in the drive...", - "Please enter the backup name", - "on" + "Please enter the backup name" }; static const CommandeType confirmMenu_EN[] = { @@ -258,6 +268,16 @@ void initLanguage(Common::Language lang) { "NOACTION" }; + static const char *commandPrepositionTable_FR[] = { + "", // EXAMINER + "", // PRENDRE + "", // INVENTAIRE + "sur", // UTILISER + "", // ACTIONNER + "a", // PARLER + "" // NOACTION + }; + static const CommandeType systemMenu_FR[] = { "Pause", "Nouvelle partie", @@ -279,8 +299,7 @@ void initLanguage(Common::Language lang) { "Sauvegarde de | %s", "Sauvegarde Annul\x82""e ...", "Aucune sauvegarde dans le lecteur ...", - "Veuillez entrer le Nom de la Sauvegarde .", - "sur" + "Veuillez entrer le Nom de la Sauvegarde ." }; static const char *failureMessages_ES[] = { @@ -326,6 +345,16 @@ void initLanguage(Common::Language lang) { "NOACTION" }; + static const char *commandPrepositionTable_ES[] = { + "", // EXAMINAR + "", // COGER + "", // INVENTARIO + "donde", // USAR + "", // ACCIONAR + "a", // HABLAR + "" // NOACTION + }; + static const CommandeType systemMenu_ES[] = { "Pause", "Nueva partida", @@ -347,8 +376,7 @@ void initLanguage(Common::Language lang) { "Gabacion de| %s", "Rrabacion anulada", "No hay partidas grabadas en este disco...", - "Teclea el nombre de la partida grabada", - "donde" + "Teclea el nombre de la partida grabada" }; static const char *failureMessages_DE[] = { @@ -385,15 +413,25 @@ void initLanguage(Common::Language lang) { }; static const CommandeType defaultActionCommand_DE[] = { - "Pr\x81""fe", + "Pr\x81""fe", // FIXME? The third letter should be Latin Small Letter U with diaeresis "Nimm", "Bestand", "Benutze", - "Bet\x84tige", + "Bet\x84tige", // FIXME? The third letter should be Latin Small Letter A with diaeresis "Sprich", "NOACTION" }; + static const char *commandPrepositionTable_DE[] = { + "", // Prufe + "", // Nimm + "", // Bestand + "gegen", // Benutze + "", // Betatige + "a", // Sprich + "" // NOACTION + }; + static const CommandeType systemMenu_DE[] = { "Pause", "Spiel Neu Starten", @@ -415,8 +453,7 @@ void initLanguage(Common::Language lang) { "Er L\x84""dt | %s", "Ladevorgang Abgebrochen...", "Kein Backup im Laufwerk...", - "Geben Sie den Namen|der Sicherungsdiskette ein", - "gegen" + "Geben Sie den Namen|der Sicherungsdiskette ein" }; static const char *failureMessages_IT[] = { @@ -462,6 +499,16 @@ void initLanguage(Common::Language lang) { "NOACTION" }; + static const char *commandPrepositionTable_IT[] = { + "", // ESAMINARE + "", // PRENDERE + "", // INVENTARIO + "su", // UTILIZZARE + "", // AZIONARE + "a", // PARLARE + "" // NOACTION + }; + static const CommandeType systemMenu_IT[] = { "Pausa", "Parte nuova", @@ -483,8 +530,7 @@ void initLanguage(Common::Language lang) { "Caricamento di| %s", "Caricamento annullato...", "Nessun salvataggio su questo disco...", - "Vogliate accedere con il nome del salvataggio", - "su" + "Vogliate accedere con il nome del salvataggio" }; switch (lang) { @@ -494,7 +540,8 @@ void initLanguage(Common::Language lang) { systemMenu = systemMenu_FR; confirmMenu = confirmMenu_FR; otherMessages = otherMessages_FR; - commandPrepositionOn = otherMessages_FR[7]; + defaultCommandPreposition = commandPrepositionTable_FR[3]; + commandPrepositionTable = commandPrepositionTable_FR; break; case Common::ES_ESP: @@ -503,7 +550,8 @@ void initLanguage(Common::Language lang) { systemMenu = systemMenu_ES; confirmMenu = confirmMenu_ES; otherMessages = otherMessages_ES; - commandPrepositionOn = otherMessages_ES[7]; + defaultCommandPreposition = commandPrepositionTable_ES[3]; + commandPrepositionTable = commandPrepositionTable_ES; break; case Common::DE_DEU: @@ -512,7 +560,8 @@ void initLanguage(Common::Language lang) { systemMenu = systemMenu_DE; confirmMenu = confirmMenu_DE; otherMessages = otherMessages_DE; - commandPrepositionOn = otherMessages_DE[7]; + defaultCommandPreposition = commandPrepositionTable_DE[3]; + commandPrepositionTable = commandPrepositionTable_DE; break; case Common::IT_ITA: @@ -521,7 +570,8 @@ void initLanguage(Common::Language lang) { systemMenu = systemMenu_IT; confirmMenu = confirmMenu_IT; otherMessages = otherMessages_IT; - commandPrepositionOn = otherMessages_IT[7]; + defaultCommandPreposition = commandPrepositionTable_IT[3]; + commandPrepositionTable = commandPrepositionTable_IT; break; default: @@ -530,7 +580,8 @@ void initLanguage(Common::Language lang) { systemMenu = systemMenu_EN; confirmMenu = confirmMenu_EN; otherMessages = otherMessages_EN; - commandPrepositionOn = otherMessages_EN[7]; + defaultCommandPreposition = commandPrepositionTable_EN[3]; + commandPrepositionTable = commandPrepositionTable_EN; break; } diff --git a/engines/cine/texte.h b/engines/cine/texte.h index 03d0c5faec..bc4beac492 100644 --- a/engines/cine/texte.h +++ b/engines/cine/texte.h @@ -51,7 +51,8 @@ extern const CommandeType *defaultActionCommand; extern const CommandeType *systemMenu; extern const CommandeType *confirmMenu; extern const char **otherMessages; -extern const char *commandPrepositionOn; +extern const char *defaultCommandPreposition; +extern const char **commandPrepositionTable; void loadTextData(const char *filename); void loadErrmessDat(const char *fname); diff --git a/engines/cine/various.cpp b/engines/cine/various.cpp index 6da2931c8a..a3359287ce 100644 --- a/engines/cine/various.cpp +++ b/engines/cine/various.cpp @@ -1491,6 +1491,8 @@ int16 selectSubObject(int16 x, int16 y, int16 param) { return objListTab[selectedObject]; } +// TODO: Make separate functions for Future Wars's and Operation Stealth's version of this function, this is getting too messy +// TODO: Add support for using the different prepositions for different verbs (Doesn't work currently) void makeCommandLine(void) { uint16 x, y; @@ -1515,8 +1517,12 @@ void makeCommandLine(void) { } if (si < 0) { - playerCommand = -1; - commandBuffer = ""; + if (g_cine->getGameType() == Cine::GType_OS) { + canUseOnObject = 0; + } else { // Future Wars + playerCommand = -1; + commandBuffer = ""; + } } else { if (g_cine->getGameType() == Cine::GType_OS) { if (si >= 8000) { @@ -1532,9 +1538,15 @@ void makeCommandLine(void) { commandBuffer += " "; commandBuffer += objectTable[commandVar3[0]].name; commandBuffer += " "; - commandBuffer += commandPrepositionOn; + if (g_cine->getGameType() == Cine::GType_OS) { + commandBuffer += commandPrepositionTable[playerCommand]; + } else { // Future Wars + commandBuffer += defaultCommandPreposition; + } } - } else { + } + + if (g_cine->getGameType() == Cine::GType_OS || !(playerCommand != -1 && choiceResultTable[playerCommand] == 2)) { if (playerCommand == 2) { getMouseData(mouseUpdateStatus, &dummyU16, &x, &y); processInventory(x, y + 8); @@ -1544,7 +1556,7 @@ void makeCommandLine(void) { } } - if (g_cine->getGameType() == Cine::GType_OS) { + if (g_cine->getGameType() == Cine::GType_OS && playerCommand != 2) { if (playerCommand != -1 && canUseOnObject != 0) { // call use on sub object int16 si; @@ -1552,34 +1564,37 @@ void makeCommandLine(void) { si = selectSubObject(x, y + 8, -subObjectUseTable[playerCommand]); - if (si) { + if (si >= 0) { if (si >= 8000) { si -= 8000; } commandVar3[commandVar1] = si; - commandVar1++; - - // TODO: add command message draw + commandBuffer += " "; + commandBuffer += objectTable[si].name; } + } - isDrawCommandEnabled = 1; + isDrawCommandEnabled = 1; - if (playerCommand != -1 && choiceResultTable[playerCommand] == commandVar1) { - SelectedObjStruct obj; - obj.idx = commandVar3[0]; - obj.param = commandVar3[1]; - int16 di = getRelEntryForObject(playerCommand, commandVar1, &obj); + if (playerCommand != -1 && choiceResultTable[playerCommand] == commandVar1) { + SelectedObjStruct obj; + obj.idx = commandVar3[0]; + obj.param = commandVar3[1]; + int16 di = getRelEntryForObject(playerCommand, commandVar1, &obj); - if (di != -1) { - runObjectScript(di); - } - } + if (di != -1) { + runObjectScript(di); + } // TODO: else addFailureMessage(playerCommand) + + playerCommand = -1; + commandVar1 = 0; + commandBuffer = ""; } } - if (!disableSystemMenu) { + if (g_cine->getGameType() == Cine::GType_OS || !disableSystemMenu) { isDrawCommandEnabled = 1; renderer->setCommand(commandBuffer); } -- cgit v1.2.3 From e547eeb116a7747aaf49f82a626418ecf9cc69e9 Mon Sep 17 00:00:00 2001 From: Kari Salminen Date: Tue, 12 Aug 2008 20:27:49 +0000 Subject: Tiny comment fix. svn-id: r33807 --- engines/cine/texte.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'engines') diff --git a/engines/cine/texte.cpp b/engines/cine/texte.cpp index a7533c30a9..b5ca628b03 100644 --- a/engines/cine/texte.cpp +++ b/engines/cine/texte.cpp @@ -417,7 +417,7 @@ void initLanguage(Common::Language lang) { "Nimm", "Bestand", "Benutze", - "Bet\x84tige", // FIXME? The third letter should be Latin Small Letter A with diaeresis + "Bet\x84tige", // FIXME? The fourth letter should be Latin Small Letter A with diaeresis "Sprich", "NOACTION" }; -- cgit v1.2.3 From 095fa5552754626fb12f5c6bc97104697658d671 Mon Sep 17 00:00:00 2001 From: Kari Salminen Date: Tue, 12 Aug 2008 20:58:26 +0000 Subject: Fix for GCC warning in OSRenderer::renderOverlay: declaration of 'len' shadows a previous local. svn-id: r33808 --- engines/cine/gfx.cpp | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) (limited to 'engines') diff --git a/engines/cine/gfx.cpp b/engines/cine/gfx.cpp index f0149043f9..3c8966b7ec 100644 --- a/engines/cine/gfx.cpp +++ b/engines/cine/gfx.cpp @@ -1071,10 +1071,11 @@ void OSRenderer::drawBackground() { * \todo Add handling of type 22 overlays */ void OSRenderer::renderOverlay(const Common::List::iterator &it) { - int len; + int len, idx, width, height; objectStruct *obj; AnimData *sprite; byte *mask; + byte color; switch (it->type) { // color sprite @@ -1105,18 +1106,17 @@ void OSRenderer::renderOverlay(const Common::List::iterator &it) { break; // action failure message - case 3: { - int idx = it->objIdx * 4 + g_cine->_rnd.getRandomNumber(3); - int len = strlen(failureMessages[idx]); + case 3: + idx = it->objIdx * 4 + g_cine->_rnd.getRandomNumber(3); + len = strlen(failureMessages[idx]); _messageLen += len; - int width = 6 * len + 20; + width = 6 * len + 20; width = width > 300 ? 300 : width; // The used color here differs from Future Wars drawMessage(failureMessages[idx], (320 - width) / 2, 80, width, _messageBg); waitForPlayerClick = 1; break; - } // bitmap case 4: @@ -1147,18 +1147,17 @@ void OSRenderer::renderOverlay(const Common::List::iterator &it) { // TODO: Check how the original game looks under DOSBox to see if the oxygen gauge works in it case 21: // A filled rectangle: - case 22: { + case 22: // TODO: Check it this implementation really works correctly (Some things might be wrong, needs testing). assert(it->objIdx < NUM_MAX_OBJECT); obj = &objectTable[it->objIdx]; - byte color = obj->part & 0x0F; - int width = obj->frame; - int height = obj->costume; + color = obj->part & 0x0F; + width = obj->frame; + height = obj->costume; drawPlainBox(obj->x, obj->y, width, height, color); debug(5, "renderOverlay: type=%d, x=%d, y=%d, width=%d, height=%d, color=%d", it->type, obj->x, obj->y, width, height, color); break; - } // something else default: -- cgit v1.2.3 From 03edc74ef69cdedfc440607cad2109500d87d2e3 Mon Sep 17 00:00:00 2001 From: Joost Peters Date: Tue, 12 Aug 2008 21:23:40 +0000 Subject: fix typo 'baclup' -> 'backup' svn-id: r33809 --- engines/cine/texte.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'engines') diff --git a/engines/cine/texte.cpp b/engines/cine/texte.cpp index b5ca628b03..33c16159ec 100644 --- a/engines/cine/texte.cpp +++ b/engines/cine/texte.cpp @@ -216,7 +216,7 @@ void initLanguage(Common::Language lang) { "PAUSE", "Loading | %s", "Loading canceled ...", - "No baclup in the drive...", + "No backup in the drive...", "Please enter the backup name" }; -- cgit v1.2.3 From 00cbedb25f891ef508e71c49ffa0f9973361ba60 Mon Sep 17 00:00:00 2001 From: Kari Salminen Date: Tue, 12 Aug 2008 22:45:38 +0000 Subject: Added possibility to get the read resource's size from readBundleFile. Made loadMsg handle input data that has empty strings residing just beyond the input buffer (Thanks Valgrind :-)). svn-id: r33810 --- engines/cine/msg.cpp | 45 ++++++++++++++++++++++++++++----------------- engines/cine/part.cpp | 7 ++++++- engines/cine/part.h | 2 +- 3 files changed, 35 insertions(+), 19 deletions(-) (limited to 'engines') diff --git a/engines/cine/msg.cpp b/engines/cine/msg.cpp index 55eb627309..c826db3bf3 100644 --- a/engines/cine/msg.cpp +++ b/engines/cine/msg.cpp @@ -34,29 +34,40 @@ namespace Cine { Common::StringList messageTable; void loadMsg(char *pMsgName) { - int i, count, len; - byte *ptr, *dataPtr; - const char *messagePtr; + uint32 sourceSize; checkDataDisk(-1); - messageTable.clear(); - - ptr = dataPtr = readBundleFile(findFileInBundle(pMsgName)); + byte *dataPtr = readBundleFile(findFileInBundle(pMsgName), &sourceSize); setMouseCursor(MOUSE_CURSOR_DISK); - count = READ_BE_UINT16(ptr); - ptr += 2; - - messagePtr = (const char*)(ptr + 2 * count); - - for (i = 0; i < count; i++) { - len = READ_BE_UINT16(ptr); - ptr += 2; - - messageTable.push_back(messagePtr); - messagePtr += len; + uint count = READ_BE_UINT16(dataPtr); + uint messageLenPos = 2; + uint messageDataPos = messageLenPos + 2 * count; + + // Read in the messages + for (uint i = 0; i < count; i++) { + // Read message's length + uint messageLen = READ_BE_UINT16(dataPtr + messageLenPos); + messageLenPos += 2; + + // Store the read message. + // This code works around input data that has empty strings residing outside the input + // buffer (e.g. message indexes 58-254 in BATEAU.MSG in PROCS08 in Operation Stealth). + if (messageDataPos < sourceSize) { + messageTable.push_back((const char *)(dataPtr + messageDataPos)); + } else { + if (messageLen > 0) { // Only warn about overflowing non-empty strings + warning("loadMsg(%s): message (%d. / %d) is overflowing the input buffer. Replacing it with an empty string", pMsgName, i + 1, count); + } else { + debugC(5, kCineDebugPart, "loadMsg(%s): empty message (%d. / %d) resides outside input buffer", pMsgName, i + 1, count); + } + // Message resides outside the input buffer so we replace it with an empty string + messageTable.push_back(""); + } + // Jump to the next message + messageDataPos += messageLen; } free(dataPtr); diff --git a/engines/cine/part.cpp b/engines/cine/part.cpp index df530b77f2..657471be4e 100644 --- a/engines/cine/part.cpp +++ b/engines/cine/part.cpp @@ -217,7 +217,7 @@ void readFromPart(int16 idx, byte *dataPtr, uint32 maxSize) { g_cine->_partFileHandle.read(dataPtr, MIN(partBuffer[idx].packedSize, maxSize)); } -byte *readBundleFile(int16 foundFileIdx) { +byte *readBundleFile(int16 foundFileIdx, uint32 *size) { assert(foundFileIdx >= 0 && foundFileIdx < (int32)partBuffer.size()); bool error = false; byte *dataPtr = (byte *)calloc(partBuffer[foundFileIdx].unpackedSize, 1); @@ -236,6 +236,11 @@ byte *readBundleFile(int16 foundFileIdx) { warning("Error unpacking '%s' from bundle file '%s'", partBuffer[foundFileIdx].partName, currentPartName); } + // Set the size variable if a pointer to it has been given + if (size != NULL) { + *size = partBuffer[foundFileIdx].unpackedSize; + } + return dataPtr; } diff --git a/engines/cine/part.h b/engines/cine/part.h index dc9d1db537..755f843b4a 100644 --- a/engines/cine/part.h +++ b/engines/cine/part.h @@ -46,7 +46,7 @@ int16 findFileInBundle(const char *fileName); void readFromPart(int16 idx, byte *dataPtr, uint32 maxSize); -byte *readBundleFile(int16 foundFileIdx); +byte *readBundleFile(int16 foundFileIdx, uint32 *size = NULL); byte *readBundleSoundFile(const char *entryName, uint32 *size = 0); byte *readFile(const char *filename, bool crypted = false); -- cgit v1.2.3 From 954244d3502343cc945f730bddd116f1e461d46f Mon Sep 17 00:00:00 2001 From: Kari Salminen Date: Tue, 12 Aug 2008 23:44:39 +0000 Subject: Fixed drawPlainBox's boundary checking (It wrote outside the screen occasionally). Now using the Common::Rect for clipping, yay! It's good. svn-id: r33811 --- engines/cine/gfx.cpp | 58 ++++++++++++++++++++++------------------------------ 1 file changed, 24 insertions(+), 34 deletions(-) (limited to 'engines') diff --git a/engines/cine/gfx.cpp b/engines/cine/gfx.cpp index 3c8966b7ec..3c47c9ec9c 100644 --- a/engines/cine/gfx.cpp +++ b/engines/cine/gfx.cpp @@ -287,54 +287,44 @@ void FWRenderer::drawMessage(const char *str, int x, int y, int width, int color * \param width Rectangle width (Negative values draw the box horizontally flipped) * \param height Rectangle height (Negative values draw the box vertically flipped) * \param color Fill color - * \note Rectangle's drawn width is always at least one. - * \note Rectangle's drawn height is always at least one. + * \note An on-screen rectangle's drawn width is always at least one. + * \note An on-screen rectangle's drawn height is always at least one. */ void FWRenderer::drawPlainBox(int x, int y, int width, int height, byte color) { - int i; + // Make width's and height's absolute values at least one + // which forces this function to always draw something if the + // drawing position is inside screen bounds. This fixes at least + // the showing of the oxygen gauge meter in Operation Stealth's + // first arcade sequence where this function is called with a + // height of zero. + if (width == 0) { + width = 1; + } + if (height == 0) { + height = 1; + } // Handle horizontally flipped boxes if (width < 0) { - x += width; width = ABS(width); + x -= width; } // Handle vertically flipped boxes if (height < 0) { - y += height; height = ABS(height); + y -= height; } - // Handle horizontal boundaries - if (x < 0) { - width += x; // Remove invisible columns - x = 0; // Start drawing at the screen's left border - } else if (x > 319) { - // Nothing left to draw as we're over the screen's right border - width = 0; - } - - // Handle vertical boundaries - if (y < 0) { - height += y; // Remove invisible rows - y = 0; // Start drawing at the screen's top border - } else if (y > 199) { - // Nothing left to draw as we're below the screen's bottom border - height = 0; - } - - // Make width and height at least one - // which forces this function to always draw something. - // This fixes at least the showing of the oxygen gauge meter in - // Operation Stealth's first arcade sequence where this function - // is called with a height of zero. - width = MAX(1, width); - height = MAX(1, height); + // Clip the rectangle to screen dimensions + Common::Rect boxRect(x, y, x + width, y + height); + Common::Rect screenRect(320, 200); + boxRect.clip(screenRect); - // Draw the filled rectangle - byte *dest = _backBuffer + y * 320 + x; - for (i = 0; i < height; i++) { - memset(dest + i * 320, color, width); + // Draw the filled rectangle + byte *dest = _backBuffer + boxRect.top * 320 + boxRect.left; + for (int i = 0; i < boxRect.height(); i++) { + memset(dest + i * 320, color, boxRect.width()); } } -- cgit v1.2.3 From 582104752b337adcc2f51b3fa4842a0b8a5b42db Mon Sep 17 00:00:00 2001 From: Kari Salminen Date: Tue, 12 Aug 2008 23:56:13 +0000 Subject: Hopefully fixes 'Conditional jump or move depends on uninitialised value(s)' Valgrind warning at sound.cpp:611. svn-id: r33812 --- engines/cine/sound.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'engines') diff --git a/engines/cine/sound.cpp b/engines/cine/sound.cpp index f26032fe98..3618350476 100644 --- a/engines/cine/sound.cpp +++ b/engines/cine/sound.cpp @@ -604,6 +604,7 @@ bool PCSoundFxPlayer::load(const char *song) { _instrumentsData[i] = NULL; char instrument[64]; + memset(instrument, 0, 64); // Clear the data first memcpy(instrument, _sfxData + 20 + i * 30, 12); instrument[63] = '\0'; -- cgit v1.2.3 From eeba630cbf48b093bd07d3e8413d6059fddb07df Mon Sep 17 00:00:00 2001 From: Kari Salminen Date: Wed, 13 Aug 2008 01:02:00 +0000 Subject: Changed Agi::SoundMgr's sound buffer to a member array of size BUFFER_SIZE. Also added initialization of _playing to false in SoundMgr's constructor. Hopefully helps with the occasional crashes in the sound code when starting the first sound in an AGI game. svn-id: r33815 --- engines/agi/sound.cpp | 19 +++++++------------ engines/agi/sound.h | 3 ++- 2 files changed, 9 insertions(+), 13 deletions(-) (limited to 'engines') diff --git a/engines/agi/sound.cpp b/engines/agi/sound.cpp index 77f79272f8..69ccc2c218 100644 --- a/engines/agi/sound.cpp +++ b/engines/agi/sound.cpp @@ -435,13 +435,9 @@ void IIgsMidiChannel::stopSounds() { _gsChannels.clear(); } -static int16 *buffer; - int SoundMgr::initSound() { int r = -1; - buffer = _sndBuffer = (int16 *)calloc(2, BUFFER_SIZE); - _env = false; switch (_vm->_soundemu) { @@ -478,7 +474,6 @@ int SoundMgr::initSound() { void SoundMgr::deinitSound() { debugC(3, kDebugLevelSound, "()"); _mixer->stopHandle(_soundHandle); - free(_sndBuffer); } void SoundMgr::stopNote(int i) { @@ -1185,7 +1180,7 @@ bool SoundMgr::loadInstruments() { return _gsSound.loadWaveFile(waveFsnode->getPath(), *exeInfo) && _gsSound.loadInstrumentHeaders(exeFsnode->getPath(), *exeInfo); } -static void fillAudio(void *udata, int16 *stream, uint len) { +void SoundMgr::fillAudio(void *udata, int16 *stream, uint len) { SoundMgr *soundMgr = (SoundMgr *)udata; uint32 p = 0; static uint32 n = 0, s = 0; @@ -1193,32 +1188,32 @@ static void fillAudio(void *udata, int16 *stream, uint len) { len <<= 2; debugC(5, kDebugLevelSound, "(%p, %p, %d)", (void *)udata, (void *)stream, len); - memcpy(stream, (uint8 *)buffer + s, p = n); + memcpy(stream, ((uint8 *)&_sndBuffer[0]) + s, p = n); for (n = 0, len -= p; n < len; p += n, len -= n) { soundMgr->playSound(); n = soundMgr->mixSound() << 1; if (len < n) { - memcpy((uint8 *)stream + p, buffer, len); + memcpy((uint8 *)stream + p, _sndBuffer, len); s = len; n -= s; return; } else { - memcpy((uint8 *)stream + p, buffer, n); + memcpy((uint8 *)stream + p, _sndBuffer, n); } } soundMgr->playSound(); n = soundMgr->mixSound() << 1; - memcpy((uint8 *)stream + p, buffer, s = len); + memcpy((uint8 *)stream + p, _sndBuffer, s = len); n -= s; } -SoundMgr::SoundMgr(AgiBase *agi, Audio::Mixer *pMixer) { +SoundMgr::SoundMgr(AgiBase *agi, Audio::Mixer *pMixer) : _sndBuffer() { _vm = agi; _mixer = pMixer; _sampleRate = pMixer->getOutputRate(); _endflag = -1; + _playing = false; _playingSound = -1; - _sndBuffer = 0; _waveform = 0; } diff --git a/engines/agi/sound.h b/engines/agi/sound.h index f1c2782421..9b71ac388e 100644 --- a/engines/agi/sound.h +++ b/engines/agi/sound.h @@ -468,10 +468,11 @@ private: int _playingSound; uint8 _env; - int16 *_sndBuffer; + int16 _sndBuffer[BUFFER_SIZE]; const int16 *_waveform; void premixerCall(int16 *buf, uint len); + void fillAudio(void *udata, int16 *stream, uint len); public: void unloadSound(int); -- cgit v1.2.3 From be9192687b22e11bee2fe98f5e06a7a2dd623fd1 Mon Sep 17 00:00:00 2001 From: Kari Salminen Date: Wed, 13 Aug 2008 01:10:03 +0000 Subject: Shutting up Valgrind about using uninitialised values from array _chn in function stopNote. svn-id: r33816 --- engines/agi/sound.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'engines') diff --git a/engines/agi/sound.cpp b/engines/agi/sound.cpp index 69ccc2c218..ec56763a93 100644 --- a/engines/agi/sound.cpp +++ b/engines/agi/sound.cpp @@ -1207,7 +1207,7 @@ void SoundMgr::fillAudio(void *udata, int16 *stream, uint len) { n -= s; } -SoundMgr::SoundMgr(AgiBase *agi, Audio::Mixer *pMixer) : _sndBuffer() { +SoundMgr::SoundMgr(AgiBase *agi, Audio::Mixer *pMixer) : _sndBuffer(), _chn() { _vm = agi; _mixer = pMixer; _sampleRate = pMixer->getOutputRate(); -- cgit v1.2.3 From 9b8665fa85ae2a65d448ad9dba06dd27455f48d1 Mon Sep 17 00:00:00 2001 From: Max Horn Date: Wed, 13 Aug 2008 10:13:22 +0000 Subject: Clarify SCUMM MD5 message: We do not want reports on fanmade translations svn-id: r33817 --- engines/scumm/detection.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'engines') diff --git a/engines/scumm/detection.cpp b/engines/scumm/detection.cpp index 68d3010199..ca5dba7865 100644 --- a/engines/scumm/detection.cpp +++ b/engines/scumm/detection.cpp @@ -820,9 +820,10 @@ PluginError ScummMetaEngine::createInstance(OSystem *syst, Engine **engine) cons // unknown MD5, or with a medium debug level in case of a known MD5 (for // debugging purposes). if (!findInMD5Table(res.md5.c_str())) { - printf("Your game version appears to be unknown. Please, report the following\n"); - printf("data to the ScummVM team along with name of the game you tried to add\n"); - printf("and its version/language/etc.:\n"); + printf("Your game version appears to be unknown. If this is *NOT* a fan-modified\n"); + printf("version (in particular, not a fan-made translation), please, report the\n"); + printf("following data to the ScummVM team along with name of the game you tried\n"); + printf("to add and its version/language/etc.:\n"); printf(" SCUMM gameid '%s', file '%s', MD5 '%s'\n\n", res.game.gameid, -- cgit v1.2.3 From f69cc559b9d35526b25ac76bcc82046471b39d06 Mon Sep 17 00:00:00 2001 From: Kari Salminen Date: Wed, 13 Aug 2008 11:36:45 +0000 Subject: Reverted r33815 (But not r33816). svn-id: r33819 --- engines/agi/sound.cpp | 19 ++++++++++++------- engines/agi/sound.h | 3 +-- 2 files changed, 13 insertions(+), 9 deletions(-) (limited to 'engines') diff --git a/engines/agi/sound.cpp b/engines/agi/sound.cpp index ec56763a93..cfa87d2c98 100644 --- a/engines/agi/sound.cpp +++ b/engines/agi/sound.cpp @@ -435,9 +435,13 @@ void IIgsMidiChannel::stopSounds() { _gsChannels.clear(); } +static int16 *buffer; + int SoundMgr::initSound() { int r = -1; + buffer = _sndBuffer = (int16 *)calloc(2, BUFFER_SIZE); + _env = false; switch (_vm->_soundemu) { @@ -474,6 +478,7 @@ int SoundMgr::initSound() { void SoundMgr::deinitSound() { debugC(3, kDebugLevelSound, "()"); _mixer->stopHandle(_soundHandle); + free(_sndBuffer); } void SoundMgr::stopNote(int i) { @@ -1180,7 +1185,7 @@ bool SoundMgr::loadInstruments() { return _gsSound.loadWaveFile(waveFsnode->getPath(), *exeInfo) && _gsSound.loadInstrumentHeaders(exeFsnode->getPath(), *exeInfo); } -void SoundMgr::fillAudio(void *udata, int16 *stream, uint len) { +static void fillAudio(void *udata, int16 *stream, uint len) { SoundMgr *soundMgr = (SoundMgr *)udata; uint32 p = 0; static uint32 n = 0, s = 0; @@ -1188,32 +1193,32 @@ void SoundMgr::fillAudio(void *udata, int16 *stream, uint len) { len <<= 2; debugC(5, kDebugLevelSound, "(%p, %p, %d)", (void *)udata, (void *)stream, len); - memcpy(stream, ((uint8 *)&_sndBuffer[0]) + s, p = n); + memcpy(stream, (uint8 *)buffer + s, p = n); for (n = 0, len -= p; n < len; p += n, len -= n) { soundMgr->playSound(); n = soundMgr->mixSound() << 1; if (len < n) { - memcpy((uint8 *)stream + p, _sndBuffer, len); + memcpy((uint8 *)stream + p, buffer, len); s = len; n -= s; return; } else { - memcpy((uint8 *)stream + p, _sndBuffer, n); + memcpy((uint8 *)stream + p, buffer, n); } } soundMgr->playSound(); n = soundMgr->mixSound() << 1; - memcpy((uint8 *)stream + p, _sndBuffer, s = len); + memcpy((uint8 *)stream + p, buffer, s = len); n -= s; } -SoundMgr::SoundMgr(AgiBase *agi, Audio::Mixer *pMixer) : _sndBuffer(), _chn() { +SoundMgr::SoundMgr(AgiBase *agi, Audio::Mixer *pMixer) : _chn() { _vm = agi; _mixer = pMixer; _sampleRate = pMixer->getOutputRate(); _endflag = -1; - _playing = false; _playingSound = -1; + _sndBuffer = 0; _waveform = 0; } diff --git a/engines/agi/sound.h b/engines/agi/sound.h index 9b71ac388e..f1c2782421 100644 --- a/engines/agi/sound.h +++ b/engines/agi/sound.h @@ -468,11 +468,10 @@ private: int _playingSound; uint8 _env; - int16 _sndBuffer[BUFFER_SIZE]; + int16 *_sndBuffer; const int16 *_waveform; void premixerCall(int16 *buf, uint len); - void fillAudio(void *udata, int16 *stream, uint len); public: void unloadSound(int); -- cgit v1.2.3 From 09762ac7a6c7e201b44466b8286aa1e53e7fadaa Mon Sep 17 00:00:00 2001 From: Kari Salminen Date: Wed, 13 Aug 2008 11:57:48 +0000 Subject: Fixed initialization of some SoundMgr-class's member variables. Moved _sndBuffer's allocation to SoundMgr's constructor and its deallocation to the destructor. Made fillAudio SoundMgr's method and removed a superfluous global static variable 'int16 *buffer'. Should help with the occasional crashes when starting the first sound in an AGI game. svn-id: r33822 --- engines/agi/sound.cpp | 21 ++++++++++----------- engines/agi/sound.h | 1 + 2 files changed, 11 insertions(+), 11 deletions(-) (limited to 'engines') diff --git a/engines/agi/sound.cpp b/engines/agi/sound.cpp index cfa87d2c98..9fe8fbf41a 100644 --- a/engines/agi/sound.cpp +++ b/engines/agi/sound.cpp @@ -435,13 +435,10 @@ void IIgsMidiChannel::stopSounds() { _gsChannels.clear(); } -static int16 *buffer; - int SoundMgr::initSound() { int r = -1; - buffer = _sndBuffer = (int16 *)calloc(2, BUFFER_SIZE); - + memset(_sndBuffer, 0, BUFFER_SIZE << 1); _env = false; switch (_vm->_soundemu) { @@ -478,7 +475,6 @@ int SoundMgr::initSound() { void SoundMgr::deinitSound() { debugC(3, kDebugLevelSound, "()"); _mixer->stopHandle(_soundHandle); - free(_sndBuffer); } void SoundMgr::stopNote(int i) { @@ -1185,7 +1181,7 @@ bool SoundMgr::loadInstruments() { return _gsSound.loadWaveFile(waveFsnode->getPath(), *exeInfo) && _gsSound.loadInstrumentHeaders(exeFsnode->getPath(), *exeInfo); } -static void fillAudio(void *udata, int16 *stream, uint len) { +void SoundMgr::fillAudio(void *udata, int16 *stream, uint len) { SoundMgr *soundMgr = (SoundMgr *)udata; uint32 p = 0; static uint32 n = 0, s = 0; @@ -1193,22 +1189,22 @@ static void fillAudio(void *udata, int16 *stream, uint len) { len <<= 2; debugC(5, kDebugLevelSound, "(%p, %p, %d)", (void *)udata, (void *)stream, len); - memcpy(stream, (uint8 *)buffer + s, p = n); + memcpy(stream, (uint8 *)_sndBuffer + s, p = n); for (n = 0, len -= p; n < len; p += n, len -= n) { soundMgr->playSound(); n = soundMgr->mixSound() << 1; if (len < n) { - memcpy((uint8 *)stream + p, buffer, len); + memcpy((uint8 *)stream + p, _sndBuffer, len); s = len; n -= s; return; } else { - memcpy((uint8 *)stream + p, buffer, n); + memcpy((uint8 *)stream + p, _sndBuffer, n); } } soundMgr->playSound(); n = soundMgr->mixSound() << 1; - memcpy((uint8 *)stream + p, buffer, s = len); + memcpy((uint8 *)stream + p, _sndBuffer, s = len); n -= s; } @@ -1218,7 +1214,9 @@ SoundMgr::SoundMgr(AgiBase *agi, Audio::Mixer *pMixer) : _chn() { _sampleRate = pMixer->getOutputRate(); _endflag = -1; _playingSound = -1; - _sndBuffer = 0; + _env = false; + _playing = false; + _sndBuffer = (int16 *)calloc(2, BUFFER_SIZE); _waveform = 0; } @@ -1231,6 +1229,7 @@ void SoundMgr::setVolume(uint8 volume) { } SoundMgr::~SoundMgr() { + free(_sndBuffer); } } // End of namespace Agi diff --git a/engines/agi/sound.h b/engines/agi/sound.h index f1c2782421..a1f079891f 100644 --- a/engines/agi/sound.h +++ b/engines/agi/sound.h @@ -472,6 +472,7 @@ private: const int16 *_waveform; void premixerCall(int16 *buf, uint len); + void fillAudio(void *udata, int16 *stream, uint len); public: void unloadSound(int); -- cgit v1.2.3 From 6ee8022bac3d14fae9b9d0548e2a638534c6d0ac Mon Sep 17 00:00:00 2001 From: Kari Salminen Date: Wed, 13 Aug 2008 13:40:28 +0000 Subject: Type 21 overlay comment update (Found the drawing routine in the disassembly and checked the original for how the oxygen gauge during the first arcade sequence looks like. They're some kind of sprites most likely and not just simply filled rectangles). svn-id: r33826 --- engines/cine/gfx.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'engines') diff --git a/engines/cine/gfx.cpp b/engines/cine/gfx.cpp index 3c47c9ec9c..3198427117 100644 --- a/engines/cine/gfx.cpp +++ b/engines/cine/gfx.cpp @@ -1129,12 +1129,12 @@ void OSRenderer::renderOverlay(const Common::List::iterator &it) { maskBgOverlay(_bgTable[it->x].bg, sprite->data(), sprite->_realWidth, sprite->_height, _backBuffer, obj->x, obj->y); break; - // FIXME: Looking at Operation Stealth's disassembly I can't find any codepath that - // will draw a type 21 overlay. But looking at the first arcade sequence's scripts - // it looks like the oxygen gauge meter is implemented using a type 21 overlay. - // So for the time being I'm simply drawing type 21 overlays as type 22 overlays - // and hoping for the best. - // TODO: Check how the original game looks under DOSBox to see if the oxygen gauge works in it + // FIXME: Implement correct drawing of type 21 overlays. + // Type 21 overlays aren't just filled rectangles, I found their drawing routine + // from Operation Stealth's drawSprite routine. So they're likely some kind of sprites + // and it's just a coincidence that the oxygen meter during the first arcade sequence + // works even somehow currently. I tried the original under DOSBox and the oxygen gauge + // is a long red bar that gets shorter as the air runs out. case 21: // A filled rectangle: case 22: -- cgit v1.2.3 From 0f95bb9fd516ad9d61f9d8ccc492cdb1c69cfc87 Mon Sep 17 00:00:00 2001 From: Johannes Schickel Date: Wed, 13 Aug 2008 19:10:31 +0000 Subject: Added detection entries for kyra3 Mac. svn-id: r33837 --- engines/kyra/detection.cpp | 47 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) (limited to 'engines') diff --git a/engines/kyra/detection.cpp b/engines/kyra/detection.cpp index 160a60d6f4..0ae289e09d 100644 --- a/engines/kyra/detection.cpp +++ b/engines/kyra/detection.cpp @@ -655,6 +655,53 @@ const KYRAGameDescription adGameDescs[] = { KYRA3_CD_INS_FLAGS }, + // Mac version + { + { + "kyra3", + 0, + { + { "ONETIME.PAK", 0, "3833ff312757b8e6147f464cca0a6587", -1 }, + { "AUD.PAK", 0, 0, -1 }, + { 0, 0, 0, 0 } + }, + Common::EN_ANY, + Common::kPlatformMacintosh, + Common::ADGF_DROPLANGUAGE + }, + KYRA3_CD_INS_FLAGS + }, + { + { + "kyra3", + 0, + { + { "ONETIME.PAK", 0, "3833ff312757b8e6147f464cca0a6587", -1 }, + { "AUD.PAK", 0, 0, -1 }, + { 0, 0, 0, 0 } + }, + Common::DE_DEU, + Common::kPlatformMacintosh, + Common::ADGF_DROPLANGUAGE + }, + KYRA3_CD_INS_FLAGS + }, + { + { + "kyra3", + 0, + { + { "ONETIME.PAK", 0, "3833ff312757b8e6147f464cca0a6587", -1 }, + { "AUD.PAK", 0, 0, -1 }, + { 0, 0, 0, 0 } + }, + Common::FR_FRA, + Common::kPlatformMacintosh, + Common::ADGF_DROPLANGUAGE + }, + KYRA3_CD_INS_FLAGS + }, + // Spanish fan translation, see fr#1994040 "KYRA3: Add support for Spanish fan translation" { { -- cgit v1.2.3 From 4a46c99026b4287c8cbb69d60a4ddeb3f8026bd7 Mon Sep 17 00:00:00 2001 From: Nicola Mettifogo Date: Thu, 14 Aug 2008 07:10:42 +0000 Subject: Removed cross-references between the general parser and the text formatter. To achieve this, I have rewritten the latter for both NS and BRA. svn-id: r33858 --- engines/parallaction/balloons.cpp | 512 ++++++++++++++++++++------------------ 1 file changed, 264 insertions(+), 248 deletions(-) (limited to 'engines') diff --git a/engines/parallaction/balloons.cpp b/engines/parallaction/balloons.cpp index bbd8bc9ca7..222954ec3a 100644 --- a/engines/parallaction/balloons.cpp +++ b/engines/parallaction/balloons.cpp @@ -30,6 +30,183 @@ namespace Parallaction { +class WrappedLineFormatter { + +protected: + Common::String _line; + Font *_font; + uint16 _lines, _lineWidth; + + virtual void setup() = 0; + virtual void action() = 0; + virtual void end() = 0; + virtual Common::String expand(const Common::String &token) { return token; } + + void textAccum(const Common::String &token, uint16 width) { + if (token.empty()) { + return; + } + + _lineWidth += width; + _line += token; + } + + void textNewLine() { + _lines++; + _lineWidth = 0; + _line.clear(); + } + +public: + WrappedLineFormatter(Font *font) : _font(font) { } + virtual ~WrappedLineFormatter() { } + + virtual void calc(const char *text, uint16 maxwidth) { + setup(); + + _lineWidth = 0; + _line.clear(); + _lines = 0; + + Common::StringTokenizer tokenizer(text, " "); + Common::String token; + Common::String blank(" "); + + uint16 blankWidth = _font->getStringWidth(" "); + uint16 tokenWidth = 0; + + while (!tokenizer.empty()) { + token = tokenizer.nextToken(); + token = expand(token); + + if (token == '/') { + tokenWidth = 0; + action(); + textNewLine(); + } else { + // todo: expand '%' + tokenWidth = _font->getStringWidth(token.c_str()); + + if (_lineWidth == 0) { + textAccum(token, tokenWidth); + } else { + if (_lineWidth + blankWidth + tokenWidth <= maxwidth) { + textAccum(blank, blankWidth); + textAccum(token, tokenWidth); + } else { + action(); + textNewLine(); + textAccum(token, tokenWidth); + } + } + } + } + + end(); + } +}; + +class StringExtent_NS : public WrappedLineFormatter { + + uint _width, _height; + +protected: + virtual Common::String expand(const Common::String &token) { + if (token.compareToIgnoreCase("%p") == 0) { + return Common::String("/"); + } + + return token; + } + + virtual void setup() { + _width = _height = 0; + + _line.clear(); + _lines = 0; + _width = 0; + } + + virtual void action() { + if (_lineWidth > _width) { + _width = _lineWidth; + } + _height = _lines * _font->height(); + } + + virtual void end() { + action(); + } + +public: + StringExtent_NS(Font *font) : WrappedLineFormatter(font) { } + + uint width() const { return _width; } + uint height() const { return _height; } +}; + + +class StringWriter_NS : public WrappedLineFormatter { + + uint _width, _height; + byte _color; + + Graphics::Surface *_surf; + +protected: + virtual Common::String expand(const Common::String& token) { + if (token.compareToIgnoreCase("%p") == 0) { + Common::String t("......."); + for (int i = 0; _password[i]; i++) { + t.setChar(_password[i], i); + } + return Common::String("> ") + t; + } else + if (token.compareToIgnoreCase("%s") == 0) { + char buf[20]; + sprintf(buf, "%i", _score); + return Common::String(buf); + } + + return token; + } + + virtual void setup() { + } + + virtual void action() { + if (_line.empty()) { + return; + } + uint16 rx = 10; + uint16 ry = 4 + _lines * _font->height(); // y + + byte *dst = (byte*)_surf->getBasePtr(rx, ry); + _font->setColor(_color); + _font->drawString(dst, _surf->w, _line.c_str()); + } + + virtual void end() { + action(); + } + +public: + StringWriter_NS(Font *font) : WrappedLineFormatter(font) { } + + void write(const char *text, uint maxWidth, byte color, Graphics::Surface *surf) { + StringExtent_NS se(_font); + se.calc(text, maxWidth); + _width = se.width() + 10; + _height = se.height() + 20; + _color = color; + _surf = surf; + + calc(text, maxWidth); + } + +}; + + #define BALLOON_TRANSPARENT_COLOR_NS 2 #define BALLOON_TRANSPARENT_COLOR_BR 0 @@ -78,8 +255,6 @@ class BalloonManager_ns : public BalloonManager { uint _numBalloons; - void getStringExtent(Font *font, char *text, uint16 maxwidth, int16* width, int16* height); - void drawWrappedText(Font *font, Graphics::Surface* surf, char *text, byte color, int16 wrapwidth); int createBalloon(int16 w, int16 h, int16 winding, uint16 borderThickness); Balloon *getBalloon(uint id); @@ -152,12 +327,16 @@ int BalloonManager_ns::setSingleBalloon(char *text, uint16 x, uint16 y, uint16 w int16 w, h; - getStringExtent(_vm->_dialogueFont, text, MAX_BALLOON_WIDTH, &w, &h); + StringExtent_NS se(_vm->_dialogueFont); + se.calc(text, MAX_BALLOON_WIDTH); + w = se.width() + 14; + h = se.height() + 20; int id = createBalloon(w+5, h, winding, 1); Balloon *balloon = &_intBalloons[id]; - drawWrappedText(_vm->_dialogueFont, balloon->surface, text, textColor, MAX_BALLOON_WIDTH); + StringWriter_NS sw(_vm->_dialogueFont); + sw.write(text, MAX_BALLOON_WIDTH, textColor, balloon->surface); // TODO: extract some text to make a name for obj balloon->obj = _gfx->registerBalloon(new SurfaceToFrames(balloon->surface), 0); @@ -172,12 +351,17 @@ int BalloonManager_ns::setDialogueBalloon(char *text, uint16 winding, byte textC int16 w, h; - getStringExtent(_vm->_dialogueFont, text, MAX_BALLOON_WIDTH, &w, &h); + StringExtent_NS se(_vm->_dialogueFont); + se.calc(text, MAX_BALLOON_WIDTH); + w = se.width() + 14; + h = se.height() + 20; + int id = createBalloon(w+5, h, winding, 1); Balloon *balloon = &_intBalloons[id]; - drawWrappedText(_vm->_dialogueFont, balloon->surface, text, textColor, MAX_BALLOON_WIDTH); + StringWriter_NS sw(_vm->_dialogueFont); + sw.write(text, MAX_BALLOON_WIDTH, textColor, balloon->surface); // TODO: extract some text to make a name for obj balloon->obj = _gfx->registerBalloon(new SurfaceToFrames(balloon->surface), 0); @@ -196,7 +380,9 @@ int BalloonManager_ns::setDialogueBalloon(char *text, uint16 winding, byte textC void BalloonManager_ns::setBalloonText(uint id, char *text, byte textColor) { Balloon *balloon = getBalloon(id); balloon->surface->fillRect(balloon->innerBox, 1); - drawWrappedText(_vm->_dialogueFont, balloon->surface, text, textColor, MAX_BALLOON_WIDTH); + + StringWriter_NS sw(_vm->_dialogueFont); + sw.write(text, MAX_BALLOON_WIDTH, textColor, balloon->surface); } @@ -204,11 +390,15 @@ int BalloonManager_ns::setLocationBalloon(char *text, bool endGame) { int16 w, h; - getStringExtent(_vm->_dialogueFont, text, MAX_BALLOON_WIDTH, &w, &h); + StringExtent_NS se(_vm->_dialogueFont); + se.calc(text, MAX_BALLOON_WIDTH); + w = se.width() + 14; + h = se.height() + 20; int id = createBalloon(w+(endGame ? 5 : 10), h+5, -1, BALLOON_TRANSPARENT_COLOR_NS); Balloon *balloon = &_intBalloons[id]; - drawWrappedText(_vm->_dialogueFont, balloon->surface, text, 0, MAX_BALLOON_WIDTH); + StringWriter_NS sw(_vm->_dialogueFont); + sw.write(text, MAX_BALLOON_WIDTH, 0, balloon->surface); // TODO: extract some text to make a name for obj balloon->obj = _gfx->registerBalloon(new SurfaceToFrames(balloon->surface), 0); @@ -245,110 +435,99 @@ void BalloonManager_ns::freeBalloons() { _numBalloons = 0; } -// TODO: get rid of parseNextToken from here. Use the -// StringTokenizer instead. -void BalloonManager_ns::drawWrappedText(Font *font, Graphics::Surface* surf, char *text, byte color, int16 wrapwidth) { - uint16 lines = 0; - uint16 linewidth = 0; - uint16 rx = 10; - uint16 ry = 4; - uint16 blankWidth = font->getStringWidth(" "); - uint16 tokenWidth = 0; - char token[MAX_TOKEN_LEN]; - if (wrapwidth == -1) - wrapwidth = _vm->_screenWidth; - while (strlen(text) > 0) { - text = parseNextToken(text, token, MAX_TOKEN_LEN, " ", true); - if (!scumm_stricmp(token, "%p")) { - lines++; - rx = 10; - ry = 4 + lines*10; // y - strcpy(token, "> ......."); - strncpy(token+2, _password, strlen(_password)); - tokenWidth = font->getStringWidth(token); - } else { - tokenWidth = font->getStringWidth(token); - linewidth += tokenWidth; - - if (linewidth > wrapwidth) { - // wrap line - lines++; - rx = 10; // x - ry = 4 + lines*10; // y - linewidth = tokenWidth; - } +class StringExtent_BR : public WrappedLineFormatter { - if (!scumm_stricmp(token, "%s")) { - sprintf(token, "%d", _score); - } + uint _width, _height; - } +protected: + virtual void setup() { + _width = _height = 0; - _gfx->drawText(font, surf, rx, ry, token, color); + _line.clear(); + _lines = 0; + _width = 0; + } - rx += tokenWidth + blankWidth; - linewidth += blankWidth; + virtual void action() { + if (_lineWidth > _width) { + _width = _lineWidth; + } + _height = _lines * _font->height(); + } - text = Common::ltrim(text); + virtual void end() { + action(); } -} +public: + StringExtent_BR(Font *font) : WrappedLineFormatter(font) { } -// TODO: get rid of parseNextToken from here. Use the -// StringTokenizer instead. -void BalloonManager_ns::getStringExtent(Font *font, char *text, uint16 maxwidth, int16* width, int16* height) { + uint width() const { return _width; } + uint height() const { return _height; } +}; - uint16 lines = 0; - uint16 w = 0; - *width = 0; - uint16 blankWidth = font->getStringWidth(" "); - uint16 tokenWidth = 0; +class StringWriter_BR : public WrappedLineFormatter { - char token[MAX_TOKEN_LEN]; + uint _width, _height; + byte _color; + uint _x, _y; - while (strlen(text) != 0) { + Graphics::Surface *_surf; - text = parseNextToken(text, token, MAX_TOKEN_LEN, " ", true); - tokenWidth = font->getStringWidth(token); +protected: + StringWriter_BR(Font *font, byte color) : WrappedLineFormatter(font) { - w += tokenWidth; + } - if (!scumm_stricmp(token, "%p")) { - lines++; - } else { - if (w > maxwidth) { - w -= tokenWidth; - lines++; - if (w > *width) - *width = w; + virtual void setup() { + } - w = tokenWidth; - } + virtual void action() { + if (_line.empty()) { + return; } + uint16 rx = _x + (_surf->w - _lineWidth) / 2; + uint16 ry = _y + _lines * _font->height(); // y - w += blankWidth; - text = Common::ltrim(text); + byte *dst = (byte*)_surf->getBasePtr(rx, ry); + _font->setColor(_color); + _font->drawString(dst, _surf->w, _line.c_str()); } - if (*width < w) *width = w; - *width += 10; + virtual void end() { + action(); + } - *height = lines * 10 + 20; +public: + StringWriter_BR(Font *font) : WrappedLineFormatter(font) { } - return; -} + void write(const char *text, uint maxWidth, byte color, Graphics::Surface *surf) { + maxWidth = 216; + + StringExtent_BR se(_font); + se.calc(text, maxWidth); + _width = se.width() + 10; + _height = se.height() + 12; + _color = color; + _surf = surf; + _x = 0; + _y = (_surf->h - _height) / 2; + calc(text, maxWidth); + } + +}; @@ -370,29 +549,12 @@ class BalloonManager_br : public BalloonManager { Frames *_rightBalloon; void cacheAnims(); - void getStringExtent(Font *font, const char *text, uint16 maxwidth, int16* width, int16* height); void drawWrappedText(Font *font, Graphics::Surface* surf, char *text, byte color, int16 wrapwidth); int createBalloon(int16 w, int16 h, int16 winding, uint16 borderThickness); Balloon *getBalloon(uint id); Graphics::Surface *expandBalloon(Frames *data, int frameNum); - void textSetupRendering(const Common::String &text, Graphics::Surface *dest, Font *font, byte color); - void textEmitCenteredLine(); - void textAccum(const Common::String &token, uint16 width); - void textNewLine(); - - Common::String _textLine; - Graphics::Surface *_textSurf; - Font *_textFont; - uint16 _textX, _textY; - byte _textColor; - uint16 _textLines, _textWidth; - - void extentSetup(Font *font, int16 *width, int16 *height); - void extentAction(); - - int16 *_extentWidth, *_extentHeight; - + StringWriter_BR _writer; public: BalloonManager_br(Disk *disk, Gfx *gfx); @@ -451,7 +613,7 @@ int BalloonManager_br::setSingleBalloon(char *text, uint16 x, uint16 y, uint16 w balloon->surface = expandBalloon(src, srcFrame); src->getRect(srcFrame, balloon->box); - drawWrappedText(_vm->_dialogueFont, balloon->surface, text, textColor, MAX_BALLOON_WIDTH); + _writer.write(text, MAX_BALLOON_WIDTH, textColor, balloon->surface); // TODO: extract some text to make a name for obj balloon->obj = _gfx->registerBalloon(new SurfaceToFrames(balloon->surface), 0); @@ -487,7 +649,7 @@ int BalloonManager_br::setDialogueBalloon(char *text, uint16 winding, byte textC balloon->surface = expandBalloon(src, srcFrame); src->getRect(srcFrame, balloon->box); - drawWrappedText(_vm->_dialogueFont, balloon->surface, text, textColor, MAX_BALLOON_WIDTH); + _writer.write(text, MAX_BALLOON_WIDTH, textColor, balloon->surface); // TODO: extract some text to make a name for obj balloon->obj = _gfx->registerBalloon(new SurfaceToFrames(balloon->surface), 0); @@ -558,155 +720,9 @@ void BalloonManager_br::cacheAnims() { } -void BalloonManager_br::extentSetup(Font *font, int16 *width, int16 *height) { - _extentWidth = width; - _extentHeight = height; - - _textLine.clear(); - _textLines = 0; - _textWidth = 0; - _textFont = font; -} - -void BalloonManager_br::extentAction() { - if (_textWidth > *_extentWidth) { - *_extentWidth = _textWidth; - } - *_extentHeight = _textLines * _textFont->height(); -} - -void BalloonManager_br::textSetupRendering(const Common::String &text, Graphics::Surface *dest, Font *font, byte color) { - uint16 maxWidth = 216; - - int16 w, h; - getStringExtent(font, text.c_str(), maxWidth, &w, &h); - - w += 10; - h += 12; - - _textLine.clear(); - _textSurf = dest; - _textFont = font; - _textX = 0; - _textY = (_textSurf->h - h) / 2; - _textColor = color; - _textLines = 0; - _textWidth = 0; -} - -void BalloonManager_br::textEmitCenteredLine() { - if (_textLine.empty()) { - return; - } - uint16 rx = _textX + (_textSurf->w - _textWidth) / 2; - uint16 ry = _textY + _textLines * _textFont->height(); // y - _gfx->drawText(_textFont, _textSurf, rx, ry, _textLine.c_str(), _textColor); -} - -void BalloonManager_br::textAccum(const Common::String &token, uint16 width) { - if (token.empty()) { - return; - } - - _textWidth += width; - _textLine += token; -} - -void BalloonManager_br::textNewLine() { - _textLines++; - _textWidth = 0; - _textLine.clear(); -} - - -// TODO: really, base this and getStringExtent on some kind of LineTokenizer, instead of -// repeating the algorithm and changing a couple of lines. -void BalloonManager_br::drawWrappedText(Font *font, Graphics::Surface* surf, char *text, byte color, int16 wrapWidth) { - textSetupRendering(text, surf, font, color); - - wrapWidth = 216; - - Common::StringTokenizer tokenizer(text, " "); - Common::String token; - Common::String blank(" "); - - uint16 blankWidth = font->getStringWidth(" "); - uint16 tokenWidth = 0; - - while (!tokenizer.empty()) { - token = tokenizer.nextToken(); - - if (token == '/') { - tokenWidth = 0; - textEmitCenteredLine(); - textNewLine(); - } else { - // todo: expand '%' - tokenWidth = font->getStringWidth(token.c_str()); - - if (_textWidth == 0) { - textAccum(token, tokenWidth); - } else { - if (_textWidth + blankWidth + tokenWidth <= wrapWidth) { - textAccum(blank, blankWidth); - textAccum(token, tokenWidth); - } else { - textEmitCenteredLine(); - textNewLine(); - textAccum(token, tokenWidth); - } - } - } - } - - textEmitCenteredLine(); -} - - - -void BalloonManager_br::getStringExtent(Font *font, const char *text, uint16 maxwidth, int16* width, int16* height) { - extentSetup(font, width, height); - - Common::StringTokenizer tokenizer(text, " "); - Common::String token; - Common::String blank(" "); - - uint16 blankWidth = font->getStringWidth(" "); - uint16 tokenWidth = 0; - - while (!tokenizer.empty()) { - token = tokenizer.nextToken(); - - if (token == '/') { - tokenWidth = 0; - extentAction(); - textNewLine(); - } else { - // todo: expand '%' - tokenWidth = font->getStringWidth(token.c_str()); - - if (_textWidth == 0) { - textAccum(token, tokenWidth); - } else { - if (_textWidth + blankWidth + tokenWidth <= maxwidth) { - textAccum(blank, blankWidth); - textAccum(token, tokenWidth); - } else { - extentAction(); - textNewLine(); - textAccum(token, tokenWidth); - } - } - } - } - - extentAction(); -} - - - -BalloonManager_br::BalloonManager_br(Disk *disk, Gfx *gfx) : _numBalloons(0), _disk(disk), _gfx(gfx), _leftBalloon(0), _rightBalloon(0) { +BalloonManager_br::BalloonManager_br(Disk *disk, Gfx *gfx) : _numBalloons(0), _disk(disk), _gfx(gfx), + _leftBalloon(0), _rightBalloon(0), _writer(_vm->_dialogueFont) { } BalloonManager_br::~BalloonManager_br() { -- cgit v1.2.3 From 5cfa50f02839dd34a3f600f36000b989c614c5b2 Mon Sep 17 00:00:00 2001 From: Nicola Mettifogo Date: Thu, 14 Aug 2008 07:14:34 +0000 Subject: Finally moved parseNextToken to Script, where it belongs! svn-id: r33859 --- engines/parallaction/parser.cpp | 2 +- engines/parallaction/parser.h | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) (limited to 'engines') diff --git a/engines/parallaction/parser.cpp b/engines/parallaction/parser.cpp index 97caa9dc6c..8e30a631e4 100644 --- a/engines/parallaction/parser.cpp +++ b/engines/parallaction/parser.cpp @@ -93,7 +93,7 @@ void Script::skip(const char* endToken) { // // The routine returns the unparsed portion of the input string 's'. // -char *parseNextToken(char *s, char *tok, uint16 count, const char *brk, bool ignoreQuotes) { +char *Script::parseNextToken(char *s, char *tok, uint16 count, const char *brk, bool ignoreQuotes) { enum STATES { NORMAL, QUOTED }; diff --git a/engines/parallaction/parser.h b/engines/parallaction/parser.h index 7e7937fb19..5a01282e37 100644 --- a/engines/parallaction/parser.h +++ b/engines/parallaction/parser.h @@ -32,8 +32,6 @@ namespace Parallaction { -char *parseNextToken(char *s, char *tok, uint16 count, const char *brk, bool ignoreQuotes = false); - #define MAX_TOKEN_LEN 50 extern int _numTokens; extern char _tokens[][MAX_TOKEN_LEN]; @@ -46,6 +44,7 @@ class Script { void clearTokens(); uint16 fillTokens(char* line); + char *parseNextToken(char *s, char *tok, uint16 count, const char *brk, bool ignoreQuotes = false); public: Script(Common::ReadStream *, bool _disposeSource = false); -- cgit v1.2.3 From 4447be7102ec0689ed5a27f14a61a51532848dfe Mon Sep 17 00:00:00 2001 From: Nicola Mettifogo Date: Thu, 14 Aug 2008 10:04:43 +0000 Subject: Cleanup. svn-id: r33860 --- engines/parallaction/exec.h | 2 -- engines/parallaction/exec_br.cpp | 46 ++++--------------------------------- engines/parallaction/exec_ns.cpp | 30 +++++++++++------------- engines/parallaction/parallaction.h | 2 ++ 4 files changed, 19 insertions(+), 61 deletions(-) (limited to 'engines') diff --git a/engines/parallaction/exec.h b/engines/parallaction/exec.h index 22e75744f1..4239857ec0 100644 --- a/engines/parallaction/exec.h +++ b/engines/parallaction/exec.h @@ -84,8 +84,6 @@ class CommandExec_ns : public CommandExec { Parallaction_ns *_vm; protected: - void updateGetZone(ZonePtr z, bool visible); - DECLARE_UNQUALIFIED_COMMAND_OPCODE(invalid); DECLARE_UNQUALIFIED_COMMAND_OPCODE(set); DECLARE_UNQUALIFIED_COMMAND_OPCODE(clear); diff --git a/engines/parallaction/exec_br.cpp b/engines/parallaction/exec_br.cpp index 0b7400f0f7..cb123dc19a 100644 --- a/engines/parallaction/exec_br.cpp +++ b/engines/parallaction/exec_br.cpp @@ -139,31 +139,12 @@ DECLARE_COMMAND_OPCODE(close) { DECLARE_COMMAND_OPCODE(on) { - CommandData *data = &_ctxt.cmd->u; - ZonePtr z = data->_zone; - - if (z) { - z->_flags |= kFlagsActive; - z->_flags &= ~kFlagsRemove; - - if ((z->_type & 0xFFFF) & kZoneGet) { - _vm->_gfx->showGfxObj(z->u.get->gfxobj, true); - } - } + _vm->showZone(_ctxt.cmd->u._zone, true); } DECLARE_COMMAND_OPCODE(off) { - CommandData *data = &_ctxt.cmd->u; - ZonePtr z = data->_zone; - - if (z) { - z->_flags |= kFlagsRemove; - - if ((z->_type & 0xFFFF) & kZoneGet) { - _vm->_gfx->showGfxObj(z->u.get->gfxobj, false); - } - } + _vm->showZone(_ctxt.cmd->u._zone, false); } @@ -335,31 +316,12 @@ DECLARE_COMMAND_OPCODE(offsave) { DECLARE_INSTRUCTION_OPCODE(on) { - InstructionPtr inst = *_ctxt.inst; - ZonePtr z = inst->_z; - - if (z) { - z->_flags |= kFlagsActive; - z->_flags &= ~kFlagsRemove; - - if ((z->_type & 0xFFFF) & kZoneGet) { - _vm->_gfx->showGfxObj(z->u.get->gfxobj, true); - } - } + _vm->showZone((*_ctxt.inst)->_z, true); } DECLARE_INSTRUCTION_OPCODE(off) { - InstructionPtr inst = *_ctxt.inst; - ZonePtr z = inst->_z; - - if (z) { - z->_flags |= kFlagsRemove; - - if ((z->_type & 0xFFFF) & kZoneGet) { - _vm->_gfx->showGfxObj(z->u.get->gfxobj, false); - } - } + _vm->showZone((*_ctxt.inst)->_z, false); } diff --git a/engines/parallaction/exec_ns.cpp b/engines/parallaction/exec_ns.cpp index 99a492863b..bad0b34327 100644 --- a/engines/parallaction/exec_ns.cpp +++ b/engines/parallaction/exec_ns.cpp @@ -260,34 +260,31 @@ DECLARE_COMMAND_OPCODE(close) { } } -void CommandExec_ns::updateGetZone(ZonePtr z, bool visible) { +void Parallaction::showZone(ZonePtr z, bool visible) { if (!z) { return; } + if (visible) { + z->_flags &= ~kFlagsRemove; + z->_flags |= kFlagsActive; + } else { + z->_flags |= kFlagsRemove; + } + if ((z->_type & 0xFFFF) == kZoneGet) { - _vm->_gfx->showGfxObj(z->u.get->gfxobj, visible); + _gfx->showGfxObj(z->u.get->gfxobj, visible); } + } DECLARE_COMMAND_OPCODE(on) { - ZonePtr z = _ctxt.cmd->u._zone; - - if (z) { - z->_flags &= ~kFlagsRemove; - z->_flags |= kFlagsActive; - updateGetZone(z, true); - } + _vm->showZone(_ctxt.cmd->u._zone, true); } DECLARE_COMMAND_OPCODE(off) { - ZonePtr z = _ctxt.cmd->u._zone; - - if (z) { - _ctxt.cmd->u._zone->_flags |= kFlagsRemove; - updateGetZone(z, false); - } + _vm->showZone(_ctxt.cmd->u._zone, false); } @@ -618,7 +615,6 @@ uint16 Parallaction::runZone(ZonePtr z) { if (pickupItem(z) != 0) { return 1; } - z->_flags |= kFlagsRemove; break; case kZoneDoor: @@ -666,7 +662,7 @@ void Parallaction::updateDoor(ZonePtr z) { int16 Parallaction::pickupItem(ZonePtr z) { int r = addInventoryItem(z->u.get->_icon); if (r != -1) { - _gfx->showGfxObj(z->u.get->gfxobj, false); + showZone(z, false); } return (r == -1); diff --git a/engines/parallaction/parallaction.h b/engines/parallaction/parallaction.h index e5c5221414..661cf169d3 100644 --- a/engines/parallaction/parallaction.h +++ b/engines/parallaction/parallaction.h @@ -424,6 +424,8 @@ public: void setInternLanguage(uint id); uint getInternLanguage(); + + void showZone(ZonePtr z, bool visible); }; -- cgit v1.2.3 From 15f4bc43cf03b7e1f69b883ea5c5f2d17d2798ef Mon Sep 17 00:00:00 2001 From: Nicola Mettifogo Date: Thu, 14 Aug 2008 10:24:39 +0000 Subject: More cleanup. svn-id: r33861 --- engines/parallaction/exec_br.cpp | 10 ++------- engines/parallaction/exec_ns.cpp | 43 ++++++++++++++++--------------------- engines/parallaction/parallaction.h | 6 +++--- 3 files changed, 24 insertions(+), 35 deletions(-) (limited to 'engines') diff --git a/engines/parallaction/exec_br.cpp b/engines/parallaction/exec_br.cpp index cb123dc19a..5c718bf61a 100644 --- a/engines/parallaction/exec_br.cpp +++ b/engines/parallaction/exec_br.cpp @@ -122,19 +122,13 @@ DECLARE_COMMAND_OPCODE(location) { DECLARE_COMMAND_OPCODE(open) { warning("Parallaction_br::cmdOp_open command not yet implemented"); - _ctxt.cmd->u._zone->_flags &= ~kFlagsClosed; - if (_ctxt.cmd->u._zone->u.door->gfxobj) { - _vm->updateDoor(_ctxt.cmd->u._zone); - } + _vm->updateDoor(_ctxt.cmd->u._zone, false); } DECLARE_COMMAND_OPCODE(close) { warning("Parallaction_br::cmdOp_close not yet implemented"); - _ctxt.cmd->u._zone->_flags |= kFlagsClosed; - if (_ctxt.cmd->u._zone->u.door->gfxobj) { - _vm->updateDoor(_ctxt.cmd->u._zone); - } + _vm->updateDoor(_ctxt.cmd->u._zone, true); } diff --git a/engines/parallaction/exec_ns.cpp b/engines/parallaction/exec_ns.cpp index bad0b34327..12ee68a3ed 100644 --- a/engines/parallaction/exec_ns.cpp +++ b/engines/parallaction/exec_ns.cpp @@ -246,18 +246,12 @@ DECLARE_COMMAND_OPCODE(location) { DECLARE_COMMAND_OPCODE(open) { - _ctxt.cmd->u._zone->_flags &= ~kFlagsClosed; - if (_ctxt.cmd->u._zone->u.door->gfxobj) { - _vm->updateDoor(_ctxt.cmd->u._zone); - } + _vm->updateDoor(_ctxt.cmd->u._zone, false); } DECLARE_COMMAND_OPCODE(close) { - _ctxt.cmd->u._zone->_flags |= kFlagsClosed; - if (_ctxt.cmd->u._zone->u.door->gfxobj) { - _vm->updateDoor(_ctxt.cmd->u._zone); - } + _vm->updateDoor(_ctxt.cmd->u._zone, true); } void Parallaction::showZone(ZonePtr z, bool visible) { @@ -598,7 +592,7 @@ void Parallaction::runCommentFrame() { } -uint16 Parallaction::runZone(ZonePtr z) { +void Parallaction::runZone(ZonePtr z) { debugC(3, kDebugExec, "runZone (%s)", z->_name); uint16 subtype = z->_type & 0xFFFF; @@ -608,19 +602,15 @@ uint16 Parallaction::runZone(ZonePtr z) { case kZoneExamine: enterCommentMode(z); - return 0; + return; case kZoneGet: - if (z->_flags & kFlagsFixed) break; - if (pickupItem(z) != 0) { - return 1; - } + pickupItem(z); break; case kZoneDoor: if (z->_flags & kFlagsLocked) break; - z->_flags ^= kFlagsClosed; - updateDoor(z); + updateDoor(z, !(z->_flags & kFlagsClosed)); break; case kZoneHear: @@ -629,23 +619,24 @@ uint16 Parallaction::runZone(ZonePtr z) { case kZoneSpeak: enterDialogueMode(z); - return 0; + return; } debugC(3, kDebugExec, "runZone completed"); _cmdExec->run(z->_commands, z); - return 0; + return; } // // ZONE TYPE: DOOR // -void Parallaction::updateDoor(ZonePtr z) { +void Parallaction::updateDoor(ZonePtr z, bool close) { + z->_flags = close ? (z->_flags |= kFlagsClosed) : (z->_flags &= ~kFlagsClosed); if (z->u.door->gfxobj) { - uint frame = (z->_flags & kFlagsClosed ? 0 : 1); + uint frame = (close ? 0 : 1); // z->u.door->gfxobj->setFrame(frame); z->u.door->gfxobj->frame = frame; } @@ -659,13 +650,17 @@ void Parallaction::updateDoor(ZonePtr z) { // ZONE TYPE: GET // -int16 Parallaction::pickupItem(ZonePtr z) { - int r = addInventoryItem(z->u.get->_icon); - if (r != -1) { +bool Parallaction::pickupItem(ZonePtr z) { + if (z->_flags & kFlagsFixed) { + return false; + } + + int slot = addInventoryItem(z->u.get->_icon); + if (slot != -1) { showZone(z, false); } - return (r == -1); + return (slot != -1); } diff --git a/engines/parallaction/parallaction.h b/engines/parallaction/parallaction.h index 661cf169d3..98d91ed16a 100644 --- a/engines/parallaction/parallaction.h +++ b/engines/parallaction/parallaction.h @@ -263,7 +263,7 @@ public: ZonePtr findZone(const char *name); ZonePtr hitZone(uint32 type, uint16 x, uint16 y); - uint16 runZone(ZonePtr z); + void runZone(ZonePtr z); void freeZones(); AnimationPtr findAnimation(const char *name); @@ -354,7 +354,7 @@ protected: // members void freeCharacter(); - int16 pickupItem(ZonePtr z); + bool pickupItem(ZonePtr z); void clearSet(OpcodeSet &opcodes); @@ -370,7 +370,7 @@ public: virtual void parseLocation(const char* name) = 0; - void updateDoor(ZonePtr z); + void updateDoor(ZonePtr z, bool close); virtual void drawAnimations() = 0; -- cgit v1.2.3 From d3440f2cc5f7cb6e617d8e04047808ba38c8b7d6 Mon Sep 17 00:00:00 2001 From: Nicola Mettifogo Date: Thu, 14 Aug 2008 13:45:32 +0000 Subject: Some variable renamed to make more sense. svn-id: r33864 --- engines/parallaction/callables_ns.cpp | 2 +- engines/parallaction/debug.cpp | 6 +++--- engines/parallaction/dialogue.cpp | 2 +- engines/parallaction/exec_ns.cpp | 10 +++++----- engines/parallaction/parallaction.cpp | 6 +++--- engines/parallaction/parallaction.h | 4 ++-- engines/parallaction/parallaction_br.cpp | 6 +++--- engines/parallaction/parallaction_ns.cpp | 4 ++-- engines/parallaction/parser_ns.cpp | 10 +++++----- engines/parallaction/saveload.cpp | 4 ++-- 10 files changed, 27 insertions(+), 27 deletions(-) (limited to 'engines') diff --git a/engines/parallaction/callables_ns.cpp b/engines/parallaction/callables_ns.cpp index 761e11dc7d..7e9395ef1f 100644 --- a/engines/parallaction/callables_ns.cpp +++ b/engines/parallaction/callables_ns.cpp @@ -261,7 +261,7 @@ void Parallaction_ns::_c_contaFoglie(void *parm) { if (num_foglie != 6) return; - _commandFlags |= 0x1000; + _globalFlags |= 0x1000; return; } diff --git a/engines/parallaction/debug.cpp b/engines/parallaction/debug.cpp index f57976594e..625c28dd5f 100644 --- a/engines/parallaction/debug.cpp +++ b/engines/parallaction/debug.cpp @@ -101,14 +101,14 @@ bool Debugger::Cmd_Locations(int argc, const char **argv) { bool Debugger::Cmd_GlobalFlags(int argc, const char **argv) { - uint32 flags = _commandFlags; + uint32 flags = _globalFlags; DebugPrintf("+------------------------------+---------+\n" "| flag name | value |\n" "+------------------------------+---------+\n"); - for (uint i = 0; i < _vm->_globalTable->count(); i++) { + for (uint i = 0; i < _vm->_globalFlagsNames->count(); i++) { const char *value = ((flags & (1 << i)) == 0) ? "OFF" : "ON"; - DebugPrintf("|%-30s| %-6s|\n", _vm->_globalTable->item(i), value); + DebugPrintf("|%-30s| %-6s|\n", _vm->_globalFlagsNames->item(i), value); } DebugPrintf("+------------------------------+---------+\n"); diff --git a/engines/parallaction/dialogue.cpp b/engines/parallaction/dialogue.cpp index 21584a0525..205d702aa0 100644 --- a/engines/parallaction/dialogue.cpp +++ b/engines/parallaction/dialogue.cpp @@ -168,7 +168,7 @@ bool DialogueManager::displayAnswer(uint16 i) { uint32 flags = _vm->getLocationFlags(); if (a->_yesFlags & kFlagsGlobal) - flags = _commandFlags | kFlagsGlobal; + flags = _globalFlags | kFlagsGlobal; // display suitable answers if (((a->_yesFlags & flags) == a->_yesFlags) && ((a->_noFlags & ~flags) == a->_noFlags)) { diff --git a/engines/parallaction/exec_ns.cpp b/engines/parallaction/exec_ns.cpp index 12ee68a3ed..bd05c169e7 100644 --- a/engines/parallaction/exec_ns.cpp +++ b/engines/parallaction/exec_ns.cpp @@ -203,7 +203,7 @@ DECLARE_COMMAND_OPCODE(invalid) { DECLARE_COMMAND_OPCODE(set) { if (_ctxt.cmd->u._flags & kFlagsGlobal) { _ctxt.cmd->u._flags &= ~kFlagsGlobal; - _commandFlags |= _ctxt.cmd->u._flags; + _globalFlags |= _ctxt.cmd->u._flags; } else { _vm->setLocationFlags(_ctxt.cmd->u._flags); } @@ -213,7 +213,7 @@ DECLARE_COMMAND_OPCODE(set) { DECLARE_COMMAND_OPCODE(clear) { if (_ctxt.cmd->u._flags & kFlagsGlobal) { _ctxt.cmd->u._flags &= ~kFlagsGlobal; - _commandFlags &= ~_ctxt.cmd->u._flags; + _globalFlags &= ~_ctxt.cmd->u._flags; } else { _vm->clearLocationFlags(_ctxt.cmd->u._flags); } @@ -290,7 +290,7 @@ DECLARE_COMMAND_OPCODE(call) { DECLARE_COMMAND_OPCODE(toggle) { if (_ctxt.cmd->u._flags & kFlagsGlobal) { _ctxt.cmd->u._flags &= ~kFlagsGlobal; - _commandFlags ^= _ctxt.cmd->u._flags; + _globalFlags ^= _ctxt.cmd->u._flags; } else { _vm->toggleLocationFlags(_ctxt.cmd->u._flags); } @@ -336,7 +336,7 @@ void Parallaction_ns::drawAnimations() { if ((anim->_flags & kFlagsActive) && ((anim->_flags & kFlagsRemove) == 0)) { if (anim->_flags & kFlagsNoMasked) - layer = 3; + layer = LAYER_FOREGROUND; else layer = _gfx->_backgroundInfo->getLayer(anim->_top + anim->height()); @@ -439,7 +439,7 @@ void CommandExec::runList(CommandList::iterator first, CommandList::iterator las CommandPtr cmd = *first; if (cmd->_flagsOn & kFlagsGlobal) { - useFlags = _commandFlags | kFlagsGlobal; + useFlags = _globalFlags | kFlagsGlobal; useLocalFlags = false; } else { useFlags = _vm->getLocationFlags(); diff --git a/engines/parallaction/parallaction.cpp b/engines/parallaction/parallaction.cpp index bb306c3299..dca3d04157 100644 --- a/engines/parallaction/parallaction.cpp +++ b/engines/parallaction/parallaction.cpp @@ -53,7 +53,7 @@ uint32 _engineFlags = 0; uint16 _score = 1; char _password[8]; -uint32 _commandFlags = 0; +uint32 _globalFlags = 0; // private stuff @@ -85,7 +85,7 @@ Parallaction::Parallaction(OSystem *syst, const PARALLACTIONGameDescription *gam Parallaction::~Parallaction() { delete _debugger; - delete _globalTable; + delete _globalFlagsNames; delete _callableNames; delete _cmdExec; delete _programExec; @@ -114,7 +114,7 @@ int Parallaction::init() { _engineFlags = 0; _objectsNames = NULL; - _globalTable = NULL; + _globalFlagsNames = NULL; _location._hasSound = false; _baseTime = 0; _numLocations = 0; diff --git a/engines/parallaction/parallaction.h b/engines/parallaction/parallaction.h index 98d91ed16a..06adf8fa16 100644 --- a/engines/parallaction/parallaction.h +++ b/engines/parallaction/parallaction.h @@ -136,7 +136,7 @@ extern uint16 _score; extern uint16 _language; extern uint32 _engineFlags; extern char _saveData1[]; -extern uint32 _commandFlags; +extern uint32 _globalFlags; extern const char *_dinoName; extern const char *_donnaName; extern const char *_doughName; @@ -272,7 +272,7 @@ public: void setBackground(const char *background, const char *mask, const char *path); void freeBackground(); - Table *_globalTable; + Table *_globalFlagsNames; Table *_objectsNames; Table *_callableNames; Table *_localFlagNames; diff --git a/engines/parallaction/parallaction_br.cpp b/engines/parallaction/parallaction_br.cpp index 761c8d1b74..bb8ddc5654 100644 --- a/engines/parallaction/parallaction_br.cpp +++ b/engines/parallaction/parallaction_br.cpp @@ -193,7 +193,7 @@ void Parallaction_br::initPart() { memset(_counters, 0, ARRAYSIZE(_counters)); - _globalTable = _disk->loadTable("global"); + _globalFlagsNames = _disk->loadTable("global"); _objectsNames = _disk->loadTable("objects"); _countersNames = _disk->loadTable("counters"); @@ -208,11 +208,11 @@ void Parallaction_br::initPart() { void Parallaction_br::freePart() { - delete _globalTable; + delete _globalFlagsNames; delete _objectsNames; delete _countersNames; - _globalTable = 0; + _globalFlagsNames = 0; _objectsNames = 0; _countersNames = 0; } diff --git a/engines/parallaction/parallaction_ns.cpp b/engines/parallaction/parallaction_ns.cpp index e81492e655..bfbe7c3eb3 100644 --- a/engines/parallaction/parallaction_ns.cpp +++ b/engines/parallaction/parallaction_ns.cpp @@ -218,7 +218,7 @@ void Parallaction_ns::callFunction(uint index, void* parm) { int Parallaction_ns::go() { renameOldSavefiles(); - _globalTable = _disk->loadTable("global"); + _globalFlagsNames = _disk->loadTable("global"); startGui(); @@ -438,7 +438,7 @@ void Parallaction_ns::cleanupGame() { // this code saves main character animation from being removed from the following code _location._animations.remove(_char._ani); _numLocations = 0; - _commandFlags = 0; + _globalFlags = 0; memset(_localFlags, 0, sizeof(_localFlags)); memset(_locationNames, 0, sizeof(_locationNames)); diff --git a/engines/parallaction/parser_ns.cpp b/engines/parallaction/parser_ns.cpp index ad0f714fdc..dd4a79a8d2 100644 --- a/engines/parallaction/parser_ns.cpp +++ b/engines/parallaction/parser_ns.cpp @@ -608,7 +608,7 @@ DECLARE_COMMAND_PARSER(flags) { createCommand(_parser->_lookup); - if (_vm->_globalTable->lookup(_tokens[1]) == Table::notFound) { + if (_vm->_globalFlagsNames->lookup(_tokens[1]) == Table::notFound) { do { char _al = _vm->_localFlagNames->lookup(_tokens[ctxt.nextToken]); ctxt.nextToken++; @@ -618,7 +618,7 @@ DECLARE_COMMAND_PARSER(flags) { } else { ctxt.cmd->u._flags |= kFlagsGlobal; do { - char _al = _vm->_globalTable->lookup(_tokens[1]); + char _al = _vm->_globalFlagsNames->lookup(_tokens[1]); ctxt.nextToken++; ctxt.cmd->u._flags |= 1 << (_al - 1); } while (!scumm_stricmp(_tokens[ctxt.nextToken++], "|")); @@ -759,11 +759,11 @@ void LocationParser_ns::parseCommandFlags() { cmd->_flagsOn |= kFlagsEnter; } else if (!scumm_strnicmp(_tokens[_si], "no", 2)) { - byte _al = _vm->_globalTable->lookup(&_tokens[_si][2]); + byte _al = _vm->_globalFlagsNames->lookup(&_tokens[_si][2]); assert(_al != Table::notFound); cmd->_flagsOff |= 1 << (_al - 1); } else { - byte _al = _vm->_globalTable->lookup(_tokens[_si]); + byte _al = _vm->_globalFlagsNames->lookup(_tokens[_si]); assert(_al != Table::notFound); cmd->_flagsOn |= 1 << (_al - 1); } @@ -880,7 +880,7 @@ Answer *LocationParser_ns::parseAnswer() { if (!scumm_stricmp(_tokens[1], "global")) { token = 2; - flagNames = _vm->_globalTable; + flagNames = _vm->_globalFlagsNames; answer->_yesFlags |= kFlagsGlobal; } else { token = 1; diff --git a/engines/parallaction/saveload.cpp b/engines/parallaction/saveload.cpp index 002295315d..c07d976a3c 100644 --- a/engines/parallaction/saveload.cpp +++ b/engines/parallaction/saveload.cpp @@ -125,7 +125,7 @@ void Parallaction_ns::doLoadGame(uint16 slot) { _score = atoi(s); f->readLine(s, 15); - _commandFlags = atoi(s); + _globalFlags = atoi(s); f->readLine(s, 15); @@ -213,7 +213,7 @@ void Parallaction_ns::doSaveGame(uint16 slot, const char* name) { f->writeString(s); sprintf(s, "%d\n", _score); f->writeString(s); - sprintf(s, "%u\n", _commandFlags); + sprintf(s, "%u\n", _globalFlags); f->writeString(s); sprintf(s, "%d\n", _numLocations); -- cgit v1.2.3 From 63f31692133a085f9aaf9a0635afaa0cc62870d6 Mon Sep 17 00:00:00 2001 From: Kari Salminen Date: Thu, 14 Aug 2008 20:18:13 +0000 Subject: Added debug showing of the collision page when pressing the Alt key. Alt isn't used for anything else so one might as well use it for this. svn-id: r33871 --- engines/cine/gfx.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'engines') diff --git a/engines/cine/gfx.cpp b/engines/cine/gfx.cpp index 3198427117..b8b3bf38dd 100644 --- a/engines/cine/gfx.cpp +++ b/engines/cine/gfx.cpp @@ -31,6 +31,7 @@ #include "common/endian.h" #include "common/system.h" +#include "common/events.h" #include "graphics/cursorman.h" @@ -514,7 +515,13 @@ void FWRenderer::drawFrame() { /*! \brief Update screen */ void FWRenderer::blit() { - g_system->copyRectToScreen(_backBuffer, 320, 0, 0, 320, 200); + if (g_system->getEventManager()->getModifierState() & Common::KBD_ALT) { + // Show collision page if the Alt key is being pressed + g_system->copyRectToScreen(collisionPage, 320, 0, 0, 320, 200); + } else { + // Normally show the back buffer + g_system->copyRectToScreen(_backBuffer, 320, 0, 0, 320, 200); + } } /*! \brief Set player command string -- cgit v1.2.3 From c2c2e940d0fc3960529e757195190568adb34580 Mon Sep 17 00:00:00 2001 From: Kari Salminen Date: Thu, 14 Aug 2008 20:49:34 +0000 Subject: Fix for bugging moving at the bottom of the ocean when trying to free the girl from the ropes and swimming to the surface. Some global variables related to mouse position weren't being updated in executePlayerInput, now they are and things seem to work. Also enables moving in the labyrinth arcade sequence at the palace. svn-id: r33872 --- engines/cine/various.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'engines') diff --git a/engines/cine/various.cpp b/engines/cine/various.cpp index a3359287ce..e96e03b03c 100644 --- a/engines/cine/various.cpp +++ b/engines/cine/various.cpp @@ -2033,6 +2033,14 @@ uint16 executePlayerInput(void) { } } + // Update Operation Stealth specific global variables. + // This fixes swimming at the bottom of the ocean after + // having been thrown into it with the girl. + if (g_cine->getGameType() == Cine::GType_OS) { + globalVars[251] = globalVars[VAR_MOUSE_X_POS]; + globalVars[252] = globalVars[VAR_MOUSE_Y_POS]; + } + return var_5E; } -- cgit v1.2.3 From 8fe533657c4387ffcd0212c7e36aacc4b790cb80 Mon Sep 17 00:00:00 2001 From: Florian Kagerer Date: Thu, 14 Aug 2008 21:21:04 +0000 Subject: - HOF: another Italian fan translation svn-id: r33873 --- engines/kyra/detection.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'engines') diff --git a/engines/kyra/detection.cpp b/engines/kyra/detection.cpp index 0ae289e09d..08c362404a 100644 --- a/engines/kyra/detection.cpp +++ b/engines/kyra/detection.cpp @@ -466,6 +466,18 @@ const KYRAGameDescription adGameDescs[] = { KYRA2_CD_FAN_FLAGS(Common::IT_ITA, Common::EN_ANY) }, + { + { + "kyra2", + "CD", + AD_ENTRY1("FATE.PAK", "39772ff82e42c4c520050518deb82e64"), + Common::IT_ITA, + Common::kPlatformPC, + Common::ADGF_DROPLANGUAGE | Common::ADGF_CD + }, + KYRA2_CD_FAN_FLAGS(Common::IT_ITA, Common::EN_ANY) + }, + { // Interactive Demo { "kyra2", -- cgit v1.2.3 From 3f316681a00108d668867261a93e9ae789aa058f Mon Sep 17 00:00:00 2001 From: Florian Kagerer Date: Thu, 14 Aug 2008 21:34:29 +0000 Subject: - HOF: forgot french and german entries in last commit svn-id: r33875 --- engines/kyra/detection.cpp | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'engines') diff --git a/engines/kyra/detection.cpp b/engines/kyra/detection.cpp index 08c362404a..f8fd0d6308 100644 --- a/engines/kyra/detection.cpp +++ b/engines/kyra/detection.cpp @@ -478,6 +478,30 @@ const KYRAGameDescription adGameDescs[] = { KYRA2_CD_FAN_FLAGS(Common::IT_ITA, Common::EN_ANY) }, + { + { + "kyra2", + "CD", + AD_ENTRY1("FATE.PAK", "39772ff82e42c4c520050518deb82e64"), + Common::DE_DEU, + Common::kPlatformPC, + Common::ADGF_DROPLANGUAGE | Common::ADGF_CD + }, + KYRA2_CD_FAN_FLAGS(Common::IT_ITA, Common::EN_ANY) + }, + + { + { + "kyra2", + "CD", + AD_ENTRY1("FATE.PAK", "39772ff82e42c4c520050518deb82e64"), + Common::FR_FRA, + Common::kPlatformPC, + Common::ADGF_DROPLANGUAGE | Common::ADGF_CD + }, + KYRA2_CD_FAN_FLAGS(Common::IT_ITA, Common::EN_ANY) + }, + { // Interactive Demo { "kyra2", -- cgit v1.2.3 From e56359eac0d994c18e79a8a3a19acfcbedc0e0fb Mon Sep 17 00:00:00 2001 From: Kari Salminen Date: Thu, 14 Aug 2008 22:01:56 +0000 Subject: Moved showing of the collision page from Alt-key to F11-key because Alt conflicted with taking screenshots using Alt-s. Great. Hopefully F11 doesn't conflict with anything useful. svn-id: r33877 --- engines/cine/gfx.cpp | 23 +++++++++++++++-------- engines/cine/gfx.h | 2 ++ engines/cine/main_loop.cpp | 6 ++++++ 3 files changed, 23 insertions(+), 8 deletions(-) (limited to 'engines') diff --git a/engines/cine/gfx.cpp b/engines/cine/gfx.cpp index b8b3bf38dd..cb900e8850 100644 --- a/engines/cine/gfx.cpp +++ b/engines/cine/gfx.cpp @@ -92,7 +92,7 @@ static const byte cursorPalette[] = { */ FWRenderer::FWRenderer() : _background(NULL), _palette(NULL), _cmd(""), _cmdY(0), _messageBg(0), _backBuffer(new byte[_screenSize]), - _activeLowPal(NULL), _changePal(0) { + _activeLowPal(NULL), _changePal(0), _showCollisionPage(false) { assert(_backBuffer); @@ -126,6 +126,7 @@ void FWRenderer::clear() { _cmdY = 0; _messageBg = 0; _changePal = 0; + _showCollisionPage = false; } /*! \brief Draw 1bpp sprite using selected color @@ -512,16 +513,22 @@ void FWRenderer::drawFrame() { blit(); } +/*! + * \brief Turn on or off the showing of the collision page. + * If turned on the blitting routine shows the collision page instead of the back buffer. + * \note Useful for debugging collision page related problems. + */ +void FWRenderer::showCollisionPage(bool state) { + _showCollisionPage = state; +} + /*! \brief Update screen */ void FWRenderer::blit() { - if (g_system->getEventManager()->getModifierState() & Common::KBD_ALT) { - // Show collision page if the Alt key is being pressed - g_system->copyRectToScreen(collisionPage, 320, 0, 0, 320, 200); - } else { - // Normally show the back buffer - g_system->copyRectToScreen(_backBuffer, 320, 0, 0, 320, 200); - } + // Show the back buffer or the collision page. Normally the back + // buffer but showing the collision page is useful for debugging. + byte *source = (_showCollisionPage ? collisionPage : _backBuffer); + g_system->copyRectToScreen(source, 320, 0, 0, 320, 200); } /*! \brief Set player command string diff --git a/engines/cine/gfx.h b/engines/cine/gfx.h index ccd955db8f..c07214028c 100644 --- a/engines/cine/gfx.h +++ b/engines/cine/gfx.h @@ -62,6 +62,7 @@ protected: byte *_backBuffer; ///< Screen backbuffer uint16 *_activeLowPal; ///< Active 16 color palette int _changePal; ///< Load active palette to video backend on next frame + bool _showCollisionPage; ///< Should we show the collision page instead of the back buffer? Used for debugging. void fillSprite(const objectStruct &obj, uint8 color = 0); void drawMaskedSprite(const objectStruct &obj, const byte *mask); @@ -124,6 +125,7 @@ public: void drawInputBox(const char *info, const char *input, int cursor, int x, int y, int width); virtual void fadeToBlack(); + void showCollisionPage(bool state); }; /*! \brief Operation Stealth renderer diff --git a/engines/cine/main_loop.cpp b/engines/cine/main_loop.cpp index 17240f9ef8..e2402a4c8d 100644 --- a/engines/cine/main_loop.cpp +++ b/engines/cine/main_loop.cpp @@ -125,6 +125,9 @@ static void processEvent(Common::Event &event) { g_cine->makeSystemMenu(); } break; + case Common::KEYCODE_F11: + renderer->showCollisionPage(true); + break; case Common::KEYCODE_MINUS: case Common::KEYCODE_KP_MINUS: g_cine->modifyGameSpeed(-1); // Slower @@ -168,6 +171,9 @@ static void processEvent(Common::Event &event) { break; case Common::EVENT_KEYUP: switch (event.kbd.keycode) { + case Common::KEYCODE_F11: + renderer->showCollisionPage(false); + break; case Common::KEYCODE_KP5: // Emulated left mouse button click case Common::KEYCODE_LEFT: // Left case Common::KEYCODE_KP4: // Left -- cgit v1.2.3 From 027e6c51a8279a7e4e2a66ddb40cf6bfc31af3c6 Mon Sep 17 00:00:00 2001 From: Johannes Schickel Date: Thu, 14 Aug 2008 22:09:36 +0000 Subject: Improved version of my resource loading patch from -devel (check also r33876). svn-id: r33878 --- engines/kyra/resource.cpp | 71 ++++++++++++++++++++++++----------------------- 1 file changed, 37 insertions(+), 34 deletions(-) (limited to 'engines') diff --git a/engines/kyra/resource.cpp b/engines/kyra/resource.cpp index d3b66ba6c6..0ce364500d 100644 --- a/engines/kyra/resource.cpp +++ b/engines/kyra/resource.cpp @@ -184,8 +184,14 @@ bool Resource::loadPakFile(const Common::String &filename) { for (ResArchiveLoader::FileList::iterator i = files.begin(); i != files.end(); ++i) { iter = _map.find(i->filename); if (iter == _map.end()) { + // We do an internal check for a file in gamepath with same filename to + // allow overwriting files inside archives with plain files inside the + // game directory + checkFile(i->filename); + // A new file entry, so we just insert it into the file map. - _map[i->filename] = i->entry; + if (_map.find(i->filename) == _map.end()) + _map[i->filename] = i->entry; } else if (!iter->_value.parent.empty()) { if (!iter->_value.parent.equalsIgnoreCase(filename)) { ResFileMap::iterator oldParent = _map.find(iter->_value.parent); @@ -353,7 +359,17 @@ bool Resource::loadFileToBuf(const char *file, void *buf, uint32 maxSize) { Common::SeekableReadStream *Resource::getFileStream(const Common::String &file) { CompFileMap::iterator compEntry; - if (Common::File::exists(file)) { + if ((compEntry = _compFiles.find(file)) != _compFiles.end()) + return new Common::MemoryReadStream(compEntry->_value.data, compEntry->_value.size, false); + + if (!isAccessable(file)) + return 0; + + ResFileMap::const_iterator iter = _map.find(file); + if (iter == _map.end()) + return 0; + + if (iter->_value.parent.empty()) { Common::File *stream = new Common::File(); if (!stream->open(file)) { delete stream; @@ -361,28 +377,15 @@ Common::SeekableReadStream *Resource::getFileStream(const Common::String &file) error("Couldn't open file '%s'", file.c_str()); } return stream; - } else if ((compEntry = _compFiles.find(file)) != _compFiles.end()) { - return new Common::MemoryReadStream(compEntry->_value.data, compEntry->_value.size, false); } else { - if (!isAccessable(file)) - return 0; + Common::SeekableReadStream *parent = getFileStream(iter->_value.parent); + assert(parent); - ResFileMap::const_iterator iter = _map.find(file); - if (iter == _map.end()) - return 0; + ResFileMap::const_iterator parentIter = _map.find(iter->_value.parent); + const ResArchiveLoader *loader = getLoader(parentIter->_value.type); + assert(loader); - if (!iter->_value.parent.empty()) { - Common::SeekableReadStream *parent = getFileStream(iter->_value.parent); - assert(parent); - - ResFileMap::const_iterator parentIter = _map.find(iter->_value.parent); - const ResArchiveLoader *loader = getLoader(parentIter->_value.type); - assert(loader); - - return loader->loadFileFromArchive(file, parent, iter->_value); - } else { - error("Couldn't open file '%s'", file.c_str()); - } + return loader->loadFileFromArchive(file, parent, iter->_value); } return 0; @@ -414,7 +417,19 @@ void Resource::checkFile(const Common::String &file) { if (_map.find(file) == _map.end()) { CompFileMap::const_iterator iter; - if (Common::File::exists(file)) { + if ((iter = _compFiles.find(file)) != _compFiles.end()) { + ResFileEntry entry; + entry.parent = ""; + entry.size = iter->_value.size; + entry.mounted = false; + entry.preload = false; + entry.prot = false; + entry.type = ResFileEntry::kAutoDetect; + entry.offset = 0; + _map[file] = entry; + + detectFileTypes(); + } else if (Common::File::exists(file)) { Common::File temp; if (temp.open(file)) { ResFileEntry entry; @@ -430,18 +445,6 @@ void Resource::checkFile(const Common::String &file) { detectFileTypes(); } - } else if ((iter = _compFiles.find(file)) != _compFiles.end()) { - ResFileEntry entry; - entry.parent = ""; - entry.size = iter->_value.size; - entry.mounted = false; - entry.preload = false; - entry.prot = false; - entry.type = ResFileEntry::kAutoDetect; - entry.offset = 0; - _map[file] = entry; - - detectFileTypes(); } } } -- cgit v1.2.3 From 7b87867a4865493246c15f2f18f3c2c7fad3d316 Mon Sep 17 00:00:00 2001 From: Johannes Schickel Date: Thu, 14 Aug 2008 22:11:56 +0000 Subject: Formatting. svn-id: r33879 --- engines/kyra/resource.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'engines') diff --git a/engines/kyra/resource.cpp b/engines/kyra/resource.cpp index 0ce364500d..5da6bb3873 100644 --- a/engines/kyra/resource.cpp +++ b/engines/kyra/resource.cpp @@ -186,7 +186,7 @@ bool Resource::loadPakFile(const Common::String &filename) { if (iter == _map.end()) { // We do an internal check for a file in gamepath with same filename to // allow overwriting files inside archives with plain files inside the - // game directory + // game directory checkFile(i->filename); // A new file entry, so we just insert it into the file map. -- cgit v1.2.3 From d6ac646d0bebb1a67a3578b3462a65f4c44c4813 Mon Sep 17 00:00:00 2001 From: Florian Kagerer Date: Thu, 14 Aug 2008 23:46:37 +0000 Subject: lol: new detection entry (german floppy extracted) svn-id: r33886 --- engines/kyra/detection.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'engines') diff --git a/engines/kyra/detection.cpp b/engines/kyra/detection.cpp index f8fd0d6308..0c6eb29665 100644 --- a/engines/kyra/detection.cpp +++ b/engines/kyra/detection.cpp @@ -944,6 +944,22 @@ const KYRAGameDescription adGameDescs[] = { LOL_FLOPPY_CMP_FLAGS }, + { + { + "lol", + "Extracted", + { + { "GENERAL.PAK", 0, "996e66e81054d36249907a1d8158da3d", -1 }, + { "CHAPTER7.PAK", 0, "cabee57f00d6d84b65a732b6868a4959", -1 }, + { 0, 0, 0, 0 } + }, + Common::DE_DEU, + Common::kPlatformPC, + Common::ADGF_NO_FLAGS + }, + LOL_FLOPPY_FLAGS + }, + /* disable these targets until they get supported { { -- cgit v1.2.3 From ea2a2cbb7c3a0d8721f1968414bd421a43b13596 Mon Sep 17 00:00:00 2001 From: Nicola Mettifogo Date: Fri, 15 Aug 2008 02:52:42 +0000 Subject: Simplified handling of script variables (especially locals). svn-id: r33889 --- engines/parallaction/exec_br.cpp | 29 +++++++-------------- engines/parallaction/exec_ns.cpp | 30 ++++++++-------------- engines/parallaction/objects.cpp | 44 ++++++++++++++++++-------------- engines/parallaction/objects.h | 29 +++++++++++---------- engines/parallaction/parallaction.cpp | 2 -- engines/parallaction/parallaction_ns.cpp | 4 --- engines/parallaction/parser_br.cpp | 3 --- engines/parallaction/parser_ns.cpp | 9 +------ 8 files changed, 61 insertions(+), 89 deletions(-) (limited to 'engines') diff --git a/engines/parallaction/exec_br.cpp b/engines/parallaction/exec_br.cpp index 5c718bf61a..e58ec13d98 100644 --- a/engines/parallaction/exec_br.cpp +++ b/engines/parallaction/exec_br.cpp @@ -321,12 +321,7 @@ DECLARE_INSTRUCTION_OPCODE(off) { DECLARE_INSTRUCTION_OPCODE(set) { InstructionPtr inst = *_ctxt.inst; - - int16 rvalue = inst->_opB.getRValue(); - int16* lvalue = inst->_opA.getLValue(); - - *lvalue = rvalue; - + inst->_opA.setValue(inst->_opB.getValue()); } @@ -334,7 +329,7 @@ DECLARE_INSTRUCTION_OPCODE(set) { DECLARE_INSTRUCTION_OPCODE(inc) { InstructionPtr inst = *_ctxt.inst; - int16 rvalue = inst->_opB.getRValue(); + int16 rvalue = inst->_opB.getValue(); if (inst->_flags & kInstMod) { // mod int16 _bx = (rvalue > 0 ? rvalue : -rvalue); @@ -343,32 +338,30 @@ DECLARE_INSTRUCTION_OPCODE(inc) { rvalue = (rvalue > 0 ? 1 : -1); } - int16 *lvalue = inst->_opA.getLValue(); + int16 lvalue = inst->_opA.getValue(); switch (inst->_index) { case INST_INC: - *lvalue += rvalue; + lvalue += rvalue; break; case INST_DEC: - *lvalue -= rvalue; + lvalue -= rvalue; break; case INST_MUL: - *lvalue *= rvalue; + lvalue *= rvalue; break; case INST_DIV: - *lvalue /= rvalue; + lvalue /= rvalue; break; default: error("This should never happen. Report immediately"); } - if (inst->_opA._flags & kParaLocal) { - inst->_opA._local->wrap(); - } + inst->_opA.setValue(lvalue); } @@ -401,11 +394,7 @@ DECLARE_INSTRUCTION_OPCODE(move) { DECLARE_INSTRUCTION_OPCODE(color) { InstructionPtr inst = *_ctxt.inst; - - int16 entry = inst->_opB.getRValue(); - - _vm->_gfx->_palette.setEntry(entry, inst->_colors[0], inst->_colors[1], inst->_colors[2]); - + _vm->_gfx->_palette.setEntry(inst->_opB.getValue(), inst->_colors[0], inst->_colors[1], inst->_colors[2]); } diff --git a/engines/parallaction/exec_ns.cpp b/engines/parallaction/exec_ns.cpp index bd05c169e7..d63582f8d1 100644 --- a/engines/parallaction/exec_ns.cpp +++ b/engines/parallaction/exec_ns.cpp @@ -80,7 +80,7 @@ DECLARE_INSTRUCTION_OPCODE(off) { DECLARE_INSTRUCTION_OPCODE(loop) { InstructionPtr inst = *_ctxt.inst; - _ctxt.program->_loopCounter = inst->_opB.getRValue(); + _ctxt.program->_loopCounter = inst->_opB.getValue(); _ctxt.program->_loopStart = _ctxt.ip; } @@ -93,7 +93,7 @@ DECLARE_INSTRUCTION_OPCODE(endloop) { DECLARE_INSTRUCTION_OPCODE(inc) { InstructionPtr inst = *_ctxt.inst; - int16 _si = inst->_opB.getRValue(); + int16 _si = inst->_opB.getValue(); if (inst->_flags & kInstMod) { // mod int16 _bx = (_si > 0 ? _si : -_si); @@ -102,29 +102,22 @@ DECLARE_INSTRUCTION_OPCODE(inc) { _si = (_si > 0 ? 1 : -1); } - int16* lvalue = inst->_opA.getLValue(); + int16 lvalue = inst->_opA.getValue(); if (inst->_index == INST_INC) { - *lvalue += _si; + lvalue += _si; } else { - *lvalue -= _si; + lvalue -= _si; } - if (inst->_opA._flags & kParaLocal) { - inst->_opA._local->wrap(); - } + inst->_opA.setValue(lvalue); } DECLARE_INSTRUCTION_OPCODE(set) { InstructionPtr inst = *_ctxt.inst; - - int16 _si = inst->_opB.getRValue(); - int16 *lvalue = inst->_opA.getLValue(); - - *lvalue = _si; - + inst->_opA.setValue(inst->_opB.getValue()); } @@ -135,8 +128,8 @@ DECLARE_INSTRUCTION_OPCODE(put) { v18.h = inst->_a->height(); v18.pixels = inst->_a->getFrameData(inst->_a->_frame); - int16 x = inst->_opA.getRValue(); - int16 y = inst->_opB.getRValue(); + int16 x = inst->_opA.getValue(); + int16 y = inst->_opB.getValue(); bool mask = (inst->_flags & kInstMaskedPut) == kInstMaskedPut; _vm->_gfx->patchBackground(v18, x, y, mask); @@ -176,8 +169,8 @@ DECLARE_INSTRUCTION_OPCODE(sound) { DECLARE_INSTRUCTION_OPCODE(move) { InstructionPtr inst = (*_ctxt.inst); - int16 x = inst->_opA.getRValue(); - int16 y = inst->_opB.getRValue(); + int16 x = inst->_opA.getValue(); + int16 y = inst->_opB.getValue(); _vm->_char.scheduleWalk(x, y); } @@ -352,7 +345,6 @@ void Parallaction_ns::drawAnimations() { if (((anim->_flags & kFlagsActive) == 0) && (anim->_flags & kFlagsRemove)) { anim->_flags &= ~kFlagsRemove; - anim->_oldPos.x = -1000; } if ((anim->_flags & kFlagsActive) && (anim->_flags & kFlagsRemove)) { diff --git a/engines/parallaction/objects.cpp b/engines/parallaction/objects.cpp index c387484de7..b91644d02d 100644 --- a/engines/parallaction/objects.cpp +++ b/engines/parallaction/objects.cpp @@ -115,24 +115,29 @@ int16 Program::addLocal(const char *name, int16 value, int16 min, int16 max) { assert(_numLocals < NUM_LOCALS); strcpy(_localNames[_numLocals], name); - _locals[_numLocals]._value = value; - - _locals[_numLocals]._min = min; - _locals[_numLocals]._max = max; + _locals[_numLocals].setRange(min, max); + _locals[_numLocals].setValue(value); return _numLocals++; } -void LocalVariable::wrap() { +void LocalVariable::setValue(int16 value) { + if (value >= _max) + value = _min; + if (value < _min) + value = _max - 1; - if (_value >= _max) - _value = _min; - if (_value < _min) - _value = _max - 1; + _value = value; +} - return; +void LocalVariable::setRange(int16 min, int16 max) { + _max = max; + _min = min; } +int16 LocalVariable::getValue() const { + return _value; +} Zone::Zone() { @@ -273,14 +278,14 @@ Instruction::~Instruction() { free(_text2); } -int16 ScriptVar::getRValue() { +int16 ScriptVar::getValue() { if (_flags & kParaImmediate) { return _value; } if (_flags & kParaLocal) { - return _local->_value; + return _local->getValue(); } if (_flags & kParaField) { @@ -296,28 +301,29 @@ int16 ScriptVar::getRValue() { return 0; } -int16* ScriptVar::getLValue() { +void ScriptVar::setValue(int16 value) { + if ((_flags & kParaLValue) == 0) { + error("Only l-value can be set"); + } if (_flags & kParaLocal) { - return &_local->_value; + _local->setValue(value); } if (_flags & kParaField) { - return _pvalue; + *_pvalue = value; } - error("Parameter is not an l-value"); - } void ScriptVar::setLocal(LocalVariable *local) { _local = local; - _flags |= kParaLocal; + _flags |= (kParaLocal | kParaLValue); } void ScriptVar::setField(int16 *field) { _pvalue = field; - _flags |= kParaField; + _flags |= (kParaField | kParaLValue); } void ScriptVar::setImmediate(int16 value) { diff --git a/engines/parallaction/objects.h b/engines/parallaction/objects.h index 7e7a811ba6..ee681a5dc4 100644 --- a/engines/parallaction/objects.h +++ b/engines/parallaction/objects.h @@ -306,8 +306,7 @@ struct Zone { uint32 _type; uint32 _flags; uint _label; - uint16 field_2C; // unused - uint16 field_2E; // unused + TypeData u; CommandList _commands; Common::Point _moveTo; @@ -328,24 +327,33 @@ struct Zone { struct LocalVariable { +protected: int16 _value; int16 _min; int16 _max; +public: + LocalVariable() { _value = 0; _min = -10000; _max = 10000; } - void wrap(); + void setRange(int16 min, int16 max); + + int16 getValue() const; + void setValue(int16 value); }; + enum ParaFlags { kParaImmediate = 1, // instruction is using an immediate parameter kParaLocal = 2, // instruction is using a local variable kParaField = 0x10, // instruction is using an animation's field - kParaRandom = 0x100 + kParaRandom = 0x100, + + kParaLValue = 0x20 }; @@ -358,8 +366,8 @@ struct ScriptVar { ScriptVar(); - int16 getRValue(); - int16* getLValue(); + int16 getValue(); + void setValue(int16 value); void setLocal(LocalVariable *local); void setField(int16 *field); @@ -431,18 +439,11 @@ typedef Common::List ProgramList; struct Animation : public Zone { - Common::Point _oldPos; GfxObj *gfxobj; char *_scriptName; int16 _frame; - uint16 field_50; // unused int16 _z; - uint16 field_54; // unused - uint16 field_56; // unused - uint16 field_58; // unused - uint16 field_5A; // unused - uint16 field_5C; // unused - uint16 field_5E; // unused + Animation(); virtual ~Animation(); diff --git a/engines/parallaction/parallaction.cpp b/engines/parallaction/parallaction.cpp index dca3d04157..195dc7a89a 100644 --- a/engines/parallaction/parallaction.cpp +++ b/engines/parallaction/parallaction.cpp @@ -513,8 +513,6 @@ Character::Character(Parallaction *vm) : _vm(vm), _ani(new Animation) { _ani->_left = 150; _ani->_top = 100; _ani->_z = 10; - _ani->_oldPos.x = -1000; - _ani->_oldPos.y = -1000; _ani->_frame = 0; _ani->_flags = kFlagsActive | kFlagsNoName; _ani->_type = kZoneYou; diff --git a/engines/parallaction/parallaction_ns.cpp b/engines/parallaction/parallaction_ns.cpp index bfbe7c3eb3..b95fcf68b2 100644 --- a/engines/parallaction/parallaction_ns.cpp +++ b/engines/parallaction/parallaction_ns.cpp @@ -318,10 +318,6 @@ void Parallaction_ns::changeLocation(char *location) { strcpy(_saveData1, locname.location()); parseLocation(_saveData1); - _char._ani->_oldPos.x = -1000; - _char._ani->_oldPos.y = -1000; - - _char._ani->field_50 = 0; if (_location._startPosition.x != -1000) { _char._ani->_left = _location._startPosition.x; _char._ani->_top = _location._startPosition.y; diff --git a/engines/parallaction/parser_br.cpp b/engines/parallaction/parser_br.cpp index dee08485fb..b71ac44d3c 100644 --- a/engines/parallaction/parser_br.cpp +++ b/engines/parallaction/parser_br.cpp @@ -849,9 +849,6 @@ DECLARE_ANIM_PARSER(endanimation) { ctxt.a->_bottom = ctxt.a->height(); } - ctxt.a->_oldPos.x = -1000; - ctxt.a->_oldPos.y = -1000; - ctxt.a->_flags |= 0x1000000; _parser->popTables(); diff --git a/engines/parallaction/parser_ns.cpp b/engines/parallaction/parser_ns.cpp index dd4a79a8d2..52256c341c 100644 --- a/engines/parallaction/parser_ns.cpp +++ b/engines/parallaction/parser_ns.cpp @@ -221,9 +221,6 @@ DECLARE_ANIM_PARSER(type) { } } - ctxt.a->_oldPos.x = -1000; - ctxt.a->_oldPos.y = -1000; - ctxt.a->_flags |= 0x1000000; _parser->popTables(); @@ -284,10 +281,6 @@ DECLARE_ANIM_PARSER(moveto) { DECLARE_ANIM_PARSER(endanimation) { debugC(7, kDebugParser, "ANIM_PARSER(endanimation) "); - - ctxt.a->_oldPos.x = -1000; - ctxt.a->_oldPos.y = -1000; - ctxt.a->_flags |= 0x1000000; _parser->popTables(); @@ -523,7 +516,7 @@ DECLARE_INSTRUCTION_PARSER(defLocal) { } ctxt.inst->_opA.setLocal(&ctxt.locals[index]); - ctxt.inst->_opB.setImmediate(ctxt.locals[index]._value); + ctxt.inst->_opB.setImmediate(ctxt.locals[index].getValue()); ctxt.inst->_index = INST_SET; } -- cgit v1.2.3 From 2679f6ce7ae1d3810187f8472d9cf8fe2368d83c Mon Sep 17 00:00:00 2001 From: Nicola Mettifogo Date: Fri, 15 Aug 2008 03:36:01 +0000 Subject: Disabled lip syncing code in BRA, since I couldn't find any scripts actually using it. Some warnings have been added as a sentinel. svn-id: r33890 --- engines/parallaction/callables_br.cpp | 2 +- engines/parallaction/exec_br.cpp | 3 ++- engines/parallaction/parallaction.h | 2 ++ engines/parallaction/parser_br.cpp | 3 +++ 4 files changed, 8 insertions(+), 2 deletions(-) (limited to 'engines') diff --git a/engines/parallaction/callables_br.cpp b/engines/parallaction/callables_br.cpp index 628ba0c1f1..a4aec8e93e 100644 --- a/engines/parallaction/callables_br.cpp +++ b/engines/parallaction/callables_br.cpp @@ -41,7 +41,7 @@ void Parallaction_br::_c_ferrcycle(void*) { } void Parallaction_br::_c_lipsinc(void*) { - warning("Parallaction_br::_c_lipsinc() not yet implemented"); + warning("Unexpected lipsinc routine call! Please notify the team!"); } void Parallaction_br::_c_albcycle(void*) { diff --git a/engines/parallaction/exec_br.cpp b/engines/parallaction/exec_br.cpp index e58ec13d98..fe7b1b2903 100644 --- a/engines/parallaction/exec_br.cpp +++ b/engines/parallaction/exec_br.cpp @@ -97,8 +97,9 @@ void Parallaction_br::setupSubtitles(char *s, char *s2, int y) { } else { _subtitle[1] = -1; } - +#if 0 // disabled because no references to lip sync has been found in the scripts _subtitleLipSync = 0; +#endif } void Parallaction_br::clearSubtitles() { diff --git a/engines/parallaction/parallaction.h b/engines/parallaction/parallaction.h index 06adf8fa16..fb004a25b7 100644 --- a/engines/parallaction/parallaction.h +++ b/engines/parallaction/parallaction.h @@ -625,8 +625,10 @@ public: int _part; int _progress; +#if 0 // disabled since I couldn't find any references to lip sync in the scripts int16 _lipSyncVal; uint _subtitleLipSync; +#endif int _subtitleY; int _subtitle[2]; diff --git a/engines/parallaction/parser_br.cpp b/engines/parallaction/parser_br.cpp index b71ac44d3c..b68401a88b 100644 --- a/engines/parallaction/parser_br.cpp +++ b/engines/parallaction/parser_br.cpp @@ -1009,7 +1009,10 @@ void ProgramParser_br::parseRValue(ScriptVar &v, const char *str) { v.setRandom(atoi(&str[1])); } else if (str[0] == 'L') { +#if 0 // disabled because no references to lip sync has been found in the scripts v.setField(&_vm->_lipSyncVal); +#endif + warning("Lip sync instruction encountered! Please notify the team!"); } } -- cgit v1.2.3 From c70d09bc26c28b565de022491dfa164bc1d720e6 Mon Sep 17 00:00:00 2001 From: Nicola Mettifogo Date: Fri, 15 Aug 2008 03:59:45 +0000 Subject: Made scripts access Animation fields via accessors and mutators, instead of using raw pointers. svn-id: r33891 --- engines/parallaction/objects.cpp | 20 +++++++++---- engines/parallaction/objects.h | 58 ++++++++++++++++++++++++++++++++++++-- engines/parallaction/parser_br.cpp | 8 +++--- engines/parallaction/parser_ns.cpp | 16 +++++------ 4 files changed, 83 insertions(+), 19 deletions(-) (limited to 'engines') diff --git a/engines/parallaction/objects.cpp b/engines/parallaction/objects.cpp index b91644d02d..6aeae3a92f 100644 --- a/engines/parallaction/objects.cpp +++ b/engines/parallaction/objects.cpp @@ -289,7 +289,7 @@ int16 ScriptVar::getValue() { } if (_flags & kParaField) { - return *_pvalue; + return _field->getValue(); } if (_flags & kParaRandom) { @@ -311,7 +311,7 @@ void ScriptVar::setValue(int16 value) { } if (_flags & kParaField) { - *_pvalue = value; + _field->setValue(value); } } @@ -321,11 +321,16 @@ void ScriptVar::setLocal(LocalVariable *local) { _flags |= (kParaLocal | kParaLValue); } -void ScriptVar::setField(int16 *field) { - _pvalue = field; +void ScriptVar::setField(Animation *anim, AnimationField::AccessorFunc accessor, AnimationField::MutatorFunc mutator) { + _field = new AnimationField(anim, accessor, mutator); _flags |= (kParaField | kParaLValue); } +void ScriptVar::setField(Animation *anim, AnimationField::AccessorFunc accessor) { + _field = new AnimationField(anim, accessor); + _flags |= kParaField; +} + void ScriptVar::setImmediate(int16 value) { _value = value; _flags |= kParaImmediate; @@ -341,9 +346,14 @@ ScriptVar::ScriptVar() { _flags = 0; _local = 0; _value = 0; - _pvalue = 0; + _field = 0; } +ScriptVar::~ScriptVar() { + delete _field; +} + + Table::Table(uint32 size) : _size(size), _used(0), _disposeMemory(true) { _data = (char**)calloc(size, sizeof(char*)); } diff --git a/engines/parallaction/objects.h b/engines/parallaction/objects.h index ee681a5dc4..1a724dcd77 100644 --- a/engines/parallaction/objects.h +++ b/engines/parallaction/objects.h @@ -357,20 +357,61 @@ enum ParaFlags { }; +struct AnimationField { + typedef Common::Functor0Mem Accessor; + typedef Common::Functor1Mem Mutator; + + typedef Accessor::FuncType AccessorFunc; + typedef Mutator::FuncType MutatorFunc; + +protected: + Accessor *_accessor; + Mutator *_mutator; + +public: + AnimationField(Animation* instance, AccessorFunc accessor, MutatorFunc mutator) { + _accessor = new Accessor(instance, accessor); + _mutator = new Mutator(instance, mutator); + } + + AnimationField(Animation* instance, AccessorFunc accessor) { + _accessor = new Accessor(instance, accessor); + _mutator = 0; + } + + ~AnimationField() { + delete _accessor; + delete _mutator; + } + + int16 getValue() const { + assert(_accessor); + return _accessor->operator()(); + } + + void setValue(int16 value) { + assert(_mutator); + _mutator->operator()(value); + } +}; + + struct ScriptVar { uint32 _flags; int16 _value; - int16* _pvalue; LocalVariable* _local; + AnimationField* _field; ScriptVar(); + ~ScriptVar(); int16 getValue(); void setValue(int16 value); void setLocal(LocalVariable *local); - void setField(int16 *field); + void setField(Animation *anim, AnimationField::AccessorFunc accessor, AnimationField::MutatorFunc mutator); + void setField(Animation *anim, AnimationField::AccessorFunc accessor); void setImmediate(int16 value); void setRandom(int16 seed); }; @@ -453,6 +494,19 @@ struct Animation : public Zone { byte* getFrameData(uint32 index) const; void validateScriptVars(); + + // getters/setters used by scripts + int16 getX() { return _left; } + void setX(int16 value) { _left = value; } + + int16 getY() { return _top; } + void setY(int16 value) { _top = value; } + + int16 getZ() { return _z; } + void setZ(int16 value) { _z = value; } + + int16 getF() { return _frame; } + void setF(int16 value) { _frame = value; } }; class Table { diff --git a/engines/parallaction/parser_br.cpp b/engines/parallaction/parser_br.cpp index b68401a88b..7b208feb95 100644 --- a/engines/parallaction/parser_br.cpp +++ b/engines/parallaction/parser_br.cpp @@ -991,16 +991,16 @@ void ProgramParser_br::parseRValue(ScriptVar &v, const char *str) { a = AnimationPtr(ctxt.a); if (str[0] == 'X') { - v.setField(&a->_left); + v.setField(a.get(), &Animation::getX); } else if (str[0] == 'Y') { - v.setField(&a->_top); + v.setField(a.get(), &Animation::getY); } else if (str[0] == 'Z') { - v.setField(&a->_z); + v.setField(a.get(), &Animation::getZ); } else if (str[0] == 'F') { - v.setField(&a->_frame); + v.setField(a.get(), &Animation::getF); } else if (str[0] == 'N') { v.setImmediate(a->getFrameNum()); diff --git a/engines/parallaction/parser_ns.cpp b/engines/parallaction/parser_ns.cpp index 52256c341c..f252f7ffdd 100644 --- a/engines/parallaction/parser_ns.cpp +++ b/engines/parallaction/parser_ns.cpp @@ -551,16 +551,16 @@ void ProgramParser_ns::parseRValue(ScriptVar &v, const char *str) { } if (str[0] == 'X') { - v.setField(&a->_left); + v.setField(a.get(), &Animation::getX); } else if (str[0] == 'Y') { - v.setField(&a->_top); + v.setField(a.get(), &Animation::getY); } else if (str[0] == 'Z') { - v.setField(&a->_z); + v.setField(a.get(), &Animation::getZ); } else if (str[0] == 'F') { - v.setField(&a->_frame); + v.setField(a.get(), &Animation::getF); } } @@ -581,16 +581,16 @@ void ProgramParser_ns::parseLValue(ScriptVar &v, const char *str) { } if (str[0] == 'X') { - v.setField(&a->_left); + v.setField(a.get(), &Animation::getX, &Animation::setX); } else if (str[0] == 'Y') { - v.setField(&a->_top); + v.setField(a.get(), &Animation::getY, &Animation::setY); } else if (str[0] == 'Z') { - v.setField(&a->_z); + v.setField(a.get(), &Animation::getZ, &Animation::setZ); } else if (str[0] == 'F') { - v.setField(&a->_frame); + v.setField(a.get(), &Animation::getF, &Animation::setF); } } -- cgit v1.2.3 From 0606fef24e03580d2d2f3c34f9fd254f361d7623 Mon Sep 17 00:00:00 2001 From: Nicola Mettifogo Date: Fri, 15 Aug 2008 04:30:45 +0000 Subject: Made coordinates and frame number protected into Zone and Animation, and changed client code to use get/set. This will allow various simplifications (e.g. when calculating Z), and is a step towards correct handling of interactive zones of Zone/Animation in BRA. svn-id: r33892 --- engines/parallaction/callables_ns.cpp | 42 +++++++++++++++----------------- engines/parallaction/debug.cpp | 4 +-- engines/parallaction/exec_ns.cpp | 32 ++++++++++++------------ engines/parallaction/graphics.cpp | 2 +- engines/parallaction/objects.h | 28 +++++++++++++++++---- engines/parallaction/parallaction.cpp | 30 +++++++++++------------ engines/parallaction/parallaction_ns.cpp | 6 ++--- engines/parallaction/parser_br.cpp | 25 +++++++++---------- engines/parallaction/parser_ns.cpp | 26 +++++++++----------- engines/parallaction/saveload.cpp | 4 +-- engines/parallaction/walk.cpp | 8 +++--- 11 files changed, 108 insertions(+), 99 deletions(-) (limited to 'engines') diff --git a/engines/parallaction/callables_ns.cpp b/engines/parallaction/callables_ns.cpp index 7e9395ef1f..0f89ca22d1 100644 --- a/engines/parallaction/callables_ns.cpp +++ b/engines/parallaction/callables_ns.cpp @@ -211,21 +211,17 @@ void Parallaction_ns::_c_moveSarc(void *parm) { } } - _introSarcData1 = _introSarcData3 - _moveSarcZone1->_left; - a->_z = _introSarcData3; - a->_frame = _moveSarcZone1->_top - (_introSarcData1 / 20); - _introSarcData3 = _moveSarcZone1->_left; + _introSarcData1 = _introSarcData3 - _moveSarcZone1->getX(); + a->setZ(_introSarcData3); + a->setF(_moveSarcZone1->getY() - (_introSarcData1 / 20)); + _introSarcData3 = _moveSarcZone1->getX(); if (_introSarcData1 > 0) { - a->_left = _introSarcData1 / 2; + a->setX(_introSarcData1 / 2); + a->setY(2); } else { - a->_left = -_introSarcData1 / 2; - } - - if (_introSarcData1 > 0) { - a->_top = 2; - } else { - a->_top = -2; + a->setX(-_introSarcData1 / 2); + a->setY(-2); } return; @@ -236,11 +232,11 @@ void Parallaction_ns::_c_moveSarc(void *parm) { _moveSarcZone1->translate(_introSarcData1, -_introSarcData1 / 20); _moveSarcZone0->translate(_introSarcData1, -_introSarcData1 / 20); - if (_moveSarcZones[0]->_left == 35 && - _moveSarcZones[1]->_left == 68 && - _moveSarcZones[2]->_left == 101 && - _moveSarcZones[3]->_left == 134 && - _moveSarcZones[4]->_left == 167) { + if (_moveSarcZones[0]->getX() == 35 && + _moveSarcZones[1]->getX() == 68 && + _moveSarcZones[2]->getX() == 101 && + _moveSarcZones[3]->getX() == 134 && + _moveSarcZones[4]->getX() == 167) { a = findAnimation("finito"); @@ -482,8 +478,8 @@ void Parallaction_ns::_c_sketch(void *parm) { Graphics::drawLine(oldx, oldy, newx, newy, 0, zeroMask, &_gfx->_backgroundInfo); - _rightHandAnim->_left = newx; - _rightHandAnim->_top = newy - 20; + _rightHandAnim->setX(newx); + _rightHandAnim->setY(newy - 20); index++; @@ -496,10 +492,10 @@ void Parallaction_ns::_c_sketch(void *parm) { void Parallaction_ns::_c_shade(void *parm) { Common::Rect r( - _rightHandAnim->_left - 36, - _rightHandAnim->_top - 36, - _rightHandAnim->_left, - _rightHandAnim->_top + _rightHandAnim->getX() - 36, + _rightHandAnim->getY() - 36, + _rightHandAnim->getX(), + _rightHandAnim->getY() ); uint16 _di = r.left/4 + r.top * _gfx->_backgroundInfo->mask.internalWidth; diff --git a/engines/parallaction/debug.cpp b/engines/parallaction/debug.cpp index 625c28dd5f..623cb3224c 100644 --- a/engines/parallaction/debug.cpp +++ b/engines/parallaction/debug.cpp @@ -157,7 +157,7 @@ bool Debugger::Cmd_Zones(int argc, const char **argv) { "+--------------------+---+---+---+---+--------+--------+\n"); for ( ; b != e; b++) { ZonePtr z = *b; - DebugPrintf("|%-20s|%3i|%3i|%3i|%3i|%8x|%8x|\n", z->_name, z->_left, z->_top, z->_right, z->_bottom, z->_type, z->_flags ); + DebugPrintf("|%-20s|%3i|%3i|%3i|%3i|%8x|%8x|\n", z->_name, z->getX(), z->getY(), z->getX() + z->width(), z->getY() + z->height(), z->_type, z->_flags ); } DebugPrintf("+--------------------+---+---+---+---+--------+--------+\n"); @@ -175,7 +175,7 @@ bool Debugger::Cmd_Animations(int argc, const char **argv) { "+--------------------+---+---+---+---+--------+--------+\n"); for ( ; b != e; b++) { AnimationPtr a = *b; - DebugPrintf("|%-20s|%3i|%3i|%3i|%3i|%8x|%8x|\n", a->_name, a->_left, a->_top, a->_z, a->_frame, a->_type, a->_flags ); + DebugPrintf("|%-20s|%3i|%3i|%3i|%3i|%8x|%8x|\n", a->_name, a->getX(), a->getY(), a->getZ(), a->getF(), a->_type, a->_flags ); } DebugPrintf("+--------------------+---+---+---+---+--------+--------+\n"); diff --git a/engines/parallaction/exec_ns.cpp b/engines/parallaction/exec_ns.cpp index d63582f8d1..873c235a1a 100644 --- a/engines/parallaction/exec_ns.cpp +++ b/engines/parallaction/exec_ns.cpp @@ -126,7 +126,7 @@ DECLARE_INSTRUCTION_OPCODE(put) { Graphics::Surface v18; v18.w = inst->_a->width(); v18.h = inst->_a->height(); - v18.pixels = inst->_a->getFrameData(inst->_a->_frame); + v18.pixels = inst->_a->getFrameData(inst->_a->getF()); int16 x = inst->_opA.getValue(); int16 y = inst->_opB.getValue(); @@ -331,14 +331,14 @@ void Parallaction_ns::drawAnimations() { if (anim->_flags & kFlagsNoMasked) layer = LAYER_FOREGROUND; else - layer = _gfx->_backgroundInfo->getLayer(anim->_top + anim->height()); + layer = _gfx->_backgroundInfo->getLayer(anim->getY() + anim->height()); if (obj) { _gfx->showGfxObj(obj, true); - obj->frame = anim->_frame; - obj->x = anim->_left; - obj->y = anim->_top; - obj->z = anim->_z; + obj->frame = anim->getF(); + obj->x = anim->getX(); + obj->y = anim->getY(); + obj->z = anim->getZ(); obj->layer = layer; } } @@ -401,7 +401,7 @@ void ProgramExec::runScripts(ProgramList::iterator first, ProgramList::iterator AnimationPtr a = (*it)->_anim; if (a->_flags & kFlagsCharacter) - a->_z = a->_top + a->height(); + a->setZ(a->getY() + a->height()); if ((a->_flags & kFlagsActing) == 0) continue; @@ -409,7 +409,7 @@ void ProgramExec::runScripts(ProgramList::iterator first, ProgramList::iterator runScript(*it, a); if (a->_flags & kFlagsCharacter) - a->_z = a->_top + a->height(); + a->setZ(a->getY() + a->height()); } _modCounter++; @@ -680,7 +680,7 @@ ZonePtr Parallaction::hitZone(uint32 type, uint16 x, uint16 y) { if (!r.contains(_si, _di)) { // out of Zone, so look for special values - if ((z->_left == -2) || (z->_left == -3)) { + if ((z->getX() == -2) || (z->getX() == -3)) { // WORKAROUND: this huge condition is needed because we made TypeData a collection of structs // instead of an union. So, merge->_obj1 and get->_icon were just aliases in the original engine, @@ -699,15 +699,15 @@ ZonePtr Parallaction::hitZone(uint32 type, uint16 x, uint16 y) { } } - if (z->_left != -1) + if (z->getX() != -1) continue; - if (_si < _char._ani->_left) + if (_si < _char._ani->getX()) continue; - if (_si > (_char._ani->_left + _char._ani->width())) + if (_si > (_char._ani->getX() + _char._ani->width())) continue; - if (_di < _char._ani->_top) + if (_di < _char._ani->getY()) continue; - if (_di > (_char._ani->_top + _char._ani->height())) + if (_di > (_char._ani->getY() + _char._ani->height())) continue; } @@ -729,8 +729,8 @@ ZonePtr Parallaction::hitZone(uint32 type, uint16 x, uint16 y) { AnimationPtr a = *ait; _a = (a->_flags & kFlagsActive) ? 1 : 0; // _a: active Animation - _e = ((_si >= a->_left + a->width()) || (_si <= a->_left)) ? 0 : 1; // _e: horizontal range - _f = ((_di >= a->_top + a->height()) || (_di <= a->_top)) ? 0 : 1; // _f: vertical range + _e = ((_si >= a->getX() + a->width()) || (_si <= a->getX())) ? 0 : 1; // _e: horizontal range + _f = ((_di >= a->getY() + a->height()) || (_di <= a->getY())) ? 0 : 1; // _f: vertical range _b = ((type != 0) || (a->_type == kZoneYou)) ? 0 : 1; // _b: (no type specified) AND (Animation is not the character) _c = (a->_type & 0xFFFF0000) ? 0 : 1; // _c: Animation is not an object diff --git a/engines/parallaction/graphics.cpp b/engines/parallaction/graphics.cpp index c19d6ae5e5..29c07b2793 100644 --- a/engines/parallaction/graphics.cpp +++ b/engines/parallaction/graphics.cpp @@ -441,7 +441,7 @@ void Gfx::updateScreen() { for (; b != e; b++) { ZonePtr z = *b; if (z->_type & kZonePath) { - surf->frameRect(Common::Rect(z->_left, z->_top, z->_right, z->_bottom), 2); + surf->frameRect(Common::Rect(z->getX(), z->getY(), z->getX() + z->width(), z->getY() + z->height()), 2); } } g_system->unlockScreen(); diff --git a/engines/parallaction/objects.h b/engines/parallaction/objects.h index 1a724dcd77..96145578fc 100644 --- a/engines/parallaction/objects.h +++ b/engines/parallaction/objects.h @@ -297,12 +297,15 @@ struct TypeData { #define ZONENAME_LENGTH 32 struct Zone { - char _name[ZONENAME_LENGTH]; - +protected: int16 _left; int16 _top; int16 _right; int16 _bottom; + +public: + char _name[ZONENAME_LENGTH]; + uint32 _type; uint32 _flags; uint _label; @@ -323,6 +326,20 @@ struct Zone { void translate(int16 x, int16 y); virtual uint16 width() const; virtual uint16 height() const; + + void setBox(int16 left, int16 top, int16 right, int16 bottom) { + setX(left); + setY(top); + _right = right; + _bottom = bottom; + } + + // getters/setters + virtual int16 getX() { return _left; } + virtual void setX(int16 value) { _left = value; } + + virtual int16 getY() { return _top; } + virtual void setY(int16 value) { _top = value; } }; @@ -479,12 +496,13 @@ typedef Common::SharedPtr ProgramPtr; typedef Common::List ProgramList; struct Animation : public Zone { - - GfxObj *gfxobj; - char *_scriptName; +protected: int16 _frame; int16 _z; +public: + GfxObj *gfxobj; + char *_scriptName; Animation(); virtual ~Animation(); diff --git a/engines/parallaction/parallaction.cpp b/engines/parallaction/parallaction.cpp index 195dc7a89a..e8621d5fd7 100644 --- a/engines/parallaction/parallaction.cpp +++ b/engines/parallaction/parallaction.cpp @@ -352,9 +352,9 @@ void Parallaction::runGame() { if (_input->_inputMode == Input::kInputModeGame) { _programExec->runScripts(_location._programs.begin(), _location._programs.end()); - _char._ani->_z = _char._ani->height() + _char._ani->_top; + _char._ani->setZ(_char._ani->height() + _char._ani->getY()); if (_char._ani->gfxobj) { - _char._ani->gfxobj->z = _char._ani->_z; + _char._ani->gfxobj->z = _char._ani->getZ(); } _char._walker->walk(); drawAnimations(); @@ -452,7 +452,7 @@ void Parallaction::freeZones() { // NOTE : this condition has been relaxed compared to the original, to allow the engine // to retain special - needed - zones that were lost across location switches. ZonePtr z = *it; - if (((z->_top == -1) || (z->_left == -2)) && ((_engineFlags & kEngineQuit) == 0)) { + if (((z->getY() == -1) || (z->getX() == -2)) && ((_engineFlags & kEngineQuit) == 0)) { debugC(2, kDebugExec, "freeZones preserving zone '%s'", z->_name); it++; } else { @@ -510,10 +510,10 @@ Character::Character(Parallaction *vm) : _vm(vm), _ani(new Animation) { _dummy = false; - _ani->_left = 150; - _ani->_top = 100; - _ani->_z = 10; - _ani->_frame = 0; + _ani->setX(150); + _ani->setY(100); + _ani->setZ(10); + _ani->setF(0); _ani->_flags = kFlagsActive | kFlagsNoName; _ani->_type = kZoneYou; strncpy(_ani->_name, "yourself", ZONENAME_LENGTH); @@ -540,18 +540,18 @@ Character::~Character() { void Character::getFoot(Common::Point &foot) { Common::Rect rect; - _ani->gfxobj->getRect(_ani->_frame, rect); + _ani->gfxobj->getRect(_ani->getF(), rect); - foot.x = _ani->_left + (rect.left + rect.width() / 2); - foot.y = _ani->_top + (rect.top + rect.height()); + foot.x = _ani->getX() + (rect.left + rect.width() / 2); + foot.y = _ani->getY() + (rect.top + rect.height()); } void Character::setFoot(const Common::Point &foot) { Common::Rect rect; - _ani->gfxobj->getRect(_ani->_frame, rect); + _ani->gfxobj->getRect(_ani->getF(), rect); - _ani->_left = foot.x - (rect.left + rect.width() / 2); - _ani->_top = foot.y - (rect.top + rect.height()); + _ani->setX(foot.x - (rect.left + rect.width() / 2)); + _ani->setY(foot.y - (rect.top + rect.height())); } #if 0 @@ -675,7 +675,7 @@ void Character::updateDirection(const Common::Point& pos, const Common::Point& t _step++; if (dist.x == 0 && dist.y == 0) { - _ani->_frame = frames->stillFrame[_direction]; + _ani->setF(frames->stillFrame[_direction]); return; } @@ -685,7 +685,7 @@ void Character::updateDirection(const Common::Point& pos, const Common::Point& t dist.y = -dist.y; _direction = (dist.x > dist.y) ? ((to.x > pos.x) ? WALK_LEFT : WALK_RIGHT) : ((to.y > pos.y) ? WALK_DOWN : WALK_UP); - _ani->_frame = frames->firstWalkFrame[_direction] + (_step / frames->frameRepeat[_direction]) % frames->numWalkFrames[_direction]; + _ani->setF(frames->firstWalkFrame[_direction] + (_step / frames->frameRepeat[_direction]) % frames->numWalkFrames[_direction]); } diff --git a/engines/parallaction/parallaction_ns.cpp b/engines/parallaction/parallaction_ns.cpp index b95fcf68b2..61f2859e8a 100644 --- a/engines/parallaction/parallaction_ns.cpp +++ b/engines/parallaction/parallaction_ns.cpp @@ -319,9 +319,9 @@ void Parallaction_ns::changeLocation(char *location) { parseLocation(_saveData1); if (_location._startPosition.x != -1000) { - _char._ani->_left = _location._startPosition.x; - _char._ani->_top = _location._startPosition.y; - _char._ani->_frame = _location._startFrame; + _char._ani->setX(_location._startPosition.x); + _char._ani->setY(_location._startPosition.y); + _char._ani->setF(_location._startFrame); _location._startPosition.y = -1000; _location._startPosition.x = -1000; } diff --git a/engines/parallaction/parser_br.cpp b/engines/parallaction/parser_br.cpp index 7b208feb95..1de69a78b5 100644 --- a/engines/parallaction/parser_br.cpp +++ b/engines/parallaction/parser_br.cpp @@ -331,14 +331,14 @@ DECLARE_LOCATION_PARSER(location) { // TODO: handle background horizontal flip (via a context parameter) if (_tokens[nextToken][0] != '\0') { - _vm->_char._ani->_left = atoi(_tokens[nextToken]); + _vm->_char._ani->setX(atoi(_tokens[nextToken])); nextToken++; - _vm->_char._ani->_top = atoi(_tokens[nextToken]); + _vm->_char._ani->setY(atoi(_tokens[nextToken])); nextToken++; } if (_tokens[nextToken][0] != '\0') { - _vm->_char._ani->_frame = atoi(_tokens[nextToken]); + _vm->_char._ani->setF(atoi(_tokens[nextToken])); } } @@ -716,10 +716,7 @@ DECLARE_ZONE_PARSER(limits) { ctxt.z->_linkedAnim = _vm->findAnimation(_tokens[1]); ctxt.z->_linkedName = strdup(_tokens[1]); } else { - ctxt.z->_left = atoi(_tokens[1]); - ctxt.z->_top = atoi(_tokens[2]); - ctxt.z->_right = atoi(_tokens[3]); - ctxt.z->_bottom = atoi(_tokens[4]); + ctxt.z->setBox(atoi(_tokens[1]), atoi(_tokens[2]), atoi(_tokens[3]), atoi(_tokens[4])); } } @@ -824,10 +821,10 @@ DECLARE_ANIM_PARSER(file) { DECLARE_ANIM_PARSER(position) { debugC(7, kDebugParser, "ANIM_PARSER(position) "); - ctxt.a->_left = atoi(_tokens[1]); - ctxt.a->_top = atoi(_tokens[2]); - ctxt.a->_z = atoi(_tokens[3]); - ctxt.a->_frame = atoi(_tokens[4]); + ctxt.a->setX(atoi(_tokens[1])); + ctxt.a->setY(atoi(_tokens[2])); + ctxt.a->setZ(atoi(_tokens[3])); + ctxt.a->setF(atoi(_tokens[4])); } @@ -843,12 +840,14 @@ DECLARE_ANIM_PARSER(moveto) { DECLARE_ANIM_PARSER(endanimation) { debugC(7, kDebugParser, "ANIM_PARSER(endanimation) "); - +#if 0 + // I have disabled the following code since it seems useless. + // I will remove it after mask processing is done. if (ctxt.a->gfxobj) { ctxt.a->_right = ctxt.a->width(); ctxt.a->_bottom = ctxt.a->height(); } - +#endif ctxt.a->_flags |= 0x1000000; _parser->popTables(); diff --git a/engines/parallaction/parser_ns.cpp b/engines/parallaction/parser_ns.cpp index f252f7ffdd..4b90e2364f 100644 --- a/engines/parallaction/parser_ns.cpp +++ b/engines/parallaction/parser_ns.cpp @@ -264,9 +264,9 @@ DECLARE_ANIM_PARSER(file) { DECLARE_ANIM_PARSER(position) { debugC(7, kDebugParser, "ANIM_PARSER(position) "); - ctxt.a->_left = atoi(_tokens[1]); - ctxt.a->_top = atoi(_tokens[2]); - ctxt.a->_z = atoi(_tokens[3]); + ctxt.a->setX(atoi(_tokens[1])); + ctxt.a->setY(atoi(_tokens[2])); + ctxt.a->setZ(atoi(_tokens[3])); } @@ -985,12 +985,12 @@ DECLARE_LOCATION_PARSER(location) { _vm->switchBackground(_vm->_location._name, mask); if (_tokens[2][0] != '\0') { - _vm->_char._ani->_left = atoi(_tokens[2]); - _vm->_char._ani->_top = atoi(_tokens[3]); + _vm->_char._ani->setX(atoi(_tokens[2])); + _vm->_char._ani->setY(atoi(_tokens[3])); } if (_tokens[4][0] != '\0') { - _vm->_char._ani->_frame = atoi(_tokens[4]); + _vm->_char._ani->setF(atoi(_tokens[4])); } } @@ -1309,11 +1309,7 @@ DECLARE_ZONE_PARSER(endzone) { DECLARE_ZONE_PARSER(limits) { debugC(7, kDebugParser, "ZONE_PARSER(limits) "); - - ctxt.z->_left = atoi(_tokens[1]); - ctxt.z->_top = atoi(_tokens[2]); - ctxt.z->_right = atoi(_tokens[3]); - ctxt.z->_bottom = atoi(_tokens[4]); + ctxt.z->setBox(atoi(_tokens[1]), atoi(_tokens[2]), atoi(_tokens[3]), atoi(_tokens[4])); } @@ -1404,8 +1400,8 @@ void LocationParser_ns::parseGetData(ZonePtr z) { GfxObj *obj = _vm->_gfx->loadGet(_tokens[1]); obj->frame = 0; - obj->x = z->_left; - obj->y = z->_top; + obj->x = z->getX(); + obj->y = z->getY(); _vm->_gfx->showGfxObj(obj, visible); data->gfxobj = obj; @@ -1467,8 +1463,8 @@ void LocationParser_ns::parseDoorData(ZonePtr z) { GfxObj *obj = _vm->_gfx->loadDoor(_tokens[1]); obj->frame = frame; - obj->x = z->_left; - obj->y = z->_top; + obj->x = z->getX(); + obj->y = z->getY(); _vm->_gfx->showGfxObj(obj, true); data->gfxobj = obj; diff --git a/engines/parallaction/saveload.cpp b/engines/parallaction/saveload.cpp index c07d976a3c..25cf3c8cf0 100644 --- a/engines/parallaction/saveload.cpp +++ b/engines/parallaction/saveload.cpp @@ -207,9 +207,9 @@ void Parallaction_ns::doSaveGame(uint16 slot, const char* name) { sprintf(s, "%s\n", _saveData1); f->writeString(s); - sprintf(s, "%d\n", _char._ani->_left); + sprintf(s, "%d\n", _char._ani->getX()); f->writeString(s); - sprintf(s, "%d\n", _char._ani->_top); + sprintf(s, "%d\n", _char._ani->getY()); f->writeString(s); sprintf(s, "%d\n", _score); f->writeString(s); diff --git a/engines/parallaction/walk.cpp b/engines/parallaction/walk.cpp index bf8f423fd5..5fd67d26dc 100644 --- a/engines/parallaction/walk.cpp +++ b/engines/parallaction/walk.cpp @@ -479,7 +479,7 @@ void PathWalker_BR::finalizeWalk() { _char.setFoot(foot); #endif - _ch->_ani->_frame = _dirFrame; // temporary solution + _ch->_ani->setF(_dirFrame); // temporary solution #if 0 // TODO: support scrolling ;) @@ -515,7 +515,7 @@ void PathWalker_BR::walk() { GfxObj *obj = _ch->_ani->gfxobj; Common::Rect rect; - obj->getRect(_ch->_ani->_frame, rect); + obj->getRect(_ch->_ani->getF(), rect); uint scale; if (rect.bottom > _vm->_location._zeta0) { @@ -609,11 +609,11 @@ void PathWalker_BR::walk() { if (_fieldC) { debugC(9, kDebugWalk, "PathWalker_BR::walk, foot moved from (%i, %i) to (%i, %i)\n", _startFoot.x, _startFoot.y, newpos.x, newpos.y); - _ch->_ani->_frame = walkFrame + _dirFrame + 1; + _ch->_ani->setF(walkFrame + _dirFrame + 1); _startFoot.x = newpos.x; _startFoot.y = newpos.y; _ch->setFoot(_startFoot); - _ch->_ani->_z = newpos.y; + _ch->_ani->setZ(newpos.y); } if (_fieldC || !_ch->_walkPath.empty()) { -- cgit v1.2.3 From 22eaffcb343c688defbcd53445ad111390edb71d Mon Sep 17 00:00:00 2001 From: Nicola Mettifogo Date: Fri, 15 Aug 2008 08:44:41 +0000 Subject: Updated layer calculation: animations are now hidden properly by background elements (but not items yet). svn-id: r33894 --- engines/parallaction/debug.cpp | 10 +++++----- engines/parallaction/exec_ns.cpp | 33 +++++++++++++++++++++------------ engines/parallaction/graphics.cpp | 6 ++++++ engines/parallaction/objects.cpp | 21 ++++++++++++++------- engines/parallaction/objects.h | 12 +++++++++++- engines/parallaction/parallaction.cpp | 2 +- engines/parallaction/parser_br.cpp | 7 ++++--- 7 files changed, 62 insertions(+), 29 deletions(-) (limited to 'engines') diff --git a/engines/parallaction/debug.cpp b/engines/parallaction/debug.cpp index 623cb3224c..0ff38913f7 100644 --- a/engines/parallaction/debug.cpp +++ b/engines/parallaction/debug.cpp @@ -187,19 +187,19 @@ bool Debugger::Cmd_GfxObjects(int argc, const char **argv) { const char *objType[] = { "DOOR", "GET", "ANIM" }; - DebugPrintf("+--------------------+-----+-----+-----+-----+--------+--------+\n" - "| name | x | y | z | f | type | visi |\n" - "+--------------------+-----+-----+-----+-----+--------+--------+\n"); + DebugPrintf("+--------------------+-----+-----+-----+-------+-----+--------+--------+\n" + "| name | x | y | z | layer | f | type | visi |\n" + "+--------------------+-----+-----+-----+-------+-----+--------+--------+\n"); GfxObjList::iterator b = _vm->_gfx->_gfxobjList.begin(); GfxObjList::iterator e = _vm->_gfx->_gfxobjList.end(); for ( ; b != e; b++) { GfxObj *obj = *b; - DebugPrintf("|%-20s|%5i|%5i|%5i|%5i|%8s|%8x|\n", obj->getName(), obj->x, obj->y, obj->z, obj->frame, objType[obj->type], obj->isVisible() ); + DebugPrintf("|%-20s|%5i|%5i|%5i|%7i|%5i|%8s|%8x|\n", obj->getName(), obj->x, obj->y, obj->z, obj->layer, obj->frame, objType[obj->type], obj->isVisible() ); } - DebugPrintf("+--------------------+-----+-----+-----+-----+--------+--------+\n"); + DebugPrintf("+--------------------+-----+-----+-----+-------+-----+--------+--------+\n"); return true; } diff --git a/engines/parallaction/exec_ns.cpp b/engines/parallaction/exec_ns.cpp index 873c235a1a..bf0423bbd1 100644 --- a/engines/parallaction/exec_ns.cpp +++ b/engines/parallaction/exec_ns.cpp @@ -330,12 +330,21 @@ void Parallaction_ns::drawAnimations() { if (anim->_flags & kFlagsNoMasked) layer = LAYER_FOREGROUND; - else - layer = _gfx->_backgroundInfo->getLayer(anim->getY() + anim->height()); + else { + if (getGameType() == GType_Nippon) { + // Layer in NS depends on where the animation is on the screen, for each animation. + layer = _gfx->_backgroundInfo->getLayer(anim->getFrameY() + anim->height()); + } else { + // Layer in BRA is calculated from Z value. For characters it is the same as NS, + // but other animations can have Z set from scripts independently from their + // position on the screen. + layer = _gfx->_backgroundInfo->getLayer(anim->getZ()); + } + } if (obj) { _gfx->showGfxObj(obj, true); - obj->frame = anim->getF(); + obj->frame = anim->getF(); obj->x = anim->getX(); obj->y = anim->getY(); obj->z = anim->getZ(); @@ -401,7 +410,7 @@ void ProgramExec::runScripts(ProgramList::iterator first, ProgramList::iterator AnimationPtr a = (*it)->_anim; if (a->_flags & kFlagsCharacter) - a->setZ(a->getY() + a->height()); + a->setZ(a->getFrameY() + a->height()); if ((a->_flags & kFlagsActing) == 0) continue; @@ -409,7 +418,7 @@ void ProgramExec::runScripts(ProgramList::iterator first, ProgramList::iterator runScript(*it, a); if (a->_flags & kFlagsCharacter) - a->setZ(a->getY() + a->height()); + a->setZ(a->getFrameY() + a->height()); } _modCounter++; @@ -671,7 +680,7 @@ ZonePtr Parallaction::hitZone(uint32 type, uint16 x, uint16 y) { if (z->_flags & kFlagsRemove) continue; Common::Rect r; - z->getRect(r); + z->getBox(r); r.right++; // adjust border because Common::Rect doesn't include bottom-right edge r.bottom++; @@ -701,13 +710,13 @@ ZonePtr Parallaction::hitZone(uint32 type, uint16 x, uint16 y) { if (z->getX() != -1) continue; - if (_si < _char._ani->getX()) + if (_si < _char._ani->getFrameX()) continue; - if (_si > (_char._ani->getX() + _char._ani->width())) + if (_si > (_char._ani->getFrameX() + _char._ani->width())) continue; - if (_di < _char._ani->getY()) + if (_di < _char._ani->getFrameY()) continue; - if (_di > (_char._ani->getY() + _char._ani->height())) + if (_di > (_char._ani->getFrameY() + _char._ani->height())) continue; } @@ -729,8 +738,8 @@ ZonePtr Parallaction::hitZone(uint32 type, uint16 x, uint16 y) { AnimationPtr a = *ait; _a = (a->_flags & kFlagsActive) ? 1 : 0; // _a: active Animation - _e = ((_si >= a->getX() + a->width()) || (_si <= a->getX())) ? 0 : 1; // _e: horizontal range - _f = ((_di >= a->getY() + a->height()) || (_di <= a->getY())) ? 0 : 1; // _f: vertical range + _e = ((_si >= a->getFrameX() + a->width()) || (_si <= a->getFrameX())) ? 0 : 1; // _e: horizontal range + _f = ((_di >= a->getFrameY() + a->height()) || (_di <= a->getFrameY())) ? 0 : 1; // _f: vertical range _b = ((type != 0) || (a->_type == kZoneYou)) ? 0 : 1; // _b: (no type specified) AND (Animation is not the character) _c = (a->_type & 0xFFFF0000) ? 0 : 1; // _c: Animation is not an object diff --git a/engines/parallaction/graphics.cpp b/engines/parallaction/graphics.cpp index 29c07b2793..1c2cb58b5b 100644 --- a/engines/parallaction/graphics.cpp +++ b/engines/parallaction/graphics.cpp @@ -377,6 +377,12 @@ void Gfx::beginFrame() { *data++ = _backgroundInfo->mask.getValue(x, y); } } +#if 1 + Common::DumpFile dump; + dump.open("maskdump.bin"); + dump.write(_bitmapMask.pixels, _bitmapMask.w * _bitmapMask.h); + dump.close(); +#endif break; } } diff --git a/engines/parallaction/objects.cpp b/engines/parallaction/objects.cpp index 6aeae3a92f..d2332643ed 100644 --- a/engines/parallaction/objects.cpp +++ b/engines/parallaction/objects.cpp @@ -71,6 +71,20 @@ uint16 Animation::height() const { return r.height(); } +int16 Animation::getFrameX() const { + if (!gfxobj) return _left; + Common::Rect r; + gfxobj->getRect(_frame, r); + return r.left + _left; +} + +int16 Animation::getFrameY() const { + if (!gfxobj) return _top; + Common::Rect r; + gfxobj->getRect(_frame, r); + return r.top + _top; +} + uint16 Animation::getFrameNum() const { if (!gfxobj) return 0; return gfxobj->getNum(); @@ -198,13 +212,6 @@ Zone::~Zone() { free(_linkedName); } -void Zone::getRect(Common::Rect& r) const { - r.left = _left; - r.right = _right; - r.top = _top; - r.bottom = _bottom; -} - void Zone::translate(int16 x, int16 y) { _left += x; _right += x; diff --git a/engines/parallaction/objects.h b/engines/parallaction/objects.h index 96145578fc..d06eaf1a03 100644 --- a/engines/parallaction/objects.h +++ b/engines/parallaction/objects.h @@ -322,7 +322,6 @@ public: Zone(); virtual ~Zone(); - void getRect(Common::Rect& r) const; void translate(int16 x, int16 y); virtual uint16 width() const; virtual uint16 height() const; @@ -334,6 +333,14 @@ public: _bottom = bottom; } + void getBox(Common::Rect& r) { + r.left = getX(); + r.right = getX() + width(); + r.top = getY(); + r.bottom = getY() + height(); + } + + // getters/setters virtual int16 getX() { return _left; } virtual void setX(int16 value) { _left = value; } @@ -513,6 +520,9 @@ public: void validateScriptVars(); + int16 getFrameX() const; + int16 getFrameY() const; + // getters/setters used by scripts int16 getX() { return _left; } void setX(int16 value) { _left = value; } diff --git a/engines/parallaction/parallaction.cpp b/engines/parallaction/parallaction.cpp index e8621d5fd7..c810d22b33 100644 --- a/engines/parallaction/parallaction.cpp +++ b/engines/parallaction/parallaction.cpp @@ -352,7 +352,7 @@ void Parallaction::runGame() { if (_input->_inputMode == Input::kInputModeGame) { _programExec->runScripts(_location._programs.begin(), _location._programs.end()); - _char._ani->setZ(_char._ani->height() + _char._ani->getY()); + _char._ani->setZ(_char._ani->height() + _char._ani->getFrameY()); if (_char._ani->gfxobj) { _char._ani->gfxobj->z = _char._ani->getZ(); } diff --git a/engines/parallaction/parser_br.cpp b/engines/parallaction/parser_br.cpp index 1de69a78b5..b9df3a2aa2 100644 --- a/engines/parallaction/parser_br.cpp +++ b/engines/parallaction/parser_br.cpp @@ -466,9 +466,10 @@ DECLARE_LOCATION_PARSER(mask) { debugC(7, kDebugParser, "LOCATION_PARSER(mask) "); ctxt.maskName = strdup(_tokens[1]); - ctxt.info->layers[0] = atoi(_tokens[2]); - ctxt.info->layers[1] = atoi(_tokens[3]); - ctxt.info->layers[2] = atoi(_tokens[4]); + ctxt.info->layers[0] = 0; + ctxt.info->layers[1] = atoi(_tokens[2]); + ctxt.info->layers[2] = atoi(_tokens[3]); + ctxt.info->layers[3] = atoi(_tokens[4]); } -- cgit v1.2.3 From 4e0485197fcfb6e8807996e5bf179c0249a7369c Mon Sep 17 00:00:00 2001 From: Sven Hesse Date: Fri, 15 Aug 2008 10:47:42 +0000 Subject: Fixing a segfault in the Bargon Attack menu svn-id: r33896 --- engines/gob/mult_v2.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'engines') diff --git a/engines/gob/mult_v2.cpp b/engines/gob/mult_v2.cpp index 20a81174e5..6bd4ddb625 100644 --- a/engines/gob/mult_v2.cpp +++ b/engines/gob/mult_v2.cpp @@ -510,10 +510,11 @@ void Mult_v2::playMultInit() { if (!_animSurf) { int16 width, height; - for (int i = 0; i < _objCount; i++) { - delete _objects[i].pPosX; - delete _objects[i].pPosY; - } + if (_objects) + for (int i = 0; i < _objCount; i++) { + delete _objects[i].pPosX; + delete _objects[i].pPosY; + } delete[] _objects; -- cgit v1.2.3 From 05a021fd952c4d35ab82f487753162f3ed3bbd43 Mon Sep 17 00:00:00 2001 From: Nicola Mettifogo Date: Fri, 15 Aug 2008 14:25:43 +0000 Subject: Added routines to load and handle item masks: animation are now correctly hidden when they are behind any object. The masks of items that are not explicitly activated (even if visible) still are handled (e.g. the crown in the museum is not visible in the foreground). svn-id: r33900 --- engines/parallaction/disk.h | 2 ++ engines/parallaction/disk_br.cpp | 23 ++++++++++++++ engines/parallaction/exec_ns.cpp | 7 ++++- engines/parallaction/graphics.h | 30 +++++++++++++++++- engines/parallaction/objects.h | 3 ++ engines/parallaction/parser.h | 4 +-- engines/parallaction/parser_br.cpp | 64 ++++++++++++++++++++++++++++++++------ 7 files changed, 118 insertions(+), 15 deletions(-) (limited to 'engines') diff --git a/engines/parallaction/disk.h b/engines/parallaction/disk.h index 341229a649..2923f239d4 100644 --- a/engines/parallaction/disk.h +++ b/engines/parallaction/disk.h @@ -69,6 +69,7 @@ public: virtual Table* loadTable(const char* name) = 0; virtual Common::SeekableReadStream* loadMusic(const char* name) = 0; virtual Common::ReadStream* loadSound(const char* name) = 0; + virtual void loadMask(const char *name, MaskBuffer &buffer) { } }; @@ -248,6 +249,7 @@ public: Table* loadTable(const char* name); Common::SeekableReadStream* loadMusic(const char* name); Common::ReadStream* loadSound(const char* name); + void loadMask(const char *name, MaskBuffer &buffer); }; class DosDemo_br : public DosDisk_br { diff --git a/engines/parallaction/disk_br.cpp b/engines/parallaction/disk_br.cpp index 11f67a2d58..f52567bea2 100644 --- a/engines/parallaction/disk_br.cpp +++ b/engines/parallaction/disk_br.cpp @@ -357,6 +357,29 @@ void DosDisk_br::loadSlide(BackgroundInfo& info, const char *name) { return; } +void DosDisk_br::loadMask(const char *name, MaskBuffer &buffer) { + if (!name) { + return; + } + + Common::String filepath; + FilesystemNode node; + Common::File stream; + + filepath = Common::String(name) + ".msk"; + node = _mskDir.getChild(filepath); + if (!node.exists()) { + errorFileNotFound(_mskDir, filepath); + } + stream.open(node); + + // NOTE: info.width and info.height are only valid if the background graphics + // have already been loaded + buffer.bigEndian = false; + stream.read(buffer.data, buffer.size); + stream.close(); +} + void DosDisk_br::loadScenery(BackgroundInfo& info, const char *name, const char *mask, const char* path) { debugC(5, kDebugDisk, "DosDisk_br::loadScenery"); diff --git a/engines/parallaction/exec_ns.cpp b/engines/parallaction/exec_ns.cpp index bf0423bbd1..6ccec4ed17 100644 --- a/engines/parallaction/exec_ns.cpp +++ b/engines/parallaction/exec_ns.cpp @@ -261,8 +261,13 @@ void Parallaction::showZone(ZonePtr z, bool visible) { if ((z->_type & 0xFFFF) == kZoneGet) { _gfx->showGfxObj(z->u.get->gfxobj, visible); - } + GetData *data = z->u.get; + if (data->hasMask && _gfx->_backgroundInfo->hasMask) { + int frame = visible ? 0 : 1; + _gfx->_backgroundInfo->mask.blt(data->gfxobj->x, data->gfxobj->y, data->_mask[frame], 0, 0, data->_mask->w, data->_mask->h); + } + } } DECLARE_COMMAND_OPCODE(on) { diff --git a/engines/parallaction/graphics.h b/engines/parallaction/graphics.h index 23b4569c6a..0b5cdb02f2 100644 --- a/engines/parallaction/graphics.h +++ b/engines/parallaction/graphics.h @@ -209,6 +209,32 @@ public: return (m >> n) & 3; } + inline byte* getPtr(uint16 x, uint16 y) const { + return data + (x >> 2) + y * internalWidth; + } + + void blt(uint16 dx, uint16 dy, const MaskBuffer &src, uint16 sx, uint16 sy, uint width, uint height) { + assert((width <= w) && (width <= src.w) && (height <= h) && (height <= src.h)); + + byte *s = src.getPtr(sx, sy); + byte *d = getPtr(dx, dy); + + uint diffs = 0; + + // this code assumes buffers are aligned on 4-pixels boundaries, as the original does + uint16 linewidth = width >> 2; + for (uint16 i = 0; i < height; i++) { + for (uint16 j = 0; j < linewidth; j++) { + if (*s) diffs++; + *d++ |= *s++; + } + d += internalWidth - linewidth; + s += src.internalWidth - linewidth; + } + + printf("MaskBuffer::blt() diffs = %i\n", diffs); + } + }; @@ -419,7 +445,9 @@ struct BackgroundInfo { int layers[4]; PaletteFxRange ranges[6]; - BackgroundInfo() : x(0), y(0), width(0), height(0) { + bool hasMask; + + BackgroundInfo() : x(0), y(0), width(0), height(0), hasMask(false) { layers[0] = layers[1] = layers[2] = layers[3] = 0; memset(ranges, 0, sizeof(ranges)); } diff --git a/engines/parallaction/objects.h b/engines/parallaction/objects.h index d06eaf1a03..f66e602f68 100644 --- a/engines/parallaction/objects.h +++ b/engines/parallaction/objects.h @@ -198,11 +198,14 @@ struct GetData { // size = 24 byte *_backup; uint16 field_14; // unused uint16 field_16; // unused + MaskBuffer _mask[2]; + bool hasMask; GetData() { _icon = 0; _backup = NULL; gfxobj = NULL; + hasMask = false; } }; struct SpeakData { // size = 36 diff --git a/engines/parallaction/parser.h b/engines/parallaction/parser.h index 5a01282e37..e622bfd81f 100644 --- a/engines/parallaction/parser.h +++ b/engines/parallaction/parser.h @@ -131,9 +131,6 @@ protected: // BRA specific int numZones; BackgroundInfo *info; - char *bgName; - char *maskName; - char *pathName; char *characterName; } ctxt; @@ -306,6 +303,7 @@ protected: virtual void parseZoneTypeBlock(ZonePtr z); void parsePathData(ZonePtr z); + void parseGetData(ZonePtr z); public: LocationParser_br(Parallaction_br *vm) : LocationParser_ns((Parallaction_ns*)vm), _vm(vm) { diff --git a/engines/parallaction/parser_br.cpp b/engines/parallaction/parser_br.cpp index b9df3a2aa2..2a8064264d 100644 --- a/engines/parallaction/parser_br.cpp +++ b/engines/parallaction/parser_br.cpp @@ -316,7 +316,6 @@ DECLARE_LOCATION_PARSER(location) { debugC(7, kDebugParser, "LOCATION_PARSER(location) "); strcpy(_vm->_location._name, _tokens[1]); - ctxt.bgName = strdup(_tokens[1]); bool flip = false; int nextToken; @@ -340,6 +339,8 @@ DECLARE_LOCATION_PARSER(location) { if (_tokens[nextToken][0] != '\0') { _vm->_char._ani->setF(atoi(_tokens[nextToken])); } + + _vm->_disk->loadScenery(*ctxt.info, _tokens[1], 0, 0); } @@ -465,18 +466,20 @@ DECLARE_LOCATION_PARSER(null) { DECLARE_LOCATION_PARSER(mask) { debugC(7, kDebugParser, "LOCATION_PARSER(mask) "); - ctxt.maskName = strdup(_tokens[1]); ctxt.info->layers[0] = 0; ctxt.info->layers[1] = atoi(_tokens[2]); ctxt.info->layers[2] = atoi(_tokens[3]); ctxt.info->layers[3] = atoi(_tokens[4]); + + _vm->_disk->loadScenery(*ctxt.info, 0, _tokens[1], 0); + ctxt.info->hasMask = true; } DECLARE_LOCATION_PARSER(path) { debugC(7, kDebugParser, "LOCATION_PARSER(path) "); - ctxt.pathName = strdup(_tokens[1]); + _vm->_disk->loadScenery(*ctxt.info, 0, 0, _tokens[1]); } @@ -768,6 +771,54 @@ void LocationParser_br::parsePathData(ZonePtr z) { z->u.path = data; } +void LocationParser_br::parseGetData(ZonePtr z) { + + GetData *data = new GetData; + + do { + + if (!scumm_stricmp(_tokens[0], "file")) { + + GfxObj *obj = _vm->_gfx->loadGet(_tokens[1]); + obj->frame = 0; + obj->x = z->getX(); + obj->y = z->getY(); + data->gfxobj = obj; + } + + if (!scumm_stricmp(_tokens[0], "mask")) { + if (ctxt.info->hasMask) { + Common::Rect rect; + data->gfxobj->getRect(0, rect); + data->_mask[0].create(rect.width(), rect.height()); + _vm->_disk->loadMask(_tokens[1], data->_mask[0]); + data->_mask[1].create(rect.width(), rect.height()); + data->_mask[1].blt(0, 0, ctxt.info->mask, data->gfxobj->x, data->gfxobj->y, data->_mask->w, data->_mask->h); + data->hasMask = true; + } else { + warning("Mask for zone '%s' ignored, since background doesn't have one", z->_name); + } + } + + if (!scumm_stricmp(_tokens[0], "path")) { + + } + + if (!scumm_stricmp(_tokens[0], "icon")) { + data->_icon = 4 + _vm->_objectsNames->lookup(_tokens[1]); + } + + _script->readLineToken(true); + } while (scumm_stricmp(_tokens[0], "endzone")); + + z->u.get = data; + + // FIXME: right now showZone doesn't work properly when called during location + // parsing. In fact, the main backgroundInfo is not properly set yet. + bool visible = (z->_flags & kFlagsRemove) == 0; + _vm->showZone(z, visible); +} + void LocationParser_br::parseZoneTypeBlock(ZonePtr z) { debugC(7, kDebugParser, "parseZoneTypeBlock(name: %s, type: %x)", z->_name, z->_type); @@ -1192,15 +1243,11 @@ void LocationParser_br::parse(Script *script) { Script *script2 = new Script(getStream(list), true); ctxt.numZones = 0; - ctxt.bgName = 0; - ctxt.maskName = 0; - ctxt.pathName = 0; ctxt.characterName = 0; ctxt.info = new BackgroundInfo; LocationParser_ns::parse(script2); - _vm->_disk->loadScenery(*ctxt.info, ctxt.bgName, ctxt.maskName, ctxt.pathName); _vm->_gfx->setBackground(kBackgroundLocation, ctxt.info); _vm->_pathBuffer = &ctxt.info->path; @@ -1209,9 +1256,6 @@ void LocationParser_br::parse(Script *script) { _vm->changeCharacter(ctxt.characterName); } - free(ctxt.bgName); - free(ctxt.maskName); - free(ctxt.pathName); free(ctxt.characterName); delete script2; -- cgit v1.2.3 From 7891e5afceff341c2a225a1f1856ea870f2e015d Mon Sep 17 00:00:00 2001 From: Nicola Mettifogo Date: Fri, 15 Aug 2008 15:08:08 +0000 Subject: Implemented raster operation for masks and postponed blitting of zones after everything in the location has been loaded. This fixes the remaining problems with animations not being masked by items. svn-id: r33903 --- engines/parallaction/exec_ns.cpp | 7 +++++-- engines/parallaction/graphics.h | 20 +++++++++++++++----- engines/parallaction/parser_br.cpp | 13 +++++++------ 3 files changed, 27 insertions(+), 13 deletions(-) (limited to 'engines') diff --git a/engines/parallaction/exec_ns.cpp b/engines/parallaction/exec_ns.cpp index 6ccec4ed17..4ea7d601e0 100644 --- a/engines/parallaction/exec_ns.cpp +++ b/engines/parallaction/exec_ns.cpp @@ -264,8 +264,11 @@ void Parallaction::showZone(ZonePtr z, bool visible) { GetData *data = z->u.get; if (data->hasMask && _gfx->_backgroundInfo->hasMask) { - int frame = visible ? 0 : 1; - _gfx->_backgroundInfo->mask.blt(data->gfxobj->x, data->gfxobj->y, data->_mask[frame], 0, 0, data->_mask->w, data->_mask->h); + if (visible) { + _gfx->_backgroundInfo->mask.bltOr(data->gfxobj->x, data->gfxobj->y, data->_mask[0], 0, 0, data->_mask->w, data->_mask->h); + } else { + _gfx->_backgroundInfo->mask.bltCopy(data->gfxobj->x, data->gfxobj->y, data->_mask[1], 0, 0, data->_mask->w, data->_mask->h); + } } } } diff --git a/engines/parallaction/graphics.h b/engines/parallaction/graphics.h index 0b5cdb02f2..471f71dfa8 100644 --- a/engines/parallaction/graphics.h +++ b/engines/parallaction/graphics.h @@ -213,28 +213,38 @@ public: return data + (x >> 2) + y * internalWidth; } - void blt(uint16 dx, uint16 dy, const MaskBuffer &src, uint16 sx, uint16 sy, uint width, uint height) { + void bltOr(uint16 dx, uint16 dy, const MaskBuffer &src, uint16 sx, uint16 sy, uint width, uint height) { assert((width <= w) && (width <= src.w) && (height <= h) && (height <= src.h)); byte *s = src.getPtr(sx, sy); byte *d = getPtr(dx, dy); - uint diffs = 0; - // this code assumes buffers are aligned on 4-pixels boundaries, as the original does uint16 linewidth = width >> 2; for (uint16 i = 0; i < height; i++) { for (uint16 j = 0; j < linewidth; j++) { - if (*s) diffs++; *d++ |= *s++; } d += internalWidth - linewidth; s += src.internalWidth - linewidth; } + } + + void bltCopy(uint16 dx, uint16 dy, const MaskBuffer &src, uint16 sx, uint16 sy, uint width, uint height) { + assert((width <= w) && (width <= src.w) && (height <= h) && (height <= src.h)); - printf("MaskBuffer::blt() diffs = %i\n", diffs); + byte *s = src.getPtr(sx, sy); + byte *d = getPtr(dx, dy); + + // this code assumes buffers are aligned on 4-pixels boundaries, as the original does + for (uint16 i = 0; i < height; i++) { + memcpy(d, s, (width >> 2)); + d += internalWidth; + s += src.internalWidth; + } } + }; diff --git a/engines/parallaction/parser_br.cpp b/engines/parallaction/parser_br.cpp index 2a8064264d..20800abc33 100644 --- a/engines/parallaction/parser_br.cpp +++ b/engines/parallaction/parser_br.cpp @@ -793,7 +793,7 @@ void LocationParser_br::parseGetData(ZonePtr z) { data->_mask[0].create(rect.width(), rect.height()); _vm->_disk->loadMask(_tokens[1], data->_mask[0]); data->_mask[1].create(rect.width(), rect.height()); - data->_mask[1].blt(0, 0, ctxt.info->mask, data->gfxobj->x, data->gfxobj->y, data->_mask->w, data->_mask->h); + data->_mask[1].bltCopy(0, 0, ctxt.info->mask, data->gfxobj->x, data->gfxobj->y, data->_mask->w, data->_mask->h); data->hasMask = true; } else { warning("Mask for zone '%s' ignored, since background doesn't have one", z->_name); @@ -812,11 +812,6 @@ void LocationParser_br::parseGetData(ZonePtr z) { } while (scumm_stricmp(_tokens[0], "endzone")); z->u.get = data; - - // FIXME: right now showZone doesn't work properly when called during location - // parsing. In fact, the main backgroundInfo is not properly set yet. - bool visible = (z->_flags & kFlagsRemove) == 0; - _vm->showZone(z, visible); } void LocationParser_br::parseZoneTypeBlock(ZonePtr z) { @@ -1252,6 +1247,12 @@ void LocationParser_br::parse(Script *script) { _vm->_pathBuffer = &ctxt.info->path; + ZoneList::iterator it = _vm->_location._zones.begin(); + for ( ; it != _vm->_location._zones.end(); it++) { + bool visible = ((*it)->_flags & kFlagsRemove) == 0; + _vm->showZone((*it), visible); + } + if (ctxt.characterName) { _vm->changeCharacter(ctxt.characterName); } -- cgit v1.2.3 From f2111eeb45dc8c41afb3e63bf3b86a09bf9a3532 Mon Sep 17 00:00:00 2001 From: Max Horn Date: Fri, 15 Aug 2008 22:06:15 +0000 Subject: SCUMM: Made some potentially ambiguous (to the reader, at least) checks slightly less ambiguous svn-id: r33919 --- engines/scumm/boxes.cpp | 20 ++++++++++---------- engines/scumm/script_v5.cpp | 2 +- 2 files changed, 11 insertions(+), 11 deletions(-) (limited to 'engines') diff --git a/engines/scumm/boxes.cpp b/engines/scumm/boxes.cpp index 0fa8b579ca..1e632a034e 100644 --- a/engines/scumm/boxes.cpp +++ b/engines/scumm/boxes.cpp @@ -544,8 +544,8 @@ bool ScummEngine::checkXYInBoxBounds(int boxnum, int x, int y) { // Corner case: If the box is a simple line segment, we consider the // point to be contained "in" (or rather, lying on) the line if it // is very close to its projection to the line segment. - if (box.ul == box.ur && box.lr == box.ll || - box.ul == box.ll && box.ur == box.lr) { + if ((box.ul == box.ur && box.lr == box.ll) || + (box.ul == box.ll && box.ur == box.lr)) { Common::Point tmp; tmp = closestPtOnLine(box.ul, box.lr, p); @@ -803,8 +803,8 @@ bool Actor::findPathTowards(byte box1nr, byte box2nr, byte box3nr, Common::Point } if (box1.ul.y > box2.ur.y || box2.ul.y > box1.ur.y || - (box1.ur.y == box2.ul.y || box2.ur.y == box1.ul.y) && - box1.ul.y != box1.ur.y && box2.ul.y != box2.ur.y) { + ((box1.ur.y == box2.ul.y || box2.ur.y == box1.ul.y) && + box1.ul.y != box1.ur.y && box2.ul.y != box2.ur.y)) { if (flag & 1) SWAP(box1.ul.y, box1.ur.y); if (flag & 2) @@ -858,8 +858,8 @@ bool Actor::findPathTowards(byte box1nr, byte box2nr, byte box3nr, Common::Point } if (box1.ul.x > box2.ur.x || box2.ul.x > box1.ur.x || - (box1.ur.x == box2.ul.x || box2.ur.x == box1.ul.x) && - box1.ul.x != box1.ur.x && box2.ul.x != box2.ur.x) { + ((box1.ur.x == box2.ul.x || box2.ur.x == box1.ul.x) && + box1.ul.x != box1.ur.x && box2.ul.x != box2.ur.x)) { if (flag & 1) SWAP(box1.ul.x, box1.ur.x); if (flag & 2) @@ -1074,8 +1074,8 @@ bool ScummEngine::areBoxesNeighbours(int box1nr, int box2nr) { } if (box.ur.y < box2.ul.y || box.ul.y > box2.ur.y || - (box.ul.y == box2.ur.y || - box.ur.y == box2.ul.y) && box2.ur.y != box2.ul.y && box.ul.y != box.ur.y) { + ((box.ul.y == box2.ur.y || + box.ur.y == box2.ul.y) && box2.ur.y != box2.ul.y && box.ul.y != box.ur.y)) { } else { return true; } @@ -1103,8 +1103,8 @@ bool ScummEngine::areBoxesNeighbours(int box1nr, int box2nr) { } if (box.ur.x < box2.ul.x || box.ul.x > box2.ur.x || - (box.ul.x == box2.ur.x || - box.ur.x == box2.ul.x) && box2.ur.x != box2.ul.x && box.ul.x != box.ur.x) { + ((box.ul.x == box2.ur.x || + box.ur.x == box2.ul.x) && box2.ur.x != box2.ul.x && box.ul.x != box.ur.x)) { } else { return true; diff --git a/engines/scumm/script_v5.cpp b/engines/scumm/script_v5.cpp index 431321f459..3cbb2b8266 100644 --- a/engines/scumm/script_v5.cpp +++ b/engines/scumm/script_v5.cpp @@ -1402,7 +1402,7 @@ void ScummEngine_v5::o5_ifClassOfIs() { while ((_opcode = fetchScriptByte()) != 0xFF) { cls = getVarOrDirectWord(PARAM_1); b = getClass(act, cls); - if (cls & 0x80 && !b || !(cls & 0x80) && b) + if (((cls & 0x80) && !b) || (!(cls & 0x80) && b)) cond = false; } if (cond) -- cgit v1.2.3