本帖最后由 shane007 于 2023-8-26 17:10 编辑
! ]% r M/ s4 ~* y ^8 d+ r8 z* c: L2 b
这个游戏的主要修改点在\player\BuildingBlocks目录下的Adventure.dll中。' a: r. S' |: t) l) w
用API monitor对本DLL的CreateFontA函数进行跟踪,发现确实有调用, 参数如下。
V) r3 ^$ D, O
, k6 y( s" B/ b' ~( u; u- # Type Name Pre-Call Value Post-Call Value/ n7 N" f( G, i5 D* Y- N
- 1 int nHeight 0xfffffff0 0xfffffff0
5 k( X! Z: Z, g - 2 int nWidth 0x00000000 0x00000000$ N. Y, V/ U8 C1 b: p1 v8 W
- 3 int nEscapement 0x00000000 0x00000000& F: ?+ D8 D' V( c2 ~, H
- 4 int nOrientation 0x00000000 0x00000000) ?: g* ?/ h; h% V& F# p
- 5 int fnWeight FW_NORMAL FW_NORMAL/ r4 o s2 M0 I/ o8 j5 G+ I
- 6 DWORD fdwItalic 0x00000000 0x00000000 Z/ y" I2 K ?- l! Y) H
- 7 DWORD fdwUnderline 0x00000000 0x000000001 K3 J$ `5 u% K+ y& w. |
- 8 DWORD fdwStrikeOut 0x00000000 0x00000000
+ f( p8 G" q) k' G5 J% b - 9 DWORD fdwCharSet DEFAULT_CHARSET DEFAULT_CHARSET
( x; ~ o3 L- E/ |; ]2 s - 10 DWORD fdwOutputPrecision OUT_TT_ONLY_PRECIS OUT_TT_ONLY_PRECIS
1 {# k0 U6 T, v, p `# j - 11 DWORD fdwClipPrecision CLIP_DEFAULT_PRECIS CLIP_DEFAULT_PRECIS: e- Y5 j8 Q4 \* ~/ ^: X; ^8 Q
- 12 DWORD fdwQuality PROOF_QUALITY PROOF_QUALITY
8 L5 d. y/ ^& V, N* D+ {! _; ` - 13 DWORD fdwPitchAndFamily FF_DONTCARE | DEFAULT_PITCH FF_DONTCARE | DEFAULT_PITCH
2 q5 [+ E r6 G4 b - 14 LPCTSTR lpszFace 0x09148a58 "Arial" 0x09148a58 "Arial"! w3 m8 J3 m: z! ]
复制代码 8 G; B3 Q( i' Y, c4 q
! E$ n! S, w/ N& h- b x# ]9 {0 b
用ida pro找到调用CreateFontA的源头函数如下。
; u/ [" d) G' Q' B% J, i从函数的参数可以看出,这应该就是字幕显示函数了。
0 ?, r6 `& Q" ], r% T关于后续修改,先修改CreateFontA函数的fdwCharSet,lpszFace这2个参数,也许就能出中文。
+ }) h. Q# c; K1 q% O还不行的话,就自己写一个显示函数。以下函数中lpMultiByteStr就是指向字幕的指针。- [' n u( B' X/ P
^6 _" X2 b- l y! i1 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)
, L, }$ O H8 z+ B/ @) S - {
6 |. X) M: k j - void *v11; // edi! ]1 K) C7 l8 }* a" b2 t
- int v12; // eax
* O* N( o4 J+ Q3 h2 I' ]0 _ - int v14; // ecx3 C2 Z4 T" r. T) e
- int v15; // eax
1 m% f- A8 L4 @8 F7 P - char *v16; // eax
$ Z- |3 m7 ]' p" q. }) p - int v17; // eax
5 @1 k# q. x- g) H& {' j - HDC v18; // ebp
* Q% ?$ s" _4 k- F3 Y. q# \ - int v19; // eax
+ B+ `% t5 D3 y/ q- ? - int v20; // eax u* L9 ~4 T' h7 W: n; D
- int v21; // esi- O1 S {& I3 Q8 R2 p
- char *v22; // eax: M3 P# P: O# x, C" p: w7 }
- int v23; // esi5 F* X* H7 h# n" P% B# N. x
- int v24; // ecx
* S" b8 n; M8 p+ I - HBRUSH v25; // eax
: b9 t: [( u5 H8 n. N% @ - signed int v26; // ebx. {, |0 X* j4 Q+ K4 R" v1 l
- WCHAR *v27; // eax
6 A: T6 k, d! \$ d& T5 H - int v28; // esi) c% u3 j, [# o, v
- int v29; // ecx
: I9 w) A( ]% v3 t# E2 D6 G6 _2 v - int v30; // eax
( r" y6 n U7 K+ |% P2 T. y - int v31; // ST28_4
9 e" R+ t6 o: O: i6 C% l - bool v32; // sf! g! x! I* t v2 w# q) ^
- unsigned __int8 v33; // of3 ?+ H2 Z. g1 ~/ D0 X ?' u7 N" ^
- unsigned __int8 *v34; // ebx
1 `" u, y/ g9 ]4 r5 L( q - int v35; // ecx
" N$ `& Y! Q3 I d( X4 |8 K A4 \ H - int v36; // esi
8 K" y. d0 U2 F5 k# q# g - int v37; // edx8 J# U' N4 u3 S Y" l2 \- C8 \) ]
- int v38; // eax
4 B* {' z* S4 R3 v2 @ - unsigned __int8 *v39; // ecx
: P! b, M6 |: s) g - int v40; // [esp+40h] [ebp-2098h]
9 g" T, Z; Q ?4 N: X# J - signed int v41; // [esp+44h] [ebp-2094h]
* b7 Q+ V- H& q5 n% D: ~9 q - WCHAR *v42; // [esp+48h] [ebp-2090h]
2 a, o5 N' E0 k% \) P7 l$ ]% Z - LPCSTR v43; // [esp+4Ch] [ebp-208Ch]
9 A6 P) @2 \2 y. p5 h5 D& k7 M - int v44; // [esp+50h] [ebp-2088h]
6 r; U8 `1 a* e7 Q: W# {+ Y1 l9 |* g - HGDIOBJ v45; // [esp+54h] [ebp-2084h]4 ~/ R, k$ q0 o) _4 {- `& S6 h
- HGDIOBJ v46; // [esp+58h] [ebp-2080h]& z! ?) Z8 m/ C6 T9 Z4 x
- HGDIOBJ v47; // [esp+60h] [ebp-2078h]
! v2 p9 {. e z$ m* \; ^8 ]1 b - HFONT v48; // [esp+64h] [ebp-2074h]
. m, t+ K6 i% h+ G/ Q* t - float v49; // [esp+68h] [ebp-2070h] M: {7 L2 G' L+ \ q, l" k
- float v50; // [esp+6Ch] [ebp-206Ch]
) j8 F4 T s0 {: [8 ` - char v51; // [esp+70h] [ebp-2068h]
# f Q0 ?& j, k8 g6 X# v/ W6 A - int v52; // [esp+74h] [ebp-2064h]6 C- X3 l7 X2 j W' T3 M9 K
- int v53; // [esp+78h] [ebp-2060h]2 w6 l" H w$ e+ a8 k
- int v54; // [esp+7Ch] [ebp-205Ch]! C% k1 [! B! z
- int v55; // [esp+84h] [ebp-2054h]
# q- j0 G& F) B: q - struct tagSIZE v56; // [esp+88h] [ebp-2050h]
; e- n6 K- N A4 N/ R9 L - struct tagRECT rc; // [esp+90h] [ebp-2048h]4 g: u0 ~9 O! O# n* \: j$ T
- int v58; // [esp+A0h] [ebp-2038h]2 v+ b+ ~. q& u$ ^' _4 ?1 P u+ J/ R
- char v59; // [esp+A4h] [ebp-2034h]; o# z- T5 |( i% i3 `
- WCHAR WideCharStr[4096]; // [esp+D4h] [ebp-2004h]
" f# c3 ?6 T3 B; M
9 M( x- s& M( h7 W- ?9 T- v11 = this;
7 X7 ?: u1 Y( l x* e: i - v58 = 52;0 N3 G0 n/ ~* r. s; V" h
- memset(&v59, 0, 0x30u);
( E, o5 x2 Z! t6 i+ R% A - if ( *lpMultiByteStr )8 @( M: D P1 g9 J/ @' @, ]
- {! z w- i+ ~& ], X' W
- v12 = MultiByteToWideChar(0xFDE9u, 0, lpMultiByteStr, -1, WideCharStr, 4096);2 b+ z$ ~4 z4 f& {/ @
- *((_DWORD *)v11 + 4) = v12;
& U$ h* Z6 E/ @0 u* P4 P* z - if ( v12 <= 1 )
P& w1 d- i1 ^: v( H; e5 c - return 0;
0 {2 E; ?# ]) n - *((_DWORD *)v11 + 4) = v12 - 1;
) C) W, O! y* u( X3 g - qsort(WideCharStr, v12 - 1, 2u, sub_10057A40);
5 A( [8 D% L: N3 L* G7 d - }# l! F7 m+ Q2 I
- else
( O N5 ]" }: Q. D$ [2 D, H - {+ b7 o) g1 ]+ w
- *((_DWORD *)v11 + 4) = 352;3 T/ P/ u5 z* l$ R. i
- v14 = *((_DWORD *)v11 + 4);
7 X5 i+ n Y( o0 n p - v15 = 0;( `# a. b. P2 Z0 h
- do
1 b( O: f" {: J8 I/ O! A - {1 k) {5 r9 K: f
- WideCharStr[v15] = v15 + 32;
* y0 L, K( O A( x3 B - ++v15;& q4 Z+ H" H% w. h9 S
- }/ X( u$ C& F2 i( L9 z# A" r% w
- while ( v15 < v14 );
7 `& Q7 f1 o1 w' h3 t! b - }4 b4 {/ U3 h4 d1 f* j9 l" s
- v16 = *(char **)v11;. a* I$ {7 p, A6 I9 N
- if ( !*(_DWORD *)v11 )* p% w+ K& M. V- {
- v16 = byte_100B2D6E;% U; v4 m, l8 J0 s2 c
- v17 = CKContext::CreateObject(a2, 31, v16, 0, 0);& y* ~, r9 Y- P2 h
- *((_DWORD *)v11 + 6) = v17;
. U8 n# T$ ~" y! t; M - if ( !(*(int (__thiscall **)(int, int, int, signed int, _DWORD))(*(_DWORD *)v17 + 84))(v17, xRight, yBottom, 32, 0) )
% C. v9 d2 d' Y% M; z2 D - return 0;# ]- m3 P- ]1 t' w
- (*(void (__stdcall **)(int *))(**((_DWORD **)v11 + 6) + 136))(&v58);% v- G' r: C1 S. ?0 }* w4 s
- v18 = CreateCompatibleDC(0);. a0 j" }0 _6 z( h( ~
- v45 = VxCreateBitmap((const struct VxImageDescEx *)&v58);7 ?6 m- E- C, y' _
- v47 = SelectObject(v18, v45);4 Z8 }5 f4 r3 n# B8 G( C2 [
- XString::operator=(v11, a3);; |# x4 q. r: u2 v# ~% a$ J
- *((_DWORD *)v11 + 2) = nNumber;
- C# [) ]: v8 S k9 p - v19 = GetDeviceCaps(v18, 90);
' D. g8 t6 y9 M$ x, ? - v20 = MulDiv(nNumber, v19, 72);: I7 k. z9 ~- O& a# K
- v48 = CreateFontA(-v20, 0, 0, 0, a6, a8 & 1, ((unsigned int)a8 >> 1) & 1, 0, 1u, 7u, 0, a7, 0, (LPCSTR)a4);" n4 {1 [8 U* K8 o
- v46 = SelectObject(v18, v48);
9 e& K! E* K/ |) j9 l: ] - GetTextExtentPointA(v18, "A", 1, &v56);
1 M; W1 {- p5 m( {; L9 \0 n+ Q - v21 = *((_DWORD *)v11 + 4);
/ u: y7 o# U! }7 m! a- M. O+ p - *((_DWORD *)v11 + 3) = v56.cy;3 ~: e( k, d {# ~, z, A+ r' v7 t
- v22 = (char *)operator new(32 * v21);
& X. }+ i. z, a, |2 ~( d) } - if ( v22 )) g4 a5 u- \3 ?% Z- z. J
- {& s6 R8 Z5 C: Y5 q
- v23 = v21 - 1;4 @; p9 [! g/ f. l5 C! k
- if ( v23 >= 0 )$ ?( P9 v% l" M! t
- {
! p) a; ~/ K7 h) e9 ]4 n - v24 = (int)(v22 + 12);
: S9 G0 x' ?. P9 S) { - do
5 }3 L5 r) l% G, h9 j# n- A( c - {: Y! I: \0 C' h* o. ?% H" r" |4 a
- *(float *)(v24 - 4) = 0.0;
( ]( B! {" i, Q( s7 T - v24 += 32;
4 d+ H+ `: S/ l( j4 v) o* u - --v23;$ b) V" g$ s5 M3 h
- *(float *)(v24 - 32) = 0.0;4 H' V! @1 D" e& i! S
- *(float *)(v24 - 44) = 0.0;6 B; a. ^5 M9 I7 `0 i6 G
- *(float *)(v24 - 40) = 0.0;0 \& E; g* k9 u y; D W
- *(float *)(v24 - 36) = 0.0;. @& \7 U# E( S s
- *(float *)(v24 - 32) = 0.0;- m/ I) G+ z7 m/ s; S6 s+ q
- }
. G' |- P0 `# R7 Z+ ?; i - while ( v23 >= 0 );
6 ?" o9 E2 c( ?( A4 A; H - }: A' H* l7 {/ u* C
- }
2 Y# l% `- x1 g' y+ E0 j - else
$ |3 C! x' {9 D$ u) ~4 a: ` - { n2 T3 s2 N- p! I" J5 U- G
- v22 = 0;+ H9 s. N7 o/ t0 e
- }
/ H+ p9 j8 Z1 O2 d$ z: `! K# B% } - *((_DWORD *)v11 + 5) = v22;- {; P! {. O( r' [# K7 N& f
- SetRect(&rc, 0, 0, xRight, yBottom);
4 C2 c) K3 x8 ^) b2 n5 n/ T - v25 = (HBRUSH)GetStockObject(4);) `$ P) _8 X. G$ b; C9 J5 w
- FillRect(v18, &rc, v25);5 ^. S: d; z7 C3 x, H3 j
- SetBkColor(v18, 0);
% [1 C3 a& f) R; G5 x$ n) g( X | - SetTextColor(v18, 0xFFFFFFu);
' i' V9 n2 G1 b' {, E' s9 j - SetBkMode(v18, 1);' Z0 U1 _- u8 N0 ]- n" ~. k
- v26 = 1;
# y- x$ `7 V; [: O - v41 = 1;
3 [$ @+ Q# A* }4 } ^ - v40 = 0;
m, h$ r4 k( r2 Z$ [ - v43 = 0;
; G: R& J- v: C( F - if ( *((_DWORD *)v11 + 4) > 0 )9 y0 V' z# v( i
- {' O9 s- Q% f9 O5 g* G6 K
- v27 = WideCharStr;
/ F, g; r+ Q; D+ q - v44 = 0;
5 P& s8 {: ~8 i& f - v42 = WideCharStr;* k: P/ C8 H, [9 l) o
- v49 = (double)xRight;
1 M# v' E8 Q$ R) x6 {. T0 C - v50 = (double)yBottom;
( h) s0 N+ |% b - while ( 1 )0 h7 g' S$ |1 E5 {
- {
1 _9 N9 ~1 s$ O8 d+ H, T - v28 = v44 + *((_DWORD *)v11 + 5);
4 c: H3 e! w% N0 t9 m" ~ - *(_WORD *)(v28 + 16) = *v27;
) J, z+ V, T. A9 ~ r! t1 O; p - GetCharABCWidthsW(v18, *v27, *v27, (LPABC)(v28 + 20));
, @5 T: y+ f# J }; d8 L9 @ - if ( *v42 >= 0x20u )0 M& {2 `) ?, q4 X3 x
- {' d$ w" N, g, T4 V
- --*(_DWORD *)(v28 + 20);
3 u% L' d. x& p5 R% O - *(_DWORD *)(v28 + 24) += 2;
; b% _2 T% r! H; Q, i) S - --*(_DWORD *)(v28 + 28);( T/ p y, Q6 u( N. b
- }0 j- Q* s0 P$ }& I$ Z) h9 s
- else6 G( c. M# ~0 `/ f
- {5 l& f7 b% e- j L6 @# h, Y4 x
- *(_DWORD *)(v28 + 20) = 0;
) r: d0 C1 v& D, V$ l! h# U. m - *(_DWORD *)(v28 + 28) = 0;0 O% F/ J8 g+ Z' f! [
- }
' H, g' Y, \% w# b. k7 u& g5 W; j - v29 = *(_DWORD *)(v28 + 24);
; g) i( ~4 s: G u* O - v30 = v40;/ ~ V4 _+ _, |# m$ B) P
- if ( v29 + v26 + 1 >= (unsigned int)xRight )
3 D1 ^9 l7 p m$ z - {
+ O3 W; a4 d2 M) s2 F8 x D* E. T* m - v26 = 1;
+ S2 l) \# v1 h - v30 = v40 + *((_DWORD *)v11 + 3) + 1;; S6 ~( E5 k5 Q6 x- N" T; A) I
- v41 = 1;
$ @1 ?: q' @6 O - v40 += *((_DWORD *)v11 + 3) + 1;
) h, A/ b: q8 _4 Y - }; n: [7 k' A0 z0 |$ }9 a
- *(float *)v28 = (double)v41 / v49;
4 R" y7 b0 x* a: F5 N7 L! d2 n - *(float *)(v28 + 4) = (double)v40 / v50;4 o0 e8 U5 O( |! r
- *(float *)(v28 + 8) = (double)(unsigned int)(v26 + v29) / v49;
4 l! A7 t4 m1 K: f - v31 = v26 - *(_DWORD *)(v28 + 20);
) g3 e$ S" V$ z1 p: \7 k0 } - *(float *)(v28 + 12) = (double)(v30 + *((_DWORD *)v11 + 3)) / v50; [4 u4 y. v6 e5 x1 E) a4 o
- TextOutW(v18, v31, v30, v42, 1);& p8 k0 G/ m, h' ?/ s+ y- A4 B7 w
- v44 += 32;- \0 x, N' z, P0 d2 Z
- ++v42;# e7 H3 `2 F0 t7 X# p
- v33 = __OFSUB__(v43 + 1, *((_DWORD *)v11 + 4));( ?2 u& e* i+ E$ z
- v32 = (signed int)&v43[-*((_DWORD *)v11 + 4) + 1] < 0;
% m! _/ ]3 [' I2 |$ x; Z( H - v26 += *(_DWORD *)(v28 + 24) + 1;3 P1 D; B3 r# R! R9 o
- v41 = v26;. y+ E& Q' ?: P. U( S& D; U& M8 T
- ++v43;
- k4 n) T, y8 E' c - if ( !(v32 ^ v33) )
) U( v+ C2 O4 `' v3 d5 u! x$ E - break;
^8 k6 l6 Q2 D2 p7 V - v27 = v42;- n1 s, o. ~2 e; L. A0 {6 _
- }
V W7 u* \! d - }' g# U1 H3 U5 X1 C; [/ h) ]
- v34 = CKBitmapData::LockSurfacePtr((CKBitmapData *)(*((_DWORD *)v11 + 6) + 56), -1);
4 Y) Y% t1 V2 \* z& B- t - if ( v34 )$ S8 E4 u' B3 g! ~# o1 X& p
- {
: ]; k" Q+ s Q3 t) c! R' { - GetObjectA(v45, 24, &v51);
: E, ^4 _6 V- H* Y/ Y$ F: }$ y - v35 = v53;& ~" A3 L# ]! l9 ]( @
- v36 = v55 + v54 * (v53 - 1);
, Q9 I- w! g# z; \! ?; ~ - v40 = 0;
* Q) G! U2 H2 `) ~8 }! i - if ( v53 > 0 )
( A, k$ t! M+ w" D, @* B+ J - {
6 l: U; S& X- H - v37 = v52;, C9 C& [* C% g# J; P8 _
- do
! P6 i. i7 u5 T* j/ U - {( C1 \; _' `9 s- q: d
- v38 = 0;
; m1 f( E' j8 A }9 Q5 F$ M - if ( v37 > 0 )
! N% X% \2 o7 R, f6 @, X7 s - {* V2 L* U0 D, e' I
- v39 = (unsigned __int8 *)v36;* n! r1 B7 q$ w9 U; J3 y: C0 |& u
- do5 l2 P ^: G l8 Z; h$ T, W
- {
/ @* r9 F0 |& C( u5 Q4 F4 Y - *(_DWORD *)&v34[4 * v38] = (*v39 << 24) | 0xFFFFFF;' _ e1 i' k8 _( |
- v37 = v52;
; w0 \; U# G1 \% d - ++v38;) ~3 w+ |6 @- D* `
- v39 += 3;" V% [1 _& ~+ o% L) @% L
- }: {# `; v: f3 F, M K. d8 p4 M! S j4 S
- while ( v38 < v52 );
2 L! ^/ A4 |: \; w* ]1 j - v35 = v53;
1 W9 R }# u$ i$ A( |8 m0 e - }+ f: r5 @' Q& I9 j. Q0 H
- v36 -= v54;
0 N. O; t# t0 i; q( E- Q - v33 = __OFSUB__(v40 + 1, v35);
5 N" W1 ~* K5 ^# _) s0 b* z( B" O, S, _ - v32 = v40 + 1 - v35 < 0;
4 C& [6 z* g' {6 a8 L - v34 += 4 * v37;3 j) @% A/ o9 ^8 M9 S8 d& O( r# R
- ++v40;
g7 E( B, R9 X# n7 u' r W - }( B7 I6 E1 f; `
- while ( v32 ^ v33 );
: v+ E7 ]. r3 z4 h8 O; U% C7 [ - }, y9 G# W, P6 V4 V% j" r& [
- }
$ _3 g2 N' [$ k - CKBitmapData::ReleaseSurfacePtr((CKBitmapData *)(*((_DWORD *)v11 + 6) + 56), -1);3 i8 O2 C: g. p5 ~
- SelectObject(v18, v46);
" y: u, k# _$ b$ u - VxDeleteFont(v48);
: v0 q( w3 f1 {- ~: _5 U5 @* h - SelectObject(v18, v47); `3 H& q$ X. h
- VxDeleteBitmap(v45);3 i: i4 e8 } E1 ~: m. w/ z
- DeleteDC(v18);1 n+ B' F( d& g+ V& W
- CKObject::SetName(*((CKObject **)v11 + 6), (char *)a3, 0);3 r4 n0 |; [6 ]
- CKBitmapData::SetDesiredVideoFormat(*((_DWORD *)v11 + 6) + 56, 1);
! s6 t) U7 S J: s W - (*(void (__stdcall **)(_DWORD))(**((_DWORD **)v11 + 6) + 120))(0);+ }# q: e" q; K
- return v40 + *((_DWORD *)v11 + 3) < yBottom;
: G* B) @1 k- ^. e8 O W, t1 Z( h - }
7 \' m) O( V1 A9 \, L. t& e
复制代码 ! m. f5 {8 K- V9 G' l2 l3 z) _
) O* W p( _7 U3 G# J$ N |