本帖最后由 shane007 于 2023-8-26 17:10 编辑
: s t! G/ H d& @4 u5 Q( c: Q1 ~& O, }
这个游戏的主要修改点在\player\BuildingBlocks目录下的Adventure.dll中。
: ~$ I. g0 c( j1 w用API monitor对本DLL的CreateFontA函数进行跟踪,发现确实有调用, 参数如下。# O1 v8 |$ ]) X3 b) k
2 l) |+ @, T8 o, H5 s- # Type Name Pre-Call Value Post-Call Value
. o, K B! }9 F& u& T# z) m2 Y4 U7 Y - 1 int nHeight 0xfffffff0 0xfffffff0
9 R8 a0 I- p3 e - 2 int nWidth 0x00000000 0x00000000
U1 k# s: T( n3 d - 3 int nEscapement 0x00000000 0x00000000+ b! P( B% k! Q$ l9 e. O
- 4 int nOrientation 0x00000000 0x00000000
1 w8 K# p. i* v) G A - 5 int fnWeight FW_NORMAL FW_NORMAL8 o/ S/ m: D* k
- 6 DWORD fdwItalic 0x00000000 0x000000000 ` L, }7 ^; p, C% q
- 7 DWORD fdwUnderline 0x00000000 0x00000000
6 Y9 ?1 [; A' \$ A; K; F - 8 DWORD fdwStrikeOut 0x00000000 0x000000004 e! g& r5 k; c. G3 [7 n6 o
- 9 DWORD fdwCharSet DEFAULT_CHARSET DEFAULT_CHARSET
' |! h" y- r1 a# ]3 u# i: x5 h* T - 10 DWORD fdwOutputPrecision OUT_TT_ONLY_PRECIS OUT_TT_ONLY_PRECIS
, p6 o9 `' M& q; t B# _ - 11 DWORD fdwClipPrecision CLIP_DEFAULT_PRECIS CLIP_DEFAULT_PRECIS6 k, h! l& k9 G$ G
- 12 DWORD fdwQuality PROOF_QUALITY PROOF_QUALITY
/ T* v' k+ D6 f I( Z0 u - 13 DWORD fdwPitchAndFamily FF_DONTCARE | DEFAULT_PITCH FF_DONTCARE | DEFAULT_PITCH
" n2 \, R! z& L1 t/ p - 14 LPCTSTR lpszFace 0x09148a58 "Arial" 0x09148a58 "Arial", _8 m4 c7 M9 J. p9 p
复制代码
1 m( j# i# |& s( r1 d: M0 f6 r4 W y0 r
用ida pro找到调用CreateFontA的源头函数如下。
( k6 P2 b# R: T/ z& m" o从函数的参数可以看出,这应该就是字幕显示函数了。- M* i1 b3 E8 c6 F( B5 f) F
关于后续修改,先修改CreateFontA函数的fdwCharSet,lpszFace这2个参数,也许就能出中文。
+ D- j9 X3 {7 o7 M还不行的话,就自己写一个显示函数。以下函数中lpMultiByteStr就是指向字幕的指针。
" r/ r9 n+ p( w+ j, k
B# p- S2 t: i+ b" @7 `/ A; t+ _3 `- 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)
. e! N0 \/ d; `" |! @; |6 J! _ - {: p3 B/ A* I. N/ s! z( m' s9 ~. X
- void *v11; // edi
5 e$ N( f0 v- U$ }6 M2 ]+ D5 @4 h - int v12; // eax
6 @/ L% {% R* C, p' D; z! i+ X - int v14; // ecx" x6 v. s3 {5 C7 |" L, e0 R
- int v15; // eax1 p( y% Y4 g" d: @6 v0 P) u6 {
- char *v16; // eax
# ^; i, ~; T. B- S" Q: r - int v17; // eax
0 l3 c; m, r: n( c" i5 A& h - HDC v18; // ebp2 B& p( v* M' q* ?7 u
- int v19; // eax. h3 g+ l: q8 M5 R) j
- int v20; // eax9 g% _/ t; @: d" o- i: c- R
- int v21; // esi
/ d& [; [4 y- _" g) f& `+ Y - char *v22; // eax2 O9 p) r, h- Q
- int v23; // esi' e' b+ V3 _: i. G" i8 V
- int v24; // ecx1 m" ~. E) i* e2 f3 t" [/ P* N, m! x
- HBRUSH v25; // eax
! |* N! o q# W" T- a$ _ U - signed int v26; // ebx
: X7 G( f o& c - WCHAR *v27; // eax
. ~7 L6 O0 [* s! { - int v28; // esi
( |+ `0 ^0 P4 p/ Q" C, n% P - int v29; // ecx
; A% Z! w, s) x0 B3 _8 h' Q - int v30; // eax7 j: ~: z; V/ n" n
- int v31; // ST28_4, L% q) a6 Q+ V$ {) A
- bool v32; // sf; A9 J; w" t y, E3 J! B
- unsigned __int8 v33; // of
, _3 W3 g! W0 P4 \, w ? - unsigned __int8 *v34; // ebx" z4 Q, @7 ^% y
- int v35; // ecx2 n Z: b, [- t! @' ]& l7 |8 [
- int v36; // esi
8 B+ h/ ^" u7 j# w5 e - int v37; // edx3 `7 o) v3 n& Q+ K, m. C
- int v38; // eax
) i" t% r% `# [' v6 Y+ j - unsigned __int8 *v39; // ecx$ ^- I& ^2 F# S% B$ l
- int v40; // [esp+40h] [ebp-2098h]: F3 [; l3 L+ B$ J- [% w l
- signed int v41; // [esp+44h] [ebp-2094h]
`9 B* C: {5 s, M& m; ] - WCHAR *v42; // [esp+48h] [ebp-2090h]' @1 n) {7 f) |; q B
- LPCSTR v43; // [esp+4Ch] [ebp-208Ch]
7 o7 ]2 ^: ?$ |) b: v - int v44; // [esp+50h] [ebp-2088h]
- F0 q, h' e7 G1 F& s- o - HGDIOBJ v45; // [esp+54h] [ebp-2084h]
s1 h' w! r! n9 O- |5 \% y - HGDIOBJ v46; // [esp+58h] [ebp-2080h]
1 M& G2 `$ W2 f* G5 L5 F$ i - HGDIOBJ v47; // [esp+60h] [ebp-2078h]# m: I( W3 f3 u8 D0 C, ]
- HFONT v48; // [esp+64h] [ebp-2074h]
9 K8 r6 ?. F- v" q; v - float v49; // [esp+68h] [ebp-2070h]
9 u$ |$ B& U R7 ^) ?; g- i6 s - float v50; // [esp+6Ch] [ebp-206Ch]$ p7 ?. V1 Q1 p
- char v51; // [esp+70h] [ebp-2068h]: e+ u4 F. e# y8 Q
- int v52; // [esp+74h] [ebp-2064h]
) X* ^$ L, w) ^6 ~2 ?1 e - int v53; // [esp+78h] [ebp-2060h]
* g, p" R; c3 ^, a - int v54; // [esp+7Ch] [ebp-205Ch]
6 {9 E6 D2 m4 C; T' W - int v55; // [esp+84h] [ebp-2054h]" ~' v3 F( {0 z$ [: x
- struct tagSIZE v56; // [esp+88h] [ebp-2050h]
( ] ]3 Q- R+ u: q - struct tagRECT rc; // [esp+90h] [ebp-2048h]
, }; J& C: ~! J' \3 M/ Z - int v58; // [esp+A0h] [ebp-2038h]
1 V* j) L- Q, U6 ^" x9 Y - char v59; // [esp+A4h] [ebp-2034h]9 J& ~, |+ z4 f% R2 a o) U- q
- WCHAR WideCharStr[4096]; // [esp+D4h] [ebp-2004h]
3 q/ _( L4 q. s1 e8 O" e - : j' _5 @# W4 `3 S
- v11 = this;
8 ]$ n/ M7 ]" Y' [9 L0 F& r2 _ - v58 = 52;% D1 P2 T, h% l* i2 D
- memset(&v59, 0, 0x30u);/ E- k6 d& M# q0 V# b7 j1 o
- if ( *lpMultiByteStr )
) p; f1 u' ^7 C" W. k- {- w* W - {
$ q& }2 A+ ]) d a0 t - v12 = MultiByteToWideChar(0xFDE9u, 0, lpMultiByteStr, -1, WideCharStr, 4096);
' r* M4 ?" W) f( a3 N& B% t - *((_DWORD *)v11 + 4) = v12;
6 L+ u; L1 t( l - if ( v12 <= 1 )
& ?" Y6 ~: i7 i) m. \8 f - return 0; e% h! ~, R% y
- *((_DWORD *)v11 + 4) = v12 - 1;: [7 R# N) d: Z8 J
- qsort(WideCharStr, v12 - 1, 2u, sub_10057A40);
A, o/ \6 e! ]# O# L1 J/ Z - }
( [; J* {6 ]9 R; g1 R3 u$ E - else7 ?& `2 s# b6 u4 K5 R; O
- {) w7 t/ y; {& a
- *((_DWORD *)v11 + 4) = 352;
2 g+ A2 q6 F: p - v14 = *((_DWORD *)v11 + 4);
/ {+ }) ^7 s$ Q7 X& E - v15 = 0;6 J6 z9 j8 ?0 e
- do$ @- u* j0 A6 w& V) w
- {
2 k& k* B1 l, ^0 E: ^2 P9 g" h - WideCharStr[v15] = v15 + 32;- b( x& Z2 H) K7 E' r3 R
- ++v15;/ }. G/ i. P# u6 u/ g9 P) P
- }
/ \; U& s% R. p& i - while ( v15 < v14 );
" k5 l9 Y7 Z: a' g; F4 M* W - }( F3 ?: e- ^" z- o1 D" ^: Q0 J7 e; h
- v16 = *(char **)v11;2 F' Y# g! ^9 K Y/ o1 N; {& R& ^
- if ( !*(_DWORD *)v11 )
- d" K1 ]1 d+ U - v16 = byte_100B2D6E;2 M. s. X! i$ ~+ X+ |% Y: B
- v17 = CKContext::CreateObject(a2, 31, v16, 0, 0);7 j' P6 J* R- n' w( P* a. G
- *((_DWORD *)v11 + 6) = v17;
! i) P3 I' r% g4 E - if ( !(*(int (__thiscall **)(int, int, int, signed int, _DWORD))(*(_DWORD *)v17 + 84))(v17, xRight, yBottom, 32, 0) )
& |" n' x( c* K; n3 ^' a - return 0;
, ^7 C, K, ~+ a& p5 t7 {, ]& S - (*(void (__stdcall **)(int *))(**((_DWORD **)v11 + 6) + 136))(&v58);( z( l( w1 U) X. ~9 X4 b/ Q2 i
- v18 = CreateCompatibleDC(0);3 P! L. ^% k7 s
- v45 = VxCreateBitmap((const struct VxImageDescEx *)&v58);
) S+ U- w- [9 w9 p - v47 = SelectObject(v18, v45);7 I! O9 ^% {7 R* u
- XString::operator=(v11, a3); D" H0 @+ T; ?1 H o1 n6 [3 M3 \
- *((_DWORD *)v11 + 2) = nNumber;5 A3 x% U% \" J i$ Q
- v19 = GetDeviceCaps(v18, 90);
; N7 W8 y! [- r6 P - v20 = MulDiv(nNumber, v19, 72);) o: L9 N0 ?9 J5 i
- v48 = CreateFontA(-v20, 0, 0, 0, a6, a8 & 1, ((unsigned int)a8 >> 1) & 1, 0, 1u, 7u, 0, a7, 0, (LPCSTR)a4);
% R E( U# v5 L' V k1 N - v46 = SelectObject(v18, v48);
4 ^, Q5 p# A- V; J0 W - GetTextExtentPointA(v18, "A", 1, &v56);$ G0 z+ j* w7 t# t, k
- v21 = *((_DWORD *)v11 + 4);
O, S9 @9 x% @$ S - *((_DWORD *)v11 + 3) = v56.cy;
9 Z, W- E8 T4 y; s8 `& d - v22 = (char *)operator new(32 * v21);
. | M$ d4 {& I: n4 D5 x - if ( v22 )
+ ^9 h }" I8 o - {
- K V3 |& n, Y5 n0 R3 x - v23 = v21 - 1;
K% J6 ^) Q6 h% { - if ( v23 >= 0 )0 J F4 n( I4 a5 h4 Q$ m4 x
- {5 E* ^/ o9 C# \/ n% |8 d% X( Q
- v24 = (int)(v22 + 12);
$ O( G) a9 v2 B3 C$ l8 f - do7 Z9 q7 [( Q- ^5 u8 |; i7 T
- {, ~: n; F k3 u
- *(float *)(v24 - 4) = 0.0;
, V8 p# q8 y& n; S. G0 ?# x - v24 += 32;
+ K( |, x$ |( h - --v23;
4 D9 d) S8 P+ C" ` - *(float *)(v24 - 32) = 0.0;
% j& U5 j7 s) m6 U6 C2 h - *(float *)(v24 - 44) = 0.0;' i& s6 X. @4 Q9 F ?# H9 w
- *(float *)(v24 - 40) = 0.0;
6 ~ W+ T: M3 |0 t1 @ - *(float *)(v24 - 36) = 0.0;
% ~7 K! a' K0 z5 v, u - *(float *)(v24 - 32) = 0.0;3 Y5 P. C" \" a4 d9 C
- }# d- {2 _$ u$ u6 n8 V$ {
- while ( v23 >= 0 );
5 I/ r' G" N' A/ ^% w - }
0 E# a g; P$ o c2 K, W6 _ - }2 W( h! V& N8 ]) x* i& ^. t
- else }* W ]( [6 g0 K5 ]; t! m
- {/ |( v8 ~; Q0 J3 S) f7 y
- v22 = 0;
( d! k5 C4 w2 t: G& T; s - }
3 `" z \% ` s2 }# o0 P* q - *((_DWORD *)v11 + 5) = v22;
/ v3 s1 k7 j8 y5 W- e" n$ S- N' y% m - SetRect(&rc, 0, 0, xRight, yBottom);
, n+ ~3 q9 t. x - v25 = (HBRUSH)GetStockObject(4);
; ?- z* e9 s7 \$ b0 X - FillRect(v18, &rc, v25);
2 k+ S; M9 K' u. P. { - SetBkColor(v18, 0);) m% C, y Q/ y) }6 M7 e7 o+ n
- SetTextColor(v18, 0xFFFFFFu);
! p5 E- _) J: b6 S - SetBkMode(v18, 1);
/ ~/ @) |# [/ E8 Z$ ]& V - v26 = 1;
) K1 {$ V7 e" r: g - v41 = 1;1 A+ z! P+ d7 w( d4 \
- v40 = 0;
& B* e: e6 i* \/ D: q0 I: k. L - v43 = 0;/ \. d* h5 v9 F4 O$ q
- if ( *((_DWORD *)v11 + 4) > 0 )8 G$ {" g F3 a
- {
e: M z; E/ B - v27 = WideCharStr;
% M2 {- h" z$ y- _; n5 n - v44 = 0;
& E: Q8 H8 A5 l - v42 = WideCharStr;9 y% @' ~0 y! @4 m3 O7 A
- v49 = (double)xRight;: R6 b- c# S @# `% k
- v50 = (double)yBottom;3 T2 V) a3 I6 p' L
- while ( 1 )( ?6 x6 |* V6 k
- {' G2 L5 C. v, ^0 w
- v28 = v44 + *((_DWORD *)v11 + 5);- M: h7 o: b) M! o
- *(_WORD *)(v28 + 16) = *v27;
% u8 E. b3 h2 d; }. ]7 e - GetCharABCWidthsW(v18, *v27, *v27, (LPABC)(v28 + 20));
, }# y/ j$ B& u% F0 @* b - if ( *v42 >= 0x20u )$ \1 E9 `3 l9 o% ?, H
- {' r: N3 f6 a4 a% a$ ?, o9 _1 U' ]6 s
- --*(_DWORD *)(v28 + 20);
! ~: K' Y% m' x9 {3 `5 |( E - *(_DWORD *)(v28 + 24) += 2;
& O6 ^8 \! s/ F. ^6 x6 p - --*(_DWORD *)(v28 + 28);
& B( _- e8 n, H9 T - }
& e R7 V2 U5 j& @! S+ y: p2 f: X - else
$ a6 w- }! s# n' N) f! D% n: w - {
5 `/ H0 X2 u2 {, _0 j - *(_DWORD *)(v28 + 20) = 0;- m9 A6 Z- v' J0 a9 [( V/ w
- *(_DWORD *)(v28 + 28) = 0;
1 {8 o& [, \ q' l7 D3 i - }
; |0 b3 R: c. E - v29 = *(_DWORD *)(v28 + 24);
: o/ P. w& i7 ]6 P3 o4 L n - v30 = v40;* r# j. R5 [" t) z, L* b
- if ( v29 + v26 + 1 >= (unsigned int)xRight )" _. `4 _" e+ }1 c4 Z* r) a2 F
- {4 W. g8 }/ @) a1 z% m5 f# [& I
- v26 = 1;0 Z0 @3 A3 H5 i' Y# E3 ~6 F4 X
- v30 = v40 + *((_DWORD *)v11 + 3) + 1;% o4 s5 J. f6 b( P. o
- v41 = 1;$ ?5 j! {4 y, w" [& l
- v40 += *((_DWORD *)v11 + 3) + 1;( ]" u4 k- Q+ y) K( s8 K& q- D$ b% i
- }
; g, @5 I. Y6 O( q - *(float *)v28 = (double)v41 / v49;( U( `1 A7 y) X3 R- g
- *(float *)(v28 + 4) = (double)v40 / v50;
$ T( y7 n4 X: H7 G( n: F8 H - *(float *)(v28 + 8) = (double)(unsigned int)(v26 + v29) / v49;
& w' p; r8 b% t9 B) ?' s D1 m - v31 = v26 - *(_DWORD *)(v28 + 20);
+ o* X8 C6 P2 j/ Q - *(float *)(v28 + 12) = (double)(v30 + *((_DWORD *)v11 + 3)) / v50;( `$ `' d6 ~9 D* B8 P
- TextOutW(v18, v31, v30, v42, 1);% v/ a4 l( p4 i5 A& ~
- v44 += 32;2 b/ ]1 j1 G2 A9 y7 S
- ++v42;! d! l& I m1 t- h! v/ q5 r5 R8 y
- v33 = __OFSUB__(v43 + 1, *((_DWORD *)v11 + 4));# y2 J1 ^2 Q5 h3 I
- v32 = (signed int)&v43[-*((_DWORD *)v11 + 4) + 1] < 0;0 f5 v. h" U0 p0 I0 I3 Y
- v26 += *(_DWORD *)(v28 + 24) + 1;
- R8 \5 |) p: v; ]) g( f5 y( e - v41 = v26;
7 K" T* r2 u3 ? - ++v43;
- _, w; ^) p- b: `& } - if ( !(v32 ^ v33) ): N) t/ Q3 a1 e
- break;
4 [1 h$ f3 n9 t% @( e* I2 c - v27 = v42;
e/ A' r3 C* l( N - }$ u; Y$ Q2 I) I& ?1 d0 v; o
- }
K+ H( O/ u* n; y5 b% c1 C - v34 = CKBitmapData::LockSurfacePtr((CKBitmapData *)(*((_DWORD *)v11 + 6) + 56), -1);) L5 M- ^7 o/ Y* S. e. l
- if ( v34 )% |4 w0 i" T3 D- Y* b. j E+ l4 M7 k
- {4 a: K7 |5 M/ j ~
- GetObjectA(v45, 24, &v51);
# g1 `, [3 s# @. b! C4 P( A - v35 = v53;
9 }, w; W! H! b; X; A7 u - v36 = v55 + v54 * (v53 - 1);
; w% O1 i+ G& [" v7 f - v40 = 0;% r9 y, _' f" E: B
- if ( v53 > 0 )
3 I, o& H, s; [( M - {' X1 R' K3 M" ~) |" d
- v37 = v52;' n& B8 A) V/ e X
- do6 r. A+ L) N# Y* r, k5 k9 U
- {
% }" ~# _! g- k - v38 = 0;
8 Y* p1 X& n3 z+ t2 c- ~ - if ( v37 > 0 )1 [* ^# p6 K G+ k' p: a
- {1 |; s- e! Z) X( y3 H) a% E+ t( a
- v39 = (unsigned __int8 *)v36;/ s, o7 V5 p* B
- do
3 M0 e7 W7 W+ i0 f- x2 J$ b6 _ K - {
/ w! b, O; D3 ]/ ^8 i# r4 a! P - *(_DWORD *)&v34[4 * v38] = (*v39 << 24) | 0xFFFFFF;, V- n4 n! \! a
- v37 = v52; g" `1 s/ c3 C6 u
- ++v38;# [& r5 @; E8 f9 M( T0 @
- v39 += 3;
0 Z% W8 ?) \1 g- X- Q! A7 j& m - }9 v0 ~, I5 \) A* E7 v: u
- while ( v38 < v52 );
4 A, r. F4 J0 T) N+ a' I - v35 = v53;
7 P) Z+ v' { e* R: F# o2 x/ r0 q - }
) I5 r% p5 c6 D: f: }' v - v36 -= v54;! |; w- E, |/ w1 L
- v33 = __OFSUB__(v40 + 1, v35);
6 W; P7 z! {* s7 u! {$ ? - v32 = v40 + 1 - v35 < 0;
* y7 T4 y2 G9 S* C0 y - v34 += 4 * v37;) S q$ Q* H* B1 a5 e3 x
- ++v40;
3 Y9 _9 n1 S8 y, U - }
8 H- E$ h+ l5 k - while ( v32 ^ v33 );
# H; Z0 ~) K. \8 Z a) w - }6 j/ N/ `3 D0 m& i
- }& S, ]/ [" |4 x7 G, `( O
- CKBitmapData::ReleaseSurfacePtr((CKBitmapData *)(*((_DWORD *)v11 + 6) + 56), -1);
# |' F3 \. ^# _! l; ~7 K - SelectObject(v18, v46);
2 ?& g, G: W1 M1 b% Q3 ` - VxDeleteFont(v48);4 [% H) R$ F; B' E n
- SelectObject(v18, v47);
) N* Y0 ^1 g @8 s- c0 x& H5 d$ _( t - VxDeleteBitmap(v45);
! D# ^: Q' ^& a; P7 G" q/ B - DeleteDC(v18);* q' r; z+ J! r3 H5 X( T. H$ k( n
- CKObject::SetName(*((CKObject **)v11 + 6), (char *)a3, 0);
+ X7 X# r9 g* k3 x7 Y - CKBitmapData::SetDesiredVideoFormat(*((_DWORD *)v11 + 6) + 56, 1);0 Z5 u% X$ z; L- B1 h5 ]
- (*(void (__stdcall **)(_DWORD))(**((_DWORD **)v11 + 6) + 120))(0);1 F1 f6 ?4 O- d' g
- return v40 + *((_DWORD *)v11 + 3) < yBottom;
6 z' W) T+ ~9 I% Z: Z/ E3 n/ h! E - }
7 ]" P9 N9 e* P }$ |! k0 N/ q
复制代码
$ X1 V0 Q0 @- s0 _ a1 G0 R J8 Y
$ U! u8 w. Y6 b/ V2 j9 S5 ^ |