[Scummvm-git-logs] scummvm master -> b4881f14514f31490cdd6f4426ec8ef1ef0aa9c1
sev-
noreply at scummvm.org
Sun May 14 21:12:49 UTC 2023
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:
b4881f1451 GRAPHICS: Support PC98 font ROM
Commit: b4881f14514f31490cdd6f4426ec8ef1ef0aa9c1
https://github.com/scummvm/scummvm/commit/b4881f14514f31490cdd6f4426ec8ef1ef0aa9c1
Author: Vladimir Serbinenko (phcoder at gmail.com)
Date: 2023-05-14T23:12:46+02:00
Commit Message:
GRAPHICS: Support PC98 font ROM
Changed paths:
graphics/sjis.cpp
graphics/sjis.h
diff --git a/graphics/sjis.cpp b/graphics/sjis.cpp
index bdaaeb11ab4..d6a601a3caf 100644
--- a/graphics/sjis.cpp
+++ b/graphics/sjis.cpp
@@ -48,13 +48,12 @@ FontSJIS *FontSJIS::createFont(const Common::Platform platform) {
if (ret->loadData())
return ret;
delete ret;
- } // TODO: PC98 font rom support
- /* else if (platform == Common::kPlatformPC98) {
- ret = new FontPC98();
- if (ret->loadData())
- return ret;
- delete ret;
- }*/
+ } else if (platform == Common::kPlatformPC98) {
+ FontPC98 *ret98 = new FontPC98();
+ if (ret98->loadBMPData() || ret98->loadData())
+ return ret98;
+ delete ret98;
+ }
// Try ScummVM's font.
ret = new FontSjisSVM(platform);
@@ -448,6 +447,131 @@ bool FontTowns::hasFeature(int feat) const {
return (features & feat) ? true : false;
}
+// PC98 ROM font
+
+bool FontPC98::loadData() {
+ Common::ScopedPtr<Common::SeekableReadStream> data(SearchMan.createReadStreamForMember("FONT.ROM"));
+ if (!data)
+ return false;
+
+ // First comes 8x8 font that we skip
+ data->seek(256 * 8, SEEK_SET);
+ data->read(_fontData8x16, kFont8x16Chars * 16);
+
+ for (uint i = 0; i < kFont16x16Chars; i++) {
+ byte block[32];
+ data->read(block, 32);
+ // PC98 uses 2 8x16 bitmaps to form one 16x16 glyph. Reshuffle to make a single 16x16 glyph
+ for (uint j = 0; j < 16; j++)
+ _fontData16x16[i * 32 + 2 * j] = block[j];
+ for (uint j = 0; j < 16; j++)
+ _fontData16x16[i * 32 + 2 * j + 1] = block[j + 16];
+ }
+
+ return !data->err();
+}
+
+bool FontPC98::loadBMPData() {
+ Common::ScopedPtr<Common::SeekableReadStream> data(SearchMan.createReadStreamForMember("FONT.BMP"));
+ if (!data)
+ return false;
+
+ if (data->readUint16BE() != MKTAG16('B', 'M')) {
+ warning("Invalid header in font.bmp");
+ return false;
+ }
+
+ data->readUint32LE();
+ data->readUint16LE();
+ data->readUint16LE();
+ uint32 imageOffset = data->readUint32LE();
+
+ uint32 infoSize = data->readUint32LE();
+
+ if (infoSize != 40) {
+ warning("Unexpected header size in font.bmp");
+ return false;
+ }
+
+ if (data->readUint32LE() != 2048 || data->readUint32LE() != 2048) {
+ warning("font.bmp needs to be 2048x2048");
+ return false;
+ }
+
+ if (data->readUint16LE() != 1) {
+ warning("font.bmp needs to be single-planed");
+ return false;
+ }
+
+ if (data->readUint16LE() != 1) {
+ warning("font.bmp needs to be 1bpp");
+ return false;
+ }
+
+ data->seek(imageOffset);
+
+ for (int row = 95; row >= 0; row--)
+ for (int y = 15; y >= 0; y--) {
+ // Skip 16 pixels
+ data->skip(2);
+ for (uint col = 0; col < 96; col++) {
+ byte a = data->readByte();
+ byte b = data->readByte();
+ uint point = row + col * 96;
+ if (point >= kFont16x16Chars)
+ continue;
+ _fontData16x16[point * 32 + y * 2] = ~a;
+ _fontData16x16[point * 32 + y * 2 + 1] = ~b;
+ }
+ data->skip((2048 - 96 * 16 - 16) / 8);
+ }
+
+ data->seek(imageOffset + (2048 - 16) * (2048 / 8));
+
+ for (int y = 15; y >= 0; y--)
+ for (uint i = 0; i < kFont8x16Chars; i++)
+ _fontData8x16[i * 16 + y] = ~data->readByte();
+
+ return true;
+}
+
+const uint8 *FontPC98::getCharData(uint16 ch) const {
+ if (ch < kFont8x16Chars)
+ return _fontData8x16 + ch * 16;
+
+ uint8 lo = ch >> 8, hi = ch & 0xff;
+
+ uint hiblock = 0;
+
+ if (hi >= 0x81 && hi <= 0x9f)
+ hiblock = hi - 0x81;
+ else if (hi >= 0xe0 && hi <= 0xee)
+ hiblock = hi - 0x81 - 0x40;
+ else
+ return nullptr;
+
+ uint glyph = hiblock * 192;
+
+ if (lo >= 0x3f && lo <= 0x7e)
+ glyph += lo - 0x3f;
+ else if (lo >= 0x80 && lo <= 0x9d)
+ glyph += lo - 0x80 + 64;
+ else if (lo >= 0x9e && lo <= 0xfc)
+ glyph += lo - 0x9e + 96;
+ else
+ return nullptr;
+
+ if (glyph >= kFont16x16Chars)
+ return nullptr;
+ else
+ return _fontData16x16 + glyph * 32;
+}
+
+bool FontPC98::hasFeature(int feat) const {
+ static const int features = kFeatDefault | kFeatOutline | kFeatShadow | kFeatFMTownsShadow | kFeatFlipped | kFeatFatPrint;
+ return (features & feat) ? true : false;
+}
+
// PC-Engine ROM font
bool FontPCEngine::loadData() {
diff --git a/graphics/sjis.h b/graphics/sjis.h
index a0a1ca43687..681e58d6897 100644
--- a/graphics/sjis.h
+++ b/graphics/sjis.h
@@ -233,6 +233,38 @@ private:
bool hasFeature(int feat) const;
};
+/**
+ * PC98 ROM based SJIS compatible font.
+ *
+ * This is used in KYRA and SCI.
+ */
+class FontPC98 : public FontSJISBase {
+public:
+ /**
+ * Loads the ROM data from "FONT.ROM".
+ */
+ bool loadData();
+
+ /**
+ * Loads the ROM data from "FONT.ROM".
+ */
+ bool loadBMPData();
+
+protected:
+ const uint8 *getCharData(uint16 c) const override;
+
+private:
+ enum {
+ kFont16x16Chars = 8831,
+ kFont8x16Chars = 256
+ };
+
+ uint8 _fontData16x16[kFont16x16Chars * 32];
+ uint8 _fontData8x16[kFont8x16Chars * 16];
+
+ bool hasFeature(int feat) const;
+};
+
/**
* PC-Engine System Card based SJIS compatible font.
*
More information about the Scummvm-git-logs
mailing list