本帖最后由 shane007 于 2023-8-12 09:10 编辑
% n f1 X0 ], S. x
6 l/ P4 D4 }" n( n 这游戏的字幕放在LINK目录下,分为*.IND和*.TXT 这2类文件。
/ C. b& O, p3 v, k3 d2 J 其中*.IND是索引文件,每4字节是一个索引,定义了每条字幕在*.TXT中的偏移位置。3 I8 R0 g7 @8 W
" v) _* _; Z* M" w% \ 比如,对话字幕保存在以下一对文件中,其中an代表的英文,此游戏共支持3种语言。
3 U9 q; Q: ^. d) S% P RUEAN.IND
; u7 A: ^; i- G$ S ruean.Txt2 v9 z4 H/ }8 t7 c2 d
, s9 t' r8 v7 |' w! C *.TXT使用了加密方法,将字幕逐字节按照某种方式进行加密,具体实现可以参考代码。' i r% H! I& R* R, A
提取字幕的方法,暂定为在*.TXT的解密代码后边临时加入一段代码,将解密后的明文输出到控制台,然后提取出来进行整理。+ O, b, \7 r0 _
9 d$ G! q9 E/ w( y5 I" z6 x' T6 T! A' E
*.TXT的解密代码如下
) D: Q6 ` k/ R' d3 X7 E9 P7 W- int TalkManager::countBoxLines(int idx, const Common::String &file) {
1 E; v* V5 }% w - _vm->_fontMan->_fontFixedWidth = 11;
: Y3 O6 U5 t: a# l5 o9 t% G
5 F5 b0 M! j5 ~* J6 h3 |# Y- // Build up the filename
7 e: A3 Q4 i* m8 \+ S3 Q" r+ J - Common::String filename;6 |3 b8 u% G* j
- Common::String dest;* u8 U2 S2 T$ Y
- filename = dest = file;% C7 I4 M6 Y; T2 y! y
- while (filename.lastChar() != '.')% ]3 g2 k: I! B+ Z$ Q
- filename.deleteLastChar();
2 k/ [ d/ ~6 x - filename += "IND";) D4 o/ f) s4 [+ b% d
- " j) m% L" H! J
- Common::File f;
8 T/ u% _0 P" H3 f; {) a - if (!f.open(filename))
8 P! ?; l3 F8 u$ y/ m$ B' T - error("Could not open file - %s", filename.c_str());
: k! l3 O- O, T/ H - int filesize = f.size();
7 B& R$ g5 O; t - assert(filesize < 16188);( V1 \( c1 S; b/ e7 A
- ! E4 C+ v( F: V
- uint32 indexData[4047];9 J) L3 L2 i3 k8 ]7 X
- for (int i = 0; i < (filesize / 4); ++i)+ l' @ Y3 G. k
- indexData[i] = f.readUint32LE();% z0 v( {. n4 t5 b' `
- f.close();1 @5 h" t2 B, R; u% C( I* Z; n0 t
5 l0 J* H, n& u9 O% n- if (!f.open(dest))
V1 c* ?; F9 P1 |8 s" m8 E - error("Error opening file - %s", dest.c_str());
1 Y$ L- G. f; b* R& B _) n - ' D* |7 z! L% x/ X' x
- f.seek(indexData[idx]);
& [ [2 Q+ f* @3 c: {$ b* V0 }8 ` - byte *decryptBuf = _vm->_globals->allocMemory(2058);
. _: i* a9 ~# N+ N4 z3 Z0 e2 R; l - assert(decryptBuf);
5 y. h' V0 X$ X2 Z0 M4 c - - |2 q) @; i# U
- f.read(decryptBuf, 2048);
" A7 B$ q8 h4 B- i4 y+ t7 K5 T - f.close();; l# {! x a. h* U5 V# C
D6 q! P7 _; f- ]# m- // Decrypt buffer1 ]7 T2 ?, U% G
- byte *curDecryptPtr = decryptBuf;% \- M1 U' p% Z3 A6 Y( J) L" i6 j
- for (int i = 0; i < 2048; i++) {! ?( `, B+ e; M9 O2 ]7 {
- char curByte = *curDecryptPtr;1 n5 w% i9 a9 W1 v
- if ((byte)(curByte + 46) > 27) {4 ]" B$ `$ A; U: s5 ^; U& E; `7 u
- if ((byte)(curByte + 80) > 27) {' ]- ^% A0 T( v! p. V8 J
- if ((curByte >= 'A' && curByte <= 'Z') || (curByte >= 'a' && curByte <= 'z'))" H: ~: }) ~1 z) W! K
- curByte = ' ';! e e' H9 o6 H8 ^4 l. _7 Q6 Q
- } else {9 [' F+ ~ S' Z5 N
- curByte -= 79;
4 T* K3 g, O5 t$ x4 v# @ - }
# L, _) t9 Y' v0 p! B& q } @ - } else {0 M$ n- ~$ n, ?3 r4 C: i
- curByte += 111;
& C) @% E: @/ [; `1 t3 ~1 G3 ] - }3 V, f9 `$ K& Q) s) H$ o2 Z# X
- *curDecryptPtr = curByte;
, h* _( W, v* k9 O - curDecryptPtr++;
+ h* j6 Z y% N - }
) A, W/ Q2 i/ ~# `6 s4 s - * H/ [4 [6 |8 Y. W8 V5 v: ?
- // Separate strings' f( O; ^( G% ^+ c
- for (int i = 0; i < 2048; i++) {/ G4 L# z! r- H: X% w2 b9 N
- if ( decryptBuf[i] == 10 || decryptBuf[i] == 13)0 D! R' }: X/ s1 b
- decryptBuf[i] = 0;
2 U* q/ i/ I( ~8 d' }7 u! x6 [ A - }
5 g; n* i: |# u5 Z
$ b7 |/ q/ K/ i. r$ u2 ]/ Z- //add by shane007
0 x5 l! B& T w' u - //debug((const char *)decryptBuf);# A" t* X v' A
- 4 @% H; c( G6 G' W9 j) t( h% k
- // Check size of each strings in order to compute box width
! I ~$ H. b" [9 F- k0 L - int curBufIndx = 0;- R) o, Y# Y; b* b
- int lineCount = 0;4 W+ g) G& Q# w; s6 c( r! P
- int lineSize = 0;- J8 a, c. Y% d
- char curChar;% A8 q% ~7 O2 r4 \$ m! i4 |' y+ i
- do {
% z+ P+ F2 R) A - int curLineSize = 0;
1 J6 K9 r% w# z2 m- e O - for (;;) {
' q7 n! i, \8 i! M - lineSize = curLineSize;+ Y% S3 G. o1 o8 V1 |9 g$ f
- do {
& q1 a6 f0 F1 u - curChar = decryptBuf[curBufIndx + curLineSize];
! ^. i& @( F' S' C+ n& o- u9 I: x - ++curLineSize;) U% W4 z7 ^2 O. U
- } while (curChar != ' ' && curChar != '%');* D5 k6 y" H/ |0 b5 ^; y8 |+ |
- " b e) e `4 ?7 {. l
- if (curLineSize >= MIN_LETTERS_PER_LINE - 1) {
1 M$ _: F f# u- d - if (curChar == '%')
{- _$ h' D* ] - curChar = ' ';
) F6 |/ B) ^$ j. P7 Q( N - break;0 z! _& n8 i' V7 X0 e
- }
7 U3 x' H% C. x5 t" h
6 ]5 Z+ H7 q0 y8 F" r- if (curChar == '%') {/ v2 S" [/ T" |
- lineSize = curLineSize;- t5 W+ i; D' }9 O# J* Z5 c
- break;
. F3 P4 `2 o6 a* A5 C - }
% P2 t8 j; w* T. r - }1 U B, B( J& e' d7 ~
- ++lineCount;0 _6 }& g* q8 X: j& r
- curBufIndx += lineSize;
7 c- c2 r. M# G7 S, |7 h2 W5 k - } while (curChar != '%');3 D2 V4 r- R" _/ h4 F8 R. l' E
- _vm->_globals->freeMemory(decryptBuf);
" r+ i) M, u$ F+ T - return lineCount;$ v; H! K M; X" ]
- }
复制代码
$ N5 L( {$ N/ A; h: e3 |; b/ y5 ^* V6 n. Q# X4 h
|