本帖最后由 shane007 于 2023-8-26 17:10 编辑
- Y% `) y; W; L% X3 c5 }( k! C% H' b& h% e5 e
这个游戏的主要修改点在\player\BuildingBlocks目录下的Adventure.dll中。
5 g& A$ t r( r用API monitor对本DLL的CreateFontA函数进行跟踪,发现确实有调用, 参数如下。3 Z& h, ]/ b( `" a. ?# T
W" z2 y5 A9 E& F4 @- # Type Name Pre-Call Value Post-Call Value
- ^2 V2 C M3 ^4 ? - 1 int nHeight 0xfffffff0 0xfffffff02 K7 x4 r' s% }: E' i
- 2 int nWidth 0x00000000 0x00000000- {$ ~! d- I% |5 b1 { t) v
- 3 int nEscapement 0x00000000 0x00000000
" n3 o) x( F, D% A+ f - 4 int nOrientation 0x00000000 0x000000000 m, m# O; W5 N$ k
- 5 int fnWeight FW_NORMAL FW_NORMAL/ p' g; U5 d9 @2 v" Z9 i( z" _
- 6 DWORD fdwItalic 0x00000000 0x00000000( j0 x- P% I' B" z. ]/ X
- 7 DWORD fdwUnderline 0x00000000 0x000000004 J/ \. h4 ]1 X
- 8 DWORD fdwStrikeOut 0x00000000 0x00000000 J2 d {6 t# s* v+ q+ t
- 9 DWORD fdwCharSet DEFAULT_CHARSET DEFAULT_CHARSET* r# E! `# U5 l8 N$ n- I2 y
- 10 DWORD fdwOutputPrecision OUT_TT_ONLY_PRECIS OUT_TT_ONLY_PRECIS
* P1 y9 `) Z- d \# j - 11 DWORD fdwClipPrecision CLIP_DEFAULT_PRECIS CLIP_DEFAULT_PRECIS
$ D( o( t9 C6 W3 x( U# n$ i" p - 12 DWORD fdwQuality PROOF_QUALITY PROOF_QUALITY
% p; x: C7 h. v# V - 13 DWORD fdwPitchAndFamily FF_DONTCARE | DEFAULT_PITCH FF_DONTCARE | DEFAULT_PITCH' Q5 j+ {2 B$ W% t* J. a( k
- 14 LPCTSTR lpszFace 0x09148a58 "Arial" 0x09148a58 "Arial"3 U/ L# ?1 g" @' H. y/ `+ J" }' o; h
复制代码
$ }* u& l R& F d1 t( K C% |4 {5 ~; k( j' u' v
用ida pro找到调用CreateFontA的源头函数如下。6 u2 u$ w: c- O' V% `& ]
从函数的参数可以看出,这应该就是字幕显示函数了。
) L1 {. _2 ~5 b5 O, S% u关于后续修改,先修改CreateFontA函数的fdwCharSet,lpszFace这2个参数,也许就能出中文。3 V$ m" {8 }; X x
还不行的话,就自己写一个显示函数。以下函数中lpMultiByteStr就是指向字幕的指针。
# X: W8 X! O, a( g- N( N) X) d% h* A! a
- 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)
9 }* K5 K- y8 b1 }/ d# m - {+ R& J( \9 w8 E* K/ m5 p I' l* ?
- void *v11; // edi( n5 s4 K. O% N; J" W9 r* U" J) t# v
- int v12; // eax. _2 v; @% w) h( K- }
- int v14; // ecx* Y" u- C! \9 r$ K6 s
- int v15; // eax
& \/ R5 W7 m9 j6 C - char *v16; // eax
) L1 |+ J7 Q- ~( C; E9 Z1 O* F/ o/ ~5 f( Y - int v17; // eax: ]4 H1 i$ T1 a/ p% X/ O
- HDC v18; // ebp
$ G4 _$ [% u+ h - int v19; // eax- X5 y6 O6 v, ]: T6 }$ B% X
- int v20; // eax
4 c1 g, Q6 c9 q2 g- `) |) t; s - int v21; // esi
+ b- U" Y+ _0 R) u - char *v22; // eax' F% I$ }9 W/ Q# n3 Q( h7 W: M8 ?: \
- int v23; // esi& o% }0 D) [, f
- int v24; // ecx* Q6 I8 ?, f. \2 ^# ], k
- HBRUSH v25; // eax
' o! R5 T8 \6 \7 C- R! b - signed int v26; // ebx: J$ a; {6 s3 y
- WCHAR *v27; // eax
* O/ t4 ~8 F) n) W - int v28; // esi' _( a6 x! F) v
- int v29; // ecx
4 V4 ]3 r; m$ |# v$ ?0 X - int v30; // eax
* V8 h- A; j5 b' r - int v31; // ST28_42 L; @8 I) L/ |9 f O/ I
- bool v32; // sf4 V7 \1 y& J# Q7 |+ L p! z: k
- unsigned __int8 v33; // of
! T+ T1 i9 J2 e+ w% ~7 o$ ^' e& C: R - unsigned __int8 *v34; // ebx
) g' i+ l1 X0 G5 R - int v35; // ecx
- f& m6 j$ {0 C - int v36; // esi
. y' H1 Y) k9 H* a. S - int v37; // edx
7 ~( l% b7 k6 F$ p+ b( g) n5 a' u - int v38; // eax
1 V1 X# i: _- ]5 F- L n - unsigned __int8 *v39; // ecx
- l- j9 n" u* ~ - int v40; // [esp+40h] [ebp-2098h]0 p f5 p7 O; U: J
- signed int v41; // [esp+44h] [ebp-2094h]
+ W6 j3 O9 T+ B7 K" h6 {- p - WCHAR *v42; // [esp+48h] [ebp-2090h]3 l$ j6 o% v8 z+ Q
- LPCSTR v43; // [esp+4Ch] [ebp-208Ch]/ z, ^. h4 C" k7 H, v1 ~
- int v44; // [esp+50h] [ebp-2088h]& }' R2 n- Z6 R6 q4 P4 c# Z
- HGDIOBJ v45; // [esp+54h] [ebp-2084h]
! ]2 h- s9 n# u) x0 b - HGDIOBJ v46; // [esp+58h] [ebp-2080h]
" t' S9 @6 c/ t. V) T - HGDIOBJ v47; // [esp+60h] [ebp-2078h]
3 U. \6 j9 J9 s' g* N t0 [ - HFONT v48; // [esp+64h] [ebp-2074h]0 b6 w9 i$ ^* u9 E4 H) e3 v1 r# B
- float v49; // [esp+68h] [ebp-2070h]
. f; ~$ `0 w( B' n6 } - float v50; // [esp+6Ch] [ebp-206Ch]5 X' t- O( `6 p. w6 x
- char v51; // [esp+70h] [ebp-2068h]. t; q- c" Y$ a% v! T7 Z
- int v52; // [esp+74h] [ebp-2064h]& V1 P# c0 `/ o2 V
- int v53; // [esp+78h] [ebp-2060h]/ o7 R3 E# n, T& g3 h5 ^
- int v54; // [esp+7Ch] [ebp-205Ch]$ @7 U2 ?- l+ a( _; m3 j+ y
- int v55; // [esp+84h] [ebp-2054h]" d [. T5 G+ Q
- struct tagSIZE v56; // [esp+88h] [ebp-2050h]+ ~$ q0 ?- r; s1 ?3 u
- struct tagRECT rc; // [esp+90h] [ebp-2048h] _9 F2 k4 a0 `- n0 w
- int v58; // [esp+A0h] [ebp-2038h]4 a3 O `# a1 y( U
- char v59; // [esp+A4h] [ebp-2034h]" u E- r+ e) n6 r8 j9 x
- WCHAR WideCharStr[4096]; // [esp+D4h] [ebp-2004h]
) J A! q* j- u6 M" T) U - - V/ X. V5 U: s/ Z' ^7 t
- v11 = this;
$ G) d3 d8 r% D3 t5 `" { - v58 = 52;8 I) X: }0 h- Q1 S
- memset(&v59, 0, 0x30u);
3 G/ e0 r: }1 s" c: H8 C - if ( *lpMultiByteStr )
6 [; ~( A/ B3 |$ Z- i m0 n. D - {& q6 c" \8 i' W1 H
- v12 = MultiByteToWideChar(0xFDE9u, 0, lpMultiByteStr, -1, WideCharStr, 4096);
1 O+ P. c- y5 J - *((_DWORD *)v11 + 4) = v12;
5 Q/ K5 E/ f) N9 [7 @ - if ( v12 <= 1 )! y. C% [; q- O* l, m$ w- p
- return 0;
) E! V1 c4 _9 N# W. R$ ^ - *((_DWORD *)v11 + 4) = v12 - 1;
( x' D: x* W. O* E/ D! p( ] - qsort(WideCharStr, v12 - 1, 2u, sub_10057A40);
2 u) J' e* }# r( O* Y - }0 o$ _% i2 i2 _( i6 ]& H: Y& L
- else
1 o" ^. s5 m3 Z5 O9 ?& k - {
# C3 W P3 o2 I4 L. {" n - *((_DWORD *)v11 + 4) = 352;
2 D6 P$ Q# h) h# k9 S" g% R - v14 = *((_DWORD *)v11 + 4);: M( O: }/ B. c6 L$ w" {. i
- v15 = 0;: [- ?. u% w% C6 v2 M0 f
- do
' G# G3 j- m, ] - {
; a4 K+ ]" e( o1 H, }0 W - WideCharStr[v15] = v15 + 32;# d6 Y3 p6 r, m( H3 b
- ++v15;
" c2 J" m' k! j; d* ~# I, r - }3 c6 m8 y1 g& V( @9 o
- while ( v15 < v14 );# i. O! b6 j! u' r1 Z, ^! `9 v
- }
7 I! j/ I4 ]$ E# r - v16 = *(char **)v11;' \# s( Y. _: f- V6 U& M
- if ( !*(_DWORD *)v11 )
* W1 s. p! _4 ^0 X - v16 = byte_100B2D6E;9 N% ?; c5 j; j8 q0 y
- v17 = CKContext::CreateObject(a2, 31, v16, 0, 0);% n$ a T. t9 P9 R4 L) e
- *((_DWORD *)v11 + 6) = v17;, L8 v/ j. ]2 t, e
- if ( !(*(int (__thiscall **)(int, int, int, signed int, _DWORD))(*(_DWORD *)v17 + 84))(v17, xRight, yBottom, 32, 0) )0 K" m4 f Z4 c0 [1 F
- return 0;
2 E4 i9 E6 ]' Z- v3 s( W - (*(void (__stdcall **)(int *))(**((_DWORD **)v11 + 6) + 136))(&v58);5 X% {9 x7 t8 y: B7 k) F4 t$ q
- v18 = CreateCompatibleDC(0);
* Y6 H* V5 x. F! l( i/ a+ \ x1 L - v45 = VxCreateBitmap((const struct VxImageDescEx *)&v58);
) V) ]; S7 d2 `3 g0 F - v47 = SelectObject(v18, v45);, `) W" o; S7 D( U
- XString::operator=(v11, a3);( B' ?3 r" F- [' b0 S
- *((_DWORD *)v11 + 2) = nNumber;4 T) i) @9 t1 ?8 N9 o
- v19 = GetDeviceCaps(v18, 90);
0 z3 s) Z" L3 I8 h. e M - v20 = MulDiv(nNumber, v19, 72);
, u3 S4 \, v1 Y$ Y: R; K - v48 = CreateFontA(-v20, 0, 0, 0, a6, a8 & 1, ((unsigned int)a8 >> 1) & 1, 0, 1u, 7u, 0, a7, 0, (LPCSTR)a4);
4 X0 \0 Y5 E' ` - v46 = SelectObject(v18, v48);
0 w8 w; A3 F/ m5 O( n& d; f W( \ - GetTextExtentPointA(v18, "A", 1, &v56);: ^( g. d9 Z+ p# H
- v21 = *((_DWORD *)v11 + 4);
$ {5 A; n& E4 E/ \/ |1 e: Y: J - *((_DWORD *)v11 + 3) = v56.cy;
+ f* Z' y% u ~# ?2 O5 y - v22 = (char *)operator new(32 * v21);$ f6 ^+ g' I6 g; i! `2 l' l. w2 U6 Q
- if ( v22 ) l* c1 s4 E1 A2 e# Q
- {
5 t) {9 Q5 Y* Y% H( L - v23 = v21 - 1;. d: |! F4 c, j5 h
- if ( v23 >= 0 ): J% F: q+ }9 k2 K8 p4 m0 i- f
- {2 Q O0 _3 ?+ p; E
- v24 = (int)(v22 + 12);9 S6 E" `0 G- _3 e$ j
- do
2 j9 o+ H$ p5 ~1 o$ |0 M - {9 z. f! y- V8 g2 C8 S& }1 z1 M
- *(float *)(v24 - 4) = 0.0;! X4 S7 C. Z2 ?0 D5 ^0 e- B3 E p4 J; q
- v24 += 32;
) t4 A8 C0 S: k, j$ | - --v23;/ r9 D$ h5 D5 n; l r7 @' J
- *(float *)(v24 - 32) = 0.0;: D; g- V# d9 n$ |- S( w
- *(float *)(v24 - 44) = 0.0;+ f5 C: h" M3 p d( W1 }4 [, u& R! ^
- *(float *)(v24 - 40) = 0.0;- q5 ]) X |9 r' `5 I. \5 _& b
- *(float *)(v24 - 36) = 0.0;
8 m+ x. V% c" F1 Q - *(float *)(v24 - 32) = 0.0;8 a" [' s% P( Y! p5 u" I; X
- }
0 o3 b6 M! g) y6 ]# z5 [ - while ( v23 >= 0 );
6 V' \4 ?& j/ Z5 @ - }% R. s8 v; e) |) K. j
- }1 I. M; m3 l; y+ m6 [ b, ]4 F$ H
- else; C2 t, L; e. `/ @) L3 ]
- {/ m/ }# h0 b& V9 B6 O- z
- v22 = 0;
; j. P, X/ s5 X F: n/ Q - }
$ O# b+ A X2 V - *((_DWORD *)v11 + 5) = v22;
: Y: D/ U8 N u5 v% Y - SetRect(&rc, 0, 0, xRight, yBottom);
* v# W, w, ?4 s \; W6 K w - v25 = (HBRUSH)GetStockObject(4);2 ]; d4 r0 A2 I3 ^* D
- FillRect(v18, &rc, v25);: U& g6 N- I5 H/ c- F, G
- SetBkColor(v18, 0);' s2 }1 |5 c0 K( \
- SetTextColor(v18, 0xFFFFFFu);5 K/ `& o# r( P0 i
- SetBkMode(v18, 1);
4 q3 K! e. s2 {. }0 e - v26 = 1;
' g, c, N5 B8 N8 u8 b# f: \ - v41 = 1;
4 C2 C& f5 ?: y c" ]6 s5 q6 s - v40 = 0;+ M: w! V2 X0 e3 a. v: h
- v43 = 0;/ b H: t. q1 W e, e+ u7 _! r
- if ( *((_DWORD *)v11 + 4) > 0 )
# i; o" F |5 o- ]" i' P - {3 d4 Y6 }9 ^5 X5 [5 I% b
- v27 = WideCharStr;: M# Z) l$ X. ~% E# i! w' k5 l
- v44 = 0;
0 M c6 e' q# j J8 c/ x - v42 = WideCharStr;
2 a1 }1 R# ? J - v49 = (double)xRight;
$ R& d9 }4 y% ^ U& I9 e. @/ S - v50 = (double)yBottom;1 G! [2 X/ k8 X+ X! V0 s
- while ( 1 )
& n2 x* j3 S6 Z _ - {; ?% b J- A' z
- v28 = v44 + *((_DWORD *)v11 + 5);
* t- K2 k S, Z3 h - *(_WORD *)(v28 + 16) = *v27;
" U4 O" y2 p+ o& O4 X. I5 B - GetCharABCWidthsW(v18, *v27, *v27, (LPABC)(v28 + 20));
3 F0 v5 G$ {+ y* A% T [ - if ( *v42 >= 0x20u )
( b. `9 r' e9 p# z& \% C c- s - {
+ [$ d4 h, W7 C! d3 l - --*(_DWORD *)(v28 + 20);
) R6 z2 N- g6 B - *(_DWORD *)(v28 + 24) += 2;
- y! M; r- y" i" R - --*(_DWORD *)(v28 + 28);3 z8 X3 a+ ?$ T& e# O3 A
- }7 O9 ]& |2 X0 i! U9 C. w+ ]
- else
7 P3 V5 M: D" a - {5 g. h7 e# I* n% f7 E
- *(_DWORD *)(v28 + 20) = 0;
4 p! W0 A* j4 [1 Z0 l0 A' I% P - *(_DWORD *)(v28 + 28) = 0;, C5 \. O" y3 C9 L1 d
- }5 H" n2 y# k& w: w/ J% [4 E
- v29 = *(_DWORD *)(v28 + 24);
# |( [+ {* n% ]# |8 y% V - v30 = v40;
# O y/ E7 q0 x - if ( v29 + v26 + 1 >= (unsigned int)xRight )
z+ j5 a, y" L# I/ C% w$ U+ ? - {
8 H, P. o4 H" Q) U6 @! w- S8 K$ p - v26 = 1;5 z+ N0 l2 {0 y
- v30 = v40 + *((_DWORD *)v11 + 3) + 1;
) i3 B' }2 c t+ h6 j# h' L: [ - v41 = 1;
0 s6 |$ Q( X$ m: L' |- h! x( G - v40 += *((_DWORD *)v11 + 3) + 1;+ H0 Z8 K) E- \: p6 f8 R
- }% U3 p2 s7 s3 Z, H5 a$ ]
- *(float *)v28 = (double)v41 / v49;
/ s; w. d2 f, p5 ~4 ^# y! ^ - *(float *)(v28 + 4) = (double)v40 / v50;. m7 c; x- E; {- }" d& C
- *(float *)(v28 + 8) = (double)(unsigned int)(v26 + v29) / v49;" ?. k; j, ~: H# M( O0 a
- v31 = v26 - *(_DWORD *)(v28 + 20);
& r; T: _" x* d9 M* @! ~' a - *(float *)(v28 + 12) = (double)(v30 + *((_DWORD *)v11 + 3)) / v50;
; B( z x# r( n+ v( N - TextOutW(v18, v31, v30, v42, 1);' k. o6 x! r, l+ m" Q: r6 y
- v44 += 32;7 S5 y9 W8 e1 l6 ]( n
- ++v42;, @2 a; I% W( Z( L! H8 W
- v33 = __OFSUB__(v43 + 1, *((_DWORD *)v11 + 4));
8 m3 {, W7 t! ?7 S# c - v32 = (signed int)&v43[-*((_DWORD *)v11 + 4) + 1] < 0;
- O" B+ I T% M$ p0 _, o - v26 += *(_DWORD *)(v28 + 24) + 1;
) ~1 U; F: w7 |+ ~/ x+ O" \ - v41 = v26;
7 X3 F( b. M& f B - ++v43;
% C8 j/ N7 R4 |7 u% B5 O - if ( !(v32 ^ v33) )
- b# [" ?4 `+ @5 U2 q9 L9 J - break;7 I$ R7 M7 t0 ~/ x& z" r: D. G
- v27 = v42;. f J1 @. h% z- ]& d$ M
- }8 ]+ c7 j. C! k6 V5 n+ l K
- }
' }' g, h. z1 Z, m5 I h - v34 = CKBitmapData::LockSurfacePtr((CKBitmapData *)(*((_DWORD *)v11 + 6) + 56), -1);
+ p8 E% s. C$ w8 s4 J7 o5 D6 u - if ( v34 )
4 P0 w' `2 O; b! C" _ - {; c) `$ ^" Y& U
- GetObjectA(v45, 24, &v51);+ K: m s' W8 Z, V) N
- v35 = v53;7 O: ~3 J/ }+ C% N, W2 o4 w3 _
- v36 = v55 + v54 * (v53 - 1);
' j4 Q, N- N% t* O - v40 = 0;
) f: h* N9 c1 z- e+ h* X - if ( v53 > 0 )
3 ~% B3 L3 y, M8 U% ], t+ ? - {
8 s. y0 ~/ c X/ ^ - v37 = v52;6 P* {7 R5 |* \& P0 ~
- do
4 D; [. Q/ r( b3 h4 B - {
( x% }3 I; w# E8 a' B, D: p - v38 = 0;, `) L2 Q, L) R) _! ]5 w+ W) V+ D4 C
- if ( v37 > 0 )
( H" ?4 @9 S5 f3 y' D4 N+ r& g - {
# `& |# R s) h- {, Y - v39 = (unsigned __int8 *)v36;
8 T1 D% U! l# u7 r9 m% Z* O% D - do8 m! e; \& s. F0 }& n
- {6 f) E7 b3 J0 r+ O1 \
- *(_DWORD *)&v34[4 * v38] = (*v39 << 24) | 0xFFFFFF;
" P& ~/ a( n9 E7 K" ~4 E - v37 = v52;4 V- s( C2 w4 {( d8 K$ \) M' Y9 n
- ++v38;# E# I0 S+ n5 n0 O2 d
- v39 += 3;
: Q9 B9 Y" x C8 k0 N! c - }
. X0 g/ l+ `; x9 H0 X4 G; o - while ( v38 < v52 );
. E) F0 J. Q' |7 I+ q5 d - v35 = v53;
6 L* }4 l3 x) m' F - }
# E8 Z! ~, Q+ N - v36 -= v54;
4 b: [& B4 p* h* S2 k- @ - v33 = __OFSUB__(v40 + 1, v35);+ c, H0 f% L/ k9 V
- v32 = v40 + 1 - v35 < 0;
& v* K7 q' b4 G3 Q. | - v34 += 4 * v37;5 K# b0 ^; x$ c: ^
- ++v40;
9 e2 B7 j4 w" P) K, J2 Q# l- u1 _5 B3 d - }
0 E: P$ h' f8 {* Z6 v# H# \' R @ - while ( v32 ^ v33 );
7 ? \- E* K7 u - }, v3 e B- Z, a" r- k* |
- }2 p4 B4 c0 i1 d2 o
- CKBitmapData::ReleaseSurfacePtr((CKBitmapData *)(*((_DWORD *)v11 + 6) + 56), -1);' N7 C* b' c5 e! T& j/ F! j9 i
- SelectObject(v18, v46);
: _6 M% L! A8 g2 C" c" J8 \ - VxDeleteFont(v48);& i" ^' X' Z! E' @7 d( G
- SelectObject(v18, v47);. g$ d' V1 N/ s- u/ {& f
- VxDeleteBitmap(v45);
6 y, O1 V/ P" H; ]+ b - DeleteDC(v18);4 B. C9 o8 E2 d2 p& S
- CKObject::SetName(*((CKObject **)v11 + 6), (char *)a3, 0);
6 L3 K+ K: P3 {2 e3 M - CKBitmapData::SetDesiredVideoFormat(*((_DWORD *)v11 + 6) + 56, 1);0 Y2 z7 M# q# C5 [. E
- (*(void (__stdcall **)(_DWORD))(**((_DWORD **)v11 + 6) + 120))(0);9 }" b+ N$ Q) b, W7 R
- return v40 + *((_DWORD *)v11 + 3) < yBottom;& ]6 m& h6 e) e; Y9 v* A" C4 j
- }
" z) \9 Z/ i) [$ x8 Y, _ p" W
复制代码 / Z) G& F9 S7 n! @
- V" ^0 Y( Y% k- O; b, a2 ]2 W
|