看这个标题好像挺神秘的,其实,这个帖子只是要向大家详细解释一下是如何修改scummvm,使它能够显示出汉字的。+ @6 s( e4 U, U! r+ B8 [
( f _+ V& y4 Q/ J1 u4 p- I( L汉字字库' u! ^1 h2 X- A& `
先说一下汉字字库,scummvm原先支持几个繁体中文的游戏,比如猴岛小英雄3,使用的是16X15的繁体字库。字库的文件名是chinese.fnt,在繁体中文版的文件中可以找到。看字体的样子好像是以前DOS时代的倚天字库。好,我们就从这里入手。既然能用繁体字库,那么使用简体中文的字库应该也是可以的。一开始我找了一个UCDOS的HZK16字库,但是放到游戏里面一试,高度太高了,在对话选择画面的时候,上下2行的字都会互相遮挡住,看来用现成的HZK16字库是不行了。在网上找了半天,也没有找到合适的字库。于是我决定自己造一个点阵字库。要造多大的字库呢,经过一番调查,最小只能用12点阵的字库,再小的话就看不清了。字库是用一个在网是找到的免费的TTF转点阵字库的工具转换的,没有费太大的力气。转换出来的字库是字节对齐的,也就是说,是12X16的,在宽度方向上对齐到16个点,也就是2个字节。既然是这样,1行是2个字节,12行就是24个字节,字库中每24个字节就能表示一个汉字,这一点不难理解吧。
. S; b9 R6 t" q/ s! F* V7 ]1 f; r( ^: O9 m# Z& g
下面我们来看一段代码,这段代码在charset.cpp这个文件里面。
/ G( Q1 O2 Z: j* N) K8 Q& G. o% v. {# g4 H8 R- q! M4 v
case Common::ZH_TWN:
8 H" U9 U, ^% H* D9 L, v! S if (_game.id == GID_CMI) {
9 b0 ^, p" s U% \4 A2 S fontFile = "chinese.fnt";
3 N/ X5 e# p1 J numChar = 13630;( q9 v: d @3 l% h
}( F2 r# x$ J- U
break;- ~* x& t/ q" M, u: n6 Z# C% _% t/ Q
case Common::ZH_CNA: //add by shane007 2009.7.12
( W! E! u* {4 s" x! O! ` if (_game.id == GID_FT || 3 M$ H0 F# [9 {# S$ \( c. w
_game.id == GID_SAMNMAX ||
) _& N" r# `; Y) U8 p- K _game.id == GID_LOOM ||
' b4 q! D" F9 P" X _game.id == GID_INDY3 ||
& O1 D X5 K1 J) O; C3 \ _game.id == GID_INDY4 ||. h1 u+ x0 E: O& t% w9 E
_game.id == GID_MONKEY||
$ m, L7 V( {: k7 n3 A# E. G1 N, w _game.id == GID_MONKEY2||
: }2 u( P# F7 R- o2 t _game.id == GID_TENTACLE) { d- T2 _# S! [$ ]% `7 f7 s
7 ]) k9 M( H7 r7 X. Q
fontFile = "chinese_gb16x12.fnt";
; l1 W0 R1 J% f7 {! t' T; O( Q numChar = 8178; 3 t) g: I O3 V
}
: B( f9 _, ?& w1 J1 |, W2 n( p break;
9 U( s. {: C+ F/ m* h; Bdefault:7 o! k) j: ]: p- A* W1 c8 e6 B4 f! m1 J
break;
) x% d5 K: a& d3 A" K. d}
+ n& m9 u; g* \# U0 \ c6 _7 k( x ], T3 @: K0 M) K! Y: ?8 [# O, E
代码包括了繁体字库和简体字库的定义,game.id是游戏的ID,我们让那些SCUMM引擎的游戏进来的时候,使用我们制作好的简体字库chinese_gb16x12.fnt。numChar是字库里面的中文字符数量。ZH_CNA是我们新增加的一种语言类型,在原版的scummvm里面是没有的。所以有的朋友在原版的scummvm里面找不到简体中文的选项,就是这个道理。是我加上去的。 Q! b; g5 Z3 y& K7 f4 E: m
; g3 j* ^8 Y! I1 O4 H0 Q
有的朋友也许还不太清楚,游戏是怎么找到我们需要的那个汉字的字模的,让我们再来看一段代码。: W# @! ~+ z1 l
& T1 r2 S g- ]% s9 W# A% Qcase Common::ZH_CNA: //add by shane007 2009.5.196 [1 ?" N' Y2 ]1 b
idx = ((idx % 256) - 0xa1)* 94 + ((idx / 256) - 0xa1);
' e3 S* ~, ^) r' e2 T3 |break;6 X. F4 u2 |1 H$ a% T9 n
8 W- M% D* I1 B1 @) h其实很简单,我们汉字的区位码索引公式就是 (位码- 0xa1)* 94 + (区码 - 0xa1),
4 } q1 p5 j& S- `: X知道了汉字的区位码就可以推算出这个汉字在我们字库中的索引值,由于每个汉字占用24个字节,我们就可以取得这个汉字的字模。
1 E' X3 V, X- R3 U$ O4 F4 F# O4 Q0 Q- U1 H% p+ [( U
return _2byteFontPtr + ((_2byteWidth + 7) / 8) * _2byteHeight * idx;
, v F1 U. }- L9 J9 O9 \, z3 }/ n, G E! r8 a& S+ H' ^1 n( i
((_2byteWidth + 7) / 8)的意义就是字节对齐。
, Q' v0 d: E* n
- Z) x; R/ i% G8 l3 C经过以上的修改,我们的scummvm就能显示出汉字了,是不是很简单呢?
6 n7 q9 d4 u3 V6 ]2 k- ]当然,在scumm引擎的游戏里面本来就有双字节函数的支持,所以修改相对比较简单,我们的修改主要是使它兼容于简体中文。
7 j0 W- e6 o7 z" [; U" q对于其他引擎的游戏的汉化修改就没有这么简单了。但是,我们可以考虑把这些双字节函数移植过去。# C5 j6 [$ G' }" r
写下这篇小文章希望给后来者以些许启示吧。。。 |