本帖最后由 shane007 于 2023-8-26 17:10 编辑 ( g- Y& { P o2 r2 g6 U
* _+ c8 T8 I. b/ S- H' t0 q6 k
这个游戏的主要修改点在\player\BuildingBlocks目录下的Adventure.dll中。' R& K1 P5 b8 }/ ~$ O
用API monitor对本DLL的CreateFontA函数进行跟踪,发现确实有调用, 参数如下。4 z ~/ O" k6 ?. d0 M$ b6 w
. Z1 w$ z' G$ e( c* ^( h( e) j/ [- # Type Name Pre-Call Value Post-Call Value$ u/ q1 k) v" Q$ w! Z; O) F
- 1 int nHeight 0xfffffff0 0xfffffff0; N: X3 `) u6 p6 @" T: |6 j
- 2 int nWidth 0x00000000 0x00000000
- J9 V: b! A* G+ H - 3 int nEscapement 0x00000000 0x00000000% p3 \+ A# X) {+ b2 ~( G+ m' {
- 4 int nOrientation 0x00000000 0x00000000
# n1 S) f3 K& K. v" w - 5 int fnWeight FW_NORMAL FW_NORMAL
8 f) f/ S( L9 v+ K2 b( C4 T - 6 DWORD fdwItalic 0x00000000 0x00000000
: R) @5 y& q# ^1 i! a9 o5 X4 ] - 7 DWORD fdwUnderline 0x00000000 0x00000000
h7 C8 V6 c* A' I/ A9 J8 y. I - 8 DWORD fdwStrikeOut 0x00000000 0x00000000
4 {+ P1 D, `1 }; \( ^6 Z - 9 DWORD fdwCharSet DEFAULT_CHARSET DEFAULT_CHARSET
2 D4 P& M& @" m( I: L) x - 10 DWORD fdwOutputPrecision OUT_TT_ONLY_PRECIS OUT_TT_ONLY_PRECIS1 y' `- ]6 K2 E/ C' o
- 11 DWORD fdwClipPrecision CLIP_DEFAULT_PRECIS CLIP_DEFAULT_PRECIS4 C& Q3 M' w; S6 ^4 \: }$ t
- 12 DWORD fdwQuality PROOF_QUALITY PROOF_QUALITY
$ W( K! Z+ \" o, y3 e - 13 DWORD fdwPitchAndFamily FF_DONTCARE | DEFAULT_PITCH FF_DONTCARE | DEFAULT_PITCH
: j% b) A- ~: ]+ @7 p: S - 14 LPCTSTR lpszFace 0x09148a58 "Arial" 0x09148a58 "Arial"
8 H1 o3 K9 L7 s$ g- I
复制代码
' D9 v' ~7 Y% J& o
, M9 E; b/ w T0 Y用ida pro找到调用CreateFontA的源头函数如下。" H* O( o- k* s# g
从函数的参数可以看出,这应该就是字幕显示函数了。0 {6 H7 z+ w7 P4 g$ h
关于后续修改,先修改CreateFontA函数的fdwCharSet,lpszFace这2个参数,也许就能出中文。
2 y/ U& N9 R9 e8 {还不行的话,就自己写一个显示函数。以下函数中lpMultiByteStr就是指向字幕的指针。
* F5 Q' K, y( W$ r0 N, D4 n- 8 I5 W, F' S( b2 K! u1 {2 }
- 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)
8 u2 Z2 Y; c# f5 V, b9 ?5 b1 a& v - {& i8 B$ w: b1 d6 L- X
- void *v11; // edi
* d; C6 q9 t: V0 M - int v12; // eax
) ]1 c9 s K9 O0 z" p$ m) ~' o5 J3 g - int v14; // ecx
! N t" J' `$ A5 ?! n - int v15; // eax! C7 y. u0 I3 q7 w4 A
- char *v16; // eax% I2 ~* u, z4 @1 p
- int v17; // eax! L! O: p/ c8 D6 B4 l% e; D
- HDC v18; // ebp" @; I8 K; y/ x% R8 l
- int v19; // eax
5 ^0 w6 G* S8 [ - int v20; // eax$ P- I- U/ \: l, u7 l
- int v21; // esi
3 n7 G r' i9 z& Q% ~7 I5 q - char *v22; // eax+ c# W- o K8 Q- h, X1 L
- int v23; // esi( c5 w* _5 U% q% f
- int v24; // ecx# {( z" P7 w6 c, Z" ~
- HBRUSH v25; // eax
1 V# ?- [( v! [* `" i - signed int v26; // ebx# X8 P" b3 v6 J, k) p5 }
- WCHAR *v27; // eax
) r9 F# h* V" s9 { - int v28; // esi
- U; e1 N1 @ ]+ |/ Q - int v29; // ecx
6 p3 b" f2 l3 D6 r - int v30; // eax
# t7 N& A* R2 I0 p. Y% U: _* \" h - int v31; // ST28_4: w4 j5 a ^, J7 i& r( n
- bool v32; // sf4 \8 z9 I/ |* W# M) Y2 S' d1 e8 R
- unsigned __int8 v33; // of
8 R5 ]6 D5 I+ c+ h# S - unsigned __int8 *v34; // ebx
, t0 A; _! c3 k4 c - int v35; // ecx
+ }5 k' g2 ?/ l - int v36; // esi* ?+ }3 Q- o) q& q
- int v37; // edx' L6 L: y1 V. w$ G1 B K
- int v38; // eax
* G- |2 y: ^5 C4 m" p8 R' X2 ~ - unsigned __int8 *v39; // ecx
( _7 `5 k" _% O - int v40; // [esp+40h] [ebp-2098h]
7 [2 ^$ {8 l1 C7 }7 I, H- w5 ~ - signed int v41; // [esp+44h] [ebp-2094h]8 H2 b" m K. p$ T
- WCHAR *v42; // [esp+48h] [ebp-2090h]$ E: y: A q# }4 {% g% E
- LPCSTR v43; // [esp+4Ch] [ebp-208Ch]
' Y, I) c. Q6 S7 H( t/ h: I: s - int v44; // [esp+50h] [ebp-2088h]3 B( `1 L/ M$ E+ ~
- HGDIOBJ v45; // [esp+54h] [ebp-2084h]
7 n5 o( I. s6 \6 t, W - HGDIOBJ v46; // [esp+58h] [ebp-2080h]. T5 x! p8 |4 c4 u9 x% S
- HGDIOBJ v47; // [esp+60h] [ebp-2078h]; `2 g; c, O! P5 |/ W, l
- HFONT v48; // [esp+64h] [ebp-2074h]5 K5 x( `' O3 Q: B5 A3 j: r, D
- float v49; // [esp+68h] [ebp-2070h]: L, I# @( k! i7 J2 n+ c& x3 z
- float v50; // [esp+6Ch] [ebp-206Ch]
8 d! s2 k' e. Z6 U - char v51; // [esp+70h] [ebp-2068h]
2 H) Y2 i ]( p& e4 @- I- y - int v52; // [esp+74h] [ebp-2064h]
& I* t3 R; O4 x - int v53; // [esp+78h] [ebp-2060h]: R* x8 }; \3 N g1 R% [
- int v54; // [esp+7Ch] [ebp-205Ch]
- A" N) D% K0 \8 h0 L3 l+ Q4 M - int v55; // [esp+84h] [ebp-2054h]
- `; a2 E9 I3 R) Q/ ^ - struct tagSIZE v56; // [esp+88h] [ebp-2050h]2 W# |( h$ |# W2 q9 i" j: ^7 l
- struct tagRECT rc; // [esp+90h] [ebp-2048h]- t. S" Z6 \" b; p
- int v58; // [esp+A0h] [ebp-2038h]. p" d0 w) J0 `- o! j- u. l
- char v59; // [esp+A4h] [ebp-2034h]% {5 U* g# T0 b
- WCHAR WideCharStr[4096]; // [esp+D4h] [ebp-2004h]& @1 |! Z+ J2 N% I' H3 y! S% }
4 F4 V( `8 w0 b) ?2 M3 L- v11 = this;
! L# ]5 t( R, F1 y7 ?3 _ - v58 = 52;
/ n) \; j [- J& ]' E* l! q, I( `$ } - memset(&v59, 0, 0x30u);2 F y% v, Y: i, D: W
- if ( *lpMultiByteStr )
+ A. g5 P( S: c. d$ H - {1 W m9 R5 }/ z9 P' _
- v12 = MultiByteToWideChar(0xFDE9u, 0, lpMultiByteStr, -1, WideCharStr, 4096);
, P$ Y0 K1 f6 n* g8 Y. ^ - *((_DWORD *)v11 + 4) = v12;5 d2 o" s( U4 I. A5 H/ Z0 [
- if ( v12 <= 1 )
1 C5 `) T! t! \# G9 m" `" b) v - return 0;5 O: Z$ w9 r7 N
- *((_DWORD *)v11 + 4) = v12 - 1;* [, r) ?* N5 k' Q/ g3 y9 C
- qsort(WideCharStr, v12 - 1, 2u, sub_10057A40);
' R8 F1 U# ^# }8 ?1 s - }) {0 u J* I @6 X& n H
- else/ M; _0 |# K, x& j! A$ W6 T
- {1 {/ f/ O3 S; c( }1 J) L
- *((_DWORD *)v11 + 4) = 352;
* ^& K8 L# b4 ^/ x$ J - v14 = *((_DWORD *)v11 + 4);
8 Z8 l2 {/ Y3 @: \ - v15 = 0;
/ ], p& \" `, Z - do
" k5 @: c4 C$ T! d+ k- O - {. n' k$ P) h! R
- WideCharStr[v15] = v15 + 32;' `: s( Q3 L% J$ |8 Z# \
- ++v15;, G8 S" q' Q: F7 R* u2 C9 _
- }5 Q& J# \6 b- V* {1 R: y
- while ( v15 < v14 );
5 V! z2 C( Y/ E- w' a - }
5 R* D- [: c" Z' V! U - v16 = *(char **)v11;
# ?$ w. @. V6 `% ?) h - if ( !*(_DWORD *)v11 )
7 c7 D; n7 @. E1 _; o' p v; K/ u' ` - v16 = byte_100B2D6E;
$ G# R0 G0 ^; b% `. _" M# u - v17 = CKContext::CreateObject(a2, 31, v16, 0, 0);
+ u$ Z: B+ G; K) G' C$ R7 P - *((_DWORD *)v11 + 6) = v17;: _7 s3 |4 B ]4 u" K) j7 [) d5 C
- if ( !(*(int (__thiscall **)(int, int, int, signed int, _DWORD))(*(_DWORD *)v17 + 84))(v17, xRight, yBottom, 32, 0) ), [% M. U, h8 B7 B6 k$ y
- return 0;
6 s6 s; \# b7 d+ w0 V4 l; k - (*(void (__stdcall **)(int *))(**((_DWORD **)v11 + 6) + 136))(&v58);+ o/ a3 p9 n7 n N; g/ _
- v18 = CreateCompatibleDC(0);9 c$ S( D5 l) M: j6 P
- v45 = VxCreateBitmap((const struct VxImageDescEx *)&v58);. y7 J6 _3 x4 z1 w l* d+ T# D9 o8 K; e
- v47 = SelectObject(v18, v45); T7 |1 c& l4 N' J
- XString::operator=(v11, a3);
5 e8 s: V: _1 p7 e' ~# U - *((_DWORD *)v11 + 2) = nNumber;, C T/ P8 ~0 |# `
- v19 = GetDeviceCaps(v18, 90);( J# `( ~! T7 }+ o- x
- v20 = MulDiv(nNumber, v19, 72);
7 q- D7 f1 ~' ^, ? - v48 = CreateFontA(-v20, 0, 0, 0, a6, a8 & 1, ((unsigned int)a8 >> 1) & 1, 0, 1u, 7u, 0, a7, 0, (LPCSTR)a4);% ?, K" U: h5 f
- v46 = SelectObject(v18, v48);
' m5 s# J6 P9 `2 x- `. y6 R - GetTextExtentPointA(v18, "A", 1, &v56);, S+ }3 W5 H4 i$ i/ |# I* m& B
- v21 = *((_DWORD *)v11 + 4);
* |: c$ l G' `0 v/ X - *((_DWORD *)v11 + 3) = v56.cy;; J( E9 O$ @/ d' f S% w
- v22 = (char *)operator new(32 * v21);
( E. }6 Y# |* }2 y8 k - if ( v22 )
$ ^$ L, M) }0 k: E) M" D! ` - {7 `/ P, B" x4 p1 w
- v23 = v21 - 1;
+ \6 L' `, B6 m3 T- v2 N - if ( v23 >= 0 )% r! t9 @8 u5 |6 ]/ Y
- {
6 E2 x- ]- U1 C* ^ - v24 = (int)(v22 + 12);
# I' m3 w, h9 N( h. Y% t - do3 z" @% a! ?3 X* w
- { [; b! B3 Z B5 K
- *(float *)(v24 - 4) = 0.0;: a6 ~1 W1 ]4 a; A* {& M0 s5 c
- v24 += 32;
; P# y8 l: b" z+ q$ w! g - --v23;
5 Y, G6 D! ]7 p: }7 R! t& c7 k - *(float *)(v24 - 32) = 0.0;+ t, u) T0 f: s4 _
- *(float *)(v24 - 44) = 0.0;
" [- A w: v. D% ^4 R4 n3 ` - *(float *)(v24 - 40) = 0.0;
& ~( \( _; M4 a8 b - *(float *)(v24 - 36) = 0.0;
1 [+ W v* a4 r+ U6 h0 t- n: M- C1 v# y - *(float *)(v24 - 32) = 0.0;
& i% d: W* U9 { - }9 f1 O/ `3 k5 I9 u
- while ( v23 >= 0 );
+ n9 u& m" Y+ [/ t* j1 Y - }
7 ?- \! g& }# \ - }% K1 E5 Z2 ]9 p' A0 f e
- else. w. W9 w5 I- I; O& N2 R1 w( W/ Y
- {
; Q2 |4 i9 t% I' V - v22 = 0;
& P! m: J2 r7 E8 N% F - }
; N' f6 B e1 i4 T7 T - *((_DWORD *)v11 + 5) = v22;
$ L% @& F$ `; {0 }" _+ w1 G - SetRect(&rc, 0, 0, xRight, yBottom);
7 L6 A. D/ o- m6 [ - v25 = (HBRUSH)GetStockObject(4);
: K+ P e, T& r( I; L1 G% l, f" O - FillRect(v18, &rc, v25);: T4 O+ h6 U) V: |. g6 }
- SetBkColor(v18, 0);
3 X* k) g5 d6 A4 @( o/ _; L - SetTextColor(v18, 0xFFFFFFu);
/ ?6 k! f$ d" |* u5 y3 W! @0 D ]8 d. C8 E - SetBkMode(v18, 1);; T( S2 L+ N- L
- v26 = 1;2 @: n1 D- w! B. Z8 t7 @5 X
- v41 = 1;
% M9 l/ r7 D" ` - v40 = 0;
6 x" z/ h# ~# Z- D% z2 i6 ]% N - v43 = 0;
$ g8 E" j/ }+ L9 `- D4 f - if ( *((_DWORD *)v11 + 4) > 0 )6 z( ?3 \, f) U6 E( c& l5 a
- {
. b t+ A s- ~, | - v27 = WideCharStr;
: H- f0 Z! D9 X1 h5 i' T' r - v44 = 0;
" n3 R, `( h; z5 A - v42 = WideCharStr;
% H$ Y2 `/ y: M$ U) P - v49 = (double)xRight;
* g2 a( e) T/ y7 R8 c0 r, u4 n - v50 = (double)yBottom;/ J" k$ o, x1 A2 c4 A. s
- while ( 1 )
% t: v4 [' o! e* j$ s' p - {
$ L0 D& d3 ^2 L/ z9 D* l) { - v28 = v44 + *((_DWORD *)v11 + 5);' d8 N& ?. B1 m% ?; h+ c
- *(_WORD *)(v28 + 16) = *v27;( @+ J% ~& v! [9 X4 O) M( u3 |" M
- GetCharABCWidthsW(v18, *v27, *v27, (LPABC)(v28 + 20));7 G* c" t# b" ] K. u3 Y# R
- if ( *v42 >= 0x20u )
$ I/ X. f2 f" a% E, Q$ Y9 R - {; e$ {* _9 j9 [) I. y& |, U6 j
- --*(_DWORD *)(v28 + 20);9 M" j5 u M$ d. @! ]& t, _
- *(_DWORD *)(v28 + 24) += 2;
2 I6 @( `. L! u0 w - --*(_DWORD *)(v28 + 28);
. Z* \" S6 L0 { - }
# ?9 z3 `5 |5 K$ G5 ?2 b \ - else
! C( Y8 [+ o# i" ^1 `- s2 @0 C+ Z5 E - {9 [; X- J' Z- W* ?* ?
- *(_DWORD *)(v28 + 20) = 0;+ t! J( b. ^0 v( _+ ~2 c' G
- *(_DWORD *)(v28 + 28) = 0;
$ J9 [3 q4 m1 \5 W# [ - }1 o, K& F' ]* |1 h/ j
- v29 = *(_DWORD *)(v28 + 24);+ [( d2 p# }* [1 E9 X. \
- v30 = v40;, n$ z3 ]$ U: N \& A7 L- B, q
- if ( v29 + v26 + 1 >= (unsigned int)xRight )9 }! S1 w) a+ s0 o9 z N; z4 ~
- {, D) `# J8 n; j) y
- v26 = 1;' M9 h) X K V) F. c
- v30 = v40 + *((_DWORD *)v11 + 3) + 1;4 s' f+ C4 I. m9 [
- v41 = 1;' W2 U9 k! w* R: f F& V
- v40 += *((_DWORD *)v11 + 3) + 1;0 }- t* y6 j# }# L8 m4 H- U
- }: z) ]2 t4 d1 |
- *(float *)v28 = (double)v41 / v49;) I0 i0 t/ Q2 E, P5 v/ H
- *(float *)(v28 + 4) = (double)v40 / v50;
+ r* ]4 z" N) ^; I - *(float *)(v28 + 8) = (double)(unsigned int)(v26 + v29) / v49;
0 z8 H( m' r8 W$ S" T1 B o - v31 = v26 - *(_DWORD *)(v28 + 20);' S" V3 d* O: \) \4 }$ b- i2 ?! H
- *(float *)(v28 + 12) = (double)(v30 + *((_DWORD *)v11 + 3)) / v50;" \' ], m9 T8 w, p# ~+ b3 F8 Q
- TextOutW(v18, v31, v30, v42, 1);4 {' P# H' U) h- X
- v44 += 32;% @( w$ i4 z# T& q6 q
- ++v42;$ l" V0 d: A% A$ u; {! ~# L; c
- v33 = __OFSUB__(v43 + 1, *((_DWORD *)v11 + 4));
, t+ i9 ?* D7 R! ] - v32 = (signed int)&v43[-*((_DWORD *)v11 + 4) + 1] < 0;0 Q5 k9 g7 B& c
- v26 += *(_DWORD *)(v28 + 24) + 1;
9 E$ j6 \1 A2 b0 ~- `8 N5 R$ O - v41 = v26;4 m6 N" R3 p* j7 a
- ++v43;2 D' D4 Z4 l* T# k. c$ ?7 Y& H
- if ( !(v32 ^ v33) )) b% X/ ]. p: [% l" c
- break;/ `+ e6 Z$ Z0 O, z; X% b" L
- v27 = v42;" b: c/ _( B, N1 G! s2 L
- }
0 i' l6 u, }. C0 Z/ o3 a1 k9 p - }5 A. `# s* v: ?' B% d% C
- v34 = CKBitmapData::LockSurfacePtr((CKBitmapData *)(*((_DWORD *)v11 + 6) + 56), -1);
+ `- ?1 z- g! o" s e* A, V3 [ - if ( v34 )7 [/ I+ D( [6 p+ I4 d
- {5 N) g6 z l7 s
- GetObjectA(v45, 24, &v51);
2 F+ M4 R( M9 x6 Y& P; ]* Q - v35 = v53;
$ _+ I ]$ ?1 M0 H - v36 = v55 + v54 * (v53 - 1);
% u9 K* Z" y' @$ k+ Z - v40 = 0;7 M% \6 V& y) d+ X. n
- if ( v53 > 0 )0 t3 E2 {" U7 w3 Y, L
- {6 K* a [8 G" F, y5 W; ~- W
- v37 = v52;: G; \3 d, a% S& F
- do$ O- c# ]+ g U; g2 f; |
- {
3 N& m1 ] k* V - v38 = 0;- V! c6 _) ?2 s: Y) N; n! h
- if ( v37 > 0 )
/ j1 T( n3 S z - {
' T) f' u. f; p+ i: H7 b' K - v39 = (unsigned __int8 *)v36;' O+ P9 U9 \8 ^. I
- do
' n4 ]6 ], ^% S - {2 x* J; c! v F& l5 H! P _9 p
- *(_DWORD *)&v34[4 * v38] = (*v39 << 24) | 0xFFFFFF;7 d5 [/ r d8 d% t. \
- v37 = v52;6 |5 Y# `, z b& V: Q X! I
- ++v38;$ P2 {$ M* q) w( Y, v6 G
- v39 += 3;" u$ }' C; h8 y' s8 l: k5 d! j
- }: s* v& |5 k$ F* f
- while ( v38 < v52 );3 [& `* B3 z1 y4 @
- v35 = v53;
0 I, F6 k6 ]0 d8 q* Y* r - }
* w. @" y! u8 \, [& v3 f. p - v36 -= v54;
K. Q9 ~& d4 K) w - v33 = __OFSUB__(v40 + 1, v35);
$ s0 K7 m4 L. y& Z - v32 = v40 + 1 - v35 < 0;: B) T0 V6 l6 z7 z
- v34 += 4 * v37;
4 @. X9 l9 w2 i$ E - ++v40;
7 x; ]/ D7 N- p) \5 c* ` - }6 t# C# t+ ^, Y; @
- while ( v32 ^ v33 );
' ~; p) B0 W% k4 H, c - }
8 b$ o! N, S( L( `. u1 ^/ s - }/ e( {0 ?- r7 Q+ p$ B
- CKBitmapData::ReleaseSurfacePtr((CKBitmapData *)(*((_DWORD *)v11 + 6) + 56), -1);
3 {& T* @, h: D1 Z5 U v$ n0 U8 P - SelectObject(v18, v46);# u7 f; h9 D! `8 ^. s" |9 Y
- VxDeleteFont(v48);
- Y$ b, k: h! P4 f - SelectObject(v18, v47);
7 ~$ K0 q# O6 H4 y% u# T; m - VxDeleteBitmap(v45);% k# a! m, _6 _+ K5 o
- DeleteDC(v18);4 s0 }7 X$ `8 A! j) ^
- CKObject::SetName(*((CKObject **)v11 + 6), (char *)a3, 0);
4 D( m5 E7 ~5 R) T4 V. Y8 { - CKBitmapData::SetDesiredVideoFormat(*((_DWORD *)v11 + 6) + 56, 1);( s9 r# p# I% x/ @/ a
- (*(void (__stdcall **)(_DWORD))(**((_DWORD **)v11 + 6) + 120))(0);
' T( e2 m( ]) `" f - return v40 + *((_DWORD *)v11 + 3) < yBottom;
, j1 @/ Z& K2 ]) x' M - }5 A. B, } S# U" X8 _ r$ A
复制代码 , h, o4 i6 [* j6 X4 Y; Q6 F
0 R' R: a7 p7 C1 r" @) m" k |