本帖最后由 shane007 于 2023-8-12 09:10 编辑 . x* P1 ^3 D# J$ ~" i* G
% R5 L% d% I. E% P, z$ C7 b5 S 这游戏的字幕放在LINK目录下,分为*.IND和*.TXT 这2类文件。
+ w8 }7 V; v, C 其中*.IND是索引文件,每4字节是一个索引,定义了每条字幕在*.TXT中的偏移位置。
0 Q" W# J' U9 I$ j- w `' t
3 x: [2 F% _% `& O8 v) N9 T. u, n 比如,对话字幕保存在以下一对文件中,其中an代表的英文,此游戏共支持3种语言。
: T. ], l) C- G- ^9 Y RUEAN.IND% |. a# q& N9 W; K+ @
ruean.Txt* P# D/ `' Y) |0 ~4 x5 D0 U
0 @$ V9 V+ i# \5 S& p T *.TXT使用了加密方法,将字幕逐字节按照某种方式进行加密,具体实现可以参考代码。
, j# v3 m& \1 [2 ] 提取字幕的方法,暂定为在*.TXT的解密代码后边临时加入一段代码,将解密后的明文输出到控制台,然后提取出来进行整理。$ f& K* N' [/ r+ f% T
: c$ J2 s0 [ o3 B* K
3 ~6 j4 W6 \2 o0 ]* f: r *.TXT的解密代码如下* E" f8 d0 k) O8 S
- int TalkManager::countBoxLines(int idx, const Common::String &file) {
: J$ {. z/ F3 O+ n - _vm->_fontMan->_fontFixedWidth = 11;
/ d$ k8 B) `( g% z: d+ q: i. i
5 j3 h. W# k1 P* ^" |, w9 Z- // Build up the filename i$ O/ K# H5 G+ ^6 j
- Common::String filename;
: @3 A" N. N+ k - Common::String dest;
0 n: ~- H% ~# j) W) z9 L - filename = dest = file;0 U9 ]" a9 ]$ B" {- l
- while (filename.lastChar() != '.'). }5 G2 z+ }% R7 P- d5 U$ W$ K
- filename.deleteLastChar();
7 w8 \! c$ Z! c+ {" r2 y - filename += "IND";
# I" f8 H7 b9 |5 p1 ~7 H; h - , t0 L- z, Y$ {* F. e7 Z- q0 m/ J
- Common::File f;. U8 _/ i) r+ w- U7 [
- if (!f.open(filename))& R. P7 ?3 l: G7 t. S9 r' R
- error("Could not open file - %s", filename.c_str());, h7 z V1 ? e; b* x5 X$ k, u
- int filesize = f.size();$ n+ C+ f8 @# k; p @. E. [
- assert(filesize < 16188);$ g1 U0 C5 i; r2 @0 n) W
6 B3 J6 Y8 W2 i5 s/ b- uint32 indexData[4047];
! ], d% i6 w" o( |+ y' s1 G - for (int i = 0; i < (filesize / 4); ++i)1 I% ^" B* X/ c$ {& O
- indexData[i] = f.readUint32LE();( G' F& l5 v( \
- f.close();
1 D. Y1 ~. ~# \$ Q+ E" ]. {: @
# ]8 P* ]7 o# I! e, I! ^' R( b5 I( v- if (!f.open(dest))
! x1 X, g* ~. I9 u* g4 A, z0 m3 p7 a - error("Error opening file - %s", dest.c_str());
, H, ~8 F' k0 _3 s$ \" p - $ |* W# m L$ K1 f1 ?- `0 X: [8 q
- f.seek(indexData[idx]);
' g0 ~1 l7 y/ V4 [' z* N - byte *decryptBuf = _vm->_globals->allocMemory(2058);( s" Q! U8 U( H
- assert(decryptBuf);
8 S; @, x3 B' a! w - ; }* E" w- Y9 q: ^ |
- f.read(decryptBuf, 2048);
' X3 [4 |, H1 B- B, R4 D - f.close();% a2 ~: s: Y2 U
- / v4 Y* r* {! L/ A# Y
- // Decrypt buffer) e& h/ P/ @6 ]6 B# x* ?5 X* g
- byte *curDecryptPtr = decryptBuf;' ]$ e: B7 {+ I- |+ K
- for (int i = 0; i < 2048; i++) { h3 x0 i2 G' P* _3 n* l! Q9 S
- char curByte = *curDecryptPtr;
" ~* f5 s+ t- @ x* e( b h - if ((byte)(curByte + 46) > 27) {
, ]$ j; I' |8 `$ T T - if ((byte)(curByte + 80) > 27) {0 i2 F! D+ |" ?5 M, }
- if ((curByte >= 'A' && curByte <= 'Z') || (curByte >= 'a' && curByte <= 'z')): Y& u* S0 g7 T- k/ ]" B# z* U
- curByte = ' ';
. m9 [+ o3 L4 _# O/ A - } else {
2 E, {$ @: b Z* O9 U - curByte -= 79;
+ ~9 @, [. H1 L: l# C; q - }
% }3 y- a. X q: k - } else {
+ t! Y3 T) v7 f% t - curByte += 111;% w8 Q d4 O: N% S! K* V1 ]
- }
$ o4 ]$ r; Z% s4 J+ E/ } - *curDecryptPtr = curByte;
+ K' D) s8 D; Y! r - curDecryptPtr++;4 p1 l: X3 x) q1 @' L6 C/ F
- }
; {, b+ l2 A! o, ]. o7 z3 \9 Q- m - , }% U. G- Y7 X
- // Separate strings
' y& H, ~; _. k% W" P/ F( g% X - for (int i = 0; i < 2048; i++) {6 k2 Y% v' p4 x- K
- if ( decryptBuf[i] == 10 || decryptBuf[i] == 13)1 n# L6 _* h* K2 F
- decryptBuf[i] = 0;
& P* t9 b. N. h* L" Z - }
7 c0 C2 j* a# k% K
/ q% b6 _5 p: G8 N$ l4 X- //add by shane007) s; j% Y) v9 G
- //debug((const char *)decryptBuf);
- o A& `, g' a7 J. W- T9 h - ' x; c; n0 X s
- // Check size of each strings in order to compute box width
5 @& ` S/ r! h, p4 O - int curBufIndx = 0;
# ^9 c: g# j- a - int lineCount = 0;$ W7 g/ p! d+ S9 m/ n9 i5 J2 d a4 ]
- int lineSize = 0;
6 |4 V( N t" i: i% X) B% [ - char curChar;
. n3 x+ f2 t; w1 p8 f% P8 u - do {
5 `+ Q3 S! i/ c7 g8 U% D - int curLineSize = 0;3 b5 n. j' \) }; ?
- for (;;) {% U4 k( B) X ]- @& a! o, q2 M
- lineSize = curLineSize;
$ j( G" [# Q, j5 H1 \! Q9 z - do {
$ g6 w" l4 @/ j- s6 U4 h/ { - curChar = decryptBuf[curBufIndx + curLineSize];
2 s N2 [) i8 C* [" j$ G - ++curLineSize;& [3 O- @8 l7 c6 N. w$ Z
- } while (curChar != ' ' && curChar != '%');
9 C1 v/ }3 }8 _ E) u$ k; L' ?$ P e - 3 o: l0 y; o3 l: ?/ h" Z
- if (curLineSize >= MIN_LETTERS_PER_LINE - 1) {
9 a6 @7 K# E9 L8 R$ \' F- c - if (curChar == '%')& U! B1 I$ e( [3 B) N @8 t" F6 q
- curChar = ' ';
: J$ V4 g- r4 @* k9 l( S+ }# ~; Z7 s# z - break;
# S4 C" f* M( T' |4 g3 A) [4 f- L - }! B, Y2 {9 k; m) v4 o
- & @: o9 I5 z6 S+ ^, t# \( b4 J m" ^3 P
- if (curChar == '%') {3 Y f* c1 p! W, V+ M6 `
- lineSize = curLineSize;$ a I8 I- R6 Y1 O1 d9 {" H; B
- break;0 f7 Y. v9 R( y& u$ M" k7 p
- }" m1 D- l+ O' J0 ? `& @
- }# d1 d& t$ Z3 Q, c/ T( S& _7 N
- ++lineCount;
8 @( ^& S; @. C) X! x; X/ C - curBufIndx += lineSize;
$ M# z! r x. Q1 R6 S1 o/ ] - } while (curChar != '%');
2 w! m$ [: F1 o3 L; c* ^ - _vm->_globals->freeMemory(decryptBuf);$ e! t! ?2 i5 A1 I8 [. [/ e' g8 W: B
- return lineCount;' h8 {4 n a0 E5 f5 A
- }
复制代码 2 I) n- f6 r. f) p
7 C( {' T5 E- X$ Z9 W |