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

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

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

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

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

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

本帖最后由 shane007 于 2023-8-26 14:47 编辑
3 m" t& Z- Z  d" r8 D& p9 Z8 t/ G  m. N4 }  s2 E  J5 V" _  x
这个有的在上一波(第4波)中进行了比较深入的分析。
  w& B: ~) j9 S. j! G本次在以前分析的基础上,排除无关内容,只抓和汉化有关的要点。! I  Q/ `% D6 b& x$ j
$ w; z% r7 a; g. X7 u( k
《1》这个游戏的初始化Directx9共有2处,一处是xcDxShader.dll,还有一处是xcDxOldschool.dll9 _* M: C' C# s! w5 I: X
     具体要抓取哪个CreateDevice用于往屏幕上写字,需要写代码测试一下。& @9 d2 x% v% Y4 O

5 u; k* U/ t& M8 u9 g  T- H1 ]《2》这个函数,以ida pro的静态分析为主,暂时认为字幕显示函数是xcEngine.dll中的SetTextString方法。6 \4 w4 V8 }& y' R$ v* `8 z) N
& v8 X+ r' w3 {) o
关键是这2句,Str是完整的字幕,char_unicode是其中一个字符。9 i+ h! A& s/ D; u0 j- [/ f5 u% Q# t7 H
从代码上看,这个游戏是支持双字节的。但是由于采用的是图片字库,搞清楚结构不容易,因此暂定用hook方法自己写一个显示函数。, C# |5 e* k" E: s8 i' R
这函数传入一个text_object,里边也许会有颜色和坐标。: n0 {* R8 c+ `: f6 j; K
  1. char_unicode = (unsigned __int16 *)(*str + 2 * counter);
    5 H1 C9 V# u# T
  2. *char_unicode = xccTextureFont::GetCharacterIndex((xccTextureFont *)text_object[20], *char_unicode);
复制代码

# E: d7 a2 z! G' p0 R+ k此外,该游戏在字体文件Sl2fnt.dat不存在的时候调用系统字库,
0 q( z' j, ?; n" }1 E因此,也许在调用createfont的时候,能用修改参数的方法让该游戏支持中文。
' }7 C' R/ V" l3 _3 ~; N$ l5 a8 O7 J0 w
' X+ L+ d+ L; m# m& s4 P
以下是修改过变量名的代码。
9 ^" g" X3 g3 ^, W9 }
  1. int __thiscall xccFrameText::SetTextString(_DWORD *this, int length, _DWORD *a3, int show_subtitle_flag)
      k% O' S" b6 |4 T
  2. {
    # |2 o$ b* r7 v* L, v7 ?& B/ |! {/ s
  3.   _DWORD *text_object; // esi
    " X, _# t# P9 j1 @9 i7 h
  4.   int offset; // ebx! R8 V( i4 C9 R- G
  5.   int counter; // edi4 y' p( L  @0 L) k0 e
  6.   _DWORD *str; // eax
    $ T  w4 b/ }+ w1 x" c
  7.   unsigned __int16 *char_unicode; // ebp
    1 b6 ^+ \# S3 v( `* [  l) n$ _
  8.   int v9; // edx4 q9 b, c' y9 E7 {

  9. 3 i: y& C3 |: ]$ A1 \
  10.   text_object = this;3 Z) d) R" \6 M3 I  {  s3 B
  11.   offset = 32 * length;9 Z7 ?2 u. L6 i7 R" R. J
  12.   counter = 0;6 X2 h! m6 `  x& D, B+ g
  13.   *(_DWORD *)(32 * length + this[21] + 8) = 0;
      F3 L& l5 R1 S2 N$ _: ^2 T" x
  14.   xctArray<unsigned short>::add(*a3, a3[2]);
    * g2 Y7 d, p7 l' f6 G3 o* N
  15.   if ( !show_subtitle_flag )
    4 m% w* s' _! j
  16.   {" w9 J% q1 i- C- s8 r
  17.     str = (_DWORD *)(offset + text_object[21]);
    ! b' a8 ~3 q* Q4 J
  18.     if ( str[2] > 0 )
    * ?% Q, Y8 X1 P4 z  F2 c
  19.     {
    : S) }. F1 L1 k$ |
  20.       do
    ' _  ^2 q9 s7 l
  21.       {
    / j) U4 r3 e& c' `1 D
  22.         char_unicode = (unsigned __int16 *)(*str + 2 * counter);' y6 w5 B& ^+ {+ l4 d& |1 m
  23.         *char_unicode = xccTextureFont::GetCharacterIndex((xccTextureFont *)text_object[20], *char_unicode);3 ]" F3 [# {) L% t1 C. n+ t% ]- r
  24.         ++counter;- b9 z% Q, p" s  ?
  25.         str = (_DWORD *)(offset + text_object[21]);! K& Z1 c6 h- n% S  N/ a0 N+ A
  26.       }' H. D8 {* b6 f1 V7 m' i
  27.       while ( counter < str[2] );3 w3 X+ z+ _8 ^' m6 c; Y
  28.     }5 o& t+ x, V) {; b5 x8 U7 a
  29.   }% d; ?, F3 d( \5 e8 _4 f% ?
  30.   v9 = text_object[21];  j. a/ @4 d: k. B$ O4 o; C
  31.   *(_DWORD *)(offset + v9 + 28) |= 4u;
    6 E# r" V0 S5 f4 X  v  \
  32.   return offset + v9 + 28;
    $ ]5 f1 j6 h, _5 L! Z, Y3 Z# B
  33. }
