aboutsummaryrefslogtreecommitdiff
path: root/engines/kyra/screen.cpp
diff options
context:
space:
mode:
authorJohannes Schickel2009-08-09 22:46:43 +0000
committerJohannes Schickel2009-08-09 22:46:43 +0000
commit300297d557e0fbd75ccb503233159b1ad7445e05 (patch)
treeaef0e0236204f7ca0a60d995c24de2feb2f38308 /engines/kyra/screen.cpp
parent518cb968b23bfb37cd1248c3a884d004a3309bba (diff)
downloadscummvm-rg350-300297d557e0fbd75ccb503233159b1ad7445e05.tar.gz
scummvm-rg350-300297d557e0fbd75ccb503233159b1ad7445e05.tar.bz2
scummvm-rg350-300297d557e0fbd75ccb503233159b1ad7445e05.zip
Add support for the font format used in Kyrandia 1 Amiga. (font colors are wrong though)
svn-id: r43187
Diffstat (limited to 'engines/kyra/screen.cpp')
-rw-r--r--engines/kyra/screen.cpp119
1 files changed, 115 insertions, 4 deletions
diff --git a/engines/kyra/screen.cpp b/engines/kyra/screen.cpp
index 2628ecdf65..e05e18d96f 100644
--- a/engines/kyra/screen.cpp
+++ b/engines/kyra/screen.cpp
@@ -949,8 +949,9 @@ bool Screen::loadFont(FontId fontId, const char *filename) {
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 @@ void Screen::decodeFrameDeltaPage(uint8 *dst, const uint8 *src, int pitch, bool
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 @@ void DOSFont::unload() {
_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) {