diff options
Diffstat (limited to 'engines/sherlock/image_file.cpp')
-rw-r--r-- | engines/sherlock/image_file.cpp | 137 |
1 files changed, 73 insertions, 64 deletions
diff --git a/engines/sherlock/image_file.cpp b/engines/sherlock/image_file.cpp index 81087dae8b..c53e537bb8 100644 --- a/engines/sherlock/image_file.cpp +++ b/engines/sherlock/image_file.cpp @@ -172,7 +172,7 @@ void ImageFrame::decompressFrame(const byte *src, bool isRoseTattoo) { while (frameSize > 0) { if (*src == _rleMarker) { byte rleColor = src[1]; - byte rleCount = src[2]; + byte rleCount = MIN((int)src[2], frameSize); src += 3; frameSize -= rleCount; while (rleCount--) @@ -182,7 +182,6 @@ void ImageFrame::decompressFrame(const byte *src, bool isRoseTattoo) { --frameSize; } } - assert(frameSize == 0); } else { // Uncompressed frame Common::copy(src, src + _width * _height, dest); @@ -220,6 +219,9 @@ int ImageFrame::sDrawYSize(int scaleVal) const { } int ImageFrame::sDrawXOffset(int scaleVal) const { + if (scaleVal == SCALE_THRESHOLD) + return _offset.x; + int width = _offset.x; int scale = scaleVal == 0 ? 1 : scaleVal; @@ -227,13 +229,16 @@ int ImageFrame::sDrawXOffset(int scaleVal) const { --width; int result = width * SCALE_THRESHOLD / scale; - if (scaleVal >= SCALE_THRESHOLD) + if (scaleVal > SCALE_THRESHOLD) ++result; return result; } int ImageFrame::sDrawYOffset(int scaleVal) const { + if (scaleVal == SCALE_THRESHOLD) + return _offset.y; + int height = _offset.y; int scale = scaleVal == 0 ? 1 : scaleVal; @@ -241,7 +246,7 @@ int ImageFrame::sDrawYOffset(int scaleVal) const { --height; int result = height * SCALE_THRESHOLD / scale; - if (scaleVal >= SCALE_THRESHOLD) + if (scaleVal > SCALE_THRESHOLD) ++result; return result; @@ -297,12 +302,6 @@ ImageFile3DO::ImageFile3DO(Common::SeekableReadStream &stream, bool isRoomData) } } -ImageFile3DO::~ImageFile3DO() { - // already done in ImageFile destructor - //for (uint idx = 0; idx < size(); ++idx) - // (*this)[idx]._frame.free(); -} - void ImageFile3DO::load(Common::SeekableReadStream &stream, bool isRoomData) { uint32 headerId = 0; @@ -375,7 +374,7 @@ void ImageFile3DO::loadAnimationFile(Common::SeekableReadStream &stream) { if (streamLeft < celDataSize) error("load3DOAnimationFile: expected cel data, not enough bytes"); - // + // // Load data for frame and decompress it byte *data = new byte[celDataSize]; stream.read(data, celDataSize); @@ -678,7 +677,7 @@ void ImageFile3DO::load3DOCelRoomData(Common::SeekableReadStream &stream) { if (ccbFlags & 0x200) // bit 9 ccbFlags_compressed = true; - + // PRE0 first 3 bits define how many bits per encoded pixel are used ccbPRE0_bitsPerPixel = imagefile3DO_cel_bitsPerPixelLookupTable[ccbPRE0 & 0x07]; if (!ccbPRE0_bitsPerPixel) @@ -708,7 +707,7 @@ void ImageFile3DO::load3DOCelRoomData(Common::SeekableReadStream &stream) { stream.read(celDataPtr, celDataSize); streamLeft -= celDataSize; - + // Set up frame { ImageFrame imageFrame; @@ -955,59 +954,57 @@ void ImageFile3DO::loadFont(Common::SeekableReadStream &stream) { for (curChar = 33; curChar < header_charCount; curChar++) { // create frame - { - ImageFrame imageFrame; - - imageFrame._width = widthTablePtr[curChar]; - imageFrame._height = header_fontHeight; - imageFrame._paletteBase = 0; - imageFrame._offset.x = 0; - imageFrame._offset.y = 0; - imageFrame._rleEncoded = false; - imageFrame._size = 0; - - // Extract pixels - imageFrame._frame.create(imageFrame._width, imageFrame._height, Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0)); - uint16 *dest = (uint16 *)imageFrame._frame.getPixels(); - Common::fill(dest, dest + imageFrame._width * imageFrame._height, 0); - - curCharHeightLeft = header_fontHeight; - while (curCharHeightLeft) { - curCharWidthLeft = widthTablePtr[curChar]; - curBitsPtr = curBitsLinePtr; - curBitsLeft = 8; - curPosX = 0; - - while (curCharWidthLeft) { - if (!(curPosX & 1)) { - curBits = *curBitsPtr >> 4; - } else { - curBits = *curBitsPtr & 0x0F; - curBitsPtr++; - } - // doing this properly is complicated - // the 3DO has built-in anti-aliasing - // this here at least results in somewhat readable text - // TODO: make it better - if (curBits) { - curBitsReversed = (curBits >> 3) | ((curBits & 0x04) >> 1) | ((curBits & 0x02) << 1) | ((curBits & 0x01) << 3); - curBits = 20 - curBits; - } - - byte curIntensity = curBits; - *dest = (curIntensity << 11) | (curIntensity << 6) | curIntensity; - dest++; - - curCharWidthLeft--; - curPosX++; + ImageFrame imageFrame; + + imageFrame._width = widthTablePtr[curChar]; + imageFrame._height = header_fontHeight; + imageFrame._paletteBase = 0; + imageFrame._offset.x = 0; + imageFrame._offset.y = 0; + imageFrame._rleEncoded = false; + imageFrame._size = 0; + + // Extract pixels + imageFrame._frame.create(imageFrame._width, imageFrame._height, Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0)); + uint16 *dest = (uint16 *)imageFrame._frame.getPixels(); + Common::fill(dest, dest + imageFrame._width * imageFrame._height, 0); + + curCharHeightLeft = header_fontHeight; + while (curCharHeightLeft) { + curCharWidthLeft = widthTablePtr[curChar]; + curBitsPtr = curBitsLinePtr; + curBitsLeft = 8; + curPosX = 0; + + while (curCharWidthLeft) { + if (!(curPosX & 1)) { + curBits = *curBitsPtr >> 4; + } else { + curBits = *curBitsPtr & 0x0F; + curBitsPtr++; + } + // doing this properly is complicated + // the 3DO has built-in anti-aliasing + // this here at least results in somewhat readable text + // TODO: make it better + if (curBits) { + curBitsReversed = (curBits >> 3) | ((curBits & 0x04) >> 1) | ((curBits & 0x02) << 1) | ((curBits & 0x01) << 3); + curBits = 20 - curBits; } - curCharHeightLeft--; - curBitsLinePtr += header_bytesPerLine; + byte curIntensity = curBits; + *dest = (curIntensity << 11) | (curIntensity << 6) | curIntensity; + dest++; + + curCharWidthLeft--; + curPosX++; } - push_back(imageFrame); + curCharHeightLeft--; + curBitsLinePtr += header_bytesPerLine; } + + push_back(imageFrame); } // Warning below being used to silence unused variable warnings for now @@ -1026,6 +1023,7 @@ StreamingImageFile::StreamingImageFile() { _scaleVal = 0; _zPlacement = 0; _compressed = false; + _active = false; } StreamingImageFile::~StreamingImageFile() { @@ -1036,18 +1034,24 @@ void StreamingImageFile::load(Common::SeekableReadStream *stream, bool compresse _stream = stream; _compressed = compressed; _frameNumber = -1; + _active = true; } void StreamingImageFile::close() { delete _stream; _stream = nullptr; _frameNumber = -1; + _active = false; + _imageFrame._frame.free(); } -void StreamingImageFile::getNextFrame() { +bool StreamingImageFile::getNextFrame() { // Don't proceed if we're already at the end of the stream - if (_stream->pos() >= _stream->size()) - return; + assert(_stream); + if (_stream->pos() >= _stream->size()) { + _active = false; + return false; + } // Increment frame number ++_frameNumber; @@ -1070,6 +1074,9 @@ void StreamingImageFile::getNextFrame() { _imageFrame._size = frameStream->readUint16LE() - 11; _imageFrame._rleMarker = frameStream->readByte(); + // Free the previous frame + _imageFrame._frame.free(); + // Decode the frame if (_compressed) { delete frameStream; @@ -1080,6 +1087,8 @@ void StreamingImageFile::getNextFrame() { _imageFrame.decompressFrame(_buffer + 11, true); delete[] data; } + + return true; } } // End of namespace Sherlock |