aboutsummaryrefslogtreecommitdiff
path: root/engines/sci
diff options
context:
space:
mode:
authorMartin Kiewitz2010-05-25 18:45:25 +0000
committerMartin Kiewitz2010-05-25 18:45:25 +0000
commitaa8c6377a5cb8c51717f6bcf1ffc950c6c837021 (patch)
tree80d7884a604feb59f04a6ea3ffa7d0af00dbc2ed /engines/sci
parent5f3952e5787079d8acd3476d3b7f0d67116b5d94 (diff)
downloadscummvm-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')
-rw-r--r--engines/sci/graphics/picture.cpp32
-rw-r--r--engines/sci/graphics/picture.h9
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;