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

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

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

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

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

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

本帖最后由 shane007 于 2023-8-26 14:47 编辑 5 l3 \0 p  G- W. f4 ~' F
; x/ l/ X( n7 A% d: H8 a; Z$ w
这个有的在上一波(第4波)中进行了比较深入的分析。+ W+ y2 e/ i/ A' X1 ~" q
本次在以前分析的基础上,排除无关内容,只抓和汉化有关的要点。
% _( \" K" l+ k0 b" |# A2 x  I* M* b% s- f, _& P. [2 b# [
《1》这个游戏的初始化Directx9共有2处,一处是xcDxShader.dll,还有一处是xcDxOldschool.dll
5 x# X6 h& d0 a1 @" `/ S0 o) l     具体要抓取哪个CreateDevice用于往屏幕上写字,需要写代码测试一下。
% m4 R$ c, Z1 d! _1 y1 o& w7 L& Q. v7 `0 M
《2》这个函数,以ida pro的静态分析为主,暂时认为字幕显示函数是xcEngine.dll中的SetTextString方法。
: W9 S: s+ M; |# S, Z, {/ A0 {' H
9 h$ q/ y# q' D! ~0 q" A4 c! E+ V5 C7 ^关键是这2句,Str是完整的字幕,char_unicode是其中一个字符。
) v; Y8 j9 @* s4 t$ V从代码上看,这个游戏是支持双字节的。但是由于采用的是图片字库,搞清楚结构不容易,因此暂定用hook方法自己写一个显示函数。. ~, A3 P, m" V
这函数传入一个text_object,里边也许会有颜色和坐标。* o5 i, s' v. Q9 ]/ A# g
  1. char_unicode = (unsigned __int16 *)(*str + 2 * counter);
    - q* y5 L( Z  [: Q4 U) ^: }3 z- T+ y
  2. *char_unicode = xccTextureFont::GetCharacterIndex((xccTextureFont *)text_object[20], *char_unicode);
复制代码

( Z7 \9 @( e) v% D, E) [0 T0 X1 _此外,该游戏在字体文件Sl2fnt.dat不存在的时候调用系统字库,
( P; f* m. o. A$ ]% @* e: _& b因此,也许在调用createfont的时候,能用修改参数的方法让该游戏支持中文。3 b4 ~, }. z# G" |
" q' q& q1 ?5 |) R- [
, D  T2 Y  f  v! Z
以下是修改过变量名的代码。
' g" Y3 K. F# A9 Q, |) G. V
  1. int __thiscall xccFrameText::SetTextString(_DWORD *this, int length, _DWORD *a3, int show_subtitle_flag)" K3 x/ h5 n) l; t: t
  2. {
    : E( B! m. I. ]/ O0 G4 B
  3.   _DWORD *text_object; // esi
    * @6 w' K( ~7 s5 N# A
  4.   int offset; // ebx
    $ g- V) }' z# S
  5.   int counter; // edi! W5 f0 p# L: U) O# q2 D
  6.   _DWORD *str; // eax
    4 i$ }9 u) a5 L& G
  7.   unsigned __int16 *char_unicode; // ebp
    # R6 D$ k2 ~" n8 g
  8.   int v9; // edx
    # I( u7 i! W1 d) k1 j9 x
  9. ( Z7 C) a/ T$ i7 z3 Z
  10.   text_object = this;6 h  ^6 y3 [1 b: d/ \, S8 m
  11.   offset = 32 * length;# z4 B. r+ N# u8 X' h- ]" Y
  12.   counter = 0;
    # Y) `3 G0 R5 s0 J. ~; j" Q, Z
  13.   *(_DWORD *)(32 * length + this[21] + 8) = 0;1 R. Z! T' I. e
  14.   xctArray<unsigned short>::add(*a3, a3[2]);0 B# K' N/ [! o% p% D/ @4 t
  15.   if ( !show_subtitle_flag )! J9 C  |8 I/ Q9 t
  16.   {" @9 W2 e; s# l0 z8 V
  17.     str = (_DWORD *)(offset + text_object[21]);
    1 E7 ?/ o; z1 c3 p
  18.     if ( str[2] > 0 )4 ?9 q9 \' x' V
  19.     {
    * K5 u- L; r+ Q1 r  t' ?; Z
  20.       do
    % z; G7 g. @3 O+ u7 n
  21.       {
    4 W5 R# B/ S% ~" z$ F, V1 d
  22.         char_unicode = (unsigned __int16 *)(*str + 2 * counter);, F1 u; _1 N6 \7 E$ w' w
  23.         *char_unicode = xccTextureFont::GetCharacterIndex((xccTextureFont *)text_object[20], *char_unicode);' e5 T" l+ |3 C- y% L/ E# N
  24.         ++counter;
    , z+ @5 R  S" `' C7 g' L5 z
  25.         str = (_DWORD *)(offset + text_object[21]);: r& |+ C5 ^% C, p& e  U$ D
  26.       }
    , L& M- K5 ^& ?8 F0 i6 X: p/ B
  27.       while ( counter < str[2] );' o! }/ h& O9 n! p
  28.     }  C% A7 y- A  H. ?! a
  29.   }% |5 A& o; J% M6 _. D% N
  30.   v9 = text_object[21];
    % w3 Z* P3 q2 V- `6 {
  31.   *(_DWORD *)(offset + v9 + 28) |= 4u;( s9 O9 E5 h5 p4 M0 ^/ W/ K7 e" q
  32.   return offset + v9 + 28;) x; m" \1 x% |) t7 m" i6 [
  33. }
复制代码
( |' Z' s' M9 Q! A0 ]' S3 n
xcEngine.dll 中的CreateFontA代码,可以尝试修改字符集和字符名称,看看是否能显示出中文。! p! `* L+ c6 e; p0 C  p
  1. h = CreateFontA(
    + v  r. C# c! j, }+ j
  2.         -*((_DWORD *)a1 + 1),      // 字体高度(负值用于可变尺寸字体)7 q- f% j6 }" E. S( {
  3.         0,                         // 字体宽度(0 表示由系统选择合适的宽度)
    ) m! t0 ^" `4 I# h
  4.         0,                         // 文本输出方向角度; D% @9 _; i3 r2 Y
  5.         0,                         // 字体基线方向角度
    ( d1 B4 J+ G9 [& a8 k  r; c
  6.         *((_DWORD *)a1 + 3),       // 字体重量(例如:FW_NORMAL、FW_BOLD)' H3 w1 v+ n) {2 l0 ^
  7.         *((_DWORD *)a1 + 4),       // 是否斜体; L5 ?5 A' A+ u1 i9 |
  8.         *((_DWORD *)a1 + 5),       // 是否下划线
    1 r0 o- s4 G) M; G. H& \
  9.         *((_DWORD *)a1 + 6),       // 是否删除线# f3 D) r0 S* ]" Z5 p; P
  10.         *((_DWORD *)a1 + 7),       // 字符集(例如:ANSI_CHARSET、DEFAULT_CHARSET)/ T! r" B( {: V
  11.         6u,                        // 输出精度(OUT_DEFAULT_PRECIS)" W! y- i4 }: \
  12.         0,                         // 剪裁精度(默认剪裁精度:CLIP_DEFAULT_PRECIS)  Z5 Z, ^2 y/ n8 k& P* s
  13.         4u,                        // 字体质量(DEFAULT_QUALITY). \: _" }, t# z
  14.         2u,                        // 字体族和固定/可变宽标志(字符剪裁精度:CLIP_CHARACTER_PRECIS)/ p: o  z! W, M/ C1 H) y
  15.         *(LPCSTR *)a1);            // 字体名称
复制代码
; z- C. e0 q& c" H: o* b5 c/ U
用API monitor 跟踪了一下GetDrawnCharCount ,发现和画面都能对应上,比如一下2行的24和8,就是对应画面上2行字幕的字符数。- J% v' u+ M6 \8 i

' ?, _$ X) k1 S' f+ Z) F
  1. #        Time of Day        Thread        Module        API        Return Value        Error        Duration% d6 H$ R9 d' ?1 {( r7 L8 H
  2. 6353        2:44:57.277 PM        1        SL2.exe        xccFrameText::GetDrawnCharCount ( ... )        24                0.0000002
    & m% |; o" E! `* C) M$ [
  3. 6354        2:44:57.277 PM        1        SL2.exe        xccFrameText::GetDrawnCharCount ( ... )        8                0.0000001
    % \. n& i8 H" Q) H/ Q* p+ c  ]
复制代码

0 U1 j; J' y3 d& \8 I  G- M  _( |% }6 X+ }+ j

: A$ q" Y' T+ [" `' m6 I3 Q
6 Z( {. w& o. n7 h- I
; o- [6 g. W, t7 `) i; H3 {8 b
/ B8 ^  G+ _9 Y3 G; b' k8 ~) J: G' g: A8 L$ O1 P$ _2 P5 I1 N
分享到:  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日,是全球华人共同的冒险解谜类游戏家园。我们致力于提供各类冒险游戏资讯供大家学习交流。本站所有资源均不用于商业用途。

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