diff options
-rw-r--r-- | engines/kyra/screen.cpp | 12 | ||||
-rw-r--r-- | graphics/sjis.cpp | 56 | ||||
-rw-r--r-- | graphics/sjis.h | 27 |
3 files changed, 79 insertions, 16 deletions
diff --git a/engines/kyra/screen.cpp b/engines/kyra/screen.cpp index f66d2bea91..079529f1ef 100644 --- a/engines/kyra/screen.cpp +++ b/engines/kyra/screen.cpp @@ -114,9 +114,12 @@ bool Screen::init() { error("missing font rom ('FONT.ROM') required for this version"); }*/ } + + _sjisFont->enableShadow(!_use16ColorMode); } } + _curPage = 0; uint8 *pagePtr = new uint8[SCREEN_PAGE_SIZE * 8]; for (int pageNum = 0; pageNum < SCREEN_PAGE_NUM; pageNum += 2) @@ -3016,6 +3019,9 @@ void Screen::drawCharSJIS(uint16 c, int x, int y) { } else { color1 = _textColorsMap[1]; color2 = _textColorsMap[0]; + + if (color2 == _sjisInvisibleColor) + _sjisFont->enableShadow(false); } if (_curPage == 0 || _curPage == 1) @@ -3032,9 +3038,9 @@ void Screen::drawCharSJIS(uint16 c, int x, int y) { destPage += y * 640 + x; - // We used to have shadow around the gylphs, with the old drawing code, but that didn't - // match the original. - _sjisFont->drawChar(destPage, c, 640, 1, color1); + _sjisFont->drawChar(destPage, c, 640, 1, color1, color2); + + _sjisFont->enableShadow(!_use16ColorMode); } #pragma mark - diff --git a/graphics/sjis.cpp b/graphics/sjis.cpp index 4421a86eef..1478c1c286 100644 --- a/graphics/sjis.cpp +++ b/graphics/sjis.cpp @@ -35,8 +35,43 @@ bool FontTowns::loadFromStream(Common::ReadStream &stream) { } template<typename Color> +void FontTowns::drawCharInternShadow(const uint16 *glyph, uint8 *dst, int pitch, Color c1, Color c2) const { + uint32 outlineGlyph[18]; + memset(outlineGlyph, 0, sizeof(outlineGlyph)); + + // Create an outline map including the original character + const uint16 *src = glyph; + for (int i = 0; i < 16; ++i) { + uint32 line = *src++; + line = (line << 2) | (line << 1) | (line << 0); + + outlineGlyph[i + 0] |= line; + outlineGlyph[i + 1] |= line; + outlineGlyph[i + 2] |= line; + } + + uint8 *dstLine = dst; + for (int y = 0; y < 18; ++y) { + Color *lineBuf = (Color *)dstLine; + uint32 line = outlineGlyph[y]; + + for (int x = 0; x < 18; ++x) { + if (line & 0x20000) + *lineBuf = c2; + line <<= 1; + ++lineBuf; + } + + dstLine += pitch; + } + + // draw the original char + drawCharIntern<Color>(glyph, dst + pitch + 1, pitch, c1); +} + +template<typename Color> void FontTowns::drawCharIntern(const uint16 *glyph, uint8 *dst, int pitch, Color c1) const { - for (int y = getFontHeight(); y > 0; --y) { + for (int y = 0; y < 16; ++y) { Color *lineBuf = (Color *)dst; uint16 line = *glyph++; @@ -51,15 +86,22 @@ void FontTowns::drawCharIntern(const uint16 *glyph, uint8 *dst, int pitch, Color } } -void FontTowns::drawChar(void *dst, uint16 ch, int pitch, int bpp, uint32 c1) const { +void FontTowns::drawChar(void *dst, uint16 ch, int pitch, int bpp, uint32 c1, uint32 c2) const { const uint16 *glyphSource = _fontData + sjisToChunk(ch & 0xFF, ch >> 8) * 16; - if (bpp == 1) - drawCharIntern<uint8>(glyphSource, (uint8 *)dst, pitch, c1); - else if (bpp == 2) - drawCharIntern<uint16>(glyphSource, (uint8 *)dst, pitch, c1); - else + if (bpp == 1) { + if (!_shadowEnabled) + drawCharIntern<uint8>(glyphSource, (uint8 *)dst, pitch, c1); + else + drawCharInternShadow<uint8>(glyphSource, (uint8 *)dst, pitch, c1, c2); + } else if (bpp == 2) { + if (!_shadowEnabled) + drawCharIntern<uint16>(glyphSource, (uint8 *)dst, pitch, c1); + else + drawCharInternShadow<uint16>(glyphSource, (uint8 *)dst, pitch, c1, c2); + } else { error("FontTowns::drawChar: unsupported bpp: %d", bpp); + } } uint FontTowns::sjisToChunk(uint8 f, uint8 s) { diff --git a/graphics/sjis.h b/graphics/sjis.h index f6277b62a4..63013dccf1 100644 --- a/graphics/sjis.h +++ b/graphics/sjis.h @@ -42,6 +42,14 @@ public: virtual ~FontSJIS() {} /** + * Enable shadow drawing. + * + * After changing shadow state, getFontHeight and getFontWidth might return + * different values! + */ + virtual void enableShadow(bool enable) {} + + /** * Returns the height of the font. */ virtual uint getFontHeight() const = 0; @@ -54,8 +62,8 @@ public: /** * Draws a SJIS encoded character on the given surface. */ - void drawChar(Graphics::Surface &dst, uint16 ch, int x, int y, uint32 c1) const { - drawChar(dst.getBasePtr(x, y), ch, c1, dst.pitch, dst.bytesPerPixel); + void drawChar(Graphics::Surface &dst, uint16 ch, int x, int y, uint32 c1, uint32 c2) const { + drawChar(dst.getBasePtr(x, y), ch, c1, c2, dst.pitch, dst.bytesPerPixel); } /** @@ -66,8 +74,9 @@ public: * @param pitch pitch of the destination buffer (size in *bytes*) * @param bpp bytes per pixel of the destination buffer * @param c1 forground color + * @param c2 shadow/outline color */ - virtual void drawChar(void *dst, uint16 ch, int pitch, int bpp, uint32 c1) const = 0; + virtual void drawChar(void *dst, uint16 ch, int pitch, int bpp, uint32 c1, uint32 c2) const = 0; }; /** @@ -82,19 +91,25 @@ public: */ bool loadFromStream(Common::ReadStream &stream); - uint getFontHeight() const { return 16; } - uint getFontWidth() const { return 16; } + void enableShadow(bool enable) { _shadowEnabled = enable; } - void drawChar(void *dst, uint16 ch, int pitch, int bpp, uint32 c1) const; + uint getFontHeight() const { return _shadowEnabled ? 18 : 16; } + uint getFontWidth() const { return _shadowEnabled ? 18 : 16; } + + void drawChar(void *dst, uint16 ch, int pitch, int bpp, uint32 c1, uint32 c2) const; private: template<typename Color> + void drawCharInternShadow(const uint16 *glyph, uint8 *dst, int pitch, Color c1, Color c2) const; + + template<typename Color> void drawCharIntern(const uint16 *glyph, uint8 *dst, int pitch, Color c1) const; enum { kFontRomSize = 262144 }; + bool _shadowEnabled; uint16 _fontData[kFontRomSize / 2]; static uint sjisToChunk(uint8 low, uint8 high); |