本帖最后由 shane007 于 2023-8-26 17:10 编辑 ; m: e' |2 [# ^ e& S* l
' C# l9 d* S9 \& X. {. m
这个游戏的主要修改点在\player\BuildingBlocks目录下的Adventure.dll中。
# k! ^ g5 @4 p1 V$ W) _用API monitor对本DLL的CreateFontA函数进行跟踪,发现确实有调用, 参数如下。
: h& `; x4 t, T9 ]$ V J8 Q, b+ g$ V8 T- u' z U
- # Type Name Pre-Call Value Post-Call Value* C4 R7 R, T0 o5 w
- 1 int nHeight 0xfffffff0 0xfffffff0& u( g2 ~/ m; }1 h. D
- 2 int nWidth 0x00000000 0x00000000$ Z% Y( B0 k2 R( w. o! q" C
- 3 int nEscapement 0x00000000 0x00000000
2 f+ z' o% }+ r& T( |1 x; X+ O9 Q - 4 int nOrientation 0x00000000 0x00000000( K/ w/ \3 ^7 w/ l7 J, ]
- 5 int fnWeight FW_NORMAL FW_NORMAL- E! W- x0 o; U/ Q! K
- 6 DWORD fdwItalic 0x00000000 0x00000000
, t5 ]" Q* C7 X+ v9 A - 7 DWORD fdwUnderline 0x00000000 0x00000000( o9 |6 c( c# l5 j, x3 {
- 8 DWORD fdwStrikeOut 0x00000000 0x00000000 l0 m# _4 y9 e3 E
- 9 DWORD fdwCharSet DEFAULT_CHARSET DEFAULT_CHARSET
7 w* N, G/ u4 `! @% T - 10 DWORD fdwOutputPrecision OUT_TT_ONLY_PRECIS OUT_TT_ONLY_PRECIS
0 _1 }# U# Q' i. r( r' B7 s7 h - 11 DWORD fdwClipPrecision CLIP_DEFAULT_PRECIS CLIP_DEFAULT_PRECIS
' ^/ r2 A# K4 F: |* Z - 12 DWORD fdwQuality PROOF_QUALITY PROOF_QUALITY! m, f- T- g2 r9 ^! M( g! s
- 13 DWORD fdwPitchAndFamily FF_DONTCARE | DEFAULT_PITCH FF_DONTCARE | DEFAULT_PITCH+ U9 y ? h& d: r8 F6 Q
- 14 LPCTSTR lpszFace 0x09148a58 "Arial" 0x09148a58 "Arial"" W5 h; S0 U; r' }
复制代码
) |6 {+ r! I/ Q- Z$ i: }/ B4 ]+ W
/ z: Z* s1 L* ? p0 H用ida pro找到调用CreateFontA的源头函数如下。$ I2 l8 u# f+ A# L/ X- \) c
从函数的参数可以看出,这应该就是字幕显示函数了。
- f5 h- Z. f" y7 E9 j关于后续修改,先修改CreateFontA函数的fdwCharSet,lpszFace这2个参数,也许就能出中文。: _ w5 f0 X; N( a4 z; W# u4 d
还不行的话,就自己写一个显示函数。以下函数中lpMultiByteStr就是指向字幕的指针。
* s% f5 |. C0 D% G. T3 b
\: Y- c% p7 k) x- bool __thiscall sub_10058A00(void *this, int a2, int a3, int a4, int nNumber, int a6, DWORD a7, int a8, int xRight, int yBottom, LPCSTR lpMultiByteStr)( S# M! y7 E8 R7 o
- {
, w8 A1 Z7 u% b! [- [' |6 k - void *v11; // edi8 R, @4 Y" p6 M
- int v12; // eax
. u3 F0 {- s3 f - int v14; // ecx9 T! n: b0 B7 p- x r0 v, A
- int v15; // eax
. t6 p+ `' M# y( }6 M, Z8 u - char *v16; // eax
5 f! h. U, M5 Y' p4 T - int v17; // eax
, i, t; w6 J2 X( c% _ u" i - HDC v18; // ebp: {9 w3 x9 j; P+ J/ f
- int v19; // eax3 ~) S: u4 W: `( w( y
- int v20; // eax
& A" M2 R; a) U; e5 \ - int v21; // esi9 c. U9 t( j2 q0 l" u! q4 y* e. ]
- char *v22; // eax
$ z8 s6 o/ [+ Q - int v23; // esi
% S5 x$ s! Q3 F3 u9 \: \! c3 D7 V& n/ | - int v24; // ecx
" G2 S! C1 D% I - HBRUSH v25; // eax
) g" b; k! h, g1 j' F" g - signed int v26; // ebx
0 A3 K5 D J# ] - WCHAR *v27; // eax/ I( ?! R" x1 J( }
- int v28; // esi! m$ X8 Q0 R; K% t I
- int v29; // ecx8 ?) {. M$ E% ]- F
- int v30; // eax
2 f; n* p) B8 y+ i: [! p4 Y - int v31; // ST28_4' A/ L! P( D1 d* x& O* K k
- bool v32; // sf
/ ~6 J0 `! c& {: ]* T" q4 R - unsigned __int8 v33; // of
; K. H$ F g, S$ u: T - unsigned __int8 *v34; // ebx
$ v! ?7 b. j) q2 s! B2 i - int v35; // ecx% O, F% [0 J5 R/ K6 s7 P
- int v36; // esi
5 N% X: F$ y0 V3 F - int v37; // edx
4 n$ X7 [" y; Q) F3 B6 p& i - int v38; // eax
" {1 B/ P# _4 t, Q! t2 R% `6 u - unsigned __int8 *v39; // ecx
6 p y- Z- i3 g3 f- {2 M) Z - int v40; // [esp+40h] [ebp-2098h]
8 ]6 h/ m6 D3 ^1 |( R - signed int v41; // [esp+44h] [ebp-2094h]0 o: W5 }, ]+ o" t( r
- WCHAR *v42; // [esp+48h] [ebp-2090h]3 I' R/ c; c2 {% ]
- LPCSTR v43; // [esp+4Ch] [ebp-208Ch]/ z3 n* N+ U/ ^
- int v44; // [esp+50h] [ebp-2088h]
3 C& c. T) ~& s; k3 a }6 z- { - HGDIOBJ v45; // [esp+54h] [ebp-2084h]& e0 M( U* q+ [) i. e8 w' N+ i4 U
- HGDIOBJ v46; // [esp+58h] [ebp-2080h]
- a2 X$ W4 ] Y4 k5 L - HGDIOBJ v47; // [esp+60h] [ebp-2078h]# P/ x }3 X3 U1 G u ^% Y2 {+ U7 a
- HFONT v48; // [esp+64h] [ebp-2074h]
, ?/ v" O1 W* D* f% D2 ?7 A - float v49; // [esp+68h] [ebp-2070h]! v+ p& |$ I5 X! h3 v/ G: m+ G7 u4 |
- float v50; // [esp+6Ch] [ebp-206Ch]
7 `5 [3 ^+ A. N - char v51; // [esp+70h] [ebp-2068h]
4 @% W { v7 i+ P: Q7 ~2 l. N - int v52; // [esp+74h] [ebp-2064h]
5 p- D/ A; \( f% k; _5 v - int v53; // [esp+78h] [ebp-2060h]0 _" w+ Q4 K3 V" }" i$ E" u% I
- int v54; // [esp+7Ch] [ebp-205Ch]
2 ]' H! A$ Q+ j$ N- E4 ~7 P - int v55; // [esp+84h] [ebp-2054h]
/ w3 v/ ~, d/ D4 n9 A* m% s. f - struct tagSIZE v56; // [esp+88h] [ebp-2050h]
+ i, _+ ~* A3 ]: x$ G - struct tagRECT rc; // [esp+90h] [ebp-2048h]
9 u+ I1 M' t R( O - int v58; // [esp+A0h] [ebp-2038h]+ [5 [! ?( G: m: F9 ~! P
- char v59; // [esp+A4h] [ebp-2034h]
9 l" s1 o4 o+ l8 N - WCHAR WideCharStr[4096]; // [esp+D4h] [ebp-2004h]
. ?) |! `7 |1 q - $ A9 T$ e/ p1 _/ a' O4 m
- v11 = this;
! Z4 o+ ~8 I: p' _ - v58 = 52;( Z4 q" V) ~3 e# d$ P4 u
- memset(&v59, 0, 0x30u);
0 Q- x" V4 E9 X \5 _8 | - if ( *lpMultiByteStr )5 U! c0 c( b" N5 R
- {, O/ w4 H- c: m
- v12 = MultiByteToWideChar(0xFDE9u, 0, lpMultiByteStr, -1, WideCharStr, 4096);
$ O% @( Q; B9 S - *((_DWORD *)v11 + 4) = v12;
" q" @: W% M- g9 O+ _ - if ( v12 <= 1 )
: R" D: {4 b- r - return 0;( ?6 ]7 g7 ]7 p" M% h) s2 h
- *((_DWORD *)v11 + 4) = v12 - 1;! j3 A5 J+ M' L) V7 W
- qsort(WideCharStr, v12 - 1, 2u, sub_10057A40);$ s9 [3 k3 z) O
- }
, w1 B/ j2 k& M" r5 v - else
, ?. a" H+ R- ?0 n i9 H - {; `& \0 r9 ?" a( {
- *((_DWORD *)v11 + 4) = 352;- w7 n# y( V) W, L/ J) w6 P- m
- v14 = *((_DWORD *)v11 + 4);! i7 s- h$ Y( C& R1 u
- v15 = 0;
, z0 F! B. `* Y8 c% O - do
( g4 B" `* _% C5 A - {6 I7 s/ z7 D+ a ?$ _( B
- WideCharStr[v15] = v15 + 32;
9 U7 X! @' x3 S2 m# {& c* i5 m - ++v15;
, B9 x& T1 o* N& T - }
% F5 K" `% g D' \; f, i - while ( v15 < v14 );
+ j o$ I8 G, ] ~' T - }
7 \ b0 X7 a s0 B7 K, k, u - v16 = *(char **)v11;/ U, E8 r8 R. h3 x, k
- if ( !*(_DWORD *)v11 )
" A6 {( k" _9 g/ k( ] - v16 = byte_100B2D6E;
* `( O7 x* n- P- `# s0 J, G( w) L - v17 = CKContext::CreateObject(a2, 31, v16, 0, 0);6 ^) D- T. h7 ]
- *((_DWORD *)v11 + 6) = v17;
; I X8 G6 X$ a1 h0 Z - if ( !(*(int (__thiscall **)(int, int, int, signed int, _DWORD))(*(_DWORD *)v17 + 84))(v17, xRight, yBottom, 32, 0) )
z! \7 J7 Q% M% } - return 0;: s* x9 ^& ?/ {9 U& c
- (*(void (__stdcall **)(int *))(**((_DWORD **)v11 + 6) + 136))(&v58);
) g y. u8 C7 Q- S3 g4 V' J+ `* ? - v18 = CreateCompatibleDC(0);1 W, {' ^' B1 a' m2 p
- v45 = VxCreateBitmap((const struct VxImageDescEx *)&v58);
) e2 o0 i& w* a7 X - v47 = SelectObject(v18, v45);
) _7 w! C8 \8 b% M. @6 L: e3 h - XString::operator=(v11, a3);
9 c2 o3 E' e" b y$ |9 K% O - *((_DWORD *)v11 + 2) = nNumber;
+ x! l4 T1 T: |9 J - v19 = GetDeviceCaps(v18, 90);# e) o M7 @, [' l# s3 i
- v20 = MulDiv(nNumber, v19, 72);3 D3 ], a6 s) |8 L
- v48 = CreateFontA(-v20, 0, 0, 0, a6, a8 & 1, ((unsigned int)a8 >> 1) & 1, 0, 1u, 7u, 0, a7, 0, (LPCSTR)a4);2 E6 V8 `: c& F/ ]7 l" l1 h4 q' N1 G4 S
- v46 = SelectObject(v18, v48);
% t, b1 g& |; M" i4 Q - GetTextExtentPointA(v18, "A", 1, &v56);9 K- o% L8 }$ r; W
- v21 = *((_DWORD *)v11 + 4);
& L- b9 S0 g% v - *((_DWORD *)v11 + 3) = v56.cy;
: G* W. @6 D$ S" E - v22 = (char *)operator new(32 * v21);
1 J8 P! \: M# R - if ( v22 )
- O' ~2 V: \7 q5 B) Q1 K - {
" X+ Y9 s! N3 L - v23 = v21 - 1;
' t7 h; Q+ _0 G - if ( v23 >= 0 )) k/ _$ P0 I% y
- {
! U% }( b+ q/ J5 U. g - v24 = (int)(v22 + 12);
0 A& z! n* ]( F5 N - do
! F2 |0 c, U9 P3 \ - {
- l! `+ H. r) _- s3 ` - *(float *)(v24 - 4) = 0.0;% x& o! n) V! B- A5 Z; a8 |# x3 V9 O" c
- v24 += 32;
1 J+ ]1 a7 ?. B) Q9 D - --v23;' C6 J$ \6 d7 m6 L8 r
- *(float *)(v24 - 32) = 0.0;8 I! S' |* y+ s/ y8 L3 ~
- *(float *)(v24 - 44) = 0.0; b7 c; a; S& s
- *(float *)(v24 - 40) = 0.0;0 O1 O% b5 e- ^: I8 P
- *(float *)(v24 - 36) = 0.0;
2 m+ n9 Z1 P' y0 Q# ?; H - *(float *)(v24 - 32) = 0.0;8 L# \% |/ M0 Y
- }
' A3 C* S' ~7 _ - while ( v23 >= 0 );
$ L8 ~" ]; w0 P) o - }7 @( H9 B9 D8 p: V. r% e% i
- }
; |7 v+ v$ U* ^9 X3 h; p - else/ {8 |. s4 X; `. U3 B9 z
- {
( v! p. q' s8 a) i7 a. q/ g - v22 = 0;9 V7 p% h4 _ e
- }
" ]9 @- q1 T# F1 b: P+ `( I, t8 a - *((_DWORD *)v11 + 5) = v22;* L9 Q7 o4 v+ @
- SetRect(&rc, 0, 0, xRight, yBottom);" v5 h5 F2 \) c' n& ?3 B7 l3 s3 o
- v25 = (HBRUSH)GetStockObject(4);' z* H5 q8 {! R3 t$ ~3 X5 ]: q. z) v
- FillRect(v18, &rc, v25); L% d: n8 T, S; i n# u
- SetBkColor(v18, 0);
0 J; q$ H; z2 V - SetTextColor(v18, 0xFFFFFFu);
6 S' `- d" W" s4 X \' a) D - SetBkMode(v18, 1);
8 h+ Y0 O" r2 T: f8 V- h - v26 = 1;
# C# ^" h6 x: P - v41 = 1;
( I/ O/ _! _3 I1 f - v40 = 0;
; ?, P! k7 R9 Z& @ C - v43 = 0;* u1 Y! t( }( `8 |# v
- if ( *((_DWORD *)v11 + 4) > 0 )- k, K2 P& Y8 h' y
- {
. S2 U' `# [# H# Z - v27 = WideCharStr;
( o! k# Y V( E# A) w - v44 = 0;) w: w& F+ d& }, I% r
- v42 = WideCharStr;
7 |+ o8 P* A5 a# p. o( k& k - v49 = (double)xRight;8 a+ f2 _2 J2 E$ x0 c. C+ F
- v50 = (double)yBottom;! u6 I: d$ E- N/ N0 \; S3 p
- while ( 1 ); u! \' @" _9 C$ ^+ r, |
- {
. k: h- x& @( c1 L O - v28 = v44 + *((_DWORD *)v11 + 5);0 U7 [, T& |% \" V
- *(_WORD *)(v28 + 16) = *v27;6 Y* E3 \4 m# E! O
- GetCharABCWidthsW(v18, *v27, *v27, (LPABC)(v28 + 20));
8 c$ M3 E, t3 H - if ( *v42 >= 0x20u )
O% n+ A1 G4 | h8 y - {1 g4 e, p. w: z; C) s
- --*(_DWORD *)(v28 + 20);0 G4 c$ I6 u4 |( w0 n
- *(_DWORD *)(v28 + 24) += 2;4 f2 f* ?1 x! d, g4 ~
- --*(_DWORD *)(v28 + 28);- Y7 F S6 O( C2 K C _
- }
" C3 j, ~6 V3 S# s/ A2 G - else1 p- f5 ?& g6 e0 k: n% v% y
- {' K& X; f, ?+ M) S* b; V; H
- *(_DWORD *)(v28 + 20) = 0;- x4 \! H! X! s# g
- *(_DWORD *)(v28 + 28) = 0;
; e) V G) l1 \; p6 {/ K - }
# Q2 N5 I- n8 K0 k+ K! g7 O - v29 = *(_DWORD *)(v28 + 24);
* F! [7 z& W( D6 J f - v30 = v40;' a0 Q; t1 {' ~
- if ( v29 + v26 + 1 >= (unsigned int)xRight )& A% _2 T! v% I! }! W7 Z
- {! x7 ?5 r% K) Z- U5 @+ n9 ]! w! r
- v26 = 1;# ~6 c/ U- r* Q# l" }* e5 J$ ~
- v30 = v40 + *((_DWORD *)v11 + 3) + 1;* m% F- L( j# W2 m
- v41 = 1;
& l5 k- P4 \- i% N - v40 += *((_DWORD *)v11 + 3) + 1;5 p/ M5 S5 ?$ D* T9 r. l1 v& s
- }
8 ?5 ~6 t1 D1 S, \ - *(float *)v28 = (double)v41 / v49;
1 w7 U/ E$ E6 K& T* \% o1 A6 e - *(float *)(v28 + 4) = (double)v40 / v50;/ j3 q) ~/ \* Z0 x" Z' R; @
- *(float *)(v28 + 8) = (double)(unsigned int)(v26 + v29) / v49;7 i& [0 R3 |8 l t1 S c
- v31 = v26 - *(_DWORD *)(v28 + 20);
! M6 x/ I8 }' O - *(float *)(v28 + 12) = (double)(v30 + *((_DWORD *)v11 + 3)) / v50;
/ _) o: Z; [; ^: J' `1 a - TextOutW(v18, v31, v30, v42, 1);5 I* p. y; d) H; V8 {+ v
- v44 += 32;( Z- k4 X h. I( ^1 \! r \% {
- ++v42;
, T3 I) M" }4 ^3 D/ G - v33 = __OFSUB__(v43 + 1, *((_DWORD *)v11 + 4));
7 C2 W1 o. g e2 u: i E$ {+ E - v32 = (signed int)&v43[-*((_DWORD *)v11 + 4) + 1] < 0;
3 g2 Q4 P( R2 @* M - v26 += *(_DWORD *)(v28 + 24) + 1;* M1 ~- A0 l3 F5 Y- F
- v41 = v26;
0 P$ P" U( I8 {+ m - ++v43;6 H. T+ E( |- }* p
- if ( !(v32 ^ v33) )
9 @& K8 u/ o3 o q- y' |* N2 z - break;) t: x1 C+ M, |* b& w6 b" t8 s" ]
- v27 = v42;
) {- h$ ~0 k( t6 w4 P - }. ~5 v+ @6 _- z0 l: A g: r
- }3 S3 I# b0 p# d# e
- v34 = CKBitmapData::LockSurfacePtr((CKBitmapData *)(*((_DWORD *)v11 + 6) + 56), -1);
" N( T! Z- K% I, Y - if ( v34 )
0 B) n& H: X0 s - {7 l; L: w! U5 q( Z, M/ t0 a3 Y5 {
- GetObjectA(v45, 24, &v51);
! k& k. Y* y, s6 u( J b# x - v35 = v53;, Q; i7 K% k7 Z7 W* _9 M! y$ D4 Z$ T) ^
- v36 = v55 + v54 * (v53 - 1);
, a) O9 M! y! w; k7 z, l - v40 = 0;' |) Z: N1 k! c8 \6 m' V8 c: ?
- if ( v53 > 0 )* G1 D; p: e1 |4 G2 ]$ f
- {: A0 c! f, i; _+ B) n3 [
- v37 = v52;, O% U! @. `0 n" u/ N5 J. R
- do
2 h* R ]6 b4 H# u' t9 L - {
4 x& U$ Z7 }8 Z+ U! D* r! } - v38 = 0;
$ I/ {+ s& f) t- |& @ - if ( v37 > 0 )6 i6 q, ~# V$ A( E* X, `* C9 n
- {
" x2 N2 x6 d6 R- U* @8 i - v39 = (unsigned __int8 *)v36;5 d* l, D3 s% Y: f
- do
( G. Y6 w% A3 P5 P, _ - {
: I! K$ E; E. [2 w4 H - *(_DWORD *)&v34[4 * v38] = (*v39 << 24) | 0xFFFFFF;* Z5 i9 ^- Z/ Q
- v37 = v52;( U0 T7 ~- l4 I( [ F& M. [; x( q
- ++v38;
! K+ V" G/ o: e0 H - v39 += 3;5 D' M- N4 h$ ~/ I
- }
, `: a7 e7 |! Y - while ( v38 < v52 );
1 u; c1 m2 R Z' u2 _ - v35 = v53;; ^- @, F. M2 s2 H
- }% t C" Y1 m* J* r# U3 }5 ^9 e
- v36 -= v54;+ p3 v2 l5 C$ z3 o' ]& T6 d
- v33 = __OFSUB__(v40 + 1, v35);) f! \6 Y( v7 U
- v32 = v40 + 1 - v35 < 0;
9 L5 T4 A: [& Z6 i+ n5 y - v34 += 4 * v37;/ u) c* Y m, m) V/ d0 Y9 E. E; I
- ++v40;, k }# J- o2 K5 M7 I5 S
- }+ a% H" c3 e: `) A' ~/ j
- while ( v32 ^ v33 );- [* t4 e7 O4 S# D% e3 i& s% R/ f
- }( w9 m' T5 p: x! r5 c8 i4 b
- }
, f6 t; K% c9 V' r2 P - CKBitmapData::ReleaseSurfacePtr((CKBitmapData *)(*((_DWORD *)v11 + 6) + 56), -1);! f/ |$ f* |$ F) U# ^
- SelectObject(v18, v46);
' C: H5 a: U/ I. |# r - VxDeleteFont(v48);! Q3 l! X4 p. H7 `0 E9 h1 H% b
- SelectObject(v18, v47);* [4 s: z4 \" K
- VxDeleteBitmap(v45);
1 J9 E; T/ n, \! D! J6 F2 ~/ D - DeleteDC(v18);
6 }1 N F+ J' a - CKObject::SetName(*((CKObject **)v11 + 6), (char *)a3, 0);
( L& g, h+ b9 @! r* w - CKBitmapData::SetDesiredVideoFormat(*((_DWORD *)v11 + 6) + 56, 1);
) |! j7 }; k$ l: V8 h5 H; X - (*(void (__stdcall **)(_DWORD))(**((_DWORD **)v11 + 6) + 120))(0);
, q" [, S9 }1 J. V - return v40 + *((_DWORD *)v11 + 3) < yBottom;+ ~0 q8 |; k6 ~8 g8 b: |
- }; g8 o, k& c, r& F0 V3 F9 M
复制代码 . Q. P4 ~8 O$ K9 X* y4 \, _
8 y5 ?0 B' K$ b" Z" n6 ?
|