Adapt KYRA to use the new Graphics::FontSJIS code.

svn-id: r42222
This commit is contained in:
Johannes Schickel
2009-07-07 14:22:39 +00:00
parent 8623081666
commit ec2c7cfefa
2 changed files with 25 additions and 266 deletions
+20 -257
View File
@@ -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 -
+5 -9
View File
@@ -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;