看这个标题好像挺神秘的,其实,这个帖子只是要向大家详细解释一下是如何修改scummvm,使它能够显示出汉字的。5 ?# q# g7 U9 R% F0 \9 d7 i* U
# `# `/ j% n& c! B5 M) P
汉字字库
6 ]( t p& e' |* ~% |先说一下汉字字库,scummvm原先支持几个繁体中文的游戏,比如猴岛小英雄3,使用的是16X15的繁体字库。字库的文件名是chinese.fnt,在繁体中文版的文件中可以找到。看字体的样子好像是以前DOS时代的倚天字库。好,我们就从这里入手。既然能用繁体字库,那么使用简体中文的字库应该也是可以的。一开始我找了一个UCDOS的HZK16字库,但是放到游戏里面一试,高度太高了,在对话选择画面的时候,上下2行的字都会互相遮挡住,看来用现成的HZK16字库是不行了。在网上找了半天,也没有找到合适的字库。于是我决定自己造一个点阵字库。要造多大的字库呢,经过一番调查,最小只能用12点阵的字库,再小的话就看不清了。字库是用一个在网是找到的免费的TTF转点阵字库的工具转换的,没有费太大的力气。转换出来的字库是字节对齐的,也就是说,是12X16的,在宽度方向上对齐到16个点,也就是2个字节。既然是这样,1行是2个字节,12行就是24个字节,字库中每24个字节就能表示一个汉字,这一点不难理解吧。
0 S1 N* W% w h" ^' d6 z' x9 T) L0 x/ P4 c9 D% v' \) p
下面我们来看一段代码,这段代码在charset.cpp这个文件里面。4 b' D" f, I% F' }5 j+ I0 @- y3 A
: Q6 J; l: f' V
case Common::ZH_TWN:
5 i. S- l3 d) J/ x0 l2 A) P if (_game.id == GID_CMI) {: @7 P; O4 A C, x/ H/ R
fontFile = "chinese.fnt";
G& G+ x! S' [/ S3 ?+ D3 S- O numChar = 13630;
$ m4 B! w, c$ i }
( @" J( Z1 F7 Z: X break;
) P; b8 T" z! bcase Common::ZH_CNA: //add by shane007 2009.7.12: n: V) _% r6 m3 k
if (_game.id == GID_FT || - t/ Y5 w Y4 p& r9 I3 M( P7 u
_game.id == GID_SAMNMAX ||
! \% y2 | ]$ S* k8 u8 Y7 U _game.id == GID_LOOM ||
9 ~! q: E) C' t1 V: i% t3 H+ m _game.id == GID_INDY3 ||* N7 w& \4 M6 c0 c/ O
_game.id == GID_INDY4 ||, w9 n8 ^$ k6 d: ~7 @0 u2 _
_game.id == GID_MONKEY|| F0 C5 N, Q) `$ H
_game.id == GID_MONKEY2||
: J k/ v6 Q8 A+ X# p$ B _game.id == GID_TENTACLE) {' X% N5 K1 k& y( ~, Z. H. ^
2 _9 d- `' i6 H9 d) k, b8 ~( |
fontFile = "chinese_gb16x12.fnt";
6 R( u4 E" |* m3 I- X numChar = 8178; 0 h9 M/ j1 N8 s) p; A3 i, ~
}) K+ _* T) G$ r9 I- a% f6 q
break;+ {& m( `. g! k# E
default:
6 f7 Z4 v! f$ J9 l% G4 r break;) R* C, v( S8 \7 O) t7 S5 ^& l
}
" b. }0 l0 |3 o* _/ c
2 b1 X) r! i) x7 w代码包括了繁体字库和简体字库的定义,game.id是游戏的ID,我们让那些SCUMM引擎的游戏进来的时候,使用我们制作好的简体字库chinese_gb16x12.fnt。numChar是字库里面的中文字符数量。ZH_CNA是我们新增加的一种语言类型,在原版的scummvm里面是没有的。所以有的朋友在原版的scummvm里面找不到简体中文的选项,就是这个道理。是我加上去的。
2 Y+ b9 s0 Z- |+ T$ w+ O
! R1 G4 m& z% }( }1 o有的朋友也许还不太清楚,游戏是怎么找到我们需要的那个汉字的字模的,让我们再来看一段代码。6 N8 ~3 n0 X% v$ B
( h0 m' R9 o1 u" T4 ^case Common::ZH_CNA: //add by shane007 2009.5.19, O5 s+ I4 u K% c; N* H
idx = ((idx % 256) - 0xa1)* 94 + ((idx / 256) - 0xa1);6 W! w6 \; N9 ~
break;) S2 C- i8 O2 o$ [$ M3 U; G
6 f0 Q7 ]& G d4 z; o+ D6 H" _! K9 z
其实很简单,我们汉字的区位码索引公式就是 (位码- 0xa1)* 94 + (区码 - 0xa1),
( X+ k) I. `$ h/ Y+ v知道了汉字的区位码就可以推算出这个汉字在我们字库中的索引值,由于每个汉字占用24个字节,我们就可以取得这个汉字的字模。
7 s1 d& S" G) i, t& h, _2 J, W
7 B/ ` I8 @8 a w* `1 S+ Z% Jreturn _2byteFontPtr + ((_2byteWidth + 7) / 8) * _2byteHeight * idx;
: p+ m; B1 C1 X: O3 q' J" P& o5 {) g: E; M- |: {
((_2byteWidth + 7) / 8)的意义就是字节对齐。
" E2 `: H9 M; d1 C2 g4 p9 V! {' [+ y8 f0 {; E& l
经过以上的修改,我们的scummvm就能显示出汉字了,是不是很简单呢?
: R8 c: c+ V- `# ]+ |1 d当然,在scumm引擎的游戏里面本来就有双字节函数的支持,所以修改相对比较简单,我们的修改主要是使它兼容于简体中文。
" s# A7 H/ S8 S4 [5 z对于其他引擎的游戏的汉化修改就没有这么简单了。但是,我们可以考虑把这些双字节函数移植过去。! B/ w8 i/ A. [# R; {
写下这篇小文章希望给后来者以些许启示吧。。。 |