本帖最后由 shane007 于 2023-8-26 17:10 编辑
' y% l" S7 O, A7 E) S$ D; l$ b: X2 D6 d8 r
这个游戏的主要修改点在\player\BuildingBlocks目录下的Adventure.dll中。
2 t$ w5 c: i( C$ F用API monitor对本DLL的CreateFontA函数进行跟踪,发现确实有调用, 参数如下。
& k5 }/ D: `1 } ~/ q5 j: W A3 Y' ~ ~, X/ D5 {0 k
- # Type Name Pre-Call Value Post-Call Value
3 S$ ]) [+ @* f* E! x( r6 t$ a - 1 int nHeight 0xfffffff0 0xfffffff0$ l5 O9 r+ l8 Y) k, n2 E
- 2 int nWidth 0x00000000 0x00000000
0 w8 X3 {0 F' F K, w5 I* k - 3 int nEscapement 0x00000000 0x00000000
2 _' y+ q+ y* I - 4 int nOrientation 0x00000000 0x00000000
) H k3 z# v( v - 5 int fnWeight FW_NORMAL FW_NORMAL+ A7 |. s0 f( k# q( I! B
- 6 DWORD fdwItalic 0x00000000 0x00000000
" ]6 r$ A+ Q1 R+ B - 7 DWORD fdwUnderline 0x00000000 0x000000001 c* W: f: }0 l* R% N4 S2 j, u
- 8 DWORD fdwStrikeOut 0x00000000 0x000000004 i# j* W, a( L+ H# J
- 9 DWORD fdwCharSet DEFAULT_CHARSET DEFAULT_CHARSET
% W) ]& Z0 l2 _5 _8 n( ^ - 10 DWORD fdwOutputPrecision OUT_TT_ONLY_PRECIS OUT_TT_ONLY_PRECIS; {7 K" b# {3 \4 [/ B+ k6 o
- 11 DWORD fdwClipPrecision CLIP_DEFAULT_PRECIS CLIP_DEFAULT_PRECIS6 e6 `, y* B8 U" ~: B$ B* w
- 12 DWORD fdwQuality PROOF_QUALITY PROOF_QUALITY. y2 d- O8 [! z2 f- X6 J! F. ]
- 13 DWORD fdwPitchAndFamily FF_DONTCARE | DEFAULT_PITCH FF_DONTCARE | DEFAULT_PITCH
* i$ o, [' j! n- G: N6 T - 14 LPCTSTR lpszFace 0x09148a58 "Arial" 0x09148a58 "Arial"! _' T- g! m. _7 O$ I# A
复制代码 - g2 o# ?( M, s$ N. v8 m) I
0 n3 g L7 Q0 Q% B$ q
用ida pro找到调用CreateFontA的源头函数如下。5 w! B# ?- \4 D8 D$ G9 F( H
从函数的参数可以看出,这应该就是字幕显示函数了。9 `# f+ j" x/ K+ G: e, Q
关于后续修改,先修改CreateFontA函数的fdwCharSet,lpszFace这2个参数,也许就能出中文。
8 N6 ~8 [! n! r" d5 p还不行的话,就自己写一个显示函数。以下函数中lpMultiByteStr就是指向字幕的指针。
6 n" r6 D; ^8 o/ J8 B- ' H% G5 x( `/ b" b- k( E! 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). [+ s! v5 T' g* v& @
- {
4 C1 x H2 @ R3 s; |+ F - void *v11; // edi
. ~2 ^: r4 l- Z0 Z3 e - int v12; // eax
: b; Z; U% [6 x* C* W - int v14; // ecx1 h6 K8 ]* r* z D. C( V
- int v15; // eax
: ]& [1 O8 l# ], r5 Q: b- W8 \: o - char *v16; // eax/ a7 _, u; ^) Q
- int v17; // eax
$ \2 y" }4 o0 g7 c% R - HDC v18; // ebp
- W4 c1 x9 g0 z# u Z - int v19; // eax) m* I/ G* a% W+ W9 w4 J
- int v20; // eax
% V1 i& _. N0 O2 l - int v21; // esi
! _3 R% X# a3 V3 ` - char *v22; // eax1 k4 O3 W( R/ x2 R% x
- int v23; // esi# V. W5 M- t' L
- int v24; // ecx; r7 O7 Z6 X: L# s7 N7 K
- HBRUSH v25; // eax
B$ X9 K4 Z7 Z2 g9 ` - signed int v26; // ebx- V9 w0 @' o+ p: J9 c6 J3 D+ u8 U' \# @
- WCHAR *v27; // eax
6 l" x- p5 A! \ - int v28; // esi2 _7 |7 R3 w% A0 D+ k5 ?
- int v29; // ecx7 \- ]9 T' \# x: g6 p: n" q% v
- int v30; // eax
; ?. r+ [2 q J1 R3 o - int v31; // ST28_4
. a4 N; q7 T! q# A, ~3 z5 v - bool v32; // sf
4 E7 m6 R2 k, l! \ - unsigned __int8 v33; // of
, [1 U. }# b( {: B G( }0 p - unsigned __int8 *v34; // ebx
% A( [8 w8 a/ {7 N# G, D5 e) C0 Y8 m - int v35; // ecx
' B" u7 \% X5 q3 O0 j2 n7 W8 p - int v36; // esi! \8 q* d; J" S! k
- int v37; // edx& W9 }' L! r' v" ?* x, g% p
- int v38; // eax
% a4 b0 H2 N8 d' [ p/ u' t - unsigned __int8 *v39; // ecx
6 |6 C+ y6 g: Q, J3 y/ N - int v40; // [esp+40h] [ebp-2098h]
' u' Q( M- M" Y$ N: |2 u - signed int v41; // [esp+44h] [ebp-2094h]: q/ K) {# U7 |
- WCHAR *v42; // [esp+48h] [ebp-2090h]+ |% b2 A+ M+ ^' J* i
- LPCSTR v43; // [esp+4Ch] [ebp-208Ch]& `7 d x" D4 i, c. \
- int v44; // [esp+50h] [ebp-2088h]
( Z U3 {9 G/ i! x5 i6 I8 C - HGDIOBJ v45; // [esp+54h] [ebp-2084h]/ l+ z$ ] A& T, g" u8 G6 D# a
- HGDIOBJ v46; // [esp+58h] [ebp-2080h]
7 D; _* G& M$ g6 y. n - HGDIOBJ v47; // [esp+60h] [ebp-2078h]% t6 W+ [0 f, ?' Y
- HFONT v48; // [esp+64h] [ebp-2074h]! q) A) T1 G! N- p, f+ u: h
- float v49; // [esp+68h] [ebp-2070h]
8 @- l, m) _5 H; a) ~ - float v50; // [esp+6Ch] [ebp-206Ch]3 |8 J5 {$ K) H0 o
- char v51; // [esp+70h] [ebp-2068h]
, n* ]! Q* V0 i2 A3 ?, L! W$ S - int v52; // [esp+74h] [ebp-2064h]$ M9 l, O4 D! C y1 S& {
- int v53; // [esp+78h] [ebp-2060h]
: u9 {3 t6 o' a4 w1 \ - int v54; // [esp+7Ch] [ebp-205Ch]
0 _" |% {2 ]* y - int v55; // [esp+84h] [ebp-2054h]0 o* `1 ]$ f8 R7 r. ?. |
- struct tagSIZE v56; // [esp+88h] [ebp-2050h]
9 T0 P' {/ i7 S/ ^, B - struct tagRECT rc; // [esp+90h] [ebp-2048h]' Z* u$ F# `" t+ H7 i' ~0 |9 C2 y
- int v58; // [esp+A0h] [ebp-2038h]& H$ `1 _- S3 C& |- h
- char v59; // [esp+A4h] [ebp-2034h]. F! x! D% U0 `# v- t+ A
- WCHAR WideCharStr[4096]; // [esp+D4h] [ebp-2004h]
1 P: Y( U; B, w3 Y
/ ]* o- O. n' J& U W: w- v11 = this;, O) D4 j$ A* k& a+ J8 \) @
- v58 = 52;
2 n: L) R& U& t8 p - memset(&v59, 0, 0x30u);
0 @6 ^" J$ a& h8 N - if ( *lpMultiByteStr ). T3 Q. {, {! G, B$ Y' Y5 a1 O4 j
- {6 p+ r3 E7 @/ \3 i& S- L# C( j
- v12 = MultiByteToWideChar(0xFDE9u, 0, lpMultiByteStr, -1, WideCharStr, 4096);# }6 {' d$ h! @0 Y
- *((_DWORD *)v11 + 4) = v12;
& e3 S4 ~. b, J7 p3 d) ~ - if ( v12 <= 1 )
, @, R* r H, a( A( a1 G5 m - return 0; P/ p5 ~$ t! r) H5 Q, j% A) T
- *((_DWORD *)v11 + 4) = v12 - 1;
! w. q, {% ^- u5 E: I* P! \ - qsort(WideCharStr, v12 - 1, 2u, sub_10057A40);
. a4 F3 K. m" K) F - }( J1 D/ O% ?0 o4 r8 l
- else! n% G5 e! S; L/ V
- {
6 B+ d- q3 F' c+ T; X - *((_DWORD *)v11 + 4) = 352;; ~# H+ h! D4 U2 `
- v14 = *((_DWORD *)v11 + 4);3 {5 w- X! s. a# o: t* K
- v15 = 0;
# r+ _) k% b2 N$ `6 g" d" A- [4 C7 {9 c - do* x; N6 K1 v& x0 ^# E6 x
- {- ^. x2 X2 `( G
- WideCharStr[v15] = v15 + 32;7 T0 ~$ |& v! z: ~' T
- ++v15;9 p! z& o+ P& \1 `9 Q; |% Z
- }$ f. |4 a/ H% D& q2 m
- while ( v15 < v14 );2 C+ e( ?7 `& I P; d" {/ J
- }
1 K" `- e" t4 J4 ? - v16 = *(char **)v11;. O) `% F% o3 {; N+ f
- if ( !*(_DWORD *)v11 )
8 o0 z/ F$ B. j, [( G/ Q( p1 Y. o0 n0 t - v16 = byte_100B2D6E;
/ D0 R; R9 g2 C$ e - v17 = CKContext::CreateObject(a2, 31, v16, 0, 0);; V! m7 T" H) @. g7 K
- *((_DWORD *)v11 + 6) = v17;* n- @% v# @, T8 n+ `
- if ( !(*(int (__thiscall **)(int, int, int, signed int, _DWORD))(*(_DWORD *)v17 + 84))(v17, xRight, yBottom, 32, 0) )
9 J+ |6 G+ ^& d; |2 a# T, N5 | - return 0;
5 g$ T$ J2 u/ Q - (*(void (__stdcall **)(int *))(**((_DWORD **)v11 + 6) + 136))(&v58);
1 C9 I$ c; \$ L8 m( j# W - v18 = CreateCompatibleDC(0);
: o3 K' Q3 w. G% b - v45 = VxCreateBitmap((const struct VxImageDescEx *)&v58);
; K( r' Y3 {6 s' Y2 O, ] - v47 = SelectObject(v18, v45);
" F* h- o) p4 N! x - XString::operator=(v11, a3);
1 @/ y+ f6 M4 I4 D; C - *((_DWORD *)v11 + 2) = nNumber;! h1 y* B0 F$ h* t* R
- v19 = GetDeviceCaps(v18, 90);
: R# }: N# k$ z8 y s- X - v20 = MulDiv(nNumber, v19, 72);
6 A/ N! y8 C3 ]/ z# s7 G' q - v48 = CreateFontA(-v20, 0, 0, 0, a6, a8 & 1, ((unsigned int)a8 >> 1) & 1, 0, 1u, 7u, 0, a7, 0, (LPCSTR)a4);! \7 r" m+ T6 J# \5 `$ X
- v46 = SelectObject(v18, v48);! ~5 n/ a- u/ C6 P6 o% j
- GetTextExtentPointA(v18, "A", 1, &v56);( U# n) w2 J: v" C0 B
- v21 = *((_DWORD *)v11 + 4);1 \- r- g( l9 L+ O4 M7 L
- *((_DWORD *)v11 + 3) = v56.cy;, j# m* l, d& b0 @
- v22 = (char *)operator new(32 * v21);/ _3 O: h' y! A* z3 l# g7 g. U
- if ( v22 )
8 l U* E& n# x% Q$ C - {! D6 ?* \8 {6 X4 _* E. t
- v23 = v21 - 1;1 |/ C0 I4 W: G
- if ( v23 >= 0 )/ S" f' b1 `. u0 S8 G) q
- {
3 ^0 X; U' C/ s% H: ]+ V m' e, g - v24 = (int)(v22 + 12);
) _) d6 T0 }) r9 D( i, z - do- ]9 Q, ^; [# x1 p
- {3 |6 ~: x8 u5 ?3 f
- *(float *)(v24 - 4) = 0.0;
: H2 T, B: [ }$ y$ l - v24 += 32;7 q9 l! R5 e: N* l
- --v23;
+ e" S# k; ?7 W: b - *(float *)(v24 - 32) = 0.0;
# K' e9 H1 t0 q) E( r: |. w - *(float *)(v24 - 44) = 0.0;+ w m) m: v1 U" i+ z' b
- *(float *)(v24 - 40) = 0.0;
+ [" K8 r, Y& ^, u - *(float *)(v24 - 36) = 0.0;
' T# `; }4 E7 I3 p - *(float *)(v24 - 32) = 0.0;, L2 B: X+ ]# N) F1 p
- }
4 P5 I$ F4 n& I1 l( ^6 z* V) r - while ( v23 >= 0 );! I7 x6 `% ~0 @( g9 V% w" }: f, k
- }: h w H4 d, ^6 m2 C7 ~- g0 y
- }$ b) v" ~1 S' w. U5 P5 f/ s! r
- else$ a; V# k: Y5 A! G
- {
& R; B6 h1 D2 Y1 W3 j3 F, X - v22 = 0;+ ^& }) r1 t2 Y7 T+ v7 X0 X
- }: |% \! D8 t/ v3 D
- *((_DWORD *)v11 + 5) = v22; a( X& L O) O& Q" U6 f1 ^
- SetRect(&rc, 0, 0, xRight, yBottom);
8 P- U' s# b8 |8 S( j! a% R - v25 = (HBRUSH)GetStockObject(4);7 ?7 D1 Q- |( U% U S
- FillRect(v18, &rc, v25);
0 |1 o0 G# n3 ]9 [; `3 ?4 a: Y; y - SetBkColor(v18, 0);
" `6 O5 q, x6 E3 y, t3 R - SetTextColor(v18, 0xFFFFFFu);+ E1 F7 d. v# H* L* [
- SetBkMode(v18, 1);
u9 g$ C" t( o6 }* V+ j& A - v26 = 1;
4 Y7 Y' n, t1 Z - v41 = 1;
6 b* A* T: l. ^ - v40 = 0;
1 \6 \8 p% B' m2 K: t - v43 = 0;
' ~2 y, q* g) R; k. \- r; Q - if ( *((_DWORD *)v11 + 4) > 0 )
* C, O+ |& y& A: f1 K5 u, c* s - {
/ I7 ^" S2 h& I; n- p - v27 = WideCharStr;
3 Q2 u! M, y2 R5 L+ G1 J - v44 = 0;: l; J* d/ W% Z" k0 Z/ H# E
- v42 = WideCharStr;
$ L H( q% q4 D: ~ - v49 = (double)xRight;$ s$ ?) U4 g% [8 G. f, f, `
- v50 = (double)yBottom;7 O& {$ x; L* d3 m$ e4 i# C; I3 F
- while ( 1 )( E( J% o- H" b, d
- {& [& B8 j* \3 e( |
- v28 = v44 + *((_DWORD *)v11 + 5);
. H V; H- [+ P) W- m! s - *(_WORD *)(v28 + 16) = *v27;
+ o. p* O' Y! K! i( S - GetCharABCWidthsW(v18, *v27, *v27, (LPABC)(v28 + 20));( _ U1 J' r3 R# W
- if ( *v42 >= 0x20u )
, L; Q* Q! U9 R# Y2 Q. W8 @( _. V1 y - { C' a# n! ^; i
- --*(_DWORD *)(v28 + 20);* W' B+ F. [* U4 v; ~$ p
- *(_DWORD *)(v28 + 24) += 2;; o' ]) C4 p* v. c( d5 ^3 J# s0 E5 q
- --*(_DWORD *)(v28 + 28);2 c& Q+ D0 i& ?' G5 A
- }
4 D* A _( l2 T+ L2 f - else7 ]$ y+ F, e$ T8 s
- {5 F ~5 l* @3 {3 {) `: {
- *(_DWORD *)(v28 + 20) = 0;7 C' [# h: B" d
- *(_DWORD *)(v28 + 28) = 0;
& P- c7 W; U; q - }
( c7 v/ ]! i2 D4 ?; M9 J2 W - v29 = *(_DWORD *)(v28 + 24);
: d E! C# c7 U# Y - v30 = v40;( j) y. i* h7 Z/ i _) H
- if ( v29 + v26 + 1 >= (unsigned int)xRight )- \1 i5 l/ S5 L9 k5 T5 j% L
- {
$ H& u* k& d8 M - v26 = 1;
( W* W6 `3 s2 e) U2 |5 B - v30 = v40 + *((_DWORD *)v11 + 3) + 1;" N: L0 k1 t; s% t, }3 g
- v41 = 1;
4 U j$ ]) Q K0 m1 n - v40 += *((_DWORD *)v11 + 3) + 1;/ H$ A8 D* G( g
- }/ [$ n) H1 ]+ Z2 C: l
- *(float *)v28 = (double)v41 / v49; Q6 d4 {5 f+ t* u; _; i/ z
- *(float *)(v28 + 4) = (double)v40 / v50;, b, r z% M& r3 v* c+ X1 X
- *(float *)(v28 + 8) = (double)(unsigned int)(v26 + v29) / v49;
5 G' d9 ^, _1 u, L+ q4 x4 o8 k - v31 = v26 - *(_DWORD *)(v28 + 20);
; b/ F8 x9 k; @% g% l% O5 g - *(float *)(v28 + 12) = (double)(v30 + *((_DWORD *)v11 + 3)) / v50;
y& x) v! |5 Y- x+ E - TextOutW(v18, v31, v30, v42, 1);3 c9 ^& Z) \1 u, O: q* k
- v44 += 32;# Q8 R6 E0 J' B6 c/ _0 T
- ++v42;
: T7 v( u- n' r - v33 = __OFSUB__(v43 + 1, *((_DWORD *)v11 + 4));" y" ^- X# q8 ~( ]0 ]$ R0 Z
- v32 = (signed int)&v43[-*((_DWORD *)v11 + 4) + 1] < 0;
! [# }; E) t6 Q, `" K - v26 += *(_DWORD *)(v28 + 24) + 1;0 [/ m" P( o6 l$ @2 d0 \# x& p
- v41 = v26;
: P8 }7 i5 @( x' g# ?1 x, e- ^4 s4 \ - ++v43;% E/ c! D' u7 Y# g; R$ T8 O
- if ( !(v32 ^ v33) )
9 \$ L3 {; l9 Y$ Y% P8 s4 J - break;
" M/ h/ c; B3 R5 s - v27 = v42;& i8 }/ e4 ]1 [; y; F9 @
- }
! u" R( g& x% l# v - }
1 C! ^* {" @6 Q) s0 t, p V) K - v34 = CKBitmapData::LockSurfacePtr((CKBitmapData *)(*((_DWORD *)v11 + 6) + 56), -1);% q* V# ]2 L! y5 b
- if ( v34 )
( f/ ^4 A3 j" q* T r - {
( L5 t0 C- o* J. [% G - GetObjectA(v45, 24, &v51);
- I& y4 d- G" N& ]1 A2 U - v35 = v53;# K" x4 i- G9 c# T
- v36 = v55 + v54 * (v53 - 1);7 x# l$ h' b% P3 ]+ w
- v40 = 0;
4 v" K6 l1 ~7 I9 {: @+ D' f - if ( v53 > 0 ); B7 i [( M0 J1 T( m/ ^5 B5 c
- {" O L% i& a; q' K( e1 J+ F* g
- v37 = v52;
( ^* Y: ~- p1 @6 m/ [- l# f - do1 ^" M6 j$ l' g( Q/ x
- {2 {8 i# m$ i8 y H# i: o
- v38 = 0;
4 H+ ^& l! \. o* S4 l0 V9 V0 r - if ( v37 > 0 )2 M3 U0 f% p! P' D
- {
: ^$ ` C0 E# }- Z. A2 N: ?& Y - v39 = (unsigned __int8 *)v36;6 h" i1 |. F3 e6 f1 \$ @% Z
- do+ f) W2 R1 |) r9 ^
- {
+ w$ ?2 ~* `1 r8 x- i7 S - *(_DWORD *)&v34[4 * v38] = (*v39 << 24) | 0xFFFFFF;% @" p# @2 \: a0 ~# e
- v37 = v52;
$ q# I+ V W* g! }/ M9 u# s% t - ++v38;
- o2 |. y. T+ Y) d - v39 += 3;
% x( g3 i; W. m/ X - }
# l8 h& _, ^3 A - while ( v38 < v52 );
& c7 j) j( S7 r+ h m/ }+ @/ q3 B - v35 = v53;
$ B' D$ o+ H: M( Z2 V/ d - }, U* h5 B9 M9 M
- v36 -= v54;) M. F8 W9 Q$ m' R9 ~. \% {) K' I$ A
- v33 = __OFSUB__(v40 + 1, v35);
0 _9 Z$ \0 P* i @ - v32 = v40 + 1 - v35 < 0;
' k. g- d5 |, r1 R: e( S" Y. D - v34 += 4 * v37;9 ^8 q7 \/ ~+ ^/ a6 ^1 i1 j+ S& [
- ++v40;
2 d+ Z3 J6 r- |( v7 X - }
! [1 O+ a2 [# f* X4 S! p - while ( v32 ^ v33 );
) K+ o8 Z, O3 t - }
( S# Z" m; Q( `3 q - }
( w' B+ M2 q# d+ X8 e8 a - CKBitmapData::ReleaseSurfacePtr((CKBitmapData *)(*((_DWORD *)v11 + 6) + 56), -1);0 R- M2 y9 X9 Y# a" w8 m+ s& E4 G. t
- SelectObject(v18, v46);% A' ~- f: i6 Z
- VxDeleteFont(v48);
) m' A, G3 K" @( f2 B5 E - SelectObject(v18, v47);# I6 n3 e2 i) t0 F, P/ B" C: ^$ T: m
- VxDeleteBitmap(v45);
/ @: Q# v2 M" S* g - DeleteDC(v18);7 s& g, l2 e7 w9 E# l: ]. Q! q
- CKObject::SetName(*((CKObject **)v11 + 6), (char *)a3, 0);
: ?0 u3 [ t+ G5 T" z - CKBitmapData::SetDesiredVideoFormat(*((_DWORD *)v11 + 6) + 56, 1);
, b! p1 g: {5 f- ^- F& m1 ] - (*(void (__stdcall **)(_DWORD))(**((_DWORD **)v11 + 6) + 120))(0);+ k w7 q V$ V6 \
- return v40 + *((_DWORD *)v11 + 3) < yBottom;
# Y# Y6 Q: V. X! Y - }
S x7 R7 @ H( N" ^7 C
复制代码 * q; @5 c4 ?* h+ Z* L! S# U5 E
$ y& e; N6 H- A/ _) r+ F
|