本帖最后由 shane007 于 2023-8-26 17:10 编辑 , B- c8 {: A5 ]0 Y
3 E$ ~ Q! C4 k! }/ e4 G( N ^; P这个游戏的主要修改点在\player\BuildingBlocks目录下的Adventure.dll中。
8 R* N, {+ Z! S. Q( H/ l用API monitor对本DLL的CreateFontA函数进行跟踪,发现确实有调用, 参数如下。
& j4 x; n) z9 b$ W5 Q4 Q R
9 J$ }; R- ^. Q4 ?' n7 D- # Type Name Pre-Call Value Post-Call Value
f5 h2 v; ~5 S5 S: M - 1 int nHeight 0xfffffff0 0xfffffff0* ~) M3 R# f5 r
- 2 int nWidth 0x00000000 0x000000004 k( m3 q4 }' J8 G8 u
- 3 int nEscapement 0x00000000 0x00000000
9 B0 w" H: H* {$ [3 R - 4 int nOrientation 0x00000000 0x00000000
/ f& Q0 [3 a2 u" U+ ] - 5 int fnWeight FW_NORMAL FW_NORMAL! f! n* D3 Y& @# P+ m
- 6 DWORD fdwItalic 0x00000000 0x00000000' J1 D5 e0 Y& U
- 7 DWORD fdwUnderline 0x00000000 0x00000000
( j3 Y, T3 G8 k5 i - 8 DWORD fdwStrikeOut 0x00000000 0x00000000
8 p$ J% f( ]. e - 9 DWORD fdwCharSet DEFAULT_CHARSET DEFAULT_CHARSET' x7 y9 ~" N! ]
- 10 DWORD fdwOutputPrecision OUT_TT_ONLY_PRECIS OUT_TT_ONLY_PRECIS" S7 ]" ?9 T$ o" n; b
- 11 DWORD fdwClipPrecision CLIP_DEFAULT_PRECIS CLIP_DEFAULT_PRECIS
$ @6 X1 A' Y9 G6 W' f p - 12 DWORD fdwQuality PROOF_QUALITY PROOF_QUALITY
- K+ v- K; X! V# Y" c - 13 DWORD fdwPitchAndFamily FF_DONTCARE | DEFAULT_PITCH FF_DONTCARE | DEFAULT_PITCH
$ t$ m0 p0 }% f% R5 P/ U7 i - 14 LPCTSTR lpszFace 0x09148a58 "Arial" 0x09148a58 "Arial"+ C% A) C! G3 x5 L& O `
复制代码 $ n4 R1 F5 L: P2 W
8 z! _6 ?( T8 @! d
用ida pro找到调用CreateFontA的源头函数如下。
8 V9 {/ [' i; c从函数的参数可以看出,这应该就是字幕显示函数了。6 C/ q" q! c+ `
关于后续修改,先修改CreateFontA函数的fdwCharSet,lpszFace这2个参数,也许就能出中文。
6 j+ V3 f8 y8 t% `- V还不行的话,就自己写一个显示函数。以下函数中lpMultiByteStr就是指向字幕的指针。
2 r, z. n& o. S. ~& Z
4 E5 U9 i5 e7 [! A- 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)$ q9 C6 H6 C$ H1 {
- {
) ~9 X- X- q/ k H - void *v11; // edi
$ B9 a b& P- C5 U$ w9 t - int v12; // eax
6 D' l1 _$ ~. x) E9 m, S - int v14; // ecx% g3 K- v: {3 t4 N- k# X. i+ X
- int v15; // eax9 S. U. ^" W& ~/ P
- char *v16; // eax+ H' [8 b# w$ y' O# Y4 P: ?
- int v17; // eax
9 u5 {' }. A4 C/ g5 a% s4 g - HDC v18; // ebp
' R, l/ g/ I+ v( z0 i - int v19; // eax$ m1 L2 f( E7 v. e5 W7 F/ V
- int v20; // eax% F$ P' ` \# u" ?2 C) H
- int v21; // esi
' Q! e4 o [1 L - char *v22; // eax
: M8 i+ Z3 q% v* M; x' l - int v23; // esi
2 r4 {& a0 t' J2 y3 \ - int v24; // ecx
& } z6 b" V0 k* o7 J! z6 D3 w - HBRUSH v25; // eax. d9 M; |! n7 i' x" @9 N) u* |
- signed int v26; // ebx
9 n6 O0 r* @; e- \% X - WCHAR *v27; // eax* v: Q; b4 h2 Z, K8 F$ C
- int v28; // esi# H* `! n Y6 T. x; K
- int v29; // ecx6 ?8 P& }0 J. ?% y8 X
- int v30; // eax
6 i' V. q: h6 \$ |$ F% ` - int v31; // ST28_46 K5 l6 m4 h; V; A' l( ?& }2 ^: j2 t
- bool v32; // sf
( O" k6 Y; ^: P* e3 Q' A - unsigned __int8 v33; // of
, V2 x' `9 v) ]& P: u g9 V8 } - unsigned __int8 *v34; // ebx
/ k0 o7 W9 H F4 ? - int v35; // ecx
$ c$ e! I+ M9 l - int v36; // esi, n# M& p' \: I3 {0 s9 T4 g
- int v37; // edx+ l1 e1 }, d/ {: O) a% z; O5 D
- int v38; // eax
* h, @8 v/ l. x - unsigned __int8 *v39; // ecx
" w, X" s2 R. O( {8 y" } - int v40; // [esp+40h] [ebp-2098h]/ k7 `. t) l, _" | D8 P
- signed int v41; // [esp+44h] [ebp-2094h]4 `5 `8 t# O' p* z8 R
- WCHAR *v42; // [esp+48h] [ebp-2090h]8 A% S+ m+ D9 y2 u7 K
- LPCSTR v43; // [esp+4Ch] [ebp-208Ch]8 {, W8 g. j4 S1 w9 m. B
- int v44; // [esp+50h] [ebp-2088h]4 D2 H! l% j; l+ a1 I+ S
- HGDIOBJ v45; // [esp+54h] [ebp-2084h]/ V A7 b1 M! d- B/ Y" D$ D
- HGDIOBJ v46; // [esp+58h] [ebp-2080h]+ [+ }: c' \0 \: i9 u( q
- HGDIOBJ v47; // [esp+60h] [ebp-2078h], ^3 w D/ r" O9 b# b. I6 l7 [0 M
- HFONT v48; // [esp+64h] [ebp-2074h]
7 t" Y7 y* \3 g. I* z - float v49; // [esp+68h] [ebp-2070h]+ G! k" V- {! n" G1 X6 I6 F
- float v50; // [esp+6Ch] [ebp-206Ch]
, A4 |8 \7 W3 Y& j5 A( H0 Y - char v51; // [esp+70h] [ebp-2068h]
, C. ~+ A! H1 |% `7 ` w - int v52; // [esp+74h] [ebp-2064h], @, b+ s# {' b. [- v% W
- int v53; // [esp+78h] [ebp-2060h]
3 v! b( F8 N0 n/ n9 {4 y. Y - int v54; // [esp+7Ch] [ebp-205Ch]* E6 e; v# }2 N3 e4 u5 L
- int v55; // [esp+84h] [ebp-2054h]( [1 a" u) o; A. h- j
- struct tagSIZE v56; // [esp+88h] [ebp-2050h]
( v. C7 a9 Q: O" E2 K - struct tagRECT rc; // [esp+90h] [ebp-2048h]" r0 H( G+ c* |- a* z- c
- int v58; // [esp+A0h] [ebp-2038h]
4 {( S# C0 Q, ~- d/ a, F - char v59; // [esp+A4h] [ebp-2034h]) ~7 l1 w' z# k* d0 P. p# h
- WCHAR WideCharStr[4096]; // [esp+D4h] [ebp-2004h]
* p& X4 k4 Q, v* M3 o
2 ?, Q. m6 @! g8 T* o+ J- v11 = this;
! Y- _- R( ~" ~+ i' i. T( ^ - v58 = 52;5 @0 U v# K1 T0 Y
- memset(&v59, 0, 0x30u);6 [7 x' H2 _5 w- Q& l3 [$ a+ x+ r
- if ( *lpMultiByteStr )+ o7 r3 n+ y( T* x, v7 k
- {
1 v) }: Y t4 R0 b/ L - v12 = MultiByteToWideChar(0xFDE9u, 0, lpMultiByteStr, -1, WideCharStr, 4096);7 Q8 ~7 N' t: f5 }) L, A: y
- *((_DWORD *)v11 + 4) = v12;+ q6 S% }: ^4 P' d. E9 Q+ B- p% d
- if ( v12 <= 1 )
5 z/ x8 c# b0 d) \( I" U - return 0;
. Z' z( ?+ q( I u% z' `8 ?; Y - *((_DWORD *)v11 + 4) = v12 - 1;$ Q" Y. ]- Z6 y1 L3 U& w
- qsort(WideCharStr, v12 - 1, 2u, sub_10057A40);$ m! Z1 T' ^ e8 `' [$ e
- }( j% Q' a W- [* @
- else
2 T( }: g9 f& ^! { - {2 Z2 R- o2 Y! a$ h
- *((_DWORD *)v11 + 4) = 352; N! c, J D ~0 W! u. f2 g2 p
- v14 = *((_DWORD *)v11 + 4);
- g0 G5 L; g, t6 @ - v15 = 0;" U9 D0 x7 C/ g( B! }( U
- do2 v% O' U F# p0 @" A4 f, ^
- {8 W& p* I$ t1 H" U) C$ Z% L2 D
- WideCharStr[v15] = v15 + 32;
( ?" Y o" i6 ?. h% U1 g - ++v15;4 P1 h2 M2 I @2 X8 y
- }
* Q5 f( n9 h1 D3 ] - while ( v15 < v14 );
% P& a2 T5 z& S- L" r; I) Q - }( X' Y7 w% `& ~ U; A
- v16 = *(char **)v11;5 {- |7 `+ p0 K% r* d: q
- if ( !*(_DWORD *)v11 )' |. v. t4 @2 F d: q) R, E" |' G
- v16 = byte_100B2D6E;! G/ g9 h- n% y
- v17 = CKContext::CreateObject(a2, 31, v16, 0, 0);
+ b7 o7 Q! |- n - *((_DWORD *)v11 + 6) = v17;+ y9 `2 G5 e" ?$ z! P
- if ( !(*(int (__thiscall **)(int, int, int, signed int, _DWORD))(*(_DWORD *)v17 + 84))(v17, xRight, yBottom, 32, 0) )# l9 I% C9 q! G ~
- return 0;
3 P: S" A1 ?7 I( u$ ]6 Q* j6 a - (*(void (__stdcall **)(int *))(**((_DWORD **)v11 + 6) + 136))(&v58);
0 d! b* F9 z4 r - v18 = CreateCompatibleDC(0);+ s; I9 d% @( X& ~0 |5 n0 `, [
- v45 = VxCreateBitmap((const struct VxImageDescEx *)&v58);
F. {. g+ \8 j - v47 = SelectObject(v18, v45);
7 V/ s$ `6 i4 h6 M2 ~ - XString::operator=(v11, a3);- L3 L" N' n# t( P+ J$ G
- *((_DWORD *)v11 + 2) = nNumber;! {, g0 E, c3 G
- v19 = GetDeviceCaps(v18, 90);
7 j0 l- {7 m' P( E8 ~0 M; A - v20 = MulDiv(nNumber, v19, 72);
* C) B; J; F, d - v48 = CreateFontA(-v20, 0, 0, 0, a6, a8 & 1, ((unsigned int)a8 >> 1) & 1, 0, 1u, 7u, 0, a7, 0, (LPCSTR)a4);
. M/ ^+ ] C4 p% ?8 [# m - v46 = SelectObject(v18, v48);
1 X8 C$ ~7 [. q5 D& ] - GetTextExtentPointA(v18, "A", 1, &v56);
% [. V$ @# E, r/ ?% ^, N6 p - v21 = *((_DWORD *)v11 + 4);
1 ]" t% j8 J' ?2 ~9 v( X, N - *((_DWORD *)v11 + 3) = v56.cy;( w3 r: n' v0 O3 T$ b
- v22 = (char *)operator new(32 * v21);
0 |' |2 t- K+ F% O, e9 j5 e - if ( v22 )- Z$ q3 B$ p/ B8 ?8 U
- {
9 G% [/ o) {( Y( s7 Z+ x0 X - v23 = v21 - 1;/ g, M% E7 m# S0 `
- if ( v23 >= 0 )( N4 V+ l- t8 B' q# X9 {: A- J/ I
- {/ b* j1 M/ u- Q) N0 O
- v24 = (int)(v22 + 12);) y1 H3 B M- X& a$ M n' w
- do
/ M; M' y) R: G- {9 d3 ~7 C - {
. y p& Y6 m6 K2 m - *(float *)(v24 - 4) = 0.0;, K( R/ k) m. L- V! L- U/ o, K
- v24 += 32;2 G; L9 a. e8 R2 @, n1 G
- --v23;
, T; V' J& Y0 G5 T - *(float *)(v24 - 32) = 0.0;$ r4 |6 w0 Z! w4 j5 S4 e) a
- *(float *)(v24 - 44) = 0.0;4 X" G% u5 e( a
- *(float *)(v24 - 40) = 0.0;
: z, Z, A T2 Z4 Y - *(float *)(v24 - 36) = 0.0;# Z K2 Z' D" a
- *(float *)(v24 - 32) = 0.0;9 F. F5 a; ?/ ` V S, j+ v
- }1 x9 Z( J; p0 K; T# j+ j
- while ( v23 >= 0 );: U" _! [. T1 _4 f6 r/ I) |
- }; y! B* ]3 m- g, L
- }
2 Q7 F4 L# ~3 U; ^ - else
7 r- V) K; c. F7 L - {8 e* l5 v8 g2 h( `$ {4 m
- v22 = 0;
6 N) }; d, \9 ^. e+ V* ? - }+ T% {1 t9 i+ c$ u* w+ l! i
- *((_DWORD *)v11 + 5) = v22;/ t/ H6 f+ s- k1 y. r5 x5 S- \
- SetRect(&rc, 0, 0, xRight, yBottom);6 ^! G3 V8 U% d8 J- A- t6 L9 `
- v25 = (HBRUSH)GetStockObject(4);
& t8 o% u6 F& A9 S - FillRect(v18, &rc, v25);0 ~; h) [4 c) Y
- SetBkColor(v18, 0);' s% X9 q, q, Q2 z* a9 }
- SetTextColor(v18, 0xFFFFFFu);. K& y2 z* F" f, l/ N" g, |
- SetBkMode(v18, 1);8 y( o8 _, {9 s
- v26 = 1;4 \5 Y* b$ B5 @; w$ ]0 f
- v41 = 1;
" h9 l( ~( p) V4 g4 h0 H9 C - v40 = 0;, |6 q% X' }- ]* e- b$ | J
- v43 = 0;# Z, s8 P+ A" k* s4 P
- if ( *((_DWORD *)v11 + 4) > 0 )2 W( L4 c! v; l9 Z" ~2 {( y* ?! [
- {; E B; Z. f/ `
- v27 = WideCharStr;+ a) [1 {, p1 a) ~: N+ K; C. Y
- v44 = 0;
6 V7 t3 N9 |" W; W& _7 P - v42 = WideCharStr;
4 s/ G4 r0 ?3 a. H% w+ i' b - v49 = (double)xRight;
i5 ]6 w z4 c$ O - v50 = (double)yBottom;/ C4 |* s z& e2 o. o
- while ( 1 )* v2 H7 C6 {0 B* u0 E' C2 h/ u
- {# V" Q& D- H3 Z9 v3 y
- v28 = v44 + *((_DWORD *)v11 + 5);
8 x/ |0 Y: }0 E& `. s+ R9 L - *(_WORD *)(v28 + 16) = *v27;
( G) p* ~: ^3 ^) ^; u - GetCharABCWidthsW(v18, *v27, *v27, (LPABC)(v28 + 20));# a) Y: }" R5 {% b+ G* P4 H
- if ( *v42 >= 0x20u )4 Z( ^6 i9 L- N @6 ~
- {
) a* B+ M( q$ E9 w# i! p - --*(_DWORD *)(v28 + 20);# p9 n# l7 L2 A, _3 ^+ r
- *(_DWORD *)(v28 + 24) += 2;: D: V6 y# B4 u9 F0 e+ J7 e# _
- --*(_DWORD *)(v28 + 28);
( ]/ V8 s( V0 | - }
3 e1 B3 R6 d4 _ g" c - else3 s1 G- L8 H8 S+ [
- {/ b! V$ h& s9 q" F
- *(_DWORD *)(v28 + 20) = 0;/ Q! z$ o- J# M9 ]7 }3 n
- *(_DWORD *)(v28 + 28) = 0;# l: P' ?$ ^; J# @9 |+ s
- }
8 r8 l9 Q# b# X - v29 = *(_DWORD *)(v28 + 24);
2 J5 Z7 I: v, R2 A0 s - v30 = v40;
% m# ?5 G# [5 J/ E+ S% X - if ( v29 + v26 + 1 >= (unsigned int)xRight )" g; I$ s# N$ b2 e5 I
- {7 z* _3 x5 I+ D ~' P0 J* Q9 F
- v26 = 1;7 B9 T8 d! y9 {
- v30 = v40 + *((_DWORD *)v11 + 3) + 1;# N$ z% ~, h Q( W- L* Z$ u$ O+ a
- v41 = 1;1 z' r9 W( v! K& p6 p6 x/ m
- v40 += *((_DWORD *)v11 + 3) + 1;9 j8 a* [& F* ] r& f0 `" j3 a- S
- }
; } A# H* s5 `5 C% [ - *(float *)v28 = (double)v41 / v49;
' g' P; `* f5 u0 G0 Y - *(float *)(v28 + 4) = (double)v40 / v50;3 k% Y/ l& X' h- b& w- w
- *(float *)(v28 + 8) = (double)(unsigned int)(v26 + v29) / v49;8 J" m. w* s; { d, I) ^
- v31 = v26 - *(_DWORD *)(v28 + 20);7 w4 S& b4 g n* Z
- *(float *)(v28 + 12) = (double)(v30 + *((_DWORD *)v11 + 3)) / v50;
! N: {6 t" Y' Y u% j - TextOutW(v18, v31, v30, v42, 1);2 f j* Z' t+ v3 A) {/ [ q0 F
- v44 += 32;
0 y- p }4 Y# U4 j+ P7 h - ++v42;
/ t6 y. O+ q6 {4 E) U; K - v33 = __OFSUB__(v43 + 1, *((_DWORD *)v11 + 4));! l$ v7 E! I6 ]
- v32 = (signed int)&v43[-*((_DWORD *)v11 + 4) + 1] < 0;
/ R+ E2 i4 Q) ?5 |5 A$ x+ s - v26 += *(_DWORD *)(v28 + 24) + 1;6 T# y+ e# k# n2 v, x4 t
- v41 = v26;
$ T3 S3 L, t9 V4 v9 A - ++v43;
1 W1 T5 m5 H, q: K) s+ H) } - if ( !(v32 ^ v33) )3 i) c0 ^! z; x/ W3 t! \ x
- break;
$ `" r7 E5 d2 K1 c) y - v27 = v42;6 f4 C- ] v. }
- }
/ b- r$ ~ z2 y+ e( P* M0 f& j. n; L - }
7 d# m- B: G" t9 l - v34 = CKBitmapData::LockSurfacePtr((CKBitmapData *)(*((_DWORD *)v11 + 6) + 56), -1); i* a, m* J* E$ j$ L1 [
- if ( v34 )
6 K- i; S) D# V3 T - {+ [) |( H" }& O1 j5 Q
- GetObjectA(v45, 24, &v51);5 @( L; D; {& p, X5 J
- v35 = v53;' Z0 a% s3 B: C2 G
- v36 = v55 + v54 * (v53 - 1);
7 L4 h/ a6 _! \- F: s - v40 = 0;5 d" w, A) ?- D4 `
- if ( v53 > 0 )
- G, U/ o# \- P; E# e - {: e W0 }: F( F
- v37 = v52;9 ~2 Q0 i' |6 t% K6 i
- do; S. \8 [ R0 U6 P, `9 F2 [
- {# ~$ t6 J+ e1 q0 }. ?; B3 D
- v38 = 0;, u% a+ e, O: J
- if ( v37 > 0 )
* N+ a4 N( a% Y4 j - {& [; O9 Q7 j" D: ~
- v39 = (unsigned __int8 *)v36;
; o3 P+ N7 I9 v" ?3 I - do; W$ }& A7 e4 v. A" P5 E" p
- {0 Z z. t' K0 G# a* ?# c2 ]$ f
- *(_DWORD *)&v34[4 * v38] = (*v39 << 24) | 0xFFFFFF;
`6 o( V, s. d8 s - v37 = v52;7 E" y" @/ V) F& ~' L$ v! W0 V
- ++v38;
, d" a0 `; ?* W; P. e - v39 += 3;
/ s, G* v; h8 r7 y$ i9 y H - }
/ ^6 a5 O [; ?/ f - while ( v38 < v52 );2 @$ H$ z$ ]! z1 V: D. i- F" y
- v35 = v53;) q2 `* I5 D1 G9 o3 ^; v+ Q" ]
- }
. Z' N9 [- n( A; D, w( Z+ S; D* U - v36 -= v54;$ ^# L& I7 E Q! |3 Z4 v) m
- v33 = __OFSUB__(v40 + 1, v35);: l6 M( G% n5 V4 e
- v32 = v40 + 1 - v35 < 0;
3 Y6 U2 ^! [% d; H - v34 += 4 * v37;
& K% v$ M1 r* e0 y, n2 i - ++v40;, w; m8 g9 k) l$ k9 W
- }7 r; r! q0 m, k9 a
- while ( v32 ^ v33 );
+ s7 x6 ^& V6 v7 C6 I" E - }* V% Q7 E/ h- d" G/ S
- }8 E9 r1 ]. n6 ^; ?$ C2 L
- CKBitmapData::ReleaseSurfacePtr((CKBitmapData *)(*((_DWORD *)v11 + 6) + 56), -1);
6 F2 ]# w3 \9 n# V$ d8 H ] - SelectObject(v18, v46);
+ J, v4 N, Z# I - VxDeleteFont(v48);
6 c$ m6 O% T" o# s" m - SelectObject(v18, v47);' @5 c3 u- z/ ?5 Z
- VxDeleteBitmap(v45);6 M1 T5 |, W: Q( }3 d" b
- DeleteDC(v18);
/ ?, ^- F, ]% j4 \; t- x - CKObject::SetName(*((CKObject **)v11 + 6), (char *)a3, 0);
; N3 H- T! o4 n _ - CKBitmapData::SetDesiredVideoFormat(*((_DWORD *)v11 + 6) + 56, 1);
* V" W# p3 [8 ?0 e- ]3 D- p+ \& d - (*(void (__stdcall **)(_DWORD))(**((_DWORD **)v11 + 6) + 120))(0);
+ `' n6 w/ ~6 m0 p5 b5 y - return v40 + *((_DWORD *)v11 + 3) < yBottom;% _- _ }. s. E: H4 C. y
- }1 c! b+ _6 r0 s# C/ D* E% E
复制代码 & W, n. j% `. G; N7 b
1 ~, u7 K9 v0 O+ }# s |