本帖最后由 shane007 于 2023-8-12 09:10 编辑 * C) ?$ N8 F0 [2 b0 n# ]8 G
8 k- ~8 ^( x. H4 K" p8 q9 X' g 这游戏的字幕放在LINK目录下,分为*.IND和*.TXT 这2类文件。
0 m/ T- n( I* p: g 其中*.IND是索引文件,每4字节是一个索引,定义了每条字幕在*.TXT中的偏移位置。
6 U7 o% S( y% {8 L2 a: X
6 H6 R3 G1 \0 L+ y& y3 s5 J 比如,对话字幕保存在以下一对文件中,其中an代表的英文,此游戏共支持3种语言。) @" Q! J, _# b q+ z; v: v
RUEAN.IND
3 Q. u: r* ?% G. c. {5 Y9 w* W ruean.Txt
+ {+ w% t' p. [- o3 f! S) m. f/ D; @& P0 |* ~8 |4 a5 I2 _2 N
*.TXT使用了加密方法,将字幕逐字节按照某种方式进行加密,具体实现可以参考代码。1 H$ s9 U' {% ?& E( ]& l
提取字幕的方法,暂定为在*.TXT的解密代码后边临时加入一段代码,将解密后的明文输出到控制台,然后提取出来进行整理。0 H0 O. c: E' D+ K0 D1 o, P
& F; ?9 U% b6 }4 D I6 L* S
8 m: C% }8 ^, C& }' c' @
*.TXT的解密代码如下7 I' d, x* V6 G; t1 x: |- N: |) H
- int TalkManager::countBoxLines(int idx, const Common::String &file) {0 }) U4 D6 k. c2 Z5 N
- _vm->_fontMan->_fontFixedWidth = 11;0 w3 c+ ~7 V$ \2 L S7 d( x+ [7 Q) ?
) E7 J, c* `+ B$ ]% }8 b) A8 J* a5 e4 C0 \- // Build up the filename
6 W p, A. \ v% `0 ~$ I1 b6 P - Common::String filename;& S7 O% j* n! p6 O, O) X- _" v* k
- Common::String dest;2 y! F5 r; ]) K, f: q; ?
- filename = dest = file;0 Z1 T% n- Z- q5 Z, Z) ?
- while (filename.lastChar() != '.')& n; u, C% t1 [/ h- }; ~, D' |
- filename.deleteLastChar();8 {! c1 O1 e: }% F' L; d
- filename += "IND";
' p/ m( p) m( i7 S( t - & a% V, E; }0 o7 R# L0 i) B3 m
- Common::File f;) a2 a1 s8 |. `/ ^7 |4 P
- if (!f.open(filename))3 z& b- t6 B E# O9 m
- error("Could not open file - %s", filename.c_str());5 G+ J6 i% _ W, \3 x) L. e( U
- int filesize = f.size();! l& s- J, M* z! m3 i6 M0 P
- assert(filesize < 16188);4 x P+ o0 h6 x4 J$ n
- ' z2 N# H# ]3 i1 \* g
- uint32 indexData[4047];" I9 N! u B$ B/ e2 V( `, \2 s
- for (int i = 0; i < (filesize / 4); ++i)
8 S" {( |( A1 [, h, ^. _, u& j - indexData[i] = f.readUint32LE();4 b& K8 m: h4 [% g( D' b6 ^* h
- f.close();
7 f: r, ^6 l0 t. B6 o
1 p k8 i) u4 t1 Z% w) V- if (!f.open(dest))' _" p! o- F( r0 a% K0 ~
- error("Error opening file - %s", dest.c_str());
7 q- N x) q3 ?0 X
; K$ `- l8 V+ V; k- f.seek(indexData[idx]);
2 b, g; @8 V& W( c3 W0 |$ ? - byte *decryptBuf = _vm->_globals->allocMemory(2058);
& e- [2 }2 M1 F; P0 e/ {6 z$ o - assert(decryptBuf); K+ k& w+ a# _/ @& J# @6 ?
2 q, I0 h" d8 |& O- f.read(decryptBuf, 2048);% ?9 O/ G A, L8 D" o
- f.close();
& K W6 }+ V5 e8 P - 7 H4 z0 F. W/ }9 }
- // Decrypt buffer) d! z& k2 h7 Y# f/ R
- byte *curDecryptPtr = decryptBuf;6 z }9 U: x6 h1 G7 C* {7 J
- for (int i = 0; i < 2048; i++) {
M, h8 w8 e6 P; ~, d - char curByte = *curDecryptPtr;
) b1 \+ F! Y8 n3 A - if ((byte)(curByte + 46) > 27) {) r$ Q# f, E2 t3 [' p
- if ((byte)(curByte + 80) > 27) {
, B9 K. ]7 E4 }* f - if ((curByte >= 'A' && curByte <= 'Z') || (curByte >= 'a' && curByte <= 'z'))/ n$ \" ^, `( ~
- curByte = ' ';- }4 _, N* d/ Q, w$ y
- } else {$ l& P3 b( C' x- e3 ?
- curByte -= 79;& Z7 z0 j: @5 T9 ^
- }0 [* a4 W ~1 U+ p- a! I9 r0 s% I
- } else {
0 X& N) B) D( O! ?+ V3 v - curByte += 111;
9 M6 a6 g8 Y9 C' [ ?, G. r7 N - }' y [8 Z* G0 b8 {2 D! C' J
- *curDecryptPtr = curByte;2 R; b; |$ j: c
- curDecryptPtr++;, E6 J3 ^. V( r) p ?! \( n
- }
. v* a5 U3 {8 m. w& q) E - 9 X+ d5 D$ ]( M
- // Separate strings
& y5 k" {( t. v' S$ ]" k1 v. t - for (int i = 0; i < 2048; i++) {3 D4 E6 Z& i9 q/ }% [( b& M
- if ( decryptBuf[i] == 10 || decryptBuf[i] == 13)
- F4 \+ ^ D3 j) }. c - decryptBuf[i] = 0;
6 q# [3 |" V: \ - }- P; T* F' K, ~( _9 B' e3 l. P
- % V/ p+ r5 q/ n9 B& J
- //add by shane007
/ V8 W7 S# E8 V& N Z1 _ - //debug((const char *)decryptBuf);
0 f- T# f8 }" c& h
. r4 R: v& u/ m' k8 q, I- // Check size of each strings in order to compute box width q! n& _5 u5 N$ _. }# b
- int curBufIndx = 0;1 J9 U. l5 p* ^
- int lineCount = 0;
& t6 i2 m/ X! B8 a+ Y7 R6 _ - int lineSize = 0;: a/ e8 ?, w0 D2 X9 b
- char curChar;" ], o# f. B0 U% P4 W6 O/ \# c
- do {
4 ~+ T7 c7 K) R! n; ^: z* P1 p - int curLineSize = 0;6 l" X# _$ c" Q; G% P( m
- for (;;) {
5 T9 {4 i0 C [' ^8 d1 f - lineSize = curLineSize;
4 o, f: S! ?3 x5 C. E2 N - do {3 q8 C; N- |; z& z, a- l
- curChar = decryptBuf[curBufIndx + curLineSize];& _8 e7 v, k* ^0 I
- ++curLineSize;
1 ]2 i$ J$ T& e0 | - } while (curChar != ' ' && curChar != '%');0 V, ?+ `6 d A" N: o+ |" v
- % X% @# k! D3 O
- if (curLineSize >= MIN_LETTERS_PER_LINE - 1) {
: j, l0 I4 F# T* e - if (curChar == '%')! U$ Q( {% k( {. K* ?7 G
- curChar = ' ';
0 U9 F* H+ {# B% G( s - break;
% ]6 A# D; F0 K% l7 q3 l& j3 Z/ a - }
8 W( _7 l& R" n7 c& X; C - 8 q5 l4 X$ }8 _+ ~
- if (curChar == '%') {
( K: J6 X+ p0 O! c - lineSize = curLineSize;$ E" ^ l3 O1 d6 V- ]$ f) j
- break;
" e, ~4 \- o* _. M3 B/ i0 K - }! F! B: L% v) A2 P: U0 ~0 v" L. Y
- }
5 g8 R) l9 h* J. i. f4 ]6 ~. f - ++lineCount;( O$ b' p6 T+ z( e
- curBufIndx += lineSize;
$ O. B8 n( P. u - } while (curChar != '%');6 S7 B" N* x0 u7 @8 _1 K3 e
- _vm->_globals->freeMemory(decryptBuf);
& [! O5 e r6 r# F. e - return lineCount;
8 p. k7 K3 }4 |/ e2 O- V. \ - }
复制代码 " r6 B" H+ I# @8 E
6 k/ J4 B4 R( k- D' C |