看这个标题好像挺神秘的,其实,这个帖子只是要向大家详细解释一下是如何修改scummvm,使它能够显示出汉字的。
$ W: v9 `/ `' G4 ?) s" }) ^! Q, r9 L& a
汉字字库
( l) n/ y F" @6 c6 \先说一下汉字字库,scummvm原先支持几个繁体中文的游戏,比如猴岛小英雄3,使用的是16X15的繁体字库。字库的文件名是chinese.fnt,在繁体中文版的文件中可以找到。看字体的样子好像是以前DOS时代的倚天字库。好,我们就从这里入手。既然能用繁体字库,那么使用简体中文的字库应该也是可以的。一开始我找了一个UCDOS的HZK16字库,但是放到游戏里面一试,高度太高了,在对话选择画面的时候,上下2行的字都会互相遮挡住,看来用现成的HZK16字库是不行了。在网上找了半天,也没有找到合适的字库。于是我决定自己造一个点阵字库。要造多大的字库呢,经过一番调查,最小只能用12点阵的字库,再小的话就看不清了。字库是用一个在网是找到的免费的TTF转点阵字库的工具转换的,没有费太大的力气。转换出来的字库是字节对齐的,也就是说,是12X16的,在宽度方向上对齐到16个点,也就是2个字节。既然是这样,1行是2个字节,12行就是24个字节,字库中每24个字节就能表示一个汉字,这一点不难理解吧。
`7 F7 A) i6 V8 Y( l
* X' Y1 ~) e. ?4 o+ E* P1 {: B下面我们来看一段代码,这段代码在charset.cpp这个文件里面。7 E% X$ M1 u# l# T z8 y
% G" |* t/ \7 z2 v2 o
case Common::ZH_TWN:
) ^! I( g# k* I8 A) b* b# Y1 c* w, _ if (_game.id == GID_CMI) {4 T* s; l( |: s8 h( P
fontFile = "chinese.fnt";, N1 n1 k, p: [7 \% A
numChar = 13630;: l$ q7 Y: ^- c8 h
}8 t* i0 Y4 S" T7 s1 P0 I
break;
6 [4 n H- x9 t' j. D. \7 o* }( }case Common::ZH_CNA: //add by shane007 2009.7.12# J$ }5 c! t0 s- Q" C) q
if (_game.id == GID_FT ||
: [) u0 g( }0 i q" k; L0 V- s _game.id == GID_SAMNMAX || + G% R6 K, v! y [) t
_game.id == GID_LOOM ||
4 k9 \+ G8 R q ^' I% e7 B _game.id == GID_INDY3 ||' a" ~/ q( l" M7 h3 C
_game.id == GID_INDY4 ||
) Y8 t9 n" Y! y2 X _game.id == GID_MONKEY||4 D, q6 @9 q- `4 T: |" A
_game.id == GID_MONKEY2||- E {/ k0 e! N; \5 r; b* `: l
_game.id == GID_TENTACLE) {* o" G) x* s% x2 ?+ b
' ?* k. f. v, i/ ]4 N( E
fontFile = "chinese_gb16x12.fnt";
) O: }5 M" S# k' ?4 h numChar = 8178; * a* q/ y' k* p( N: N
}) U5 i2 a; s# s
break;
+ x: s1 ~# t) J5 e# L4 J4 {( idefault:. f9 e2 y6 U8 {, y0 v) e; K9 U* Z
break;6 o' z3 `: p. ^# Q; \% X
}: y, O6 {5 U* K
/ z$ K7 E. s Z5 f
代码包括了繁体字库和简体字库的定义,game.id是游戏的ID,我们让那些SCUMM引擎的游戏进来的时候,使用我们制作好的简体字库chinese_gb16x12.fnt。numChar是字库里面的中文字符数量。ZH_CNA是我们新增加的一种语言类型,在原版的scummvm里面是没有的。所以有的朋友在原版的scummvm里面找不到简体中文的选项,就是这个道理。是我加上去的。0 T& e! t& K$ C) ^ t
7 b+ @7 n. i1 Q9 f有的朋友也许还不太清楚,游戏是怎么找到我们需要的那个汉字的字模的,让我们再来看一段代码。' v! x1 j. r4 e" e+ X" p
. G7 B* O7 i: }5 U1 T: m) lcase Common::ZH_CNA: //add by shane007 2009.5.19
w' ~* d8 W O, j) r& Cidx = ((idx % 256) - 0xa1)* 94 + ((idx / 256) - 0xa1);
& I* O6 `6 m; L7 Y; d4 t" p. \8 lbreak;
7 d4 i% j# J: y: I" }! m6 W2 a
, a! R3 N8 g/ J0 \ D1 X其实很简单,我们汉字的区位码索引公式就是 (位码- 0xa1)* 94 + (区码 - 0xa1),
2 K, r0 X. D, T5 O# k/ h% |! a知道了汉字的区位码就可以推算出这个汉字在我们字库中的索引值,由于每个汉字占用24个字节,我们就可以取得这个汉字的字模。' T+ w4 ?$ c' t b* @5 }, t
$ ?2 c( Z5 Z+ A" d7 M
return _2byteFontPtr + ((_2byteWidth + 7) / 8) * _2byteHeight * idx;
$ D7 |0 | ^9 m9 \- p
u# m2 {# x7 [5 M' I((_2byteWidth + 7) / 8)的意义就是字节对齐。 j0 B' f, u3 s: H
z! W( M; [ R# g' H( {, e
经过以上的修改,我们的scummvm就能显示出汉字了,是不是很简单呢?* Z% f" w0 k, E- a% J2 o
当然,在scumm引擎的游戏里面本来就有双字节函数的支持,所以修改相对比较简单,我们的修改主要是使它兼容于简体中文。
, X c3 e( R0 N" M1 F8 N0 q1 Z* K" u对于其他引擎的游戏的汉化修改就没有这么简单了。但是,我们可以考虑把这些双字节函数移植过去。
$ o4 C4 [' l- n5 }6 R写下这篇小文章希望给后来者以些许启示吧。。。 |