看这个标题好像挺神秘的,其实,这个帖子只是要向大家详细解释一下是如何修改scummvm,使它能够显示出汉字的。8 W9 z" [( E# e9 w
3 g8 z! h0 \' V7 m7 X/ F汉字字库 V- } y) B4 K: [# [3 s6 P
先说一下汉字字库,scummvm原先支持几个繁体中文的游戏,比如猴岛小英雄3,使用的是16X15的繁体字库。字库的文件名是chinese.fnt,在繁体中文版的文件中可以找到。看字体的样子好像是以前DOS时代的倚天字库。好,我们就从这里入手。既然能用繁体字库,那么使用简体中文的字库应该也是可以的。一开始我找了一个UCDOS的HZK16字库,但是放到游戏里面一试,高度太高了,在对话选择画面的时候,上下2行的字都会互相遮挡住,看来用现成的HZK16字库是不行了。在网上找了半天,也没有找到合适的字库。于是我决定自己造一个点阵字库。要造多大的字库呢,经过一番调查,最小只能用12点阵的字库,再小的话就看不清了。字库是用一个在网是找到的免费的TTF转点阵字库的工具转换的,没有费太大的力气。转换出来的字库是字节对齐的,也就是说,是12X16的,在宽度方向上对齐到16个点,也就是2个字节。既然是这样,1行是2个字节,12行就是24个字节,字库中每24个字节就能表示一个汉字,这一点不难理解吧。+ C; ?% x6 @; ]
# L' A: D" p' @# Q4 D3 k下面我们来看一段代码,这段代码在charset.cpp这个文件里面。
/ D+ f/ k1 s) V F; M5 k/ O* R4 n9 U q$ h2 k
case Common::ZH_TWN:# H L9 `: @* B+ x
if (_game.id == GID_CMI) {' S* p8 A- _# z, F: I
fontFile = "chinese.fnt";- Z" v) \4 ^. O9 k( a: d; {% V
numChar = 13630;
" W8 y* U8 ]+ V G5 i! j }, g$ n Y1 ~- h9 B) C" z" Y$ t
break;( M# |$ A7 C5 Q2 b( ?/ C+ m% d
case Common::ZH_CNA: //add by shane007 2009.7.12
4 i* T+ ?! \! H1 g7 H' c5 N if (_game.id == GID_FT ||
_, Z+ p* S% i5 d9 { E _game.id == GID_SAMNMAX ||
. c$ q: v, F& G' I$ E _game.id == GID_LOOM ||
! [. X0 d1 @8 d- P: ~5 z/ V+ J; R7 p _game.id == GID_INDY3 ||2 w1 g6 i' a, ?2 q
_game.id == GID_INDY4 ||
2 C( Z7 O0 K/ W5 ^ z1 D _game.id == GID_MONKEY||
1 e: ?0 N: |* S: [% N# }! {9 K _game.id == GID_MONKEY2||! C" l6 Y" t( ~& R* Q
_game.id == GID_TENTACLE) {8 j6 V. Y* z# X' U" s/ ^0 X! C* r
7 g- f# E: B ]7 E" d" j7 f
fontFile = "chinese_gb16x12.fnt";
) ~6 y" W/ R) }) h( ] numChar = 8178;
* `, P8 O4 M5 o2 T* ~8 i }
' T' k& H1 x: U$ b break;* v f( r& y+ E) ?
default:& }) k3 t: s8 l- a/ \# \. m- s
break;: g8 @' F( O6 k7 r
}
* {5 G5 t; c) P& Y6 m+ ~8 I6 [ E$ m* o( Y. c# L, A C
代码包括了繁体字库和简体字库的定义,game.id是游戏的ID,我们让那些SCUMM引擎的游戏进来的时候,使用我们制作好的简体字库chinese_gb16x12.fnt。numChar是字库里面的中文字符数量。ZH_CNA是我们新增加的一种语言类型,在原版的scummvm里面是没有的。所以有的朋友在原版的scummvm里面找不到简体中文的选项,就是这个道理。是我加上去的。( v6 f+ e/ u* W+ r
- s( e8 h2 `& d. m+ _& o; ?有的朋友也许还不太清楚,游戏是怎么找到我们需要的那个汉字的字模的,让我们再来看一段代码。) _# V; W3 w' w& E
+ i) j: }+ {7 G' q, d: O
case Common::ZH_CNA: //add by shane007 2009.5.198 G% [ v5 J' [+ k* M# Z
idx = ((idx % 256) - 0xa1)* 94 + ((idx / 256) - 0xa1);
& K1 S$ N; H" z5 y3 I* T- M7 qbreak;$ l/ ^ n8 b/ o( K) a6 t* r
9 U) _" Z( f) m* D& P; G$ _
其实很简单,我们汉字的区位码索引公式就是 (位码- 0xa1)* 94 + (区码 - 0xa1),
- Z ]& r9 V/ {# P- X知道了汉字的区位码就可以推算出这个汉字在我们字库中的索引值,由于每个汉字占用24个字节,我们就可以取得这个汉字的字模。3 Y( H! K. _- {( z+ |1 r& Z
. ^, L! j0 y$ ^2 K. q9 L4 z5 Y9 vreturn _2byteFontPtr + ((_2byteWidth + 7) / 8) * _2byteHeight * idx;
! x+ I0 b n* N1 @$ v+ E) c+ {
6 A' N3 Z9 U" K& o2 O: j1 v((_2byteWidth + 7) / 8)的意义就是字节对齐。2 p. C# Y! k& e4 D( ~( v+ j
Z' E/ |" n& @( o; _4 m
经过以上的修改,我们的scummvm就能显示出汉字了,是不是很简单呢?
# M' g$ z! ]/ R当然,在scumm引擎的游戏里面本来就有双字节函数的支持,所以修改相对比较简单,我们的修改主要是使它兼容于简体中文。 n7 ~+ J: ^! |. B/ @$ H, Q. H
对于其他引擎的游戏的汉化修改就没有这么简单了。但是,我们可以考虑把这些双字节函数移植过去。& Z' d4 W( G/ l4 s) C- X
写下这篇小文章希望给后来者以些许启示吧。。。 |