本帖最后由 shane007 于 2023-8-26 17:10 编辑 5 I4 I1 e& T+ e4 C# x% g# S" W
( P: F- l; \* S' h2 Q- [) Z! n这个游戏的主要修改点在\player\BuildingBlocks目录下的Adventure.dll中。5 H8 w8 }5 U- s, c' f
用API monitor对本DLL的CreateFontA函数进行跟踪,发现确实有调用, 参数如下。
# z' f& x9 I0 K4 D* U3 j9 K/ R9 ^$ r" q$ k9 p# f: h. r
- # Type Name Pre-Call Value Post-Call Value4 Y% }* G3 @7 T. R- \8 Z
- 1 int nHeight 0xfffffff0 0xfffffff09 L a% x( W: {! y1 i. i# r7 E, y
- 2 int nWidth 0x00000000 0x000000005 d* q% Q- {( U- _/ d; b- |
- 3 int nEscapement 0x00000000 0x00000000
5 {5 I$ S! f3 K* Z& X' X8 \; ] - 4 int nOrientation 0x00000000 0x00000000
9 {2 j) _# i* T. X - 5 int fnWeight FW_NORMAL FW_NORMAL
; p0 E% ?5 l( E - 6 DWORD fdwItalic 0x00000000 0x00000000" Q7 E% w& b5 G0 w& `
- 7 DWORD fdwUnderline 0x00000000 0x00000000% ^$ C8 Y4 R1 J+ f6 y% p
- 8 DWORD fdwStrikeOut 0x00000000 0x00000000' r1 d1 H0 n. d: L5 t( `, U
- 9 DWORD fdwCharSet DEFAULT_CHARSET DEFAULT_CHARSET
( [3 m% ]/ V' M - 10 DWORD fdwOutputPrecision OUT_TT_ONLY_PRECIS OUT_TT_ONLY_PRECIS
5 G5 O |2 q+ U" V) X( @ - 11 DWORD fdwClipPrecision CLIP_DEFAULT_PRECIS CLIP_DEFAULT_PRECIS; \* U# a8 F/ v! u0 u3 |
- 12 DWORD fdwQuality PROOF_QUALITY PROOF_QUALITY
9 E- o1 o4 m* [" H6 o. Z - 13 DWORD fdwPitchAndFamily FF_DONTCARE | DEFAULT_PITCH FF_DONTCARE | DEFAULT_PITCH3 X% g% ~! S3 q& ]5 n/ u' z6 u
- 14 LPCTSTR lpszFace 0x09148a58 "Arial" 0x09148a58 "Arial"
/ B% z& a% r# b
复制代码
, F9 h9 ^/ ^- O
* {$ N- |2 y8 B' g( [% q3 P用ida pro找到调用CreateFontA的源头函数如下。
* X( m8 l* \% C* K* q从函数的参数可以看出,这应该就是字幕显示函数了。8 e c' Y5 |- q( X, o7 A# E, }
关于后续修改,先修改CreateFontA函数的fdwCharSet,lpszFace这2个参数,也许就能出中文。
# q' y: e8 _& X) r还不行的话,就自己写一个显示函数。以下函数中lpMultiByteStr就是指向字幕的指针。4 [/ ^; M' K, f* `4 M8 b9 \
8 ?5 j/ Z h6 ^) W- 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)
+ p# D$ X* D- T9 z# O - {
+ F- o5 Q& m/ J. H/ \ - void *v11; // edi
+ L+ I5 I4 h$ t: l6 q- T8 N) h: n - int v12; // eax* t- s7 c. @- b- F3 a C
- int v14; // ecx2 A! I' K/ Y( l, V0 q/ b
- int v15; // eax
9 f) G: f' h. j4 ` - char *v16; // eax7 S$ I X! Q n, G
- int v17; // eax
( B ^$ c1 |! _9 |7 y% o, \ - HDC v18; // ebp2 ?3 @: j, l: R- C6 k
- int v19; // eax1 {7 A% J+ T$ b/ I/ j, z4 f
- int v20; // eax
$ p7 q' j: W2 C; H- T - int v21; // esi
( z s7 b0 S% U+ H2 ^ - char *v22; // eax
( q! ?4 p, L6 M; Q4 V4 M$ r - int v23; // esi5 b$ H* l: |0 J" f$ m7 h
- int v24; // ecx, C g* F7 n( e& c4 A# R
- HBRUSH v25; // eax
* H9 B% t/ \6 A" C - signed int v26; // ebx
+ C& [( {! k. Q! h - WCHAR *v27; // eax
; B) i: h) B+ G5 ^ - int v28; // esi+ p1 A9 g. g5 w1 [! }6 c
- int v29; // ecx& h j+ U1 o# M
- int v30; // eax
1 h( ^) m8 s8 Z, U, G - int v31; // ST28_4- W4 a: n2 S3 u1 s/ ^# N2 a- g0 L
- bool v32; // sf
$ p. @: ~, J! x- G9 z - unsigned __int8 v33; // of' J# _# ?+ O6 y. T
- unsigned __int8 *v34; // ebx9 f) R3 K- z0 O0 a3 u! a r
- int v35; // ecx* @6 E& ?. P$ G' T k2 ?* K( g0 S
- int v36; // esi
4 B! j: ~2 B" O+ n$ O6 h - int v37; // edx
* S% n( p: n& e! l: c2 d+ |9 x - int v38; // eax3 B& j5 L& L, _0 n. a; c6 Y7 [
- unsigned __int8 *v39; // ecx5 Y6 M% Y9 b* Q. g- `
- int v40; // [esp+40h] [ebp-2098h]/ g% L+ o- z" Z4 m
- signed int v41; // [esp+44h] [ebp-2094h]# g! Q; ? i, z
- WCHAR *v42; // [esp+48h] [ebp-2090h]6 V6 |1 a: u- f% e: j* ?
- LPCSTR v43; // [esp+4Ch] [ebp-208Ch]: t* e# Y( o) }# V4 k" E; {
- int v44; // [esp+50h] [ebp-2088h]
* q4 E6 d$ \7 ~9 \ - HGDIOBJ v45; // [esp+54h] [ebp-2084h]
/ }/ W' }- D7 @ - HGDIOBJ v46; // [esp+58h] [ebp-2080h]
) }8 g k) @8 n8 ~+ H) [ ?9 w - HGDIOBJ v47; // [esp+60h] [ebp-2078h]
4 J7 j5 p2 O! Z! w0 [; a8 _9 O - HFONT v48; // [esp+64h] [ebp-2074h]. s9 i3 T$ \/ d. K
- float v49; // [esp+68h] [ebp-2070h]
- X3 I! E# \2 n* B! J8 P - float v50; // [esp+6Ch] [ebp-206Ch]! Z# Y& B$ e& f8 O
- char v51; // [esp+70h] [ebp-2068h]
0 g7 T/ t( r1 V3 } - int v52; // [esp+74h] [ebp-2064h]
6 O! r/ L h3 {! v - int v53; // [esp+78h] [ebp-2060h]- ~; M9 t5 m$ Y o, P/ h) {2 U! n
- int v54; // [esp+7Ch] [ebp-205Ch]& K2 S& I- j9 b0 B7 Q
- int v55; // [esp+84h] [ebp-2054h]
' \% Z6 D4 M! g0 U* q4 H - struct tagSIZE v56; // [esp+88h] [ebp-2050h]
: n+ ^/ H8 V0 j - struct tagRECT rc; // [esp+90h] [ebp-2048h]; k1 X- K( z% i
- int v58; // [esp+A0h] [ebp-2038h]! o4 T. J+ i0 O) r
- char v59; // [esp+A4h] [ebp-2034h]
& t7 L- S2 d& M& s - WCHAR WideCharStr[4096]; // [esp+D4h] [ebp-2004h]
& g. F+ s0 I8 Q; i - 1 ~% S+ u& Z. h, P+ n: m! w
- v11 = this;
2 f& f! }: W* s0 e+ ^. w - v58 = 52;- a5 Y3 S$ U% ]- [" q) ?! F, P7 }9 j
- memset(&v59, 0, 0x30u);
: K; B' n' ]$ U* q - if ( *lpMultiByteStr )
+ [) K. X* @/ @: N4 s- N - {
i% ~$ u/ B. U' P J$ [ - v12 = MultiByteToWideChar(0xFDE9u, 0, lpMultiByteStr, -1, WideCharStr, 4096);
9 b- ?+ M, O) D0 I - *((_DWORD *)v11 + 4) = v12;9 @& G8 E% o. i& y6 W
- if ( v12 <= 1 )# ]4 x2 _, O3 [7 {& f
- return 0;
/ y7 U r/ {' i7 S2 E+ T - *((_DWORD *)v11 + 4) = v12 - 1;
6 \4 b7 w# I) \& [8 S" | - qsort(WideCharStr, v12 - 1, 2u, sub_10057A40);( Q1 _( L% g9 t
- }
O, {( _. f! K \' H - else3 T( ]1 F8 r) z
- {8 T/ z9 f6 s2 t9 d2 s4 J" v
- *((_DWORD *)v11 + 4) = 352;
# d/ C) |5 O/ |! _0 ]$ B% o - v14 = *((_DWORD *)v11 + 4);8 \: Y) R) ?& \
- v15 = 0;
$ y! F M2 {. r& X9 K! i7 n( U8 v0 [ - do9 k F+ U4 p4 l/ ?
- {
, d5 A4 x# ?- a& A' Z - WideCharStr[v15] = v15 + 32;
- `' t. q! a" t7 x7 O- i7 c - ++v15;
" g. `" c4 X; ?- `$ R# Q3 ? - }7 H% e, g) p9 S7 B- n* F9 S" i
- while ( v15 < v14 );
! l9 |9 h; E: \3 q4 w4 f - }
! u8 {) e4 y* S$ L3 ] - v16 = *(char **)v11;
# _6 @ m$ r: f - if ( !*(_DWORD *)v11 )
5 u: P5 \# |1 ~ - v16 = byte_100B2D6E;* {- c9 l$ v/ Y, O" d
- v17 = CKContext::CreateObject(a2, 31, v16, 0, 0);
6 U) }/ z b& l& v - *((_DWORD *)v11 + 6) = v17;
, \3 j6 {( ?2 V; P+ V - if ( !(*(int (__thiscall **)(int, int, int, signed int, _DWORD))(*(_DWORD *)v17 + 84))(v17, xRight, yBottom, 32, 0) )
, p. ?3 y6 w/ b - return 0;7 Y9 ~3 q& c" W- E
- (*(void (__stdcall **)(int *))(**((_DWORD **)v11 + 6) + 136))(&v58);. M9 ^4 M, Z( W7 W$ n
- v18 = CreateCompatibleDC(0); F+ H1 ^ l- o" x: i# ~& C& k& |
- v45 = VxCreateBitmap((const struct VxImageDescEx *)&v58);5 Z4 l- @4 o0 O
- v47 = SelectObject(v18, v45);7 ~4 e0 r2 P6 W6 @
- XString::operator=(v11, a3);
' \% c' x+ H/ R- {9 V. n9 G - *((_DWORD *)v11 + 2) = nNumber;
& f8 |5 X9 Z" A8 ]. b- I - v19 = GetDeviceCaps(v18, 90);9 F9 H* J, w" O/ }5 `. D& M
- v20 = MulDiv(nNumber, v19, 72);
8 ~' y; U, e: m - v48 = CreateFontA(-v20, 0, 0, 0, a6, a8 & 1, ((unsigned int)a8 >> 1) & 1, 0, 1u, 7u, 0, a7, 0, (LPCSTR)a4);- a2 X( y7 T, f$ @4 V" u
- v46 = SelectObject(v18, v48);; {& W4 D0 m# X% T% \* G
- GetTextExtentPointA(v18, "A", 1, &v56);
% K4 u% c6 ?- P - v21 = *((_DWORD *)v11 + 4);0 D3 }: M2 M& H+ D% ^, B
- *((_DWORD *)v11 + 3) = v56.cy;
# \( Q* y. d& {6 I8 A, h" C - v22 = (char *)operator new(32 * v21);: G) p5 N( |4 v6 D
- if ( v22 )" K! ^' {% Z3 R+ y5 l' ?2 i
- {0 H$ B) b8 n( z# j0 X6 r/ _' C
- v23 = v21 - 1;
5 H& H2 P9 t6 {* [. r4 n - if ( v23 >= 0 )
8 B% y t9 y& X9 `- N4 Y* F2 |& O - {
5 @ C) x ]' e - v24 = (int)(v22 + 12);. R8 l8 M2 ~8 D
- do
' p& Q( U% m. _8 V5 {# i9 i - {
6 B2 e4 B3 C Z% i - *(float *)(v24 - 4) = 0.0;
, l, L4 t/ g `* f. Y4 @7 {2 v - v24 += 32;' F& q3 U* Y9 G( W+ D+ Y" y
- --v23;
" t. `' {' t+ F- a; G4 O- E% X - *(float *)(v24 - 32) = 0.0;
2 H& R# b$ k6 _5 e0 w3 f - *(float *)(v24 - 44) = 0.0;+ q8 d7 C8 w1 z5 Q! y
- *(float *)(v24 - 40) = 0.0;6 w! ^$ Q% p) u
- *(float *)(v24 - 36) = 0.0;7 n1 f% c& \& C- ]4 {! a5 i& V! ]
- *(float *)(v24 - 32) = 0.0;
* g+ \) a. ]8 x* e1 s( N0 o5 M - }) d) M/ h. [+ J/ \# d! }' C
- while ( v23 >= 0 );8 W+ ]& h; r5 J: Q( x" }" m& r8 |
- }
, C; u5 U x) m - }7 B) X4 g, A7 {
- else* A7 l- I( w* K2 N$ T2 L! O
- {
" V/ W$ ?; u x) U+ F0 S8 Q - v22 = 0;
) M. S* U( D/ }/ ? - }
( B ~. |6 `4 s* g6 _ - *((_DWORD *)v11 + 5) = v22;/ y8 G; }$ C6 X* u1 E2 U1 E5 y
- SetRect(&rc, 0, 0, xRight, yBottom);9 Y; M, P k* M9 x
- v25 = (HBRUSH)GetStockObject(4);
% f: Z3 y9 m6 S! d h+ u - FillRect(v18, &rc, v25);, K2 j1 E; T% i8 \9 j
- SetBkColor(v18, 0);
( w& ~ w S g# m% i. u - SetTextColor(v18, 0xFFFFFFu);0 `+ \4 Q6 x4 b2 n& t! J7 I
- SetBkMode(v18, 1);# B9 {7 X. n0 k& M6 p" j" W+ S% v
- v26 = 1;
" S; j# S- @% |% d2 T - v41 = 1;/ k+ L( y3 f( [3 b2 a! F7 i
- v40 = 0;5 ^% o' o) N y0 d. E v; r5 {
- v43 = 0;
: |* o4 {$ i" c9 X) ~ - if ( *((_DWORD *)v11 + 4) > 0 )) V: X E- @+ v8 ~$ `8 f+ @- h3 x3 D
- {/ K5 }) b- u# Z6 d0 } r3 d
- v27 = WideCharStr;
* P' E: z, b. f- W - v44 = 0;" @) d! T- X2 X& D6 w# b7 i( l4 a
- v42 = WideCharStr;+ K2 `: M" ^) ] h7 Y4 i
- v49 = (double)xRight;
1 ?: ^- ^8 n; T+ q: k: T - v50 = (double)yBottom;
5 ?( I# s/ T) O" ~. A: I6 w' ] - while ( 1 )7 _! e2 k. A- S% ^2 h/ d( D
- {- i* g% |' z5 S1 x: y
- v28 = v44 + *((_DWORD *)v11 + 5);
$ D8 j& h, Y( b" A" p* l - *(_WORD *)(v28 + 16) = *v27;
0 b* R5 t x9 A) O* @% J3 t9 {5 c - GetCharABCWidthsW(v18, *v27, *v27, (LPABC)(v28 + 20));4 C+ d5 D9 q* R1 e2 l8 G
- if ( *v42 >= 0x20u )- }5 X5 P4 b& c8 J
- {
8 @( S4 Z% e5 T7 z, Q. _ - --*(_DWORD *)(v28 + 20);5 C6 {; _' n3 w+ w$ R$ R4 P- F9 X
- *(_DWORD *)(v28 + 24) += 2;' ]: y M5 u# S5 y# r/ W. h5 O
- --*(_DWORD *)(v28 + 28);
- J( b h% K* P: r - }
- ~% U. I U* x7 L$ P7 D# U7 i - else
4 |, K. d3 V, }( N% }, F7 {' V5 Q - {
! a0 h# t+ a. D0 w q7 L) ]$ g - *(_DWORD *)(v28 + 20) = 0;+ {. z$ `0 x7 `
- *(_DWORD *)(v28 + 28) = 0;
2 U+ D( a3 l) u) v; F3 [: @ - }: t$ N+ u# Z: F
- v29 = *(_DWORD *)(v28 + 24);3 }3 q5 N' y3 I: U& y
- v30 = v40; e8 n4 z! \' R- n& Z9 H! [' N) e* i
- if ( v29 + v26 + 1 >= (unsigned int)xRight )
S% ^* U% B3 c - {/ [; E( K9 O% ~5 J m( r
- v26 = 1;
" e9 T4 O. s A3 ]6 }$ m) w& z- ? - v30 = v40 + *((_DWORD *)v11 + 3) + 1;/ u* Z7 b z' Z8 D0 Q' x6 B2 {
- v41 = 1;
) t: F- Z1 f) F0 @" o. J - v40 += *((_DWORD *)v11 + 3) + 1;0 N. }; j, G B4 Q2 O
- }
$ Z. _3 l0 `0 t/ `3 D% P) e - *(float *)v28 = (double)v41 / v49;
7 ~" F' F# P' a3 j/ Z6 \3 d - *(float *)(v28 + 4) = (double)v40 / v50;
0 d5 O2 K7 k2 x I' Y3 ~# v* z - *(float *)(v28 + 8) = (double)(unsigned int)(v26 + v29) / v49;" A' b z3 ^% X* |5 d5 z
- v31 = v26 - *(_DWORD *)(v28 + 20);
, |% S" Y9 \6 j" t- o* C - *(float *)(v28 + 12) = (double)(v30 + *((_DWORD *)v11 + 3)) / v50;* Y" G1 f) {+ c5 \1 X- e" m
- TextOutW(v18, v31, v30, v42, 1);/ A' Z" p. L! C7 N# {
- v44 += 32;
2 q( F! }4 u5 d8 ^& g$ \! w - ++v42;
* ]* z4 {1 x* u$ c# L2 Y' l - v33 = __OFSUB__(v43 + 1, *((_DWORD *)v11 + 4));
' F; {4 r2 u' ?8 s# d - v32 = (signed int)&v43[-*((_DWORD *)v11 + 4) + 1] < 0;' g/ f( f5 h. ^$ g1 J
- v26 += *(_DWORD *)(v28 + 24) + 1;- ^+ G% y$ S. ~4 l
- v41 = v26;8 L# _ n) R! `, t {
- ++v43;" ]( k* V$ d6 ^ a; V! W
- if ( !(v32 ^ v33) )
8 i6 o0 k4 L0 } - break;2 v9 Y4 M" N. b6 B
- v27 = v42;. l! A, \$ D9 }4 r3 a, T
- }( q* P6 w+ f6 V" e( T
- } ` b: h M5 Q! t) v+ e
- v34 = CKBitmapData::LockSurfacePtr((CKBitmapData *)(*((_DWORD *)v11 + 6) + 56), -1);
- m% n" Y: W1 i) l - if ( v34 )
* T+ N* X% ~: H - {
# v0 R" H. p4 x: Z y$ p/ U - GetObjectA(v45, 24, &v51);8 E1 G9 S2 d3 n% {0 \; w( ^
- v35 = v53;
; [/ V1 x# w/ }7 D/ Z - v36 = v55 + v54 * (v53 - 1);
, |; E7 k7 w+ L3 T5 \9 b* q - v40 = 0;1 c9 J! l' P }( p2 }, v$ p7 y
- if ( v53 > 0 )0 a$ b. }$ o1 l( [1 F+ h
- { @* q" I( O! {& `
- v37 = v52;
, I- f* K x9 X' J( e6 g( C - do
6 T! X9 A: ~5 C; } - {$ A. \$ N' l u# m! x
- v38 = 0;
6 n( z ~% u& }8 F$ N) r - if ( v37 > 0 )" e! B( X) v) i* q! [; X/ V. H
- {, `' n# r f: @3 g
- v39 = (unsigned __int8 *)v36;: e, J5 j9 s% L7 f) [! e' |! b9 A
- do
( Z0 i6 k5 @; V5 D i - {
1 q" s* x8 e# N @4 f - *(_DWORD *)&v34[4 * v38] = (*v39 << 24) | 0xFFFFFF;1 ~+ a% l9 r! |5 m; p, v# c
- v37 = v52;" l% X2 @3 G# R- {" n: f0 B: y( `
- ++v38;
( P1 k& ^- C% d - v39 += 3;
5 ]; m& p, H! u - }
) p; v3 Y: ^3 t2 Y" y& k - while ( v38 < v52 );
% H* n+ A, j' e2 I4 b - v35 = v53;
6 ? Z6 O: ?( @) L9 C. J8 z - }% a3 i( l9 Y4 Y( k$ \& q& F
- v36 -= v54;
, l' o; A' M$ @2 [( O5 _ - v33 = __OFSUB__(v40 + 1, v35);
% o0 m& |6 F: ^) Z - v32 = v40 + 1 - v35 < 0;
6 ] J8 B ~' T - v34 += 4 * v37;3 K7 g( C* y' s% _5 v2 t5 z' L" B
- ++v40;- w h. ]) P% W+ u+ X Y
- }+ {( d3 b3 o) c4 n3 B4 |
- while ( v32 ^ v33 );- f) B' }" n! P, f5 Z" r r% z
- }
8 T& A: X9 z2 g' G - }
- \4 H9 B! x; a, F( W - CKBitmapData::ReleaseSurfacePtr((CKBitmapData *)(*((_DWORD *)v11 + 6) + 56), -1);
3 i, ~2 u! m. T, G/ }' v - SelectObject(v18, v46);, t/ `+ b. v) L& D
- VxDeleteFont(v48);& W( ^3 n- F3 P( d. O
- SelectObject(v18, v47);- e" Z: _! g4 F
- VxDeleteBitmap(v45);+ ~0 x* [8 l8 M
- DeleteDC(v18);
4 r" N( B3 B1 n9 K% }# @9 p - CKObject::SetName(*((CKObject **)v11 + 6), (char *)a3, 0);' B& p! D6 |: Q) B: t7 ?
- CKBitmapData::SetDesiredVideoFormat(*((_DWORD *)v11 + 6) + 56, 1);
: i8 @$ p; q5 I9 J P1 D - (*(void (__stdcall **)(_DWORD))(**((_DWORD **)v11 + 6) + 120))(0);
' }2 ~9 a/ P2 ?9 G) n7 b/ s$ v - return v40 + *((_DWORD *)v11 + 3) < yBottom;
1 z$ }1 L% o$ D7 ], q& u - }
1 w! @7 q/ i4 ~* `
复制代码 2 l0 U% K& h _ n2 ?2 f
; N/ M5 l' C/ ?# [ |