复制代码
8 Z. \+ Z& I" [
xcEngine.dll 中的CreateFontA代码,可以尝试修改字符集和字符名称,看看是否能显示出中文。
( }% A/ \; b1 d4 [7 j- }( f3 Y
  1. h = CreateFontA(
    6 D: O& f9 D3 ^
  2.         -*((_DWORD *)a1 + 1),      // 字体高度(负值用于可变尺寸字体)) z$ a2 K8 _" Q/ Y5 R
  3.         0,                         // 字体宽度(0 表示由系统选择合适的宽度)
    " i7 h) p6 I: ]/ k1 t. U
  4.         0,                         // 文本输出方向角度
    4 K/ N. `; d9 Q. N- A
  5.         0,                         // 字体基线方向角度* d( J, B& D7 v& d% M
  6.         *((_DWORD *)a1 + 3),       // 字体重量(例如:FW_NORMAL、FW_BOLD)  F! z! e9 @  _" d* i) Q# w5 \
  7.         *((_DWORD *)a1 + 4),       // 是否斜体3 H( Z( t) T7 Y5 I! z
  8.         *((_DWORD *)a1 + 5),       // 是否下划线
    2 V: M2 e# F% e- i  s/ Y# |4 Y
  9.         *((_DWORD *)a1 + 6),       // 是否删除线- B' y5 Y" O( Y! {$ d$ v: {, |
  10.         *((_DWORD *)a1 + 7),       // 字符集(例如:ANSI_CHARSET、DEFAULT_CHARSET)
    # ?* a) D' m/ w' I- _/ r
  11.         6u,                        // 输出精度(OUT_DEFAULT_PRECIS)8 L) B. s3 p0 V- j5 i2 q
  12.         0,                         // 剪裁精度(默认剪裁精度:CLIP_DEFAULT_PRECIS)1 V& i: @, ], M& L" x1 |) i" {8 ?
  13.         4u,                        // 字体质量(DEFAULT_QUALITY)5 d: Y2 P/ J4 f% I- c
  14.         2u,                        // 字体族和固定/可变宽标志(字符剪裁精度:CLIP_CHARACTER_PRECIS)
    1 f% g! q8 R( @- i0 @( b
  15.         *(LPCSTR *)a1);            // 字体名称
复制代码
3 c+ \3 o# Y+ c  w: ]( ~
用API monitor 跟踪了一下GetDrawnCharCount ,发现和画面都能对应上,比如一下2行的24和8,就是对应画面上2行字幕的字符数。1 `' d2 ^+ R; Z9 M# A1 j
( r, R% X! n- R
  1. #        Time of Day        Thread        Module        API        Return Value        Error        Duration7 S: X/ c( D; j: i5 t
  2. 6353        2:44:57.277 PM        1        SL2.exe        xccFrameText::GetDrawnCharCount ( ... )        24                0.0000002
    ) u9 e) n6 N: i* Q) T
  3. 6354        2:44:57.277 PM        1        SL2.exe        xccFrameText::GetDrawnCharCount ( ... )        8                0.0000001
    2 m3 d& X4 y& Q8 T6 H' f  r! x7 I
复制代码

8 _$ s, R" |3 d6 ?
0 S0 R+ \8 v9 M
  B% Q1 Q  i0 D" A, x1 X
; H& x) L5 L+ N' Z+ t, l' x( p' \( V, d% I
  _1 |0 f- g7 Q+ F' t
8 j% |3 p5 U' M7 T! J% t+ W
分享到:  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日,是全球华人共同的冒险解谜类游戏家园。我们致力于提供各类冒险游戏资讯供大家学习交流。本站所有资源均不用于商业用途。

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