SHERLOCK: Merged decompression code into Resources class
This commit is contained in:
parent
8c7f5bf92f
commit
052e04c005
7 changed files with 77 additions and 132 deletions
|
@ -1,80 +0,0 @@
|
||||||
/* ScummVM - Graphic Adventure Engine
|
|
||||||
*
|
|
||||||
* ScummVM is the legal property of its developers, whose names
|
|
||||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
|
||||||
* file distributed with this source distribution.
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU General Public License
|
|
||||||
* as published by the Free Software Foundation; either version 2
|
|
||||||
* of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "sherlock/decompress.h"
|
|
||||||
|
|
||||||
namespace Sherlock {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Decompresses an LZW compressed resource. If no outSize is specified, it will
|
|
||||||
* decompress the entire resource. If, however, an explicit size is specified,
|
|
||||||
* then it means we're already within a resource, and only want to decompress
|
|
||||||
* part of it.
|
|
||||||
*/
|
|
||||||
Common::SeekableReadStream *decompressLZ(Common::SeekableReadStream &source, int32 outSize) {
|
|
||||||
if (outSize == -1) {
|
|
||||||
source.seek(4);
|
|
||||||
outSize = source.readSint32LE();
|
|
||||||
}
|
|
||||||
|
|
||||||
byte lzWindow[4096];
|
|
||||||
uint16 lzWindowPos;
|
|
||||||
uint16 cmd;
|
|
||||||
|
|
||||||
byte *outBuffer = (byte *)malloc(outSize);
|
|
||||||
byte *outBufferEnd = outBuffer + outSize;
|
|
||||||
Common::MemoryReadStream *outS = new Common::MemoryReadStream(outBuffer, outSize, DisposeAfterUse::YES);
|
|
||||||
|
|
||||||
memset(lzWindow, 0xFF, 0xFEE);
|
|
||||||
lzWindowPos = 0xFEE;
|
|
||||||
cmd = 0;
|
|
||||||
|
|
||||||
do {
|
|
||||||
cmd >>= 1;
|
|
||||||
if (!(cmd & 0x100))
|
|
||||||
cmd = source.readByte() | 0xFF00;
|
|
||||||
|
|
||||||
if (cmd & 1) {
|
|
||||||
byte literal = source.readByte();
|
|
||||||
*outBuffer++ = literal;
|
|
||||||
lzWindow[lzWindowPos] = literal;
|
|
||||||
lzWindowPos = (lzWindowPos + 1) & 0x0FFF;
|
|
||||||
} else {
|
|
||||||
int copyPos, copyLen;
|
|
||||||
copyPos = source.readByte();
|
|
||||||
copyLen = source.readByte();
|
|
||||||
copyPos = copyPos | ((copyLen & 0xF0) << 4);
|
|
||||||
copyLen = (copyLen & 0x0F) + 3;
|
|
||||||
while (copyLen--) {
|
|
||||||
byte literal = lzWindow[copyPos];
|
|
||||||
copyPos = (copyPos + 1) & 0x0FFF;
|
|
||||||
*outBuffer++ = literal;
|
|
||||||
lzWindow[lzWindowPos] = literal;
|
|
||||||
lzWindowPos = (lzWindowPos + 1) & 0x0FFF;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} while (outBuffer < outBufferEnd);
|
|
||||||
|
|
||||||
return outS;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Sherlock
|
|
|
@ -1,36 +0,0 @@
|
||||||
/* ScummVM - Graphic Adventure Engine
|
|
||||||
*
|
|
||||||
* ScummVM is the legal property of its developers, whose names
|
|
||||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
|
||||||
* file distributed with this source distribution.
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU General Public License
|
|
||||||
* as published by the Free Software Foundation; either version 2
|
|
||||||
* of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef SHERLOCK_DECOMPRESS_H
|
|
||||||
#define SHERLOCK_DECOMPRESS_H
|
|
||||||
|
|
||||||
#include "common/memstream.h"
|
|
||||||
|
|
||||||
namespace Sherlock {
|
|
||||||
|
|
||||||
#include "common/stream.h"
|
|
||||||
|
|
||||||
Common::SeekableReadStream *decompressLZ(Common::SeekableReadStream &source, int32 outSize = -1);
|
|
||||||
|
|
||||||
} // namespace Sherlock
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -5,7 +5,6 @@ MODULE_OBJS = \
|
||||||
scalpel/scalpel.o \
|
scalpel/scalpel.o \
|
||||||
tattoo/tattoo.o \
|
tattoo/tattoo.o \
|
||||||
animation.o \
|
animation.o \
|
||||||
decompress.o \
|
|
||||||
debugger.o \
|
debugger.o \
|
||||||
detection.o \
|
detection.o \
|
||||||
events.o \
|
events.o \
|
||||||
|
|
|
@ -21,14 +21,14 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "sherlock/resources.h"
|
#include "sherlock/resources.h"
|
||||||
#include "sherlock/decompress.h"
|
|
||||||
#include "sherlock/screen.h"
|
#include "sherlock/screen.h"
|
||||||
#include "sherlock/sherlock.h"
|
#include "sherlock/sherlock.h"
|
||||||
#include "common/debug.h"
|
#include "common/debug.h"
|
||||||
|
#include "common/memstream.h"
|
||||||
|
|
||||||
namespace Sherlock {
|
namespace Sherlock {
|
||||||
|
|
||||||
Cache::Cache() {
|
Cache::Cache(SherlockEngine *vm): _vm(vm) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -76,7 +76,7 @@ void Cache::load(const Common::String &name, Common::SeekableReadStream &stream)
|
||||||
// Check whether the file is compressed
|
// Check whether the file is compressed
|
||||||
if (signature == MKTAG('L', 'Z', 'V', 26)) {
|
if (signature == MKTAG('L', 'Z', 'V', 26)) {
|
||||||
// It's compressed, so decompress the file and store it's data in the cache entry
|
// It's compressed, so decompress the file and store it's data in the cache entry
|
||||||
Common::SeekableReadStream *decompressed = decompressLZ(stream);
|
Common::SeekableReadStream *decompressed = _vm->_res->decompressLZ(stream);
|
||||||
cacheEntry.resize(decompressed->size());
|
cacheEntry.resize(decompressed->size());
|
||||||
decompressed->read(&cacheEntry[0], decompressed->size());
|
decompressed->read(&cacheEntry[0], decompressed->size());
|
||||||
|
|
||||||
|
@ -99,7 +99,7 @@ Common::SeekableReadStream *Cache::get(const Common::String &filename) const {
|
||||||
|
|
||||||
/*----------------------------------------------------------------*/
|
/*----------------------------------------------------------------*/
|
||||||
|
|
||||||
Resources::Resources() {
|
Resources::Resources(SherlockEngine *vm): _vm(vm), _cache(vm) {
|
||||||
_resourceIndex = -1;
|
_resourceIndex = -1;
|
||||||
|
|
||||||
addToCache("vgs.lib");
|
addToCache("vgs.lib");
|
||||||
|
@ -404,4 +404,62 @@ void ImageFile::decompressFrame(ImageFrame &frame, const byte *src) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decompress an LZW compressed resource
|
||||||
|
*/
|
||||||
|
Common::SeekableReadStream *Resources::decompressLZ(Common::SeekableReadStream &source) {
|
||||||
|
if (_vm->getGameID() == GType_SerratedScalpel) {
|
||||||
|
uint32 id = source.readUint32BE();
|
||||||
|
assert(id == MKTAG('L', 'Z', 'V', 0x1A));
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 size = source.readUint32LE();
|
||||||
|
return decompressLZ(source, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decompresses an LZW block of data with a specified output size
|
||||||
|
*/
|
||||||
|
Common::SeekableReadStream *Resources::decompressLZ(Common::SeekableReadStream &source, uint32 outSize) {
|
||||||
|
byte lzWindow[4096];
|
||||||
|
uint16 lzWindowPos;
|
||||||
|
uint16 cmd;
|
||||||
|
|
||||||
|
byte *outBuffer = (byte *)malloc(outSize);
|
||||||
|
byte *outBufferEnd = outBuffer + outSize;
|
||||||
|
Common::MemoryReadStream *outS = new Common::MemoryReadStream(outBuffer, outSize, DisposeAfterUse::YES);
|
||||||
|
|
||||||
|
memset(lzWindow, 0xFF, 0xFEE);
|
||||||
|
lzWindowPos = 0xFEE;
|
||||||
|
cmd = 0;
|
||||||
|
|
||||||
|
do {
|
||||||
|
cmd >>= 1;
|
||||||
|
if (!(cmd & 0x100))
|
||||||
|
cmd = source.readByte() | 0xFF00;
|
||||||
|
|
||||||
|
if (cmd & 1) {
|
||||||
|
byte literal = source.readByte();
|
||||||
|
*outBuffer++ = literal;
|
||||||
|
lzWindow[lzWindowPos] = literal;
|
||||||
|
lzWindowPos = (lzWindowPos + 1) & 0x0FFF;
|
||||||
|
} else {
|
||||||
|
int copyPos, copyLen;
|
||||||
|
copyPos = source.readByte();
|
||||||
|
copyLen = source.readByte();
|
||||||
|
copyPos = copyPos | ((copyLen & 0xF0) << 4);
|
||||||
|
copyLen = (copyLen & 0x0F) + 3;
|
||||||
|
while (copyLen--) {
|
||||||
|
byte literal = lzWindow[copyPos];
|
||||||
|
copyPos = (copyPos + 1) & 0x0FFF;
|
||||||
|
*outBuffer++ = literal;
|
||||||
|
lzWindow[lzWindowPos] = literal;
|
||||||
|
lzWindowPos = (lzWindowPos + 1) & 0x0FFF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while (outBuffer < outBufferEnd);
|
||||||
|
|
||||||
|
return outS;
|
||||||
|
}
|
||||||
|
|
||||||
} // End of namespace Sherlock
|
} // End of namespace Sherlock
|
||||||
|
|
|
@ -52,9 +52,10 @@ class SherlockEngine;
|
||||||
|
|
||||||
class Cache {
|
class Cache {
|
||||||
private:
|
private:
|
||||||
|
SherlockEngine *_vm;
|
||||||
CacheHash _resources;
|
CacheHash _resources;
|
||||||
public:
|
public:
|
||||||
Cache();
|
Cache(SherlockEngine *_vm);
|
||||||
|
|
||||||
bool isCached(const Common::String &filename) const;
|
bool isCached(const Common::String &filename) const;
|
||||||
|
|
||||||
|
@ -66,13 +67,14 @@ public:
|
||||||
|
|
||||||
class Resources {
|
class Resources {
|
||||||
private:
|
private:
|
||||||
|
SherlockEngine *_vm;
|
||||||
Cache _cache;
|
Cache _cache;
|
||||||
LibraryIndexes _indexes;
|
LibraryIndexes _indexes;
|
||||||
int _resourceIndex;
|
int _resourceIndex;
|
||||||
|
|
||||||
void loadLibraryIndex(const Common::String &libFilename, Common::SeekableReadStream *stream);
|
void loadLibraryIndex(const Common::String &libFilename, Common::SeekableReadStream *stream);
|
||||||
public:
|
public:
|
||||||
Resources();
|
Resources(SherlockEngine *vm);
|
||||||
|
|
||||||
void addToCache(const Common::String &filename);
|
void addToCache(const Common::String &filename);
|
||||||
void addToCache(const Common::String &filename, const Common::String &libFilename);
|
void addToCache(const Common::String &filename, const Common::String &libFilename);
|
||||||
|
@ -86,6 +88,9 @@ public:
|
||||||
bool exists(const Common::String &filename) const;
|
bool exists(const Common::String &filename) const;
|
||||||
|
|
||||||
int resourceIndex() const;
|
int resourceIndex() const;
|
||||||
|
|
||||||
|
static Common::SeekableReadStream *decompressLZ(Common::SeekableReadStream &source, uint32 outSize);
|
||||||
|
Common::SeekableReadStream *decompressLZ(Common::SeekableReadStream &source);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ImageFrame {
|
struct ImageFrame {
|
||||||
|
|
|
@ -23,7 +23,6 @@
|
||||||
#include "sherlock/scene.h"
|
#include "sherlock/scene.h"
|
||||||
#include "sherlock/sherlock.h"
|
#include "sherlock/sherlock.h"
|
||||||
#include "sherlock/scalpel/scalpel.h"
|
#include "sherlock/scalpel/scalpel.h"
|
||||||
#include "sherlock/decompress.h"
|
|
||||||
|
|
||||||
namespace Sherlock {
|
namespace Sherlock {
|
||||||
|
|
||||||
|
@ -274,7 +273,7 @@ bool Scene::loadScene(const Common::String &filename) {
|
||||||
|
|
||||||
// Read information
|
// Read information
|
||||||
Common::SeekableReadStream *infoStream = !_lzwMode ? rrmStream :
|
Common::SeekableReadStream *infoStream = !_lzwMode ? rrmStream :
|
||||||
decompressLZ(*rrmStream, bgHeader._numImages * 569 +
|
Resources::decompressLZ(*rrmStream, bgHeader._numImages * 569 +
|
||||||
bgHeader._descSize + bgHeader._seqSize);
|
bgHeader._descSize + bgHeader._seqSize);
|
||||||
|
|
||||||
_bgShapes.resize(bgHeader._numStructs);
|
_bgShapes.resize(bgHeader._numStructs);
|
||||||
|
@ -302,7 +301,7 @@ bool Scene::loadScene(const Common::String &filename) {
|
||||||
|
|
||||||
// Read in the image data
|
// Read in the image data
|
||||||
Common::SeekableReadStream *imageStream = _lzwMode ?
|
Common::SeekableReadStream *imageStream = _lzwMode ?
|
||||||
decompressLZ(*rrmStream, bgInfo[idx]._filesize) :
|
Resources::decompressLZ(*rrmStream, bgInfo[idx]._filesize) :
|
||||||
rrmStream->readStream(bgInfo[idx]._filesize);
|
rrmStream->readStream(bgInfo[idx]._filesize);
|
||||||
|
|
||||||
_images[idx + 1]._images = new ImageFile(*imageStream);
|
_images[idx + 1]._images = new ImageFile(*imageStream);
|
||||||
|
@ -331,7 +330,7 @@ bool Scene::loadScene(const Common::String &filename) {
|
||||||
_cAnim.clear();
|
_cAnim.clear();
|
||||||
if (bgHeader._numcAnimations) {
|
if (bgHeader._numcAnimations) {
|
||||||
Common::SeekableReadStream *canimStream = _lzwMode ?
|
Common::SeekableReadStream *canimStream = _lzwMode ?
|
||||||
decompressLZ(*rrmStream, 65 * bgHeader._numcAnimations) :
|
Resources::decompressLZ(*rrmStream, 65 * bgHeader._numcAnimations) :
|
||||||
rrmStream->readStream(65 * bgHeader._numcAnimations);
|
rrmStream->readStream(65 * bgHeader._numcAnimations);
|
||||||
|
|
||||||
_cAnim.resize(bgHeader._numcAnimations);
|
_cAnim.resize(bgHeader._numcAnimations);
|
||||||
|
@ -344,7 +343,7 @@ bool Scene::loadScene(const Common::String &filename) {
|
||||||
// Read in the room bounding areas
|
// Read in the room bounding areas
|
||||||
int size = rrmStream->readUint16LE();
|
int size = rrmStream->readUint16LE();
|
||||||
Common::SeekableReadStream *boundsStream = !_lzwMode ? rrmStream :
|
Common::SeekableReadStream *boundsStream = !_lzwMode ? rrmStream :
|
||||||
decompressLZ(*rrmStream, size);
|
Resources::decompressLZ(*rrmStream, size);
|
||||||
|
|
||||||
_zones.resize(size / 10);
|
_zones.resize(size / 10);
|
||||||
for (uint idx = 0; idx < _zones.size(); ++idx) {
|
for (uint idx = 0; idx < _zones.size(); ++idx) {
|
||||||
|
@ -371,7 +370,7 @@ bool Scene::loadScene(const Common::String &filename) {
|
||||||
// Read in the walk data
|
// Read in the walk data
|
||||||
size = rrmStream->readUint16LE();
|
size = rrmStream->readUint16LE();
|
||||||
Common::SeekableReadStream *walkStream = !_lzwMode ? rrmStream :
|
Common::SeekableReadStream *walkStream = !_lzwMode ? rrmStream :
|
||||||
decompressLZ(*rrmStream, size);
|
Resources::decompressLZ(*rrmStream, size);
|
||||||
|
|
||||||
_walkData.resize(size);
|
_walkData.resize(size);
|
||||||
walkStream->read(&_walkData[0], size);
|
walkStream->read(&_walkData[0], size);
|
||||||
|
@ -408,7 +407,7 @@ bool Scene::loadScene(const Common::String &filename) {
|
||||||
|
|
||||||
// Read in the background
|
// Read in the background
|
||||||
Common::SeekableReadStream *bgStream = !_lzwMode ? rrmStream :
|
Common::SeekableReadStream *bgStream = !_lzwMode ? rrmStream :
|
||||||
decompressLZ(*rrmStream, SHERLOCK_SCREEN_WIDTH * SHERLOCK_SCENE_HEIGHT);
|
Resources::decompressLZ(*rrmStream, SHERLOCK_SCREEN_WIDTH * SHERLOCK_SCENE_HEIGHT);
|
||||||
|
|
||||||
bgStream->read(screen._backBuffer1.getPixels(), SHERLOCK_SCREEN_WIDTH * SHERLOCK_SCENE_HEIGHT);
|
bgStream->read(screen._backBuffer1.getPixels(), SHERLOCK_SCREEN_WIDTH * SHERLOCK_SCENE_HEIGHT);
|
||||||
|
|
||||||
|
@ -982,7 +981,7 @@ int Scene::startCAnim(int cAnimNum, int playRate) {
|
||||||
|
|
||||||
// Load the canimation into the cache
|
// Load the canimation into the cache
|
||||||
Common::SeekableReadStream *imgStream = !_lzwMode ? rrmStream->readStream(cAnim._size) :
|
Common::SeekableReadStream *imgStream = !_lzwMode ? rrmStream->readStream(cAnim._size) :
|
||||||
decompressLZ(*rrmStream, cAnim._size);
|
Resources::decompressLZ(*rrmStream, cAnim._size);
|
||||||
res.addToCache(fname, *imgStream);
|
res.addToCache(fname, *imgStream);
|
||||||
|
|
||||||
delete imgStream;
|
delete imgStream;
|
||||||
|
|
|
@ -79,7 +79,7 @@ void SherlockEngine::initialize() {
|
||||||
ImageFile::setVm(this);
|
ImageFile::setVm(this);
|
||||||
Object::setVm(this);
|
Object::setVm(this);
|
||||||
Sprite::setVm(this);
|
Sprite::setVm(this);
|
||||||
_res = new Resources();
|
_res = new Resources(this);
|
||||||
_animation = new Animation(this);
|
_animation = new Animation(this);
|
||||||
_debugger = new Debugger(this);
|
_debugger = new Debugger(this);
|
||||||
_events = new Events(this);
|
_events = new Events(this);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue