ACCESS: MM: Implement proper game data and fonts in access.dat

This commit is contained in:
Paul Gilbert 2018-07-20 19:05:56 -07:00
parent b6dc832346
commit af6034efcd
15 changed files with 334 additions and 136 deletions

View file

@ -255,15 +255,15 @@ void AccessEngine::speakText(BaseSurface *s, const Common::String &msg) {
_events->zeroKeys();
int width = 0;
bool lastLine = _fonts._font2.getLine(lines, s->_maxChars * 6, line, width);
bool lastLine = _fonts._font2->getLine(lines, s->_maxChars * 6, line, width);
// Set font colors
_fonts._font2._fontColors[0] = 0;
_fonts._font2._fontColors[1] = 28;
_fonts._font2._fontColors[2] = 29;
_fonts._font2._fontColors[3] = 30;
Font::_fontColors[0] = 0;
Font::_fontColors[1] = 28;
Font::_fontColors[2] = 29;
Font::_fontColors[3] = 30;
_fonts._font2.drawString(s, line, s->_printOrg);
_fonts._font2->drawString(s, line, s->_printOrg);
s->_printOrg = Common::Point(s->_printStart.x, s->_printOrg.y + 9);
if ((s->_printOrg.y > _printEnd) && (!lastLine)) {
@ -331,14 +331,14 @@ void AccessEngine::printText(BaseSurface *s, const Common::String &msg) {
int width = 0;
for (;;) {
bool lastLine = _fonts._font2.getLine(lines, s->_maxChars * 6, line, width);
bool lastLine = _fonts._font2->getLine(lines, s->_maxChars * 6, line, width);
// Set font colors
_fonts._font2._fontColors[0] = 0;
_fonts._font2._fontColors[1] = 28;
_fonts._font2._fontColors[2] = 29;
_fonts._font2._fontColors[3] = 30;
_fonts._font2.drawString(s, line, s->_printOrg);
_fonts._font2->_fontColors[0] = 0;
_fonts._font2->_fontColors[1] = 28;
_fonts._font2->_fontColors[2] = 29;
_fonts._font2->_fontColors[3] = 30;
_fonts._font2->drawString(s, line, s->_printOrg);
s->_printOrg = Common::Point(s->_printStart.x, s->_printOrg.y + 9);
@ -598,7 +598,7 @@ void AccessEngine::writeSavegameHeader(Common::OutSaveFile *out, AccessSavegameH
void AccessEngine::SPRINTCHR(char c, int fontNum) {
warning("TODO: SPRINTCHR");
_fonts._font1.drawChar(_screen, c, _screen->_printOrg);
_fonts._font1->drawChar(_screen, c, _screen->_printOrg);
}
void AccessEngine::PRINTCHR(Common::String msg, int fontNum) {
@ -607,7 +607,7 @@ void AccessEngine::PRINTCHR(Common::String msg, int fontNum) {
for (int i = 0; msg[i]; i++) {
if (!(_fonts._charSet._hi & 8)) {
_fonts._font1.drawChar(_screen, msg[i], _screen->_printOrg);
_fonts._font1->drawChar(_screen, msg[i], _screen->_printOrg);
continue;
} else if (_fonts._charSet._hi & 2) {
Common::Point oldPos = _screen->_printOrg;

View file

@ -162,8 +162,7 @@ void AmazonEngine::setupGame() {
_deaths._cells[i] = CellIdent(DEATH_CELLS[i][0], DEATH_CELLS[i][1], DEATH_CELLS[i][2]);
// Miscellaneous
_fonts._font1.load(&res.FONT6x6_INDEX[0], &res.FONT6x6_DATA[0]);
_fonts._font2.load(&res.FONT2_INDEX[0], &res.FONT2_DATA[0]);
_fonts.load(res._font6x6, res._font3x5);
initVariables();
}
@ -409,21 +408,21 @@ void AmazonEngine::calcIQ() {
void AmazonEngine::helpTitle() {
AmazonResources &res = *(AmazonResources *)_res;
int width = _fonts._font2.stringWidth(_bubbleBox->_bubbleTitle);
int width = _fonts._font2->stringWidth(_bubbleBox->_bubbleTitle);
int posX = 160 - (width / 2);
_fonts._font2._fontColors[0] = 0;
_fonts._font2._fontColors[1] = 33;
_fonts._font2._fontColors[2] = 34;
_fonts._font2._fontColors[3] = 35;
_fonts._font2.drawString(_screen, _bubbleBox->_bubbleTitle, Common::Point(posX, 24));
_fonts._font2->_fontColors[0] = 0;
_fonts._font2->_fontColors[1] = 33;
_fonts._font2->_fontColors[2] = 34;
_fonts._font2->_fontColors[3] = 35;
_fonts._font2->drawString(_screen, _bubbleBox->_bubbleTitle, Common::Point(posX, 24));
width = _fonts._font2.stringWidth(res.HELPLVLTXT[_helpLevel]);
width = _fonts._font2->stringWidth(res.HELPLVLTXT[_helpLevel]);
posX = 160 - (width / 2);
_fonts._font2._fontColors[0] = 0;
_fonts._font2._fontColors[1] = 10;
_fonts._font2._fontColors[2] = 11;
_fonts._font2._fontColors[3] = 12;
_fonts._font2.drawString(_screen, res.HELPLVLTXT[_helpLevel], Common::Point(posX, 36));
_fonts._font2->_fontColors[0] = 0;
_fonts._font2->_fontColors[1] = 10;
_fonts._font2->_fontColors[2] = 11;
_fonts._font2->_fontColors[3] = 12;
_fonts._font2->drawString(_screen, res.HELPLVLTXT[_helpLevel], Common::Point(posX, 36));
Common::String iqText = "IQ: ";
calcIQ();
@ -441,13 +440,13 @@ void AmazonEngine::helpTitle() {
iqText += " ";
iqText += res.IQLABELS[index];
width = _fonts._font2.stringWidth(iqText);
width = _fonts._font2->stringWidth(iqText);
posX = 160 - (width / 2);
_fonts._font2._fontColors[0] = 0;
_fonts._font2._fontColors[1] = 10;
_fonts._font2._fontColors[2] = 11;
_fonts._font2._fontColors[3] = 12;
_fonts._font2.drawString(_screen, iqText, Common::Point(posX, 44));
_fonts._font2->_fontColors[0] = 0;
_fonts._font2->_fontColors[1] = 10;
_fonts._font2->_fontColors[2] = 11;
_fonts._font2->_fontColors[3] = 12;
_fonts._font2->drawString(_screen, iqText, Common::Point(posX, 44));
}
void AmazonEngine::drawHelpText(const Common::String &msg) {
@ -460,15 +459,15 @@ void AmazonEngine::drawHelpText(const Common::String &msg) {
int width = 0;
bool lastLine = false;
do {
lastLine = _fonts._font2.getLine(lines, _screen->_maxChars * 6, line, width);
lastLine = _fonts._font2->getLine(lines, _screen->_maxChars * 6, line, width);
// Set font colors
_fonts._font2._fontColors[0] = 0;
_fonts._font2._fontColors[1] = 27;
_fonts._font2._fontColors[2] = 28;
_fonts._font2._fontColors[3] = 29;
_fonts._font2->_fontColors[0] = 0;
_fonts._font2->_fontColors[1] = 27;
_fonts._font2->_fontColors[2] = 28;
_fonts._font2->_fontColors[3] = 29;
_fonts._font2.drawString(_screen, line, _screen->_printOrg);
_fonts._font2->drawString(_screen, line, _screen->_printOrg);
_screen->_printOrg = Common::Point(_screen->_printStart.x, _screen->_printOrg.y + 8);
} while (!lastLine);

View file

@ -1743,7 +1743,7 @@ void River::plotRiver() {
}
// Draw the text for skipping the river
Font &font2 = _vm->_fonts._font2;
Font &font2 = *_vm->_fonts._font2;
font2.drawString(_vm->_screen, "SKIP", Common::Point(5, 5));
}

View file

@ -27,6 +27,11 @@ namespace Access {
namespace Amazon {
AmazonResources::~AmazonResources() {
delete _font3x5;
delete _font6x6;
}
void AmazonResources::load(Common::SeekableReadStream &s) {
Resources::load(s);
uint count;
@ -60,24 +65,29 @@ void AmazonResources::load(Common::SeekableReadStream &s) {
// Load font data
count = s.readUint16LE();
FONT2_INDEX.resize(count);
Common::Array<int> index;
Common::Array<byte> data;
index.resize(count);
for (uint idx = 0; idx < count; ++idx)
FONT2_INDEX[idx] = s.readSint16LE();
index[idx] = s.readSint16LE();
count = s.readUint16LE();
FONT2_DATA.resize(count);
data.resize(count);
for (uint idx = 0; idx < count; ++idx)
FONT2_DATA[idx] = s.readByte();
data[idx] = s.readByte();
_font3x5 = new AmazonFont(&index[0], &data[0]);
count = s.readUint16LE();
FONT6x6_INDEX.resize(count);
index.resize(count);
for (uint idx = 0; idx < count; ++idx)
FONT6x6_INDEX[idx] = s.readSint16LE();
index[idx] = s.readSint16LE();
count = s.readUint16LE();
FONT6x6_DATA.resize(count);
data.resize(count);
for (uint idx = 0; idx < count; ++idx)
FONT6x6_DATA[idx] = s.readByte();
data[idx] = s.readByte();
_font6x6 = new AmazonFont(&index[0], &data[0]);
}
/*------------------------------------------------------------------------*/

View file

@ -26,6 +26,7 @@
#include "common/scummsys.h"
#include "common/array.h"
#include "access/resources.h"
#include "access/font.h"
namespace Access {
@ -128,10 +129,7 @@ protected:
*/
virtual void load(Common::SeekableReadStream &s);
public:
Common::Array<int> FONT2_INDEX;
Common::Array<byte> FONT2_DATA;
Common::Array<int> FONT6x6_INDEX;
Common::Array<byte> FONT6x6_DATA;
AmazonFont *_font3x5, *_font6x6;
Common::String NO_HELP_MESSAGE;
Common::String NO_HINTS_MESSAGE;
Common::String RIVER_HIT1;
@ -140,8 +138,8 @@ public:
Common::String HELPLVLTXT[3];
Common::String IQLABELS[9];
public:
AmazonResources(AccessEngine *vm) : Resources(vm) {}
virtual ~AmazonResources() {}
AmazonResources(AccessEngine *vm) : Resources(vm), _font3x5(nullptr), _font6x6(nullptr) {}
virtual ~AmazonResources();
};
#define AMRES (*((Amazon::AmazonResources *)_vm->_res))

View file

@ -106,7 +106,7 @@ void BubbleBox::calcBubble(const Common::String &msg) {
if (_type == kBoxTypeFileDialog) {
_vm->_fonts._printMaxX = 110;
} else {
_vm->_fonts._printMaxX = _vm->_fonts._font2.stringWidth(_bubbleDisplStr);
_vm->_fonts._printMaxX = _vm->_fonts._font2->stringWidth(_bubbleDisplStr);
}
// Start of with a rect with the given starting x and y
@ -118,7 +118,7 @@ void BubbleBox::calcBubble(const Common::String &msg) {
int width = 0;
bool lastLine;
do {
lastLine = _vm->_fonts._font2.getLine(s, screen._maxChars * 6, line, width);
lastLine = _vm->_fonts._font2->getLine(s, screen._maxChars * 6, line, width);
_vm->_fonts._printMaxX = MAX(width, _vm->_fonts._printMaxX);
screen._printOrg.y += 6;
@ -173,7 +173,7 @@ void BubbleBox::printBubble_v1(const Common::String &msg) {
bool lastLine;
do {
// Get next line
Font &font2 = _vm->_fonts._font2;
Font &font2 = *_vm->_fonts._font2;
lastLine = font2.getLine(s, _vm->_screen->_maxChars * 6, line, width);
// Draw the text
printString(line);
@ -195,7 +195,7 @@ void BubbleBox::printBubble_v2(const Common::String &msg) {
bool lastLine;
do {
// Get next line
Font &font2 = _vm->_fonts._font2;
Font &font2 = *_vm->_fonts._font2;
lastLine = font2.getLine(s, _vm->_screen->_maxChars * 6, line, width);
// Set font colors
@ -309,8 +309,8 @@ void BubbleBox::doBox(int item, int box) {
}
// Handle drawing title
int titleWidth = _vm->_fonts._font2.stringWidth(_bubbleDisplStr);
Font &font2 = _vm->_fonts._font2;
int titleWidth = _vm->_fonts._font2->stringWidth(_bubbleDisplStr);
Font &font2 = *_vm->_fonts._font2;
font2._fontColors[0] = 0;
font2._fontColors[1] = 3;
font2._fontColors[2] = 2;
@ -338,7 +338,7 @@ void BubbleBox::setCursorPos(int posX, int posY) {
void BubbleBox::printString(Common::String msg) {
warning("TODO: Proper implementation of printString");
_vm->_fonts._font1.drawString(_vm->_screen, msg, _vm->_screen->_printOrg);
_vm->_fonts._font1->drawString(_vm->_screen, msg, _vm->_screen->_printOrg);
}
void BubbleBox::displayBoxData() {
@ -605,7 +605,7 @@ int BubbleBox::doBox_v1(int item, int box, int &btnSelected) {
setCursorPos(newX, newY);
_vm->_fonts._charFor._lo = 0xFF;
_vm->_fonts._font1.drawString(_vm->_screen, _bubbleDisplStr, _vm->_screen->_printOrg);
_vm->_fonts._font1->drawString(_vm->_screen, _bubbleDisplStr, _vm->_screen->_printOrg);
if (_type == TYPE_2) {
_vm->_events->showCursor();

View file

@ -26,9 +26,7 @@ namespace Access {
byte Font::_fontColors[4];
Font::Font() {
_bitWidth = 0;
_height = 0;
Font::Font(byte firstCharIndex) : _firstCharIndex(firstCharIndex), _bitWidth(0), _height(0) {
}
Font::~Font() {
@ -36,50 +34,11 @@ Font::~Font() {
_chars[i].free();
}
void Font::load(const int *fontIndex, const byte *fontData) {
assert(_chars.size() == 0);
int count = fontIndex[0];
_bitWidth = fontIndex[1];
_height = fontIndex[2];
_chars.resize(count);
for (int i = 0; i < count; ++i) {
const byte *pData = fontData + fontIndex[i + 3];
_chars[i].create(*pData++, _height, Graphics::PixelFormat::createFormatCLUT8());
for (int y = 0; y < _height; ++y) {
int bitsLeft = 0;
byte srcByte = 0;
byte pixel;
byte *pDest = (byte *)_chars[i].getBasePtr(0, y);
for (int x = 0; x < _chars[i].w; ++x, ++pDest) {
// Get the pixel
pixel = 0;
for (int pixelCtr = 0; pixelCtr < _bitWidth; ++pixelCtr, --bitsLeft) {
// No bits in current byte left, so get next byte
if (bitsLeft == 0) {
bitsLeft = 8;
srcByte = *pData++;
}
pixel = (pixel << 1) | (srcByte >> 7);
srcByte <<= 1;
}
// Write out the pixel
*pDest = pixel;
}
}
}
}
int Font::charWidth(char c) {
if (c < ' ')
if (c < _firstCharIndex)
return 0;
return _chars[c - ' '].w;
return _chars[c - _firstCharIndex].w;
}
int Font::stringWidth(const Common::String &msg) {
@ -150,7 +109,7 @@ void Font::drawString(BaseSurface *s, const Common::String &msg, const Common::P
}
int Font::drawChar(BaseSurface *s, char c, Common::Point &pt) {
Graphics::Surface &ch = _chars[c - ' '];
Graphics::Surface &ch = _chars[c - _firstCharIndex];
Graphics::Surface dest = s->getSubArea(Common::Rect(pt.x, pt.y, pt.x + ch.w, pt.y + ch.h));
// Loop through the lines of the character
@ -170,9 +129,109 @@ int Font::drawChar(BaseSurface *s, char c, Common::Point &pt) {
/*------------------------------------------------------------------------*/
FontManager::FontManager() {
void AmazonFont::load(const int *fontIndex, const byte *fontData) {
assert(_chars.size() == 0);
int count = fontIndex[0];
_bitWidth = fontIndex[1];
_height = fontIndex[2];
_chars.resize(count);
for (int i = 0; i < count; ++i) {
const byte *pData = fontData + fontIndex[i + 3];
_chars[i].create(*pData++, _height, Graphics::PixelFormat::createFormatCLUT8());
for (int y = 0; y < _height; ++y) {
int bitsLeft = 0;
byte srcByte = 0;
byte pixel;
byte *pDest = (byte *)_chars[i].getBasePtr(0, y);
for (int x = 0; x < _chars[i].w; ++x, ++pDest) {
// Get the pixel
pixel = 0;
for (int pixelCtr = 0; pixelCtr < _bitWidth; ++pixelCtr, --bitsLeft) {
// No bits in current byte left, so get next byte
if (bitsLeft == 0) {
bitsLeft = 8;
srcByte = *pData++;
}
pixel = (pixel << 1) | (srcByte >> 7);
srcByte <<= 1;
}
// Write out the pixel
*pDest = pixel;
}
}
}
}
/*------------------------------------------------------------------------*/
MartianFont::MartianFont(int height, Common::SeekableReadStream &s) : Font(0) {
_height = height;
load(s);
}
void MartianFont::load(Common::SeekableReadStream &s) {
// Get the number of characters and the size of the raw font data
size_t count = s.readUint16LE();
size_t dataSize = s.readUint16LE();
assert(count < 256);
// Get the character widths
Common::Array<byte> widths;
widths.resize(count);
s.read(&widths[0], count);
// Get the character offsets
Common::Array<int> offsets;
offsets.resize(count);
for (size_t idx = 0; idx < count; ++idx)
offsets[idx] = s.readUint16LE();
// Get the raw character data
Common::Array<byte> data;
data.resize(dataSize);
s.read(&data[0], dataSize);
// Iterate through decoding each character
_chars.resize(count);
for (size_t idx = 0; idx < count; ++idx) {
Graphics::Surface &s = _chars[idx];
s.create(widths[idx], _height, Graphics::PixelFormat::createFormatCLUT8());
const byte *srcP = &data[offsets[idx]];
int x1, y1, x2, y2;
// Write horizontal lines
while ((x1 = *srcP++) != 0xff) {
x2 = *srcP++;
y1 = *srcP++;
s.hLine(x1, y1, x2, 3);
}
// Write vertical lines
while ((x1 = *srcP++) != 0xff) {
y1 = *srcP++;
y2 = *srcP++;
s.vLine(x1, y1, y2, 3);
}
}
}
/*------------------------------------------------------------------------*/
FontManager::FontManager() : _font1(nullptr), _font2(nullptr) {
_printMaxX = 0;
Common::fill(&Font::_fontColors[0], &Font::_fontColors[4], 0);
}
void FontManager::load(Font *font1, Font *font2) {
_font1 = font1;
_font2 = font2;
}
} // End of namespace Access

View file

@ -39,21 +39,23 @@ public:
};
class Font {
private:
protected:
byte _firstCharIndex;
int _bitWidth;
int _height;
Common::Array<Graphics::Surface> _chars;
protected:
/**
* Constructor
*/
Font(byte firstCharIndex);
public:
static byte _fontColors[4];
public:
Font();
~Font();
/**
* Load the given font data
* Destructor
*/
void load(const int *fontIndex, const byte *fontData);
virtual ~Font();
/**
* Get the width of a given character
@ -87,15 +89,53 @@ public:
};
class AmazonFont : public Font {
private:
/**
* Load the given font data
*/
void load(const int *fontIndex, const byte *fontData);
public:
/**
* Constructor
*/
AmazonFont(const int *fontIndex, const byte *fontData) : Font(32) {
load(fontIndex, fontData);
}
};
class MartianFont : public Font {
private:
/**
* Load the given font data
*/
void load(Common::SeekableReadStream &s);
public:
/**
* Constructor
*/
MartianFont(int height, Common::SeekableReadStream &s);
};
class FontManager {
public:
FontVal _charSet;
FontVal _charFor;
int _printMaxX;
Font _font1;
Font _font2;
Font *_font1;
Font *_font2;
public:
/**
* Constructor
*/
FontManager();
/**
* Set the fonts
*/
void load(Font *font1, Font *font2);
};
} // End of namespace Access

View file

@ -397,7 +397,7 @@ void InventoryManager::outlineIcon(int itemIndex) {
screen.frameRect(_invCoords[itemIndex], 7);
Common::String s = _tempLOff[itemIndex];
Font &font = _vm->_fonts._font2;
Font &font = *_vm->_fonts._font2;
int strWidth = font.stringWidth(s);
font._fontColors[0] = 0;

View file

@ -115,7 +115,7 @@ void MartianEngine::displayNote(const Common::String &msg) {
int width = 0;
bool lastLine = false;
do {
lastLine = _fonts._font1.getLine(lines, _screen->_maxChars * 6, line, width);
lastLine = _fonts._font1->getLine(lines, _screen->_maxChars * 6, line, width);
_bubbleBox->printString(line);
_screen->_printOrg = Common::Point(_screen->_printStart.x, _screen->_printOrg.y + 6);
@ -299,9 +299,8 @@ void MartianEngine::setupGame() {
}
// Miscellaneous
Amazon::AmazonResources &res = *((Amazon::AmazonResources *)_res);
_fonts._font1.load(&res.FONT6x6_INDEX[0], &res.FONT6x6_DATA[0]);
_fonts._font2.load(&res.FONT2_INDEX[0], &res.FONT2_DATA[0]);
Martian::MartianResources &res = *((Martian::MartianResources *)_res);
_fonts.load(res._font6x6, res._font3x5);
// Set player room and position
_player->_roomNumber = 7;
@ -314,7 +313,7 @@ void MartianEngine::showDeathText(Common::String msg) {
int width = 0;
bool lastLine;
do {
lastLine = _fonts._font2.getLine(msg, _screen->_maxChars * 6, line, width);
lastLine = _fonts._font2->getLine(msg, _screen->_maxChars * 6, line, width);
// Draw the text
_bubbleBox->printString(line);

View file

@ -27,6 +27,35 @@ namespace Access {
namespace Martian {
MartianResources::~MartianResources() {
delete _font6x6;
delete _font3x5;
}
void MartianResources::load(Common::SeekableReadStream &s) {
Resources::load(s);
uint count;
// Get the offset of the general shared data for the game
uint entryOffset = findEntry(_vm->getGameID(), 2, 0, (Common::Language)0);
s.seek(entryOffset);
// Read in the cursor list
count = s.readUint16LE();
CURSORS.resize(count);
for (uint idx = 0; idx < count; ++idx) {
uint count2 = s.readUint16LE();
CURSORS[idx].resize(count2);
s.read(&CURSORS[idx][0], count2);
}
// Load font data
_font6x6 = new MartianFont(6, s);
_font3x5 = new MartianFont(5, s);
}
/*------------------------------------------------------------------------*/
const int SIDEOFFR[] = { 4, 0, 7, 10, 3, 1, 2, 13, 0, 0, 0, 0 };
const int SIDEOFFL[] = { 11, 6, 1, 4, 10, 6, 1, 4, 0, 0, 0, 0 };
const int SIDEOFFU[] = { 1, 2, 0, 2, 2, 1, 1, 0, 0, 0, 0, 0 };

View file

@ -25,6 +25,7 @@
#include "common/scummsys.h"
#include "access/resources.h"
#include "access/font.h"
namespace Access {
@ -55,11 +56,17 @@ extern const byte _byte1EEB5[];
extern const int PICTURERANGE[][2];
class MartianResources : public Resources {
protected:
/**
* Load data from the access.dat file
*/
virtual void load(Common::SeekableReadStream &s);
public:
MartianFont *_font6x6;
MartianFont *_font3x5;
public:
MartianResources(AccessEngine *vm) : Resources(vm) {}
virtual ~MartianResources() {}
MartianResources(AccessEngine *vm) : Resources(vm), _font6x6(nullptr), _font3x5(nullptr) {}
virtual ~MartianResources();
};
#define MMRES (*((Martian::MartianResources *)_vm->_res))

View file

@ -203,7 +203,7 @@ void Scripts::printWatch() {
int width = 0;
bool lastLine;
do {
lastLine = _vm->_fonts._font2.getLine(msg, _vm->_screen->_maxChars * 6, line, width);
lastLine = _vm->_fonts._font2->getLine(msg, _vm->_screen->_maxChars * 6, line, width);
// Draw the text
_vm->_bubbleBox->printString(line);