Skip to content

Commit

Permalink
SHERLOCK: 3do cel uncompressed fix, adjust city
Browse files Browse the repository at this point in the history
- uncompressed data is still DWORD aligned
- fixes "copyright EA" cel
- adjusted city scene coordinates
  • Loading branch information
Martin Kiewitz committed Jun 8, 2015
1 parent 65d94d3 commit 460d387
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 22 deletions.
36 changes: 23 additions & 13 deletions engines/sherlock/resources.cpp
Expand Up @@ -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;

Expand Down Expand Up @@ -822,7 +821,6 @@ void ImageFile3DO::load3DOCelFile(Common::SeekableReadStream &stream) {
}
// read data into memory
chunkDataPtr = new byte[dataSize];
assert(chunkDataPtr);

stream.read(chunkDataPtr, dataSize);

Expand All @@ -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;
Expand Down Expand Up @@ -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);
Expand All @@ -904,17 +902,19 @@ 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);
}

if (frame._rleEncoded) {
// compressed
const byte *srcLineStart = dataPtr;
const byte *srcLineData = dataPtr;
byte srcLineDataBitsLeft = 0;
uint16 lineDWordSize = 0;
byte compressionType = 0;
byte compressionPixels = 0;

Expand All @@ -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);
Expand Down Expand Up @@ -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];
}
Expand All @@ -1005,6 +1012,9 @@ void ImageFile3DO::decompress3DOCelFrame(ImageFrame &frame, const byte *dataPtr,
frameWidthLeft--;
}
frameHeightLeft--;

// Seek to next line start
srcLineStart += lineByteSize;
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion engines/sherlock/resources.h
Expand Up @@ -250,7 +250,7 @@ class ImageFile3DO : public Common::Array<ImageFrame> {
/**
* 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
Expand Down
18 changes: 10 additions & 8 deletions engines/sherlock/scalpel/scalpel.cpp
Expand Up @@ -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);
}
}

Expand All @@ -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
Expand Down

0 comments on commit 460d387

Please sign in to comment.