diff options
-rw-r--r-- | engines/kyra/screen.cpp | 277 | ||||
-rw-r--r-- | engines/kyra/screen.h | 14 |
2 files changed, 25 insertions, 266 deletions
diff --git a/engines/kyra/screen.cpp b/engines/kyra/screen.cpp index 963dc3f4d6..f66d2bea91 100644 --- a/engines/kyra/screen.cpp +++ b/engines/kyra/screen.cpp @@ -26,7 +26,10 @@ #include "common/endian.h" #include "common/system.h" + #include "graphics/cursorman.h" +#include "graphics/sjis.h" + #include "kyra/screen.h" #include "kyra/kyra_v1.h" #include "kyra/resource.h" @@ -43,6 +46,8 @@ Screen::Screen(KyraEngine_v1 *vm, OSystem *system) _drawShapeVar3 = 1; _drawShapeVar4 = 0; _drawShapeVar5 = 0; + + _sjisFont = 0; } Screen::~Screen() { @@ -56,8 +61,7 @@ Screen::~Screen() { _fonts[f].fontData = NULL; } - delete[] _sjisFontData; - delete[] _sjisTempPage; + delete _sjisFont; delete _screenPalette; delete _internFadePalette; delete[] _decodeShapeBuffer; @@ -78,8 +82,6 @@ bool Screen::init() { _useSJIS = false; _use16ColorMode = _vm->gameFlags().use16ColorMode; - _sjisTempPage = _sjisFontData = 0; - if (_vm->gameFlags().useHiResOverlay) { _useOverlays = true; _useSJIS = (_vm->gameFlags().lang == Common::JA_JPN); @@ -94,14 +96,17 @@ bool Screen::init() { } if (_useSJIS) { - if (!_sjisFontData) { + if (!_sjisFont) { // we use the FM-Towns font rom for PC-98, too, until we feel // like adding support for the PC-98 font //if (_vm->gameFlags().platform == Common::kPlatformFMTowns) { // FM-Towns - _sjisFontData = _vm->resource()->fileData("FMT_FNT.ROM", 0); - if (!_sjisFontData) - error("missing font rom ('FMT_FNT.ROM') required for this version"); + Common::SeekableReadStream *rom = _vm->resource()->createReadStream("FMT_FNT.ROM"); + Graphics::FontTowns *townsFont = new Graphics::FontTowns(); + if (!rom || !townsFont || !townsFont->loadFromStream(*rom)) + error("Could not load font rom ('FMT_FNT.ROM') required for this version"); + _sjisFont = townsFont; + delete rom; /*} else { // PC-98 _sjisFontData = _vm->resource()->fileData("FONT.ROM", 0); @@ -109,13 +114,6 @@ bool Screen::init() { error("missing font rom ('FONT.ROM') required for this version"); }*/ } - - if (!_sjisTempPage) { - _sjisTempPage = new uint8[420]; - assert(_sjisTempPage); - _sjisTempPage2 = _sjisTempPage + 60; - _sjisSourceChar = _sjisTempPage + 384; - } } } @@ -1027,8 +1025,8 @@ int Screen::getCharWidth(uint16 c) const { if (_vm->gameFlags().platform == Common::kPlatformAmiga) return 0; - if (c & 0xFF00) - return SJIS_CHARSIZE >> 1; + if ((c & 0xFF00) && _sjisFont) + return _sjisFont->getFontWidth() >> 1; if (_fonts[_currentFont].lastGlyph < c) return 0; @@ -1115,7 +1113,7 @@ void Screen::printText(const char *str, int x, int y, uint8 color1, uint8 color2 c = READ_LE_UINT16(str - 1); ++str; charWidth = getCharWidth(c); - charHeight = SJIS_CHARSIZE >> 1; + charHeight = _sjisFont->getFontHeight() >> 1; drawCharSJIS(c, x, y); } @@ -3007,93 +3005,6 @@ void Screen::copyOverlayRegion(int x, int y, int x2, int y2, int w, int h, int s } } -// SJIS rendering - -namespace { -int SJIStoFMTChunk(int f, int s) { // copied from scumm\charset.cpp - enum { - KANA = 0, - KANJI = 1, - EKANJI = 2 - }; - int base = s - ((s + 1) % 32); - int c = 0, p = 0, chunk_f = 0, chunk = 0, cr = 0, kanjiType = KANA; - - if (f >= 0x81 && f <= 0x84) kanjiType = KANA; - if (f >= 0x88 && f <= 0x9f) kanjiType = KANJI; - if (f >= 0xe0 && f <= 0xea) kanjiType = EKANJI; - - if ((f > 0xe8 || (f == 0xe8 && base >= 0x9f)) || (f > 0x90 || (f == 0x90 && base >= 0x9f))) { - c = 48; //correction - p = -8; //correction - } - - if (kanjiType == KANA) {//Kana - chunk_f = (f - 0x81) * 2; - } else if (kanjiType == KANJI) {//Standard Kanji - p += f - 0x88; - chunk_f = c + 2 * p; - } else if (kanjiType == EKANJI) {//Enhanced Kanji - p += f - 0xe0; - chunk_f = c + 2 * p; - } - - // Base corrections - if (base == 0x7f && s == 0x7f) - base -= 0x20; - if (base == 0x9f && s == 0xbe) - base += 0x20; - if (base == 0xbf && s == 0xde) - base += 0x20; - //if (base == 0x7f && s == 0x9e) - // base += 0x20; - - switch (base) { - case 0x3f: - cr = 0; //3f - if (kanjiType == KANA) chunk = 1; - else if (kanjiType == KANJI) chunk = 31; - else if (kanjiType == EKANJI) chunk = 111; - break; - case 0x5f: - cr = 0; //5f - if (kanjiType == KANA) chunk = 17; - else if (kanjiType == KANJI) chunk = 47; - else if (kanjiType == EKANJI) chunk = 127; - break; - case 0x7f: - cr = -1; //80 - if (kanjiType == KANA) chunk = 9; - else if (kanjiType == KANJI) chunk = 63; - else if (kanjiType == EKANJI) chunk = 143; - break; - case 0x9f: - cr = 1; //9e - if (kanjiType == KANA) chunk = 2; - else if (kanjiType == KANJI) chunk = 32; - else if (kanjiType == EKANJI) chunk = 112; - break; - case 0xbf: - cr = 1; //be - if (kanjiType == KANA) chunk = 18; - else if (kanjiType == KANJI) chunk = 48; - else if (kanjiType == EKANJI) chunk = 128; - break; - case 0xdf: - cr = 1; //de - if (kanjiType == KANA) chunk = 10; - else if (kanjiType == KANJI) chunk = 64; - else if (kanjiType == EKANJI) chunk = 144; - break; - default: - debug(4, "Invalid Char! f %x s %x base %x c %d p %d", f, s, base, c, p); - } - - debug(6, "Kanji: %c%c f 0x%x s 0x%x base 0x%x c %d p %d chunk %d cr %d index %d", f, s, f, s, base, c, p, chunk, cr, ((chunk_f + chunk) * 32 + (s - base)) + cr); - return ((chunk_f + chunk) * 32 + (s - base)) + cr; -} -} // end of anonymous namespace - void Screen::drawCharSJIS(uint16 c, int x, int y) { int color1, color2; @@ -3107,12 +3018,8 @@ void Screen::drawCharSJIS(uint16 c, int x, int y) { color2 = _textColorsMap[0]; } - memset(_sjisTempPage2, _sjisInvisibleColor, 324); - memset(_sjisSourceChar, 0, 36); - memcpy(_sjisSourceChar, _sjisFontData + 0x20 * SJIStoFMTChunk(c & 0xff, c >> 8), 0x20); - if (_curPage == 0 || _curPage == 1) - addDirtyRect(x, y, SJIS_CHARSIZE >> 1, SJIS_CHARSIZE >> 1); + addDirtyRect(x, y, _sjisFont->getFontWidth() >> 1, _sjisFont->getFontHeight() >> 1); x <<= 1; y <<= 1; @@ -3124,154 +3031,10 @@ void Screen::drawCharSJIS(uint16 c, int x, int y) { } destPage += y * 640 + x; - uint8 *src = 0, *dst = 0; - - if (color2 != _sjisInvisibleColor) { - // draw color2 shadow - src = _sjisSourceChar; - dst = _sjisTempPage2; - for (int i = 0; i < SJIS_CHARSIZE; i++) { - *((uint16*)dst) = READ_LE_UINT16(src); - dst += 2; src += 2; - *dst++ = 0; - } - - src = _sjisTempPage2; - dst = _sjisTempPage; - memset(dst, 0, 60); - for (int i = 0; i < 48; i++) - *dst++ |= *src++; - - src = _sjisTempPage2; - dst = _sjisTempPage + 3; - for (int i = 0; i < 48; i++) - *dst++ |= *src++; - - src = _sjisTempPage2; - dst = _sjisTempPage + 6; - for (int i = 0; i < 48; i++) - *dst++ |= *src++; - - for (int i = 0; i < 2; i++) { - src = _sjisTempPage; - for (int ii = 0; ii < SJIS_CHARSIZE; ii++) { - uint8 cy2 = 0; - uint8 cy1 = 0; - for (int iii = 0; iii < 3; iii++) { - cy1 = *src & 1; - *src |= ((*src >> 1) | (cy2 << 7)); - cy2 = cy1; - src++; - } - } - } - - src = _sjisTempPage2; - for (int i = 0; i < SJIS_CHARSIZE; i++) { - uint8 cy2 = 0; - uint8 cy1 = 0; - for (int ii = 0; ii < 3; ii++) { - cy1 = *src & 1; - *src = ((*src >> 1) | (cy2 << 7)); - cy2 = cy1; - src++; - } - } - - src = _sjisTempPage2; - dst = _sjisTempPage + 3; - for (int i = 0; i < 48; i++) - *dst++ ^= *src++; - - memset(_sjisTempPage2, _sjisInvisibleColor, 324); - src = _sjisTempPage; - dst = _sjisTempPage2; - - uint8 height = SJIS_CHARSIZE * 3; - uint8 width = SJIS_CHARSIZE; - if (color2 & 0xff00) { - height -= 3; - width--; - dst += 0x13; - } - - for (int i = 0; i < height; i++) { - uint8 rs = *src++; - for (int ii = 0; ii < 8; ii++) { - if (rs & 0x80) - *dst = (color2 & 0xff); - rs <<= 1; - dst++; - - if (!--width) { - width = SJIS_CHARSIZE; - if (color2 & 0xff00) { - width--; - dst++; - } - break; - } - } - } - } - - // draw color1 char - src = _sjisSourceChar; - dst = _sjisTempPage; - - for (int i = 0; i < SJIS_CHARSIZE; i++) { - *(uint16*)dst = READ_LE_UINT16(src); - dst += 2; src += 2; - *dst++ = 0; - } - - src = _sjisTempPage; - dst = _sjisTempPage2; - if (color2 != _sjisInvisibleColor) - color1 = (color1 & 0xff) | 0x100; - - uint8 height = SJIS_CHARSIZE * 3; - uint8 width = SJIS_CHARSIZE; - if (color1 & 0xff00) { - height -= 3; - width--; - dst += 0x13; - } - - for (int i = 0; i < height; i++) { - uint8 rs = *src++; - for (int ii = 0; ii < 8; ii++) { - if (rs & 0x80) - *dst = (color1 & 0xff); - rs <<= 1; - dst++; - - if (!--width) { - width = SJIS_CHARSIZE; - if (color1 & 0xff00) { - width--; - dst++; - } - break; - } - } - } - - // copy char to surface - src = _sjisTempPage2; - dst = destPage; - int pitch = 640 - SJIS_CHARSIZE; - - for (int i = 0; i < SJIS_CHARSIZE; i++) { - for (int ii = 0; ii < SJIS_CHARSIZE; ii++) { - if (*src != _sjisInvisibleColor) - *dst = *src; - src++; - dst++; - } - dst += pitch; - } + // 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); } #pragma mark - diff --git a/engines/kyra/screen.h b/engines/kyra/screen.h index 956bd7107e..a7a7efa7ca 100644 --- a/engines/kyra/screen.h +++ b/engines/kyra/screen.h @@ -35,6 +35,10 @@ class OSystem; +namespace Graphics { +class FontSJIS; +} // end of namespace Graphics + namespace Kyra { typedef Common::Functor0<void> UpdateFunctor; @@ -360,11 +364,6 @@ protected: void drawCharANSI(uint8 c, int x, int y); void drawCharSJIS(uint16 c, int x, int y); - enum { - SJIS_CHARSIZE = 18, - SJIS_CHARS = 8192 - }; - int16 encodeShapeAndCalculateSize(uint8 *from, uint8 *to, int size); template<bool noXor> static void wrapped_decodeFrameDelta(uint8 *dst, const uint8 *src); @@ -377,10 +376,7 @@ protected: bool _useSJIS; bool _use16ColorMode; - uint8 *_sjisFontData; - uint8 *_sjisTempPage; - uint8 *_sjisTempPage2; - uint8 *_sjisSourceChar; + Graphics::FontSJIS *_sjisFont; uint8 _sjisInvisibleColor; Palette *_screenPalette; |