冒险解谜游戏中文网 ChinaAVG

标题: 【Directx9游戏汉化 #6】 静物2 (Still Life 2) 字幕显示函数 [打印本页]

作者: shane007    时间: 2023-8-26 12:30
标题: 【Directx9游戏汉化 #6】 静物2 (Still Life 2) 字幕显示函数
本帖最后由 shane007 于 2023-8-26 14:47 编辑 9 \2 }/ Y! B4 ]# z5 U

. ]1 k7 k0 w0 a6 g& F这个有的在上一波(第4波)中进行了比较深入的分析。
9 G! l& N7 C* Y, t& ?本次在以前分析的基础上,排除无关内容,只抓和汉化有关的要点。; I$ ]* _# y( l3 {* r" x

: x2 u- t' X( O$ ~+ e《1》这个游戏的初始化Directx9共有2处,一处是xcDxShader.dll,还有一处是xcDxOldschool.dll
, U* _- l$ ^: G. B; c9 ?' L     具体要抓取哪个CreateDevice用于往屏幕上写字,需要写代码测试一下。
* u$ B- T+ a: I3 Z; M: `% A: Y$ h. R0 o$ R, [% `# l/ D  V
《2》这个函数,以ida pro的静态分析为主,暂时认为字幕显示函数是xcEngine.dll中的SetTextString方法。! F' l1 M  O  l, h- R

! R: t3 }9 g1 B9 ]9 R; y! ]关键是这2句,Str是完整的字幕,char_unicode是其中一个字符。
2 p; `; A  ^1 n0 n+ J- m从代码上看,这个游戏是支持双字节的。但是由于采用的是图片字库,搞清楚结构不容易,因此暂定用hook方法自己写一个显示函数。
# u# a: e4 t/ B" m( K6 [# n这函数传入一个text_object,里边也许会有颜色和坐标。8 @: \: U: f/ m  {6 g% g# M5 }% k
  1. char_unicode = (unsigned __int16 *)(*str + 2 * counter);% u! J' j. u( v3 h2 M. y
  2. *char_unicode = xccTextureFont::GetCharacterIndex((xccTextureFont *)text_object[20], *char_unicode);
复制代码

* |) Y3 m3 b& K: Y+ x" Z5 \+ g此外,该游戏在字体文件Sl2fnt.dat不存在的时候调用系统字库,( |6 w. s8 b4 ~1 V
因此,也许在调用createfont的时候,能用修改参数的方法让该游戏支持中文。5 z8 n) ~. W' R- M( t8 L9 ~

, U+ L! D5 D( c' K( J. [) f% e6 ?4 V/ p, z& P" k7 ^* N
以下是修改过变量名的代码。. u/ N/ H1 O3 R& Z
  1. int __thiscall xccFrameText::SetTextString(_DWORD *this, int length, _DWORD *a3, int show_subtitle_flag)
    , _% G' s( x  ?9 h/ t6 v9 @: B
  2. {  Z7 Y5 B' H8 ~$ f; Q
  3.   _DWORD *text_object; // esi/ \$ `" S2 m7 K! C7 w" l; w8 T
  4.   int offset; // ebx
    5 ?& n% m4 R6 `3 s( e* H. ]1 I6 x. [0 i
  5.   int counter; // edi
    4 O, x2 U' x+ x
  6.   _DWORD *str; // eax- p8 Q3 g" v+ z5 M6 A, s
  7.   unsigned __int16 *char_unicode; // ebp
    ; F, b; ~8 {9 f$ E( o8 O
  8.   int v9; // edx
    9 h' v# i+ P7 A0 P2 E
  9. % m1 _6 r' W9 n9 H& l: ?
  10.   text_object = this;; x' E. N! i# N/ ?, s
  11.   offset = 32 * length;
    , f+ [" s  B6 v  _. U: N
  12.   counter = 0;$ ^3 A+ m3 {/ w3 x9 Q' V
  13.   *(_DWORD *)(32 * length + this[21] + 8) = 0;) T, J" P' t) D  ~7 f6 o
  14.   xctArray<unsigned short>::add(*a3, a3[2]);
      a9 N% F7 J0 g
  15.   if ( !show_subtitle_flag ); S' i- r5 T- ~7 L  J+ M8 L, Y( K0 z
  16.   {' E3 O& q* {6 A7 W
  17.     str = (_DWORD *)(offset + text_object[21]);
    2 J) X/ p# F, s5 X2 `; R
  18.     if ( str[2] > 0 )
    2 r; q5 L# O: V' {" T5 c+ t0 ?4 m8 v
  19.     {
    ! d# \( m# i! T0 z
  20.       do
    # j: ]5 J9 c/ ?) B$ \0 N8 L
  21.       {0 W, `/ T& }  \# \; n$ f
  22.         char_unicode = (unsigned __int16 *)(*str + 2 * counter);
    ( A% q, Q  m: S% p. X0 b
  23.         *char_unicode = xccTextureFont::GetCharacterIndex((xccTextureFont *)text_object[20], *char_unicode);; c0 j8 h) c" G, g2 X6 B
  24.         ++counter;1 K% E/ p- c* D0 y
  25.         str = (_DWORD *)(offset + text_object[21]);  ?  [2 y: k, d# O$ S
  26.       }" @0 b3 {0 ~5 ?0 s6 w6 P3 W+ l( n
  27.       while ( counter < str[2] );; |& l5 Z  E4 \) W. L/ Y0 k& ]
  28.     }
    6 E" f" Q& s1 [5 D  p$ y, j, l6 @$ P
  29.   }1 S: D2 t: `: r5 v3 `) _
  30.   v9 = text_object[21];
    ) F# u# _. U" [; v: l
  31.   *(_DWORD *)(offset + v9 + 28) |= 4u;
    ' \# y# K/ l8 C$ n7 Z
  32.   return offset + v9 + 28;& A0 H/ N" F6 N9 j8 d0 D5 m
  33. }
复制代码
% t8 J; k$ j. N$ c9 I) u
xcEngine.dll 中的CreateFontA代码,可以尝试修改字符集和字符名称,看看是否能显示出中文。
4 `, q1 U" s# z* ]  D
  1. h = CreateFontA(
    3 t2 [* G5 O9 B
  2.         -*((_DWORD *)a1 + 1),      // 字体高度(负值用于可变尺寸字体)
    ( p. }3 G) S( f+ }2 W' }& P# s& X# a
  3.         0,                         // 字体宽度(0 表示由系统选择合适的宽度)/ r) W0 J- l) }0 \. z$ g8 f+ T9 F
  4.         0,                         // 文本输出方向角度" z' _! U8 ?' O. W; A* h7 z+ f
  5.         0,                         // 字体基线方向角度
    ' {+ D; S( ?8 X3 s+ @
  6.         *((_DWORD *)a1 + 3),       // 字体重量(例如:FW_NORMAL、FW_BOLD)
    / K/ ~, a- T2 M8 `6 d
  7.         *((_DWORD *)a1 + 4),       // 是否斜体6 Q9 n. i( p/ N7 X: w/ J; j) z
  8.         *((_DWORD *)a1 + 5),       // 是否下划线
    ' y, N# y- Y$ G2 h" o* `5 Z/ v
  9.         *((_DWORD *)a1 + 6),       // 是否删除线
    4 w8 k0 K7 S( q4 u, w
  10.         *((_DWORD *)a1 + 7),       // 字符集(例如:ANSI_CHARSET、DEFAULT_CHARSET)
    # r$ T6 i; S7 F# S' z/ F
  11.         6u,                        // 输出精度(OUT_DEFAULT_PRECIS)8 P8 T1 S: o4 S5 }
  12.         0,                         // 剪裁精度(默认剪裁精度:CLIP_DEFAULT_PRECIS)
    , j$ B8 y9 D: {
  13.         4u,                        // 字体质量(DEFAULT_QUALITY)# m! j- y" Z6 N- R! Q
  14.         2u,                        // 字体族和固定/可变宽标志(字符剪裁精度:CLIP_CHARACTER_PRECIS)
    & v+ U* u6 k1 S8 \6 f) H
  15.         *(LPCSTR *)a1);            // 字体名称
复制代码
4 k/ d$ M$ [5 c& S6 }
用API monitor 跟踪了一下GetDrawnCharCount ,发现和画面都能对应上,比如一下2行的24和8,就是对应画面上2行字幕的字符数。
. H3 o5 o$ }2 q* a; V' P0 j' K% W9 F/ ?$ S3 i, e- A
  1. #        Time of Day        Thread        Module        API        Return Value        Error        Duration
    * @  G% v/ _" H/ _. y" x- p7 }
  2. 6353        2:44:57.277 PM        1        SL2.exe        xccFrameText::GetDrawnCharCount ( ... )        24                0.0000002
    ) v5 D. E3 E# V; z
  3. 6354        2:44:57.277 PM        1        SL2.exe        xccFrameText::GetDrawnCharCount ( ... )        8                0.00000015 R( a2 w& F2 P
复制代码
0 W8 f8 `1 ]  K
# \. U/ T5 V) h' H& S

' n8 S' q, I# m$ H8 l# A2 l( |# u8 U: T$ R% z& p
) G2 F3 O8 ?. Y" Y  p8 B! V
2 @* G" w( W4 q) J( P. L

; L" z* A2 ]6 k/ @$ x9 L! s
作者: 匿名    时间: 2023-10-22 04:09
等了十年了这游戏的汉化,还有望吗?




欢迎光临 冒险解谜游戏中文网 ChinaAVG (https://chinaavg.com/) Powered by Discuz! X3.2