本帖最后由 shane007 于 2023-8-26 17:10 编辑 ! E% p! E0 V6 Q9 d
0 k( m" U: x0 m这个游戏的主要修改点在\player\BuildingBlocks目录下的Adventure.dll中。
5 B; D r: L- C5 T用API monitor对本DLL的CreateFontA函数进行跟踪,发现确实有调用, 参数如下。" m; K2 |3 q2 m& Y5 ^
' L$ `0 A3 n4 V4 y% p, P M1 X- # Type Name Pre-Call Value Post-Call Value5 h- `8 _; B1 N' n9 S
- 1 int nHeight 0xfffffff0 0xfffffff0% Z5 t/ F: P" N! l7 D+ K! G
- 2 int nWidth 0x00000000 0x000000003 U6 o6 x! M7 Q( c/ U0 Q7 X& D
- 3 int nEscapement 0x00000000 0x00000000" u8 U) [" C4 A) i2 Q" h% O
- 4 int nOrientation 0x00000000 0x00000000
7 f8 @* J4 s$ W) S" U& _ - 5 int fnWeight FW_NORMAL FW_NORMAL1 H" r6 k$ g: D8 h' O0 P2 n0 r
- 6 DWORD fdwItalic 0x00000000 0x00000000( p7 Y0 B# s+ o" u6 z- d# O9 }! g4 C
- 7 DWORD fdwUnderline 0x00000000 0x000000001 h2 D( F7 [, M+ P7 T2 u2 p) C
- 8 DWORD fdwStrikeOut 0x00000000 0x00000000! g$ p8 a% u x- K
- 9 DWORD fdwCharSet DEFAULT_CHARSET DEFAULT_CHARSET
+ ~! O3 s, J2 @ - 10 DWORD fdwOutputPrecision OUT_TT_ONLY_PRECIS OUT_TT_ONLY_PRECIS
! S2 }7 B* s, W: P( [ - 11 DWORD fdwClipPrecision CLIP_DEFAULT_PRECIS CLIP_DEFAULT_PRECIS
$ J6 _1 e! T' v; J - 12 DWORD fdwQuality PROOF_QUALITY PROOF_QUALITY
3 b( e5 m. X9 Q - 13 DWORD fdwPitchAndFamily FF_DONTCARE | DEFAULT_PITCH FF_DONTCARE | DEFAULT_PITCH
9 J+ T R" O5 j - 14 LPCTSTR lpszFace 0x09148a58 "Arial" 0x09148a58 "Arial"
3 f0 x- v) Z G" A( \* S/ U" u
复制代码
1 Z8 C- Q: b" y7 {% K$ z' @$ N: [( b
用ida pro找到调用CreateFontA的源头函数如下。) x( L9 ~7 M! E+ W( W5 l
从函数的参数可以看出,这应该就是字幕显示函数了。
+ }3 L K$ d# \4 ]7 Y关于后续修改,先修改CreateFontA函数的fdwCharSet,lpszFace这2个参数,也许就能出中文。3 L6 ^7 _1 {& Q0 g0 h+ n$ r& f( M
还不行的话,就自己写一个显示函数。以下函数中lpMultiByteStr就是指向字幕的指针。 d, \3 L: n& o+ l* c
- 0 J0 {' c& X* j7 w' @
- 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)
H, W7 T6 O! q0 C5 ` - {
, T6 {' l5 v% v! Z - void *v11; // edi
3 z* ]# p( N8 i1 H, E% V - int v12; // eax t2 J7 | v' g7 v2 E
- int v14; // ecx6 n% {" V+ A$ o2 c2 e
- int v15; // eax
2 X* J/ G+ ~4 [6 o( `. Q$ u - char *v16; // eax
0 P( d# a( z5 k; y E - int v17; // eax
4 l1 k! P+ m2 \: W1 d4 ^ - HDC v18; // ebp
5 B- t- [# C) w - int v19; // eax
+ x! K( E1 A ^7 X. V - int v20; // eax6 h5 o3 |( t; x* e. ~* ? P
- int v21; // esi
0 k9 f3 j1 Y( M - char *v22; // eax# F" h: R( [& m0 _$ |8 P( {4 x
- int v23; // esi% u: }% {" Q ?! O
- int v24; // ecx. o$ F: X: U! M/ x. k, q2 d
- HBRUSH v25; // eax# Q% t/ K* n0 ^/ N
- signed int v26; // ebx
7 L. M; u3 D8 A0 @+ _ - WCHAR *v27; // eax* v% c. Z8 n. U& @; r+ ?! A, z; z
- int v28; // esi
9 V' ^. v0 E1 | - int v29; // ecx3 _7 U8 J {' s: @+ S
- int v30; // eax
3 F- l4 x. M7 T - int v31; // ST28_4
: c- E3 }! y' Q6 J9 m, |( ? - bool v32; // sf
5 A' C9 B- u: `" m- P3 R8 A - unsigned __int8 v33; // of
) `: Q* Q9 R+ A. S - unsigned __int8 *v34; // ebx6 T& R/ K5 O* s* x, I W
- int v35; // ecx& f/ g5 X. k- Z- v8 ~8 U8 P# x3 u
- int v36; // esi
! ^6 Q$ T2 K, Y; P2 C$ b - int v37; // edx
- N- b* @5 x: Y5 V - int v38; // eax
1 s* S7 T0 J2 C2 v: I- s# ~% X! e - unsigned __int8 *v39; // ecx
7 `7 W: w1 |6 T* H& m7 F - int v40; // [esp+40h] [ebp-2098h]
, @; f5 y z9 @" U7 X - signed int v41; // [esp+44h] [ebp-2094h], K. f( y# q9 ~
- WCHAR *v42; // [esp+48h] [ebp-2090h]. G, Y' J& A" S
- LPCSTR v43; // [esp+4Ch] [ebp-208Ch]
# {0 B2 k& V3 C# _5 Q& x - int v44; // [esp+50h] [ebp-2088h]
! z7 q# y! M+ G; L - HGDIOBJ v45; // [esp+54h] [ebp-2084h]
* G2 I/ S) V$ A; K3 V- W - HGDIOBJ v46; // [esp+58h] [ebp-2080h]; |3 P+ Y* ^2 G! x
- HGDIOBJ v47; // [esp+60h] [ebp-2078h]
+ M+ T! J/ V8 X4 H( c$ l3 A, n0 K+ s - HFONT v48; // [esp+64h] [ebp-2074h]
) p$ P6 W, {. u) M3 q) y" Y# ? - float v49; // [esp+68h] [ebp-2070h]& b3 q, t8 a( _$ B8 c
- float v50; // [esp+6Ch] [ebp-206Ch]
1 ], }7 R. f" I$ X" K, [: v Q - char v51; // [esp+70h] [ebp-2068h]+ s1 Y) _4 l0 B* H) ?$ K
- int v52; // [esp+74h] [ebp-2064h]
3 n' ?% L$ k7 }% d - int v53; // [esp+78h] [ebp-2060h]! p1 g( |. o% M @0 Y
- int v54; // [esp+7Ch] [ebp-205Ch]
/ @, d8 G& |2 P - int v55; // [esp+84h] [ebp-2054h]" f! |8 K7 F7 E2 a7 x* b
- struct tagSIZE v56; // [esp+88h] [ebp-2050h]
* q) |8 w& x" h+ e4 o0 G - struct tagRECT rc; // [esp+90h] [ebp-2048h]
. o1 ]$ y% F5 a) o$ N' c: q - int v58; // [esp+A0h] [ebp-2038h]
4 K, B; S8 U- ^+ Z! ^$ y, i0 T! L - char v59; // [esp+A4h] [ebp-2034h]9 {$ S* P+ n' x: _1 l
- WCHAR WideCharStr[4096]; // [esp+D4h] [ebp-2004h]
3 v) H/ e, v, K9 c - 5 L3 ~6 |. y. h% p% ^; w
- v11 = this;
' f1 N. B5 h B9 F$ c# v - v58 = 52;
( h9 w: @7 C" j; u - memset(&v59, 0, 0x30u);
, j' P0 r( j P8 i - if ( *lpMultiByteStr )
& \3 \# B/ _3 M1 ^! @+ E/ s - {; y/ }/ @7 p' Q# A& {
- v12 = MultiByteToWideChar(0xFDE9u, 0, lpMultiByteStr, -1, WideCharStr, 4096);
! a7 _) T: Q3 N* K" @ - *((_DWORD *)v11 + 4) = v12;$ Z! q% W% X% a2 f% O
- if ( v12 <= 1 ) M6 \6 a: I( l, G: v5 H" u
- return 0;
* L& J3 T% x, Q8 X$ v - *((_DWORD *)v11 + 4) = v12 - 1;
- _! o+ S! B! c0 s: w3 g - qsort(WideCharStr, v12 - 1, 2u, sub_10057A40);8 `% ?/ `, u) M
- }* m$ C% h6 B' Z6 K, S/ ]$ _
- else8 c2 C" j# {, c. `6 \# A9 {
- {% v n* h0 W5 T8 n! b, {
- *((_DWORD *)v11 + 4) = 352;
* w" \: C* |( y8 S - v14 = *((_DWORD *)v11 + 4);- Q9 C/ h m, C% W) `
- v15 = 0;& W$ D+ Z7 [; T V
- do" u, `! M, S4 }! y# t# T
- {8 M: ]: {, _9 h/ b$ i) j
- WideCharStr[v15] = v15 + 32;- ~2 G! j" s0 _- e
- ++v15;4 Q3 r- d' N. I8 u* X N$ B
- }' r/ i# A1 Y2 _4 ^4 \0 u) _2 S
- while ( v15 < v14 );
2 ]. N. _* [6 y; a/ `5 } - }4 h1 \& X+ |" Z% v3 m2 ? z" f6 @
- v16 = *(char **)v11;; y3 V2 S$ H5 w0 t5 u& s# d7 X" X
- if ( !*(_DWORD *)v11 )
; I; u0 u ?6 ?5 Y9 } - v16 = byte_100B2D6E;' J( Z# ]$ J8 B$ ?+ T% S D8 y( T
- v17 = CKContext::CreateObject(a2, 31, v16, 0, 0);
+ G2 L+ a5 `/ M, r% N - *((_DWORD *)v11 + 6) = v17;$ s; J) Y5 \4 J. B" k2 n$ f0 D
- if ( !(*(int (__thiscall **)(int, int, int, signed int, _DWORD))(*(_DWORD *)v17 + 84))(v17, xRight, yBottom, 32, 0) )
. m1 E) T4 Y1 V$ i; Z* L& o8 n1 E - return 0;# v1 ~+ `5 o3 `. z, T* e
- (*(void (__stdcall **)(int *))(**((_DWORD **)v11 + 6) + 136))(&v58);
f2 c) O: P; ?' P - v18 = CreateCompatibleDC(0);; Q4 @3 e% I" q( f$ ?
- v45 = VxCreateBitmap((const struct VxImageDescEx *)&v58);" D4 {' R8 \/ @$ {( N& @: F
- v47 = SelectObject(v18, v45);
- Y! \6 B2 D( n- D/ G! R - XString::operator=(v11, a3);
3 |( i" |3 {- j# E# z - *((_DWORD *)v11 + 2) = nNumber;
4 q+ R8 J0 P4 H- y9 I - v19 = GetDeviceCaps(v18, 90);
2 ]8 Z& R# F8 q; F6 E8 Y - v20 = MulDiv(nNumber, v19, 72);! J. W$ i. L1 |: q$ p% o$ l( K- r
- v48 = CreateFontA(-v20, 0, 0, 0, a6, a8 & 1, ((unsigned int)a8 >> 1) & 1, 0, 1u, 7u, 0, a7, 0, (LPCSTR)a4);
- k- N' X. c! w% t& ?! y6 r! i - v46 = SelectObject(v18, v48);
7 e: Y- q. Z5 h& h- e( O* c - GetTextExtentPointA(v18, "A", 1, &v56);
6 i, Y, q" h- L8 w# u7 b - v21 = *((_DWORD *)v11 + 4); o! h) k0 G6 n+ B, E0 Q
- *((_DWORD *)v11 + 3) = v56.cy;
: ?- q# W# d7 k- X" R- g# Z [ - v22 = (char *)operator new(32 * v21);) U0 N& U% e+ v( J" ?2 P7 @
- if ( v22 )
7 \9 E* N1 x w9 \) p' E% F- N- O - {" r2 l" D* I8 [/ ]5 t* s! n7 |
- v23 = v21 - 1;
9 W0 q% b$ E i9 p - if ( v23 >= 0 )0 O5 O: W+ F0 o2 S( p
- {
a! l* j" \" L* d2 m) u0 S2 t - v24 = (int)(v22 + 12);
/ R& I: ]' X; T- Z7 y* ` - do8 ^' x0 T; h0 u) e1 l. P0 w' `
- {' R j+ k0 z, g- Z2 V* _7 F
- *(float *)(v24 - 4) = 0.0;
% e6 |* j8 q8 |& d8 i5 m# j - v24 += 32;
# K% ^$ |8 u5 y$ i9 Z - --v23;- d" s" d% b& c: j
- *(float *)(v24 - 32) = 0.0;, {7 X5 M) l* d+ Z& ?: Y% M( k
- *(float *)(v24 - 44) = 0.0;
1 A' a; u3 [: {1 T - *(float *)(v24 - 40) = 0.0;
! t& r) ^* u. |0 q6 D - *(float *)(v24 - 36) = 0.0;
0 B; j! x8 _0 ^ - *(float *)(v24 - 32) = 0.0;% p4 F! V5 A1 N! R2 E/ ~
- }
3 g. ?/ d* Y2 Y* F# F4 Z5 i7 K; ] - while ( v23 >= 0 );
l& T& L L' N" `" A - }
4 J; f0 R9 }: f9 d - }
* O8 n+ u7 |: f5 L - else
9 F2 x7 m0 { J1 J7 ?9 | - {# x: X2 Z% D3 d. j/ E" n1 W
- v22 = 0;: s9 Y2 j! T, v2 F' R; x+ s
- }
1 s ` g& o- X9 G2 g - *((_DWORD *)v11 + 5) = v22;0 l" t) ~! W' Z( S
- SetRect(&rc, 0, 0, xRight, yBottom);5 h) _2 z N: ?
- v25 = (HBRUSH)GetStockObject(4);
* K9 @# v- X8 p1 z9 O& _7 m - FillRect(v18, &rc, v25);6 p) ^# m& _4 b# v
- SetBkColor(v18, 0);
7 @1 I+ n% t+ B. R! O - SetTextColor(v18, 0xFFFFFFu);
. U5 P" Q( y- ^0 F, o' W8 V - SetBkMode(v18, 1);) E0 [8 p0 G+ n$ R/ G, ] \
- v26 = 1;# k- H/ K# T5 B+ {& e3 h7 j' Q
- v41 = 1;6 x! b# E9 O& v
- v40 = 0;
( G. K+ A8 B0 P; q. u - v43 = 0;
+ u* N. L! N- U, t/ k - if ( *((_DWORD *)v11 + 4) > 0 )
# w5 M! Q/ X6 H+ K: C- t* }: t - {& }8 y- b% v' K# l0 u, I. r
- v27 = WideCharStr;
: v1 s- {, f, F" C1 X6 v2 E - v44 = 0;- i' i3 _* y; T. Q
- v42 = WideCharStr;
6 r9 P% V- \( u - v49 = (double)xRight;% K9 y1 ?. T% O& ?' Z
- v50 = (double)yBottom;! y( G0 h, I* p% M& v
- while ( 1 )
) T% r# f( [7 M& i/ \* B - {
6 C& t+ i3 k- f4 H% d. ~ B. n3 t - v28 = v44 + *((_DWORD *)v11 + 5);
9 B2 R& f) d0 O1 r3 y5 ?2 ~% b - *(_WORD *)(v28 + 16) = *v27;
{6 k0 a$ _1 b$ l0 \% R2 G$ k, @5 o - GetCharABCWidthsW(v18, *v27, *v27, (LPABC)(v28 + 20));
+ K- m1 y9 b0 _" U& k- u - if ( *v42 >= 0x20u )
; ]8 f# t, e2 U9 w - {
2 o3 I9 u0 M* w% ?2 L - --*(_DWORD *)(v28 + 20);6 C; c4 `! y; S& X* c$ m* B
- *(_DWORD *)(v28 + 24) += 2;2 n, g, K) E8 U% E! o8 P5 h
- --*(_DWORD *)(v28 + 28);( S8 U4 ?- ~3 A: k2 r; \8 k8 N
- }
/ Y% @) Y2 U" b i( V/ i* K5 W - else0 x# {: \2 r) q& h+ E9 U5 I' E
- {
8 Y4 G4 c6 S0 K# Z+ d9 ^: I, J - *(_DWORD *)(v28 + 20) = 0;
# C/ H) O' i" m/ B* ~" p - *(_DWORD *)(v28 + 28) = 0;
1 b3 g3 y) o, d) _' T+ y, m3 ]6 T - }
( G% g8 T( W8 B, C9 R$ V; E ~% z - v29 = *(_DWORD *)(v28 + 24);0 R8 O. J9 c/ ~
- v30 = v40;
6 j3 }3 n# }; t - if ( v29 + v26 + 1 >= (unsigned int)xRight )
" ?& t( E7 _7 o5 E6 P - {
0 @- E5 Z0 U( K8 N; Z - v26 = 1;3 a& E' G* o% G* {/ i }
- v30 = v40 + *((_DWORD *)v11 + 3) + 1;4 B$ r; ?; {( m+ W4 U1 g, b
- v41 = 1;
) p# Q# ~$ _% @" p% L: c ~: t - v40 += *((_DWORD *)v11 + 3) + 1;
, L M+ j7 j8 ?4 a& F- Z - }2 b) V3 |% u, ?6 \
- *(float *)v28 = (double)v41 / v49;
0 Z: K( y: Z+ v - *(float *)(v28 + 4) = (double)v40 / v50;# r5 Q" \; H7 s
- *(float *)(v28 + 8) = (double)(unsigned int)(v26 + v29) / v49;
, v$ r6 h7 J2 A& T - v31 = v26 - *(_DWORD *)(v28 + 20);5 m. P( \# C+ g* F4 M
- *(float *)(v28 + 12) = (double)(v30 + *((_DWORD *)v11 + 3)) / v50;
' N6 L7 G3 V! X0 o9 | - TextOutW(v18, v31, v30, v42, 1);
2 e/ {" U* v( a0 o2 F9 K. V% `5 P- V - v44 += 32;
' f& m! x1 o) x& L+ |2 s% X, `( K; ^ - ++v42;8 N3 c/ \4 e, P
- v33 = __OFSUB__(v43 + 1, *((_DWORD *)v11 + 4));" q% C- \5 U0 w8 _# g5 W' v4 i' l& H
- v32 = (signed int)&v43[-*((_DWORD *)v11 + 4) + 1] < 0;9 M& c; R) V1 I4 ]& X4 P0 S* m9 w2 c
- v26 += *(_DWORD *)(v28 + 24) + 1;4 i; j6 u0 n0 G1 `6 O: g
- v41 = v26;
, }' p# M9 }# l3 M - ++v43;! h. `7 b. m) J4 h2 c
- if ( !(v32 ^ v33) ), p7 m! I' _9 x- a; {$ t) t0 I
- break;
; Z, ?% g( [) f# F2 Q% `1 n - v27 = v42;1 M" K& V! i* t0 Y2 S+ g1 l& D, H
- }1 y- o! g0 L9 o0 ?2 ?/ r6 C
- }
) W+ ^+ _3 @2 }! d1 ` - v34 = CKBitmapData::LockSurfacePtr((CKBitmapData *)(*((_DWORD *)v11 + 6) + 56), -1);$ l) l) r/ P' X4 q' {( Z! Y7 l3 M
- if ( v34 ) j1 a* l* B! J* b
- {) _' h1 A1 `; W* w4 y9 o6 Y# Y
- GetObjectA(v45, 24, &v51);
# S0 Z2 a; _% O - v35 = v53;# W: a0 W* c. ~% H+ b
- v36 = v55 + v54 * (v53 - 1);. P+ a9 A) Z# u/ h
- v40 = 0;
" r. ~3 T# q4 |! i: J8 I9 R - if ( v53 > 0 )
5 m3 X7 D7 J2 q' K4 j - {' X5 D3 h5 Q) w2 e: [/ b
- v37 = v52;/ G" Q+ ?# z/ B' j# P" p
- do
4 h1 W* |& }1 I( [; r- w4 }) T - {% K7 ^2 J0 v" C/ m. P
- v38 = 0;0 i$ l' ^& q% S+ n3 q4 Z
- if ( v37 > 0 )% k. q$ y, z% O* R
- {9 g# G2 c' ^) j
- v39 = (unsigned __int8 *)v36;
1 R' [4 C; F5 e" A; A - do4 X5 u: T$ x- ^* b" r' z) ]" V7 C
- {- B2 O( e6 j$ P9 p) L- m
- *(_DWORD *)&v34[4 * v38] = (*v39 << 24) | 0xFFFFFF;
2 a7 B( {4 f3 y% G) R - v37 = v52;. n/ {" E* E) {; O! D! O9 A$ Z
- ++v38;
* d) B8 a" V0 I# h - v39 += 3;0 q r# k W0 Q
- }7 b4 S5 J- o2 y0 g
- while ( v38 < v52 );( y- v. v, l& P$ `3 ]
- v35 = v53;) X6 E7 T# I3 n4 A: \# N
- }+ Z$ I6 a( S. ]6 B* j
- v36 -= v54;
) b# \! B+ \% y2 j$ ? - v33 = __OFSUB__(v40 + 1, v35);4 }8 J. E: e0 A" }
- v32 = v40 + 1 - v35 < 0;; z: g% e# c4 j0 x( C7 O4 j( V
- v34 += 4 * v37;8 U9 X5 m+ f" i, G0 B \' r; A2 [5 O$ b$ l
- ++v40;
, p- Q. Y* }( r+ \ - }( @$ @1 z* u4 z0 M8 x
- while ( v32 ^ v33 );
% S$ q% Z! B) c/ n. c& T: \% s - }
' @2 V# u& U: V% z% J% C* V - }7 ?* p( O3 F, N9 U6 @% Z6 y
- CKBitmapData::ReleaseSurfacePtr((CKBitmapData *)(*((_DWORD *)v11 + 6) + 56), -1);' S% S) }5 N% i U x H1 d
- SelectObject(v18, v46);7 u, _( X2 Y/ N( v0 y; c2 _8 b, A8 w
- VxDeleteFont(v48);6 N; r W( s9 e; |2 X! H, I+ [7 b* Y, W
- SelectObject(v18, v47);: T# e j4 F' ]8 a
- VxDeleteBitmap(v45);- e/ ^( [, }, l& d3 D D
- DeleteDC(v18);
3 {6 e# C$ v- X7 B - CKObject::SetName(*((CKObject **)v11 + 6), (char *)a3, 0);
* z2 _( I8 |0 q7 v' y - CKBitmapData::SetDesiredVideoFormat(*((_DWORD *)v11 + 6) + 56, 1);0 _, S E' {) w
- (*(void (__stdcall **)(_DWORD))(**((_DWORD **)v11 + 6) + 120))(0);
& B+ w7 H- w8 e' o9 o - return v40 + *((_DWORD *)v11 + 3) < yBottom;/ l+ U; Y- d& H9 O6 `! r5 e$ S
- }
7 _) v' J' P1 W% _% v$ `
复制代码
a( H' ~7 A8 s1 W C
. T5 w* K7 q" j7 W |