aboutsummaryrefslogtreecommitdiff
path: root/engines/kyra/graphics/screen_eob.cpp
diff options
context:
space:
mode:
authorathrxx2019-11-26 22:07:32 +0100
committerathrxx2019-12-18 20:50:44 +0100
commit5a1162e99929d4a4d6351f91b8527fc0f205ad0f (patch)
tree1c4783b434cf9f4dbd1d26342b9f675ac26ab852 /engines/kyra/graphics/screen_eob.cpp
parent1f42999a7cd3b35df4f5611cf27c7d98974e8673 (diff)
downloadscummvm-rg350-5a1162e99929d4a4d6351f91b8527fc0f205ad0f.tar.gz
scummvm-rg350-5a1162e99929d4a4d6351f91b8527fc0f205ad0f.tar.bz2
scummvm-rg350-5a1162e99929d4a4d6351f91b8527fc0f205ad0f.zip
KYRA: (EOB/PC98) - fix Japanese text display
Diffstat (limited to 'engines/kyra/graphics/screen_eob.cpp')
-rw-r--r--engines/kyra/graphics/screen_eob.cpp349
1 files changed, 248 insertions, 101 deletions
diff --git a/engines/kyra/graphics/screen_eob.cpp b/engines/kyra/graphics/screen_eob.cpp
index 93be64ae3b..371b673760 100644
--- a/engines/kyra/graphics/screen_eob.cpp
+++ b/engines/kyra/graphics/screen_eob.cpp
@@ -92,6 +92,8 @@ bool Screen_EoB::init() {
_convertHiColorBuffer = new uint8[SCREEN_H * SCREEN_W];
enableHiColorMode(true);
loadFont(FID_SJIS_SMALL_FNT, "FONT.DMP");
+ } else if (_vm->game() == GI_EOB1 && _vm->gameFlags().platform == Common::kPlatformPC98) {
+ loadFont(FID_SJIS_SMALL_FNT, "FONT12.FNT");
}
if (_vm->gameFlags().useHiRes && _renderMode == Common::kRenderEGA) {
@@ -145,7 +147,7 @@ void Screen_EoB::setClearScreenDim(int dim) {
void Screen_EoB::clearCurDim() {
static const uint8 amigaColorMap[16] = { 0x00, 0x06, 0x1d, 0x1b, 0x1a, 0x17, 0x18, 0x0e, 0x19, 0x1c, 0x1c, 0x1e, 0x13, 0x0a, 0x11, 0x1f };
- fillRect(_curDim->sx << 3, _curDim->sy, ((_curDim->sx + _curDim->w) << 3) - 1, (_curDim->sy + _curDim->h) - 1, _isAmiga ? amigaColorMap[_curDim->unkA] : _curDim->unkA);
+ fillRect(_curDim->sx << 3, _curDim->sy, ((_curDim->sx + _curDim->w) << 3) - 1, (_curDim->sy + _curDim->h) - 1, _isAmiga ? amigaColorMap[_curDim->unkA] : _use16ColorMode ? 0 : _curDim->unkA);
}
void Screen_EoB::setMouseCursor(int x, int y, const byte *shape) {
@@ -236,14 +238,21 @@ void Screen_EoB::loadFileDataToPage(Common::SeekableReadStream *s, int pageNum,
}
void Screen_EoB::printShadedText(const char *string, int x, int y, int col1, int col2, int shadowCol) {
- if (_vm->gameFlags().platform != Common::kPlatformFMTowns) {
+ if (_vm->gameFlags().lang != Common::JA_JPN) {
printText(string, x - 1, y, shadowCol, col2);
printText(string, x, y + 1, shadowCol, 0);
printText(string, x - 1, y + 1, shadowCol, 0);
} else if (col2) {
fillRect(x, y, x + getTextWidth(string) - 1, y + getFontHeight() - 1, col2);
}
+
+ if (_vm->gameFlags().use16ColorMode)
+ _fonts[_currentFont]->setStyle(Font::kFSLeftShadow);
+
printText(string, x, y, col1, 0);
+
+ if (_vm->gameFlags().use16ColorMode)
+ _fonts[_currentFont]->setStyle(Font::kFSNone);
}
void Screen_EoB::loadShapeSetBitmap(const char *file, int tempPage, int destPage) {
@@ -1472,19 +1481,23 @@ const uint8 *Screen_EoB::getEGADitheringTable() {
}
bool Screen_EoB::loadFont(FontId fontId, const char *filename) {
- if (scumm_stricmp(filename, "FONT.DMP"))
- return Screen::loadFont(fontId, filename);
-
Font *&fnt = _fonts[fontId];
- int temp;
+ int temp = 0;
+ if (fnt)
+ delete fnt;
+
+ if (!scumm_stricmp(filename, "FONT.DMP"))
+ fnt = new SJISFont12x12(_vm->staticres()->loadRawDataBe16(kEoB2FontDmpSearchTbl, temp));
+ else if (!scumm_stricmp(filename, "FONT12.FNT"))
+ fnt = new Font12x12PC98(12, _vm->staticres()->loadRawDataBe16(kEoB1Ascii2SjisTable1, temp),
+ _vm->staticres()->loadRawDataBe16(kEoB1Ascii2SjisTable2, temp), _vm->staticres()->loadRawData(kEoB1FontLookupTable, temp));
+ else if (_isAmiga)
+ fnt = new AmigaDOSFont(_vm->resource(), _vm->game() == GI_EOB2 && _vm->gameFlags().lang == Common::DE_DEU);
+ else
+ // We use normal VGA rendering in EOB II, since we do the complete EGA dithering in updateScreen().
+ fnt = new OldDOSFont(_useHiResEGADithering ? Common::kRenderVGA : _renderMode, 12);
- const uint16 *tbl = _vm->staticres()->loadRawDataBe16(kEoB2FontDmpSearchTbl, temp);
- assert(tbl);
-
- if (!fnt) {
- fnt = new SJISFont12x12(tbl);
- assert(fnt);
- }
+ assert(fnt);
Common::SeekableReadStream *file = _vm->resource()->createReadStream(filename);
if (!file)
@@ -2037,10 +2050,11 @@ const uint8 Screen_EoB::_egaMatchTable[] = {
uint16 *OldDOSFont::_cgaDitheringTable = 0;
int OldDOSFont::_numRef = 0;
-OldDOSFont::OldDOSFont(Common::RenderMode mode) : _renderMode(mode) {
+OldDOSFont::OldDOSFont(Common::RenderMode mode, uint8 shadowColor) : _renderMode(mode), _shadowColor(shadowColor) {
_data = 0;
_width = _height = _numGlyphs = 0;
_bitmapOffsets = 0;
+ _style = kFSNone;
_numRef++;
if (!_cgaDitheringTable && _numRef == 1) {
@@ -2097,61 +2111,35 @@ int OldDOSFont::getCharWidth(uint16 c) const {
return _width;
}
+void OldDOSFont::setColorMap(const uint8 *src) {
+ _colorMap8bit = src;
+}
+
void OldDOSFont::drawChar(uint16 c, byte *dst, int pitch, int bpp) const {
- static const uint8 renderMaskTable6[] = { 0xFC, 0x00, 0x7E, 0x00, 0x3F, 0x00, 0x1F, 0x80, 0x0F, 0xC0, 0x07, 0xE0, 0x03, 0xF0, 0x01, 0xF8 };
- static const uint8 renderMaskTable8[] = { 0xFF, 0x00, 0x7F, 0x80, 0x3F, 0xC0, 0x1F, 0xE0, 0x0F, 0xF0, 0x07, 0xF8, 0x03, 0xFC, 0x01, 0xFE };
+ uint16 color1 = _colorMap8bit[1];
+ uint16 color2 = _colorMap8bit[0];
- if (_width != 8 && _width != 6)
- error("EOB font rendering not implemented for other font widths than 6 and 8.");
+ if (_style == kFSLeftShadow) {
+ drawCharIntern(c, dst + pitch, pitch, 1, _shadowColor, 0);
+ drawCharIntern(c, dst - 1, pitch, 1, _shadowColor, 0);
+ drawCharIntern(c, dst - 1 + pitch, pitch, 1, _shadowColor, 0);
+ }
- if (_width == 6) {
- switch (c) {
- case 0x81:
- case 0x9A:
- c = 0x5D;
- break;
- case 0x84:
- case 0x8E:
- c = 0x5B;
- break;
- case 0x94:
- case 0x99:
- c = 0x40;
- case 0xE1:
- // TODO: recheck this: no conversion for 'ß' ?
- break;
- default:
- break;
- }
- } else if (_width == 8) {
- switch (c) {
- case 0x81:
- case 0x9A:
- case 0x5D:
- c = 0x1D;
- break;
- case 0x84:
- case 0x5B:
- c = 0x1E;
- break;
- case 0x94:
- case 0x40:
- c = 0x1F;
- break;
- case 0x8E:
- c = 0x1B;
- break;
- case 0x99:
- c = 0x1C;
- break;
- case 0xE1:
- c = 0x19;
- break;
- default:
- break;
- }
+ if (bpp == 2) {
+ color1 = _colorMap16bit[1];
+ color2 = _colorMap16bit[0];
}
+ drawCharIntern(c, dst, pitch, bpp, color1, color2);
+}
+
+void OldDOSFont::drawCharIntern(uint16 c, byte *dst, int pitch, int bpp, int col1, int col2) const {
+ static const uint16 renderMaskTable[] = {
+ 0x0000, 0x8000, 0xc000, 0xe000, 0xf000, 0xf800, 0xfc00, 0xfe00, 0xff00, 0xff80, 0xffc0, 0xffe0, 0xfff0, 0xfff8, 0xfffc, 0xfffe, 0xffff
+ };
+
+ c = convert(c);
+
if (c >= _numGlyphs)
return;
@@ -2162,43 +2150,36 @@ void OldDOSFont::drawChar(uint16 c, byte *dst, int pitch, int bpp) const {
int w = (_width - 1) >> 3;
pitch -= _width * bpp;
- uint16 color1 = _colorMap8bit[1];
- uint16 color2 = _colorMap8bit[0];
-
- if (bpp == 2) {
- color1 = _colorMap16bit[1];
- color2 = _colorMap16bit[0];
- } else if (_renderMode == Common::kRenderCGA || _renderMode == Common::kRenderEGA) {
- color1 &= 0x0F;
- color2 &= 0x0F;
+ if (_renderMode == Common::kRenderCGA || _renderMode == Common::kRenderEGA) {
+ col1 &= 0x0F;
+ col2 &= 0x0F;
}
static const uint16 cgaColorMask[] = { 0, 0x5555, 0xAAAA, 0xFFFF };
- uint16 cgaMask1 = cgaColorMask[color1 & 3];
- uint16 cgaMask2 = cgaColorMask[color2 & 3];
+ uint16 cgaMask1 = cgaColorMask[col1 & 3];
+ uint16 cgaMask2 = cgaColorMask[col2 & 3];
int cH = _height;
while (cH--) {
int cW = w;
- uint8 last = 0;
- const uint8 *mtbl = _width == 8 ? renderMaskTable8 : renderMaskTable6;
+ uint16 mask = renderMaskTable[_width];
if (_renderMode == Common::kRenderCGA) {
- uint8 s = *src++;
- uint8 m = *mtbl++;
+ uint16 s = (*src++) << 8;
+ if (_width > 8)
+ s |= *src++;
- uint8 in = s | last;
uint16 cmp1 = 0;
uint16 cmp2 = 0;
- if (color1) {
- in &= m;
- cmp1 = _cgaDitheringTable[in];
+ if (col1) {
+ s &= mask;
+ cmp1 = _cgaDitheringTable[s >> 8];
}
- if (color2) {
- in = ~in & m;
- cmp2 = _cgaDitheringTable[in];
+ if (col2) {
+ s = ~s & mask;
+ cmp2 = _cgaDitheringTable[s >> 8];
}
uint16 cDst = 0;
@@ -2215,36 +2196,36 @@ void OldDOSFont::drawChar(uint16 c, byte *dst, int pitch, int bpp) const {
*dst++ = (out >> sh) & 3;
sh = (sh - 2) & 0x0F;
}
-
- last = s;
-
} else {
for (bool runWidthLoop = true; runWidthLoop;) {
- uint8 s = *src++;
- uint8 m = *mtbl++;
+ uint16 s = (*src++) << 8;
+ if (_width > 8)
+ s |= *src++;
- for (uint8 i = 0x80; i; i >>= 1) {
- if (!(m & i)) {
+ for (uint16 i = 0x8000; i; i >>= 1) {
+ if (!(mask & i)) {
runWidthLoop = false;
break;
}
if (s & i) {
if (bpp == 2)
- *(uint16*)dst = color1;
- else if (color1)
- *dst = color1;
+ *(uint16*)dst = col1;
+ else if (col1)
+ *dst = col1;
} else {
if (bpp == 2) {
- if (color2 != 0xFFFF)
- *(uint16*)dst = color2;
- } else if (color2) {
- *dst = color2;
+ if (col2 != 0xFFFF)
+ *(uint16*)dst = col2;
+ } else if (col2) {
+ *dst = col2;
}
}
dst += bpp;
}
+ mask >>= 1;
+
if (cW)
cW--;
else
@@ -2257,6 +2238,53 @@ void OldDOSFont::drawChar(uint16 c, byte *dst, int pitch, int bpp) const {
}
}
+uint16 OldDOSFont::convert(uint16 c) const {
+ if (_width == 6) {
+ switch (c) {
+ case 0x81:
+ case 0x9A:
+ c = 0x5D;
+ break;
+ case 0x84:
+ case 0x8E:
+ c = 0x5B;
+ break;
+ case 0x94:
+ case 0x99:
+ c = 0x40;
+ case 0xE1:
+ // TODO: recheck this: no conversion for 'ß' ?
+ break;
+ }
+ } else if (_width == 8) {
+ switch (c) {
+ case 0x81:
+ case 0x9A:
+ case 0x5D:
+ c = 0x1D;
+ break;
+ case 0x84:
+ case 0x5B:
+ c = 0x1E;
+ break;
+ case 0x94:
+ case 0x40:
+ c = 0x1F;
+ break;
+ case 0x8E:
+ c = 0x1B;
+ break;
+ case 0x99:
+ c = 0x1C;
+ break;
+ case 0xE1:
+ c = 0x19;
+ break;
+ }
+ }
+ return c;
+}
+
void OldDOSFont::unload() {
delete[] _data;
_data = 0;
@@ -2509,7 +2537,126 @@ void AmigaDOSFont::selectMode(int mode) {
_last = _content[mode].data->lastChar;
}
-SJISFontLarge::SJISFontLarge(Common::SharedPtr<Graphics::FontSJIS> &font) : SJISFont(font, 0, false, false, false, 0) {
+SJISFontEoB1PC98::SJISFontEoB1PC98(Common::SharedPtr<Graphics::FontSJIS> &font, uint8 shadowColor, const uint16 *convTable1, const uint16 *convTable2) : SJISFont(font, 0, false, false, 0),
+ _shadowColor(shadowColor), _convTable1(convTable1), _convTable2(convTable2), _defaultConv(true) {
+ assert(_convTable1);
+ assert(_convTable2);
+}
+
+int SJISFontEoB1PC98::getCharWidth(uint16 c) const {
+ return SJISFont::getCharWidth(convert(c));
+}
+
+void SJISFontEoB1PC98::drawChar(uint16 c, byte *dst, int pitch, int) const {
+ c = convert(c);
+ _font->setDrawingMode(_style == kFSLeftShadow ? Graphics::FontSJIS::kShadowLeftMode : Graphics::FontSJIS::kDefaultMode);
+ _font->toggleFatPrint(false);
+ _font->drawChar(dst, c, 640, 1, _colorMap[1], _colorMap[0], 640, 400);
+}
+
+uint16 SJISFontEoB1PC98::convert(uint16 c) const {
+ uint8 l = c & 0xFF;
+ uint8 h = c >> 8;
+
+ if (c < 128) {
+ c = _convTable2[l - 32];
+ } else if (l > 160 && l < 225) {
+ bool done = false;
+ if (_defaultConv) {
+ if (h == 0xDE) {
+ if ((l >= 182 && l <= 196) || (l >= 202 && l <= 206)) {
+ c = _convTable1[l - 182];
+ done = true;
+ }
+ } else if (h == 0xDF) {
+ if (l >= 202 && l <= 206) {
+ c = _convTable1[l - 177];
+ done = true;
+ }
+ }
+ }
+ if (!done)
+ c = _convTable2[l - 64];
+ }
+
+ return c;
+}
+
+Font12x12PC98::Font12x12PC98(uint8 shadowColor, const uint16 *convTable1, const uint16 *convTable2, const uint8 *lookupTable) : OldDOSFont(Common::kRenderDefault, 12),
+ _convTable1(convTable1), _convTable2(convTable2) {
+ assert(convTable1);
+ assert(convTable2);
+ assert(lookupTable);
+
+ _width = _height = 12;
+ _numGlyphs = 275;
+ _bmpOffs = new uint16[_numGlyphs];
+ for (int i = 0; i < _numGlyphs; ++i)
+ _bmpOffs[i] = lookupTable[i] * 24;
+}
+
+Font12x12PC98::~Font12x12PC98() {
+ delete[] _bmpOffs;
+}
+
+bool Font12x12PC98::load(Common::SeekableReadStream &file) {
+ unload();
+
+ _width = _height = 12;
+ _numGlyphs = 275;
+ _bitmapOffsets = _bmpOffs;
+
+ _data = new uint8[file.size()];
+ assert(_data);
+
+ file.read(_data, file.size());
+ if (file.err())
+ return false;
+
+ return true;
+}
+
+uint16 Font12x12PC98::convert(uint16 c) const {
+ uint8 l = c & 0xFF;
+ uint8 h = c >> 8;
+
+ if (c < 128) {
+ c = _convTable2[l - 32];
+ } else if (l > 160 && l < 225) {
+ bool done = false;
+ if (1) {
+ if (h == 0xDE) {
+ if ((l >= 182 && l <= 196) || (l >= 202 && l <= 206)) {
+ c = _convTable1[l - 182];
+ done = true;
+ }
+ } else if (h == 0xDF) {
+ if (l >= 202 && l <= 206) {
+ c = _convTable1[l - 177];
+ done = true;
+ }
+ }
+ }
+ if (!done)
+ c = _convTable2[l - 64];
+ }
+
+ c = SWAP_BYTES_16(c);
+ if (c < 0x813F)
+ c = 1;
+ else if (c < 0x824F)
+ c -= 0x813F;
+ else if (c < 0x833F)
+ c -= 0x81EE;
+ else if (c > 0x839F)
+ c = 1;
+ else
+ c -= 0x828D;
+
+ return c;
+}
+
+SJISFontLarge::SJISFontLarge(Common::SharedPtr<Graphics::FontSJIS> &font) : SJISFont(font, 0, false, false, 0) {
_sjisWidth = _font->getMaxFontWidth();
_fontHeight = _font->getFontHeight();
_asciiWidth = _font->getCharWidth('a');