本帖最后由 shane007 于 2023-8-12 09:10 编辑 / l) z1 M5 M# Z$ Y; `# b
" u; F3 p5 D1 X6 P 这游戏的字幕放在LINK目录下,分为*.IND和*.TXT 这2类文件。8 n/ g8 m9 s& ~& x" }8 D& E
其中*.IND是索引文件,每4字节是一个索引,定义了每条字幕在*.TXT中的偏移位置。
+ k' ~# o5 k m5 F) q- `% p0 f0 \( I- G
; K# ~- J/ ^+ }3 N) [7 C; u 比如,对话字幕保存在以下一对文件中,其中an代表的英文,此游戏共支持3种语言。
; D( o# O+ X2 D RUEAN.IND, v D" H' O4 W7 Z6 z0 E: K
ruean.Txt3 W# \, z. R2 @8 H: H
) w6 M% D4 R u; s6 k# E. S
*.TXT使用了加密方法,将字幕逐字节按照某种方式进行加密,具体实现可以参考代码。
$ m' `9 q& J" C" W' D7 v2 A 提取字幕的方法,暂定为在*.TXT的解密代码后边临时加入一段代码,将解密后的明文输出到控制台,然后提取出来进行整理。, ?) I1 U- h* D x4 r# o0 ]2 U; J% g
2 \% y& h5 v* n8 q6 `% l# W
2 l4 t1 D2 m' o; S/ O *.TXT的解密代码如下% k4 W1 `9 l' V* J, W
- int TalkManager::countBoxLines(int idx, const Common::String &file) {. m2 V6 G( V; P' u
- _vm->_fontMan->_fontFixedWidth = 11;/ q) Y0 O, [2 _. Q3 Q4 W) ^( M5 ^+ @& L
, K3 N% @7 d4 X$ S1 b" W* @- // Build up the filename4 z) U; K1 f2 B
- Common::String filename;1 f; O5 E) i8 \9 j. ?+ e q4 }
- Common::String dest;
8 o& W) q |4 E/ V0 x - filename = dest = file;
% T4 n, h }& Z* T7 g, _1 ?: G - while (filename.lastChar() != '.')
1 q% S: r v" s& ?& j( } - filename.deleteLastChar();4 k s; h7 _4 z9 Q0 O6 N: T7 i
- filename += "IND";
3 k! Z# ^! p) A9 H3 v1 ]% Z4 D - 3 `( ?! {) a( F# C
- Common::File f;* F$ J( p% h& T* [
- if (!f.open(filename))
- z. R- h \' { - error("Could not open file - %s", filename.c_str());2 x% M! T9 b( R0 k @0 n/ T
- int filesize = f.size();( m' [+ W% L7 Z+ ^1 F3 S
- assert(filesize < 16188);: I# R( v/ e# ]: x% j0 Y [
- 0 G4 \$ e3 [9 n
- uint32 indexData[4047];, ]: p5 W# g4 p( `
- for (int i = 0; i < (filesize / 4); ++i), y$ D7 @# z$ X7 l
- indexData[i] = f.readUint32LE();
$ V4 i# l1 z; i% d1 v - f.close();+ N5 V4 U7 c. l. H1 e: l( o
- * j0 _- @: f4 r/ a: T9 P
- if (!f.open(dest))' E7 b4 O$ G, \. z
- error("Error opening file - %s", dest.c_str());
; x# e4 n, z& |0 o7 m7 i3 k9 t8 b - $ [' | l# [3 ^! l7 l6 @
- f.seek(indexData[idx]);' Y! f9 F: l; |- v. I1 z x6 |
- byte *decryptBuf = _vm->_globals->allocMemory(2058);4 _) ?" E" n$ a. n3 j& @- E
- assert(decryptBuf);
f1 L" v+ I+ |0 L3 Q3 j - 0 o9 f, R- y, z( O* Z5 ]( d# m
- f.read(decryptBuf, 2048);
9 r1 B# H$ _9 \7 m* B' t' t1 m* J: c - f.close();
# ~+ ?- E! W) C' g5 A7 U# V
! Z/ e4 b: B6 ]- // Decrypt buffer
. c) E9 `. B5 k! h4 f - byte *curDecryptPtr = decryptBuf;
# ^& }: q/ y9 f/ ]5 W, M - for (int i = 0; i < 2048; i++) {
8 m/ S: c# [. \+ @3 B1 F - char curByte = *curDecryptPtr;" N8 l$ u5 y' s! C5 d* K
- if ((byte)(curByte + 46) > 27) {4 N S$ U8 b/ n6 ` A
- if ((byte)(curByte + 80) > 27) {
0 G: [8 y. d1 g. f+ s6 n - if ((curByte >= 'A' && curByte <= 'Z') || (curByte >= 'a' && curByte <= 'z'))
! v% p' L: F2 i1 A - curByte = ' ';
9 S: H+ ^% w6 `+ R7 b! P: j - } else {
5 W+ L9 p) e. P. p* A6 b - curByte -= 79;- J7 s3 d* G# @9 r* K2 q& S# @1 S
- }
: K8 p9 H7 d% a3 O, ?. u - } else {5 T! K/ a _. \6 x( q
- curByte += 111;
; d6 g! B3 ^7 M j8 T7 H2 Q' U - }8 ?( m4 ?% n+ t) g7 e7 m) H
- *curDecryptPtr = curByte;8 _2 p; s$ \+ f5 E2 Z
- curDecryptPtr++;
3 w: O2 Y% C Y2 n6 j - }3 u, p! z9 e# L) T. w
- 3 b. ~) R# f. s3 L8 w m( S
- // Separate strings* W6 T: |0 T+ b+ r( l
- for (int i = 0; i < 2048; i++) {. |2 Z) o& z! m8 u n- v
- if ( decryptBuf[i] == 10 || decryptBuf[i] == 13)
3 _3 [, W2 U* i9 f2 L, x) W2 l2 _ - decryptBuf[i] = 0;/ P, m% S4 a( f* T/ k/ ?" x% G4 s
- }& k8 @5 h P; B2 l" K: ]6 s* n6 O
- # r, Q, c: z3 P
- //add by shane007
5 k% R7 v- U! I( U$ N7 c - //debug((const char *)decryptBuf);: `+ R4 a: ^$ R( r: B/ c) C& b) g0 E- `
- % g M/ w+ V- n( Z8 [; O. M w1 z
- // Check size of each strings in order to compute box width
3 U' K4 y4 `9 U' `( r, K - int curBufIndx = 0;5 o; [5 b [5 M! e# i
- int lineCount = 0;% [! y- _* `) [7 o1 J
- int lineSize = 0;, i; D& x$ Z$ H- `8 P7 |
- char curChar;5 N1 u" }7 d* w5 F& x* Z/ e: E
- do {
1 i2 V3 w( w9 Z8 P5 b7 c6 S - int curLineSize = 0;
! [. A, w* P! J( `5 _1 t - for (;;) {
1 U S0 u+ W+ {5 k& S2 \ - lineSize = curLineSize;1 ?5 ^3 _% V. y. w, y1 E& n( W
- do {
) H( x. Z* h0 c5 E# A# W0 d8 U - curChar = decryptBuf[curBufIndx + curLineSize];! Z8 x# O( r6 K1 ?
- ++curLineSize;% v4 D" g+ ?4 R2 n7 y
- } while (curChar != ' ' && curChar != '%');1 E$ J% p* @( u+ E+ X: }
- $ K. `% V" v6 W- P! K ]
- if (curLineSize >= MIN_LETTERS_PER_LINE - 1) {
( n; q4 Q; e6 P5 o. J - if (curChar == '%')+ M6 R2 j( _ G' D+ t7 J; C
- curChar = ' ';6 E0 @8 O* d7 Y, v7 ?5 _) J+ |( A
- break;" ]/ t4 M/ s+ |0 D
- }
$ G% u! V1 s) n' ^$ g; }3 S7 S - 8 ?4 L! }& S8 Q7 L; B
- if (curChar == '%') {6 y6 |& e# {: o6 k1 n1 ^
- lineSize = curLineSize;
+ Z/ M Z$ k6 D& [1 @ - break;( n2 b7 H; R D j& t& i
- }9 h# O2 m- y& [- J" E) S6 `
- }
& D' x' F1 X w* d, }+ A! @: C - ++lineCount;9 F, H' l5 `" M
- curBufIndx += lineSize; |- v5 u6 h; M. t) f- f& ~
- } while (curChar != '%');6 g8 l, p H8 d
- _vm->_globals->freeMemory(decryptBuf);
9 \+ k% ]+ f1 A; C9 E+ @ - return lineCount;, v1 Z3 [8 B3 @" i; L* U
- }
复制代码 ( A4 | y! D- c( r7 G5 a d W# A
6 B3 w) L3 s2 ^2 g, p
|