看这个标题好像挺神秘的,其实,这个帖子只是要向大家详细解释一下是如何修改scummvm,使它能够显示出汉字的。
' H# d. K& a( ?/ }4 w; p8 ^- r3 l) ~ s/ U
汉字字库8 |8 c$ |( X* k& V" N
先说一下汉字字库,scummvm原先支持几个繁体中文的游戏,比如猴岛小英雄3,使用的是16X15的繁体字库。字库的文件名是chinese.fnt,在繁体中文版的文件中可以找到。看字体的样子好像是以前DOS时代的倚天字库。好,我们就从这里入手。既然能用繁体字库,那么使用简体中文的字库应该也是可以的。一开始我找了一个UCDOS的HZK16字库,但是放到游戏里面一试,高度太高了,在对话选择画面的时候,上下2行的字都会互相遮挡住,看来用现成的HZK16字库是不行了。在网上找了半天,也没有找到合适的字库。于是我决定自己造一个点阵字库。要造多大的字库呢,经过一番调查,最小只能用12点阵的字库,再小的话就看不清了。字库是用一个在网是找到的免费的TTF转点阵字库的工具转换的,没有费太大的力气。转换出来的字库是字节对齐的,也就是说,是12X16的,在宽度方向上对齐到16个点,也就是2个字节。既然是这样,1行是2个字节,12行就是24个字节,字库中每24个字节就能表示一个汉字,这一点不难理解吧。" s, i3 ~4 k# }
& Y2 g; l- b' u9 l下面我们来看一段代码,这段代码在charset.cpp这个文件里面。
( ]. d' P& P" h( c. q8 X2 w1 @
5 c Q$ ?! E- C7 } r9 r0 w. Mcase Common::ZH_TWN:( T+ O9 `' Q9 ~$ @
if (_game.id == GID_CMI) {
9 A5 f8 ?% E) M, `, G fontFile = "chinese.fnt";4 c# |2 V1 z3 F/ v9 L9 F4 ~
numChar = 13630;" i" L$ ?/ c! a6 b$ r
}5 ?4 Z+ }" j( ?' N5 y. [
break;1 c- `8 R9 k. s& I8 a( h6 g# }
case Common::ZH_CNA: //add by shane007 2009.7.124 U$ p6 s7 g* {. g7 `4 t
if (_game.id == GID_FT || / ]" ?% L1 L5 B1 b! @' x
_game.id == GID_SAMNMAX || 4 t( V. S w7 `) N
_game.id == GID_LOOM ||0 q B9 Y0 Z" m6 C8 P* l5 o
_game.id == GID_INDY3 ||
! |5 K" r" P" D# w' e6 y _game.id == GID_INDY4 ||$ U* J; a/ V5 j! @, \
_game.id == GID_MONKEY||
, |9 a& _# O( W# O _game.id == GID_MONKEY2||* U2 t' t+ p3 M: V
_game.id == GID_TENTACLE) {
+ M" D) k% t9 v7 J) {
2 U5 Q/ }/ s2 w" g' O# | fontFile = "chinese_gb16x12.fnt";
7 P6 F- L/ \) N$ o, n c numChar = 8178; & V: w' ~4 ]' j8 [8 \
}9 u) C; }% ], h* e
break;5 H" w9 O; }( I/ K) X0 y$ ` O
default:9 q( \2 [' |. o
break;
/ ]$ J9 U; r' E/ X1 p}' I9 n9 F' N: ?9 _0 m# P. {
; i0 K. g: O" `* C% a代码包括了繁体字库和简体字库的定义,game.id是游戏的ID,我们让那些SCUMM引擎的游戏进来的时候,使用我们制作好的简体字库chinese_gb16x12.fnt。numChar是字库里面的中文字符数量。ZH_CNA是我们新增加的一种语言类型,在原版的scummvm里面是没有的。所以有的朋友在原版的scummvm里面找不到简体中文的选项,就是这个道理。是我加上去的。6 ~8 I+ q1 C( j7 g6 b
2 P+ `2 o$ {: q' C有的朋友也许还不太清楚,游戏是怎么找到我们需要的那个汉字的字模的,让我们再来看一段代码。
& F% m. J' @7 s8 K! S% x G
y6 {6 ^8 W! C) b& a1 Pcase Common::ZH_CNA: //add by shane007 2009.5.19
: o. C# @9 g/ n$ E* Lidx = ((idx % 256) - 0xa1)* 94 + ((idx / 256) - 0xa1);1 Z5 U( a3 C; s8 U! ]4 F$ [ u
break;
) z1 R, x9 k+ @/ n$ V% {# G( f5 M3 h, x) _
其实很简单,我们汉字的区位码索引公式就是 (位码- 0xa1)* 94 + (区码 - 0xa1),2 c3 q' i' {' m1 c/ J
知道了汉字的区位码就可以推算出这个汉字在我们字库中的索引值,由于每个汉字占用24个字节,我们就可以取得这个汉字的字模。; D; W: L3 u: {6 g
. M: E, v$ d5 J. x2 A0 @6 p1 |2 {
return _2byteFontPtr + ((_2byteWidth + 7) / 8) * _2byteHeight * idx;
4 j3 T1 I6 f4 t8 [ o0 q
+ \# ~) P2 P, r1 l% }((_2byteWidth + 7) / 8)的意义就是字节对齐。
3 R" {: d+ Z `9 g7 M* m
9 X( G3 ?4 J( W经过以上的修改,我们的scummvm就能显示出汉字了,是不是很简单呢?
( M9 z% b* O# E; c当然,在scumm引擎的游戏里面本来就有双字节函数的支持,所以修改相对比较简单,我们的修改主要是使它兼容于简体中文。
; W( k4 c' G! E$ ~: H对于其他引擎的游戏的汉化修改就没有这么简单了。但是,我们可以考虑把这些双字节函数移植过去。
0 x1 O/ f+ @) q7 g2 l8 S写下这篇小文章希望给后来者以些许启示吧。。。 |