SHERLOCK: Implement ImageFile nibble mode, fixes for scene data loading
This commit is contained in:
parent
e444d989bb
commit
840bd862b7
6 changed files with 40 additions and 39 deletions
|
@ -408,12 +408,11 @@ void Object::setVm(SherlockEngine *vm) {
|
|||
* Load the object data from the passed stream
|
||||
*/
|
||||
void Object::synchronize(Common::SeekableReadStream &s) {
|
||||
char buffer[50];
|
||||
|
||||
char buffer[12];
|
||||
s.read(buffer, 12);
|
||||
_name = Common::String(buffer);
|
||||
s.read(buffer, 41);
|
||||
_description = Common::String(buffer);
|
||||
|
||||
s.read(_description, 41);
|
||||
|
||||
_examine.clear();
|
||||
_sequences = nullptr;
|
||||
|
@ -421,8 +420,8 @@ void Object::synchronize(Common::SeekableReadStream &s) {
|
|||
_imageFrame = nullptr;
|
||||
|
||||
s.skip(4);
|
||||
_sequenceOffset = s.readUint32LE();
|
||||
s.seek(8, SEEK_CUR);
|
||||
_sequenceOffset = s.readUint16LE();
|
||||
s.seek(10, SEEK_CUR);
|
||||
|
||||
_walkCount = s.readByte();
|
||||
_allow = s.readByte();
|
||||
|
|
|
@ -152,7 +152,7 @@ public:
|
|||
static void setVm(SherlockEngine *vm);
|
||||
public:
|
||||
Common::String _name; // Name
|
||||
Common::String _description; // Description
|
||||
char _description[41]; // Description lines
|
||||
Common::String _examine; // Examine in-depth description
|
||||
int _sequenceOffset;
|
||||
uint8 *_sequences; // Holds animation sequences
|
||||
|
|
|
@ -297,13 +297,13 @@ void ImageFile::load(Common::SeekableReadStream &stream, bool skipPalette) {
|
|||
ImageFrame frame;
|
||||
frame._width = stream.readUint16LE() + 1;
|
||||
frame._height = stream.readUint16LE() + 1;
|
||||
frame._flags = stream.readByte();
|
||||
frame._paletteBase = stream.readByte();
|
||||
frame._offset.x = stream.readUint16LE();
|
||||
frame._offset.y = stream.readByte();
|
||||
|
||||
frame._rleEncoded = !skipPalette && (frame._offset.x == 1);
|
||||
|
||||
if (frame._flags & 0xFF) {
|
||||
if (frame._paletteBase) {
|
||||
// Nibble packed frame data
|
||||
frame._size = (frame._width * frame._height) / 2;
|
||||
} else if (frame._rleEncoded) {
|
||||
|
@ -351,8 +351,13 @@ void ImageFile::loadPalette(Common::SeekableReadStream &stream) {
|
|||
void ImageFile::decompressFrame(ImageFrame &frame, const byte *src) {
|
||||
frame._frame.create(frame._width, frame._height, Graphics::PixelFormat::createFormatCLUT8());
|
||||
|
||||
if (frame._flags & 0xFF) {
|
||||
error("TODO: ImageFile::decompressFrame() 4-bits/pixel\n");
|
||||
if (frame._paletteBase) {
|
||||
// Nibble-packed
|
||||
byte *pDest = (byte *)frame._frame.getPixels();
|
||||
for (int idx = 0; idx < frame._size; ++idx, ++src) {
|
||||
*pDest++ = *src & 0xF;
|
||||
*pDest++ = (*src >> 4);
|
||||
}
|
||||
} else if (frame._rleEncoded) {
|
||||
// RLE encoded
|
||||
byte *dst = (byte *)frame._frame.getPixels();
|
||||
|
|
|
@ -91,7 +91,7 @@ public:
|
|||
struct ImageFrame {
|
||||
uint32 _size;
|
||||
uint16 _width, _height;
|
||||
int _flags;
|
||||
int _paletteBase;
|
||||
bool _rleEncoded;
|
||||
Common::Point _offset;
|
||||
byte _rleMarker;
|
||||
|
|
|
@ -212,7 +212,7 @@ void Scene::freeScene() {
|
|||
_walkData.clear();
|
||||
_cAnim.clear();
|
||||
_bgShapes.clear();
|
||||
_roomBounds.clear();
|
||||
_bounds.clear();
|
||||
_canimShapes.clear();
|
||||
|
||||
for (uint idx = 0; idx < _images.size(); ++idx)
|
||||
|
@ -241,8 +241,8 @@ bool Scene::loadScene(const Common::String &filename) {
|
|||
_ongoingCans = 0;
|
||||
|
||||
// Reset the list of walkable areas
|
||||
_roomBounds.clear();
|
||||
_roomBounds.push_back(Common::Rect(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT));
|
||||
_bounds.clear();
|
||||
_bounds.push_back(Common::Rect(0, 0, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT));
|
||||
|
||||
_descText.clear();
|
||||
_comments = "";
|
||||
|
@ -281,7 +281,7 @@ bool Scene::loadScene(const Common::String &filename) {
|
|||
decompressLZ(*rrmStream, bgHeader._numImages * 569 +
|
||||
bgHeader._descSize + bgHeader._seqSize);
|
||||
|
||||
_bgShapes.resize(bgHeader._numStructs + 1);
|
||||
_bgShapes.resize(bgHeader._numStructs);
|
||||
for (int idx = 0; idx < bgHeader._numStructs; ++idx)
|
||||
_bgShapes[idx].synchronize(*infoStream);
|
||||
|
||||
|
@ -305,13 +305,13 @@ bool Scene::loadScene(const Common::String &filename) {
|
|||
_images[idx + 1]._maxFrames = bgInfo[idx]._maxFrames;
|
||||
|
||||
// Read in the image data
|
||||
Common::SeekableReadStream *imageStream = !_lzwMode ? rrmStream :
|
||||
decompressLZ(*rrmStream, bgInfo[idx]._filesize);
|
||||
Common::SeekableReadStream *imageStream = _lzwMode ?
|
||||
decompressLZ(*rrmStream, bgInfo[idx]._filesize) :
|
||||
rrmStream->readStream(bgInfo[idx]._filesize);
|
||||
|
||||
_images[idx + 1]._images = new ImageFile(*imageStream);
|
||||
|
||||
if (_lzwMode)
|
||||
delete imageStream;
|
||||
delete imageStream;
|
||||
}
|
||||
|
||||
// Set up the bgShapes
|
||||
|
@ -331,44 +331,41 @@ bool Scene::loadScene(const Common::String &filename) {
|
|||
&(*_bgShapes[idx]._images)[0];
|
||||
}
|
||||
|
||||
// Set up end of list
|
||||
_bgShapes[bgHeader._numStructs]._sequences = &_sequenceBuffer[0] + bgHeader._seqSize;
|
||||
_bgShapes[bgHeader._numStructs]._examine = nullptr;
|
||||
|
||||
// Load in cAnim list
|
||||
Common::SeekableReadStream *canimStream = !_lzwMode ? rrmStream :
|
||||
decompressLZ(*rrmStream, 65 * bgHeader._numcAnimations);
|
||||
Common::SeekableReadStream *canimStream = _lzwMode ?
|
||||
decompressLZ(*rrmStream, 65 * bgHeader._numcAnimations) :
|
||||
rrmStream->readStream(65 * bgHeader._numcAnimations);
|
||||
|
||||
_cAnim.resize(bgHeader._numcAnimations);
|
||||
for (uint idx = 0; idx < _cAnim.size(); ++idx)
|
||||
_cAnim[idx].synchronize(*canimStream);
|
||||
|
||||
if (_lzwMode)
|
||||
delete canimStream;
|
||||
delete canimStream;
|
||||
|
||||
// Read in the room bounding areas
|
||||
int size = rrmStream->readUint16LE();
|
||||
Common::SeekableReadStream *boundsStream = !_lzwMode ? rrmStream :
|
||||
decompressLZ(*rrmStream, size);
|
||||
|
||||
_roomBounds.resize(size / 10);
|
||||
for (uint idx = 0; idx < _roomBounds.size(); ++idx) {
|
||||
_roomBounds[idx].left = boundsStream->readSint16LE();
|
||||
_roomBounds[idx].top = boundsStream->readSint16LE();
|
||||
_roomBounds[idx].setWidth(boundsStream->readSint16LE());
|
||||
_roomBounds[idx].setHeight(boundsStream->readSint16LE());
|
||||
_bounds.resize(size / 10);
|
||||
for (uint idx = 0; idx < _bounds.size(); ++idx) {
|
||||
_bounds[idx].left = boundsStream->readSint16LE();
|
||||
_bounds[idx].top = boundsStream->readSint16LE();
|
||||
_bounds[idx].setWidth(boundsStream->readSint16LE());
|
||||
_bounds[idx].setHeight(boundsStream->readSint16LE());
|
||||
boundsStream->skip(2); // Skip unused scene number field
|
||||
}
|
||||
|
||||
if (_lzwMode)
|
||||
delete boundsStream;
|
||||
|
||||
// Back at version byte, so skip over it
|
||||
rrmStream->skip(1);
|
||||
// Ensure we've reached the path version byte
|
||||
if (rrmStream->readByte() != 254)
|
||||
error("Invalid scene path data");
|
||||
|
||||
// Load the walk directory
|
||||
for (int idx1 = 0; idx1 < MAX_ZONES; ++idx1) {
|
||||
for (int idx2 = 0; idx2 < MAX_ZONES; ++idx2)
|
||||
for (uint idx1 = 0; idx1 < _bounds.size(); ++idx1) {
|
||||
for (uint idx2 = 0; idx2 < _bounds.size(); ++idx2)
|
||||
_walkDirectory[idx1][idx2] = rrmStream->readSint16LE();
|
||||
}
|
||||
|
||||
|
|
|
@ -157,7 +157,7 @@ public:
|
|||
int _invGraphicItems;
|
||||
Common::String _comments;
|
||||
Common::Array<char> _descText;
|
||||
Common::Array<Common::Rect> _roomBounds;
|
||||
Common::Array<Common::Rect> _bounds;
|
||||
Common::Array<Object> _bgShapes;
|
||||
Common::Array<CAnim> _cAnim;
|
||||
Common::Array<byte> _sequenceBuffer;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue