看这个标题好像挺神秘的,其实,这个帖子只是要向大家详细解释一下是如何修改scummvm,使它能够显示出汉字的。
6 K4 ~. X, g1 o
# G3 Y. Z; P0 |! h/ x+ b: @! O8 g( r1 L汉字字库
) K! x# X; N1 } Q0 k/ O) l先说一下汉字字库,scummvm原先支持几个繁体中文的游戏,比如猴岛小英雄3,使用的是16X15的繁体字库。字库的文件名是chinese.fnt,在繁体中文版的文件中可以找到。看字体的样子好像是以前DOS时代的倚天字库。好,我们就从这里入手。既然能用繁体字库,那么使用简体中文的字库应该也是可以的。一开始我找了一个UCDOS的HZK16字库,但是放到游戏里面一试,高度太高了,在对话选择画面的时候,上下2行的字都会互相遮挡住,看来用现成的HZK16字库是不行了。在网上找了半天,也没有找到合适的字库。于是我决定自己造一个点阵字库。要造多大的字库呢,经过一番调查,最小只能用12点阵的字库,再小的话就看不清了。字库是用一个在网是找到的免费的TTF转点阵字库的工具转换的,没有费太大的力气。转换出来的字库是字节对齐的,也就是说,是12X16的,在宽度方向上对齐到16个点,也就是2个字节。既然是这样,1行是2个字节,12行就是24个字节,字库中每24个字节就能表示一个汉字,这一点不难理解吧。' B) P9 w3 j0 S' h# [
) W' r% V! Y9 O+ s下面我们来看一段代码,这段代码在charset.cpp这个文件里面。
! m( E6 B" a. U% ^
! E* b9 W# j! A- Ncase Common::ZH_TWN:+ h& {" G4 Y- b/ [
if (_game.id == GID_CMI) {3 O+ ]- I3 I4 \. G( e e8 _, d
fontFile = "chinese.fnt";
k. U% ^( c! E) T- E numChar = 13630; j. Y0 \$ j% B* L
}
4 _$ B: g0 C4 e) D" D break;, Y. n& `. |6 d& L$ B6 W
case Common::ZH_CNA: //add by shane007 2009.7.124 b1 z; w" h1 R, |; [* w
if (_game.id == GID_FT ||
, R( F$ V1 Z! Q/ W _game.id == GID_SAMNMAX ||
( N; i: d6 j1 V6 @3 {" w _game.id == GID_LOOM ||
6 A. ` D5 U* H3 ? _game.id == GID_INDY3 ||
! m6 i8 J6 G1 n _game.id == GID_INDY4 ||
' @1 h- u% F$ b: ^- X' _ _game.id == GID_MONKEY||
& R+ t7 j) f& L9 N7 ` _game.id == GID_MONKEY2||) L' A7 w! E5 T) s" l" U v; `) \
_game.id == GID_TENTACLE) {" _* ]3 N6 D& O9 n+ q$ M8 W- W6 }
2 o9 A( k5 M; D6 s- X$ Z
fontFile = "chinese_gb16x12.fnt";+ j9 M& b( n# F
numChar = 8178;
2 U! x( K' J' D4 I, W }
! e7 ~: z2 @% k' V break;. I& N0 p; y: D3 W$ d
default:
$ }( F; W h. k+ ^) P9 t break;
3 D! M# q* F' Q$ K}
) ^; R! b: A: o: t* q7 S
) @0 E. B8 E' v9 v代码包括了繁体字库和简体字库的定义,game.id是游戏的ID,我们让那些SCUMM引擎的游戏进来的时候,使用我们制作好的简体字库chinese_gb16x12.fnt。numChar是字库里面的中文字符数量。ZH_CNA是我们新增加的一种语言类型,在原版的scummvm里面是没有的。所以有的朋友在原版的scummvm里面找不到简体中文的选项,就是这个道理。是我加上去的。
4 \* w5 j+ n# V2 B6 E* z0 m% t& ?. r) ?
有的朋友也许还不太清楚,游戏是怎么找到我们需要的那个汉字的字模的,让我们再来看一段代码。
3 Q( t6 H; S' \0 t& k v. ?/ P V0 @+ z4 L1 a! G6 c# R0 v# _, H6 T- K
case Common::ZH_CNA: //add by shane007 2009.5.19$ q( l/ H% ?% d- g) f. G9 T
idx = ((idx % 256) - 0xa1)* 94 + ((idx / 256) - 0xa1);, f( e& d) g8 t7 [
break;
" ~2 Z. {' k! {- B: l: V3 P7 {7 h6 C! o% |$ m P# ?
其实很简单,我们汉字的区位码索引公式就是 (位码- 0xa1)* 94 + (区码 - 0xa1),+ L) T9 ~% q9 a7 w
知道了汉字的区位码就可以推算出这个汉字在我们字库中的索引值,由于每个汉字占用24个字节,我们就可以取得这个汉字的字模。
5 A1 I+ {. y3 h0 o9 X% X% H% U% k! w4 l8 ^1 k q# |: C
return _2byteFontPtr + ((_2byteWidth + 7) / 8) * _2byteHeight * idx;, Q3 L* M4 X. ^2 G% S
+ o6 |" e+ [$ X: R& Z
((_2byteWidth + 7) / 8)的意义就是字节对齐。
: v! u) o, q7 A% B+ s3 r0 c. W; E$ V2 m1 |3 ?! j& G
经过以上的修改,我们的scummvm就能显示出汉字了,是不是很简单呢?
% c4 w j7 t9 i: l3 h当然,在scumm引擎的游戏里面本来就有双字节函数的支持,所以修改相对比较简单,我们的修改主要是使它兼容于简体中文。
0 j8 @0 f0 Q, G对于其他引擎的游戏的汉化修改就没有这么简单了。但是,我们可以考虑把这些双字节函数移植过去。
0 u3 _5 Z* U! L' r6 _写下这篇小文章希望给后来者以些许启示吧。。。 |