From 460d387ec55a270865ac1bc40b266ca0a61ad58a Mon Sep 17 00:00:00 2001 From: Martin Kiewitz Date: Mon, 8 Jun 2015 17:24:54 +0200 Subject: SHERLOCK: 3do cel uncompressed fix, adjust city - uncompressed data is still DWORD aligned - fixes "copyright EA" cel - adjusted city scene coordinates --- engines/sherlock/resources.cpp | 36 +++++++++++++++++++++++------------- engines/sherlock/resources.h | 2 +- engines/sherlock/scalpel/scalpel.cpp | 18 ++++++++++-------- 3 files changed, 34 insertions(+), 22 deletions(-) (limited to 'engines') diff --git a/engines/sherlock/resources.cpp b/engines/sherlock/resources.cpp index cc45756588..068e193219 100644 --- a/engines/sherlock/resources.cpp +++ b/engines/sherlock/resources.cpp @@ -667,11 +667,10 @@ void ImageFile3DO::loadAnimationFile(Common::SeekableReadStream &stream, bool an // Load data for frame and decompress it byte *data = new byte[compressedSize]; - assert(data); stream.read(data, compressedSize); // always 16 bits per pixel (RGB555) - decompress3DOCelFrame(frame, data, 16, NULL); + decompress3DOCelFrame(frame, data, compressedSize, 16, NULL); delete[] data; @@ -822,7 +821,6 @@ void ImageFile3DO::load3DOCelFile(Common::SeekableReadStream &stream) { } // read data into memory chunkDataPtr = new byte[dataSize]; - assert(chunkDataPtr); stream.read(chunkDataPtr, dataSize); @@ -837,9 +835,9 @@ void ImageFile3DO::load3DOCelFile(Common::SeekableReadStream &stream) { // Decompress/copy this frame if (!plutFound) { - decompress3DOCelFrame(imageFrame, chunkDataPtr, ccbPRE0_bitsPerPixel, NULL); + decompress3DOCelFrame(imageFrame, chunkDataPtr, dataSize, ccbPRE0_bitsPerPixel, NULL); } else { - decompress3DOCelFrame(imageFrame, chunkDataPtr, ccbPRE0_bitsPerPixel, &plutRGBlookupTable); + decompress3DOCelFrame(imageFrame, chunkDataPtr, dataSize, ccbPRE0_bitsPerPixel, &plutRGBlookupTable); } delete[] chunkDataPtr; @@ -894,7 +892,7 @@ inline uint16 ImageFile3DO::celGetBits(const byte *&dataPtr, byte bitCount, byte } // decompress/copy 3DO cel data -void ImageFile3DO::decompress3DOCelFrame(ImageFrame &frame, const byte *dataPtr, byte bitsPerPixel, ImageFile3DOPixelLookupTable *pixelLookupTable) { +void ImageFile3DO::decompress3DOCelFrame(ImageFrame &frame, const byte *dataPtr, uint32 dataSize, byte bitsPerPixel, ImageFile3DOPixelLookupTable *pixelLookupTable) { frame._frame.create(frame._width, frame._height, Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0)); uint16 *dest = (uint16 *)frame._frame.getPixels(); Common::fill(dest, dest + frame._width * frame._height, 0); @@ -904,6 +902,12 @@ void ImageFile3DO::decompress3DOCelFrame(ImageFrame &frame, const byte *dataPtr, uint16 pixelCount = 0; uint16 pixel = 0; + const byte *srcLineStart = dataPtr; + const byte *srcLineData = dataPtr; + byte srcLineDataBitsLeft = 0; + uint16 lineDWordSize = 0; + uint16 lineByteSize = 0; + if (bitsPerPixel == 16) { // Must not use pixel lookup table on 16-bits-per-pixel data assert(!pixelLookupTable); @@ -911,10 +915,6 @@ void ImageFile3DO::decompress3DOCelFrame(ImageFrame &frame, const byte *dataPtr, if (frame._rleEncoded) { // compressed - const byte *srcLineStart = dataPtr; - const byte *srcLineData = dataPtr; - byte srcLineDataBitsLeft = 0; - uint16 lineDWordSize = 0; byte compressionType = 0; byte compressionPixels = 0; @@ -931,7 +931,7 @@ void ImageFile3DO::decompress3DOCelFrame(ImageFrame &frame, const byte *dataPtr, srcLineDataBitsLeft = 8; lineDWordSize += 2; - uint16 lineByteSize = lineDWordSize * 4; // calculate compressed data size in bytes for current line + lineByteSize = lineDWordSize * 4; // calculate compressed data size in bytes for current line // debug //warning("offset %d: decoding line, size %d, bytesize %d", srcSeeker - src, dwordSize, lineByteSize); @@ -991,12 +991,19 @@ void ImageFile3DO::decompress3DOCelFrame(ImageFrame &frame, const byte *dataPtr, } } else { // uncompressed - byte dataBitsLeft = 8; + srcLineDataBitsLeft = 8; + lineDWordSize = ((frame._width * bitsPerPixel) + 31) >> 5; + lineByteSize = lineDWordSize * 4; + uint32 totalExpectedSize = lineByteSize * frame._height; + + assert(totalExpectedSize <= dataSize); // security check while (frameHeightLeft > 0) { + srcLineData = srcLineStart; frameWidthLeft = frame._width; + while (frameWidthLeft > 0) { - pixel = celGetBits(dataPtr, bitsPerPixel, dataBitsLeft); + pixel = celGetBits(srcLineData, bitsPerPixel, srcLineDataBitsLeft); if (pixelLookupTable) { pixel = pixelLookupTable->pixelColor[pixel]; } @@ -1005,6 +1012,9 @@ void ImageFile3DO::decompress3DOCelFrame(ImageFrame &frame, const byte *dataPtr, frameWidthLeft--; } frameHeightLeft--; + + // Seek to next line start + srcLineStart += lineByteSize; } } } diff --git a/engines/sherlock/resources.h b/engines/sherlock/resources.h index 795918be41..4f786ee04b 100644 --- a/engines/sherlock/resources.h +++ b/engines/sherlock/resources.h @@ -250,7 +250,7 @@ private: /** * Decompress a single frame of a 3DO cel file */ - void decompress3DOCelFrame(ImageFrame &frame, const byte *dataPtr, byte bitsPerPixel, ImageFile3DOPixelLookupTable *pixelLookupTable); + void decompress3DOCelFrame(ImageFrame &frame, const byte *dataPtr, uint32 dataSize, byte bitsPerPixel, ImageFile3DOPixelLookupTable *pixelLookupTable); /** * Load animation graphics file diff --git a/engines/sherlock/scalpel/scalpel.cpp b/engines/sherlock/scalpel/scalpel.cpp index 35ef6648b0..caa0f70098 100644 --- a/engines/sherlock/scalpel/scalpel.cpp +++ b/engines/sherlock/scalpel/scalpel.cpp @@ -540,19 +540,21 @@ bool ScalpelEngine::showCityCutscene3DO() { // "London, England" ImageFile3DO titleImage_London("title2a.cel"); - _screen->transBlitFromUnscaled3DO(titleImage_London[0]._frame, Common::Point(10, 11)); + _screen->transBlitFromUnscaled3DO(titleImage_London[0]._frame, Common::Point(30, 50)); finished = _events->delay(1000, true); if (finished) { // "November, 1888" ImageFile3DO titleImage_November("title2b.cel"); - _screen->transBlitFromUnscaled3DO(titleImage_November[0]._frame, Common::Point(101, 102)); + _screen->transBlitFromUnscaled3DO(titleImage_November[0]._frame, Common::Point(101, 100)); finished = _events->delay(5000, true); - if (finished) { - _screen->blitFrom(_screen->_backBuffer2); - } + } + + if (finished) { + // Restore screen + _screen->blitFrom(_screen->_backBuffer2); } } @@ -563,14 +565,14 @@ bool ScalpelEngine::showCityCutscene3DO() { // "Sherlock Holmes" (title) ImageFile3DO titleImage_SherlockHolmesTitle("title1ab.cel"); - _screen->transBlitFromUnscaled3DO(titleImage_SherlockHolmesTitle[0]._frame, Common::Point(34, 21)); + _screen->transBlitFromUnscaled3DO(titleImage_SherlockHolmesTitle[0]._frame, Common::Point(34, 5)); finished = _events->delay(500, true); // Title should fade in, Copyright should be displayed a bit after that if (finished) { - //ImageFile3DO titleImage_Copyright("title1c.cel"); + ImageFile3DO titleImage_Copyright("title1c.cel"); - //_screen->transBlitFromUnscaled3DO(titleImage_Copyright[0]._frame, Common::Point(4, 190)); + _screen->transBlitFromUnscaled3DO(titleImage_Copyright[0]._frame, Common::Point(20, 190)); finished = _events->delay(3500, true); } // Title is supposed to get faded away after that -- cgit v1.2.3