[Scummvm-cvs-logs] SF.net SVN: scummvm:[43187] scummvm/trunk/engines/kyra

lordhoto at users.sourceforge.net lordhoto at users.sourceforge.net
Mon Aug 10 00:46:43 CEST 2009


Revision: 43187
          http://scummvm.svn.sourceforge.net/scummvm/?rev=43187&view=rev
Author:   lordhoto
Date:     2009-08-09 22:46:43 +0000 (Sun, 09 Aug 2009)

Log Message:
-----------
Add support for the font format used in Kyrandia 1 Amiga. (font colors are wrong though)

Modified Paths:
--------------
    scummvm/trunk/engines/kyra/screen.cpp
    scummvm/trunk/engines/kyra/screen.h

Modified: scummvm/trunk/engines/kyra/screen.cpp
===================================================================
--- scummvm/trunk/engines/kyra/screen.cpp	2009-08-09 22:46:25 UTC (rev 43186)
+++ scummvm/trunk/engines/kyra/screen.cpp	2009-08-09 22:46:43 UTC (rev 43187)
@@ -949,8 +949,9 @@
 	Font *&fnt = _fonts[fontId];
 
 	if (!fnt) {
-		// FIXME: add font support for Amiga version
-		if (_vm->gameFlags().platform != Common::kPlatformAmiga)
+		if (_vm->gameFlags().platform == Common::kPlatformAmiga)
+			fnt = new AMIGAFont();
+		else
 			fnt = new DOSFont();
 
 		assert(fnt);
@@ -1979,8 +1980,8 @@
 		wrapped_decodeFrameDeltaPage<false>(dst, src, pitch);
 }
 
