[Scummvm-git-logs] scummvm master -> af6034efcdf9ff12e037f03626caf2c89c11a6ed

dreammaster dreammaster at scummvm.org
Sat Jul 21 04:06:06 CEST 2018


This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

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


Commit: af6034efcdf9ff12e037f03626caf2c89c11a6ed
    https://github.com/scummvm/scummvm/commit/af6034efcdf9ff12e037f03626caf2c89c11a6ed
Author: Paul Gilbert (dreammaster at scummvm.org)
Date: 2018-07-20T19:05:56-07:00

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

Changed paths:
    devtools/create_access/create_access_dat.cpp
    dists/engine-data/access.dat
    engines/access/access.cpp
    engines/access/amazon/amazon_game.cpp
    engines/access/amazon/amazon_logic.cpp
    engines/access/amazon/amazon_resources.cpp
    engines/access/amazon/amazon_resources.h
    engines/access/bubble_box.cpp
    engines/access/font.cpp
    engines/access/font.h
    engines/access/inventory.cpp
    engines/access/martian/martian_game.cpp
    engines/access/martian/martian_resources.cpp
    engines/access/martian/martian_resources.h
    engines/access/scripts.cpp


diff --git a/devtools/create_access/create_access_dat.cpp b/devtools/create_access/create_access_dat.cpp
index a1591ef..0fac1d8 100644
--- a/devtools/create_access/create_access_dat.cpp
+++ b/devtools/create_access/create_access_dat.cpp
@@ -56,7 +56,7 @@ File outputFile;
 
 void writeHeader(int numExecutables);
 void writeAmazonCommonData();
-void writeMartianCommonData();
+void writeMartianCommonData(int argc, char *argv[]);
 bool processExecutable(int idx, const char *name);
 
 void NORETURN_PRE error(const char *s, ...) {
@@ -78,7 +78,7 @@ int main(int argc, char *argv[]) {
 
 	// Write out entries containing common data for the games
 	writeAmazonCommonData();
-	writeMartianCommonData();
+	writeMartianCommonData(argc, argv);
 
 	// Iterate through processing each specified executable
 	outputFile.seek(0, SEEK_END);
@@ -141,7 +141,7 @@ void writeAmazonCommonData() {
 }
 
 
-void writeMartianCommonData() {
+void writeMartianCommonData(int argc, char *argv[]) {
 	// Write out the header entry
 	outputFile.seek(16);
 	outputFile.writeByte(2);    // Martian
@@ -152,12 +152,69 @@ void writeMartianCommonData() {
 
 	// Write out cursor list
 	outputFile.seek(0, SEEK_END);
-	outputFile.writeByte(MARTIAN_NUM_CURSORS);
+	outputFile.writeWord(MARTIAN_NUM_CURSORS);
 
 	for (uint idx = 0; idx < MARTIAN_NUM_CURSORS; ++idx) {
 		outputFile.writeWord(Martian::CURSOR_SIZES[idx]);
 		outputFile.write(Martian::CURSORS[idx], Martian::CURSOR_SIZES[idx]);
 	}
+
+	// Check for the presence of a Martian Memorandum executable
+	for (int idx = 2; idx < argc; ++idx) {
+		File exeFile;
+		if (!exeFile.open(argv[idx]))
+			continue;
+
+		// Total up the first 256 bytes of the executable as a simplified checksum
+		uint fileChecksum = 0;
+		for (int idx = 0; idx < 256; ++idx)
+			fileChecksum += exeFile.readByte();
+
+		if (fileChecksum == 10454) {
+			// Write out font data
+			const int DATA_SEGMENT = 0x9600;
+			#define FONT_COUNT 119
+			const int FONT_WIDTHS[2] = { 0x47E6, 0x4C9C };
+			const int FONT_CHAR_OFFSETS[2] = { 0x46F8, 0x4BAE };
+			const int FONT_DATA_SIZE[2] = { 849, 907 };
+			int idx, dataOffset;
+
+			for (int fontNum = 0; fontNum < 2; ++fontNum) {
+				// Write out sizes
+				outputFile.writeWord(FONT_COUNT);
+				outputFile.writeWord(FONT_DATA_SIZE[fontNum]);
+
+				// Write out character widths
+				exeFile.seek(DATA_SEGMENT + FONT_WIDTHS[fontNum]);
+				outputFile.write(exeFile, FONT_COUNT);
+
+				// Write out character offsets
+				uint offsets[FONT_COUNT];
+				exeFile.seek(DATA_SEGMENT + FONT_CHAR_OFFSETS[fontNum]);
+				for (int idx = 0; idx < FONT_COUNT; ++idx) {
+					offsets[idx] = exeFile.readWord();
+					if (idx == 0)
+						dataOffset = offsets[0];
+					offsets[idx] -= dataOffset;
+					assert(offsets[idx] < FONT_DATA_SIZE[fontNum]);
+
+					outputFile.writeWord(offsets[idx]);
+				}
+
+				// Write out character data
+				exeFile.seek(DATA_SEGMENT + dataOffset);
+				outputFile.write(exeFile, FONT_DATA_SIZE[fontNum]);
+			}
+
+			return;
+		}
+	}
+
+	// No executable found, so store 0 size fonts
+	outputFile.writeWord(0);
+	outputFile.writeWord(0);
+	outputFile.writeWord(0);
+	outputFile.writeWord(0);
 }
 
 bool processExecutable(int exeIdx, const char *name) {
@@ -262,10 +319,10 @@ bool processExecutable(int exeIdx, const char *name) {
 		printf("It needs to be first unpacked before it can be used with this tool.\n");
 		return false;
 
-	case 0:
-		// Martian Memorandum English
+	case 10454:
+		// Martian Memorandum English decompressed
 		gameId = 2;
-		dataSegmentOffset = 0x8d78;
+		dataSegmentOffset = 0x9600;
 		filenamesOffset = dataSegmentOffset + 0x373A;
 		numFilenames = 80;
 		charsStart = dataSegmentOffset + 0x40F2;
@@ -278,7 +335,7 @@ bool processExecutable(int exeIdx, const char *name) {
 		deathScreens = Martian::DEATH_SCREENS_ENG;
 		deathText = &Martian::DEATH_TEXT_ENG[0];
 		numDeaths = sizeof(Martian::DEATH_SCREENS_ENG);
-		numItems = 85;
+		numItems = 55;
 		itemNames = &Martian::INVENTORY_NAMES_ENG[0];
 		comboTable = nullptr;
 		break;
diff --git a/dists/engine-data/access.dat b/dists/engine-data/access.dat
index e909038..3bf521b 100644
Binary files a/dists/engine-data/access.dat and b/dists/engine-data/access.dat differ
diff --git a/engines/access/access.cpp b/engines/access/access.cpp
index c1af190..6d000cc 100644
--- a/engines/access/access.cpp
+++ b/engines/access/access.cpp
@@ -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;
diff --git a/engines/access/amazon/amazon_game.cpp b/engines/access/amazon/amazon_game.cpp
index 8467d8b..065952e 100644
--- a/engines/access/amazon/amazon_game.cpp
+++ b/engines/access/amazon/amazon_game.cpp
@@ -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);
 
diff --git a/engines/access/amazon/amazon_logic.cpp b/engines/access/amazon/amazon_logic.cpp
index 5a0f797..793545d 100644
--- a/engines/access/amazon/amazon_logic.cpp
+++ b/engines/access/amazon/amazon_logic.cpp
@@ -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));
 }
 
diff --git a/engines/access/amazon/amazon_resources.cpp b/engines/access/amazon/amazon_resources.cpp
index 7dbe1c9..fb5e01c 100644
--- a/engines/access/amazon/amazon_resources.cpp
+++ b/engines/access/amazon/amazon_resources.cpp
@@ -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]);
 }
 
 /*------------------------------------------------------------------------*/
