本帖最后由 shane007 于 2023-8-26 17:10 编辑 & V/ k4 |) p; a5 ?' \- L
. y3 V2 Q! {3 `1 n/ E
这个游戏的主要修改点在\player\BuildingBlocks目录下的Adventure.dll中。
" u) c2 o$ n* Y/ g2 `用API monitor对本DLL的CreateFontA函数进行跟踪,发现确实有调用, 参数如下。. ? `$ D( ~: K. p6 N1 O
, i6 C$ v+ B _4 e! n0 C F
- # Type Name Pre-Call Value Post-Call Value, t) b/ u/ _" v2 R/ P
- 1 int nHeight 0xfffffff0 0xfffffff0
2 t1 U, J+ R4 g - 2 int nWidth 0x00000000 0x00000000
9 F, w; ?- u2 s6 N3 J1 n - 3 int nEscapement 0x00000000 0x00000000" ], ?0 E! f2 M+ r) W9 e3 Z
- 4 int nOrientation 0x00000000 0x000000008 p# z' Z6 z% z1 i
- 5 int fnWeight FW_NORMAL FW_NORMAL
$ O F4 _/ G0 ?) i7 P9 g0 w - 6 DWORD fdwItalic 0x00000000 0x00000000, {! F' S/ u ?; a8 b# \6 R9 K4 Y, {
- 7 DWORD fdwUnderline 0x00000000 0x00000000
! p8 T9 U& s3 t* x o# V+ |6 E* L - 8 DWORD fdwStrikeOut 0x00000000 0x00000000
7 \' }5 d% R+ F/ ?5 I2 J J& o$ m - 9 DWORD fdwCharSet DEFAULT_CHARSET DEFAULT_CHARSET8 @4 ^' @- h) ?7 w% q
- 10 DWORD fdwOutputPrecision OUT_TT_ONLY_PRECIS OUT_TT_ONLY_PRECIS" V4 B6 j+ k, m7 R
- 11 DWORD fdwClipPrecision CLIP_DEFAULT_PRECIS CLIP_DEFAULT_PRECIS
. \; q( y. S/ d/ s( Q" H) `3 y - 12 DWORD fdwQuality PROOF_QUALITY PROOF_QUALITY g2 P5 s4 K) U
- 13 DWORD fdwPitchAndFamily FF_DONTCARE | DEFAULT_PITCH FF_DONTCARE | DEFAULT_PITCH/ }/ p4 U8 o& |6 j9 H% x3 z, i
- 14 LPCTSTR lpszFace 0x09148a58 "Arial" 0x09148a58 "Arial"
$ [- S* {5 F5 r0 a% a7 o' q( e
复制代码
1 w! j0 o J7 S# [" W. E# p* [0 C" \. z+ \4 {8 P9 k
用ida pro找到调用CreateFontA的源头函数如下。
3 o C W& Z# M! U d从函数的参数可以看出,这应该就是字幕显示函数了。
; J0 Y- q% y3 T8 C关于后续修改,先修改CreateFontA函数的fdwCharSet,lpszFace这2个参数,也许就能出中文。
. ~ r. P2 E9 e' Z+ M( C. Y3 L# {, t还不行的话,就自己写一个显示函数。以下函数中lpMultiByteStr就是指向字幕的指针。; X+ \$ P, {' L! g) W7 R0 o
- 4 c' I1 V" \: i* o& L4 \) O
- 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( J& z/ y+ l1 p/ u' V - {
7 _- _' M. \+ I6 J* k3 ?- z - void *v11; // edi9 h! G2 H, M6 n" j
- int v12; // eax- i5 F+ `# g+ o U9 g
- int v14; // ecx5 X W5 r7 K. a# Q: \2 a. u
- int v15; // eax
9 @. e b1 J# c# c- b3 i% r6 L - char *v16; // eax
0 @% [8 K! p' ` - int v17; // eax
+ F; F' Z; H8 n1 E$ K2 p0 Q9 z2 z - HDC v18; // ebp% [" l! R0 W. j# T8 V2 ]
- int v19; // eax8 e- D) T8 r- _& \. w5 H
- int v20; // eax
' s3 U) h. h/ u: J( V2 k* I - int v21; // esi4 Z9 P+ n5 c8 l* x
- char *v22; // eax' Y4 N& Q! s1 N9 t7 A* t0 P
- int v23; // esi9 h' Q5 O2 l3 A3 R* V3 m
- int v24; // ecx* i7 j; R3 E0 @, j9 k
- HBRUSH v25; // eax; r9 x- Q$ g# J
- signed int v26; // ebx0 ~3 \; I* G$ E: b. q% `% p
- WCHAR *v27; // eax
* c/ }# Z2 X% A2 }: r* D8 k6 x - int v28; // esi! ^6 h9 ?( r+ K; `* f- @' C- R/ ^
- int v29; // ecx- q) F" E& A6 j' E R7 o
- int v30; // eax1 y% D. I8 @, I& v% L# K1 K9 J
- int v31; // ST28_4
4 r4 m7 S9 C5 k& X3 F - bool v32; // sf! R( B; p5 e/ p9 }: K5 P
- unsigned __int8 v33; // of7 B4 L$ F8 S( i2 s1 } h! \
- unsigned __int8 *v34; // ebx
' F+ t R! o8 {5 U, Z! H) H - int v35; // ecx" q% ~5 ^4 [, P y2 o9 s4 m
- int v36; // esi( X% ~5 d6 E3 k2 b. r
- int v37; // edx, h! m4 q$ V2 M0 m2 W) R
- int v38; // eax
2 ?2 q9 O* M5 c' U0 w0 \ - unsigned __int8 *v39; // ecx
- v2 A4 |4 }5 s; ^+ l. u0 X1 g - int v40; // [esp+40h] [ebp-2098h]
: q( @7 R: {) }8 D; G8 U* M5 D - signed int v41; // [esp+44h] [ebp-2094h]. z+ n' W# f4 m' j
- WCHAR *v42; // [esp+48h] [ebp-2090h]8 ^, W( m5 j1 U9 }9 \
- LPCSTR v43; // [esp+4Ch] [ebp-208Ch]
7 @7 L1 f* j a6 T! p& m/ F - int v44; // [esp+50h] [ebp-2088h]
* w' ]2 I4 S! G' c" q/ p9 O( a; } - HGDIOBJ v45; // [esp+54h] [ebp-2084h]
. Y" ~# ?8 C) U0 ~ - HGDIOBJ v46; // [esp+58h] [ebp-2080h]
8 h# l8 N- A$ G, f - HGDIOBJ v47; // [esp+60h] [ebp-2078h]
+ r! k+ ?' x+ l3 J9 Q f7 ~" J; A - HFONT v48; // [esp+64h] [ebp-2074h]
6 F+ N$ I8 c- H1 m9 F+ R9 u# K - float v49; // [esp+68h] [ebp-2070h]
8 `- p% C) G$ W - float v50; // [esp+6Ch] [ebp-206Ch]5 U5 [! C7 c ~5 p
- char v51; // [esp+70h] [ebp-2068h]. ] w& x5 d. V3 t% P! B4 A- v' a* X
- int v52; // [esp+74h] [ebp-2064h]
9 T9 j" K [3 M& | - int v53; // [esp+78h] [ebp-2060h]3 Y6 u7 q# Z N+ B2 X8 t% p
- int v54; // [esp+7Ch] [ebp-205Ch]
( w7 T9 ^! |& {, V8 C& O! m1 x9 ] - int v55; // [esp+84h] [ebp-2054h]
- H) h/ v; P' h& H/ n% [: I - struct tagSIZE v56; // [esp+88h] [ebp-2050h]
1 ]) _" [6 b; N! v! x4 |7 @ - struct tagRECT rc; // [esp+90h] [ebp-2048h]- S% {7 t5 i5 m4 y& ^ u3 `
- int v58; // [esp+A0h] [ebp-2038h]
" Z$ t6 t& ^6 \6 N3 W3 Z6 o' `; @ - char v59; // [esp+A4h] [ebp-2034h]
# x! S0 z0 [7 i - WCHAR WideCharStr[4096]; // [esp+D4h] [ebp-2004h]
* v2 z; x% D: U) X: g
! m2 O; V1 X: o0 O; N4 p8 C- v11 = this;
* W7 f; L3 x0 L5 K7 z" s7 S: O - v58 = 52; ^3 D! L# o1 {0 l Z2 q$ {
- memset(&v59, 0, 0x30u);
/ F4 ~% i* g% d3 I+ P | P; f - if ( *lpMultiByteStr )
* e4 l7 f' z% n/ o - {+ B! ^' a! U* Y5 g5 U
- v12 = MultiByteToWideChar(0xFDE9u, 0, lpMultiByteStr, -1, WideCharStr, 4096);9 N4 B( h, h f) ~) i3 S+ t
- *((_DWORD *)v11 + 4) = v12;$ P f8 V5 R- v# k1 Q' N" [
- if ( v12 <= 1 )" Z% A) y O# j: u: ]' D! u5 b
- return 0;
* E# [! F. u0 n) V9 W) W+ ]( r& p$ X/ ~ - *((_DWORD *)v11 + 4) = v12 - 1;7 q% L' l( x+ c) D* K) a' u* i. k
- qsort(WideCharStr, v12 - 1, 2u, sub_10057A40);
& C- d! `/ P# A* Y7 z - }# X( q; n& P) S- Z( n Q" W: E
- else+ m& [. L7 p) @/ c: O- B- `
- {
+ a/ s0 R" u8 ]" L - *((_DWORD *)v11 + 4) = 352;' @) \3 |6 ^: u+ ~
- v14 = *((_DWORD *)v11 + 4);
! x# X& r% `6 a& @4 s7 W - v15 = 0;* N2 R) ^( |3 v( M* ]3 d
- do, m8 G, T1 Q' D: z( X: t8 ~
- {) j' T) G% i( o# A' F
- WideCharStr[v15] = v15 + 32;- w" w" q- U0 O. I* D: T% E- s
- ++v15;
5 ~9 ~6 j; N, c, `- ~4 m/ V - }
. V/ M0 I0 v$ J/ x5 V' v6 L6 ] - while ( v15 < v14 );
0 u8 j6 g; m! V- v, W4 q! N0 G - }
+ N, b3 q/ F& v - v16 = *(char **)v11;
$ j" K+ \8 Y, t' n6 n0 n - if ( !*(_DWORD *)v11 )
! C3 V- r3 y' b' t) S' ` - v16 = byte_100B2D6E;
! A2 p. u% ~3 B8 l: [6 D9 z) | - v17 = CKContext::CreateObject(a2, 31, v16, 0, 0);9 n% {+ t* [% w7 N" P3 B$ v$ D, b- Q5 u
- *((_DWORD *)v11 + 6) = v17;
) U! a. t/ L7 V: ` - if ( !(*(int (__thiscall **)(int, int, int, signed int, _DWORD))(*(_DWORD *)v17 + 84))(v17, xRight, yBottom, 32, 0) )
6 ~, {/ l' z6 i' y+ S7 d! ~' l - return 0;9 ]# o7 N" `% }* {5 C4 [
- (*(void (__stdcall **)(int *))(**((_DWORD **)v11 + 6) + 136))(&v58);' m D' C; O* h
- v18 = CreateCompatibleDC(0);7 x( i# }$ l2 j- g1 F* ~
- v45 = VxCreateBitmap((const struct VxImageDescEx *)&v58);
5 L; y/ ^" T+ Q5 G( B; } - v47 = SelectObject(v18, v45);8 Z2 V) N# n* u0 N! @! N" i
- XString::operator=(v11, a3);
# |6 ~) {- C6 x Y$ ?& t$ g - *((_DWORD *)v11 + 2) = nNumber;- N2 m, |5 R0 N+ U' T7 Q( W( l; `5 w
- v19 = GetDeviceCaps(v18, 90);
, e9 F( o, P3 _) ~ - v20 = MulDiv(nNumber, v19, 72);
0 g8 ?: y3 F0 `9 V - v48 = CreateFontA(-v20, 0, 0, 0, a6, a8 & 1, ((unsigned int)a8 >> 1) & 1, 0, 1u, 7u, 0, a7, 0, (LPCSTR)a4);
8 p( f R* Q2 K$ i& k - v46 = SelectObject(v18, v48);7 `7 t) }2 G4 D/ k9 L: s
- GetTextExtentPointA(v18, "A", 1, &v56);
# A" h% W( [ W; e" ^: M - v21 = *((_DWORD *)v11 + 4);
2 M+ ] `/ R3 a& `) F* a - *((_DWORD *)v11 + 3) = v56.cy;
' K6 S$ i- b$ u; l: A& ]! _& v - v22 = (char *)operator new(32 * v21);
& |& p7 m4 }. b e9 X& y( U - if ( v22 )
' ?4 \- x& e$ p6 c" X - {- v2 b# f) b4 L$ c# T
- v23 = v21 - 1;0 J' ^/ i8 f2 H& L. |
- if ( v23 >= 0 )1 F A. ]- b' N9 a7 o/ }
- {
7 l4 x- Q( S$ { l4 e - v24 = (int)(v22 + 12);
2 P1 f+ e2 n0 A1 x# } - do
% ?7 V- _5 Z+ \: }" o) s+ D - {
! F2 t' i# C) K) \" R6 \ - *(float *)(v24 - 4) = 0.0;& z' R. L5 Q+ k: u
- v24 += 32;1 }! R) W$ p: |8 R
- --v23;
, ~0 Q! x' a$ ~) u - *(float *)(v24 - 32) = 0.0;
: T/ a& g/ x# e+ r7 F2 V! }; Z: v - *(float *)(v24 - 44) = 0.0;8 B0 @" Z. G) e$ P) F1 U; p
- *(float *)(v24 - 40) = 0.0;
2 b" w# B! f9 B6 G0 l - *(float *)(v24 - 36) = 0.0;. l! ?1 Y8 \4 d2 i6 y) Q1 G. j
- *(float *)(v24 - 32) = 0.0;9 ?* r- ]. [: ~$ C9 ^) Y
- }
' P8 V( k" ]! Y& x# L! G* z. p, h - while ( v23 >= 0 );
4 J, [! O7 s# N0 e5 Y - }
4 G; y% ^) E8 ?, F - }8 k) W7 B# T1 M h- }$ C
- else
. Y% K* \* s' _& J K - {1 k7 ?' D' e1 K/ z
- v22 = 0;
8 }7 @, Q5 n' D! |) V; g- N - }
# |) s& q5 y: n: J$ ` - *((_DWORD *)v11 + 5) = v22;
' M: V/ Q$ S$ a5 V - SetRect(&rc, 0, 0, xRight, yBottom);
5 u" r# K1 L/ X) N9 E- J - v25 = (HBRUSH)GetStockObject(4);
; U$ g2 x$ q# G - FillRect(v18, &rc, v25);7 \- T) Z! d, C$ }, i
- SetBkColor(v18, 0);
9 q3 {; ` t" K1 B2 u, t% ? - SetTextColor(v18, 0xFFFFFFu);$ V' [. [) T/ a
- SetBkMode(v18, 1);) j$ x" N! ], L0 K p6 F* E
- v26 = 1;3 V v, W9 D# n8 H: Q# }; @6 V
- v41 = 1;
. y/ C9 l0 e4 c! i: A/ q4 ^% a$ ?0 H - v40 = 0;" e7 W( N& I/ k' }- w
- v43 = 0; u/ V4 m; r* z- ?1 Z2 `
- if ( *((_DWORD *)v11 + 4) > 0 )
7 r9 e! w- k. Q - {) d2 Z1 y7 ^4 A: |4 m" L. d
- v27 = WideCharStr;+ ?9 \: T$ q0 G( e& ~4 P: K# Y
- v44 = 0;
* I6 K5 ~% `7 O$ M1 i7 g9 Y' i. T - v42 = WideCharStr;+ ]: T& }% O0 O: s0 {( z: H/ }
- v49 = (double)xRight;
/ G2 W3 F5 P" O' C$ v2 O - v50 = (double)yBottom;/ v/ p' f. _6 |; l, j3 V6 w
- while ( 1 )
. R; {$ X0 x9 U: _ - {5 }' f" l$ M3 P; O. I5 m
- v28 = v44 + *((_DWORD *)v11 + 5);
6 ~4 U% u- @& y& A$ U1 C - *(_WORD *)(v28 + 16) = *v27;
, p0 D( @+ }/ L6 `9 }& k/ U. B - GetCharABCWidthsW(v18, *v27, *v27, (LPABC)(v28 + 20));
# ]5 H2 V$ `" x- L( N- @ - if ( *v42 >= 0x20u )
3 q0 h$ ?0 P& R# ^5 }* {6 m+ ? - {
5 P8 S/ p% p/ [- A- ~9 B - --*(_DWORD *)(v28 + 20);3 V+ ^5 C( y* e* R
- *(_DWORD *)(v28 + 24) += 2;
4 _0 H+ Q* d4 Z1 C ] ]# A7 L; m& u - --*(_DWORD *)(v28 + 28);" C% |$ ?" U& C2 X& g, h3 [; b4 Y
- }8 m( b; `% V- n# h0 I; a
- else+ r, E4 H$ y9 `0 a# O. ]- o
- {$ X* N3 P: q! {- e( k+ a2 A
- *(_DWORD *)(v28 + 20) = 0;
( P* W) ]! u9 X - *(_DWORD *)(v28 + 28) = 0;
% y" p5 P3 |) ?! l3 L4 M8 ? - }! P) p8 o8 t: x) t
- v29 = *(_DWORD *)(v28 + 24);
7 u% D5 |9 f3 [ ` - v30 = v40;' P" |* z7 r+ Z. ~0 @2 j
- if ( v29 + v26 + 1 >= (unsigned int)xRight )
% H( J' R6 s# t - {3 }' U9 t+ z) ^ q! E6 x
- v26 = 1;
/ l F% p1 q' ?% J( X6 S - v30 = v40 + *((_DWORD *)v11 + 3) + 1;
2 j7 X# ]5 P1 m& ?- X G. l - v41 = 1;! X R( I0 M! c/ F( P5 T y1 j1 n
- v40 += *((_DWORD *)v11 + 3) + 1;1 ^6 ^) h; O% ]3 q5 a. W
- }9 q5 B! H" m1 b1 _" F
- *(float *)v28 = (double)v41 / v49;) S+ N" F0 M; `7 {/ J- S, t
- *(float *)(v28 + 4) = (double)v40 / v50;
: T- ^# l- P% o) k - *(float *)(v28 + 8) = (double)(unsigned int)(v26 + v29) / v49;. d, x' S0 a( F' |
- v31 = v26 - *(_DWORD *)(v28 + 20);5 u/ h, S) W+ n* }) L2 w# \
- *(float *)(v28 + 12) = (double)(v30 + *((_DWORD *)v11 + 3)) / v50;* Q" x% K; z* W" s4 D) N! B% k1 E
- TextOutW(v18, v31, v30, v42, 1);# G8 _# S; p" ?0 _: A3 v
- v44 += 32;
3 i& z* }+ m& t" d8 m3 c - ++v42;# h4 J5 g$ k& k0 |6 `# w
- v33 = __OFSUB__(v43 + 1, *((_DWORD *)v11 + 4));
, j* w. g/ `' H& Q7 A1 g. g- { - v32 = (signed int)&v43[-*((_DWORD *)v11 + 4) + 1] < 0;5 C7 Q) @0 G+ O9 G }
- v26 += *(_DWORD *)(v28 + 24) + 1;
' z5 A/ T6 a+ D' J - v41 = v26;
- t: X" v' U: k& \) D - ++v43;3 S# X$ G3 o a2 i+ T! j
- if ( !(v32 ^ v33) ), u/ M* t- R* q% t( b
- break;0 e/ ]& V+ X' X( a
- v27 = v42;, ?/ S1 j1 O+ G5 W) H% Y
- }3 k8 H; p* O5 v# N9 O
- }
& g9 p0 s; T& I1 ]) I7 E - v34 = CKBitmapData::LockSurfacePtr((CKBitmapData *)(*((_DWORD *)v11 + 6) + 56), -1);
* Z: x5 b- ?: r0 g q1 q - if ( v34 )/ n3 f5 p- ]+ E- B
- {
- H/ ] T0 M2 w- j2 l - GetObjectA(v45, 24, &v51);
; f- e" b4 P* b% t - v35 = v53;1 b7 k7 \ A1 E$ q
- v36 = v55 + v54 * (v53 - 1);* C, i, H) K: j0 ?: k
- v40 = 0;0 ^$ v# g: `; W7 r# a( `
- if ( v53 > 0 )
/ t0 M* w0 c; }$ u4 D; ` - {
9 V9 ^1 X" g: W% a/ l - v37 = v52;- k& Y+ Q& c( n% ^4 A' _
- do
' K' J1 \! L9 f - {& m4 Y# i0 f6 i
- v38 = 0;
4 t0 x4 G! t* d9 b% K9 z; l2 d" n - if ( v37 > 0 )
" T% x6 D, S% a - {2 H7 `+ x; v4 H* @! J
- v39 = (unsigned __int8 *)v36;
0 a- F' d4 r0 Q; D% I0 l - do
9 X& u {! o* r: P, `# q/ Q7 e8 T - {& U" H d9 C7 d+ ~6 Z, U! j1 h, @
- *(_DWORD *)&v34[4 * v38] = (*v39 << 24) | 0xFFFFFF;" o4 Q4 P' T6 L+ f
- v37 = v52;
* h5 j; D* N# N' z5 u1 [" J% w - ++v38;, U x7 ]$ o5 V% U* w2 a* F( L [
- v39 += 3; w, I/ K) e9 r% e1 }% C
- }
2 n8 q+ l; u2 i - while ( v38 < v52 );2 l# K* n- G5 X: Y" [
- v35 = v53;
- Q' o. S- ]! ^" Y6 u! g& g - }% _9 S+ j- K2 y. i9 ~2 R' P
- v36 -= v54;
8 \ P2 V0 |3 j1 y/ w$ Y) z4 l" B - v33 = __OFSUB__(v40 + 1, v35);
5 ^% U" J4 m0 y; b% F. \ - v32 = v40 + 1 - v35 < 0;! i1 [- C k; P
- v34 += 4 * v37;( g9 ]0 d9 ?$ H1 f7 L0 J# q& S7 ^* ^
- ++v40;4 Q( L; b* C5 ]6 u( M7 m
- }% N! R" s# y3 s
- while ( v32 ^ v33 );
" e' J% P, R. M/ b) v7 l2 I - }
( i9 Y! P/ Y3 ]5 |3 A4 ?% X3 v - }9 L5 L4 v4 a( K, Y* C
- CKBitmapData::ReleaseSurfacePtr((CKBitmapData *)(*((_DWORD *)v11 + 6) + 56), -1);
Z; z2 i1 B( J+ `' [: c - SelectObject(v18, v46);9 S( ~( j3 D! w
- VxDeleteFont(v48);
; A- N7 j" X' G0 R! B" h* O - SelectObject(v18, v47);- a f; Z3 U2 F: K# w
- VxDeleteBitmap(v45);
1 q, z- m$ `5 D; l - DeleteDC(v18);
4 U! ?# [5 `$ N/ I0 o+ U) _: ~ - CKObject::SetName(*((CKObject **)v11 + 6), (char *)a3, 0);9 |1 q3 e7 q' E
- CKBitmapData::SetDesiredVideoFormat(*((_DWORD *)v11 + 6) + 56, 1);
: Y; t8 r9 Z8 J4 \ - (*(void (__stdcall **)(_DWORD))(**((_DWORD **)v11 + 6) + 120))(0);7 C. \' M6 V B1 {* ~* D# N2 P
- return v40 + *((_DWORD *)v11 + 3) < yBottom;3 i# }, i0 X) O
- }: Y0 H3 K( C2 s1 ~ o
复制代码 ' s3 g" L- y: U! k8 R4 [8 V' R; O
! V# d( {. _$ y8 j+ | |