本帖最后由 shane007 于 2023-8-26 17:10 编辑 ' F" V% ^) ?4 b7 m3 f
7 d+ T+ H ?1 D' F这个游戏的主要修改点在\player\BuildingBlocks目录下的Adventure.dll中。
5 `$ H. W1 W' V# [& _用API monitor对本DLL的CreateFontA函数进行跟踪,发现确实有调用, 参数如下。( ?1 r, o$ e9 [# k4 t7 N, w
5 M7 N' B1 T" i- # Type Name Pre-Call Value Post-Call Value# B5 b# u* U7 f# {7 m3 k' q
- 1 int nHeight 0xfffffff0 0xfffffff0
, A& w3 W9 B$ r2 J0 h( ^% p - 2 int nWidth 0x00000000 0x00000000. W) K: ^* e3 @( A9 l
- 3 int nEscapement 0x00000000 0x00000000
7 _/ _. T' u+ l$ L, u1 c( L, Z - 4 int nOrientation 0x00000000 0x00000000
$ ?) h% C0 l% S; H - 5 int fnWeight FW_NORMAL FW_NORMAL8 T' N/ E2 [3 _0 I1 r3 W9 C' b2 N
- 6 DWORD fdwItalic 0x00000000 0x00000000
% D) k6 X0 Z& v4 ]9 |' D1 E - 7 DWORD fdwUnderline 0x00000000 0x00000000
8 w) _ O6 z7 o5 `. v% O9 T# ~% u, n - 8 DWORD fdwStrikeOut 0x00000000 0x000000008 M, ~! H. Z e/ Z% R
- 9 DWORD fdwCharSet DEFAULT_CHARSET DEFAULT_CHARSET* }( |" Y, K1 ?
- 10 DWORD fdwOutputPrecision OUT_TT_ONLY_PRECIS OUT_TT_ONLY_PRECIS6 x' d6 d! S( A& g
- 11 DWORD fdwClipPrecision CLIP_DEFAULT_PRECIS CLIP_DEFAULT_PRECIS/ k& _2 o' l% X
- 12 DWORD fdwQuality PROOF_QUALITY PROOF_QUALITY1 O, Y: s, ], c1 i6 u' y
- 13 DWORD fdwPitchAndFamily FF_DONTCARE | DEFAULT_PITCH FF_DONTCARE | DEFAULT_PITCH
) ^" H+ l5 @7 Y$ f; | - 14 LPCTSTR lpszFace 0x09148a58 "Arial" 0x09148a58 "Arial"
. f9 x1 P: V1 b7 h6 B1 d
复制代码
# @% R! p8 P( |" ?9 {7 i! ^4 D
" N. D( o" N8 ~0 \3 K用ida pro找到调用CreateFontA的源头函数如下。
3 Z% _, r/ Q5 L p, r' I/ M) h# X2 J从函数的参数可以看出,这应该就是字幕显示函数了。
* i- }4 _0 S( t4 O2 M H' x2 p关于后续修改,先修改CreateFontA函数的fdwCharSet,lpszFace这2个参数,也许就能出中文。4 N6 b. {% A" L( S0 s
还不行的话,就自己写一个显示函数。以下函数中lpMultiByteStr就是指向字幕的指针。
0 ^/ }/ {" W8 y& D: B- " g, @- a! A/ C ^, ?
- 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)* B) j8 q9 Z5 v$ G5 U/ j4 E
- {3 R# r+ Q/ m$ J6 a. R+ J9 q& M
- void *v11; // edi
2 @# j+ L3 c2 c* M N7 m - int v12; // eax0 u/ W( h5 g& P' y, W
- int v14; // ecx- ?2 z7 ^8 Q: u, K
- int v15; // eax1 \( s& U9 c w
- char *v16; // eax
4 I+ L: W0 d t4 J% }8 K/ r - int v17; // eax
% h% I1 F, R/ B - HDC v18; // ebp) V+ H% j/ u8 X" e
- int v19; // eax
) G/ F. o; h: ~- @ - int v20; // eax" f7 H! J1 G, ^" W: L
- int v21; // esi
# l9 h: v! K* w3 r4 d7 u8 h; k - char *v22; // eax
- I \+ E+ ^* `$ H - int v23; // esi$ A/ i! D" M5 ?& Y" ~' r. B
- int v24; // ecx
9 z+ ?' W- i8 l8 C2 [ - HBRUSH v25; // eax
9 w3 Z' H# T- [ p; i \1 O - signed int v26; // ebx- t" p# C" e# f2 [
- WCHAR *v27; // eax
/ _/ x/ k9 G9 h$ X5 N - int v28; // esi
, ?8 f2 G* l5 X - int v29; // ecx9 i) i( c# v0 h! N; x" X
- int v30; // eax8 h; \2 [( l. O+ a0 D' D# J5 ?
- int v31; // ST28_4
6 j+ z! O5 y; k - bool v32; // sf
6 R& P0 p' H' |1 u" D6 _, K- i9 ]1 l# [) w - unsigned __int8 v33; // of/ p0 i2 }( k7 R
- unsigned __int8 *v34; // ebx
$ ~, E5 E. z$ E. O3 N! F - int v35; // ecx2 m# O( X8 q' f
- int v36; // esi& H5 p% ~1 l4 S' @' B
- int v37; // edx$ N' X* N7 g- N9 f/ A
- int v38; // eax. Y0 i, |9 G* ]
- unsigned __int8 *v39; // ecx
1 W* [; A. m, v - int v40; // [esp+40h] [ebp-2098h]
" I; u0 D4 G8 v; n/ k - signed int v41; // [esp+44h] [ebp-2094h]2 e+ V! d+ L! G- j8 W: ]3 r" q4 m
- WCHAR *v42; // [esp+48h] [ebp-2090h]
* y; [7 M( j+ t5 O. x0 N+ y - LPCSTR v43; // [esp+4Ch] [ebp-208Ch]
, N$ o) w8 a! ~, s9 S - int v44; // [esp+50h] [ebp-2088h]
! J' n6 u. C, H) A3 q' q - HGDIOBJ v45; // [esp+54h] [ebp-2084h]
) d- [9 G; O/ z8 U - HGDIOBJ v46; // [esp+58h] [ebp-2080h]) J5 V2 g6 F% f
- HGDIOBJ v47; // [esp+60h] [ebp-2078h]( s, E1 y. {+ ]2 x& ~6 ^( c. ~- B* I& V
- HFONT v48; // [esp+64h] [ebp-2074h]
. m. a/ N8 B! r+ o- B m. }+ h - float v49; // [esp+68h] [ebp-2070h]+ N+ e6 K- D) y" H
- float v50; // [esp+6Ch] [ebp-206Ch]$ ^+ p/ D! z% e: }4 \4 i
- char v51; // [esp+70h] [ebp-2068h]- G# h7 q& N; }: D0 j$ E
- int v52; // [esp+74h] [ebp-2064h]& |, r+ Z* O9 [( Q" V: p
- int v53; // [esp+78h] [ebp-2060h]5 ^( t( N$ ~. ]9 G
- int v54; // [esp+7Ch] [ebp-205Ch]
, C4 a* o: j$ ]# i) s - int v55; // [esp+84h] [ebp-2054h]
. z; `$ a: c' C' K1 o: g/ ~7 M - struct tagSIZE v56; // [esp+88h] [ebp-2050h]+ z" s+ s9 I: S, F/ q0 L
- struct tagRECT rc; // [esp+90h] [ebp-2048h]0 L! c1 ?/ D" H8 \1 o
- int v58; // [esp+A0h] [ebp-2038h]" z& V$ x: }5 f) r5 W) Y
- char v59; // [esp+A4h] [ebp-2034h]) ?9 ~# ~/ k E) C( U
- WCHAR WideCharStr[4096]; // [esp+D4h] [ebp-2004h]% Z1 W& ?$ d' B0 A# [* T# k
- ) z9 V# J/ ~( U' T9 b
- v11 = this;8 c a- F, T7 b4 ]" H# I
- v58 = 52;- {, o! S' Q/ N+ M. N: D7 h
- memset(&v59, 0, 0x30u);
$ @, [6 f. X7 t) t$ g9 Y3 b - if ( *lpMultiByteStr )
8 r6 n% {+ ]6 J% b p [1 D+ Y5 t - {
! W' x' }: n$ B - v12 = MultiByteToWideChar(0xFDE9u, 0, lpMultiByteStr, -1, WideCharStr, 4096);8 M. |. ~& N! U/ D. P' H3 d5 j
- *((_DWORD *)v11 + 4) = v12;
6 i6 N- z* O6 L5 M - if ( v12 <= 1 )
- S) H. Q7 a& j$ Z - return 0;
8 A/ v! r, l! ? - *((_DWORD *)v11 + 4) = v12 - 1;
5 Q, u, W8 i2 A8 K/ S5 ~ - qsort(WideCharStr, v12 - 1, 2u, sub_10057A40);
2 T3 n* t# H" `# S - }) d. {/ s3 N1 `! |
- else; u0 U6 W4 k) s# ^9 q
- {
9 v2 \ f8 \% Z' O3 ] - *((_DWORD *)v11 + 4) = 352;
a0 d0 j' e" |+ c7 h: _9 F% i5 V - v14 = *((_DWORD *)v11 + 4);3 H: S `2 s" U/ K" t
- v15 = 0;5 U# R; L5 K" q& g
- do
8 | ~% {( i0 V: I& Z' f - {0 t+ A+ b/ l8 U7 V
- WideCharStr[v15] = v15 + 32;0 \ G; b- B9 h0 ?/ Z
- ++v15;
9 k9 J& W# Y9 F% J6 L9 j5 W" l - }
?' G4 v4 D# B9 N - while ( v15 < v14 );" S3 X* F( q, r& J& _. V0 b6 r& g# j! g" L
- }
" f: r' F5 Z) N1 c- g+ Q - v16 = *(char **)v11;
0 w% W$ \# O; I1 O - if ( !*(_DWORD *)v11 )
c' h; G) [: c; U3 S* z) V# }0 N - v16 = byte_100B2D6E; j0 v- {8 Y/ ]( v6 r$ K+ ?
- v17 = CKContext::CreateObject(a2, 31, v16, 0, 0);- V; a- M: ~3 ?0 d- ~! y
- *((_DWORD *)v11 + 6) = v17;- r5 P$ N, y0 E$ s8 ^) c c' S
- if ( !(*(int (__thiscall **)(int, int, int, signed int, _DWORD))(*(_DWORD *)v17 + 84))(v17, xRight, yBottom, 32, 0) )
, m% h( a8 r- d9 G+ a5 v# f - return 0;6 Y! z- N$ T1 r, v1 U! v" D" z O( g$ X
- (*(void (__stdcall **)(int *))(**((_DWORD **)v11 + 6) + 136))(&v58);6 K7 N$ @' h6 W
- v18 = CreateCompatibleDC(0);+ _# J6 P( w/ P# s
- v45 = VxCreateBitmap((const struct VxImageDescEx *)&v58);
" G9 }$ l' K1 B7 B, v+ H& A - v47 = SelectObject(v18, v45);
9 o. w6 u! O9 |4 g( |9 N - XString::operator=(v11, a3);8 |& L! U2 W* k% {- n3 }. v8 p/ p
- *((_DWORD *)v11 + 2) = nNumber;
1 v% z6 d: L( y+ |) e - v19 = GetDeviceCaps(v18, 90);
5 b' s0 @7 ^0 G7 q0 V& o) v! Y - v20 = MulDiv(nNumber, v19, 72);% n7 z6 G$ \9 U# ?4 v; q
- v48 = CreateFontA(-v20, 0, 0, 0, a6, a8 & 1, ((unsigned int)a8 >> 1) & 1, 0, 1u, 7u, 0, a7, 0, (LPCSTR)a4);
* n9 p5 _( D K( z" n - v46 = SelectObject(v18, v48);
- v8 d# Q d4 B# O* \! s! H - GetTextExtentPointA(v18, "A", 1, &v56);
/ ?* N! z' s6 I' @5 S( }+ n* ? - v21 = *((_DWORD *)v11 + 4);- G( Z& e. Z, @
- *((_DWORD *)v11 + 3) = v56.cy;
4 v5 q/ M/ w2 b+ f& V - v22 = (char *)operator new(32 * v21);
8 t. V$ e! o% g, | - if ( v22 )
; o: I7 Q: B( [. y - {+ a; E" p8 t9 q1 f6 p d
- v23 = v21 - 1;4 n8 g2 C+ J- ~& n" `
- if ( v23 >= 0 )
8 {8 K8 O/ u \1 n2 j/ e - {0 L3 `. |* q" [
- v24 = (int)(v22 + 12);/ T0 n5 V S: ^$ Q+ `
- do: ?9 U8 E+ U( y# g# S1 H) Q! m
- {
0 S( v4 b1 |( M7 y; X - *(float *)(v24 - 4) = 0.0;
- {% I" V. M& F+ ^3 @, P - v24 += 32;
- x+ g3 x* h0 c/ C% K& { - --v23;
; k& c3 @- f' I* g& ? - *(float *)(v24 - 32) = 0.0;: y* w% | h. _' l& E
- *(float *)(v24 - 44) = 0.0;
6 C. ~! K& M+ p% e1 d7 ` - *(float *)(v24 - 40) = 0.0;
# o3 H& d* S3 c8 f& x - *(float *)(v24 - 36) = 0.0;
2 n7 f+ ]! C3 h' \ - *(float *)(v24 - 32) = 0.0;
8 p0 I- `- r0 a8 r K1 q - }0 m2 z# i( Z. p% i5 p
- while ( v23 >= 0 );
' I& q5 T. I8 k6 N - }# S# n) m( M# @5 V7 C1 k
- }5 \2 n7 [; o/ u9 A, c" x: S/ H5 y$ Z
- else
+ O+ ~$ ?& Y+ _3 O" i - {
( L& w% }* T$ I& ]5 U5 R8 I: Z9 I - v22 = 0;
, @& v2 G3 f4 M - }
' f) @ Z: E7 r - *((_DWORD *)v11 + 5) = v22;( [/ U. k; D1 H' E
- SetRect(&rc, 0, 0, xRight, yBottom);- M U# q" i9 q F. [( \/ j( b: B
- v25 = (HBRUSH)GetStockObject(4);
- J L6 m4 m% Y5 @. i/ k. r - FillRect(v18, &rc, v25);
! @# |; \7 I9 ^% ?. } - SetBkColor(v18, 0);: o9 j) Q1 j W& I
- SetTextColor(v18, 0xFFFFFFu);" z0 M6 t2 w3 Q% `* Z2 }
- SetBkMode(v18, 1);, ^+ _2 }1 i0 ` y7 i0 e
- v26 = 1;
g# _4 ^7 [6 d8 B- `. r" F; J! y - v41 = 1;0 b& w+ k/ O6 {$ A6 d2 x0 l
- v40 = 0;
5 f, Q- p3 X& A - v43 = 0;# i& I+ R9 \9 C/ Y1 u
- if ( *((_DWORD *)v11 + 4) > 0 )
: T0 c/ V& R6 R! E+ s - {
. y% C! M L& f) d+ M$ c% T" W - v27 = WideCharStr;
4 ~6 u% ~+ h1 f: i6 ] - v44 = 0;4 r# P4 C- {% j5 J
- v42 = WideCharStr;
1 i X2 S2 |: G; Q7 v% L - v49 = (double)xRight;; m& h8 ]+ R+ X* [1 v w" m' K
- v50 = (double)yBottom;1 O- U! I: h+ N4 e
- while ( 1 )
% Z8 N. k6 y* y. y& s- p( S* _, ] - {
3 L2 b, f' x! N4 o- S3 {7 ` - v28 = v44 + *((_DWORD *)v11 + 5);
' E) J4 i. m7 y* D- }3 W7 U - *(_WORD *)(v28 + 16) = *v27;. z, `2 y( L4 U- b |0 H4 z
- GetCharABCWidthsW(v18, *v27, *v27, (LPABC)(v28 + 20));
( E; H: @( d# g5 j& _- c - if ( *v42 >= 0x20u )6 O8 b, q6 l7 p0 Y E- U h, t& j
- {
/ V7 V3 d5 Y+ `, B3 N - --*(_DWORD *)(v28 + 20);9 ^# j8 Z) ?: u" x% n e
- *(_DWORD *)(v28 + 24) += 2;
# O }, n# e3 _. o- A B; ^ - --*(_DWORD *)(v28 + 28);3 v3 r/ l: S, i; K9 t) y& X, n
- }& U# m) E; r& J: { b1 F# \* [. t" ~
- else
1 w" J5 p" G, ^( e1 C" c - {& ?3 i+ U$ d; ~* v6 V
- *(_DWORD *)(v28 + 20) = 0;1 |6 L$ m' f3 D
- *(_DWORD *)(v28 + 28) = 0;
5 X9 ~0 |! S, ?% B. B - }
# V1 O: L$ b* g" N9 t( I - v29 = *(_DWORD *)(v28 + 24);
, [% _1 `- Y) {. j - v30 = v40;
' G! M) t0 ~9 ` - if ( v29 + v26 + 1 >= (unsigned int)xRight )
# S% F& i! Q/ c0 R* P - {
# K& @/ c; S L- N! } - v26 = 1;
* \ P) v% `! @ - v30 = v40 + *((_DWORD *)v11 + 3) + 1;
( l* Y/ h( V+ I1 i& `% x - v41 = 1;$ U# \1 V1 x7 ?& C; y+ \
- v40 += *((_DWORD *)v11 + 3) + 1;1 |: ^7 c1 O- B5 B! e; D8 y
- }' q1 R3 @# \# x1 g+ u
- *(float *)v28 = (double)v41 / v49;5 {0 v5 Z6 c8 a" v% H/ b
- *(float *)(v28 + 4) = (double)v40 / v50;
, v# i( B8 I/ c0 o) `! B - *(float *)(v28 + 8) = (double)(unsigned int)(v26 + v29) / v49;5 ^ Q1 }/ `. [- c# f
- v31 = v26 - *(_DWORD *)(v28 + 20);% g7 w3 @ a; }2 E
- *(float *)(v28 + 12) = (double)(v30 + *((_DWORD *)v11 + 3)) / v50; ^; J8 a1 I& n2 C3 [
- TextOutW(v18, v31, v30, v42, 1);+ R! v- C# _- O! M8 ~+ F. E5 {
- v44 += 32;0 Q8 u) ~$ k$ t) B3 ?2 c9 E
- ++v42;% F. n9 [ L4 e: X- R/ W+ }6 Z o% l' [
- v33 = __OFSUB__(v43 + 1, *((_DWORD *)v11 + 4));+ u. t- N8 H) A' A; \3 ]9 k& j( n
- v32 = (signed int)&v43[-*((_DWORD *)v11 + 4) + 1] < 0;
0 ~ g) M4 e. [3 f - v26 += *(_DWORD *)(v28 + 24) + 1;& `! Y6 Y* }" l# P* t& E
- v41 = v26;
# i# r2 C& |2 n# s$ s f - ++v43;1 w& [3 n! W& J( R& ^
- if ( !(v32 ^ v33) )
: O; i" M- R5 N- k- G+ _' \ - break;& a% g2 @3 L" \% k
- v27 = v42;
: y; ]$ a: G! B% f2 L - }
' W- P; S# u6 ]& i - }
& A( D( ]: K4 F( i$ [ - v34 = CKBitmapData::LockSurfacePtr((CKBitmapData *)(*((_DWORD *)v11 + 6) + 56), -1);( C, U5 e" ^+ \
- if ( v34 )
. \" [( b! P: @5 a( {# }' D - {
9 O1 }, @+ s# A6 I$ p - GetObjectA(v45, 24, &v51);& B! S+ r" Z1 v c
- v35 = v53;
5 E3 w7 x% Y! f6 F @8 ?: [% ? - v36 = v55 + v54 * (v53 - 1);+ |) E3 W% m& y8 l" P
- v40 = 0;
, ]4 @" K& O1 i. v, {* W* W - if ( v53 > 0 )
" J& i: A- T( q1 s3 K% ~ - {
% c* L2 m6 M! r9 S7 [ - v37 = v52;
l4 [& c1 C, K& f& X* Z* d - do' E" [: J. M4 u: n! l
- {
; C4 d+ W, m% q" Y: {; T4 ^' x* @ - v38 = 0;6 b2 E% t3 [* `$ p' v. R
- if ( v37 > 0 )3 A1 K/ w; n9 G, \
- {
; o: v' g# i3 @9 b8 U - v39 = (unsigned __int8 *)v36;' v. o2 ]. ]7 s$ V4 B& ]$ P! S
- do
6 k5 L' s- T6 y1 r3 v0 W! t0 Q - {
3 j; m" D* F5 Y! s' G0 l* W - *(_DWORD *)&v34[4 * v38] = (*v39 << 24) | 0xFFFFFF;
/ t5 C6 _3 f7 z' i" u - v37 = v52;" A# H; _/ c2 Y0 |
- ++v38;% G# o+ g6 a1 ^% c
- v39 += 3;2 u s3 m% d! G% J( @
- }5 t# c. w) E5 N3 P9 f' r
- while ( v38 < v52 );/ K7 c" Q! r+ s1 z
- v35 = v53;
# e7 P0 \+ ]/ B+ c' x - }
+ z' O- I: D$ ~: X - v36 -= v54;
; }; A5 g) W& Z4 u" Z - v33 = __OFSUB__(v40 + 1, v35);
! P# M: i: O0 |( m6 n% W, k' ? - v32 = v40 + 1 - v35 < 0;
# p2 r7 j! e9 h: `5 l - v34 += 4 * v37;5 ?6 b$ _9 W% U; e5 I' i F+ `
- ++v40;. H5 e3 ]. R9 h# e8 m1 ]7 A
- }
% \) `+ A% A4 y. U/ G1 R - while ( v32 ^ v33 );
8 c* t3 w( N- C9 H - }, X8 I8 J \5 x5 {+ D C. ?
- }" B( J4 m& Q. k+ ?* u( X
- CKBitmapData::ReleaseSurfacePtr((CKBitmapData *)(*((_DWORD *)v11 + 6) + 56), -1);+ O: }8 P2 d7 Y+ N1 }0 e
- SelectObject(v18, v46);1 a: K" n; C- M+ a% O+ b
- VxDeleteFont(v48);
( A8 H+ r* e: B ?( o7 A; B - SelectObject(v18, v47);9 ] h7 @! ]# Z- M- E1 {; M
- VxDeleteBitmap(v45);0 e: `7 {# w% ~% N2 {
- DeleteDC(v18);. ?0 O) L8 M- R$ ?* {
- CKObject::SetName(*((CKObject **)v11 + 6), (char *)a3, 0);
6 X* w N" S2 u1 c! W - CKBitmapData::SetDesiredVideoFormat(*((_DWORD *)v11 + 6) + 56, 1);+ K, c% B @1 Q, G# u
- (*(void (__stdcall **)(_DWORD))(**((_DWORD **)v11 + 6) + 120))(0);! s& N1 D+ R" F9 u1 {; s: W
- return v40 + *((_DWORD *)v11 + 3) < yBottom; {1 p* r/ l0 z" a
- }
b% v# u. U. g2 f: D. _
复制代码 , i' s% F( @# n5 K4 T" Y3 }4 C
) W- F) X* q" P# u$ @3 i1 l8 p9 F
|