本帖最后由 shane007 于 2023-8-26 14:47 编辑
- F2 x9 y l$ _* A( m& I
. P( r& J9 Z9 o! y8 y- f这个有的在上一波(第4波)中进行了比较深入的分析。3 Q/ d; E6 R% g
本次在以前分析的基础上,排除无关内容,只抓和汉化有关的要点。7 y- M- e- C# m7 Z7 q
; x6 m, D- E2 T
《1》这个游戏的初始化Directx9共有2处,一处是xcDxShader.dll,还有一处是xcDxOldschool.dll7 h1 k/ i( o/ b8 a. A$ h
具体要抓取哪个CreateDevice用于往屏幕上写字,需要写代码测试一下。/ u6 n, K" b% a( A+ Y1 Q+ ~: n; @
" Q6 u8 C% ~5 a; h
《2》这个函数,以ida pro的静态分析为主,暂时认为字幕显示函数是xcEngine.dll中的SetTextString方法。
5 n, O. s% a7 G. J4 ~5 c0 b& N6 x# M3 y% Y
关键是这2句,Str是完整的字幕,char_unicode是其中一个字符。3 y3 _; V) e3 }) @! b1 o
从代码上看,这个游戏是支持双字节的。但是由于采用的是图片字库,搞清楚结构不容易,因此暂定用hook方法自己写一个显示函数。
. n& I4 g$ u* |0 L6 g/ B这函数传入一个text_object,里边也许会有颜色和坐标。
0 b/ O7 P+ I6 Q# [; q- char_unicode = (unsigned __int16 *)(*str + 2 * counter);; _! w D: o d
- *char_unicode = xccTextureFont::GetCharacterIndex((xccTextureFont *)text_object[20], *char_unicode);
复制代码
- M0 R- _, k: J0 T7 \此外,该游戏在字体文件Sl2fnt.dat不存在的时候调用系统字库,
8 ^0 r% J4 e% e, G, r因此,也许在调用createfont的时候,能用修改参数的方法让该游戏支持中文。
6 D! a s3 G0 h5 _
! j' J! g/ Q, X/ O+ c; h5 L* v
以下是修改过变量名的代码。! D, A" u- e) C+ E' i
- int __thiscall xccFrameText::SetTextString(_DWORD *this, int length, _DWORD *a3, int show_subtitle_flag)
i3 ?: n' J/ x3 R. Q/ `- a9 F - {. E* N, z! l* Z8 D5 ]4 L
- _DWORD *text_object; // esi
( Y8 p! x5 U$ k' [ - int offset; // ebx9 o# U3 g, j! H" t! f( Z* y/ u
- int counter; // edi. o! y7 Z% o# r* a9 X3 D
- _DWORD *str; // eax5 R: l; C9 V W: h& D" l
- unsigned __int16 *char_unicode; // ebp
5 B9 L/ F6 ]) v - int v9; // edx1 u0 s) _; E) \0 E5 A
" U: M' I# F; d8 Q: y* J& ~- text_object = this;
& ~. @. \+ U6 {* w3 {7 o: u8 ~ - offset = 32 * length;/ H8 \) t" e$ x8 o+ } }, f
- counter = 0;
. _" d# _; z" C% l" z/ O - *(_DWORD *)(32 * length + this[21] + 8) = 0; G9 W3 }% H# K T5 z
- xctArray<unsigned short>::add(*a3, a3[2]);3 E# A9 L0 @$ R. `" v
- if ( !show_subtitle_flag )/ C8 n% c7 m4 f& G; C/ W
- {/ x; M& _* n7 C
- str = (_DWORD *)(offset + text_object[21]);
6 D1 g7 _( I" K1 S1 O5 k - if ( str[2] > 0 )7 ~' N( }8 |4 A! n
- {4 Y. r, u V8 V* w8 l! t$ g
- do
# k1 i1 D3 Y) S* I9 }" e' A - {
J8 x" l: R$ @7 I8 m2 g - char_unicode = (unsigned __int16 *)(*str + 2 * counter);
- f5 Z7 X5 `! V ]* ^ - *char_unicode = xccTextureFont::GetCharacterIndex((xccTextureFont *)text_object[20], *char_unicode);
8 N$ b* m5 s" t3 }. `1 c0 o: T - ++counter;$ O0 `$ g! D* Z# J" k
- str = (_DWORD *)(offset + text_object[21]);' m& f1 `! E* {, J, |' i
- }
3 W+ I/ }4 T5 X) } - while ( counter < str[2] );
3 |$ k0 e0 ~) `) v& @' M - }
2 \- ?) L: w) _, ^! N - }
$ y. @. t5 G$ z - v9 = text_object[21];0 O/ f8 I" X* K& V) J
- *(_DWORD *)(offset + v9 + 28) |= 4u;2 L' S, h# m* o+ j: K Q- s
- return offset + v9 + 28;
; |& q+ p. f+ D. o+ d/ O - }
复制代码 7 f6 ]0 ]' U/ }& y" }
xcEngine.dll 中的CreateFontA代码,可以尝试修改字符集和字符名称,看看是否能显示出中文。2 @2 z+ _6 ~" ^' P) N7 l
- h = CreateFontA(
; P. n* y. H6 h9 j - -*((_DWORD *)a1 + 1), // 字体高度(负值用于可变尺寸字体)
3 G# {1 q7 i( d7 |$ }! u7 o( } - 0, // 字体宽度(0 表示由系统选择合适的宽度)6 V/ e; e% e: ^: b' k/ d
- 0, // 文本输出方向角度
' L* f. r# L/ C7 \% ` - 0, // 字体基线方向角度
; h. A. W2 p, w" L+ i$ `2 { - *((_DWORD *)a1 + 3), // 字体重量(例如:FW_NORMAL、FW_BOLD)+ N' g& o4 W3 _& x$ j% K' e
- *((_DWORD *)a1 + 4), // 是否斜体
4 j- O5 o$ N/ U. W - *((_DWORD *)a1 + 5), // 是否下划线/ {/ l+ ?9 V3 y; a# ^
- *((_DWORD *)a1 + 6), // 是否删除线
8 q! E' B. P% }: k4 s/ j - *((_DWORD *)a1 + 7), // 字符集(例如:ANSI_CHARSET、DEFAULT_CHARSET)% S% l8 ~6 H) R0 e6 b! o) x
- 6u, // 输出精度(OUT_DEFAULT_PRECIS)
) \4 n, Y; A7 R& c) ? ~! S( |4 O - 0, // 剪裁精度(默认剪裁精度:CLIP_DEFAULT_PRECIS)
2 j; W+ `' g3 @6 \. Y8 G6 | - 4u, // 字体质量(DEFAULT_QUALITY)
4 v) x* m* K P4 Y. A0 O& C - 2u, // 字体族和固定/可变宽标志(字符剪裁精度:CLIP_CHARACTER_PRECIS)
% Y/ B: x" y& A- \+ v( e - *(LPCSTR *)a1); // 字体名称
复制代码 / F% m" l f9 x* v4 ?8 y& G9 \6 X
用API monitor 跟踪了一下GetDrawnCharCount ,发现和画面都能对应上,比如一下2行的24和8,就是对应画面上2行字幕的字符数。7 B9 m6 N" B2 T$ e5 P
$ T+ L# S( N p, l7 |/ n
- # Time of Day Thread Module API Return Value Error Duration1 Z' O7 K, O* f% P4 j0 T
- 6353 2:44:57.277 PM 1 SL2.exe xccFrameText::GetDrawnCharCount ( ... ) 24 0.00000021 k: `. I5 t+ ~. N; O
- 6354 2:44:57.277 PM 1 SL2.exe xccFrameText::GetDrawnCharCount ( ... ) 8 0.0000001
( i# R, }2 p- B) E4 _( ^
复制代码 $ _/ d7 G5 ]8 r! N! q0 s
- m+ p: g" g3 A5 ~) m$ F1 w( ~9 H' z3 l" O4 { o; r
5 N; Z- w* H) q4 S! ~6 p
3 N+ d. d: \* E5 A) O5 T. B
& x, z& v0 {6 f
0 J9 P4 m$ E. j1 ?3 e2 M/ ~' B |