SHERLOCK: 3DO: some work on font file loading

This commit is contained in:
Martin Kiewitz
2015-06-12 21:26:24 +02:00
parent 9c66934608
commit 765dbe647c
8 changed files with 181 additions and 25 deletions
+1 -1
View File
@@ -169,7 +169,7 @@ bool Animation::play3DO(const Common::String &filename, bool intro, int minDelay
// Load initial image
Common::String graphicsName = "prologue/" + filename + ".3da";
ImageFile3DO images(graphicsName);
ImageFile3DO images(graphicsName, kImageFile3DOType_Animation);
events.wait(minDelay);
+1 -1
View File
@@ -59,7 +59,7 @@ void Events::loadCursors(const Common::String &filename) {
_cursorImages = new ImageFile(filename);
} else {
// 3DO
_cursorImages = new ImageFile3DO(filename, true);
_cursorImages = new ImageFile3DO(filename, kImageFile3DOType_RoomFormat);
}
_cursorId = INVALID_CURSOR;
}
+27 -7
View File
@@ -45,15 +45,35 @@ void Fonts::free() {
void Fonts::setFont(int fontNum) {
_fontNumber = fontNum;
if (_platform == Common::kPlatform3DO)
return;
Common::String fname = Common::String::format("FONT%d.VGS", fontNum + 1);
// Discard any previous font and read in new one
// Discard previous font
delete _font;
_font = new ImageFile(fname);
Common::String fontFilename;
if (_platform != Common::kPlatform3DO) {
// PC
// use FONT[number].VGS, which is a regular sherlock graphic file
fontFilename = Common::String::format("FONT%d.VGS", fontNum + 1);
// load font data
_font = new ImageFile(fontFilename);
} else {
// 3DO
switch (fontNum) {
case 0:
case 1:
fontFilename = "helvetica14.font";
break;
case 2:
fontFilename = "darts.font";
break;
default:
error("setFont(): unsupported 3DO font number");
}
// load font data
_font = new ImageFile3DO(fontFilename, kImageFile3DOType_Font);
}
// Iterate through the frames to find the tallest font character
_fontHeight = 0;
for (uint idx = 0; idx < _font->size(); ++idx)
+126 -3
View File
@@ -243,20 +243,41 @@ void ImageFile3DO::setVm(SherlockEngine *vm) {
_vm = vm;
}
ImageFile3DO::ImageFile3DO(const Common::String &name, bool isRoomDataFormat) {
ImageFile3DO::ImageFile3DO(const Common::String &name, ImageFile3DOType imageFile3DOType) {
Common::File *dataStream = new Common::File();
if (!dataStream->open(name)) {
error("unable to open %s\n", name.c_str());
}
load(*dataStream, isRoomDataFormat);
switch(imageFile3DOType) {
case kImageFile3DOType_Animation:
loadAnimationFile(*dataStream);
break;
case kImageFile3DOType_Cel:
case kImageFile3DOType_CelAnimation:
load3DOCelFile(*dataStream);
break;
case kImageFile3DOType_RoomFormat:
load3DOCelRoomData(*dataStream);
break;
case kImageFile3DOType_Font:
loadFont(*dataStream);
break;
default:
error("unknown Imagefile-3DO-Type");
break;
}
delete dataStream;
}
ImageFile3DO::ImageFile3DO(Common::SeekableReadStream &stream, bool isRoomData) {
load(stream, isRoomData);
if (!isRoomData) {
load(stream, isRoomData);
} else {
load3DOCelRoomData(stream);
}
}
ImageFile3DO::~ImageFile3DO() {
@@ -775,4 +796,106 @@ void ImageFile3DO::decompress3DOCelFrame(ImageFrame &frame, const byte *dataPtr,
}
}
// Reads Sherlock Holmes 3DO font file
void ImageFile3DO::loadFont(Common::SeekableReadStream &stream) {
uint32 streamSize = stream.size();
uint32 header_offsetWidthTable = 0;
uint32 header_offsetBitsTable = 0;
uint32 header_fontHeight = 0;
uint32 header_bytesPerLine = 0;
uint32 header_maxChar = 0;
uint32 header_charCount = 0;
byte *widthTablePtr = NULL;
uint32 bitsTableSize = 0;
byte *bitsTablePtr = NULL;
stream.skip(2); // Unknown bytes
stream.skip(2); // Unknown bytes (0x000E)
header_offsetWidthTable = stream.readUint32BE();
header_offsetBitsTable = stream.readUint32BE();
stream.skip(4); // Unknown bytes (0x00000004)
header_fontHeight = stream.readUint32BE();
header_bytesPerLine = stream.readUint32BE();
header_maxChar = stream.readUint32BE();
assert(header_maxChar <= 255);
header_charCount = header_maxChar + 1;
// Allocate memory for width table
widthTablePtr = new byte[header_charCount];
stream.seek(header_offsetWidthTable);
stream.read(widthTablePtr, header_charCount);
// Allocate memory for the bits
assert(header_offsetBitsTable < streamSize); // Security check
bitsTableSize = streamSize - header_offsetBitsTable;
bitsTablePtr = new byte[bitsTableSize];
stream.read(bitsTablePtr, bitsTableSize);
// Now extract all characters
uint16 curChar = 0;
const byte *curBitsLinePtr = bitsTablePtr;
const byte *curBitsPtr = NULL;
byte curBitsLeft = 0;
uint32 curCharHeightLeft = 0;
uint32 curCharWidthLeft = 0;
byte curBits = 0;
for (curChar = 0; 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);
#if 0
curCharHeightLeft = header_fontHeight;
while (curCharHeightLeft) {
curCharWidthLeft = widthTablePtr[curChar];
curBitsPtr = curBitsLinePtr;
curBitsLeft = 8;
while (curCharWidthLeft) {
curBits = celGetBits(curBitsPtr, 2, curBitsLeft);
switch (curBits) {
case 0: // Transparent
break;
case 1: // regular color
*dest = 0xFFFF;
break;
case 2: // front
//*dest = 0xFFFF; //0x333;
break;
case 3: // shadow
//*dest = 0x1111;
break;
}
dest++;
curCharWidthLeft--;
}
curCharHeightLeft--;
curBitsLinePtr += header_bytesPerLine;
}
#endif
push_back(imageFrame);
}
}
}
} // End of namespace Sherlock
+14 -1
View File
@@ -94,6 +94,14 @@ public:
static void setVm(SherlockEngine *vm);
};
enum ImageFile3DOType {
kImageFile3DOType_Animation = 0,
kImageFile3DOType_Cel = 1,
kImageFile3DOType_CelAnimation = 2,
kImageFile3DOType_RoomFormat = 3,
kImageFile3DOType_Font = 4
};
struct ImageFile3DOPixelLookupTable {
uint16 pixelColor[256];
};
@@ -134,8 +142,13 @@ private:
*/
void loadAnimationFile(Common::SeekableReadStream &stream);
/**
* Load Sherlock Holmes 3DO font file
*/
void loadFont(Common::SeekableReadStream &stream);
public:
ImageFile3DO(const Common::String &name, bool isRoomDataFormat = false);
ImageFile3DO(const Common::String &name, ImageFile3DOType imageFile3DOType);
ImageFile3DO(Common::SeekableReadStream &stream, bool isRoomData = false);
~ImageFile3DO();
static void setVm(SherlockEngine *vm);
+1 -1
View File
@@ -286,7 +286,7 @@ bool People::loadWalk() {
_data[PLAYER]->_images = new ImageFile("walk.vgs");
} else {
// Load walk.anim on 3DO, which is a cel animation file
_data[PLAYER]->_images = new ImageFile3DO("walk.anim");
_data[PLAYER]->_images = new ImageFile3DO("walk.anim", kImageFile3DOType_CelAnimation);
}
_data[PLAYER]->setImageFrame();
_data[PLAYER]->_walkLoaded = true;
+9 -9
View File
@@ -531,7 +531,7 @@ bool ScalpelEngine::showOfficeCutscene() {
// 3DO variant
bool ScalpelEngine::show3DOSplash() {
// 3DO EA Splash screen
ImageFile3DO titleImage_3DOSplash("3DOSplash.cel");
ImageFile3DO titleImage_3DOSplash("3DOSplash.cel", kImageFile3DOType_Cel);
_screen->transBlitFrom(titleImage_3DOSplash[0]._frame, Common::Point(0, -20));
bool finished = _events->delay(3000, true);
@@ -576,7 +576,7 @@ bool ScalpelEngine::showCityCutscene3DO() {
_screen->_backBuffer2.blitFrom(*_screen); // save into backbuffer 2, for restoring later
// "London, England"
ImageFile3DO titleImage_London("title2a.cel");
ImageFile3DO titleImage_London("title2a.cel", kImageFile3DOType_Cel);
_screen->_backBuffer1.transBlitFrom(titleImage_London[0]._frame, Common::Point(30, 50));
_screen->fadeIntoScreen3DO(1);
@@ -584,7 +584,7 @@ bool ScalpelEngine::showCityCutscene3DO() {
if (finished) {
// "November, 1888"
ImageFile3DO titleImage_November("title2b.cel");
ImageFile3DO titleImage_November("title2b.cel", kImageFile3DOType_Cel);
_screen->_backBuffer1.transBlitFrom(titleImage_November[0]._frame, Common::Point(100, 100));
_screen->fadeIntoScreen3DO(1);
@@ -604,7 +604,7 @@ bool ScalpelEngine::showCityCutscene3DO() {
_screen->_backBuffer1.blitFrom(*_screen); // save into backbuffer 1, used for fade
// "Sherlock Holmes" (title)
ImageFile3DO titleImage_SherlockHolmesTitle("title1ab.cel");
ImageFile3DO titleImage_SherlockHolmesTitle("title1ab.cel", kImageFile3DOType_Cel);
_screen->_backBuffer1.transBlitFrom(titleImage_SherlockHolmesTitle[0]._frame, Common::Point(34, 5));
// Blend in
@@ -613,7 +613,7 @@ bool ScalpelEngine::showCityCutscene3DO() {
// Title should fade in, Copyright should be displayed a bit after that
if (finished) {
ImageFile3DO titleImage_Copyright("title1c.cel");
ImageFile3DO titleImage_Copyright("title1c.cel", kImageFile3DOType_Cel);
_screen->transBlitFrom(titleImage_Copyright[0]._frame, Common::Point(20, 190));
finished = _events->delay(3500, true);
@@ -631,7 +631,7 @@ bool ScalpelEngine::showCityCutscene3DO() {
if (finished) {
// "In the alley behind the Regency Theatre..."
ImageFile3DO titleImage_InTheAlley("title1d.cel");
ImageFile3DO titleImage_InTheAlley("title1d.cel", kImageFile3DOType_Cel);
_screen->_backBuffer1.transBlitFrom(titleImage_InTheAlley[0]._frame, Common::Point(72, 51));
// Fade in
@@ -667,7 +667,7 @@ bool ScalpelEngine::showAlleyCutscene3DO() {
if (finished) {
// Show screaming victim
ImageFile3DO titleImage_ScreamingVictim("scream.cel");
ImageFile3DO titleImage_ScreamingVictim("scream.cel", kImageFile3DOType_Cel);
_screen->clear();
_screen->transBlitFrom(titleImage_ScreamingVictim[0]._frame, Common::Point(0, 0));
@@ -698,7 +698,7 @@ bool ScalpelEngine::showAlleyCutscene3DO() {
if (finished) {
// "Early the following morning on Baker Street..."
ImageFile3DO titleImage_EarlyTheFollowingMorning("title3.cel");
ImageFile3DO titleImage_EarlyTheFollowingMorning("title3.cel", kImageFile3DOType_Cel);
_screen->_backBuffer1.transBlitFrom(titleImage_EarlyTheFollowingMorning[0]._frame, Common::Point(35, 51));
// Fade in
@@ -751,7 +751,7 @@ bool ScalpelEngine::showOfficeCutscene3DO() {
if (finished) {
// Show the note
ImageFile3DO titleImage_CoffeeNote("note.cel");
ImageFile3DO titleImage_CoffeeNote("note.cel", kImageFile3DOType_Cel);
_screen->clear();
_screen->transBlitFrom(titleImage_CoffeeNote[0]._frame, Common::Point(0, 0));
@@ -92,8 +92,8 @@ ScalpelUserInterface::ScalpelUserInterface(SherlockEngine *vm): UserInterface(vm
_controlPanel = new ImageFile("controls.vgs");
} else {
// 3DO
_controls = new ImageFile3DO("menu.all", true);
_controlPanel = new ImageFile3DO("controls.vgs", true);
_controls = new ImageFile3DO("menu.all", kImageFile3DOType_RoomFormat);
_controlPanel = new ImageFile3DO("controls.vgs", kImageFile3DOType_RoomFormat);
}
} else {
_controls = nullptr;