冒险解谜游戏中文网 ChinaAVG
标题:
【scummvm汉化】细说scummvm汉化修改核心机密
[打印本页]
作者:
shane007
时间:
2009-8-15 20:47
标题:
【scummvm汉化】细说scummvm汉化修改核心机密
看这个标题好像挺神秘的,其实,这个帖子只是要向大家详细解释一下是如何修改scummvm,使它能够显示出汉字的。
5 l/ O3 i7 w+ j9 R5 V1 v5 e. j
" F4 g( }4 E6 b/ _9 `5 _3 N I
汉字字库
! b K) d3 Y _7 T2 t2 h# K, ?1 u: _
先说一下汉字字库,scummvm原先支持几个繁体中文的游戏,比如猴岛小英雄3,使用的是16X15的繁体字库。字库的文件名是chinese.fnt,在繁体中文版的文件中可以找到。看字体的样子好像是以前DOS时代的倚天字库。好,我们就从这里入手。既然能用繁体字库,那么使用简体中文的字库应该也是可以的。一开始我找了一个UCDOS的HZK16字库,但是放到游戏里面一试,高度太高了,在对话选择画面的时候,上下2行的字都会互相遮挡住,看来用现成的HZK16字库是不行了。在网上找了半天,也没有找到合适的字库。于是我决定自己造一个点阵字库。要造多大的字库呢,经过一番调查,最小只能用12点阵的字库,再小的话就看不清了。字库是用一个在网是找到的免费的TTF转点阵字库的工具转换的,没有费太大的力气。转换出来的字库是字节对齐的,也就是说,是12X16的,在宽度方向上对齐到16个点,也就是2个字节。既然是这样,1行是2个字节,12行就是24个字节,字库中每24个字节就能表示一个汉字,这一点不难理解吧。
2 n! n2 s; ]: N; C* N9 [0 M
7 {# S1 V- L5 ?& h& f4 ], ~2 h
下面我们来看一段代码,这段代码在charset.cpp这个文件里面。
" s( R/ o9 O- \
: H2 p7 Q, r' I& d; j
case Common::ZH_TWN:
6 g! A: X0 G" ^
if (_game.id == GID_CMI) {
4 G1 }1 l/ L b7 X4 e+ z9 J
fontFile = "chinese.fnt";
# l# U& [& ]( l3 c: J
numChar = 13630;
0 r" V( k, o- W. o' x! u! X% [
}
7 D! I/ A Y. K8 u3 ~
break;
9 Z5 A, W# w; w& [0 h2 q" h) a
case Common::ZH_CNA: //add by shane007 2009.7.12
2 h' ~6 U; o, [& W" r% I
if (_game.id == GID_FT ||
, r& _' b; y# a& _6 e8 f6 s
_game.id == GID_SAMNMAX ||
- X5 n/ j! y4 \" n3 Y
_game.id == GID_LOOM ||
. |$ v7 n/ E S9 L) ]& D2 k3 W1 G
_game.id == GID_INDY3 ||
/ L- [8 [1 ~, Q8 g) |1 z9 {1 F
_game.id == GID_INDY4 ||
! \. F3 h! X9 Y
_game.id == GID_MONKEY||
; |9 @! ? ^5 _3 `+ P8 ^
_game.id == GID_MONKEY2||
: M( k ] L# b# h+ ]
_game.id == GID_TENTACLE) {
2 W0 C" W3 Z( U! y; y1 j9 ?
- f# h+ i# Y3 I4 z: L: C6 h
fontFile = "chinese_gb16x12.fnt";
% ^0 [$ ~7 F i' [
numChar = 8178;
+ h6 n6 |4 O8 t( R: [ p
}
) T0 }- e/ z* O
break;
) A! [4 Q- |) X, Z
default:
/ d% s; h; b6 J/ I @" N
break;
, i7 _- ]: r/ s* U( m- J) d
}
/ Z5 D( Z# B2 K+ R! c: E
& A9 @( ^( Z/ r, Q; e7 n
代码包括了繁体字库和简体字库的定义,game.id是游戏的ID,我们让那些SCUMM引擎的游戏进来的时候,使用我们制作好的简体字库chinese_gb16x12.fnt。numChar是字库里面的中文字符数量。ZH_CNA是我们新增加的一种语言类型,在原版的scummvm里面是没有的。所以有的朋友在原版的scummvm里面找不到简体中文的选项,就是这个道理。是我加上去的。
6 U6 y% R7 X: r9 j1 K) @- V
) J* |( m7 w1 N" {8 f
有的朋友也许还不太清楚,游戏是怎么找到我们需要的那个汉字的字模的,让我们再来看一段代码。
, A4 ]$ j2 I3 \% U% n, t. b+ f
+ @( N- w x& R: V' w7 B4 t3 n* \3 x
case Common::ZH_CNA: //add by shane007 2009.5.19
& k' x" y- y8 g% f0 A" M' }/ F- ]
idx = ((idx % 256) - 0xa1)* 94 + ((idx / 256) - 0xa1);
) b3 a+ I7 U% l+ x. \
break;
Q! H1 p t1 J& I- p
& Z2 L# m) {% q" _& q2 a9 ~1 q
其实很简单,我们汉字的区位码索引公式就是 (位码- 0xa1)* 94 + (区码 - 0xa1),
, F" P; Y" q# c6 Q- K2 @. Z6 B
知道了汉字的区位码就可以推算出这个汉字在我们字库中的索引值,由于每个汉字占用24个字节,我们就可以取得这个汉字的字模。
$ ~* Y1 ~ q) m
. ]4 J. U9 Q' l- Y6 j
return _2byteFontPtr + ((_2byteWidth + 7) / 8) * _2byteHeight * idx;
3 `) H8 j# ?* |5 J8 ?1 C( p
5 I' p X( o; s9 c' q5 ?
((_2byteWidth + 7) / 8)的意义就是字节对齐。
! Q( u5 t* @, u" O
, Q7 q2 e5 H6 n" Q# i2 `0 ?0 _
经过以上的修改,我们的scummvm就能显示出汉字了,是不是很简单呢?
3 Y3 H# i ^* t/ E1 w3 F
当然,在scumm引擎的游戏里面本来就有双字节函数的支持,所以修改相对比较简单,我们的修改主要是使它兼容于简体中文。
, D( ~; y3 a# B( u+ b
对于其他引擎的游戏的汉化修改就没有这么简单了。但是,我们可以考虑把这些双字节函数移植过去。
( s+ d- ?4 E6 t, {% O0 n
写下这篇小文章希望给后来者以些许启示吧。。。
欢迎光临 冒险解谜游戏中文网 ChinaAVG (https://chinaavg.com/)
Powered by Discuz! X3.2