-void Screen::convertAmigaGfx(uint8 *data, int w, int h, int depth, bool wsa) {
-	const int planeWidth = (w + 7) / 8;
+void Screen::convertAmigaGfx(uint8 *data, int w, int h, int depth, bool wsa, int bytesPerPlane) {
+	const int planeWidth = (bytesPerPlane == -1) ? (w + 7) / 8 : bytesPerPlane; 
 	const int planeSize = planeWidth * h;
 	const uint imageSize = planeSize * depth;
 
@@ -3058,6 +3059,116 @@
 	_bitmapOffsets = 0;
 }
 
+
+AMIGAFont::AMIGAFont() {
+	_width = _height = 0;
+	memset(_chars, 0, sizeof(_chars));
+}
+
+bool AMIGAFont::load(Common::SeekableReadStream &file) {
+	const uint16 dataSize = file.readUint16BE();
+	if (dataSize + 2 != file.size())
+		return false;
+
+	_width = file.readByte();
+	_height = file.readByte();
+
+	// Read the character definition offset table
+	uint16 offsets[ARRAYSIZE(_chars)];
+	for (int i = 0; i < ARRAYSIZE(_chars); ++i)
+		offsets[i] = file.readUint16BE() + 4;
+
+	if (file.err())
+		return false;
+
+	for (int i = 0; i < ARRAYSIZE(_chars); ++i) {
+		file.seek(offsets[i], SEEK_SET);
+
+		_chars[i].yOffset = file.readByte();
+		_chars[i].xOffset = file.readByte();
+		_chars[i].width = file.readByte();
+		file.readByte(); // unused
+
+		// If the y offset is 255, then the character
+		// does not have any bitmap representation
+		if (_chars[i].yOffset != 255) {
+			Character::Graphics &g = _chars[i].graphics;
+
+			g.width = file.readUint16BE();
+			g.height = file.readUint16BE();
+
+			int depth = file.readByte();
+			int specialWidth = file.readByte();
+			int flags = file.readByte();
+			int bytesPerPlane = file.readByte();
+
+			assert(depth != 0 && specialWidth == 0 && flags == 0 && bytesPerPlane != 0);
+
+			// Allocate a temporary buffer to store the plane data
+			const int planesSize = bytesPerPlane * g.height * depth;
+			uint8 *tempData = new uint8[MAX(g.width * g.height, planesSize)];
+			assert(tempData);
+
+			file.read(tempData, planesSize);
+
+			// Convert the plane based graphics to our graphic format
+			Screen::convertAmigaGfx(tempData, g.width, g.height, depth, false, bytesPerPlane);
+
+			// Create a buffer perfectly fitting the character
+			g.bitmap = new uint8[g.width * g.height];
+			assert(g.bitmap);
+
+			memcpy(g.bitmap, tempData, g.width * g.height);
+			delete[] tempData;
+		}
+
+		if (file.err())
+			return false;
+	}
+
+	return !file.err();
+}
+
+int AMIGAFont::getCharWidth(uint8 c) const {
+	if (c >= 255)
+		return 0;
+	return _chars[c].width;
+}
+
+void AMIGAFont::drawChar(uint8 c, byte *dst, int pitch) const {
+	if (c >= 255)
+		return;
+
+	if (_chars[c].yOffset == 255)
+		return;
+
+	dst += _chars[c].yOffset * pitch;
+	dst += _chars[c].xOffset;
+
+	pitch -= _chars[c].graphics.width;
+
+	const uint8 *src = _chars[c].graphics.bitmap;
+	assert(src);
+
+	for (int y = 0; y < _chars[c].graphics.height; ++y) {
+		for (int x = 0; x < _chars[c].graphics.width; ++x) {
+			if (*src)
+				*dst = *src;
+			++src;
+			++dst;
+		}
+
+		dst += pitch;
+	}
+}
+
+void AMIGAFont::unload() {
+	_width = _height = 0;
+	for (int i = 0; i < ARRAYSIZE(_chars); ++i)
+		delete[] _chars[i].graphics.bitmap;
+	memset(_chars, 0, sizeof(_chars));
+}
+
 #pragma mark -
 
 Palette::Palette(const int numColors) : _palData(0), _numColors(numColors) {

Modified: scummvm/trunk/engines/kyra/screen.h
===================================================================
--- scummvm/trunk/engines/kyra/screen.h	2009-08-09 22:46:25 UTC (rev 43186)
+++ scummvm/trunk/engines/kyra/screen.h	2009-08-09 22:46:43 UTC (rev 43187)
@@ -135,6 +135,38 @@
 };
 
 /**
+ * Implementation of the Font interface for AMIGA fonts.
+ */
+class AMIGAFont : public Font {
+public:
+	AMIGAFont();
+	~AMIGAFont() { unload(); }
+
+	bool load(Common::SeekableReadStream &file);
+	int getHeight() const { return _height; }
+	int getWidth() const { return _width; }
+	int getCharWidth(uint8 c) const;
+	void setColorMap(const uint8 *src) {}
+	void drawChar(uint8 c, byte *dst, int pitch) const;
+
+private:
+	void unload();
+
+	int _width, _height;
+
+	struct Character {
+		uint8 yOffset, xOffset, width;
+
+		struct Graphics {
+			uint16 width, height;
+			uint8 *bitmap;
+		} graphics;
+	};
+
+	Character _chars[255];
+};
+
+/**
  * A class that manages KYRA palettes.
  *
  * This class stores the palette data as VGA RGB internally.
@@ -409,7 +441,7 @@
 	static void decodeFrameDelta(uint8 *dst, const uint8 *src, bool noXor = false);
 	static void decodeFrameDeltaPage(uint8 *dst, const uint8 *src, const int pitch, bool noXor);
 
-	static void convertAmigaGfx(uint8 *data, int w, int h, int depth = 5, bool wsa = false);
+	static void convertAmigaGfx(uint8 *data, int w, int h, int depth = 5, bool wsa = false, int bytesPerPlane = -1);
 	static void convertAmigaMsc(uint8 *data);
 
 protected:


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.




More information about the Scummvm-git-logs mailing list