本帖最后由 shane007 于 2023-8-26 17:10 编辑 5 K v+ V, H0 z7 Y
, o# o, U% m4 W' H
这个游戏的主要修改点在\player\BuildingBlocks目录下的Adventure.dll中。" ?8 ?( ~3 e0 I) {0 N7 L
用API monitor对本DLL的CreateFontA函数进行跟踪,发现确实有调用, 参数如下。% q( m4 v0 e( P" N/ ]. V
2 s$ H6 c- t/ T0 f+ H8 d/ F8 P- r
- # Type Name Pre-Call Value Post-Call Value, w+ q: P% a/ i
- 1 int nHeight 0xfffffff0 0xfffffff04 N" v% T" d6 _# k* x
- 2 int nWidth 0x00000000 0x00000000
* R( S) C: `3 g P7 d/ \ - 3 int nEscapement 0x00000000 0x00000000
9 _4 \* I5 T/ u# G$ G - 4 int nOrientation 0x00000000 0x000000008 O; H. Z8 p% K2 b
- 5 int fnWeight FW_NORMAL FW_NORMAL5 k4 S( G$ ~' z B
- 6 DWORD fdwItalic 0x00000000 0x00000000
1 C. e8 a) q7 s* m; a$ s* Y - 7 DWORD fdwUnderline 0x00000000 0x000000008 R p3 ` c+ u A
- 8 DWORD fdwStrikeOut 0x00000000 0x00000000) |8 `3 |/ \4 S4 R
- 9 DWORD fdwCharSet DEFAULT_CHARSET DEFAULT_CHARSET, B3 J' L m! J/ d
- 10 DWORD fdwOutputPrecision OUT_TT_ONLY_PRECIS OUT_TT_ONLY_PRECIS
( F! O: k. Q9 t) S - 11 DWORD fdwClipPrecision CLIP_DEFAULT_PRECIS CLIP_DEFAULT_PRECIS
w( s; P6 @& c4 z7 J - 12 DWORD fdwQuality PROOF_QUALITY PROOF_QUALITY; U% X( x1 j, B% R h
- 13 DWORD fdwPitchAndFamily FF_DONTCARE | DEFAULT_PITCH FF_DONTCARE | DEFAULT_PITCH8 f; t' P0 E$ j* X1 ^6 o
- 14 LPCTSTR lpszFace 0x09148a58 "Arial" 0x09148a58 "Arial"
- e/ E0 K2 [, _/ l0 _
复制代码
* a, _: X* B; \, k/ W% G5 h* g0 \
5 u6 ^% S, b& v/ |$ t: j' T- Q用ida pro找到调用CreateFontA的源头函数如下。
. F7 Q( Y- @# H5 N从函数的参数可以看出,这应该就是字幕显示函数了。8 Y9 O3 X- K) Z* Z0 u3 P
关于后续修改,先修改CreateFontA函数的fdwCharSet,lpszFace这2个参数,也许就能出中文。
' k* F4 y0 p9 ^' L还不行的话,就自己写一个显示函数。以下函数中lpMultiByteStr就是指向字幕的指针。# S7 c, L. |/ K. ]9 }
- 9 m$ d# g7 y* H; v; D/ k
- 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)
, e4 A' ~7 J7 M$ P9 F: u1 e - {
0 g# e2 b$ x$ f" R$ }% v - void *v11; // edi
' c1 P: i3 F5 }) X: O - int v12; // eax
* I5 }$ t }3 c! ~/ R) N& S7 P0 V - int v14; // ecx
3 E( ?& c% }6 H8 g$ D' ?: C - int v15; // eax R( a" `/ S1 K% u
- char *v16; // eax
/ i% ]4 b) d$ f n Y - int v17; // eax+ Y- E1 T% k! `4 h. `4 \
- HDC v18; // ebp+ R1 I7 w ?2 s' `: l: b
- int v19; // eax
4 W1 x6 M9 Q; F( ]' i0 L: m2 [( G - int v20; // eax3 ]6 P4 Q2 z+ ]- I+ f
- int v21; // esi8 l$ n4 _$ ]& m3 [' n, A
- char *v22; // eax
- K8 H/ ]5 A0 W$ f - int v23; // esi
& f3 k- u' E- ^: G5 s - int v24; // ecx
% q3 s) c% n( ]+ z/ _( n5 d. o( L+ ` - HBRUSH v25; // eax2 Z1 F4 }* g7 h" x! o
- signed int v26; // ebx- J" w! V' h1 S: I9 {6 N
- WCHAR *v27; // eax" e4 |& [, q+ n# t. G4 X# ^
- int v28; // esi5 s* W1 U& r) D# P
- int v29; // ecx5 |4 _* U- ?$ ?) b4 n3 i- d
- int v30; // eax+ B- t$ B+ Q1 s' @# P- W* W
- int v31; // ST28_4
3 n! v! H: n, [& h$ }" w6 q: e7 N - bool v32; // sf5 s' k1 `- a' ~& v
- unsigned __int8 v33; // of
, r. p7 g! a4 y& @) s6 ]) ]& [+ o - unsigned __int8 *v34; // ebx* I% C& G5 ?# V0 m7 g
- int v35; // ecx" v) Z4 S+ y( X9 z/ e' P) O
- int v36; // esi
0 N/ `; L$ a6 L' X- T$ l( P - int v37; // edx8 S9 E* F6 I' [. ~1 J
- int v38; // eax
6 u& n% i( ^* R& r! Y - unsigned __int8 *v39; // ecx
/ J0 \! D) e/ E# m0 s - int v40; // [esp+40h] [ebp-2098h]
: U) z* i' \6 P: r5 Y - signed int v41; // [esp+44h] [ebp-2094h]' `- W7 S! l' @, Q" D+ z
- WCHAR *v42; // [esp+48h] [ebp-2090h]
3 \# H; y5 H' U% C$ G - LPCSTR v43; // [esp+4Ch] [ebp-208Ch]1 o4 T) r' s1 e
- int v44; // [esp+50h] [ebp-2088h]) T5 v' R c6 ~ O8 y) c- P
- HGDIOBJ v45; // [esp+54h] [ebp-2084h]
: C. v' U( R7 l: L- S - HGDIOBJ v46; // [esp+58h] [ebp-2080h]% @, {) q! m3 v( y
- HGDIOBJ v47; // [esp+60h] [ebp-2078h]
9 A, i2 P. z& i, y* w8 j - HFONT v48; // [esp+64h] [ebp-2074h], T; F, H: Y% }; C# }
- float v49; // [esp+68h] [ebp-2070h]
: o: w& F' {6 g, x9 y7 P9 W+ s - float v50; // [esp+6Ch] [ebp-206Ch]
: Y S: W; \, u - char v51; // [esp+70h] [ebp-2068h]$ `$ @* q9 y0 T7 U/ U4 f, |
- int v52; // [esp+74h] [ebp-2064h]
6 q q& Z( ^6 x% x" w Z. A - int v53; // [esp+78h] [ebp-2060h]
9 U) N, j, B) \1 U& P; Z2 p - int v54; // [esp+7Ch] [ebp-205Ch]
4 `& C. j: t" e0 I! X1 k( h - int v55; // [esp+84h] [ebp-2054h]5 L% \6 L* v \7 W- K# a& {
- struct tagSIZE v56; // [esp+88h] [ebp-2050h]2 ?1 z; b. i$ I9 \ r
- struct tagRECT rc; // [esp+90h] [ebp-2048h]
+ M4 E8 `) W1 A, X. K; p# Q - int v58; // [esp+A0h] [ebp-2038h]
. q0 Q4 ?( M o6 `* h& M0 q - char v59; // [esp+A4h] [ebp-2034h]5 n3 [2 F4 M) s. i- N
- WCHAR WideCharStr[4096]; // [esp+D4h] [ebp-2004h]( L5 `# h7 h# f1 b
- 3 R. a9 g1 `( H& L3 |3 L9 G
- v11 = this;
; G6 C" N! A5 b2 {4 C. S/ } - v58 = 52;
; l% G6 u2 e8 ?7 u8 W - memset(&v59, 0, 0x30u);
4 @8 l: Z$ u! D6 ^5 a9 D9 N& p - if ( *lpMultiByteStr )
3 S' _+ }, u+ W) S, h7 w - {
6 p4 P4 e4 N G4 ^2 a, v - v12 = MultiByteToWideChar(0xFDE9u, 0, lpMultiByteStr, -1, WideCharStr, 4096);
5 Y+ J# z/ o2 q - *((_DWORD *)v11 + 4) = v12;; x( p4 Q& U; ^9 u7 K
- if ( v12 <= 1 ): L0 S. B$ f7 l- a/ F" N# |: Z
- return 0;# i7 C" ~* x8 X* K" C
- *((_DWORD *)v11 + 4) = v12 - 1;* x0 z, ~ d8 @; {
- qsort(WideCharStr, v12 - 1, 2u, sub_10057A40);
* v2 x: h- o4 I1 Y0 G( N - }5 l# I7 G# m+ Z) B
- else- N8 M; Z: g3 R5 D) [
- {
& q, \" y1 f! ^/ O: B - *((_DWORD *)v11 + 4) = 352;7 l( j) M8 B7 _" Z- C
- v14 = *((_DWORD *)v11 + 4);# p) o% X* y2 M8 g5 C6 a% A
- v15 = 0;, R% M7 H' z# l+ p- R u) z# o
- do" U) t# D% S T/ n
- {, [+ c; N1 {/ j' o
- WideCharStr[v15] = v15 + 32;: y' H6 H. g* o/ s/ Y0 U
- ++v15;
$ ?9 i3 n& H7 p& {5 L5 R6 b - }
' A+ }# u5 R. m" Y& k - while ( v15 < v14 );
- }2 }* B+ w1 x v3 k+ F1 P5 _ - }
$ H/ R, l0 m3 `! M" Q/ v - v16 = *(char **)v11;: A. u0 V& b6 ^
- if ( !*(_DWORD *)v11 )4 W+ U1 a4 \) z8 J* s. o9 s
- v16 = byte_100B2D6E;% q1 |0 J D0 w: F5 [- H
- v17 = CKContext::CreateObject(a2, 31, v16, 0, 0);8 A- Y, V6 X% |; S
- *((_DWORD *)v11 + 6) = v17;- l1 p) }) |8 c4 h6 }2 T8 H
- if ( !(*(int (__thiscall **)(int, int, int, signed int, _DWORD))(*(_DWORD *)v17 + 84))(v17, xRight, yBottom, 32, 0) )8 O7 D8 n" H) o1 V
- return 0;6 c" _9 r* l* b& O& s. a
- (*(void (__stdcall **)(int *))(**((_DWORD **)v11 + 6) + 136))(&v58);5 ^5 b. E/ |7 y7 b5 R# Z- Q! ^8 o
- v18 = CreateCompatibleDC(0);
# c$ }5 N% r/ D/ B( p) K - v45 = VxCreateBitmap((const struct VxImageDescEx *)&v58);
( g. a& S5 S2 p6 x8 j3 h0 t - v47 = SelectObject(v18, v45);
# r/ c) | C) @* e; \2 ~9 b: o - XString::operator=(v11, a3);
2 o! _. v) L! F1 K9 O u; ~ - *((_DWORD *)v11 + 2) = nNumber;
+ G2 Z+ O6 T) F ]+ J4 c- \/ e& U - v19 = GetDeviceCaps(v18, 90);' ~1 }) h3 p! z' S6 D
- v20 = MulDiv(nNumber, v19, 72);
9 G8 z- l2 c) j5 h - v48 = CreateFontA(-v20, 0, 0, 0, a6, a8 & 1, ((unsigned int)a8 >> 1) & 1, 0, 1u, 7u, 0, a7, 0, (LPCSTR)a4);8 K, M# ?5 Z5 X! F
- v46 = SelectObject(v18, v48);
4 |" L2 l! G+ t5 ?; |4 }' Q& Q% |+ N - GetTextExtentPointA(v18, "A", 1, &v56);2 B1 W r: i: ?, o; S5 h; a
- v21 = *((_DWORD *)v11 + 4);: \ b2 Q/ j9 [6 M& ~, }- z
- *((_DWORD *)v11 + 3) = v56.cy;
% F2 L8 [+ k$ x5 M1 ]7 Q& N - v22 = (char *)operator new(32 * v21);. i$ B/ [/ |: Z# q+ M2 o- Z
- if ( v22 )4 B9 ?4 C, ?' ~9 t0 E: V( T. D
- {
2 H& g) o2 @5 K: D5 v - v23 = v21 - 1;
5 M/ z g! O* x" B1 m. | - if ( v23 >= 0 )! E$ Q, i5 B3 ^/ g" ]( u
- {
6 r% n) s3 O" m3 s; J" A - v24 = (int)(v22 + 12);/ X" G9 s) H! M( R; \
- do
X/ x0 h. ]9 V5 q( G - {2 I- J+ g4 H7 O! K& K: Z
- *(float *)(v24 - 4) = 0.0;2 ~9 n: `0 D$ q) r. G( r$ \5 q/ z" h
- v24 += 32;$ ` @* n% b, r& l/ r' j+ s3 d
- --v23;$ k7 [& l3 u7 ]* M
- *(float *)(v24 - 32) = 0.0;
' e3 z% g/ e1 r6 y - *(float *)(v24 - 44) = 0.0;, d h2 U: q( y& A `
- *(float *)(v24 - 40) = 0.0;
- m7 y$ w) i% W# q, U& b; o - *(float *)(v24 - 36) = 0.0;3 r7 u: D+ w# i/ o: ^! w: {3 X
- *(float *)(v24 - 32) = 0.0;$ q; Z/ Y+ N9 ~/ k; K
- }( {" ]6 S& G8 l
- while ( v23 >= 0 );
; ~# F. k% z5 J& q! j1 V - }2 W; _5 G5 `& A0 r |0 s1 J
- }
# a* \* o e* ` W - else+ {* c" X N( Y3 k" y
- {4 N/ C3 b7 x1 S3 B# L
- v22 = 0;6 _* y0 e# S* m. v! @
- }" R$ p* \3 E! M$ _8 ~
- *((_DWORD *)v11 + 5) = v22;5 ^: A, a( @! }5 Z' ` y+ Y/ E6 ~
- SetRect(&rc, 0, 0, xRight, yBottom);
" l+ M. _, R* c9 ?! b) K - v25 = (HBRUSH)GetStockObject(4);, ^; p" ]0 r! T8 ]' R; T
- FillRect(v18, &rc, v25);& `3 U% Q* E5 r# ?, Y0 q
- SetBkColor(v18, 0);
1 A) b+ b1 M0 z - SetTextColor(v18, 0xFFFFFFu);
& x0 M3 e, f0 D+ Q l$ v - SetBkMode(v18, 1);0 D/ R4 K2 b4 \ K# v! ~8 e4 o
- v26 = 1;5 d2 a6 h+ v) O }3 G$ o5 s
- v41 = 1;& s5 c: p/ g3 |& `$ ]
- v40 = 0;# |+ \0 t/ u& n5 g# d7 N: a
- v43 = 0;0 x+ A( d3 ?( K9 z+ m
- if ( *((_DWORD *)v11 + 4) > 0 )
3 z# B5 l; S' l& v* {) _$ k - {2 { k! E1 C. u6 o
- v27 = WideCharStr;3 R% \$ k9 f) o9 S4 y
- v44 = 0;- Z; Q, Y4 \: f7 Q( t' m* t
- v42 = WideCharStr;& j& I7 e9 L# N. O8 \2 |1 C" g1 P
- v49 = (double)xRight;
# d, U: o, d& ~5 v' {7 | - v50 = (double)yBottom;
, X7 q: r+ c4 A8 [ - while ( 1 ) f t1 J) N+ [
- {
, }" ^7 d% s. ^) K G - v28 = v44 + *((_DWORD *)v11 + 5);& s+ R6 _/ D4 A# O1 L3 ~1 m3 [
- *(_WORD *)(v28 + 16) = *v27;
0 n5 y8 Y; i! c* w4 z7 v y( B - GetCharABCWidthsW(v18, *v27, *v27, (LPABC)(v28 + 20));- w0 w9 W/ Z/ h
- if ( *v42 >= 0x20u )
' B4 V8 p5 S1 X: Y1 f2 z - {
6 r, W* h! z) m, t! o - --*(_DWORD *)(v28 + 20);* F+ _' e0 B6 u: [
- *(_DWORD *)(v28 + 24) += 2;
" J. Q- z4 [* F1 b0 _# |2 \ - --*(_DWORD *)(v28 + 28);; u7 W: M* F! g( \: e
- }
! K. F+ l; ~- q) y - else& P' i1 h3 X4 v N
- {
% R* b) \$ j: W6 C6 y7 B - *(_DWORD *)(v28 + 20) = 0;* P* O* m+ z& p& l6 t# L( K+ c
- *(_DWORD *)(v28 + 28) = 0;
( i" H8 a% N) ~/ x) b: {5 Y - }
. v3 j, g) L0 |3 \5 Q% v& y8 \ - v29 = *(_DWORD *)(v28 + 24);6 Z$ ?& q0 l: t, h
- v30 = v40;
5 w! p) V0 A$ r( R - if ( v29 + v26 + 1 >= (unsigned int)xRight )* B" T* y/ c! M' c7 I
- {
4 V/ V7 x2 l) T* Q - v26 = 1;. G( I; Y0 N6 t& T. d. i# Y
- v30 = v40 + *((_DWORD *)v11 + 3) + 1;
& S- p H: ]4 D - v41 = 1;
/ ^, n/ L4 a$ t6 H6 t - v40 += *((_DWORD *)v11 + 3) + 1;& O4 V0 }. @6 L8 h1 i$ _
- }
8 [4 }9 `* V) v: X& f8 r/ I - *(float *)v28 = (double)v41 / v49;
- X1 b, r" H# l2 j - *(float *)(v28 + 4) = (double)v40 / v50;- g4 g/ ?- P6 R9 F ]
- *(float *)(v28 + 8) = (double)(unsigned int)(v26 + v29) / v49;1 R0 u s4 `6 ~/ y
- v31 = v26 - *(_DWORD *)(v28 + 20);
! F6 e* Z; j7 f: Z4 M4 { - *(float *)(v28 + 12) = (double)(v30 + *((_DWORD *)v11 + 3)) / v50;6 x" c/ O; A3 V- F
- TextOutW(v18, v31, v30, v42, 1);/ h- ~' n3 c* n p) ?) i0 |
- v44 += 32;- I+ n9 w6 t( Q0 r" M
- ++v42;
" l% A; L) u5 i- u1 P Q - v33 = __OFSUB__(v43 + 1, *((_DWORD *)v11 + 4));( `: C* w& f- o) ~' i3 _
- v32 = (signed int)&v43[-*((_DWORD *)v11 + 4) + 1] < 0;
" _+ b) J9 k0 ] - v26 += *(_DWORD *)(v28 + 24) + 1;
" C, u v- `3 ^: Q: s( U - v41 = v26;" v. V! A$ p7 r) t' g! f
- ++v43;, L5 z& ^ A9 F+ h! L5 m
- if ( !(v32 ^ v33) )
+ Y. o( p$ @( D* ?8 R% D - break;
* ]+ ]0 b2 Z5 @5 z2 N% e3 w) g - v27 = v42; Y2 ` M3 A/ V- {4 q4 L
- }1 M" O) H& [1 Z/ F' l. |+ ]
- }
3 R9 g( [; z0 |" c; m5 Z- ` - v34 = CKBitmapData::LockSurfacePtr((CKBitmapData *)(*((_DWORD *)v11 + 6) + 56), -1);6 x4 i) O8 r8 Z1 F
- if ( v34 )5 t3 Z( t! h2 G* r% ?
- {
% h. J" ~4 X6 A: c- v - GetObjectA(v45, 24, &v51);
) g0 A: y/ I( E/ H. x7 S4 A( o/ } - v35 = v53;
, X0 ^4 e7 j9 ^% O0 [9 ^) c1 ~( Z - v36 = v55 + v54 * (v53 - 1);
3 {6 v' A) P, f) f! y' ~$ O! b: ]: ^ - v40 = 0;
3 x" J/ `1 W+ R: F7 N - if ( v53 > 0 )
. m1 K8 Y D0 l2 j1 P - {
5 H# f1 `+ D* a9 z4 F - v37 = v52;
) D5 u5 ?# f7 r( t - do
6 `; f% \6 h* S - {
4 G+ ?+ Z8 A, d i2 X - v38 = 0;; w+ ~- c( u' z" H: x: c+ W
- if ( v37 > 0 )
0 T3 x" x/ j5 I - {4 F; g2 y4 `: c) Z. d* @+ }: H
- v39 = (unsigned __int8 *)v36;
4 | g2 b% Z& u4 ^& e - do; {8 ~) x& G% O3 m8 R' R
- {: q* I: W8 v& n3 D5 ]! Q
- *(_DWORD *)&v34[4 * v38] = (*v39 << 24) | 0xFFFFFF;
) U# y4 W: K# o1 t$ i" w" h - v37 = v52;$ \1 i' y1 E e9 R5 _4 U0 r
- ++v38;
) Q: w0 U$ s- {) ~% K/ Z/ A - v39 += 3;
# |1 K$ Q" X" _, n$ @: o# G+ Z/ } - }
" S+ i! F& n! B# ~! I7 M5 w9 U - while ( v38 < v52 );. E& D; B) d' O$ m) J
- v35 = v53;/ N0 n' }* N& j" e
- }- U5 S" K- g6 i6 O
- v36 -= v54;
3 C; S! I7 U8 h# I# l* } - v33 = __OFSUB__(v40 + 1, v35);
8 @8 P5 ?. v, P; j( A- C" X - v32 = v40 + 1 - v35 < 0;
6 C# o1 V7 D/ H2 D( t5 Q6 m - v34 += 4 * v37;0 O! l7 P6 c! N$ u3 Z' M
- ++v40;+ c5 k t$ v) z$ }
- }" G% h ~, M4 m% ~
- while ( v32 ^ v33 );- r; ]& P& a6 m& m+ H: t- r2 U
- }
8 w$ f, @" n9 j4 w+ {2 L: r# O3 [ - }0 [6 \3 d# G- o3 y! @$ K }9 G
- CKBitmapData::ReleaseSurfacePtr((CKBitmapData *)(*((_DWORD *)v11 + 6) + 56), -1);
3 Y2 w. n9 D: A1 K& Y/ J! z - SelectObject(v18, v46);
3 ^* S$ d: S) _# C3 _ - VxDeleteFont(v48);
& P4 G% z1 u2 ]1 C8 l" `+ e; l* X - SelectObject(v18, v47);
- e" E& t& d4 E: j5 s' A - VxDeleteBitmap(v45);
, l% e% N' w8 R8 I; G- r% _ - DeleteDC(v18);
1 W$ X$ b- d' k: ^9 ^ - CKObject::SetName(*((CKObject **)v11 + 6), (char *)a3, 0);+ ^8 u4 j% d4 y1 t1 S
- CKBitmapData::SetDesiredVideoFormat(*((_DWORD *)v11 + 6) + 56, 1);$ ]2 Q8 n5 V1 v3 _6 C" I7 L
- (*(void (__stdcall **)(_DWORD))(**((_DWORD **)v11 + 6) + 120))(0);6 z2 `# q' ^# }( U2 g
- return v40 + *((_DWORD *)v11 + 3) < yBottom;- c2 w0 Y4 }* f E3 W2 R7 W
- }# C! {* i3 V5 g- A* m, a% I8 j- Q
复制代码
; c4 [8 Z0 _& |% x }6 ~4 v
. T* w) `& |& K4 Y9 X' c' w |