本帖最后由 shane007 于 2023-8-26 17:10 编辑
$ T# o# r/ R1 z3 e" N; e: ]$ J8 l( F+ D- |
这个游戏的主要修改点在\player\BuildingBlocks目录下的Adventure.dll中。! K) D! s+ n/ H" Z7 g! r
用API monitor对本DLL的CreateFontA函数进行跟踪,发现确实有调用, 参数如下。" k# X' P( L6 @" q# t) _) W
6 h. m8 ~% }9 Y( V
- # Type Name Pre-Call Value Post-Call Value
& w( D' h; G* a" f - 1 int nHeight 0xfffffff0 0xfffffff06 ^7 H! K6 r9 T0 e
- 2 int nWidth 0x00000000 0x000000009 Y% d, `" I8 |* X& j, v6 j
- 3 int nEscapement 0x00000000 0x000000000 F0 g- K% s$ k% x
- 4 int nOrientation 0x00000000 0x00000000
V5 u+ X9 u# s/ I p - 5 int fnWeight FW_NORMAL FW_NORMAL
! I+ w X. J) S& H3 O# n) a9 ^ - 6 DWORD fdwItalic 0x00000000 0x00000000. o0 T3 Q8 o: F& Q' m, J& M
- 7 DWORD fdwUnderline 0x00000000 0x00000000
/ G; l, e# @2 l - 8 DWORD fdwStrikeOut 0x00000000 0x00000000$ u' K0 g4 g' Y- p: e5 ?& F* \9 `
- 9 DWORD fdwCharSet DEFAULT_CHARSET DEFAULT_CHARSET
% i( G9 ~4 O9 I; ]) k1 m+ R - 10 DWORD fdwOutputPrecision OUT_TT_ONLY_PRECIS OUT_TT_ONLY_PRECIS `" h+ f$ f. }2 S5 _( M5 W
- 11 DWORD fdwClipPrecision CLIP_DEFAULT_PRECIS CLIP_DEFAULT_PRECIS4 }6 e# A! T" ?9 m: q
- 12 DWORD fdwQuality PROOF_QUALITY PROOF_QUALITY* f% h- l/ p" O4 b# Y' B
- 13 DWORD fdwPitchAndFamily FF_DONTCARE | DEFAULT_PITCH FF_DONTCARE | DEFAULT_PITCH
% P. M, ?5 q) s& e- Y8 L! q - 14 LPCTSTR lpszFace 0x09148a58 "Arial" 0x09148a58 "Arial"( Z3 ]9 ]9 j, {0 ?) M
复制代码 s! j5 r. G) k' A
$ @; w! I( A7 C/ }+ c4 w; f( o用ida pro找到调用CreateFontA的源头函数如下。3 y2 p+ U ^( O' R
从函数的参数可以看出,这应该就是字幕显示函数了。
! P: S1 a" E* [$ U% G( z* ~关于后续修改,先修改CreateFontA函数的fdwCharSet,lpszFace这2个参数,也许就能出中文。
; h+ w/ f: X! @6 K, h0 i+ S# L还不行的话,就自己写一个显示函数。以下函数中lpMultiByteStr就是指向字幕的指针。/ p' t2 ~2 l4 u. d9 M# l9 j6 m/ k q
- * ^2 K! X" W3 l, N5 _ p/ U+ y
- 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)0 l: p* m! M. k( a7 C6 ]
- {
" S- w6 _4 _- n% E - void *v11; // edi
' H& p6 T d0 j/ @9 C - int v12; // eax; b3 E1 Y: U u$ C! ]$ N- z
- int v14; // ecx
5 v0 Z* s# w1 A - int v15; // eax( B# _4 N# y6 h: L
- char *v16; // eax
, C5 D* @* P, Q0 P5 x - int v17; // eax
^& Q/ R# p5 C; a1 Z% n - HDC v18; // ebp
: t0 G. T9 h4 k( S$ Z! x, W - int v19; // eax) s4 ]+ `$ F# D. f
- int v20; // eax
, u+ h- j8 @+ A# U" _ - int v21; // esi
3 W. c9 s* K/ U k7 L - char *v22; // eax
1 ]* W9 ?9 k3 l K. v - int v23; // esi$ E4 J, T3 F8 L v% b* y; L8 {% T
- int v24; // ecx7 s2 P) M$ H/ Z. c: j6 t: o
- HBRUSH v25; // eax
7 l1 v! P! L/ d9 p - signed int v26; // ebx% Z+ U* U3 U7 U: P# w! t. d
- WCHAR *v27; // eax
6 h' X6 X0 r9 R$ ?6 ] - int v28; // esi5 a7 _; t. U( d6 j9 w
- int v29; // ecx$ E ?6 {( n. V! A# f& c: r
- int v30; // eax* g4 g7 }$ G" J! E
- int v31; // ST28_4
: U! D* F `: [4 R' ] - bool v32; // sf) W# h# _+ c+ A8 t& H! P" i
- unsigned __int8 v33; // of+ D$ L, z8 m/ e
- unsigned __int8 *v34; // ebx
8 |7 H* r# d! }6 P - int v35; // ecx
/ D$ s. J% q$ ?. F - int v36; // esi$ m+ w# Z* R4 Z1 _4 z
- int v37; // edx
( |/ g5 L) g6 R3 I! W - int v38; // eax, f @8 V) R+ \2 f# ?! @& O& n- h
- unsigned __int8 *v39; // ecx
1 m% c) }/ y/ {% @ - int v40; // [esp+40h] [ebp-2098h]
/ u. H. [/ z- b% I0 W" Q0 h; \ - signed int v41; // [esp+44h] [ebp-2094h]
. H; I* u' ~3 d8 S6 d - WCHAR *v42; // [esp+48h] [ebp-2090h]
9 w7 Z, s2 {$ D5 f6 e4 } - LPCSTR v43; // [esp+4Ch] [ebp-208Ch] U% M, {3 w! F6 F0 ^0 h* p. E
- int v44; // [esp+50h] [ebp-2088h]
6 S+ W) e( C3 N/ n- l# M - HGDIOBJ v45; // [esp+54h] [ebp-2084h]& M9 v+ B+ a( P, q! l
- HGDIOBJ v46; // [esp+58h] [ebp-2080h]
! E, x/ R9 R! {& Z/ A ] j - HGDIOBJ v47; // [esp+60h] [ebp-2078h]
. v1 [3 P4 x8 G" R8 m4 ^ P2 c. m+ P - HFONT v48; // [esp+64h] [ebp-2074h]
" T+ a* [* P# Y" O9 M' l# t& Q - float v49; // [esp+68h] [ebp-2070h]. o, a' L# i C4 e3 }- W
- float v50; // [esp+6Ch] [ebp-206Ch]
! h/ m E6 d2 T5 p! d" Q1 I - char v51; // [esp+70h] [ebp-2068h]# Y7 R' E" N" P% S
- int v52; // [esp+74h] [ebp-2064h]: B. A) ]8 C. g1 B" x
- int v53; // [esp+78h] [ebp-2060h]$ @) ?8 C* `+ P8 n6 N
- int v54; // [esp+7Ch] [ebp-205Ch] G$ C' I9 ?2 _" W7 f t
- int v55; // [esp+84h] [ebp-2054h]1 \! X0 c2 g6 s% _
- struct tagSIZE v56; // [esp+88h] [ebp-2050h]
9 Q/ [, W$ [+ N$ W/ n1 _" B- E - struct tagRECT rc; // [esp+90h] [ebp-2048h]
8 s' ^+ ^0 T' u6 \4 M( f; S - int v58; // [esp+A0h] [ebp-2038h]
1 |: h! B( \* ?) F6 Z- L - char v59; // [esp+A4h] [ebp-2034h]* j" J' j& o# v) q
- WCHAR WideCharStr[4096]; // [esp+D4h] [ebp-2004h]
4 o2 ^% y/ U# V: u0 z - . [, h& ~* I0 o+ L+ e( Y- k0 b
- v11 = this;
" q7 c* G! x. V6 Z) s& b9 G - v58 = 52;
' r, Q9 X- S) L8 T* M; y8 c - memset(&v59, 0, 0x30u);
' @( b6 I. A$ K. W - if ( *lpMultiByteStr )5 I( S- l- n' [! J) {( w
- {) I5 s x( V1 X. q0 e- v- ~
- v12 = MultiByteToWideChar(0xFDE9u, 0, lpMultiByteStr, -1, WideCharStr, 4096);& I" n# M- s, ~
- *((_DWORD *)v11 + 4) = v12;
7 k7 v6 Z" {) t& J5 I - if ( v12 <= 1 )* J: {4 H3 e H1 h
- return 0;
- [+ i/ ?* b' Y; B/ X: _* m) }' Y - *((_DWORD *)v11 + 4) = v12 - 1;, O% J) D; \" {1 I! u# \, b
- qsort(WideCharStr, v12 - 1, 2u, sub_10057A40);
; S3 e- z# b8 N - }
% G- D& f6 R) O% { - else7 N: ^0 q" R$ _: `2 g
- {: ^8 M F( \ h% w5 J% b
- *((_DWORD *)v11 + 4) = 352;& B( n& \5 L. n6 p
- v14 = *((_DWORD *)v11 + 4);
3 E1 U- c7 f# D2 N1 p3 C - v15 = 0;- h4 L* z3 H. x
- do. M$ J6 L4 O5 ?) `
- {: `3 h6 ~- n" x: g) `9 }
- WideCharStr[v15] = v15 + 32;/ K6 W- @0 J0 p4 G4 u8 r+ B
- ++v15;
7 ^6 W' I- m. m1 p - }
4 ~4 E4 B# Y" F# l - while ( v15 < v14 );
% l4 a( \4 k5 K/ e* Q: u - }
: O! z! [& }! j! | - v16 = *(char **)v11;
: _1 q% Y& H: J# N. \# h' k4 o) f - if ( !*(_DWORD *)v11 )
. z6 v4 ?- d. `6 b( T2 p2 `* v1 g - v16 = byte_100B2D6E;0 |3 ^& V# |8 I3 u! C6 R7 C
- v17 = CKContext::CreateObject(a2, 31, v16, 0, 0);& x0 _) @, \) |9 ]0 M: L
- *((_DWORD *)v11 + 6) = v17;% S0 _- o6 J8 E4 L9 u
- if ( !(*(int (__thiscall **)(int, int, int, signed int, _DWORD))(*(_DWORD *)v17 + 84))(v17, xRight, yBottom, 32, 0) ). V0 J4 g: t- h- S8 w
- return 0;# q1 L: g* O7 {0 f; }6 `- r
- (*(void (__stdcall **)(int *))(**((_DWORD **)v11 + 6) + 136))(&v58); ], X# M6 I0 J7 t
- v18 = CreateCompatibleDC(0);
2 v) K8 J6 Q% Y( ^7 T9 ? - v45 = VxCreateBitmap((const struct VxImageDescEx *)&v58);- K: V8 ^) @& o/ c* D/ ]$ l1 j
- v47 = SelectObject(v18, v45);% E$ K/ l( Y, j0 y7 U: `1 |
- XString::operator=(v11, a3);
l9 f) A; |; W- O* L ]) t - *((_DWORD *)v11 + 2) = nNumber;: o6 j6 |# V; z* m- }3 A
- v19 = GetDeviceCaps(v18, 90);) P2 }+ [4 [( x# o R" R0 h& f
- v20 = MulDiv(nNumber, v19, 72);2 ]. p& \5 k: V( z( A
- v48 = CreateFontA(-v20, 0, 0, 0, a6, a8 & 1, ((unsigned int)a8 >> 1) & 1, 0, 1u, 7u, 0, a7, 0, (LPCSTR)a4);" x! A$ C4 \6 y2 ]8 A2 ?: L
- v46 = SelectObject(v18, v48);
b* R# O" s, T0 _' U& H% v - GetTextExtentPointA(v18, "A", 1, &v56);3 c2 r; ]* N8 T6 i5 A x
- v21 = *((_DWORD *)v11 + 4);+ M* a5 c' I8 p2 P; _6 P5 |
- *((_DWORD *)v11 + 3) = v56.cy;
2 N6 J3 A( B7 _; P3 _7 X# } - v22 = (char *)operator new(32 * v21);4 B5 d3 P% p0 c3 ?
- if ( v22 )2 ?% e" o+ o, z' w2 }. d. _1 R- @$ J
- {+ q1 E/ G5 O9 J
- v23 = v21 - 1;% o# q# ^+ T2 \2 H5 q
- if ( v23 >= 0 )
; y. Y8 z! ]6 u D& m$ ` - {2 O. O9 f! g. z- [9 r
- v24 = (int)(v22 + 12);
' E6 |3 a7 C" j# ?8 F3 Z' C K - do0 I2 b* R! ?! U, @8 S% j6 G% k
- {6 J+ E4 ^3 d0 R( s' D: x' N& k O
- *(float *)(v24 - 4) = 0.0;( r9 [2 y+ Y; D$ \# O2 e$ m
- v24 += 32;% N) ^0 z( ^' t* t0 O
- --v23;
0 K. q! D1 K) Z& e8 v2 U7 B3 i A& M( p - *(float *)(v24 - 32) = 0.0;
5 i t0 D \" N8 J - *(float *)(v24 - 44) = 0.0;
, l: k3 `- } j: M) _/ ^% U - *(float *)(v24 - 40) = 0.0;
# x/ }7 S9 a+ ?7 n9 x9 { - *(float *)(v24 - 36) = 0.0;
3 |4 E: R' c8 Z- c* ?( V - *(float *)(v24 - 32) = 0.0;$ c5 i w" N' g# }' ]0 R1 w
- }
: v' U% U) }4 B1 P: h R$ C- \+ t - while ( v23 >= 0 );
/ S5 s& d/ b, c" x1 ?8 b - }
/ ^# | _$ l# D, s+ l - }
8 F4 K2 p6 I' U" V; u$ c/ W- y - else
" M4 t9 s+ h% R' Z: X9 }9 q - {
4 O, ?2 N9 M( ]2 ~! I - v22 = 0;5 j4 q3 t& `5 d" A# ^
- }- e% M( X1 E9 ^5 j) K1 y6 O
- *((_DWORD *)v11 + 5) = v22;
) e0 T9 N$ r$ W- S - SetRect(&rc, 0, 0, xRight, yBottom);! A3 C" \: V, i: i- ~& X! Q( n" G5 }' A
- v25 = (HBRUSH)GetStockObject(4);0 B, A; A, T7 F! E; f
- FillRect(v18, &rc, v25);( q" S! Z* _2 S4 V) _: _# D" C$ T
- SetBkColor(v18, 0);
" e4 k0 h5 s1 j. _# D/ v! ~ - SetTextColor(v18, 0xFFFFFFu);5 \* ]3 S# [) u. O
- SetBkMode(v18, 1);3 s: v- }& X1 B+ _! N
- v26 = 1;/ M( K7 q7 k. H, I: W' q
- v41 = 1;
, G0 W' F& Z0 H$ B% R6 M! N - v40 = 0;9 q; V/ }- O, \- `
- v43 = 0;+ S2 L( ]. c9 }5 Q' | S9 l# m
- if ( *((_DWORD *)v11 + 4) > 0 )5 r$ }4 L) m# p$ p, j
- {
% j% D% ^1 i$ r6 y- r - v27 = WideCharStr;0 c. D/ H4 E) Y" O2 c& U
- v44 = 0;
4 S" K6 T6 Q% I& }; @/ C - v42 = WideCharStr;
) e' f8 E- D% V% n! `6 l% {2 _ - v49 = (double)xRight;
5 @) K7 _7 ^4 x2 D' T% A( G" ?3 } - v50 = (double)yBottom;. d$ I$ {: ?; X
- while ( 1 )( r' U. z) a9 @
- {0 E8 A$ w+ |8 C. q- b4 r& \$ H
- v28 = v44 + *((_DWORD *)v11 + 5);% l/ M- J. V% N) \0 t S
- *(_WORD *)(v28 + 16) = *v27;* M6 T. ^" U8 D4 V: c8 t* g( f; T7 `
- GetCharABCWidthsW(v18, *v27, *v27, (LPABC)(v28 + 20));" k4 l, ^5 v6 T) |' m
- if ( *v42 >= 0x20u )
" e% Z6 i7 }- E# z! Z+ \ - {! c& I0 m+ |' o$ e
- --*(_DWORD *)(v28 + 20);
( w% L' z, w6 g. S `: X - *(_DWORD *)(v28 + 24) += 2;# ~9 L5 d7 ?0 l! J- F
- --*(_DWORD *)(v28 + 28);3 n/ X$ ]( V! I7 N* O
- }
- j m' F# V O3 V# q% p3 e' f - else
$ p6 a' [) X" w: t; x - {
1 O3 t" j3 N# l2 g% m% D - *(_DWORD *)(v28 + 20) = 0;( @/ M8 u1 H$ B5 p
- *(_DWORD *)(v28 + 28) = 0;7 Z3 f% L' u1 l4 q
- }
v p' B/ y/ C& a( I0 a8 p/ Z - v29 = *(_DWORD *)(v28 + 24);' }2 e1 c1 y" ?3 b! }- q+ V' V
- v30 = v40;7 |, H/ U9 k9 ^" q$ A
- if ( v29 + v26 + 1 >= (unsigned int)xRight )9 }8 q) U# e0 R
- {1 D/ m0 S$ c" |: Q7 h
- v26 = 1;/ k4 I9 L7 ~: s+ B U, O
- v30 = v40 + *((_DWORD *)v11 + 3) + 1;. s: h0 G/ L) X u9 z
- v41 = 1;
; g1 t" N1 P" h3 B - v40 += *((_DWORD *)v11 + 3) + 1;% E* p" `4 r' I$ q i, g& h
- }: {0 }" |3 O0 ^" m3 J% a3 T8 d: \ o
- *(float *)v28 = (double)v41 / v49;
0 |5 E8 j; _7 M- x - *(float *)(v28 + 4) = (double)v40 / v50;
+ \$ u. f2 K. y% _ - *(float *)(v28 + 8) = (double)(unsigned int)(v26 + v29) / v49;
, r: a. M0 A" a7 `# d - v31 = v26 - *(_DWORD *)(v28 + 20);- r2 {0 c+ d; {4 ]2 Y4 e) e/ o, t
- *(float *)(v28 + 12) = (double)(v30 + *((_DWORD *)v11 + 3)) / v50;
: L1 T$ A! d, @% g( d - TextOutW(v18, v31, v30, v42, 1);
& v* J2 m" m( j: s: p - v44 += 32;
+ G' b4 P" O' z5 s g, D+ D, g - ++v42;6 q' p4 `3 K" f7 Z# S9 \
- v33 = __OFSUB__(v43 + 1, *((_DWORD *)v11 + 4));4 e* q4 _8 @" w
- v32 = (signed int)&v43[-*((_DWORD *)v11 + 4) + 1] < 0;( O, A: t/ F" [% t( Z8 k3 a
- v26 += *(_DWORD *)(v28 + 24) + 1;
& ]+ u M4 Y, r9 R# J - v41 = v26;
+ f0 e3 h7 ^, C/ I' ?( e - ++v43;
7 u: m; C8 T- f8 T! h - if ( !(v32 ^ v33) )
- B' d: B. B6 I% Q! m - break;
' w5 |* L! g! p2 ]. B- y6 f; g) c - v27 = v42;
) ?- W' G7 S: l4 R0 [ - }, Q; @( Y8 I7 V+ t1 N# F! m- P7 X) W( w# A
- }5 T7 s m% I$ l% Z I
- v34 = CKBitmapData::LockSurfacePtr((CKBitmapData *)(*((_DWORD *)v11 + 6) + 56), -1);' `$ k' @% b- K5 e( a
- if ( v34 )
' W2 Y$ y- h# X! b- ~- R - {
# R0 p, c r) r! h. v5 W5 n; y$ p - GetObjectA(v45, 24, &v51);9 _; M! a0 d) c9 ?) Y
- v35 = v53;
T2 u+ Z" N( p y5 N3 ? - v36 = v55 + v54 * (v53 - 1);
# h( }9 W" @$ u( o, }$ Z - v40 = 0;
6 ?) |, Z, p0 d* z9 M - if ( v53 > 0 )# L: k; I% o% S* m) r Q
- {
4 h* k O& x. M- }" {$ ` - v37 = v52;0 l h6 i8 z \# ~" _( R; ?
- do/ h6 p/ I2 Z$ Y, _9 B/ R- }1 [& b
- {, E' i+ E8 h( `- a& t0 R
- v38 = 0;
& ]3 }. g4 T. }3 Z# b- { - if ( v37 > 0 )
, U4 z6 D$ L# m0 o0 d - {: x: \/ ]6 m3 E
- v39 = (unsigned __int8 *)v36;
! X& q0 k, S" n) X& p' Z% | - do
$ ^5 W4 U+ U0 Z/ R5 X8 T! k+ t - {
+ H2 \! H3 `& y4 f - *(_DWORD *)&v34[4 * v38] = (*v39 << 24) | 0xFFFFFF;/ ]0 b2 A0 C' A% V5 t a0 K
- v37 = v52;
+ M9 [% C3 W+ ]& o) `/ H4 u' r - ++v38;8 V8 C- R* U3 B. }% g
- v39 += 3;
5 t- r) J3 x+ O - }; u( j- J4 l4 D" _6 f/ U
- while ( v38 < v52 );
* i* }# d: x6 j c2 p8 A0 Z - v35 = v53;
- _5 F2 _2 t r - }
- o" N8 I( m0 _4 k3 O - v36 -= v54;
, w; d9 E# C3 N4 t8 i - v33 = __OFSUB__(v40 + 1, v35);+ t3 Z! H* ^# {+ D) l0 ]" h0 L
- v32 = v40 + 1 - v35 < 0;
" Z* B3 ?) i8 \0 o; e* V3 z N - v34 += 4 * v37;* Z$ x! h/ y) O' Q. A ~
- ++v40;4 l8 ?3 j" @3 n/ u. b
- }
2 T" P u( j7 t. H& f [ - while ( v32 ^ v33 );
7 W6 V" T8 o$ L; @2 s/ T$ p - }5 V0 R7 J* F- V! c. o
- }8 M2 _ n4 l! m; N! `( R
- CKBitmapData::ReleaseSurfacePtr((CKBitmapData *)(*((_DWORD *)v11 + 6) + 56), -1);+ d/ _$ T3 m& p- ^& p
- SelectObject(v18, v46);
7 L' \' i1 x5 r) i% @0 `% v - VxDeleteFont(v48);4 m) O8 ~% t" h4 _, O
- SelectObject(v18, v47);! Y) y* Y, {! L
- VxDeleteBitmap(v45);
2 m' m" j" ]6 L. e2 @3 |, f - DeleteDC(v18);2 J6 W. p4 ]4 S, t3 f' b
- CKObject::SetName(*((CKObject **)v11 + 6), (char *)a3, 0);
5 r) k3 J# W& `, F - CKBitmapData::SetDesiredVideoFormat(*((_DWORD *)v11 + 6) + 56, 1);
7 b _6 N/ w; H+ u! U1 w' w8 X& d* i: F - (*(void (__stdcall **)(_DWORD))(**((_DWORD **)v11 + 6) + 120))(0);
" J4 U8 O0 J9 ^3 a - return v40 + *((_DWORD *)v11 + 3) < yBottom;
4 X: Y" j$ d1 B+ P# Z - }+ @7 L3 P4 |7 s5 u
复制代码
( v- P* L% g( _! s5 O4 L
9 y" _; D7 `- @% _ |