看这个标题好像挺神秘的,其实,这个帖子只是要向大家详细解释一下是如何修改scummvm,使它能够显示出汉字的。+ a) U6 ~" I, q- U
0 [7 R8 {3 o; r p8 q3 X, X% f+ U汉字字库
; B+ [* C' L7 L* H2 u+ Y4 h先说一下汉字字库,scummvm原先支持几个繁体中文的游戏,比如猴岛小英雄3,使用的是16X15的繁体字库。字库的文件名是chinese.fnt,在繁体中文版的文件中可以找到。看字体的样子好像是以前DOS时代的倚天字库。好,我们就从这里入手。既然能用繁体字库,那么使用简体中文的字库应该也是可以的。一开始我找了一个UCDOS的HZK16字库,但是放到游戏里面一试,高度太高了,在对话选择画面的时候,上下2行的字都会互相遮挡住,看来用现成的HZK16字库是不行了。在网上找了半天,也没有找到合适的字库。于是我决定自己造一个点阵字库。要造多大的字库呢,经过一番调查,最小只能用12点阵的字库,再小的话就看不清了。字库是用一个在网是找到的免费的TTF转点阵字库的工具转换的,没有费太大的力气。转换出来的字库是字节对齐的,也就是说,是12X16的,在宽度方向上对齐到16个点,也就是2个字节。既然是这样,1行是2个字节,12行就是24个字节,字库中每24个字节就能表示一个汉字,这一点不难理解吧。
1 ]' y9 e8 N1 E% x/ }' G6 Y0 h
3 l! D% y5 i4 C6 I; X* b下面我们来看一段代码,这段代码在charset.cpp这个文件里面。
" }. ^4 {2 x5 O! H- x( l4 J+ Y; v4 D
case Common::ZH_TWN:
5 Z: k/ \' S! A0 f) C* ] if (_game.id == GID_CMI) {
; u0 N8 r% }: [: q R fontFile = "chinese.fnt";
# Z- h' B$ V' H& \# ]* b2 G numChar = 13630; q# [* w7 q8 i5 v( T+ R. D$ D' W
}
. [2 B( H: y! D( m2 K break;
& X- I ~% y5 K" j. I( X Acase Common::ZH_CNA: //add by shane007 2009.7.12
! K& ]+ h. a2 i' W if (_game.id == GID_FT || , h4 b/ {3 T* n
_game.id == GID_SAMNMAX || 7 }+ j8 p L0 Q" S' O6 ~ N7 c
_game.id == GID_LOOM ||
+ B: e3 [% v; w* _# j( x _game.id == GID_INDY3 ||
/ y! j, k8 F6 ]4 ^) J! Q5 N$ { _game.id == GID_INDY4 ||
5 E, f5 B& ?" _( n x' r _game.id == GID_MONKEY||
, G D a4 i# T* y$ ~2 |/ U _game.id == GID_MONKEY2||& m# U; d! L/ V" q% w4 F
_game.id == GID_TENTACLE) {8 e5 {) ~ t* a' r9 s+ A G
6 k& T4 [) B5 A( Q; u2 e4 @% m
fontFile = "chinese_gb16x12.fnt";
, @* Q4 o9 k3 P$ i$ A! _ numChar = 8178; + r1 R- V& `( A! L
}
7 A4 d7 u' F1 x9 S1 }' I break;
/ F* `( I% Y. d, o. J1 ?default:
6 K$ _: u* q8 v6 O break;
) b) y: a- i1 u$ J9 q, }}, j- W4 u3 @ F9 ^% D; E/ d% Y3 U
! G# d4 f" f! i. \$ z代码包括了繁体字库和简体字库的定义,game.id是游戏的ID,我们让那些SCUMM引擎的游戏进来的时候,使用我们制作好的简体字库chinese_gb16x12.fnt。numChar是字库里面的中文字符数量。ZH_CNA是我们新增加的一种语言类型,在原版的scummvm里面是没有的。所以有的朋友在原版的scummvm里面找不到简体中文的选项,就是这个道理。是我加上去的。% w0 D1 i& y3 f
0 `- v+ T$ p1 R) N% T
有的朋友也许还不太清楚,游戏是怎么找到我们需要的那个汉字的字模的,让我们再来看一段代码。
) r/ F R/ C6 P2 b* R
! A% Y4 L$ ^9 V: U2 G# Icase Common::ZH_CNA: //add by shane007 2009.5.19( g# K" ^& I; K
idx = ((idx % 256) - 0xa1)* 94 + ((idx / 256) - 0xa1);
3 t- g R' N- p1 C5 @) \ @break;" u0 i. d o7 @( V$ }& o8 Y( l
/ b2 w# C! ^8 C& f0 n$ g/ g其实很简单,我们汉字的区位码索引公式就是 (位码- 0xa1)* 94 + (区码 - 0xa1),
* E/ d% i! I- O5 X2 U* B/ ~6 q- l知道了汉字的区位码就可以推算出这个汉字在我们字库中的索引值,由于每个汉字占用24个字节,我们就可以取得这个汉字的字模。; p7 r7 m" @4 ?
: N* I# h C M6 `
return _2byteFontPtr + ((_2byteWidth + 7) / 8) * _2byteHeight * idx;
! X N7 Q5 W/ P) u2 F+ D( {
5 C8 K: i+ ? f0 g% [((_2byteWidth + 7) / 8)的意义就是字节对齐。
+ d, D; J+ K2 c$ O* a( V T1 \! [0 ~9 ^8 \% v
经过以上的修改,我们的scummvm就能显示出汉字了,是不是很简单呢?0 A _9 J2 v: X9 G) C
当然,在scumm引擎的游戏里面本来就有双字节函数的支持,所以修改相对比较简单,我们的修改主要是使它兼容于简体中文。
# ]. T$ c7 f" M' ?0 P) i对于其他引擎的游戏的汉化修改就没有这么简单了。但是,我们可以考虑把这些双字节函数移植过去。
( W0 B1 T7 ?1 o( d写下这篇小文章希望给后来者以些许启示吧。。。 |