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/cine') 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/cine') 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/cine') 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/cine') 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/cine') 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/cine') 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/cine') 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/cine') 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/cine') 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/cine') 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/cine') 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/cine') 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/cine') 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/cine') 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/cine') 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/cine') 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/cine') 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 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/cine') 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 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/cine') 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/cine') 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 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/cine') 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