本帖最后由 shane007 于 2023-8-26 17:10 编辑 0 O8 M$ |0 M G9 A3 L
4 \* H8 H4 _1 q8 m. U/ S4 h- ?- l8 I
这个游戏的主要修改点在\player\BuildingBlocks目录下的Adventure.dll中。8 I" J1 {5 P; V$ W3 i1 w
用API monitor对本DLL的CreateFontA函数进行跟踪,发现确实有调用, 参数如下。
$ K+ J' j7 L2 \% \2 q5 x4 o1 s
/ k1 [! j$ m& H7 ?: R- # Type Name Pre-Call Value Post-Call Value
6 _. G9 i a- w+ T, e8 ] - 1 int nHeight 0xfffffff0 0xfffffff0
7 F( d# ]9 ?, u2 d - 2 int nWidth 0x00000000 0x00000000/ T- R* t- @. P. j' C
- 3 int nEscapement 0x00000000 0x00000000
+ @5 ?# h8 m* ^4 i, x, T8 n - 4 int nOrientation 0x00000000 0x00000000
% V$ a* M- }- p2 D4 h# g6 Y - 5 int fnWeight FW_NORMAL FW_NORMAL
+ ]1 C! ?/ a& O: a: `8 U: q Z) l - 6 DWORD fdwItalic 0x00000000 0x00000000) T* r: ^* D9 ], W* m8 |: E/ W1 J" y
- 7 DWORD fdwUnderline 0x00000000 0x000000008 @& E2 o q ^
- 8 DWORD fdwStrikeOut 0x00000000 0x00000000
) ]6 x6 u7 Z2 h: Z - 9 DWORD fdwCharSet DEFAULT_CHARSET DEFAULT_CHARSET
6 H5 y( {8 w \: ? - 10 DWORD fdwOutputPrecision OUT_TT_ONLY_PRECIS OUT_TT_ONLY_PRECIS0 Z' B1 z4 r6 g) i4 I5 K+ a
- 11 DWORD fdwClipPrecision CLIP_DEFAULT_PRECIS CLIP_DEFAULT_PRECIS8 X5 R C9 R# E9 z% U0 w( e
- 12 DWORD fdwQuality PROOF_QUALITY PROOF_QUALITY
9 }# e! ]6 T& k; ~ - 13 DWORD fdwPitchAndFamily FF_DONTCARE | DEFAULT_PITCH FF_DONTCARE | DEFAULT_PITCH- z0 _' j& l* b
- 14 LPCTSTR lpszFace 0x09148a58 "Arial" 0x09148a58 "Arial"" w1 i$ z( B" W( C. z5 j0 d! M
复制代码
- m% G5 S2 n+ Z( W# J; F3 E; R; W8 U0 p, r. s
用ida pro找到调用CreateFontA的源头函数如下。
) K5 K9 s0 j& D; v从函数的参数可以看出,这应该就是字幕显示函数了。
: C B$ w# x8 P关于后续修改,先修改CreateFontA函数的fdwCharSet,lpszFace这2个参数,也许就能出中文。, p/ a: {: m1 N) w* \5 |5 i
还不行的话,就自己写一个显示函数。以下函数中lpMultiByteStr就是指向字幕的指针。1 P, x/ w+ `4 }- K" c, j4 T2 m$ y
# O% q- e9 F" @- 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)% G2 W% v0 S6 Y' a2 F% E: E) D
- {
) y4 P$ A7 S8 C+ Y - void *v11; // edi
7 ]' g) ]* _( o6 _% v& b& L - int v12; // eax
: i1 r9 B1 b# o& e7 b - int v14; // ecx
1 E* w6 |! Y5 M+ `2 g - int v15; // eax2 Z+ f; s: x2 u" S* O$ F0 g
- char *v16; // eax
6 _7 m* w/ E) D - int v17; // eax
! x% J+ ~; m7 n7 g2 J. } - HDC v18; // ebp6 H) _3 ?, c) z$ Q3 ]7 R! Z# ]
- int v19; // eax
( `% x5 e5 ^ G; N - int v20; // eax
; d6 L) K, [# K% Y+ j$ Z - int v21; // esi
1 s9 c/ ^& H% H4 m( D - char *v22; // eax
# V! q8 {4 ` Z0 M - int v23; // esi" [2 r+ M" Q9 Y, R- n( o
- int v24; // ecx/ W' f/ \% V5 a e3 i! P( F
- HBRUSH v25; // eax
& K$ l9 d* K& V, K - signed int v26; // ebx
! ^& }) z3 x4 V. H6 k2 g1 w) ~ - WCHAR *v27; // eax5 c5 B! V! V* q* g5 z
- int v28; // esi
6 e- U2 M* T' W - int v29; // ecx
# ]' i& u" \- q- C - int v30; // eax
% T+ }1 I8 U$ ^: A2 s& P i6 X1 G - int v31; // ST28_4
# c- w2 k$ E! P4 q - bool v32; // sf
1 X- ^- ]. P8 ^$ a/ I* u( K - unsigned __int8 v33; // of( }7 |8 f; Z o! P; j. w# d
- unsigned __int8 *v34; // ebx3 U$ X, Y) y% g4 d' S B1 m6 q9 P
- int v35; // ecx
/ S! J& R4 q2 ]& _& B0 a! T& X - int v36; // esi
( y+ b" t4 I3 b4 ]9 b& E- f$ b - int v37; // edx
5 t) f# J/ J) W+ f - int v38; // eax
F; ~9 D; ^8 I" P3 q$ x4 s/ L - unsigned __int8 *v39; // ecx) }4 L. H4 x/ r: A+ W/ i
- int v40; // [esp+40h] [ebp-2098h]5 E5 [* N- y& s: t( w; r) m) X- r5 ^
- signed int v41; // [esp+44h] [ebp-2094h]
$ {+ K- k8 [$ g; ]" V( S- p3 C - WCHAR *v42; // [esp+48h] [ebp-2090h]5 g& g0 Y# v/ M' Y2 [
- LPCSTR v43; // [esp+4Ch] [ebp-208Ch]4 r8 K. A9 [! N& |+ h/ G8 h J$ @9 Y
- int v44; // [esp+50h] [ebp-2088h]! C' k* x5 O0 }
- HGDIOBJ v45; // [esp+54h] [ebp-2084h]
, P% P- Z) q7 i' m0 y3 ~$ ~% p - HGDIOBJ v46; // [esp+58h] [ebp-2080h]( X8 u0 N u9 w: M1 F) g" P
- HGDIOBJ v47; // [esp+60h] [ebp-2078h]0 u- i/ l o1 L* m, k; O1 y
- HFONT v48; // [esp+64h] [ebp-2074h]1 V! @' b% w2 z7 U( T
- float v49; // [esp+68h] [ebp-2070h]
2 `% _4 H$ ?# V! d - float v50; // [esp+6Ch] [ebp-206Ch]
' O0 S( e; t" r8 X- v0 ^ - char v51; // [esp+70h] [ebp-2068h]
3 C( R5 ~0 U' N# _+ f& }2 u - int v52; // [esp+74h] [ebp-2064h]% {/ z8 u& H. d9 `6 y! W% |6 P
- int v53; // [esp+78h] [ebp-2060h]
% u# T$ i! v4 k, l: l - int v54; // [esp+7Ch] [ebp-205Ch]* K* l( O2 }+ N( k3 c8 ?5 z
- int v55; // [esp+84h] [ebp-2054h]; t) n2 @- i0 s; D( S
- struct tagSIZE v56; // [esp+88h] [ebp-2050h]- ~$ A- f! k9 A/ b$ U) ~
- struct tagRECT rc; // [esp+90h] [ebp-2048h]. f( G/ ?6 T \
- int v58; // [esp+A0h] [ebp-2038h]
# R% u+ p2 t& T- r0 R - char v59; // [esp+A4h] [ebp-2034h]
3 \/ S8 j/ V! }. v' l - WCHAR WideCharStr[4096]; // [esp+D4h] [ebp-2004h]
# b: `1 h% x4 o, f1 s9 e
" ?$ A, Z5 N- |5 [# v! @0 Z: W# Y- v11 = this;
, b! ~2 V+ n0 ] - v58 = 52;
6 g5 Y2 i& f$ O3 F* O" a4 _ - memset(&v59, 0, 0x30u);
6 E9 l; y+ J0 C2 Y! K - if ( *lpMultiByteStr )/ q L8 N6 m) l8 l, w2 S! |
- {4 b6 O' i1 q! {9 L+ D. u/ l) w
- v12 = MultiByteToWideChar(0xFDE9u, 0, lpMultiByteStr, -1, WideCharStr, 4096);
4 e0 C5 d/ u, B/ ` - *((_DWORD *)v11 + 4) = v12;" P, f; m. ~# Z. |$ T
- if ( v12 <= 1 )+ @( M( F6 F( @; Q3 a/ n
- return 0;
$ }. \7 r' H5 x; F ^% m! H - *((_DWORD *)v11 + 4) = v12 - 1;
5 q, L. }- }6 c% B3 Y. d - qsort(WideCharStr, v12 - 1, 2u, sub_10057A40);& X; t4 L8 \: ?2 w- V5 L) `+ _5 w5 Q
- }" z6 A" `7 A* j
- else
" z* n) H: C5 @" J p - {: j9 }7 p8 Q2 Q/ E) J1 `) T. u5 l! R
- *((_DWORD *)v11 + 4) = 352;. ~/ D+ x$ l) [4 \0 u$ u+ L
- v14 = *((_DWORD *)v11 + 4);* X* u5 q' [" d1 V
- v15 = 0;4 E! M8 Q- _+ A) A6 H+ v
- do8 l; \5 Z- w8 a4 q2 U2 h
- {
6 n% c) o) R7 d/ }4 I - WideCharStr[v15] = v15 + 32;
8 Y( t! x6 I$ s% l! i* _* J - ++v15;
. P: x7 `! b4 j8 O - }) _2 p( I0 [7 Y+ w% |* Z, t8 d! w2 r
- while ( v15 < v14 );& X! G& J6 q' e& G
- }6 J" Z5 ^- f, _0 V
- v16 = *(char **)v11;4 e$ ]* `+ U6 }1 i) ?
- if ( !*(_DWORD *)v11 )# H$ `7 i1 M6 h& c* p
- v16 = byte_100B2D6E;
: P8 X; i# h. b6 r! b3 h9 P6 h - v17 = CKContext::CreateObject(a2, 31, v16, 0, 0);* C- t+ g) s+ B6 y# `4 B' q, w
- *((_DWORD *)v11 + 6) = v17;
+ u& ~. Q% s' I. e6 I* R, m/ J - if ( !(*(int (__thiscall **)(int, int, int, signed int, _DWORD))(*(_DWORD *)v17 + 84))(v17, xRight, yBottom, 32, 0) )8 x( W! u$ e J; C5 f
- return 0;
: M- J7 O0 @0 a% I9 r - (*(void (__stdcall **)(int *))(**((_DWORD **)v11 + 6) + 136))(&v58);
% s+ z7 ~" F( Z9 S - v18 = CreateCompatibleDC(0);
% f7 o& a @1 A - v45 = VxCreateBitmap((const struct VxImageDescEx *)&v58);
0 e- C9 r6 n5 [6 I - v47 = SelectObject(v18, v45);
' O) r$ K! o' T+ H9 _9 H5 p+ N% Z: [ - XString::operator=(v11, a3);0 a' }2 E2 j; Y3 |0 p# A4 v7 g
- *((_DWORD *)v11 + 2) = nNumber;( W1 }- b3 I. \* J1 C0 y5 j$ O$ \, H! C
- v19 = GetDeviceCaps(v18, 90);
9 w E4 N0 h' i6 @) t - v20 = MulDiv(nNumber, v19, 72);7 R9 t9 j. s$ O9 |) P
- v48 = CreateFontA(-v20, 0, 0, 0, a6, a8 & 1, ((unsigned int)a8 >> 1) & 1, 0, 1u, 7u, 0, a7, 0, (LPCSTR)a4);3 W b% ^6 W1 v
- v46 = SelectObject(v18, v48);( @& D F0 f( F5 u
- GetTextExtentPointA(v18, "A", 1, &v56);
0 t/ @ r% _' v6 g$ `+ o - v21 = *((_DWORD *)v11 + 4);
5 Y; |+ T' D# z5 f8 `3 z2 W; z! m - *((_DWORD *)v11 + 3) = v56.cy;
' |5 ^" I/ D% r - v22 = (char *)operator new(32 * v21);
" u/ G. @5 d. H! p - if ( v22 )
: G: u0 S$ [, C - {
( t5 a& p B0 ~) e) K* t/ O0 U - v23 = v21 - 1;8 [! `! o L$ I; y! m) D
- if ( v23 >= 0 )9 [, ]# l4 C* ^$ V3 I0 l" q3 D( N
- {
; R" I7 H8 d% ?; Y4 n - v24 = (int)(v22 + 12);
) g/ R! }/ n- J7 E - do" F. F. W O7 o
- {
, Z" P: Y5 q5 a9 w8 h3 Q - *(float *)(v24 - 4) = 0.0;
& ^% @5 E" v5 O9 c* o+ r$ W% J - v24 += 32;0 c2 e( Q" k# I# h. \7 w# x
- --v23;6 q9 u/ D# I8 M. t. x9 \- t2 W
- *(float *)(v24 - 32) = 0.0;2 _4 u, q: s" J& B( ~3 x( W/ ?
- *(float *)(v24 - 44) = 0.0;0 h" W1 s6 S0 \0 @
- *(float *)(v24 - 40) = 0.0;
% C0 k0 s/ _5 }6 D# l( c - *(float *)(v24 - 36) = 0.0;" _) V9 O; K o, r
- *(float *)(v24 - 32) = 0.0;; K' H% {/ Y& \! {+ }: A' `2 i
- }4 A3 D' @3 n9 d
- while ( v23 >= 0 );" N: H" K% H! U8 q) W
- }
( M. `# ]8 Z6 G9 ]1 m - }
8 h; }0 w( U) i - else
; x9 h- A7 L4 ^ - {
- z7 p% L5 \4 A2 O - v22 = 0;8 P4 e3 u2 D- m9 [, p% A+ W
- }& ~% ]# y* m* V/ s. o
- *((_DWORD *)v11 + 5) = v22;& J6 _+ Q( p8 l' P4 b
- SetRect(&rc, 0, 0, xRight, yBottom);" q2 K" `. h' e; ], F; z( F
- v25 = (HBRUSH)GetStockObject(4);
3 _8 T6 A/ ] r/ x: |, j$ E7 ~ - FillRect(v18, &rc, v25);* F5 m4 Y! V1 n6 t. ^8 H; g- W
- SetBkColor(v18, 0);. m% o" w# _4 S. z
- SetTextColor(v18, 0xFFFFFFu);
0 H6 l+ }2 d2 ^' m, N - SetBkMode(v18, 1);; y7 s) B" F+ `" W7 t) c. K
- v26 = 1; }# F- q* E, p1 _' Q
- v41 = 1;
: q" [0 K+ q3 e - v40 = 0;( G l5 N( h1 l' i' ]
- v43 = 0;, r) a) s0 S- z" I3 |/ `1 y
- if ( *((_DWORD *)v11 + 4) > 0 )
- x- r5 h0 L+ m - {6 p% s) p9 i: A: A- \0 y/ }9 O
- v27 = WideCharStr;
8 x- Q. q$ Q5 x* o1 r" X+ l - v44 = 0;+ X) }! E$ P* } u' f h
- v42 = WideCharStr;
3 D5 H0 w s/ p4 I - v49 = (double)xRight;
$ c, U$ A: S/ p6 G1 E! q7 w+ [ - v50 = (double)yBottom;
7 F; ^- {7 R1 B$ u6 ~' K - while ( 1 )
; M' I5 K' c6 x, R - {5 Y1 @% x% m _% R ], O; }
- v28 = v44 + *((_DWORD *)v11 + 5);
: K) e1 K" ]$ G: R8 s" ~ - *(_WORD *)(v28 + 16) = *v27;9 M; K& }8 r8 D+ R$ W! ~1 _
- GetCharABCWidthsW(v18, *v27, *v27, (LPABC)(v28 + 20));
~: R' V% z! v% Q' R7 |% I - if ( *v42 >= 0x20u )
- L1 z9 d3 q9 N - {6 y, W* J+ C& B8 O1 I6 N1 h
- --*(_DWORD *)(v28 + 20);
9 k5 R- P$ X1 A/ p) g! ? - *(_DWORD *)(v28 + 24) += 2;" g0 y3 H6 J. ~( @9 V
- --*(_DWORD *)(v28 + 28);
. Y$ w& F* W* Y$ ?# \4 U. ~% h6 | - }3 f& V1 d8 J2 X" o: P- i
- else; I$ q8 z* Z" X9 V: H+ O- E
- {- a& k; ? v d9 q( w
- *(_DWORD *)(v28 + 20) = 0;! Y4 s3 l" @$ Q* d- A: K0 j
- *(_DWORD *)(v28 + 28) = 0;7 i+ Q. ` v( E9 S# ?" {
- }
; u. w6 |1 x/ p" T - v29 = *(_DWORD *)(v28 + 24);
* J0 j; ^" c! F) H% L: { - v30 = v40;
3 r0 ?. h g0 X' U - if ( v29 + v26 + 1 >= (unsigned int)xRight )
+ B+ Z: V3 A: x - {# @$ V- K- d# D2 Z) K& f
- v26 = 1;
! G0 q- `" j' S) H' [ - v30 = v40 + *((_DWORD *)v11 + 3) + 1;1 C$ Q* C+ ?! D5 T9 S
- v41 = 1;; ?8 E+ R) [0 A% s3 h* `
- v40 += *((_DWORD *)v11 + 3) + 1;! w' h3 u1 M/ F# d1 Q. \# A, T7 G
- }' ^+ A& n9 p( c- S& U
- *(float *)v28 = (double)v41 / v49;
' C, P# U+ G' }- V% v/ W - *(float *)(v28 + 4) = (double)v40 / v50;
# c2 v' L2 j9 }& `" R6 O; K& P - *(float *)(v28 + 8) = (double)(unsigned int)(v26 + v29) / v49;. F* e& |. S. v6 n9 k2 R
- v31 = v26 - *(_DWORD *)(v28 + 20);
' z4 ^ o. z: M2 S6 K - *(float *)(v28 + 12) = (double)(v30 + *((_DWORD *)v11 + 3)) / v50;
% X- I( R3 D' y$ Y# P - TextOutW(v18, v31, v30, v42, 1);' w5 O: Q F# l& ^& h" b$ _6 d
- v44 += 32;% H7 o$ Q, x3 l3 c2 s8 C- W- C
- ++v42;8 ]9 ]) m( P) k( Z) p
- v33 = __OFSUB__(v43 + 1, *((_DWORD *)v11 + 4));
- B5 v1 T9 p: j- @9 L - v32 = (signed int)&v43[-*((_DWORD *)v11 + 4) + 1] < 0;
9 d# \! ~$ h$ ? t - v26 += *(_DWORD *)(v28 + 24) + 1;( W& r; {# J0 K( Z0 B/ N
- v41 = v26;
4 x+ D/ I$ N9 ]0 r. y, S" r - ++v43;
8 M. @. T$ d" ? - if ( !(v32 ^ v33) )
n# r8 i3 g& w - break;
; N4 q }) A; c# x' D; a$ i3 Q5 e, y - v27 = v42;4 @" p; f/ g0 S
- }: @+ A x5 O: I4 L% q
- }, v8 i, h5 M+ b; C1 p1 `8 g. U
- v34 = CKBitmapData::LockSurfacePtr((CKBitmapData *)(*((_DWORD *)v11 + 6) + 56), -1);
: S: ~* ]% P. @( a2 A" h& C ^ - if ( v34 )' h6 C8 t+ M( v9 s4 J1 X
- {& e2 l5 Y& c) X* e3 u) h2 M
- GetObjectA(v45, 24, &v51);
) B% h1 M! ]& {! U6 B: ~' Q& R - v35 = v53;, H2 v2 E3 g3 {0 J3 _
- v36 = v55 + v54 * (v53 - 1);" c) v* |: ~- j: h5 u* \
- v40 = 0;) T7 b k5 d8 H7 O* Z, `
- if ( v53 > 0 )
. G& s9 X9 }+ M* ~2 [# M W - {! _. i1 k% W; E
- v37 = v52;
/ i: a& g- w. r& n5 L5 h - do; H3 {8 a& V5 V' n7 E$ q
- {, l5 W, G5 m; ]3 L! Q( k1 r& o6 L1 H
- v38 = 0;
3 T9 D! X+ v+ R8 n - if ( v37 > 0 ): h2 J. B6 T1 t
- {" O+ d M0 S; _) g
- v39 = (unsigned __int8 *)v36;
* x* }3 T3 e7 d - do& ` N1 }& i% _
- {
" j( v: Q$ M7 p/ S - *(_DWORD *)&v34[4 * v38] = (*v39 << 24) | 0xFFFFFF;9 e( j+ \& d# f
- v37 = v52;
, W& s* @4 {" f. ]# k- _5 G - ++v38;, \) _; q, q4 @+ Y8 f: Y' q
- v39 += 3;9 z* {/ u+ X; ^: I4 d
- }( ^: v- C6 U1 L, r/ F% U
- while ( v38 < v52 ); W' \; Z9 g7 J1 T: i5 n- x
- v35 = v53;
! S; O- k% O5 N8 F: M% L7 j - }
$ Z1 l' U5 a( E# z' Y - v36 -= v54;
; L: L( ?, }- S1 G# c - v33 = __OFSUB__(v40 + 1, v35);
. I7 v8 i% B) Y6 D4 Z - v32 = v40 + 1 - v35 < 0;
3 e4 j+ m( [: I; t+ {, x5 a - v34 += 4 * v37;; b0 J% s/ M' u# D: ~
- ++v40;* F+ u" I4 |# D) M
- }6 U. F" v; P& d+ d+ ~ Z7 |1 T
- while ( v32 ^ v33 );
. ] H( x' I q! w - }. r; o! S, H$ D' Z! z0 g( z
- }
2 A/ v. p* O8 J- M7 A. _: ` - CKBitmapData::ReleaseSurfacePtr((CKBitmapData *)(*((_DWORD *)v11 + 6) + 56), -1);
- p9 N! W1 K2 ]* S$ J. X+ o1 J - SelectObject(v18, v46);4 r1 @& Q! b, o8 H" J
- VxDeleteFont(v48);, A4 D6 v2 E! W; B% F2 |
- SelectObject(v18, v47);
9 a. D' w" D9 p0 a3 V - VxDeleteBitmap(v45);+ p) g3 b0 J. M5 ?: O @
- DeleteDC(v18);/ ]. \- W' ~% Y# v
- CKObject::SetName(*((CKObject **)v11 + 6), (char *)a3, 0);$ L. [* V+ ^" Z0 f* m; \: P
- CKBitmapData::SetDesiredVideoFormat(*((_DWORD *)v11 + 6) + 56, 1);
- L5 F9 ]# y; q! O$ @ - (*(void (__stdcall **)(_DWORD))(**((_DWORD **)v11 + 6) + 120))(0);
# j* G1 _& C2 A) r - return v40 + *((_DWORD *)v11 + 3) < yBottom;
+ {! [# j6 M, |4 U/ z - }
; m/ k7 y, a- U/ [
复制代码
) X" H% }2 ^0 a3 G6 b
6 w3 w: N6 P" @/ O( M% I0 o+ [ |