Add patch for Tobias, for Kanji support in Japanese PCE version of Loom, with minor changes.
svn-id: r46061
This commit is contained in:
parent
9886c8fb91
commit
2d31fc3af8
5 changed files with 157 additions and 26 deletions
|
@ -66,6 +66,21 @@ void ScummEngine::loadCJKFont() {
|
|||
fp.close();
|
||||
}
|
||||
_textSurfaceMultiplier = 2;
|
||||
} else if (_game.id == GID_LOOM && _game.platform == Common::kPlatformPCEngine && _language == Common::JA_JPN) {
|
||||
int numChar = 3418;
|
||||
_2byteWidth = 12;
|
||||
_2byteHeight = 12;
|
||||
// use PC-Engine System Card, since game files don't have kanji font resources
|
||||
if (!fp.open("pce.cdbios")) {
|
||||
error("SCUMM::Font: Couldn't open System Card pce.cdbios");
|
||||
} else {
|
||||
_useCJKMode = true;
|
||||
debug(2, "Loading PC-Engine System Card");
|
||||
fp.seek(0x30000);
|
||||
_2byteFontPtr = new byte[_2byteWidth * _2byteHeight * numChar / 8];
|
||||
fp.read(_2byteFontPtr, _2byteWidth * _2byteHeight * numChar / 8);
|
||||
fp.close();
|
||||
}
|
||||
} else if (_game.version >= 7 && (_language == Common::KO_KOR || _language == Common::JA_JPN || _language == Common::ZH_TWN)) {
|
||||
int numChar = 0;
|
||||
const char *fontFile = NULL;
|
||||
|
@ -210,13 +225,73 @@ static int SJIStoFMTChunk(int f, int s) { //converts sjis code to fmt font offse
|
|||
return ((chunk_f + chunk) * 32 + (s - base)) + cr;
|
||||
}
|
||||
|
||||
static int SJIStoPCEChunk(int f, int s) { //converts sjis code to pce font offset
|
||||
// rangeTbl maps SJIS char-codes to the PCE System Card font rom.
|
||||
// Each pair {<upperBound>,<lowerBound>} in the array represents a SJIS range.
|
||||
const int rangeCnt = 45;
|
||||
static const uint16 rangeTbl[rangeCnt][2] = {
|
||||
// Symbols
|
||||
{0x8140,0x817E},{0x8180,0x81AC},
|
||||
// 0-9
|
||||
{0x824F,0x8258},
|
||||
// Latin upper
|
||||
{0x8260,0x8279},
|
||||
// Latin lower
|
||||
{0x8281,0x829A},
|
||||
// Kana
|
||||
{0x829F,0x82F1},{0x8340,0x837E},{0x8380,0x8396},
|
||||
// Greek upper
|
||||
{0x839F,0x83B6},
|
||||
// Greek lower
|
||||
{0x83BF,0x83D6},
|
||||
// Cyrillic upper
|
||||
{0x8440,0x8460},
|
||||
// Cyrillic lower
|
||||
{0x8470,0x847E},{0x8480,0x8491},
|
||||
// Kanji
|
||||
{0x889F,0x88FC},
|
||||
{0x8940,0x897E},{0x8980,0x89FC},
|
||||
{0x8A40,0x8A7E},{0x8A80,0x8AFC},
|
||||
{0x8B40,0x8B7E},{0x8B80,0x8BFC},
|
||||
{0x8C40,0x8C7E},{0x8C80,0x8CFC},
|
||||
{0x8D40,0x8D7E},{0x8D80,0x8DFC},
|
||||
{0x8E40,0x8E7E},{0x8E80,0x8EFC},
|
||||
{0x8F40,0x8F7E},{0x8F80,0x8FFC},
|
||||
{0x9040,0x907E},{0x9080,0x90FC},
|
||||
{0x9140,0x917E},{0x9180,0x91FC},
|
||||
{0x9240,0x927E},{0x9280,0x92FC},
|
||||
{0x9340,0x937E},{0x9380,0x93FC},
|
||||
{0x9440,0x947E},{0x9480,0x94FC},
|
||||
{0x9540,0x957E},{0x9580,0x95FC},
|
||||
{0x9640,0x967E},{0x9680,0x96FC},
|
||||
{0x9740,0x977E},{0x9780,0x97FC},
|
||||
{0x9840,0x9872}
|
||||
};
|
||||
|
||||
int ch = (f << 8) | (s & 0xFF);
|
||||
int offset = 0;
|
||||
for (int i = 0; i < rangeCnt; ++i) {
|
||||
if (ch >= rangeTbl[i][0] && ch <= rangeTbl[i][1])
|
||||
return offset + ch - rangeTbl[i][0];
|
||||
offset += rangeTbl[i][1] - rangeTbl[i][0] + 1;
|
||||
}
|
||||
|
||||
debug(4, "Invalid Char: 0x%x", ch);
|
||||
return 0;
|
||||
}
|
||||
|
||||
byte *ScummEngine::get2byteCharPtr(int idx) {
|
||||
switch (_language) {
|
||||
case Common::KO_KOR:
|
||||
idx = ((idx % 256) - 0xb0) * 94 + (idx / 256) - 0xa1;
|
||||
break;
|
||||
case Common::JA_JPN:
|
||||
idx = SJIStoFMTChunk((idx % 256), (idx / 256));
|
||||
if (_game.id == GID_LOOM && _game.platform == Common::kPlatformPCEngine) {
|
||||
idx = SJIStoPCEChunk((idx % 256), (idx / 256));
|
||||
return _2byteFontPtr + (_2byteWidth * _2byteHeight / 8) * idx;
|
||||
} else {
|
||||
idx = SJIStoFMTChunk((idx % 256), (idx / 256));
|
||||
}
|
||||
break;
|
||||
case Common::ZH_TWN:
|
||||
{
|
||||
|
@ -994,6 +1069,42 @@ void CharsetRendererCommon::drawBits1(const Graphics::Surface &s, byte *dst, con
|
|||
}
|
||||
}
|
||||
|
||||
void CharsetRendererPCE::drawBits1(const Graphics::Surface &s, byte *dst, const byte *src, int drawTop, int width, int height, uint8 bitDepth) {
|
||||
int y, x;
|
||||
int bitCount = 0;
|
||||
byte bits = 0;
|
||||
|
||||
const bool resetLineBitCount = (_vm->_language != Common::JA_JPN || width != 12);
|
||||
|
||||
for (y = 0; y < height && y + drawTop < s.h; y++) {
|
||||
if (resetLineBitCount)
|
||||
bitCount = 0;
|
||||
for (x = 0; x < width; x++) {
|
||||
if ((bitCount % 8) == 0)
|
||||
bits = *src++;
|
||||
if ((bits & revBitMask(bitCount % 8)) && y + drawTop >= 0) {
|
||||
if (bitDepth == 2) {
|
||||
if (_shadowMode != kNoShadowMode) {
|
||||
WRITE_UINT16(dst + s.pitch + 2, 0);
|
||||
}
|
||||
WRITE_UINT16(dst, _vm->_16BitPalette[_color]);
|
||||
} else {
|
||||
if (_shadowMode != kNoShadowMode) {
|
||||
*(dst + 1) = _shadowColor;
|
||||
*(dst + s.pitch) = _shadowColor;
|
||||
*(dst + s.pitch + 1) = _shadowColor;
|
||||
}
|
||||
*dst = _color;
|
||||
}
|
||||
}
|
||||
dst += bitDepth;
|
||||
bitCount++;
|
||||
}
|
||||
|
||||
dst += s.pitch - width * bitDepth;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef ENABLE_SCUMM_7_8
|
||||
CharsetRendererNut::CharsetRendererNut(ScummEngine *vm)
|
||||
: CharsetRenderer(vm) {
|
||||
|
|
|
@ -164,6 +164,14 @@ public:
|
|||
int getCharWidth(byte chr);
|
||||
};
|
||||
|
||||
class CharsetRendererPCE : public CharsetRendererV3 {
|
||||
protected:
|
||||
void drawBits1(const Graphics::Surface &s, byte *dst, const byte *src, int drawTop, int width, int height, uint8 bitDepth);
|
||||
|
||||
public:
|
||||
CharsetRendererPCE(ScummEngine *vm) : CharsetRendererV3(vm) {}
|
||||
};
|
||||
|
||||
class CharsetRendererV2 : public CharsetRendererV3 {
|
||||
protected:
|
||||
bool _deleteFontPtr;
|
||||
|
|
|
@ -1089,7 +1089,7 @@ void ScummEngine::clearCharsetMask() {
|
|||
}
|
||||
|
||||
void ScummEngine::clearTextSurface() {
|
||||
memset(_textSurface.pixels, CHARSET_MASK_TRANSPARENCY, _textSurface.pitch * _textSurface.h);
|
||||
fill((byte*)_textSurface.pixels, _textSurface.pitch, CHARSET_MASK_TRANSPARENCY, _textSurface.w, _textSurface.h, _textSurface.bytesPerPixel);
|
||||
}
|
||||
|
||||
byte *ScummEngine::getMaskBuffer(int x, int y, int z) {
|
||||
|
|
|
@ -1089,22 +1089,27 @@ Common::Error ScummEngine::init() {
|
|||
// Initialize backend
|
||||
if (_renderMode == Common::kRenderHercA || _renderMode == Common::kRenderHercG) {
|
||||
initGraphics(Common::kHercW, Common::kHercH, true);
|
||||
} else if (_useCJKMode) {
|
||||
initGraphics(_screenWidth * _textSurfaceMultiplier, _screenHeight * _textSurfaceMultiplier,
|
||||
// CJK FT and DIG use usual NUT fonts, not FM-TOWNS ROM, so
|
||||
// there is no text surface for them. This takes that into account
|
||||
(_screenWidth * _textSurfaceMultiplier > 320));
|
||||
} else if (_game.features & GF_16BIT_COLOR) {
|
||||
#ifdef USE_RGB_COLOR
|
||||
Graphics::PixelFormat format = Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0);
|
||||
initGraphics(_screenWidth, _screenHeight, _screenWidth > 320, &format);
|
||||
if (format != _system->getScreenFormat())
|
||||
return Common::kUnsupportedColorMode;
|
||||
#else
|
||||
error("16bit color support is required for this game");
|
||||
#endif
|
||||
} else {
|
||||
initGraphics(_screenWidth, _screenHeight, _screenWidth > 320);
|
||||
int screenWidth = _screenWidth;
|
||||
int screenHeight = _screenHeight;
|
||||
if (_useCJKMode) {
|
||||
// CJK FT and DIG use usual NUT fonts, not FM-TOWNS ROM, so
|
||||
// there is no text surface for them. This takes that into account
|
||||
screenWidth *= _textSurfaceMultiplier;
|
||||
screenHeight *= _textSurfaceMultiplier;
|
||||
}
|
||||
if (_game.features & GF_16BIT_COLOR) {
|
||||
#ifdef USE_RGB_COLOR
|
||||
Graphics::PixelFormat format = Graphics::PixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0);
|
||||
initGraphics(screenWidth, screenHeight, screenWidth > 320, &format);
|
||||
if (format != _system->getScreenFormat())
|
||||
return Common::kUnsupportedColorMode;
|
||||
#else
|
||||
error("16bit color support is required for this game");
|
||||
#endif
|
||||
} else {
|
||||
initGraphics(screenWidth, screenHeight, (screenWidth > 320));
|
||||
}
|
||||
}
|
||||
|
||||
setupScumm();
|
||||
|
@ -1259,18 +1264,23 @@ void ScummEngine_v7::setupScumm() {
|
|||
#endif
|
||||
|
||||
void ScummEngine::setupCharsetRenderer() {
|
||||
if (_game.platform == Common::kPlatformNES)
|
||||
_charset = new CharsetRendererNES(this);
|
||||
else if (_game.version <= 2)
|
||||
_charset = new CharsetRendererV2(this, _language);
|
||||
else if (_game.version == 3)
|
||||
_charset = new CharsetRendererV3(this);
|
||||
if (_game.version <= 2) {
|
||||
if (_game.platform == Common::kPlatformNES)
|
||||
_charset = new CharsetRendererNES(this);
|
||||
else
|
||||
_charset = new CharsetRendererV2(this, _language);
|
||||
} else if (_game.version == 3) {
|
||||
if (_game.platform == Common::kPlatformPCEngine)
|
||||
_charset = new CharsetRendererPCE(this);
|
||||
else
|
||||
_charset = new CharsetRendererV3(this);
|
||||
#ifdef ENABLE_SCUMM_7_8
|
||||
else if (_game.version == 8)
|
||||
} else if (_game.version == 8) {
|
||||
_charset = new CharsetRendererNut(this);
|
||||
#endif
|
||||
else
|
||||
} else {
|
||||
_charset = new CharsetRendererClassic(this);
|
||||
}
|
||||
}
|
||||
|
||||
void ScummEngine::setupCostumeRenderer() {
|
||||
|
|
|
@ -1093,7 +1093,9 @@ int ScummEngine::convertMessageToString(const byte *msg, byte *dst, int dstSize)
|
|||
}
|
||||
} else {
|
||||
if (!(chr == '@' && _game.heversion <= 71) ||
|
||||
(_game.id == GID_CMI && _language == Common::ZH_TWN)) {
|
||||
(_game.id == GID_CMI && _language == Common::ZH_TWN) ||
|
||||
(_game.id == GID_LOOM && _game.platform == Common::kPlatformPCEngine && _language == Common::JA_JPN))
|
||||
{
|
||||
*dst++ = chr;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue