本帖最后由 shane007 于 2023-8-12 09:10 编辑
- u8 d0 y, C* B
- W0 x! r$ r( d' ~ b; L* H! f 这游戏的字幕放在LINK目录下,分为*.IND和*.TXT 这2类文件。
3 z6 G# d5 f8 O" \' ]; b: U9 s' c 其中*.IND是索引文件,每4字节是一个索引,定义了每条字幕在*.TXT中的偏移位置。
1 f. K' b% G, c# f/ a6 N" N# I5 x M
7 {# ]9 N$ \2 Q# ]1 l 比如,对话字幕保存在以下一对文件中,其中an代表的英文,此游戏共支持3种语言。
+ ~ l |0 e/ L% z" [ RUEAN.IND
. c. k$ s9 V% j' s& i" { ruean.Txt$ l5 x6 o$ E1 f F4 Q
6 o. d* x1 c# a$ e4 A *.TXT使用了加密方法,将字幕逐字节按照某种方式进行加密,具体实现可以参考代码。; I# D- E' Q4 y1 b8 _) a
提取字幕的方法,暂定为在*.TXT的解密代码后边临时加入一段代码,将解密后的明文输出到控制台,然后提取出来进行整理。6 i# K- `$ i5 O, c# [
1 u6 O$ {) f' P! _' l/ g5 W6 I7 J% i3 R
*.TXT的解密代码如下
; E+ ]/ ^* U6 Y- int TalkManager::countBoxLines(int idx, const Common::String &file) {
' M- w* ]9 l/ \% _ m - _vm->_fontMan->_fontFixedWidth = 11;$ P2 q; |7 y# A2 s. o3 a
- % |- n, p. l& l1 w
- // Build up the filename
1 H2 A6 T+ D$ g0 d$ k7 N - Common::String filename;
( d# J2 M4 w X0 t - Common::String dest;
- } k8 j3 y6 { w, H4 \ - filename = dest = file;" Y" ?" g& Q# A4 H2 u c6 A
- while (filename.lastChar() != '.')( U/ r. i( P9 T
- filename.deleteLastChar();6 W4 e+ P' c: K3 x$ x
- filename += "IND";
. B4 q% x$ [6 X5 U' c( { - 9 Y1 q0 _# I g( I3 E
- Common::File f;: F/ F" z( J. Y7 D
- if (!f.open(filename))
2 c" i( K+ O4 A/ z$ O; s - error("Could not open file - %s", filename.c_str());! E+ _: z Y k! [
- int filesize = f.size();1 U; h5 r$ I7 `& v! |: h1 ^
- assert(filesize < 16188);
1 p8 u9 X! Z! j5 B" h# ~ - ! ?% [9 x# ~1 n) }0 a8 @
- uint32 indexData[4047];
1 P& A+ q: V8 b- ^- A# m/ ^ - for (int i = 0; i < (filesize / 4); ++i)
* u5 Z, P- u. t1 ] - indexData[i] = f.readUint32LE();( ]* x0 s8 d& c
- f.close();9 G( ~/ F2 e- c4 t
- + ~9 [2 b% T2 ^
- if (!f.open(dest))
5 V6 ^5 t- C* y. ?; B) w* J0 s - error("Error opening file - %s", dest.c_str());
& z3 G( T& ~; I% T
2 {! Y* Y$ [: |4 L* [0 b0 H- f.seek(indexData[idx]);# V) R, `5 E2 [1 [0 i$ U; K
- byte *decryptBuf = _vm->_globals->allocMemory(2058);! ~: e: m7 j; e
- assert(decryptBuf);2 H" t" W3 D2 a0 p& c
) T- i+ N2 U2 T) H J- f.read(decryptBuf, 2048);
. f% N7 h1 r8 L" s& e- ~# `2 c; [ - f.close();
$ c& F; l# @8 \4 j
$ S# |: J1 }: ?1 x& S- // Decrypt buffer: O4 L: ?" G$ ~! O8 k
- byte *curDecryptPtr = decryptBuf;
4 U; m2 i* b, i. t$ S$ w) T5 K - for (int i = 0; i < 2048; i++) {, e7 ~3 q: m+ u; u' `+ \; C( g5 I. [
- char curByte = *curDecryptPtr;
9 ~) ^2 V y; a - if ((byte)(curByte + 46) > 27) {
5 y6 M5 E. V9 J, j( E6 t) c* B - if ((byte)(curByte + 80) > 27) {
0 C4 f+ J/ \4 \( ]( h - if ((curByte >= 'A' && curByte <= 'Z') || (curByte >= 'a' && curByte <= 'z'))
$ A [7 @4 _- c1 S2 f7 |" X* ? - curByte = ' ';
0 m( F, s' k2 H6 p; h. a% f - } else {
% L1 R! t& L+ F4 [6 y - curByte -= 79;$ o8 z6 @2 v" v9 h/ T- T% T7 Y
- }9 |4 R. M; N6 o9 _% W4 g! \: I
- } else {* u# x; ]0 Y; t: x6 o
- curByte += 111;
: j+ T7 W1 s2 e - }
; v/ Q- \) u# n. H7 | - *curDecryptPtr = curByte;
h% [) o2 a" @; {, v - curDecryptPtr++;; ]! I8 o8 ~, k% D* E
- }# r1 L& U/ X! E: f2 s& a
8 w& C4 A2 L$ e, ?. u' Q- // Separate strings
+ [( h2 n' U F& d5 D& S" o/ m# s. t+ n - for (int i = 0; i < 2048; i++) {
7 Z2 F; B/ i! D' V2 T8 g# O - if ( decryptBuf[i] == 10 || decryptBuf[i] == 13)6 n6 Y' m# m6 E" a
- decryptBuf[i] = 0;
' f( ]. A( T0 ^1 T6 Z: i- y - }% N9 M5 m! H" K+ D
! b* X$ R7 w; j+ Q- //add by shane0075 n0 Y z7 w; }2 ?
- //debug((const char *)decryptBuf);! C/ J$ ]" f$ I" Y
- 2 |/ C: }* V$ N6 p
- // Check size of each strings in order to compute box width- L0 U7 Z# u' F
- int curBufIndx = 0;, {& m8 K- p" |
- int lineCount = 0;# ]7 F6 Z" M1 e3 c# q7 p7 p& X
- int lineSize = 0;6 K" [7 C! ^) [7 D# k$ D* O
- char curChar;
1 R1 v* z* y; C3 f& U/ p7 S; T - do {" p4 `, E7 K' \& b6 y( _
- int curLineSize = 0;
5 R. Y$ b1 a4 N/ S4 M! x7 [5 Z8 b - for (;;) {2 d" ]; m% }1 s. V) n; Q
- lineSize = curLineSize;
+ \" \4 b; @/ |/ e5 g2 ` - do { J+ g* E. V( _- f5 A& ?
- curChar = decryptBuf[curBufIndx + curLineSize];
( r: H0 B0 J, c7 e' n& J4 S - ++curLineSize;
$ w( p& M1 Y T7 {- s/ {) A1 e - } while (curChar != ' ' && curChar != '%');$ C8 a+ o# h* U9 r/ t8 P7 k2 E
- ( _. {4 I- X. e+ s7 T
- if (curLineSize >= MIN_LETTERS_PER_LINE - 1) {
$ `1 n- `6 F# `: \( ?" Y2 ? - if (curChar == '%'), S8 S6 v, ^: v- I( E
- curChar = ' ';1 N! h+ k: a% k: F. M- g
- break;& @ @- \ ~$ l, F5 }7 b
- }$ { P9 C% j4 A& Z2 m, Z
- - _! F# J/ d4 }" A% o7 P) r
- if (curChar == '%') {( W- S7 }7 C5 k
- lineSize = curLineSize;
g: u5 H5 Z; ~ ^2 n- A - break;+ q. r+ L" v3 X% y Z7 S
- }
X4 b/ ]6 B% C* p+ ~( z1 d5 Z - } n/ a' q2 A6 [8 n
- ++lineCount;
5 f/ Z$ Z y+ W5 ]: u$ ?# _ - curBufIndx += lineSize;
# ^# _% J, F3 U" v2 b - } while (curChar != '%');
% E* P" G8 Y: Z. [5 L5 y - _vm->_globals->freeMemory(decryptBuf);
6 V5 ]+ ]' c0 H2 P* } - return lineCount;
/ u5 e- H/ ^, [ - }
复制代码 % u3 }1 H2 R, s$ t: G4 ?
' h* a4 K! C% x |