diff options
author | Martin Kiewitz | 2010-05-25 18:45:25 +0000 |
---|---|---|
committer | Martin Kiewitz | 2010-05-25 18:45:25 +0000 |
commit | aa8c6377a5cb8c51717f6bcf1ffc950c6c837021 (patch) | |
tree | 80d7884a604feb59f04a6ea3ffa7d0af00dbc2ed /engines/sci/graphics | |
parent | 5f3952e5787079d8acd3476d3b7f0d67116b5d94 (diff) | |
download | scummvm-rg350-aa8c6377a5cb8c51717f6bcf1ffc950c6c837021.tar.gz scummvm-rg350-aa8c6377a5cb8c51717f6bcf1ffc950c6c837021.tar.bz2 scummvm-rg350-aa8c6377a5cb8c51717f6bcf1ffc950c6c837021.zip |
SCI: error out on pattern opcodes inside vector data when drawing pictures in sci1.1+, also adding workaround for garbage data inside picture 381 in sq4
svn-id: r49216
Diffstat (limited to 'engines/sci/graphics')
-rw-r--r-- | engines/sci/graphics/picture.cpp | 32 | ||||
-rw-r--r-- | engines/sci/graphics/picture.h | 9 |
2 files changed, 30 insertions, 11 deletions
diff --git a/engines/sci/graphics/picture.cpp b/engines/sci/graphics/picture.cpp index f186e09545..73eb9200ec 100644 --- a/engines/sci/graphics/picture.cpp +++ b/engines/sci/graphics/picture.cpp @@ -69,17 +69,20 @@ void GfxPicture::draw(int16 animationNr, bool mirroredFlag, bool addToFlag, int1 headerSize = READ_LE_UINT16(_resource->data); switch (headerSize) { case 0x26: // SCI 1.1 VGA picture + _resourceType = SCI_PICTURE_TYPE_SCI11; if (_addToFlag) _priority = 15; drawSci11Vga(); break; #ifdef ENABLE_SCI32 case 0x0e: // SCI32 VGA picture + _resourceType = SCI_PICTURE_TYPE_SCI32; drawSci32Vga(); break; #endif default: // VGA, EGA or Amiga vector data + _resourceType = SCI_PICTURE_TYPE_REGULAR; drawVectorData(_resource->data, _resource->size); } } @@ -111,7 +114,7 @@ void GfxPicture::drawSci11Vga() { // display Cel-data if (has_cel) - drawCelData(inbuffer, size, cel_headerPos, cel_RlePos, cel_LiteralPos, 0, 0, SCI_PICTURE_CELTYPE_SCI11); + drawCelData(inbuffer, size, cel_headerPos, cel_RlePos, cel_LiteralPos, 0, 0); // process vector data drawVectorData(inbuffer + vector_dataPos, vector_size); @@ -156,14 +159,14 @@ void GfxPicture::drawSci32Vga(int16 celNo) { cel_LiteralPos = READ_LE_UINT32(inbuffer + cel_headerPos + 28); cel_relXpos = READ_LE_UINT16(inbuffer + cel_headerPos + 38); cel_relYpos = READ_LE_UINT16(inbuffer + cel_headerPos + 40); - drawCelData(inbuffer, size, cel_headerPos, cel_RlePos, cel_LiteralPos, cel_relXpos, cel_relYpos, SCI_PICTURE_CELTYPE_SCI32); + drawCelData(inbuffer, size, cel_headerPos, cel_RlePos, cel_LiteralPos, cel_relXpos, cel_relYpos); cel_headerPos += 42; celCount--; } } #endif -void GfxPicture::drawCelData(byte *inbuffer, int size, int headerPos, int rlePos, int literalPos, int16 callerX, int16 callerY, int celType) { +void GfxPicture::drawCelData(byte *inbuffer, int size, int headerPos, int rlePos, int literalPos, int16 callerX, int16 callerY) { byte *celBitmap = NULL; byte *ptr = NULL; byte *headerPtr = inbuffer + headerPos; @@ -180,11 +183,11 @@ void GfxPicture::drawCelData(byte *inbuffer, int size, int headerPos, int rlePos int pixelNr, pixelCount; #ifdef ENABLE_SCI32 - if (celType != SCI_PICTURE_CELTYPE_SCI32) { + if (_resourceType != SCI_PICTURE_TYPE_SCI32) { #endif displaceX = (signed char)headerPtr[4]; displaceY = (unsigned char)headerPtr[5]; - if (celType == SCI_PICTURE_CELTYPE_SCI11) { + if (_resourceType == SCI_PICTURE_TYPE_SCI11) { // SCI1.1 uses hardcoded clearcolor for pictures, even if cel header specifies otherwise clearColor = _screen->getColorWhite(); } else { @@ -525,9 +528,20 @@ void GfxPicture::drawVectorData(byte *data, int dataSize) { break; case PIC_OP_SET_PATTERN: + if (_resourceType >= SCI_PICTURE_TYPE_SCI11) { + if (strcmp(g_sci->getGameID(), "sq4") == 0) { + // WORKAROUND: For SQ4 / picture 381 handle this like a terminator + // This picture includes garbage data, first a set pattern w/o parameter and then short pattern + if (_resourceId == 381) + return; + } + error("pic-operation set pattern inside sci1.1+ vector data"); + } pattern_Code = data[curPos++]; break; case PIC_OP_SHORT_PATTERNS: + if (_resourceType >= SCI_PICTURE_TYPE_SCI11) + error("pic-operation short pattern inside sci1.1+ vector data"); vectorGetPatternTexture(data, curPos, pattern_Code, pattern_Texture); vectorGetAbsCoords(data, curPos, x, y); vectorPattern(x, y, pic_color, pic_priority, pic_control, pattern_Code, pattern_Texture); @@ -538,6 +552,8 @@ void GfxPicture::drawVectorData(byte *data, int dataSize) { } break; case PIC_OP_MEDIUM_PATTERNS: + if (_resourceType >= SCI_PICTURE_TYPE_SCI11) + error("pic-operation medium pattern inside sci1.1+ vector data"); vectorGetPatternTexture(data, curPos, pattern_Code, pattern_Texture); vectorGetAbsCoords(data, curPos, x, y); vectorPattern(x, y, pic_color, pic_priority, pic_control, pattern_Code, pattern_Texture); @@ -548,6 +564,8 @@ void GfxPicture::drawVectorData(byte *data, int dataSize) { } break; case PIC_OP_ABSOLUTE_PATTERN: + if (_resourceType >= SCI_PICTURE_TYPE_SCI11) + error("pic-operation absolute pattern inside sci1.1+ vector data"); while (vectorIsNonOpcode(data[curPos])) { vectorGetPatternTexture(data, curPos, pattern_Code, pattern_Texture); vectorGetAbsCoords(data, curPos, x, y); @@ -591,7 +609,7 @@ void GfxPicture::drawVectorData(byte *data, int dataSize) { vectorGetAbsCoordsNoMirror(data, curPos, x, y); size = READ_LE_UINT16(data + curPos); curPos += 2; _priority = pic_priority; // set global priority so the cel gets drawn using current priority as well - drawCelData(data, _resource->size, curPos, curPos + 8, 0, x, y, SCI_PICTURE_CELTYPE_REGULAR); + drawCelData(data, _resource->size, curPos, curPos + 8, 0, x, y); curPos += size; break; case PIC_OPX_EGA_SET_PRIORITY_TABLE: @@ -633,7 +651,7 @@ void GfxPicture::drawVectorData(byte *data, int dataSize) { _priority = pic_priority; // set global priority so the cel gets drawn using current priority as well if (pic_priority == 255) _priority = 0; // if priority not set, use priority 0 - drawCelData(data, _resource->size, curPos, curPos + 8, 0, x, y, SCI_PICTURE_CELTYPE_REGULAR); + drawCelData(data, _resource->size, curPos, curPos + 8, 0, x, y); curPos += size; break; case PIC_OPX_VGA_PRIORITY_TABLE_EQDIST: diff --git a/engines/sci/graphics/picture.h b/engines/sci/graphics/picture.h index ba6052b059..5a86539b37 100644 --- a/engines/sci/graphics/picture.h +++ b/engines/sci/graphics/picture.h @@ -33,9 +33,9 @@ namespace Sci { #define SCI_PATTERN_CODE_PENSIZE 0x07 enum { - SCI_PICTURE_CELTYPE_REGULAR = 0, - SCI_PICTURE_CELTYPE_SCI11 = 1, - SCI_PICTURE_CELTYPE_SCI32 = 2 + SCI_PICTURE_TYPE_REGULAR = 0, + SCI_PICTURE_TYPE_SCI11 = 1, + SCI_PICTURE_TYPE_SCI32 = 2 }; class GfxPorts; @@ -63,7 +63,7 @@ private: void initData(GuiResourceId resourceId); void reset(); void drawSci11Vga(); - void drawCelData(byte *inbuffer, int size, int headerPos, int rlePos, int literalPos, int16 callerX, int16 callerY, int celType); + void drawCelData(byte *inbuffer, int size, int headerPos, int rlePos, int literalPos, int16 callerX, int16 callerY); void drawVectorData(byte *data, int size); bool vectorIsNonOpcode(byte pixel); void vectorGetAbsCoords(byte *data, int &curPos, int16 &x, int16 &y); @@ -86,6 +86,7 @@ private: int16 _resourceId; Resource *_resource; + int _resourceType; int16 _animationNr; bool _mirroredFlag; |