本帖最后由 shane007 于 2023-8-26 17:10 编辑 ! h1 y- g' \9 w( i! Y8 y" y- z
; U( f$ g# i# {$ J
这个游戏的主要修改点在\player\BuildingBlocks目录下的Adventure.dll中。" M2 |9 W; j( `6 E, d0 d( f& q7 A/ N
用API monitor对本DLL的CreateFontA函数进行跟踪,发现确实有调用, 参数如下。" `0 [* Z4 D# Y
* {6 Y4 ~ Q+ s2 |. N- # Type Name Pre-Call Value Post-Call Value
0 E2 q& i: C4 b: J - 1 int nHeight 0xfffffff0 0xfffffff0
+ F3 t; p) }5 `' ^ - 2 int nWidth 0x00000000 0x00000000
* T1 `" N' {& L" P9 x( Q7 a! e - 3 int nEscapement 0x00000000 0x00000000) w/ t( _: w& M- ?2 o
- 4 int nOrientation 0x00000000 0x000000000 Q& c2 l6 i. z5 D$ D
- 5 int fnWeight FW_NORMAL FW_NORMAL! u$ h1 ]1 x4 F
- 6 DWORD fdwItalic 0x00000000 0x00000000
) i7 e7 l1 [* g5 O4 [# q6 B! \ - 7 DWORD fdwUnderline 0x00000000 0x000000008 n8 P9 \& ^4 J$ O
- 8 DWORD fdwStrikeOut 0x00000000 0x00000000- Z/ K7 Y: h4 Y1 |' \" N% d
- 9 DWORD fdwCharSet DEFAULT_CHARSET DEFAULT_CHARSET
8 E/ @/ r! ? N: c+ j - 10 DWORD fdwOutputPrecision OUT_TT_ONLY_PRECIS OUT_TT_ONLY_PRECIS# M# A$ n4 s7 o w
- 11 DWORD fdwClipPrecision CLIP_DEFAULT_PRECIS CLIP_DEFAULT_PRECIS: ^/ C6 V/ G& x& @6 c
- 12 DWORD fdwQuality PROOF_QUALITY PROOF_QUALITY* E/ @/ S8 F9 @- ]: B# a0 K
- 13 DWORD fdwPitchAndFamily FF_DONTCARE | DEFAULT_PITCH FF_DONTCARE | DEFAULT_PITCH; u; s9 B# w1 J; m0 [' b! L$ ^7 p
- 14 LPCTSTR lpszFace 0x09148a58 "Arial" 0x09148a58 "Arial"
0 _4 l2 k" ?& T" L
复制代码
& c: O" N- F6 k* Z5 p
8 N3 l2 ?7 S' k0 z) M: f& m用ida pro找到调用CreateFontA的源头函数如下。. z/ w3 K$ ~8 X0 X6 T% ^/ E
从函数的参数可以看出,这应该就是字幕显示函数了。
0 L$ `! F. N3 ? w关于后续修改,先修改CreateFontA函数的fdwCharSet,lpszFace这2个参数,也许就能出中文。$ X# k5 D$ f6 e( Q! q. I) ~
还不行的话,就自己写一个显示函数。以下函数中lpMultiByteStr就是指向字幕的指针。3 O2 {4 P6 t" y2 j
: A) s2 t0 k7 U! r. V# I- 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)
1 {4 K* u. q* O6 V; t7 N* w - {
8 O' S2 c! w ] - void *v11; // edi
3 z r' z5 l" _% P( j% ~2 \ - int v12; // eax7 W$ z+ J- U; i4 |6 z. d& Q
- int v14; // ecx3 A' N$ O7 y. Z$ p+ Q/ V; E9 v
- int v15; // eax& d. N/ P" V) D
- char *v16; // eax
7 F1 [ o) f& c+ b/ s - int v17; // eax
* P" a0 }3 r$ E - HDC v18; // ebp
2 ~ h8 _1 C1 M. w - int v19; // eax
( Z1 i. z1 @5 P9 M( [ - int v20; // eax
4 W1 q+ H' u- X# J. @! Z3 N9 h- } - int v21; // esi
, O) M1 h& A; T ?4 A7 y - char *v22; // eax
/ _) v; Z4 ~6 D7 A1 J - int v23; // esi
* S7 |% {# `6 E3 F* I+ X) N, t - int v24; // ecx0 @2 {+ C# F G/ q" Y6 a; h& n! F9 H
- HBRUSH v25; // eax
1 h: t6 i! Q, z/ @, E - signed int v26; // ebx
8 V$ W) S( N5 K2 i) H/ y, s& m$ ? - WCHAR *v27; // eax- s; V6 c+ i* A7 G) S7 v
- int v28; // esi2 N, A4 L' q; U: a0 Y, i% G( X S
- int v29; // ecx
# j b# M/ a' [, R - int v30; // eax
1 `0 C2 H: ]4 w9 C4 \! `1 r, l1 \ - int v31; // ST28_4
/ x4 J9 V: z1 h8 B3 H: T1 @ - bool v32; // sf q" u: _8 Q# t3 k: ^5 w: ?6 b
- unsigned __int8 v33; // of
) _3 T& S& Y" C; O3 m - unsigned __int8 *v34; // ebx
/ D7 M/ \3 M( k: |& A" w - int v35; // ecx/ P9 A( K# q. N/ @
- int v36; // esi
# {0 D* G$ W$ e9 [" l/ X - int v37; // edx
! i# e" _- C0 i- s! D: V: @8 j. J - int v38; // eax- O3 Q) z. Z* m9 f8 i
- unsigned __int8 *v39; // ecx
; q, W* C( G! F1 c3 K - int v40; // [esp+40h] [ebp-2098h]8 H4 w$ \2 w+ e F8 r6 ?
- signed int v41; // [esp+44h] [ebp-2094h], |% U$ P8 `+ O8 Y9 P
- WCHAR *v42; // [esp+48h] [ebp-2090h]
4 L% e6 r7 B0 T1 K- L" Z9 K% N+ d - LPCSTR v43; // [esp+4Ch] [ebp-208Ch]
' S; p9 _" H* g E' w; M* [$ ` - int v44; // [esp+50h] [ebp-2088h]
+ _6 a3 C+ O' E ^$ t' ~& \5 e - HGDIOBJ v45; // [esp+54h] [ebp-2084h]! n; e6 L& `7 |& Y' ~" c4 i+ q: d& W
- HGDIOBJ v46; // [esp+58h] [ebp-2080h]
2 s9 u" X( J" f+ K7 M( ] - HGDIOBJ v47; // [esp+60h] [ebp-2078h]5 W1 o5 v* ]4 ?8 M- y
- HFONT v48; // [esp+64h] [ebp-2074h]6 K: [2 t- K9 k0 e& c9 \' Q
- float v49; // [esp+68h] [ebp-2070h]
6 `0 `, `$ {# O" V6 h - float v50; // [esp+6Ch] [ebp-206Ch]( U' L& R& E; {( E) M! z
- char v51; // [esp+70h] [ebp-2068h]1 X+ M6 m2 D, P) ?# U3 ]
- int v52; // [esp+74h] [ebp-2064h]. ~5 a4 F7 w: D5 }& f; C
- int v53; // [esp+78h] [ebp-2060h]
t3 {7 O3 @, k4 Y" U - int v54; // [esp+7Ch] [ebp-205Ch]4 [6 r: G/ l) ]3 ^
- int v55; // [esp+84h] [ebp-2054h]
$ W9 P; j# a4 j4 P) X1 M" ^5 ^ - struct tagSIZE v56; // [esp+88h] [ebp-2050h]6 w2 x& Z2 \3 C! x( a/ w6 D/ X
- struct tagRECT rc; // [esp+90h] [ebp-2048h]
$ U0 q" R+ p, k; o# B - int v58; // [esp+A0h] [ebp-2038h]
J6 H4 F$ Y2 M: _9 @- i" V - char v59; // [esp+A4h] [ebp-2034h]
1 b% Y2 r) l" ]. X4 W8 \" R9 i; H - WCHAR WideCharStr[4096]; // [esp+D4h] [ebp-2004h]
7 k; N' R: H% h+ g; @' Y
0 p9 h, F' C0 X; J4 a+ z- v11 = this;6 S* y$ m9 Q% x6 Z+ a1 a9 U
- v58 = 52;! U- O( y- F1 p" N; x5 o) W& ]
- memset(&v59, 0, 0x30u);
( X! p: F: t6 u/ y - if ( *lpMultiByteStr )3 w% i3 A) }: U/ e
- {; V: z4 x4 A5 n/ _
- v12 = MultiByteToWideChar(0xFDE9u, 0, lpMultiByteStr, -1, WideCharStr, 4096);
+ o6 ?4 Y! e# ?) K - *((_DWORD *)v11 + 4) = v12;/ o5 l+ t4 y* [9 A
- if ( v12 <= 1 )2 J' h0 r0 [+ |& n& a
- return 0;7 h) @ i: [ f. q# ?
- *((_DWORD *)v11 + 4) = v12 - 1;
6 H& R( U# j! p+ z* D% d6 Q$ C - qsort(WideCharStr, v12 - 1, 2u, sub_10057A40);
, m( A! E2 A5 j& B9 @2 l - }
- W" H% d D( A7 T+ c - else
/ p: B! v3 E, Q& F/ z - {5 L6 e% `( _! g
- *((_DWORD *)v11 + 4) = 352;
, M j* G$ l k - v14 = *((_DWORD *)v11 + 4);. |: ] C' A2 Y* S
- v15 = 0;
2 c& \( j* j8 V1 c4 u" `: C" k - do ~5 ]1 I; F6 [
- {
) A& |/ e' ]; a/ [7 p! H" @" V$ [: P7 o - WideCharStr[v15] = v15 + 32;- V2 S! N) W; H% C8 _
- ++v15;! J4 j( X8 d5 a' O
- }2 w6 y, R3 F) b) `
- while ( v15 < v14 );5 e$ n h" t# F& {" O# F
- }
7 A6 d( ~4 e% o5 F - v16 = *(char **)v11;
' S P0 j6 e; Y3 Q3 _6 E5 b - if ( !*(_DWORD *)v11 ); s" q9 ~, g$ n' V; U, [) [ w
- v16 = byte_100B2D6E;
4 D" g+ a% W" a; r% r - v17 = CKContext::CreateObject(a2, 31, v16, 0, 0);
: m$ k9 s6 W$ @ - *((_DWORD *)v11 + 6) = v17;
- r$ i& x9 r2 O. A9 o- q - if ( !(*(int (__thiscall **)(int, int, int, signed int, _DWORD))(*(_DWORD *)v17 + 84))(v17, xRight, yBottom, 32, 0) )) T& L; z% L. c
- return 0;
' y7 i- G) N+ ]0 u. F - (*(void (__stdcall **)(int *))(**((_DWORD **)v11 + 6) + 136))(&v58);2 R' X# |, k- x# `
- v18 = CreateCompatibleDC(0);4 m& w p* G* g; w, H/ g
- v45 = VxCreateBitmap((const struct VxImageDescEx *)&v58);
; ?- L# A9 @5 |) i - v47 = SelectObject(v18, v45);
- A2 o# P, Q h( ^% M; I! ` - XString::operator=(v11, a3);, Z2 Z8 z/ z; v4 J n
- *((_DWORD *)v11 + 2) = nNumber;
1 D# e9 Z- u) ^ - v19 = GetDeviceCaps(v18, 90);
$ C5 ~; s: k3 c2 o3 C% ` - v20 = MulDiv(nNumber, v19, 72);
( ~0 i+ l: i, b0 ~7 b' p - v48 = CreateFontA(-v20, 0, 0, 0, a6, a8 & 1, ((unsigned int)a8 >> 1) & 1, 0, 1u, 7u, 0, a7, 0, (LPCSTR)a4);4 z: E, O/ K/ F5 u
- v46 = SelectObject(v18, v48);
3 ?! J2 l: X1 H. w! E - GetTextExtentPointA(v18, "A", 1, &v56);
. u) z, t8 K3 {1 N t$ s2 B - v21 = *((_DWORD *)v11 + 4);( M: G) U! p: }' q8 k# ]6 x4 Y
- *((_DWORD *)v11 + 3) = v56.cy;
' H6 `+ W" X5 C- f. W8 `3 G - v22 = (char *)operator new(32 * v21);
% l3 s1 \% K3 X% @8 Y - if ( v22 ) r L% d- y2 h& u5 _
- {
) m" r2 i0 i# M; _1 @2 x& p6 h - v23 = v21 - 1;
& e9 B- W2 q. y6 e$ M6 O0 A - if ( v23 >= 0 )' s0 x: ^% l+ S1 S8 R5 H
- {5 V( Y* h$ J8 `4 T# c q$ X, L
- v24 = (int)(v22 + 12);
a- q0 s U* u- z - do
/ B. [+ R A+ h+ ?3 D! q - {
' S7 g* e* s2 o; T l; Q8 u - *(float *)(v24 - 4) = 0.0;) @( v& e; f# w
- v24 += 32;
+ b% D: m. M) F r2 @' T7 O - --v23;% y5 X! L9 A' M8 G
- *(float *)(v24 - 32) = 0.0;% a% n, A5 b2 O
- *(float *)(v24 - 44) = 0.0;, e, e' U8 T8 H0 k7 I! i5 w7 x
- *(float *)(v24 - 40) = 0.0;
/ Q b5 w' S7 q! X' ]: c - *(float *)(v24 - 36) = 0.0;% f t' R. X+ J1 N1 x* S
- *(float *)(v24 - 32) = 0.0;4 I3 d2 q, X2 M- }
- }0 Z9 L$ x' `. T7 ^
- while ( v23 >= 0 );
0 n0 q& o; n! e, Y4 l T7 G- u - }; {6 D9 w% e0 \3 E3 k2 H
- }. J+ G# L# B$ q. Y/ u
- else5 U, g5 a+ e4 S- V
- {
& F7 k& W9 B8 ]! M& Y - v22 = 0;
( ]1 G H' t: O% i5 i3 I - }
1 g# |' f+ K7 a' j: N - *((_DWORD *)v11 + 5) = v22;
; O7 n: V* Y/ z* D9 a. h - SetRect(&rc, 0, 0, xRight, yBottom);
- T1 S8 _: i C+ E - v25 = (HBRUSH)GetStockObject(4);
( {( J/ N: q9 l3 K: G6 v! G" Z: } - FillRect(v18, &rc, v25);/ k' C% c2 L* @ @1 [( _5 T
- SetBkColor(v18, 0);7 N# d4 z* }+ v' O0 O, W* R2 r5 e& V
- SetTextColor(v18, 0xFFFFFFu);& l1 P; A0 J4 V) E/ [; O- [
- SetBkMode(v18, 1);
% y/ z* [, d- }6 H - v26 = 1;1 p2 S( F( P0 N+ J% g0 X
- v41 = 1;
/ E8 w" W' ^8 H/ p, S. d! t& W - v40 = 0;
. j8 i* R" p" }2 ^$ n - v43 = 0;
1 E" f8 @- N- _% B: p - if ( *((_DWORD *)v11 + 4) > 0 ), N. W P' K- a6 [! d8 ]7 y2 W, O" g
- {
: w7 y! R) a3 g& w7 s T - v27 = WideCharStr;8 C# O) j5 u8 X) e! N( L
- v44 = 0;; m* R5 v, W% Q, I0 g5 J+ w- b
- v42 = WideCharStr;
# w# i4 k6 C) M/ G1 ]7 C - v49 = (double)xRight; a- |% I; }, c. G0 U
- v50 = (double)yBottom;8 `! k. a& i8 d0 i
- while ( 1 )# _+ ?7 W6 O1 Q7 N2 }: l. w$ d
- {' [& [0 ]& Y& h. q8 P
- v28 = v44 + *((_DWORD *)v11 + 5);9 Z- R8 o" X3 b4 v: T3 h) @
- *(_WORD *)(v28 + 16) = *v27;
! P: l" r# s! m: a( ^ - GetCharABCWidthsW(v18, *v27, *v27, (LPABC)(v28 + 20));
p# F9 @% \! U# q1 @) t! U - if ( *v42 >= 0x20u )# U ?& w0 O% S6 k4 G- q
- {; r# r$ d4 p' v4 q# v
- --*(_DWORD *)(v28 + 20);
$ z2 b Y) V; m2 }/ } - *(_DWORD *)(v28 + 24) += 2;
' D0 W/ T, ?3 O9 S7 w ^4 f - --*(_DWORD *)(v28 + 28);
5 ]. y% E# n) ^. `9 o3 h - } L, m( s, ~( k* p+ E( P$ M
- else. @0 R* H; X: @$ t& S
- {. h/ \. w! |8 |: i4 t5 A6 f
- *(_DWORD *)(v28 + 20) = 0;4 [3 b% R4 s# s" Q2 Y
- *(_DWORD *)(v28 + 28) = 0;
7 a: J1 ]. ]. V! {. o+ U - }
C# }5 t+ y- b4 W' r' y1 Q$ l; ^ - v29 = *(_DWORD *)(v28 + 24);4 D. W. e: x9 m7 v2 Q7 H3 l. M
- v30 = v40;
+ e8 Z8 T& o! b4 { - if ( v29 + v26 + 1 >= (unsigned int)xRight )
' X/ `9 U1 Y- W( c - {; P1 L7 ^) O8 C' x8 w9 W
- v26 = 1;7 n N+ Y. H, g* k* d- ?" G
- v30 = v40 + *((_DWORD *)v11 + 3) + 1;. [8 H7 T3 {8 x
- v41 = 1;8 v* t; L/ B/ }9 J# c& Z" O. W2 m
- v40 += *((_DWORD *)v11 + 3) + 1;% }8 J% x9 v4 h6 v4 p& l- p
- }
5 E0 w* l# c8 D8 ~2 q - *(float *)v28 = (double)v41 / v49;
) O+ ~# s4 M9 t - *(float *)(v28 + 4) = (double)v40 / v50;
# V1 I/ L! ~5 r - *(float *)(v28 + 8) = (double)(unsigned int)(v26 + v29) / v49;
* x3 @# V- H! q4 i( M9 p/ S - v31 = v26 - *(_DWORD *)(v28 + 20);
, m# R7 H/ i; | D2 q6 i - *(float *)(v28 + 12) = (double)(v30 + *((_DWORD *)v11 + 3)) / v50;+ H2 X1 a; y- {, w* ~
- TextOutW(v18, v31, v30, v42, 1);
' m$ O t- H4 Q# {. v- [9 Q+ l* q - v44 += 32;( T1 B0 H" |2 X; e0 V4 \
- ++v42;
/ \; L8 [$ k T$ n: C - v33 = __OFSUB__(v43 + 1, *((_DWORD *)v11 + 4));( @* a; q) X7 y) }2 O1 [& w
- v32 = (signed int)&v43[-*((_DWORD *)v11 + 4) + 1] < 0;& g+ |# s* ?* e, B; _: h
- v26 += *(_DWORD *)(v28 + 24) + 1;* k8 X1 S: e- A/ h+ W+ r1 ^
- v41 = v26;
1 J3 i# s9 G: o; N - ++v43;' y# U$ \ n; e. w
- if ( !(v32 ^ v33) )
$ s# _+ q3 {5 D% Q: e; u2 ?1 D! S - break;. r+ x$ D L2 N& A( _: `3 ?
- v27 = v42;' v" I# A4 a, ]' a2 `0 V. Q; z
- }
. r$ }3 g2 ~4 ?7 r* n - }
5 l& z$ V! f+ v. J, b6 \ - v34 = CKBitmapData::LockSurfacePtr((CKBitmapData *)(*((_DWORD *)v11 + 6) + 56), -1);6 @4 k# E1 L. E0 j( C
- if ( v34 )
7 [, A$ V | P0 K' x; R5 } - {
+ n2 r2 F* {/ Y* K2 \ - GetObjectA(v45, 24, &v51);) q0 M( f/ D% m# m) K0 O2 b7 h0 Q
- v35 = v53;
' d9 s6 A9 }8 A3 F( D - v36 = v55 + v54 * (v53 - 1);3 K2 l j, B' ]" I) I9 E+ [
- v40 = 0;9 `" Z4 h+ G) W' H
- if ( v53 > 0 )
; h G: G+ N% X( J! ^9 W - {
8 u/ }$ Q; N L - v37 = v52;5 x v8 ~" F) }
- do2 g; q1 I- I0 Q6 M/ s
- {8 t4 J& r; }% |' S; V
- v38 = 0;
4 Z4 Z7 H) g* N/ ?, D5 c - if ( v37 > 0 )8 c; c! k) c: C: A6 ~% }; X
- {
, v, k P: Y( c+ D1 Q0 g* @ - v39 = (unsigned __int8 *)v36;0 J2 R& a5 N l& N9 e/ @6 Y8 {' G
- do
4 {( O: _6 |4 g, b9 q- F" N& T5 P - {
3 ~1 ]7 B- N( m2 @; G1 v - *(_DWORD *)&v34[4 * v38] = (*v39 << 24) | 0xFFFFFF;: L8 O" p3 S! H$ _% o% s! w% v9 Q) u
- v37 = v52;- ~' @: ^/ H, u& v. b
- ++v38;
# s% x2 a2 w+ B; Y/ G$ K4 P - v39 += 3;/ n; q' e! D! w* }$ M$ y
- }+ A* H( y$ v3 I1 R8 l+ O) Z
- while ( v38 < v52 );
: T7 P! O& A, M r# s; a - v35 = v53;' h/ f0 [6 P# `- A; T8 [& ]( z
- }
5 j7 x$ b6 c( E0 X' d4 b - v36 -= v54;# x, c! W* O7 ?+ b
- v33 = __OFSUB__(v40 + 1, v35);
8 @2 e/ k V' ~ - v32 = v40 + 1 - v35 < 0;
1 B) F: W3 _8 R2 S' S% L - v34 += 4 * v37;
& I8 b5 \9 x1 Z% M, y! C - ++v40;
G( x5 t/ i# r0 t C% c$ D# o - }
# w, l- g7 G7 n% ?) M" ]* A - while ( v32 ^ v33 );
: N& ~+ t- W0 p, ? - }
; R1 V* H' i9 v) A: T7 g - }4 k" x- f0 ~0 {, E
- CKBitmapData::ReleaseSurfacePtr((CKBitmapData *)(*((_DWORD *)v11 + 6) + 56), -1);2 {9 ]1 v# b2 b' ~4 j
- SelectObject(v18, v46);
+ h/ Z# F) m! n) j5 d - VxDeleteFont(v48);
* g* ~) E8 l' z+ I - SelectObject(v18, v47);
2 ?' r. z0 j7 {: K: S2 Q/ y1 S; A - VxDeleteBitmap(v45);
' z8 D" t9 C4 ^% h' G0 \ - DeleteDC(v18);
. Z! L9 {2 u5 J - CKObject::SetName(*((CKObject **)v11 + 6), (char *)a3, 0);% z; g3 ?4 D+ H+ v! J2 u! k9 ^/ L+ L
- CKBitmapData::SetDesiredVideoFormat(*((_DWORD *)v11 + 6) + 56, 1);
! A6 O& P4 l3 g - (*(void (__stdcall **)(_DWORD))(**((_DWORD **)v11 + 6) + 120))(0);
% ^# G" K* y, p1 _+ b9 x5 | - return v40 + *((_DWORD *)v11 + 3) < yBottom;. M& S+ N) N4 A* k
- }8 c1 Z' S9 I5 @* }4 \
复制代码 ( u$ w' K* J5 I" r; p
1 K( \! y% H$ t# c2 m1 k- w |