本帖最后由 shane007 于 2023-8-26 14:47 编辑 # o7 y+ ]+ I9 Z1 t7 n3 A/ V& y6 S
; Y) s4 S* O- Z, U1 a9 c) g这个有的在上一波(第4波)中进行了比较深入的分析。
/ O0 N \9 p, C, g, O4 ]0 |本次在以前分析的基础上,排除无关内容,只抓和汉化有关的要点。
. ]' X& f, F/ d# T; t
- }! ?0 F6 a: X |6 I) U& b《1》这个游戏的初始化Directx9共有2处,一处是xcDxShader.dll,还有一处是xcDxOldschool.dll
" H; I0 t# ]( [ h 具体要抓取哪个CreateDevice用于往屏幕上写字,需要写代码测试一下。 w2 K- h/ R) p" s4 h; b
; U `" |! }/ l: \ y" E+ r2 \ c《2》这个函数,以ida pro的静态分析为主,暂时认为字幕显示函数是xcEngine.dll中的SetTextString方法。8 b5 g, Q5 ?# R. }& X
) {1 o& S; U8 F2 E8 y8 a( i$ t! {
关键是这2句,Str是完整的字幕,char_unicode是其中一个字符。% e, K2 i! m& c
从代码上看,这个游戏是支持双字节的。但是由于采用的是图片字库,搞清楚结构不容易,因此暂定用hook方法自己写一个显示函数。
" l ^# D* \: F. e这函数传入一个text_object,里边也许会有颜色和坐标。3 p1 t2 b' t1 P9 H* g6 o+ J
- char_unicode = (unsigned __int16 *)(*str + 2 * counter);7 T* q6 f7 ^) }' \9 c0 M
- *char_unicode = xccTextureFont::GetCharacterIndex((xccTextureFont *)text_object[20], *char_unicode);
复制代码
+ a! }- ~$ W' p9 k2 w3 \7 k" B2 |此外,该游戏在字体文件Sl2fnt.dat不存在的时候调用系统字库,
5 @* \( A6 z r3 P4 P/ k5 \8 O因此,也许在调用createfont的时候,能用修改参数的方法让该游戏支持中文。% B+ k7 ^0 B# Z, T. [' ^: N
2 g: @2 e# ~1 Z, Y3 y. {/ y3 i) i" f
以下是修改过变量名的代码。
6 W& Y% R2 D/ }" ` Y, [+ R- int __thiscall xccFrameText::SetTextString(_DWORD *this, int length, _DWORD *a3, int show_subtitle_flag)4 l$ q7 M& s1 k4 c# L
- {! o; W- i4 h; N& t r* W
- _DWORD *text_object; // esi- b' a }+ a. i! c' T" \
- int offset; // ebx* L9 l* t" [8 c* X) z/ [
- int counter; // edi
* F1 r9 |2 a' @ - _DWORD *str; // eax) p; W* |5 _1 M% a9 }8 j
- unsigned __int16 *char_unicode; // ebp7 t, X j7 x# g* C
- int v9; // edx. F& ]; G% k" w# n/ D- a3 P
; g; t1 I4 Y; ?! x- text_object = this;9 o6 t& ]% O0 Y- i
- offset = 32 * length;3 L" V- q$ R, Y& J. [% i, w. U7 v
- counter = 0;
5 @+ t! c6 P/ D: ]5 A3 p z9 S% y - *(_DWORD *)(32 * length + this[21] + 8) = 0;* o9 x& s: }, Y+ m/ R- n( L
- xctArray<unsigned short>::add(*a3, a3[2]);) |) z: N% ]4 ]5 f
- if ( !show_subtitle_flag )
" N7 I% a8 o/ p. V, |# f* S - { q M6 W; H+ z6 u7 K3 {5 h
- str = (_DWORD *)(offset + text_object[21]);
$ O' F- ] A! y% Z1 y - if ( str[2] > 0 )& H& \5 y9 y6 d- K0 s7 m; B
- {
7 M+ z u6 a) G v$ F - do1 V% [: F0 \0 K3 g1 ]
- {
! q2 T c# P+ V3 R; q - char_unicode = (unsigned __int16 *)(*str + 2 * counter);/ p! @7 C# W$ v* K' g
- *char_unicode = xccTextureFont::GetCharacterIndex((xccTextureFont *)text_object[20], *char_unicode);. r- z) [5 w* H6 t0 }
- ++counter;
7 d6 {! ~ l% z$ y - str = (_DWORD *)(offset + text_object[21]);& @. t' K0 `: n. s3 a
- }
9 b0 R$ T- L+ c - while ( counter < str[2] );
; E: F, T2 `% i, V% |/ O - }) V2 {5 U8 t( R3 V* B
- }# r9 A3 M( e) \8 T! D! n B) Q
- v9 = text_object[21];
1 l; z1 w* D' t3 |4 q7 ^ - *(_DWORD *)(offset + v9 + 28) |= 4u;1 @" w c# J& a7 Y9 k
- return offset + v9 + 28;' q2 n% [+ M0 o, r0 {
- }
复制代码 / h$ z/ O, N0 ^# f2 H" O c o
xcEngine.dll 中的CreateFontA代码,可以尝试修改字符集和字符名称,看看是否能显示出中文。
: a7 D: _% U. f3 q3 e m- p- h = CreateFontA(1 }& R: Y$ w4 a, ]: v. P" Y
- -*((_DWORD *)a1 + 1), // 字体高度(负值用于可变尺寸字体)
n; a" Z2 w5 } N - 0, // 字体宽度(0 表示由系统选择合适的宽度)! a3 Z; ~5 k0 \6 z
- 0, // 文本输出方向角度
{* p+ |" o/ [8 Q: m" I& O - 0, // 字体基线方向角度) L; ?9 i- ~* c. q+ D7 I8 Q) ^
- *((_DWORD *)a1 + 3), // 字体重量(例如:FW_NORMAL、FW_BOLD)
1 l" |( ~0 Y `2 ^- H - *((_DWORD *)a1 + 4), // 是否斜体
! }, R! k, z7 G - *((_DWORD *)a1 + 5), // 是否下划线
1 Y0 W( I( k" ^% |6 Y. N* r - *((_DWORD *)a1 + 6), // 是否删除线. a$ \% W0 W. I: V% r
- *((_DWORD *)a1 + 7), // 字符集(例如:ANSI_CHARSET、DEFAULT_CHARSET)1 O- @. k: K( d/ f6 Q0 x
- 6u, // 输出精度(OUT_DEFAULT_PRECIS)
6 c1 J4 s* E1 X - 0, // 剪裁精度(默认剪裁精度:CLIP_DEFAULT_PRECIS). U7 j/ A" [% @
- 4u, // 字体质量(DEFAULT_QUALITY)
! M% M* }$ g9 g& ]: i5 }4 U - 2u, // 字体族和固定/可变宽标志(字符剪裁精度:CLIP_CHARACTER_PRECIS)
" \2 r: f" a z3 K - *(LPCSTR *)a1); // 字体名称
复制代码 9 w. n7 F; s$ B* e I* U& S
用API monitor 跟踪了一下GetDrawnCharCount ,发现和画面都能对应上,比如一下2行的24和8,就是对应画面上2行字幕的字符数。+ f# z2 _$ @7 b6 p' n2 k& W; X
& g" A7 w5 S- E2 R- ~" Q/ R5 q+ S; w4 b- # Time of Day Thread Module API Return Value Error Duration
& e* n+ |' |0 c' ~/ }4 l - 6353 2:44:57.277 PM 1 SL2.exe xccFrameText::GetDrawnCharCount ( ... ) 24 0.0000002+ i% Y# U( N6 s4 Z8 H
- 6354 2:44:57.277 PM 1 SL2.exe xccFrameText::GetDrawnCharCount ( ... ) 8 0.0000001
0 K6 h) i, a7 D# [: |5 m$ q
复制代码 & _$ W) B7 s, G+ b
: Z# q/ Z4 b7 C e. W/ |
" E b) r9 y; o$ S, r/ w9 W, V1 W# q! J K: R+ C
8 P( B# @9 d9 f, o* d
! Q" L* O4 e1 U; s0 |* j* q7 x
/ m) O" q' T( c
|