看这个标题好像挺神秘的,其实,这个帖子只是要向大家详细解释一下是如何修改scummvm,使它能够显示出汉字的。
; R, r% Z/ r; I! u8 B- _+ p/ F- @0 |( d
汉字字库4 I- j2 q. ^& @) \; X2 i& }) N
先说一下汉字字库,scummvm原先支持几个繁体中文的游戏,比如猴岛小英雄3,使用的是16X15的繁体字库。字库的文件名是chinese.fnt,在繁体中文版的文件中可以找到。看字体的样子好像是以前DOS时代的倚天字库。好,我们就从这里入手。既然能用繁体字库,那么使用简体中文的字库应该也是可以的。一开始我找了一个UCDOS的HZK16字库,但是放到游戏里面一试,高度太高了,在对话选择画面的时候,上下2行的字都会互相遮挡住,看来用现成的HZK16字库是不行了。在网上找了半天,也没有找到合适的字库。于是我决定自己造一个点阵字库。要造多大的字库呢,经过一番调查,最小只能用12点阵的字库,再小的话就看不清了。字库是用一个在网是找到的免费的TTF转点阵字库的工具转换的,没有费太大的力气。转换出来的字库是字节对齐的,也就是说,是12X16的,在宽度方向上对齐到16个点,也就是2个字节。既然是这样,1行是2个字节,12行就是24个字节,字库中每24个字节就能表示一个汉字,这一点不难理解吧。
5 o$ V7 s- [9 m0 }: P, P4 w
* c( X/ h1 z. N; @/ @下面我们来看一段代码,这段代码在charset.cpp这个文件里面。# z9 x' _0 r" p) i$ s F* r
$ _, P, e, ^. [# y$ \
case Common::ZH_TWN:
2 r# q2 F- N5 j: J if (_game.id == GID_CMI) {) r% j. f$ d) } o4 I. Q
fontFile = "chinese.fnt";6 p% r7 P! M ^( z2 v
numChar = 13630;7 {" f Q% Z) ^/ d
}) k% @2 v4 }7 g9 C/ i) c: ~
break;' k( z% h! I2 s7 S! ?6 t- i5 Z O
case Common::ZH_CNA: //add by shane007 2009.7.12
( y. d, C7 c# V" w6 g: u if (_game.id == GID_FT ||
% }# a0 z" g$ a7 U$ J: z _game.id == GID_SAMNMAX || : q; c; [2 x3 [2 a
_game.id == GID_LOOM ||0 v) Q! p6 n1 h' G+ K: i+ ]3 L3 H
_game.id == GID_INDY3 ||* x- m3 b3 r/ ?, ~1 {
_game.id == GID_INDY4 ||# k/ u! Y' F w5 A
_game.id == GID_MONKEY||
4 u8 E0 n/ O, k5 w3 d) s _game.id == GID_MONKEY2||
: o4 ^ H F; v- E _game.id == GID_TENTACLE) {. v$ F; P# p) ]
, A6 W# J/ X9 I1 Q
fontFile = "chinese_gb16x12.fnt";# i( ^- U* g& ?& o j
numChar = 8178;
. \0 h: Z' V( G/ ` }* x! I; t6 }4 P9 ^( g" y
break;
- d u# w" \: ydefault:" R$ I1 ~; k+ n- v1 K- R$ V3 [
break;
+ C8 j5 P" E+ D( r" f, A" I3 ~}
1 v* l+ W8 P( f1 F& l* Z4 O* _: z5 } |: u. N' {( W
代码包括了繁体字库和简体字库的定义,game.id是游戏的ID,我们让那些SCUMM引擎的游戏进来的时候,使用我们制作好的简体字库chinese_gb16x12.fnt。numChar是字库里面的中文字符数量。ZH_CNA是我们新增加的一种语言类型,在原版的scummvm里面是没有的。所以有的朋友在原版的scummvm里面找不到简体中文的选项,就是这个道理。是我加上去的。
, S! x) E2 a# Y! X
; n& F' ]6 K4 M I0 v* b7 l2 `# E有的朋友也许还不太清楚,游戏是怎么找到我们需要的那个汉字的字模的,让我们再来看一段代码。" [& v& K7 N, o3 b
* |5 D; ?. o4 X% i/ [3 _case Common::ZH_CNA: //add by shane007 2009.5.19( J% {4 G: k4 }9 Z( ^" }
idx = ((idx % 256) - 0xa1)* 94 + ((idx / 256) - 0xa1);
0 Y! p9 }* C5 sbreak;# O& I9 i% N( z8 e3 S5 s2 n2 @) Q
2 h3 V2 ?6 X* D, t, a其实很简单,我们汉字的区位码索引公式就是 (位码- 0xa1)* 94 + (区码 - 0xa1),, I7 n$ K$ C; i3 @- k/ g
知道了汉字的区位码就可以推算出这个汉字在我们字库中的索引值,由于每个汉字占用24个字节,我们就可以取得这个汉字的字模。( v/ s* Q, b. y8 A9 z! ~
; z6 `' g8 ^1 g2 C
return _2byteFontPtr + ((_2byteWidth + 7) / 8) * _2byteHeight * idx;& S5 P% D- y4 W2 i$ |8 ~
2 Z9 c k$ l4 V* l' G((_2byteWidth + 7) / 8)的意义就是字节对齐。5 T" ?8 ~2 a- b, T5 Z" @' S) B
! J5 r& _9 T( X4 j6 Z% B) _
经过以上的修改,我们的scummvm就能显示出汉字了,是不是很简单呢?" o$ T* D* a) {2 W/ l
当然,在scumm引擎的游戏里面本来就有双字节函数的支持,所以修改相对比较简单,我们的修改主要是使它兼容于简体中文。1 v5 X' b; n8 s6 `
对于其他引擎的游戏的汉化修改就没有这么简单了。但是,我们可以考虑把这些双字节函数移植过去。
+ b9 S6 C1 Z: U8 e2 u写下这篇小文章希望给后来者以些许启示吧。。。 |