冒险解谜游戏中文网 ChinaAVG
标题:
【Scummvm汉化 #1】Hopkins 国际刑警 #3 字幕篇
[打印本页]
作者:
shane007
时间:
2023-8-12 09:08
标题:
【Scummvm汉化 #1】Hopkins 国际刑警 #3 字幕篇
本帖最后由 shane007 于 2023-8-12 09:10 编辑
9 \8 G; j5 d+ y3 V1 L- j t
) x: j: g2 K0 Y# u6 E3 W) R
这游戏的字幕放在LINK目录下,分为*.IND和*.TXT 这2类文件。
' t5 w+ q$ W9 `( V% o% c
其中*.IND是索引文件,每4字节是一个索引,定义了每条字幕在*.TXT中的偏移位置。
1 v$ K: h7 [6 e- ^- W
" [7 o' v4 t1 b6 G0 i! d
比如,对话字幕保存在以下一对文件中,其中an代表的英文,此游戏共支持3种语言。
# G8 a. l; @3 P! ?3 @; x( ~
RUEAN.IND
- C8 G. h( c* Z0 c9 R, Y0 ]
ruean.Txt
4 x3 {( Z/ g1 m7 N
5 V. t5 O+ M1 a; ~, W+ P2 E6 C8 J1 e
*.TXT使用了加密方法,将字幕逐字节按照某种方式进行加密,具体实现可以参考代码。
' `: \- V" f3 h, R: [
提取字幕的方法,暂定为在*.TXT的解密代码后边临时加入一段代码,将解密后的明文输出到控制台,然后提取出来进行整理。
9 }3 C9 j$ u. Z3 s$ M$ M1 A% I
, W% p& \8 Z1 m- V, G/ M$ R
: E! W7 v, \: H7 M5 [
*.TXT的解密代码如下
L/ X6 P8 u+ Z' t7 G
int TalkManager::countBoxLines(int idx, const Common::String &file) {
( P- [* ^1 C# }5 W) e: G' c
_vm->_fontMan->_fontFixedWidth = 11;
* b9 j, g/ q) c, p0 @
7 i3 i, f/ \1 y6 u Q8 k# {
// Build up the filename
6 r5 B. [8 a- Y1 T4 L2 R
Common::String filename;
+ F. b8 M$ \/ d M* M; D6 q0 q- ~
Common::String dest;
- j+ @+ o6 S( M3 G
filename = dest = file;
! [% T3 u; d0 _9 Q: I# X
while (filename.lastChar() != '.')
) C* F2 k1 ]% s' R7 i8 ~: J
filename.deleteLastChar();
5 o/ N6 h3 V1 z! P6 B/ A
filename += "IND";
; F( M% {+ g) Y/ `$ C
& a% h5 w) k, K7 W7 k
Common::File f;
3 o: J, k; I- [& P
if (!f.open(filename))
4 T% v8 [8 c2 T; s* d: W z
error("Could not open file - %s", filename.c_str());
4 `- E/ Q& D( Q& f- I1 }3 {4 s; o
int filesize = f.size();
( Y6 z; M, p' u; Z
assert(filesize < 16188);
( Q2 R/ ?3 a3 v/ H
, `6 C; p, d# v3 W, [
uint32 indexData[4047];
! F2 |" I T3 t# j) v; q% \7 a
for (int i = 0; i < (filesize / 4); ++i)
" u( p7 y L3 r/ o
indexData[i] = f.readUint32LE();
: i: k! g. y o1 p: c
f.close();
0 _2 y- F! H7 I E& x$ _
: n( o5 A5 u, @4 ]8 V8 s7 D- n0 k
if (!f.open(dest))
( l7 G* v {2 Q6 Z* P3 H" {8 s) T+ N
error("Error opening file - %s", dest.c_str());
6 w5 k6 w+ k* E4 q6 l- Q. Q, Q
/ x2 i# v. V1 B6 O& c( _/ B1 ]
f.seek(indexData[idx]);
h T4 I3 X3 ?5 M
byte *decryptBuf = _vm->_globals->allocMemory(2058);
6 c0 S) C- f6 d# V" A
assert(decryptBuf);
6 T# n: H1 T5 e, D
2 x$ F9 X. o! E- ?1 O3 @% b0 n
f.read(decryptBuf, 2048);
' Z$ [) M/ a" o* Z2 Z! y$ S
f.close();
1 r( |; P/ b% Z V2 }5 I
$ m( H, J3 s9 f- R [$ W
// Decrypt buffer
( U* |# c( r2 A; k
byte *curDecryptPtr = decryptBuf;
, @, y2 @% H' ^" V0 v
for (int i = 0; i < 2048; i++) {
( G! M8 ?% t4 B$ T! p! O* Y& D5 H' t
char curByte = *curDecryptPtr;
2 @, @4 }& J7 E& b
if ((byte)(curByte + 46) > 27) {
. f# {) M: H9 Z; R; m
if ((byte)(curByte + 80) > 27) {
0 |' {* v9 z2 u6 G. Y; H/ K
if ((curByte >= 'A' && curByte <= 'Z') || (curByte >= 'a' && curByte <= 'z'))
+ ~' c& G/ d0 r& q
curByte = ' ';
3 w5 \( l K+ n0 K$ U
} else {
C( l8 T1 U* `' J
curByte -= 79;
^& q$ J2 K" ~4 j% I" I; U
}
7 d, G3 q+ }5 U5 y! x! {4 b% P' k% s
} else {
+ ^$ f/ c1 ]7 |. R4 f1 t
curByte += 111;
' r: z" Z4 E5 H6 J. p" X
}
0 f+ x; m; n: ]$ b
*curDecryptPtr = curByte;
; y) I+ R% [2 G& {! ]) ~6 f, S& o
curDecryptPtr++;
( S. j1 a& l! f# y% s
}
q' b7 N O/ h
/ C' X3 q; R2 G
// Separate strings
5 N3 F- f6 _! R D: P/ _* G
for (int i = 0; i < 2048; i++) {
$ w5 t' g$ O. g; V, | y. ?
if ( decryptBuf[i] == 10 || decryptBuf[i] == 13)
2 W$ i" W; @! r; F2 I
decryptBuf[i] = 0;
8 {% g; u' Q3 H" X9 C
}
& ] s' R8 B* g1 P; T/ r! W
! `2 }" d0 |( W m
//add by shane007
1 @, r% K8 C$ A8 B( n/ D, W# H; ~. S
//debug((const char *)decryptBuf);
+ G( z7 i* h7 T0 S% b. c
$ Y* V. E. o/ o( b3 b
// Check size of each strings in order to compute box width
7 A. z; b P) w+ z
int curBufIndx = 0;
/ w$ j% ^! {% V$ t7 D, R0 W
int lineCount = 0;
5 V& o3 Z7 a7 B7 H- E
int lineSize = 0;
8 T$ A( E# c" ^
char curChar;
2 }& S p# ?; H/ H$ c! o3 ~- ]
do {
1 _2 L- }4 Y0 K1 W2 H. S
int curLineSize = 0;
# o- A* N7 O& v2 l1 p- P
for (;;) {
5 }1 C7 J/ b# e1 f; y
lineSize = curLineSize;
# O: W, }0 s" z( Z0 S$ U/ J
do {
/ w3 n/ A& C# D/ C& p6 K- C
curChar = decryptBuf[curBufIndx + curLineSize];
9 h1 A1 M4 A" `2 D3 l0 J
++curLineSize;
& P. ]1 H: }( e. D
} while (curChar != ' ' && curChar != '%');
7 A+ p- E# [ @1 q2 X9 D
* Y ?1 O2 X$ H4 N$ g# B- v% }
if (curLineSize >= MIN_LETTERS_PER_LINE - 1) {
* F9 t9 Q1 j/ t9 I! Z
if (curChar == '%')
! a, }# v* N7 K
curChar = ' ';
: H p. }5 m- L7 D% P
break;
+ W5 X, a% q, k. F# P2 @
}
7 H/ D4 c1 N( o# d& H
! S4 C7 g6 g6 l2 G$ \ B3 g
if (curChar == '%') {
6 X" H+ P# V2 B: w% r
lineSize = curLineSize;
. \% n1 A) o: e, Q9 l3 ^9 `
break;
# u5 F$ _. f1 k- \$ M( E6 E
}
( i' h2 i" q# U' g, m, Q
}
5 D6 ?; v" E% ^ A: r- J
++lineCount;
7 U" V, q1 O- p' i
curBufIndx += lineSize;
0 i/ L9 k5 J9 q
} while (curChar != '%');
% |/ c4 i$ M8 k8 d: p
_vm->_globals->freeMemory(decryptBuf);
0 |: P1 U9 Z% I2 e C N) e
return lineCount;
3 r9 R; v* B7 V" U
}
复制代码
+ t; d T+ ^! ?; D0 ?- @
) _; w2 ]" ~* E7 d! O
欢迎光临 冒险解谜游戏中文网 ChinaAVG (https://chinaavg.com/)
Powered by Discuz! X3.2