diff --git a/engines/access/amazon/amazon_resources.h b/engines/access/amazon/amazon_resources.h
index 20d90cc..6ce50f7 100644
--- a/engines/access/amazon/amazon_resources.h
+++ b/engines/access/amazon/amazon_resources.h
@@ -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))
diff --git a/engines/access/bubble_box.cpp b/engines/access/bubble_box.cpp
index 29b58a3..0630622 100644
--- a/engines/access/bubble_box.cpp
+++ b/engines/access/bubble_box.cpp
@@ -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();
diff --git a/engines/access/font.cpp b/engines/access/font.cpp
index 8e02f80..b098f25 100644
--- a/engines/access/font.cpp
+++ b/engines/access/font.cpp
@@ -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
diff --git a/engines/access/font.h b/engines/access/font.h
index 9234078..4614cf6 100644
--- a/engines/access/font.h
+++ b/engines/access/font.h
@@ -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
diff --git a/engines/access/inventory.cpp b/engines/access/inventory.cpp
index e9874cd..75e5526 100644
--- a/engines/access/inventory.cpp
+++ b/engines/access/inventory.cpp
@@ -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;
diff --git a/engines/access/martian/martian_game.cpp b/engines/access/martian/martian_game.cpp
index 5382cd9..41c8419 100644
--- a/engines/access/martian/martian_game.cpp
+++ b/engines/access/martian/martian_game.cpp
@@ -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);
 
diff --git a/engines/access/martian/martian_resources.cpp b/engines/access/martian/martian_resources.cpp
index 2b0479a..ee1f1c3 100644
--- a/engines/access/martian/martian_resources.cpp
+++ b/engines/access/martian/martian_resources.cpp
@@ -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 };
diff --git a/engines/access/martian/martian_resources.h b/engines/access/martian/martian_resources.h
index 76765aa..6b01ee3 100644
--- a/engines/access/martian/martian_resources.h
+++ b/engines/access/martian/martian_resources.h
@@ -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))
diff --git a/engines/access/scripts.cpp b/engines/access/scripts.cpp
index a0b4ef6..e9103a2 100644
--- a/engines/access/scripts.cpp
+++ b/engines/access/scripts.cpp
@@ -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);
 





More information about the Scummvm-git-logs mailing list