本帖最后由 shane007 于 2023-8-26 17:10 编辑
" ^) R; v: H5 g$ @9 {! ^) j( \) P- D; |! B$ g
这个游戏的主要修改点在\player\BuildingBlocks目录下的Adventure.dll中。5 ^# b0 j% B' A
用API monitor对本DLL的CreateFontA函数进行跟踪,发现确实有调用, 参数如下。9 L+ m) [5 X6 b; e/ L
1 X" V, \ _0 j; X
- # Type Name Pre-Call Value Post-Call Value) k8 M- r a8 D6 }; j" j
- 1 int nHeight 0xfffffff0 0xfffffff0
" ?. y: o: k I6 }) g9 i - 2 int nWidth 0x00000000 0x00000000% k3 b. \% Z; U/ S) p' [1 Y- A
- 3 int nEscapement 0x00000000 0x00000000
# T9 G3 c* \) A% L - 4 int nOrientation 0x00000000 0x00000000
: w1 r+ {, M" M- E2 K - 5 int fnWeight FW_NORMAL FW_NORMAL
9 V( A1 K) `. s - 6 DWORD fdwItalic 0x00000000 0x000000001 H) A1 b5 q O6 {
- 7 DWORD fdwUnderline 0x00000000 0x000000006 Z, u0 I" z, J- ~
- 8 DWORD fdwStrikeOut 0x00000000 0x00000000
' H3 H$ Y) p$ d4 v V - 9 DWORD fdwCharSet DEFAULT_CHARSET DEFAULT_CHARSET! q1 V3 E; }8 X5 [" t9 g/ t
- 10 DWORD fdwOutputPrecision OUT_TT_ONLY_PRECIS OUT_TT_ONLY_PRECIS
/ O- {1 ]) x$ u - 11 DWORD fdwClipPrecision CLIP_DEFAULT_PRECIS CLIP_DEFAULT_PRECIS/ P" J& N; a5 ?, W( X; a8 v. M3 w
- 12 DWORD fdwQuality PROOF_QUALITY PROOF_QUALITY" D3 A0 s5 o/ A0 U& G2 L8 V
- 13 DWORD fdwPitchAndFamily FF_DONTCARE | DEFAULT_PITCH FF_DONTCARE | DEFAULT_PITCH
( x3 v+ m5 W1 Z/ ?" H0 h2 t- Q% o - 14 LPCTSTR lpszFace 0x09148a58 "Arial" 0x09148a58 "Arial"9 ?( f$ s) ~) r# V; \4 v, ~$ ~8 Z% f w
复制代码 + \( s: Q: J, \# C# V9 E# @: _
7 J% [6 j/ G q8 b' D& F0 t用ida pro找到调用CreateFontA的源头函数如下。2 G( C5 v% o$ N- ^
从函数的参数可以看出,这应该就是字幕显示函数了。
! V0 K& q/ V1 b8 ~+ U B4 W' \关于后续修改,先修改CreateFontA函数的fdwCharSet,lpszFace这2个参数,也许就能出中文。& Q. h; E( M3 j
还不行的话,就自己写一个显示函数。以下函数中lpMultiByteStr就是指向字幕的指针。
: L' I! }9 `+ `& E b$ ], `/ z- 5 z! c& `( p9 d) M* R X/ e
- 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)
. a# N* q# z- a$ l, N - {
0 r% r5 ]. T, K7 \ - void *v11; // edi4 U+ j; L3 V3 p8 d* o! W
- int v12; // eax0 B/ L: Q X. H. t* ?
- int v14; // ecx
8 W; v, W/ A! u* t- o1 Q2 V) }% }- I - int v15; // eax
. h( a0 y; u3 J! h" F0 j( h6 I2 P - char *v16; // eax: n+ g, G7 G, E5 o( e
- int v17; // eax
9 i9 J) j6 g1 `& ]7 }! t/ U0 M - HDC v18; // ebp- o8 e& c' a& V* H" k7 g" E0 O
- int v19; // eax0 R. e& F9 F* v% C: }" {0 q5 v
- int v20; // eax4 `* I, v7 b0 j' j W9 _
- int v21; // esi4 a& f. G, Q1 L; k0 ^1 k
- char *v22; // eax
+ ~. T f1 s6 N+ u - int v23; // esi% j* H3 d. m+ W7 z" f" y
- int v24; // ecx! H0 F# F+ A2 ?$ U* r' K- \* t
- HBRUSH v25; // eax
/ E/ d7 y; _0 J - signed int v26; // ebx
& a$ I- I4 P, ?* J - WCHAR *v27; // eax- O. K6 j/ l% H3 Y4 I$ z
- int v28; // esi- J, V" r3 P) D2 o# p6 ]1 G- M
- int v29; // ecx Q3 h$ @) Q8 p7 R
- int v30; // eax8 q( E0 }7 h' g3 a
- int v31; // ST28_4& L9 k) q0 \3 C& H$ h
- bool v32; // sf7 z) ?+ D0 r4 E3 W; Y4 o( r$ {
- unsigned __int8 v33; // of& n0 M* {" h) } c" O' O
- unsigned __int8 *v34; // ebx2 O/ k0 ~+ K3 Q, g6 z! o" G$ K1 p$ z
- int v35; // ecx% U, d# G% d8 V- b
- int v36; // esi
! G- B( X6 R% Q5 u - int v37; // edx
' ?( {$ ]% F- w: |2 r9 T4 r - int v38; // eax
/ U* x5 ^# H& W7 ~ - unsigned __int8 *v39; // ecx
2 s6 l$ u, C/ i0 }8 B! u( I* I+ h - int v40; // [esp+40h] [ebp-2098h]
3 L- i" R! u9 W4 v8 h - signed int v41; // [esp+44h] [ebp-2094h]% P& p$ ^0 d; ~2 }
- WCHAR *v42; // [esp+48h] [ebp-2090h]
: _" d/ V/ O. ^ - LPCSTR v43; // [esp+4Ch] [ebp-208Ch]- Y# G% h; }1 w1 ?: Q7 ~# J
- int v44; // [esp+50h] [ebp-2088h]
& c3 U1 \" C* j0 M9 f) D' ?6 y8 Z8 q - HGDIOBJ v45; // [esp+54h] [ebp-2084h]
: m. k" u! }# {% v0 X$ B# n+ m& W - HGDIOBJ v46; // [esp+58h] [ebp-2080h]
0 d0 E9 O. C3 o - HGDIOBJ v47; // [esp+60h] [ebp-2078h]+ Q* P ]0 ~1 n7 s' D$ C
- HFONT v48; // [esp+64h] [ebp-2074h]
2 P0 J" _7 |; [5 A - float v49; // [esp+68h] [ebp-2070h]
Z# ~$ Y$ z, C8 w9 s. T - float v50; // [esp+6Ch] [ebp-206Ch]8 t* k! P I: t: ^
- char v51; // [esp+70h] [ebp-2068h]
3 k" R/ Q1 j2 M, L6 M6 S - int v52; // [esp+74h] [ebp-2064h]7 [2 A: [# X ?2 `! {. d# V
- int v53; // [esp+78h] [ebp-2060h]
( K) D, i' F7 G1 L - int v54; // [esp+7Ch] [ebp-205Ch]( e# ?5 y; z4 U9 e' q2 z
- int v55; // [esp+84h] [ebp-2054h]; f" o0 f: m5 `' a( Q2 N
- struct tagSIZE v56; // [esp+88h] [ebp-2050h]5 C$ p5 |+ y* U5 A. r
- struct tagRECT rc; // [esp+90h] [ebp-2048h]
. d7 `( T T. `; u* i$ _# L - int v58; // [esp+A0h] [ebp-2038h]0 {" Y7 l' V0 E/ O
- char v59; // [esp+A4h] [ebp-2034h]& H& r1 Y4 M+ l2 P2 a% ~
- WCHAR WideCharStr[4096]; // [esp+D4h] [ebp-2004h]
, \( N3 `" |6 h- T* @ - 1 F+ y5 Y8 ]+ [
- v11 = this;
4 c4 {" Z' r( [9 H `/ _ - v58 = 52;
( j4 L9 g, X: r o4 S, Y - memset(&v59, 0, 0x30u);
) a8 y. k7 F- r# g! Y8 m2 Q - if ( *lpMultiByteStr )& ?$ z; [+ e* s8 S1 V F
- {5 }1 E9 r9 ?+ X0 ~" B8 b4 d+ a
- v12 = MultiByteToWideChar(0xFDE9u, 0, lpMultiByteStr, -1, WideCharStr, 4096);
1 L' O4 u" g7 k. |0 M% ] - *((_DWORD *)v11 + 4) = v12;/ C J/ m) ?% i3 m# C
- if ( v12 <= 1 )
% G8 m# @9 t6 ]6 w3 h9 I - return 0;
/ y& A! J+ E& n! K* X7 |5 r - *((_DWORD *)v11 + 4) = v12 - 1;& Y3 t! j, y: Q0 N, W8 c
- qsort(WideCharStr, v12 - 1, 2u, sub_10057A40);
7 ~/ N9 B& y* M; @8 q# y - }0 o- ?4 y! s! ~) X6 T( M
- else# A' c9 W8 t" I! \1 q, L( Y
- {
7 B' e+ D1 f$ c. e0 E% k+ [0 R* m - *((_DWORD *)v11 + 4) = 352;
5 C8 f, q1 A2 F1 [3 A- A - v14 = *((_DWORD *)v11 + 4);% B, a; @# R4 q( \$ \% Y) e# Y' E
- v15 = 0;
: O4 ~- w# K3 B J - do3 Z/ a0 _. L5 P, v: @& R* t
- {: z! O) W# @ e
- WideCharStr[v15] = v15 + 32;, d% x6 K y# D& B7 g# P3 h
- ++v15;3 S/ _" F% n* k& [6 m" f
- }; c* d- g8 J$ q+ ?0 B7 P7 i
- while ( v15 < v14 );5 K/ D; U7 |5 F8 J/ c
- }
: e6 P2 l2 Z; l* V _$ ^2 z- r - v16 = *(char **)v11;2 j- A( R- [2 p6 H# B2 R$ l4 \" K
- if ( !*(_DWORD *)v11 )# N( E% l C C* C3 s0 V
- v16 = byte_100B2D6E;
/ B" p& Z1 _' h# g - v17 = CKContext::CreateObject(a2, 31, v16, 0, 0);
$ _% _, }: W) p3 W) Y+ g7 `4 t/ W - *((_DWORD *)v11 + 6) = v17;
- F" f' A- t, G/ |( |; V; V0 Z6 _) \$ E - if ( !(*(int (__thiscall **)(int, int, int, signed int, _DWORD))(*(_DWORD *)v17 + 84))(v17, xRight, yBottom, 32, 0) )0 I3 l' j7 n( ]7 l
- return 0;
; @' T8 r w( \' r6 _1 N$ g, o* U - (*(void (__stdcall **)(int *))(**((_DWORD **)v11 + 6) + 136))(&v58);
% k# a+ B% g* ~' B3 m - v18 = CreateCompatibleDC(0);/ c. S6 T3 r& K6 V4 T8 d
- v45 = VxCreateBitmap((const struct VxImageDescEx *)&v58);8 |) \8 w' r) l! r
- v47 = SelectObject(v18, v45);! l! w" j# x; @/ f( F" a/ J: \
- XString::operator=(v11, a3);
& T$ Z; H+ B# f$ k; W4 n - *((_DWORD *)v11 + 2) = nNumber;
, I9 n0 x7 D+ W) i4 j) y - v19 = GetDeviceCaps(v18, 90);
& |4 t# H3 N- q$ p6 A - v20 = MulDiv(nNumber, v19, 72);; c* K1 Q9 Y. c0 K8 r
- v48 = CreateFontA(-v20, 0, 0, 0, a6, a8 & 1, ((unsigned int)a8 >> 1) & 1, 0, 1u, 7u, 0, a7, 0, (LPCSTR)a4);
1 L! r: N6 g) U- Z% }; I - v46 = SelectObject(v18, v48);
$ S4 N- _- O4 `0 a9 e - GetTextExtentPointA(v18, "A", 1, &v56);
) S! L$ R6 t3 d% e, w1 R - v21 = *((_DWORD *)v11 + 4);
& I- u3 T3 c; w' R! J. I# d# T - *((_DWORD *)v11 + 3) = v56.cy;
6 d) f B, w# Y+ I - v22 = (char *)operator new(32 * v21);, u' [9 i; f+ E6 u
- if ( v22 )& ^ @* d9 G, D9 y5 T8 M
- {( L. C) a% k* J
- v23 = v21 - 1;' Y2 d5 Z9 t7 q+ T6 N, n
- if ( v23 >= 0 )
: U9 o/ {8 A+ B4 M - {
% M/ i; ~: J; v& |& u& ]+ u - v24 = (int)(v22 + 12);, S6 F# ~% R7 p2 [4 i4 B8 J( h+ N: E
- do9 Z2 h: d( j' e1 F& S ^
- {
& |! y. Z2 W- d) L, W0 H) U( M( }/ Z2 D9 M - *(float *)(v24 - 4) = 0.0;% [7 F$ A2 I) ~' i2 X; x' q; h
- v24 += 32;* f i) p) m5 \2 m+ D: Z* H; S
- --v23;5 v5 ~6 b, s g* G' A" x$ `4 G0 I
- *(float *)(v24 - 32) = 0.0;
, O" ~9 v! |3 }% f" u# m - *(float *)(v24 - 44) = 0.0;
" p, l/ C+ d, T6 k' H( l2 g - *(float *)(v24 - 40) = 0.0;" |1 j( O+ k! t6 m% ?; v* C
- *(float *)(v24 - 36) = 0.0;
# g7 s/ T+ F7 Q9 R- P7 b - *(float *)(v24 - 32) = 0.0;
5 y5 b8 p9 s# G: O/ U - }
9 h2 j3 v- f; o - while ( v23 >= 0 );
7 ~" o. F. q3 q0 R - }) k! t3 ~+ G5 t+ `/ Z
- }
2 Q: n, d0 N8 k( m# g$ I$ ^2 w( ~ - else" }* }3 |; D6 G- k2 z. p4 a
- {, g# ^% v4 d4 K) Q6 c! `
- v22 = 0;3 k9 X' d3 ~, d) w/ W7 N1 `' g6 J& V
- }
$ P; T G! D3 Y7 o! C( D+ r/ E - *((_DWORD *)v11 + 5) = v22;( m* i. q0 P- }+ R$ w B: ]
- SetRect(&rc, 0, 0, xRight, yBottom); ]( s( J0 b, ?8 A
- v25 = (HBRUSH)GetStockObject(4);( u) X8 H8 D( P4 N. f/ n
- FillRect(v18, &rc, v25);
' z) o- z. I) X1 n( [+ m - SetBkColor(v18, 0);; {0 z% ^9 t3 Y! |9 E8 |; [
- SetTextColor(v18, 0xFFFFFFu);" s; I% D, Y1 o% ~8 K
- SetBkMode(v18, 1);
# C" o- @( R: q+ |) d6 o& Q - v26 = 1;4 k3 E" Y, W3 l2 E/ u7 {: e
- v41 = 1;$ K( b5 q7 V g. Y/ B
- v40 = 0;( K' ?2 k) Q9 z+ G* h
- v43 = 0;
7 s' l" _1 s) R - if ( *((_DWORD *)v11 + 4) > 0 )
' ^6 {% O4 \* Y* D7 ` - {% Q3 ?1 h9 p' o6 ~4 c4 u
- v27 = WideCharStr;
3 L7 r( {- {6 q5 s: n: n% Z - v44 = 0;
& j9 p* G' N$ I! N8 i - v42 = WideCharStr;
+ n( _- D' |; E - v49 = (double)xRight;
% Q# F3 X& d; R& d0 v - v50 = (double)yBottom;
! x7 J% j5 W- O' V, E - while ( 1 )
! z9 X3 x0 M w& q2 I \7 Y$ H - {) t2 x+ y* P* m! k% X- w' C4 u
- v28 = v44 + *((_DWORD *)v11 + 5);
3 v, y/ z/ Z# d - *(_WORD *)(v28 + 16) = *v27;6 @) ^, X7 F) t, z
- GetCharABCWidthsW(v18, *v27, *v27, (LPABC)(v28 + 20));
3 c6 y+ W! h7 L( ` - if ( *v42 >= 0x20u )
# N! `. e0 O7 O, U! E' B7 u* S - {
8 a% r C; X0 `% ]$ o- B - --*(_DWORD *)(v28 + 20);! g* ?; L, X0 x4 }. n7 N6 B
- *(_DWORD *)(v28 + 24) += 2;
7 q9 ^* ]4 l4 t4 l1 M - --*(_DWORD *)(v28 + 28);' B5 C. j+ M1 w0 ], o8 l
- }
, y5 O9 G- S/ A* z - else% D# V0 R$ F1 p
- {
3 @3 k3 W1 {# y - *(_DWORD *)(v28 + 20) = 0;2 j5 d! @. W; `- B6 S+ e
- *(_DWORD *)(v28 + 28) = 0;+ e) K/ _# @6 U5 u5 L0 T
- }& |$ s1 o& S% C/ a- i& I
- v29 = *(_DWORD *)(v28 + 24);! x- S, b3 k5 V' d8 b/ _( J. x
- v30 = v40;! T- L* o# R3 u3 A. F- o
- if ( v29 + v26 + 1 >= (unsigned int)xRight )# a. y3 I2 \6 D- G9 d* U
- {
8 E2 ~) z$ ]' ]% `( t7 @ - v26 = 1;: F3 @8 {0 \# j2 s& Z4 x
- v30 = v40 + *((_DWORD *)v11 + 3) + 1;5 i7 r3 q9 g1 P/ h6 v$ p# _
- v41 = 1;
; D; j& \% ]/ i5 |) d( g - v40 += *((_DWORD *)v11 + 3) + 1;$ z! [7 M1 u+ J- f, l* L. C
- }
) ^/ S/ g7 w/ ?% `% |+ P& t - *(float *)v28 = (double)v41 / v49;
) e6 S; a$ T1 |& s - *(float *)(v28 + 4) = (double)v40 / v50;
/ T/ a8 P! Z# y# J1 V2 v - *(float *)(v28 + 8) = (double)(unsigned int)(v26 + v29) / v49;
( `) ^. g# l% a0 S4 n% o9 q0 E; A - v31 = v26 - *(_DWORD *)(v28 + 20);- Z/ d' Y Y0 f% p; S9 W6 i. [; f
- *(float *)(v28 + 12) = (double)(v30 + *((_DWORD *)v11 + 3)) / v50;
& H( w1 B o4 n - TextOutW(v18, v31, v30, v42, 1);
$ C! ^$ H5 p7 w( Z: Q/ f$ G8 H - v44 += 32;0 V+ Q" R, o; w0 Q1 ?0 ~6 K5 a x
- ++v42;4 [0 ]8 d" A9 Z& r' i _
- v33 = __OFSUB__(v43 + 1, *((_DWORD *)v11 + 4));
0 s6 \* p( R1 `7 ~ - v32 = (signed int)&v43[-*((_DWORD *)v11 + 4) + 1] < 0;
3 b1 Y" k8 m' r! e+ L/ s1 G - v26 += *(_DWORD *)(v28 + 24) + 1;
% U9 c% j1 U8 ~7 f - v41 = v26;
) p6 r! i+ N0 I9 b8 ?+ W - ++v43;7 ~$ ?$ G$ T8 p( h' l0 S
- if ( !(v32 ^ v33) )+ z6 k* B* h \ D( v6 x
- break;2 i1 o3 n. b& `6 y& s
- v27 = v42;
0 u' m4 X; }# Q6 }1 P - }: _. b0 {$ m3 N- N
- }2 \3 v) B- B D, \# ]1 X2 f' ?2 D
- v34 = CKBitmapData::LockSurfacePtr((CKBitmapData *)(*((_DWORD *)v11 + 6) + 56), -1);/ h% x% x# b" `+ _+ ]/ H
- if ( v34 )2 g I* [, Y; Y* c) G, c
- {6 v) e# B& V; O! A+ i, @' r
- GetObjectA(v45, 24, &v51);
$ C* ~2 I5 q2 h8 k - v35 = v53;# e2 p, H; J$ F) ^" Y
- v36 = v55 + v54 * (v53 - 1);$ A q( W. X2 f! i& o
- v40 = 0;8 t, `9 m0 q8 y4 b- p
- if ( v53 > 0 ) \4 b4 M/ S, m6 q+ P5 x( n
- {
: C& F$ P) d! C* {! d2 J( h - v37 = v52;5 V- b" }1 Q( n, k
- do
5 b" ~9 X3 D' i: h3 _; t; z& M - {- r) A9 r% D7 J& F8 c
- v38 = 0;, t/ u; U R7 s4 I! R: y2 }
- if ( v37 > 0 )
- M* n; O: Q0 o7 {9 k- D - {9 M5 \4 x, U1 T ?% G
- v39 = (unsigned __int8 *)v36;
7 V" r9 q! K) ^' S, A3 @* i/ o7 {5 r - do/ A) a& |5 L/ J! L ?# M
- {7 w) c5 q0 } V6 I
- *(_DWORD *)&v34[4 * v38] = (*v39 << 24) | 0xFFFFFF;. `9 e5 I# {0 L/ r$ S, @! B5 C7 s
- v37 = v52;
, H/ z) J4 i) g - ++v38;2 d% r& F7 O$ i; V9 a
- v39 += 3;+ h: V! m" ~1 i: G7 `
- }6 O5 j% P* H3 W9 q( a
- while ( v38 < v52 );1 d; Z+ M( `5 u, V4 l8 A
- v35 = v53;, H6 P6 ^ f. J6 [) F, K) b0 }+ q
- }
7 r$ m4 k, A. X; [ - v36 -= v54;, `3 K/ |' V* w5 y) h' ?
- v33 = __OFSUB__(v40 + 1, v35);7 Y% j7 V5 a$ `) G4 f/ A0 y4 t
- v32 = v40 + 1 - v35 < 0;
l$ r& o( ]% Z9 X9 E# c - v34 += 4 * v37;
6 o" W0 B9 J7 F' L' W - ++v40;3 _0 H5 Y7 K# }0 P: X) P; P
- }& Y8 x# r/ X; E# r% f+ n
- while ( v32 ^ v33 );, J/ b4 O) Q; f3 F( B5 I! X
- }
a, }6 Y9 | ]# x/ s4 P' R - }7 ]* ~# l8 x2 F4 p# v5 g
- CKBitmapData::ReleaseSurfacePtr((CKBitmapData *)(*((_DWORD *)v11 + 6) + 56), -1);5 t3 L8 N7 D$ c4 ^
- SelectObject(v18, v46);! `& l6 P6 ~% B. h4 E
- VxDeleteFont(v48);
. ]7 u: n) c" f& v0 `4 }1 t3 D - SelectObject(v18, v47);! B7 w7 G7 `% F# O, C
- VxDeleteBitmap(v45);7 ^& ?: }1 V: Y. |( {+ T0 Z v
- DeleteDC(v18);
; `1 b2 A6 P, A7 z3 S9 R - CKObject::SetName(*((CKObject **)v11 + 6), (char *)a3, 0);
4 c2 z" [; {2 A. Q' Q8 K - CKBitmapData::SetDesiredVideoFormat(*((_DWORD *)v11 + 6) + 56, 1);
I3 K: ?1 e- |; r& }4 {" B8 T - (*(void (__stdcall **)(_DWORD))(**((_DWORD **)v11 + 6) + 120))(0);3 h/ W' G) b9 g% h
- return v40 + *((_DWORD *)v11 + 3) < yBottom;
9 Z- d% J# x: J7 B; i) P - }$ ?8 R! y+ l! X r- R# k
复制代码 7 h B) y! H- _+ q. E3 @
( u6 |& i6 j9 U- `1 N ?) H
|