本帖最后由 shane007 于 2023-8-26 17:10 编辑 ! J! F2 D6 D, O( x* P: f4 P
. n. z5 a) y; C9 R% X这个游戏的主要修改点在\player\BuildingBlocks目录下的Adventure.dll中。 {' t3 i& u% m1 O* k
用API monitor对本DLL的CreateFontA函数进行跟踪,发现确实有调用, 参数如下。6 Q& A8 g" `0 g/ ` i, C: I$ c
0 H6 {" k( a/ e& Y; j( z2 T4 L- # Type Name Pre-Call Value Post-Call Value/ Y1 U5 }' o9 p' x: T V
- 1 int nHeight 0xfffffff0 0xfffffff0
6 g t- G# h! P/ T7 Z - 2 int nWidth 0x00000000 0x00000000
. c& `( Y- l/ [) r( L2 | - 3 int nEscapement 0x00000000 0x00000000& Z F# B! w' p" S5 {8 B7 I0 r
- 4 int nOrientation 0x00000000 0x00000000$ m& {2 ~4 v- a# V3 M7 p
- 5 int fnWeight FW_NORMAL FW_NORMAL( ~ q" z& k- h9 r7 A5 D
- 6 DWORD fdwItalic 0x00000000 0x00000000' V1 w3 W, B8 K# R& E
- 7 DWORD fdwUnderline 0x00000000 0x00000000/ E3 p1 M q$ U) b0 p
- 8 DWORD fdwStrikeOut 0x00000000 0x00000000
3 }6 E1 F* b/ z b. T* y - 9 DWORD fdwCharSet DEFAULT_CHARSET DEFAULT_CHARSET
3 y* }/ |4 ?* T- V5 p. t6 Z - 10 DWORD fdwOutputPrecision OUT_TT_ONLY_PRECIS OUT_TT_ONLY_PRECIS
6 e- m, O7 S6 N - 11 DWORD fdwClipPrecision CLIP_DEFAULT_PRECIS CLIP_DEFAULT_PRECIS( i, l# \' ^, |* ?& u' c" l$ Q5 x
- 12 DWORD fdwQuality PROOF_QUALITY PROOF_QUALITY
! y9 h) D* B9 ~, d4 c( _9 E# U - 13 DWORD fdwPitchAndFamily FF_DONTCARE | DEFAULT_PITCH FF_DONTCARE | DEFAULT_PITCH
( F$ a2 H) h1 H- w3 i8 K - 14 LPCTSTR lpszFace 0x09148a58 "Arial" 0x09148a58 "Arial"
/ [& y) L4 _ y. G. P+ p$ i
复制代码 7 [# l- U' }2 s7 }1 X8 |- ~2 ]
0 s3 \( E1 `6 O: S- ]) \% D
用ida pro找到调用CreateFontA的源头函数如下。, h+ F# |4 C; Q* Y7 ^- j+ \& R
从函数的参数可以看出,这应该就是字幕显示函数了。
4 {" ]5 I4 R! ?" k关于后续修改,先修改CreateFontA函数的fdwCharSet,lpszFace这2个参数,也许就能出中文。 \, j5 L+ R9 r; ?' c4 r5 F
还不行的话,就自己写一个显示函数。以下函数中lpMultiByteStr就是指向字幕的指针。
7 u( r3 Q( {; b8 s- & ?2 V* Z O/ v9 v0 H
- 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) v0 @: o& ]# }, D( i& g
- {
& ?! V2 W3 W: O$ w4 i- w9 i5 ] - void *v11; // edi
( j% k! {2 _. p( ~) [) v - int v12; // eax& p3 g' H, H p2 W' [& }2 `
- int v14; // ecx9 Q# ?2 X# M# o
- int v15; // eax2 }3 b2 |9 u+ D2 {
- char *v16; // eax
- M( A) Y4 D0 F7 C: m! T: x - int v17; // eax; K) q# X4 l1 g/ p4 j
- HDC v18; // ebp' r8 G; Q4 n- F- i
- int v19; // eax
2 j% O+ s; L5 z( F* G; r - int v20; // eax
4 X6 x6 |+ E. H5 Q - int v21; // esi
$ d# B/ O$ f* t' L - char *v22; // eax/ U" h0 @( q+ O0 F$ e* l' x
- int v23; // esi
3 z4 Q. @# y6 I y1 d1 {4 a - int v24; // ecx" ~1 g) q* F; z! d" R7 Y( B+ J Z2 k
- HBRUSH v25; // eax
& Y+ |! x2 v3 E, K: \9 e3 J - signed int v26; // ebx7 {6 E! N' z& n) k( P) H
- WCHAR *v27; // eax
2 x: B- _ D1 T- `5 d8 d" i - int v28; // esi2 b9 s6 v, w, R; f' S
- int v29; // ecx. s! d3 i3 g" s% j* a
- int v30; // eax( `! V& k! I( }6 K8 w. W
- int v31; // ST28_4
$ `! ]8 M" j6 Z. Z- u, ? - bool v32; // sf
9 e' ^) F, u: ?1 D N' c - unsigned __int8 v33; // of
# p( N' b" V5 y5 n2 ]9 a) W5 d+ Y, P6 { - unsigned __int8 *v34; // ebx' w7 @+ C) L7 |) S5 Z" k
- int v35; // ecx! i6 B( o s" G3 [" T5 M6 F2 g
- int v36; // esi
/ k/ X6 C2 Z8 @& N$ { - int v37; // edx
6 [* V+ `: p! G4 | - int v38; // eax
: R: }2 a# I& G: A( a+ |' } - unsigned __int8 *v39; // ecx: t) q2 I9 |' g+ ?' W' {9 p
- int v40; // [esp+40h] [ebp-2098h]) J J5 h; P6 R2 y, O
- signed int v41; // [esp+44h] [ebp-2094h]
! ]$ k+ G# m) ]; \/ A) H% k$ C - WCHAR *v42; // [esp+48h] [ebp-2090h]
2 R6 ~) R, c i$ { - LPCSTR v43; // [esp+4Ch] [ebp-208Ch]: b. Y ~, L5 ^3 G5 H$ F" n
- int v44; // [esp+50h] [ebp-2088h]5 \1 q0 g1 g9 O, X' o' }
- HGDIOBJ v45; // [esp+54h] [ebp-2084h]6 ?' \4 c. ?: [, Y! \9 a% Y) W
- HGDIOBJ v46; // [esp+58h] [ebp-2080h]
" s( r+ ~: Z3 i, X - HGDIOBJ v47; // [esp+60h] [ebp-2078h]- c! g2 @% Q. v8 {9 s% e* ]
- HFONT v48; // [esp+64h] [ebp-2074h]
/ }$ o6 E+ K5 x* ]7 ]$ d5 v0 W - float v49; // [esp+68h] [ebp-2070h]/ O8 j4 a* r. \
- float v50; // [esp+6Ch] [ebp-206Ch]
! g* h e% p1 y R1 `) T - char v51; // [esp+70h] [ebp-2068h]
) N- c/ e! ]* g4 l+ Q6 v - int v52; // [esp+74h] [ebp-2064h], O1 a& \" P2 }0 q5 ?8 ^
- int v53; // [esp+78h] [ebp-2060h]9 y) s' V% _$ r) f0 u: |
- int v54; // [esp+7Ch] [ebp-205Ch]
H; Z9 Z' x; N/ l7 d3 l - int v55; // [esp+84h] [ebp-2054h]" B" V4 I j% P/ o }" _ @
- struct tagSIZE v56; // [esp+88h] [ebp-2050h]
8 p+ w$ z* r; [' x% y2 L - struct tagRECT rc; // [esp+90h] [ebp-2048h]# r: n2 L u- J3 c% e8 J
- int v58; // [esp+A0h] [ebp-2038h]
$ P' p S+ i! ?( F5 \ - char v59; // [esp+A4h] [ebp-2034h]
% {# I+ s, F" f - WCHAR WideCharStr[4096]; // [esp+D4h] [ebp-2004h]
6 D8 X% e+ I! M
2 h0 V0 m( e, B. [6 {9 U$ Y/ C- v11 = this;
3 v! B: N$ r P2 G1 j1 Y; @2 L - v58 = 52;6 r2 }( v) }& k4 s4 b7 _1 @
- memset(&v59, 0, 0x30u);& n) X' x( `3 s9 E
- if ( *lpMultiByteStr )
) h% q, m/ \/ {. r0 |! m4 @ - { D3 N- ~* m* T2 s b- k
- v12 = MultiByteToWideChar(0xFDE9u, 0, lpMultiByteStr, -1, WideCharStr, 4096);
, X. ]: e* u. y7 H - *((_DWORD *)v11 + 4) = v12;
t- q. P8 U# ^8 j - if ( v12 <= 1 )" e6 c6 o0 M0 H5 m4 _
- return 0;1 {: e" v+ \3 ^- Z
- *((_DWORD *)v11 + 4) = v12 - 1;$ m$ R) U5 s% o% f
- qsort(WideCharStr, v12 - 1, 2u, sub_10057A40);7 n: X* v- y, x
- }8 w( q1 ~2 c2 s" Q, [7 e
- else
2 X' j/ t8 e% {% ~! D! J- _* M - {4 Z% E+ a) c7 }# h) V5 v
- *((_DWORD *)v11 + 4) = 352;- t* B% Q- j0 Q( F% b/ a+ H
- v14 = *((_DWORD *)v11 + 4);5 ]0 ~" I5 Q. c I
- v15 = 0;
6 g) o. S1 _; c. {) H/ _3 h5 L - do
! U) f4 l0 \* O - {
: W! c" C( l; q! o - WideCharStr[v15] = v15 + 32;
4 i+ V' J" @$ q2 B4 U; E! |: p q - ++v15;
* H! c$ y: @& n! J' ?; r - }
- v: T* s d( W4 } - while ( v15 < v14 );
0 c3 P2 h! D3 u! w ?+ D - }$ G3 p% z9 ~0 Y3 l4 o
- v16 = *(char **)v11; i* s- H5 x; ~4 O+ _2 x+ J
- if ( !*(_DWORD *)v11 )! V) ?% C* U8 J: i6 P4 L; c
- v16 = byte_100B2D6E;
8 G1 D5 ? `8 B r |2 U) B h - v17 = CKContext::CreateObject(a2, 31, v16, 0, 0);4 ]5 i6 D+ l# n$ O. B3 Y- N
- *((_DWORD *)v11 + 6) = v17;, ~7 T; d) @/ C0 L8 w
- if ( !(*(int (__thiscall **)(int, int, int, signed int, _DWORD))(*(_DWORD *)v17 + 84))(v17, xRight, yBottom, 32, 0) )
* x. Y! A+ g$ X( N$ Z/ V - return 0;
0 C7 n" u8 V9 V) r3 o - (*(void (__stdcall **)(int *))(**((_DWORD **)v11 + 6) + 136))(&v58);8 F9 [" T* i3 s" w" F! d
- v18 = CreateCompatibleDC(0);7 p ? P7 U! s! h$ i- E) ]
- v45 = VxCreateBitmap((const struct VxImageDescEx *)&v58);# `% n0 E2 X I' S/ J
- v47 = SelectObject(v18, v45);
7 ]& \% n3 g1 b; Y' t7 B - XString::operator=(v11, a3);8 T: ^% l4 g: X2 v4 m; a; Q! y
- *((_DWORD *)v11 + 2) = nNumber;
- m; I) i* U9 r4 @* ^ - v19 = GetDeviceCaps(v18, 90);
: R+ z9 a. C3 y; _ - v20 = MulDiv(nNumber, v19, 72);9 G S) T# A* T6 \
- v48 = CreateFontA(-v20, 0, 0, 0, a6, a8 & 1, ((unsigned int)a8 >> 1) & 1, 0, 1u, 7u, 0, a7, 0, (LPCSTR)a4);4 r) b+ h; ^4 l( ^
- v46 = SelectObject(v18, v48);
- O" ?, J- C; z" X0 f - GetTextExtentPointA(v18, "A", 1, &v56);
; J7 d& l! Q4 Q1 i; ^6 ?; s - v21 = *((_DWORD *)v11 + 4);9 c9 H* q' t) E7 }7 ]9 f8 \8 V
- *((_DWORD *)v11 + 3) = v56.cy;
' p, T0 {2 Z9 [' ] - v22 = (char *)operator new(32 * v21);6 z1 V) E; z7 I
- if ( v22 )7 @- ^6 T% r' \0 a
- {
* Y4 O9 ~2 c$ J8 E J1 g+ N - v23 = v21 - 1;2 I/ `4 Z7 _5 \# J
- if ( v23 >= 0 )
- B2 n2 b, i8 v6 J2 C - {
4 y$ p, X. G: n: Z+ f1 \6 J G T0 _& Z - v24 = (int)(v22 + 12);
1 G# C# }1 Z; I# h7 V - do# i+ [0 j3 ?3 [# w! R
- {+ x z) o6 Y0 |/ N
- *(float *)(v24 - 4) = 0.0;& x& Z, P, G: o; q% y; K/ A
- v24 += 32;$ d' V5 P( p5 H8 l! C- M2 K
- --v23;+ _2 u: a8 |* r; y
- *(float *)(v24 - 32) = 0.0;
2 j8 w* s+ e8 W3 |+ s - *(float *)(v24 - 44) = 0.0;2 v( x- _% f7 r1 h- J
- *(float *)(v24 - 40) = 0.0;
4 O5 [8 H% W9 N0 j, W - *(float *)(v24 - 36) = 0.0;
! d; l# {. X9 y' e" N - *(float *)(v24 - 32) = 0.0;. X2 i) g; E" O2 ]6 ~
- }3 h0 X+ g: R8 e9 ~: w
- while ( v23 >= 0 );
0 N' X+ P, P. V: w/ }- V- j - }. p& A9 G8 v. A3 S
- }
$ d8 c7 {6 | ^: _ - else
: _. Q( u! C: Z. T. p2 _/ p - {
! f* u7 E! J5 m& P2 @1 D1 s! S - v22 = 0;
) U% U4 A5 K: n$ @0 K1 c1 ^ - }
" K8 r* M( Z: N" \ - *((_DWORD *)v11 + 5) = v22;3 M* }/ N* s. D7 j1 I @
- SetRect(&rc, 0, 0, xRight, yBottom);* o& h8 n# d: J; n2 Q$ v+ K
- v25 = (HBRUSH)GetStockObject(4);
5 H3 C6 Q: }' e - FillRect(v18, &rc, v25);' h; d; P1 u/ n9 U/ y; g+ C
- SetBkColor(v18, 0);
. a* T) E+ r+ p - SetTextColor(v18, 0xFFFFFFu);
p5 l9 V" j) l" ` D& ~! m7 I* J - SetBkMode(v18, 1);
' T, |2 r+ c L9 J1 ] - v26 = 1;
! R$ |5 \8 I- J+ Z - v41 = 1;
2 f2 u9 s+ V1 h3 Y$ l Y5 t - v40 = 0;% d3 }0 Q* r' o/ K7 O0 @5 `" R
- v43 = 0;( u* a @/ i: x1 M
- if ( *((_DWORD *)v11 + 4) > 0 )
4 o% J* v7 J% d - { b, v: j# ?) O- e
- v27 = WideCharStr;/ B! p9 R0 I2 l8 b
- v44 = 0;5 _7 F0 l8 t8 W A6 n' T+ d$ q$ n/ B% b
- v42 = WideCharStr;
% T* d8 Q2 n; O8 C9 i8 W' F - v49 = (double)xRight;
9 }/ T, Q# `' [! u7 X2 \( Y - v50 = (double)yBottom;4 y* n- y0 {7 u( U5 }$ }; D- r- A" L
- while ( 1 )
6 T9 i, }' d7 N- I) r, n - {, B: r; T1 O F3 g
- v28 = v44 + *((_DWORD *)v11 + 5);$ K7 P' u9 `3 S3 Q
- *(_WORD *)(v28 + 16) = *v27;
9 f8 j& v" z, i8 k - GetCharABCWidthsW(v18, *v27, *v27, (LPABC)(v28 + 20));0 k8 X. i* O& o4 H" L
- if ( *v42 >= 0x20u )
. _* Z! h* c! a: [ - {
. v. p: w' E0 r - --*(_DWORD *)(v28 + 20);. ]4 z/ t4 h3 B$ {; C
- *(_DWORD *)(v28 + 24) += 2;! |! t! ^! v. j
- --*(_DWORD *)(v28 + 28);3 P2 E' y5 P/ A1 K/ h
- }. k0 F* r7 I5 S9 @
- else o" E. D* q/ G* O
- {. u6 z' B2 j+ b. E2 Y
- *(_DWORD *)(v28 + 20) = 0;$ U+ s1 m0 q( G: W
- *(_DWORD *)(v28 + 28) = 0;
# E A9 L8 n5 w$ y- P& [* p; e9 i - }+ z q: V- j( ~
- v29 = *(_DWORD *)(v28 + 24);
/ n) _8 r2 C, B0 y/ D8 c, F3 v9 Z - v30 = v40;! v# A- V9 t- x! Z% P
- if ( v29 + v26 + 1 >= (unsigned int)xRight )
+ C# ?/ O0 [$ U, Q. \, A8 ~6 P) g' t - {
5 t/ s) d @* G0 x6 h - v26 = 1;
9 T" L u; W6 i' { - v30 = v40 + *((_DWORD *)v11 + 3) + 1;
# t0 S) p, k7 R% Z, `+ } - v41 = 1;
7 t+ X+ e, D: T: v - v40 += *((_DWORD *)v11 + 3) + 1;. E9 c3 G% ?$ e8 d5 w9 N/ x. l* J; V
- }
# V- {; _$ R+ x8 y4 N* L$ K - *(float *)v28 = (double)v41 / v49;: S, M- ^) z8 {- A
- *(float *)(v28 + 4) = (double)v40 / v50;
$ [( \* D- W2 S) H7 b" u* t - *(float *)(v28 + 8) = (double)(unsigned int)(v26 + v29) / v49;) f/ r7 F1 p9 V. P9 k2 K
- v31 = v26 - *(_DWORD *)(v28 + 20);9 \' T0 _6 `' @9 o+ {
- *(float *)(v28 + 12) = (double)(v30 + *((_DWORD *)v11 + 3)) / v50;
! s; Z9 |# z. Y# k - TextOutW(v18, v31, v30, v42, 1);3 c5 t3 I- O7 C4 a. a
- v44 += 32;$ r; k+ a$ w& B! D7 h' b) {* k
- ++v42;
D* G5 x" B0 q6 L6 D' z2 m - v33 = __OFSUB__(v43 + 1, *((_DWORD *)v11 + 4));
, e. x0 d( l7 Z - v32 = (signed int)&v43[-*((_DWORD *)v11 + 4) + 1] < 0;/ m1 F# y+ E6 R& l6 k |$ o
- v26 += *(_DWORD *)(v28 + 24) + 1;
9 @' P; p0 L7 V - v41 = v26;
/ R1 \4 G& }3 ? - ++v43;3 l7 P! J( K1 R1 U0 h. T& T
- if ( !(v32 ^ v33) )
3 {) q, z. R3 ~1 @: X - break; d0 Q& n, I: i% u- J7 f
- v27 = v42;
- f+ X* G% G4 k$ Q - }
4 g8 s' X( |3 o2 k - }6 C0 h5 W( k! Z% z1 q; {! ?6 N1 @
- v34 = CKBitmapData::LockSurfacePtr((CKBitmapData *)(*((_DWORD *)v11 + 6) + 56), -1);: @9 o4 [- D. ? f
- if ( v34 ); D/ y& K9 K# J) U: N
- {3 }# J2 u2 Y: g" l3 `% f( \
- GetObjectA(v45, 24, &v51);
* H& R9 E( _3 e% w; [, Q - v35 = v53;
; K& |! m! U+ q8 {% c$ [$ R - v36 = v55 + v54 * (v53 - 1);
" K b/ t( U5 H t% |, X - v40 = 0;- v$ o/ V6 {1 o* |, O8 v
- if ( v53 > 0 )
9 L1 `" B6 g, c- N: Q5 ]1 o - {# ]8 N) J3 w- A2 f+ [
- v37 = v52;# B) _) W+ _+ G
- do
! E" U5 j+ }/ D( B - {2 e' T4 e( i, {! r5 v
- v38 = 0;: p5 b' P, X; K5 ^
- if ( v37 > 0 )
3 }* }8 U. Y" ? - { w& t1 y, R0 O
- v39 = (unsigned __int8 *)v36;6 j# C+ p' q8 e2 t1 I
- do! d3 R' @' D) x
- {
. a0 }5 C9 x8 s* Z - *(_DWORD *)&v34[4 * v38] = (*v39 << 24) | 0xFFFFFF;
) S# y% Y9 x/ p7 N0 [' B& j - v37 = v52;' H$ M# _% } i, E
- ++v38;
) n O. D+ P3 p - v39 += 3;6 U" N0 q" h5 c$ R L3 @
- }4 C* Z0 x) A7 i: M
- while ( v38 < v52 );0 a6 K& b q, H, a4 ?( v$ t$ ~
- v35 = v53;# R9 K8 ^% ?9 O: D
- }9 R1 m, C/ C W- q# g
- v36 -= v54;
0 ]9 d3 i" Z' h C - v33 = __OFSUB__(v40 + 1, v35);
`# n" F' }. G, n - v32 = v40 + 1 - v35 < 0;. Q: n5 |9 |5 Y. D. X) P% q
- v34 += 4 * v37;
% {/ }) a/ M" |* I& V& e2 g2 w* H - ++v40;4 p% H4 ~4 ~ O+ n
- }1 r) V. f' P: C4 Y) {: g
- while ( v32 ^ v33 ); H* \7 z7 s; y) ^+ X: y
- }6 c3 [5 `9 ~- p2 C
- }5 N/ [" O7 \1 Y4 c( G8 z8 T2 ?" o
- CKBitmapData::ReleaseSurfacePtr((CKBitmapData *)(*((_DWORD *)v11 + 6) + 56), -1);' R0 R: z$ E8 h& b+ | b) I0 P/ |
- SelectObject(v18, v46);
+ r* h, x1 V) g0 c - VxDeleteFont(v48);% G; L3 V2 g! {1 S/ L; C
- SelectObject(v18, v47);: r/ M( x& W0 ^/ h
- VxDeleteBitmap(v45);
( s- H8 s( O. r' ]4 O% E& o8 D. G - DeleteDC(v18);
) A: E- ]2 i/ X& v- \* j" z - CKObject::SetName(*((CKObject **)v11 + 6), (char *)a3, 0);; L- f" X, ~& |) d% |/ O, a+ p7 v
- CKBitmapData::SetDesiredVideoFormat(*((_DWORD *)v11 + 6) + 56, 1);
6 h) P7 j) f0 W8 G; e6 F, e - (*(void (__stdcall **)(_DWORD))(**((_DWORD **)v11 + 6) + 120))(0);2 [9 E0 ]$ w/ |: ]
- return v40 + *((_DWORD *)v11 + 3) < yBottom;
+ c' l- w8 [3 v, R; V - }
; p- T5 ~( n$ _1 H) Y, P L6 r
复制代码
1 p5 U, K8 g/ u& Y; w1 k
! i/ L H; I2 Z1 m$ |- M$ ^! Z |