mirror of
https://github.com/scummvm/scummvm.git
synced 2026-06-20 05:45:29 +00:00
SHERLOCK: 3DO: some work on font file loading
This commit is contained in:
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user