mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-16 22:58:09 +00:00
SHERLOCK: 3DO: support images inside room files
This commit is contained in:
parent
7ff3336a65
commit
9ce2cbca9f
@ -255,8 +255,8 @@ ImageFile3DO::ImageFile3DO(const Common::String &name) {
|
|||||||
delete dataStream;
|
delete dataStream;
|
||||||
}
|
}
|
||||||
|
|
||||||
ImageFile3DO::ImageFile3DO(Common::SeekableReadStream &stream, bool roomData) {
|
ImageFile3DO::ImageFile3DO(Common::SeekableReadStream &stream, bool isRoomData) {
|
||||||
load(stream, false);
|
load(stream, isRoomData);
|
||||||
}
|
}
|
||||||
|
|
||||||
ImageFile3DO::~ImageFile3DO() {
|
ImageFile3DO::~ImageFile3DO() {
|
||||||
@ -265,9 +265,15 @@ ImageFile3DO::~ImageFile3DO() {
|
|||||||
// (*this)[idx]._frame.free();
|
// (*this)[idx]._frame.free();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ImageFile3DO::load(Common::SeekableReadStream &stream, bool roomData) {
|
void ImageFile3DO::load(Common::SeekableReadStream &stream, bool isRoomData) {
|
||||||
uint32 headerId = stream.readUint32BE();
|
uint32 headerId = 0;
|
||||||
|
|
||||||
|
if (isRoomData) {
|
||||||
|
load3DOCelRoomData(stream);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
headerId = stream.readUint32BE();
|
||||||
assert(!stream.eos());
|
assert(!stream.eos());
|
||||||
|
|
||||||
// Seek back to the start
|
// Seek back to the start
|
||||||
@ -522,6 +528,87 @@ void ImageFile3DO::load3DOCelFile(Common::SeekableReadStream &stream) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Reads 3DO .cel data (room file format)
|
||||||
|
void ImageFile3DO::load3DOCelRoomData(Common::SeekableReadStream &stream) {
|
||||||
|
int streamSize = stream.size();
|
||||||
|
uint16 roomDataHeader_size = 0;
|
||||||
|
|
||||||
|
ImageFrame imageFrame;
|
||||||
|
|
||||||
|
// CCB chunk (cel control block)
|
||||||
|
uint32 ccbFlags = 0;
|
||||||
|
bool ccbFlags_compressed = false;
|
||||||
|
uint16 ccbPPMP0 = 0;
|
||||||
|
uint16 ccbPPMP1 = 0;
|
||||||
|
uint32 ccbPRE0 = 0;
|
||||||
|
byte ccbPRE0_bitsPerPixel = 0;
|
||||||
|
uint32 ccbPRE1 = 0;
|
||||||
|
uint32 ccbWidth = 0;
|
||||||
|
uint32 ccbHeight = 0;
|
||||||
|
// cel data
|
||||||
|
uint32 celDataSize = 0;
|
||||||
|
byte *celDataPtr = NULL;
|
||||||
|
|
||||||
|
while (stream.pos() < streamSize) {
|
||||||
|
ImageFrame frame;
|
||||||
|
|
||||||
|
// 3DO sherlock holmes room data header
|
||||||
|
stream.skip(4); // Possibly UINT16 width, UINT16 height?!?!
|
||||||
|
roomDataHeader_size = stream.readUint16BE();
|
||||||
|
stream.skip(2); // seems to be filler
|
||||||
|
|
||||||
|
// 3DO raw cel control block
|
||||||
|
ccbFlags = stream.readUint32BE();
|
||||||
|
stream.skip(3 * 4); // skip over 3 pointer fields, which are used in memory only by 3DO hardware
|
||||||
|
stream.skip(8 * 4); // skip over 8 offset fields
|
||||||
|
ccbPPMP0 = stream.readUint16BE();
|
||||||
|
ccbPPMP1 = stream.readUint16BE();
|
||||||
|
ccbPRE0 = stream.readUint32BE();
|
||||||
|
ccbPRE1 = stream.readUint32BE();
|
||||||
|
ccbWidth = stream.readUint32BE();
|
||||||
|
ccbHeight = stream.readUint32BE();
|
||||||
|
|
||||||
|
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)
|
||||||
|
error("load3DOCelRoomData: Invalid CCB PRE0 bits per pixel");
|
||||||
|
|
||||||
|
if (ccbPRE0_bitsPerPixel != 16) {
|
||||||
|
// We currently support 16-bits per pixel in here
|
||||||
|
error("load3DOCelRoomData: bits per pixel < 16?!?!?");
|
||||||
|
}
|
||||||
|
|
||||||
|
// cel data follows
|
||||||
|
assert(roomDataHeader_size > 68);
|
||||||
|
// size field does not include the 8 byte header
|
||||||
|
celDataSize = roomDataHeader_size - 68;
|
||||||
|
|
||||||
|
// read data into memory
|
||||||
|
celDataPtr = new byte[celDataSize];
|
||||||
|
|
||||||
|
stream.read(celDataPtr, celDataSize);
|
||||||
|
|
||||||
|
// Set up frame
|
||||||
|
imageFrame._width = ccbWidth;
|
||||||
|
imageFrame._height = ccbHeight;
|
||||||
|
imageFrame._paletteBase = 0;
|
||||||
|
imageFrame._offset.x = 0;
|
||||||
|
imageFrame._offset.y = 0;
|
||||||
|
imageFrame._rleEncoded = ccbFlags_compressed;
|
||||||
|
imageFrame._size = 0;
|
||||||
|
|
||||||
|
// Decompress/copy this frame
|
||||||
|
decompress3DOCelFrame(imageFrame, celDataPtr, celDataSize, ccbPRE0_bitsPerPixel, NULL);
|
||||||
|
|
||||||
|
delete[] celDataPtr;
|
||||||
|
|
||||||
|
push_back(imageFrame);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static uint16 imagefile3DO_cel_bitsMask[17] = {
|
static uint16 imagefile3DO_cel_bitsMask[17] = {
|
||||||
0,
|
0,
|
||||||
0x0001, 0x0003, 0x0007, 0x000F, 0x001F, 0x003F, 0x007F, 0x00FF,
|
0x0001, 0x0003, 0x0007, 0x000F, 0x001F, 0x003F, 0x007F, 0x00FF,
|
||||||
|
@ -105,7 +105,7 @@ private:
|
|||||||
/**
|
/**
|
||||||
* Load the data of the sprite
|
* Load the data of the sprite
|
||||||
*/
|
*/
|
||||||
void load(Common::SeekableReadStream &stream, bool animImages);
|
void load(Common::SeekableReadStream &stream, bool isRoomData);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* convert pixel RGB values from RGB555 to RGB565
|
* convert pixel RGB values from RGB555 to RGB565
|
||||||
@ -117,6 +117,11 @@ private:
|
|||||||
*/
|
*/
|
||||||
void load3DOCelFile(Common::SeekableReadStream &stream);
|
void load3DOCelFile(Common::SeekableReadStream &stream);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load 3DO cel data (room file format)
|
||||||
|
*/
|
||||||
|
void load3DOCelRoomData(Common::SeekableReadStream &stream);
|
||||||
|
|
||||||
inline uint16 celGetBits(const byte *&dataPtr, byte bitCount, byte &dataBitsLeft);
|
inline uint16 celGetBits(const byte *&dataPtr, byte bitCount, byte &dataBitsLeft);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -131,7 +136,7 @@ private:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
ImageFile3DO(const Common::String &name);
|
ImageFile3DO(const Common::String &name);
|
||||||
ImageFile3DO(Common::SeekableReadStream &stream, bool roomData = false);
|
ImageFile3DO(Common::SeekableReadStream &stream, bool isRoomData = false);
|
||||||
~ImageFile3DO();
|
~ImageFile3DO();
|
||||||
static void setVm(SherlockEngine *vm);
|
static void setVm(SherlockEngine *vm);
|
||||||
};
|
};
|
||||||
|
@ -656,21 +656,14 @@ bool Scene::loadScene(const Common::String &filename) {
|
|||||||
_images[idx + 1]._filesize = bgInfo[idx]._filesize;
|
_images[idx + 1]._filesize = bgInfo[idx]._filesize;
|
||||||
_images[idx + 1]._maxFrames = bgInfo[idx]._maxFrames;
|
_images[idx + 1]._maxFrames = bgInfo[idx]._maxFrames;
|
||||||
|
|
||||||
// Read the image data
|
// Read image data into memory
|
||||||
// It seems it's a 8 byte header per frame
|
Common::SeekableReadStream *imageStream = roomStream->readStream(bgInfo[idx]._filesize);
|
||||||
// followed by a copy of the cel header
|
|
||||||
// which is then followed by cel data
|
|
||||||
// TODO
|
|
||||||
warning("image %d, maxFrames %d", idx, bgInfo[idx]._maxFrames);
|
|
||||||
warning("size %d", bgInfo[idx]._filesize);
|
|
||||||
|
|
||||||
// Read in the image data
|
// Load image data into an ImageFile array as room file data
|
||||||
//Common::SeekableReadStream *imageStream = roomStream->readStream(bgInfo[idx]._filesize);
|
// which is basically a fixed header, followed by a raw cel header, followed by regular cel data
|
||||||
|
_images[idx + 1]._images = new ImageFile3DO(*imageStream, true);
|
||||||
|
|
||||||
//_images[idx + 1]._images = new ImageFile(*imageStream);
|
delete imageStream;
|
||||||
|
|
||||||
//delete imageStream;
|
|
||||||
warning("end");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// === BGSHAPES === Set up the bgShapes
|
// === BGSHAPES === Set up the bgShapes
|
||||||
|
Loading…
Reference in New Issue
Block a user