SHERLOCK: RT: Implement font _yOffsets table

Since this table must only be set up for RT when changing fonts, I
needed to put an engine reference in the Fonts base class. Because
of this, I've been able to simplify the creation of the various
surfaces, since you no longer need to pass in the platform
This commit is contained in:
Paul Gilbert 2015-06-18 19:21:04 -04:00
parent f6c710e5b3
commit 1732428aa6
11 changed files with 63 additions and 36 deletions

View File

@ -25,18 +25,21 @@
#include "sherlock/fonts.h"
#include "sherlock/image_file.h"
#include "sherlock/surface.h"
#include "sherlock/sherlock.h"
namespace Sherlock {
Common::Platform Fonts::_platform;
SherlockEngine *Fonts::_vm;
ImageFile *Fonts::_font;
int Fonts::_fontNumber;
int Fonts::_fontHeight;
int Fonts::_widestChar;
uint16 Fonts::_charCount;
byte Fonts::_yOffsets[255];
void Fonts::init(Common::Platform platform) {
void Fonts::setVm(SherlockEngine *vm) {
_vm = vm;
_font = nullptr;
_platform = platform;
_charCount = 0;
}
@ -52,7 +55,7 @@ void Fonts::setFont(int fontNum) {
Common::String fontFilename;
if (_platform != Common::kPlatform3DO) {
if (_vm->getPlatform() != Common::kPlatform3DO) {
// PC
// use FONT[number].VGS, which is a regular sherlock graphic file
fontFilename = Common::String::format("FONT%d.VGS", fontNum + 1);
@ -72,16 +75,32 @@ void Fonts::setFont(int fontNum) {
default:
error("setFont(): unsupported 3DO font number");
}
// load font data
_font = new ImageFile3DO(fontFilename, kImageFile3DOType_Font);
}
_charCount = _font->size();
// Iterate through the frames to find the tallest font character
_fontHeight = 0;
for (uint idx = 0; idx < _charCount; ++idx)
// Iterate through the frames to find the widest aand tallest font characters
_fontHeight = _widestChar = 0;
for (uint idx = 0; idx < _charCount; ++idx) {
_fontHeight = MAX((uint16)_fontHeight, (*_font)[idx]._frame.h);
_widestChar = MAX((uint16)_widestChar, (*_font)[idx]._frame.w);
}
// Initialize the Y offset table for the extended character set
for (int idx = 0; idx < 255; ++idx) {
_yOffsets[idx] = 0;
if (IS_ROSE_TATTOO) {
if ((idx >= 129 && idx < 135) || (idx >= 136 && idx < 143) || (idx >= 147 && idx < 155) ||
(idx >= 156 && idx < 165))
_yOffsets[idx] = 1;
else if ((idx >= 143 && idx < 146) || idx == 165)
_yOffsets[idx] = 2;
}
}
}
inline byte Fonts::translateChar(byte c) {
@ -123,7 +142,7 @@ void Fonts::writeString(Surface *surface, const Common::String &str,
assert(curChar < _charCount);
ImageFrame &frame = (*_font)[curChar];
surface->transBlitFrom(frame, charPos, false, overrideColor);
surface->transBlitFrom(frame, Common::Point(charPos.x, charPos.y + _yOffsets[curChar]), false, overrideColor);
charPos.x += frame._frame.w + 1;
}
}

View File

@ -29,16 +29,19 @@
namespace Sherlock {
class SherlockEngine;
class ImageFile;
class Surface;
class Fonts {
private:
static Common::Platform _platform;
static ImageFile *_font;
static byte _yOffsets[255];
protected:
static SherlockEngine *_vm;
static int _fontNumber;
static int _fontHeight;
static int _widestChar;
static uint16 _charCount;
static void writeString(Surface *surface, const Common::String &str,
@ -49,7 +52,7 @@ public:
/**
* Initialise the font manager
*/
static void init(Common::Platform platform);
static void setVm(SherlockEngine *vm);
/**
* Frees the font manager
@ -86,6 +89,14 @@ public:
*/
int fontHeight() const { return _fontHeight; }
/**
* Return the width of the widest character in the font
*/
int widestChar() const { return _widestChar; }
/**
* Return the currently active font number
*/
int fontNumber() const { return _fontNumber; }
};

View File

@ -56,7 +56,7 @@ const byte *MapPaths::getPath(int srcLocation, int destLocation) {
/*----------------------------------------------------------------*/
ScalpelMap::ScalpelMap(SherlockEngine *vm): Map(vm), _topLine(g_system->getWidth(), 12, vm->getPlatform()) {
ScalpelMap::ScalpelMap(SherlockEngine *vm): Map(vm), _topLine(g_system->getWidth(), 12) {
_mapCursors = nullptr;
_shapes = nullptr;
_iconShapes = nullptr;
@ -315,7 +315,7 @@ void ScalpelMap::setupSprites() {
_cursorIndex = 0;
events.setCursor((*_mapCursors)[_cursorIndex]._frame);
_iconSave.create((*_shapes)[4]._width, (*_shapes)[4]._height, _vm->getPlatform());
_iconSave.create((*_shapes)[4]._width, (*_shapes)[4]._height);
Person &p = people[HOLMES];
p._description = " ";
p._type = CHARACTER;

View File

@ -1235,7 +1235,7 @@ void ScalpelUserInterface::doLookControl() {
} else {
// Looking at an inventory object
// Backup the user interface
Surface tempSurface(SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT - CONTROLS_Y1, _vm->getPlatform());
Surface tempSurface(SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT - CONTROLS_Y1);
tempSurface.blitFrom(screen._backBuffer2, Common::Point(0, 0),
Common::Rect(0, CONTROLS_Y1, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT));
@ -1803,7 +1803,7 @@ void ScalpelUserInterface::printObjectDesc(const Common::String &str, bool first
// If it wasn't a right button click, then we need depress
// the look button before we close the window. So save a copy of the
// menu area, and draw the controls onto it
Surface tempSurface((*_controls)[0]._frame.w, (*_controls)[0]._frame.h, _vm->getPlatform());
Surface tempSurface((*_controls)[0]._frame.w, (*_controls)[0]._frame.h);
Common::Point pt(MENU_POINTS[0][0], MENU_POINTS[0][1]);
offsetButton3DO(pt, 0);
@ -1994,8 +1994,7 @@ void ScalpelUserInterface::summonWindow(bool slideUp, int height) {
Screen &screen = *_vm->_screen;
// Extract the window that's been drawn on the back buffer
Surface tempSurface(SHERLOCK_SCREEN_WIDTH,
(SHERLOCK_SCREEN_HEIGHT - height), _vm->getPlatform());
Surface tempSurface(SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT - height);
Common::Rect r(0, height, SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT);
tempSurface.blitFrom(screen._backBuffer1, Common::Point(0, 0), r);

View File

@ -104,7 +104,7 @@ void Visage::surfaceFromRes(ObjectSurface &s) {
int frameWidth = _stream->readUint16LE();
int frameHeight = _stream->readUint16LE();
Common::Rect r(0, 0, frameWidth, frameHeight);
s.create(r.width(), r.height(), Common::kPlatformDOS); // maybe change this to a bool later? TODO
s.create(r.width(), r.height());
s._centroid.x = _stream->readSint16LE();
s._centroid.y = _stream->readSint16LE();

View File

@ -28,9 +28,9 @@
namespace Sherlock {
Screen::Screen(SherlockEngine *vm) : Surface(g_system->getWidth(), g_system->getHeight(), vm->getPlatform()), _vm(vm),
_backBuffer1(g_system->getWidth(), g_system->getHeight(), vm->getPlatform()),
_backBuffer2(g_system->getWidth(), g_system->getHeight(), vm->getPlatform()),
Screen::Screen(SherlockEngine *vm) : Surface(g_system->getWidth(), g_system->getHeight()), _vm(vm),
_backBuffer1(g_system->getWidth(), g_system->getHeight()),
_backBuffer2(g_system->getWidth(), g_system->getHeight()),
_backBuffer(&_backBuffer1) {
_transitionSeed = 1;
_fadeStyle = false;
@ -39,8 +39,6 @@ Screen::Screen(SherlockEngine *vm) : Surface(g_system->getWidth(), g_system->get
Common::fill(&_tMap[0], &_tMap[PALETTE_SIZE], 0);
// Set up the initial font
Fonts::init(_vm->getPlatform());
setFont(IS_SERRATED_SCALPEL ? 1 : 4);
// Rose Tattoo specific fields

View File

@ -78,10 +78,10 @@ void SherlockEngine::initialize() {
DebugMan.addDebugChannel(kDebugLevelMT32Driver, "MT32", "MT32 driver debugging");
DebugMan.addDebugChannel(kDebugLevelMusic, "Music", "Music debugging");
Fonts::setVm(this);
ImageFile::setVm(this);
ImageFile3DO::setVm(this);
Object::setVm(this);
Sprite::setVm(this);
BaseObject::setVm(this);
if (isDemo()) {
Common::File f;

View File

@ -28,8 +28,8 @@
namespace Sherlock {
Surface::Surface(uint16 width, uint16 height, Common::Platform platform) : Fonts(), _freePixels(true) {
create(width, height, platform);
Surface::Surface(uint16 width, uint16 height) : Fonts(), _freePixels(true) {
create(width, height);
}
Surface::Surface() : Fonts(), _freePixels(false) {
@ -40,11 +40,11 @@ Surface::~Surface() {
_surface.free();
}
void Surface::create(uint16 width, uint16 height, Common::Platform platform) {
void Surface::create(uint16 width, uint16 height) {
if (_freePixels)
_surface.free();
if (platform == Common::kPlatform3DO) {
if (_vm->getPlatform() == Common::kPlatform3DO) {
_surface.create(width, height, Graphics::PixelFormat(2, 5, 6, 5, 0, 11, 5, 0, 0));
} else {
_surface.create(width, height, Graphics::PixelFormat::createFormatCLUT8());

View File

@ -70,7 +70,7 @@ protected:
virtual void addDirtyRect(const Common::Rect &r) {}
public:
Surface(uint16 width, uint16 height, Common::Platform platform);
Surface(uint16 width, uint16 height);
Surface();
virtual ~Surface();
@ -78,7 +78,7 @@ public:
* Sets up an internal surface with the specified dimensions that will be automatically freed
* when the surface object is destroyed
*/
void create(uint16 width, uint16 height, Common::Platform platform);
void create(uint16 width, uint16 height);
Graphics::PixelFormat getPixelFormat();

View File

@ -105,7 +105,7 @@ int TattooMap::show() {
// Load the map image and draw it to the back buffer
ImageFile *map = new ImageFile("map.vgs");
screen._backBuffer1.create(SHERLOCK_SCREEN_WIDTH * 2, SHERLOCK_SCREEN_HEIGHT * 2, _vm->getPlatform());
screen._backBuffer1.create(SHERLOCK_SCREEN_WIDTH * 2, SHERLOCK_SCREEN_HEIGHT * 2);
screen._backBuffer1.blitFrom((*map)[0], Common::Point(0, 0));
delete map;
@ -114,7 +114,7 @@ int TattooMap::show() {
drawMapIcons();
// Copy the map drawn in the back buffer to the secondary back buffer
screen._backBuffer2.create(SHERLOCK_SCREEN_WIDTH * 2, SHERLOCK_SCREEN_HEIGHT * 2, _vm->getPlatform());
screen._backBuffer2.create(SHERLOCK_SCREEN_WIDTH * 2, SHERLOCK_SCREEN_HEIGHT * 2);
screen._backBuffer2.blitFrom(screen._backBuffer1);
// Display the built map to the screen
@ -231,8 +231,8 @@ int TattooMap::show() {
_textBuffer = nullptr;
// Reset the back buffers back to standard size
screen._backBuffer1.create(SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT, _vm->getPlatform());
screen._backBuffer2.create(SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT, _vm->getPlatform());
screen._backBuffer1.create(SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT);
screen._backBuffer2.create(SHERLOCK_SCREEN_WIDTH, SHERLOCK_SCREEN_HEIGHT);
return result;
}
@ -391,7 +391,7 @@ void TattooMap::checkMapNames(bool slamIt) {
delete _textBuffer;
// Allocate a new surface
_textBuffer = new Surface(width, height, _vm->getPlatform());
_textBuffer = new Surface(width, height);
_textBuffer->fillRect(Common::Rect(0, 0, width, height), TRANSPARENCY);
if (space == nullptr) {

View File

@ -111,7 +111,7 @@ void WidgetTooltip::execute() {
}
// Reallocate the text surface with the new size
_surface.create(width, height, _vm->getPlatform());
_surface.create(width, height);
_surface.fill(TRANSPARENCY);
if (line2.empty()) {