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

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

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

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

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

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

本帖最后由 shane007 于 2023-8-26 14:47 编辑 & W2 R" Y% n) C  Y; z
7 A" b9 Y. y5 `
这个有的在上一波(第4波)中进行了比较深入的分析。
( H# w1 {# x6 h9 j% k' _4 t本次在以前分析的基础上,排除无关内容,只抓和汉化有关的要点。& R, v- E2 {  y, A' U' U' H# [% m
. |! d/ _' g+ P: N7 d- t9 ~7 [$ T
《1》这个游戏的初始化Directx9共有2处,一处是xcDxShader.dll,还有一处是xcDxOldschool.dll
4 w0 {* I3 ]; X) Z. u  n     具体要抓取哪个CreateDevice用于往屏幕上写字,需要写代码测试一下。  R) p+ K! ]; b* J$ ?/ H

) ~; C2 ?$ N- G  o% f' G# W+ N5 y《2》这个函数,以ida pro的静态分析为主,暂时认为字幕显示函数是xcEngine.dll中的SetTextString方法。6 P7 x! L0 ^/ v9 ?
9 J6 ^* I& [2 J2 S% g
关键是这2句,Str是完整的字幕,char_unicode是其中一个字符。4 F' g' m! L1 r* F  M( B
从代码上看,这个游戏是支持双字节的。但是由于采用的是图片字库,搞清楚结构不容易,因此暂定用hook方法自己写一个显示函数。/ k' B# E, Z; ^0 `
这函数传入一个text_object,里边也许会有颜色和坐标。
) @" a. G8 J- c* Q9 y( P
  1. char_unicode = (unsigned __int16 *)(*str + 2 * counter);
    & @0 j. c# l# `0 W( e; _- Y! @; m
  2. *char_unicode = xccTextureFont::GetCharacterIndex((xccTextureFont *)text_object[20], *char_unicode);
复制代码

% T0 M. C! e/ X; o4 R此外,该游戏在字体文件Sl2fnt.dat不存在的时候调用系统字库,' o! b9 D+ Z: l) a. [
因此,也许在调用createfont的时候,能用修改参数的方法让该游戏支持中文。
' o4 _' h5 g) e0 f) j/ a+ _% a. ?9 d8 B3 w7 ~$ F, z
+ p1 S' i2 I4 K/ `8 s
以下是修改过变量名的代码。
" i, }8 k: O$ z! }8 I
  1. int __thiscall xccFrameText::SetTextString(_DWORD *this, int length, _DWORD *a3, int show_subtitle_flag)
    " c; m0 z1 l  K/ q6 q" I7 @! B
  2. {$ P( p3 r# H. E' W
  3.   _DWORD *text_object; // esi% }% ~, p" c% U
  4.   int offset; // ebx
    9 M+ \8 U* {( e% `& J* d7 Q
  5.   int counter; // edi2 C8 Y. c* e0 S1 u4 r& z% c
  6.   _DWORD *str; // eax8 d: o6 L: y: `' Z- V
  7.   unsigned __int16 *char_unicode; // ebp
    0 E3 S5 y) m$ r  t2 v! y
  8.   int v9; // edx
    & }7 h2 y1 B8 }! T% w1 K$ l
  9. # h' u- J  h. Z/ r
  10.   text_object = this;
    , n* q2 u& w* U/ }) F
  11.   offset = 32 * length;
    , k6 G8 s3 C" P+ K
  12.   counter = 0;2 G0 |! M* x! ^, }7 m5 F
  13.   *(_DWORD *)(32 * length + this[21] + 8) = 0;  B$ i6 Y) x# B  E
  14.   xctArray<unsigned short>::add(*a3, a3[2]);5 o' G1 B; d# S5 x5 c% {7 n
  15.   if ( !show_subtitle_flag )/ s; I) i2 H4 X, c- t2 S5 Q0 e& Y
  16.   {
    9 S, f: f( ^& B+ N( f2 r/ A/ b3 J& Z
  17.     str = (_DWORD *)(offset + text_object[21]);2 @& b/ H* Z- ^& C1 E
  18.     if ( str[2] > 0 )+ v: D' m1 X2 W* s2 O. W& E% P
  19.     {
    4 L) K4 q( t" Y' P# q  ?! g* k/ d
  20.       do
    6 L8 @, I3 f5 A- o- z; P
  21.       {
    , z5 D, I* H3 F
  22.         char_unicode = (unsigned __int16 *)(*str + 2 * counter);
    3 N: P/ _4 d+ {! `
  23.         *char_unicode = xccTextureFont::GetCharacterIndex((xccTextureFont *)text_object[20], *char_unicode);
    - J$ p/ T! H6 A5 L1 c2 d) \: O
  24.         ++counter;
    : j* A+ F6 {/ n, S3 K: `: u' G
  25.         str = (_DWORD *)(offset + text_object[21]);
    & V! Q2 x0 s: |) J2 j, l
  26.       }5 Z0 I! ?+ N4 L- `3 ~% {
  27.       while ( counter < str[2] );
    + C, c7 b# b! `" S: q$ j
  28.     }/ a2 Y( Q: T4 L& H4 |
  29.   }& |& z! N( \# R' z
  30.   v9 = text_object[21];2 |9 ?$ f- P" c! r1 u: j: C4 C
  31.   *(_DWORD *)(offset + v9 + 28) |= 4u;3 B2 d7 U9 e. f/ b8 f4 o3 r2 I
  32.   return offset + v9 + 28;/ P  l3 j* C0 O& C
  33. }
复制代码

, c/ B% h, o0 t& A6 j  bxcEngine.dll 中的CreateFontA代码,可以尝试修改字符集和字符名称,看看是否能显示出中文。
8 c; f* A5 E8 _" L7 B
  1. h = CreateFontA(3 W2 H2 x' a$ D+ W9 ^# a& J0 p
  2.         -*((_DWORD *)a1 + 1),      // 字体高度(负值用于可变尺寸字体)
    7 r" p' w, z2 a
  3.         0,                         // 字体宽度(0 表示由系统选择合适的宽度)
    * l6 C4 n$ B4 @, I" k6 f# e
  4.         0,                         // 文本输出方向角度* j, d+ F. b. u) U' ^) k
  5.         0,                         // 字体基线方向角度# t/ r& L; M6 @. J; Z1 N( L
  6.         *((_DWORD *)a1 + 3),       // 字体重量(例如:FW_NORMAL、FW_BOLD)
    * L6 q! M4 p/ c" j4 ~
  7.         *((_DWORD *)a1 + 4),       // 是否斜体7 F4 t0 i; `! P9 T9 N
  8.         *((_DWORD *)a1 + 5),       // 是否下划线. H5 g- u( s, J! ]5 x/ r
  9.         *((_DWORD *)a1 + 6),       // 是否删除线/ v7 I7 ?, T" |9 w; H
  10.         *((_DWORD *)a1 + 7),       // 字符集(例如:ANSI_CHARSET、DEFAULT_CHARSET)
    % q( Y- J4 u. R1 c
  11.         6u,                        // 输出精度(OUT_DEFAULT_PRECIS)
    $ f- C5 P% c/ t2 f
  12.         0,                         // 剪裁精度(默认剪裁精度:CLIP_DEFAULT_PRECIS)
    : V+ [3 k+ k; p' A7 N: z
  13.         4u,                        // 字体质量(DEFAULT_QUALITY)8 F, r5 G" N$ j5 E" h& _; ?! Y1 R5 s4 x
  14.         2u,                        // 字体族和固定/可变宽标志(字符剪裁精度:CLIP_CHARACTER_PRECIS)4 A, C1 R2 P; W" e
  15.         *(LPCSTR *)a1);            // 字体名称
复制代码

# o; M! A' Q: A用API monitor 跟踪了一下GetDrawnCharCount ,发现和画面都能对应上,比如一下2行的24和8,就是对应画面上2行字幕的字符数。
& A7 ~2 a" A  p" }8 |0 z; G0 Q4 v1 I1 b1 ~% z2 D: p; x) a
  1. #        Time of Day        Thread        Module        API        Return Value        Error        Duration
      T0 V) O  x* I& n0 c( H9 I/ k
  2. 6353        2:44:57.277 PM        1        SL2.exe        xccFrameText::GetDrawnCharCount ( ... )        24                0.00000023 ]# |9 Q8 a! P! m1 c; ~. e3 Z
  3. 6354        2:44:57.277 PM        1        SL2.exe        xccFrameText::GetDrawnCharCount ( ... )        8                0.0000001
    2 c6 s' ?7 ?0 T- ]8 |: e1 Q  w7 M, b( K+ S
复制代码

( y% g: v$ |8 W4 p; i7 ~- f' K
' W7 [; o: E  V; M# }, a. A9 b; G, R2 Y5 @# y. o2 U
% G  d; X+ Z# H9 Z( n9 E8 F* n

; u, N4 F8 t  s- i% ]8 @3 H) Z% [2 W* h6 [6 U, z: \

+ x1 _; b0 P# a/ V/ B0 B; _5 p
分享到:  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日,是全球华人共同的冒险解谜类游戏家园。我们致力于提供各类冒险游戏资讯供大家学习交流。本站所有资源均不用于商业用途。

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