设为首页收藏本站官方微博

建议 【Directx9游戏汉化 #6】 静物2 (Still Life 2) 字幕显示函数

[复制链接]
查看: 516|回复: 1
打印 上一主题 下一主题

[建议] 【Directx9游戏汉化 #6】 静物2 (Still Life 2) 字幕显示函数

跳转到指定楼层
楼主
发表于 2023-8-26 12:30 | 只看该作者 回帖奖励 |正序浏览 |阅读模式

【Directx9游戏汉化 #6】 静物2 (Still Life 2) 字幕显示函数

本帖最后由 shane007 于 2023-8-26 14:47 编辑
: U3 J, j, q5 r; R0 U" ?5 _% M: N& v" L! A& K6 @
这个有的在上一波(第4波)中进行了比较深入的分析。
8 `: `: m7 N1 \( |本次在以前分析的基础上,排除无关内容,只抓和汉化有关的要点。
) V5 M( y( w  t/ N) I6 V- z" _( ?4 H6 I. E4 {! s
《1》这个游戏的初始化Directx9共有2处,一处是xcDxShader.dll,还有一处是xcDxOldschool.dll4 ^" e! @0 r7 l$ X; k: T8 [
     具体要抓取哪个CreateDevice用于往屏幕上写字,需要写代码测试一下。
5 ~3 a& \- F/ z% b& ~) A. {9 E) X7 X6 i0 c/ \- u6 N  n& R
《2》这个函数,以ida pro的静态分析为主,暂时认为字幕显示函数是xcEngine.dll中的SetTextString方法。$ n1 ^( c3 ]$ ~$ d' K' M
5 t7 _$ `$ ^( V. o
关键是这2句,Str是完整的字幕,char_unicode是其中一个字符。
' X8 k/ q8 H$ C$ j" [4 z  B从代码上看,这个游戏是支持双字节的。但是由于采用的是图片字库,搞清楚结构不容易,因此暂定用hook方法自己写一个显示函数。( {3 A  I( m; i' _! Q4 Z" i3 K0 ], A
这函数传入一个text_object,里边也许会有颜色和坐标。
0 d2 y4 [! X4 X+ _; O7 ]& Q8 F- M
  1. char_unicode = (unsigned __int16 *)(*str + 2 * counter);
    ( k1 v9 t2 c) D9 Y
  2. *char_unicode = xccTextureFont::GetCharacterIndex((xccTextureFont *)text_object[20], *char_unicode);
复制代码
' l- ^4 m6 H+ E9 X: d- E& Y
此外,该游戏在字体文件Sl2fnt.dat不存在的时候调用系统字库,! R+ c: I4 d- u+ }3 _0 ]9 f  A' n( @
因此,也许在调用createfont的时候,能用修改参数的方法让该游戏支持中文。2 f6 o8 C* p& u( p6 x
" W% n" H  X3 n8 Z' d7 b: c

- U+ g1 G! p, d! u以下是修改过变量名的代码。: ^1 S& R. L! s0 s( m% L
  1. int __thiscall xccFrameText::SetTextString(_DWORD *this, int length, _DWORD *a3, int show_subtitle_flag)
    * [/ q8 q; G' p4 K
  2. {
    # p* Y- q7 x6 p( i5 j: m0 N
  3.   _DWORD *text_object; // esi5 r6 Z- X" O3 N
  4.   int offset; // ebx. ?) V! P1 h: k6 ~$ n, t
  5.   int counter; // edi3 h: J8 ^0 H7 w+ }
  6.   _DWORD *str; // eax' u  S# T  N! M
  7.   unsigned __int16 *char_unicode; // ebp5 p5 Y2 ^3 M  m/ {3 `! _5 J
  8.   int v9; // edx
    4 Y- Z3 x1 Z  f# i

  9. 2 c+ H1 P0 i' h, U8 [+ [; A
  10.   text_object = this;. f9 `! j9 Y0 m1 n5 B
  11.   offset = 32 * length;
    3 z2 J2 j3 J5 m/ N
  12.   counter = 0;' S8 x7 @5 u; `2 F7 i
  13.   *(_DWORD *)(32 * length + this[21] + 8) = 0;* H2 O0 d5 W6 Q6 K
  14.   xctArray<unsigned short>::add(*a3, a3[2]);, Q' L& H; l; E& Y5 E+ J
  15.   if ( !show_subtitle_flag )
      H3 I+ L4 v: @% h4 G% [
  16.   {
    * R* G  I  H2 ]3 J3 C
  17.     str = (_DWORD *)(offset + text_object[21]);! _, @( }, O% S% J+ j9 r/ d
  18.     if ( str[2] > 0 )8 u, ~) f! E, j
  19.     {* m" v0 W, ~+ M% A# i* |
  20.       do8 A- W. ?) D+ R( B5 G
  21.       {
    5 o5 J! y% }& B7 y; O
  22.         char_unicode = (unsigned __int16 *)(*str + 2 * counter);4 X- ]2 @: F: E0 @' _( k4 e  j& m
  23.         *char_unicode = xccTextureFont::GetCharacterIndex((xccTextureFont *)text_object[20], *char_unicode);
    % g3 }4 t0 H( Z4 f  w) @' l0 ]- P
  24.         ++counter;  o* H9 e* ]9 O# M, C0 m! P" Z
  25.         str = (_DWORD *)(offset + text_object[21]);
    : U0 Y& w4 Q) ^& F; k5 O- Z
  26.       }
    2 k1 T2 L0 e: Y: m; s3 b' v
  27.       while ( counter < str[2] );5 y, \; N3 t4 B) ^" E
  28.     }% w0 H% ?' h) g& J4 y% F& N& P. r7 s
  29.   }1 D8 P% g1 n% u8 X
  30.   v9 = text_object[21];9 C7 ?1 R* j4 @, d/ X+ z
  31.   *(_DWORD *)(offset + v9 + 28) |= 4u;
    " v( h) o$ w1 K+ G! S0 Q
  32.   return offset + v9 + 28;
    - s; }+ L( U9 r: f' Z
  33. }
复制代码

# N+ h5 B/ U) j+ X' {xcEngine.dll 中的CreateFontA代码,可以尝试修改字符集和字符名称,看看是否能显示出中文。6 k. h; `: B5 N: }" f4 e% [
  1. h = CreateFontA(
    - l( V! V( X, L
  2.         -*((_DWORD *)a1 + 1),      // 字体高度(负值用于可变尺寸字体)
    ; F' |# u- o- l) r. X5 q. n
  3.         0,                         // 字体宽度(0 表示由系统选择合适的宽度)6 P% r* Y* t# g' y) U: ]2 e
  4.         0,                         // 文本输出方向角度$ f& z/ Z$ E2 z9 u8 O7 ]0 h+ s
  5.         0,                         // 字体基线方向角度  _( O8 r" g. @! |0 p# L$ v. i
  6.         *((_DWORD *)a1 + 3),       // 字体重量(例如:FW_NORMAL、FW_BOLD)
    1 D/ L' E( @! l, j  H% ?
  7.         *((_DWORD *)a1 + 4),       // 是否斜体4 I- K" Z5 O4 y+ r
  8.         *((_DWORD *)a1 + 5),       // 是否下划线$ j! D1 N# B7 f3 J% V6 O& a
  9.         *((_DWORD *)a1 + 6),       // 是否删除线9 Y# t- |# g; A4 A7 Q
  10.         *((_DWORD *)a1 + 7),       // 字符集(例如:ANSI_CHARSET、DEFAULT_CHARSET)
    9 B; P+ b4 n. O9 X5 m, }3 R
  11.         6u,                        // 输出精度(OUT_DEFAULT_PRECIS)
    . i# T9 t2 p7 H8 x
  12.         0,                         // 剪裁精度(默认剪裁精度:CLIP_DEFAULT_PRECIS)
    & p; {. E0 u; P* s# k
  13.         4u,                        // 字体质量(DEFAULT_QUALITY)# `4 F: ^$ s7 r& P+ s6 R+ h
  14.         2u,                        // 字体族和固定/可变宽标志(字符剪裁精度:CLIP_CHARACTER_PRECIS), B) p* G5 [/ _( @- S, Q# Q+ {0 c
  15.         *(LPCSTR *)a1);            // 字体名称
复制代码
6 O: k  i9 b0 D) I. t' V/ n5 N5 x1 @
用API monitor 跟踪了一下GetDrawnCharCount ,发现和画面都能对应上,比如一下2行的24和8,就是对应画面上2行字幕的字符数。
- U8 K/ e$ Q! A9 z  v) a$ A! G
% l, c4 F& M  {9 ?8 ^: I
  1. #        Time of Day        Thread        Module        API        Return Value        Error        Duration. C0 ?( M  x/ {5 i. {
  2. 6353        2:44:57.277 PM        1        SL2.exe        xccFrameText::GetDrawnCharCount ( ... )        24                0.0000002% E5 x' J/ \: B
  3. 6354        2:44:57.277 PM        1        SL2.exe        xccFrameText::GetDrawnCharCount ( ... )        8                0.0000001+ g6 }+ _9 ?6 y( h5 n$ a! X  q
复制代码

# i; e6 c% S) B" @1 m
; f. m; C# e1 S5 C# z
0 J4 o8 F9 A5 R- i) S5 z* j: ]( d. [# |( J, q! S8 }
9 h/ l/ T4 D7 c1 r8 t

9 R5 }* F' q& @  G; x1 m. S/ Y) ^; q
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享分享 很美好很美好 很差劲很差劲
回复

使用道具 举报

沙发
未注册网友  发表于 2023-10-22 04:09
等了十年了这游戏的汉化,还有望吗?
回复 支持 反对

使用道具

高级模式
B Color Image Link Quote Code Smilies

本版积分规则

冒险解谜游戏中文网 ChinaAVG

官方微博官方微信号小黑屋 微信玩家群  

(C) ChinaAVG 2004 - 2019 All Right Reserved. Powered by Discuz! X3.2
辽ICP备11008827号 | 桂公网安备 45010702000051号

冒险,与你同在。 冒险解谜游戏中文网ChinaAVG诞生于2004年9月9日,是全球华人共同的冒险解谜类游戏家园。我们致力于提供各类冒险游戏资讯供大家学习交流。本站所有资源均不用于商业用途。

快速回复 返回顶部 返回列表