本帖最后由 shane007 于 2023-8-26 17:10 编辑 1 r" ]7 g- `* p) d. C Y
4 |/ H3 u7 M# W/ O这个游戏的主要修改点在\player\BuildingBlocks目录下的Adventure.dll中。
6 k- |/ x3 t1 C0 a& p- ^0 P1 z4 u) T用API monitor对本DLL的CreateFontA函数进行跟踪,发现确实有调用, 参数如下。
& x1 C; W, I& F, D) y) r. ]3 y. B5 }! L
- # Type Name Pre-Call Value Post-Call Value
( I2 t( J& O' h B+ V0 I. U - 1 int nHeight 0xfffffff0 0xfffffff0
1 ^" |$ P/ s5 y! m6 W( I" R6 E3 s1 x% a - 2 int nWidth 0x00000000 0x00000000
* i' a Q; ?, C- G3 I2 J" u( D - 3 int nEscapement 0x00000000 0x00000000) \0 K0 e ]. v% @+ t
- 4 int nOrientation 0x00000000 0x00000000' A0 G3 C% _1 k( r4 @6 D
- 5 int fnWeight FW_NORMAL FW_NORMAL4 f8 h' Z8 k5 Y2 E/ ^4 B1 ^
- 6 DWORD fdwItalic 0x00000000 0x00000000
7 D& P; P: B; Y/ X, `: E - 7 DWORD fdwUnderline 0x00000000 0x00000000
5 i1 i" j7 P: } - 8 DWORD fdwStrikeOut 0x00000000 0x00000000# j5 y2 i. ]8 s, l' a( G
- 9 DWORD fdwCharSet DEFAULT_CHARSET DEFAULT_CHARSET$ G0 {+ U) \9 Y( O5 r
- 10 DWORD fdwOutputPrecision OUT_TT_ONLY_PRECIS OUT_TT_ONLY_PRECIS
6 k0 Q( r6 c4 Q7 `+ r - 11 DWORD fdwClipPrecision CLIP_DEFAULT_PRECIS CLIP_DEFAULT_PRECIS3 n @" t$ B, i
- 12 DWORD fdwQuality PROOF_QUALITY PROOF_QUALITY! |( L+ ~) f2 f' f W
- 13 DWORD fdwPitchAndFamily FF_DONTCARE | DEFAULT_PITCH FF_DONTCARE | DEFAULT_PITCH4 g0 `' n; J1 n: ]
- 14 LPCTSTR lpszFace 0x09148a58 "Arial" 0x09148a58 "Arial", ^( p0 U9 B8 @- h
复制代码
6 X9 c$ l& O# [$ e7 B
8 I& N, F1 u, ]5 o' M# A用ida pro找到调用CreateFontA的源头函数如下。* F; b- v& U; l& e8 f0 R
从函数的参数可以看出,这应该就是字幕显示函数了。
; W2 c& \+ @, z7 m. X! j关于后续修改,先修改CreateFontA函数的fdwCharSet,lpszFace这2个参数,也许就能出中文。
0 Z2 Z2 H9 v0 H还不行的话,就自己写一个显示函数。以下函数中lpMultiByteStr就是指向字幕的指针。. u$ g3 j+ v2 A/ y7 f9 C( k# K
- $ \# d) |' M- }' w, y2 z
- 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)
6 R% C% M# V2 k8 F5 X! f. M - {
9 Y& |0 v- s$ J. u# s - void *v11; // edi6 Y9 ~* K) @$ J; X x1 M
- int v12; // eax1 K6 _' `0 R% O f9 Z7 i( V
- int v14; // ecx6 Q1 G$ N9 L) D! c" s
- int v15; // eax( p0 \; ^# r- P" _4 [4 Q
- char *v16; // eax3 e8 T) G3 g! M& G( A
- int v17; // eax' |2 G& [2 ^* M; T* p# e& P8 y! D
- HDC v18; // ebp
6 R7 D- W7 }* V" }9 a' \ - int v19; // eax. U$ X) ?; S9 E2 G2 M1 ^# P
- int v20; // eax/ l, w; {2 N$ d! h7 a; A! `. o0 c7 P
- int v21; // esi' D0 `- }! E2 l* C& _
- char *v22; // eax
3 z1 ]" d u! S" \) G - int v23; // esi
5 K! N& p/ O }" j% Y6 T - int v24; // ecx6 a* }7 t1 n0 X) g2 } a N
- HBRUSH v25; // eax V6 E& `$ U8 c" J4 z
- signed int v26; // ebx" R! k0 f' Y* \- S0 d& E/ Z
- WCHAR *v27; // eax
/ ?, W/ {1 a: ^5 n4 M6 G - int v28; // esi% _* D- P3 \% |: w. X+ N9 N
- int v29; // ecx
+ r0 X- O. k5 _5 \& Q3 ? - int v30; // eax
) P% [/ P! A" y - int v31; // ST28_4
$ z; W8 @6 {) E0 F# h - bool v32; // sf* |+ f, K3 V$ G" ^
- unsigned __int8 v33; // of
! A3 z* ~) B, W: N8 x' X - unsigned __int8 *v34; // ebx% q0 p4 n9 w/ ^& e5 C( e" e' ?
- int v35; // ecx$ o4 p: m! N! t% ]: \: g
- int v36; // esi
, m1 z4 b& r+ ~: B' l& O - int v37; // edx5 r1 m; _$ B# F9 K5 H7 q
- int v38; // eax
) s ? x1 Y6 K0 `' D - unsigned __int8 *v39; // ecx' _9 Y! l. o2 ~+ c5 a
- int v40; // [esp+40h] [ebp-2098h]
* h4 x/ g9 g9 o% m - signed int v41; // [esp+44h] [ebp-2094h]1 ]2 U$ V( ~/ d0 z+ |; h/ v- \
- WCHAR *v42; // [esp+48h] [ebp-2090h]& x. `* H5 C; {( F& q' C4 |
- LPCSTR v43; // [esp+4Ch] [ebp-208Ch]' ~5 J. y1 H1 }! P, a" w
- int v44; // [esp+50h] [ebp-2088h]
% |5 Y3 F+ w) R- I( B" J - HGDIOBJ v45; // [esp+54h] [ebp-2084h]. v' t+ F& e% B- w4 F7 G: Y$ z4 y: P/ [
- HGDIOBJ v46; // [esp+58h] [ebp-2080h]
5 @7 N# z( j% p/ n2 m2 J% k - HGDIOBJ v47; // [esp+60h] [ebp-2078h]6 q3 G: s t3 \# q
- HFONT v48; // [esp+64h] [ebp-2074h]" Q4 r4 O4 u2 h( ^# u. Y% u5 J: g
- float v49; // [esp+68h] [ebp-2070h]5 I# b- @/ P2 y( z; i+ R2 \" r
- float v50; // [esp+6Ch] [ebp-206Ch]
* K0 u$ _4 z, ~1 o; g9 Y& k+ X; a- ~, S - char v51; // [esp+70h] [ebp-2068h]; X# N% {. l; i: t3 C' J* q
- int v52; // [esp+74h] [ebp-2064h]
5 A/ R2 x. A/ G2 N' X( m2 R4 D+ u2 f - int v53; // [esp+78h] [ebp-2060h]
* K2 Z$ b- W8 y0 \8 H0 e: ~- U - int v54; // [esp+7Ch] [ebp-205Ch]
2 A* E7 [- b2 y+ f0 {- Q - int v55; // [esp+84h] [ebp-2054h]& K$ @8 R! V" U/ E, q
- struct tagSIZE v56; // [esp+88h] [ebp-2050h]; n7 i5 |/ [0 R. {9 c# J
- struct tagRECT rc; // [esp+90h] [ebp-2048h]+ U, a5 I1 C- ]( L- l0 J) [
- int v58; // [esp+A0h] [ebp-2038h]
1 m$ b) M8 {% q5 H6 X! C - char v59; // [esp+A4h] [ebp-2034h]
& ]3 O* T9 l: l1 \8 b$ u5 g% c6 ~ - WCHAR WideCharStr[4096]; // [esp+D4h] [ebp-2004h]
6 F* |, o g4 _ - 1 |$ \: g+ U9 d R5 q
- v11 = this;
; }0 b1 g1 O0 ~$ I4 A, n - v58 = 52;
4 Y. m. P9 h( Y! r9 W3 N, N - memset(&v59, 0, 0x30u);* J- S1 K, k$ @# f
- if ( *lpMultiByteStr )" P! s7 @; [% S) I9 x
- {2 Z7 Z! X: f3 W
- v12 = MultiByteToWideChar(0xFDE9u, 0, lpMultiByteStr, -1, WideCharStr, 4096);
2 c7 G# j# a6 B- U7 J( ` - *((_DWORD *)v11 + 4) = v12;& h) Q, [6 e0 p3 R6 p
- if ( v12 <= 1 )+ }- O; ] e% j) s3 I! j# [& ?* f+ A; L
- return 0;4 @8 T2 |( ?1 I! T! m* c0 X0 [# l
- *((_DWORD *)v11 + 4) = v12 - 1;
. w* r& j+ b3 P - qsort(WideCharStr, v12 - 1, 2u, sub_10057A40);0 t$ q* ^3 {2 p# R3 ]
- }
/ l `9 E9 R( d' e. X: _$ K1 ` - else
0 Q7 H. E1 s4 u- E! A2 \( B9 M - {
$ J8 ~' Q) b# D/ J; l( l - *((_DWORD *)v11 + 4) = 352;. L7 c4 w" `8 m9 c1 i& w
- v14 = *((_DWORD *)v11 + 4);
" R/ s* `- b7 T# V6 l: G5 V - v15 = 0;
. V) v& j8 P* m% k' i4 K# E - do+ h: g- L7 { b
- {
& k" S$ N6 l" u/ L# {1 |" q- j$ z0 ^ - WideCharStr[v15] = v15 + 32;
8 j; ?9 w' F+ `1 G- E - ++v15;% x+ J4 f, q( g
- }
2 L* {5 V, g+ C4 @9 f2 e - while ( v15 < v14 );
& G5 |* N) f" V3 u: K# _4 H - }" W- S2 m! D4 Z( D
- v16 = *(char **)v11;
: ]1 u o8 \4 G; s8 _! O' W* s - if ( !*(_DWORD *)v11 )
: d4 @$ i+ }, d' [% B) k - v16 = byte_100B2D6E;
9 Q" {+ f% @6 `; m - v17 = CKContext::CreateObject(a2, 31, v16, 0, 0); e2 ?+ ^& |. B" t; D
- *((_DWORD *)v11 + 6) = v17;, N9 \; H2 _, o1 `$ O+ `: u: n9 s. o
- if ( !(*(int (__thiscall **)(int, int, int, signed int, _DWORD))(*(_DWORD *)v17 + 84))(v17, xRight, yBottom, 32, 0) )
% U! y: i# ~3 s* v9 C4 A% J9 q( [' w - return 0;! H: q0 ?4 O" h& u; C* E9 @
- (*(void (__stdcall **)(int *))(**((_DWORD **)v11 + 6) + 136))(&v58);
! \# ~: o. X# T2 G: P8 c - v18 = CreateCompatibleDC(0);8 b8 R# g8 ~) _) ?8 m& ?: G& }( I7 A1 I
- v45 = VxCreateBitmap((const struct VxImageDescEx *)&v58);8 L+ g, p3 O& ~7 ~3 S# k
- v47 = SelectObject(v18, v45);9 M4 s' v. ?- h# |6 c
- XString::operator=(v11, a3);
9 W4 m C6 Q: U - *((_DWORD *)v11 + 2) = nNumber;
& O& z$ L4 M. [" U- f& u - v19 = GetDeviceCaps(v18, 90);
6 E" z. K9 x+ z, F) r: Y. b7 e9 | - v20 = MulDiv(nNumber, v19, 72);& t7 b5 r O/ o) q* d2 v; _; X
- v48 = CreateFontA(-v20, 0, 0, 0, a6, a8 & 1, ((unsigned int)a8 >> 1) & 1, 0, 1u, 7u, 0, a7, 0, (LPCSTR)a4);2 J- P7 O6 d9 h: V
- v46 = SelectObject(v18, v48);- V6 x( n& n+ m% C" p8 d) u
- GetTextExtentPointA(v18, "A", 1, &v56);
8 T9 g' \7 z, b* b - v21 = *((_DWORD *)v11 + 4);" P" v. M8 r0 `0 R
- *((_DWORD *)v11 + 3) = v56.cy;
9 y4 U$ t- H( A& W. @$ Y5 I - v22 = (char *)operator new(32 * v21);( g& Z% K+ L, v3 e
- if ( v22 ) R: K+ }; e0 X0 `6 d8 j
- {
( ]0 j0 _2 C0 {( f" Y8 h - v23 = v21 - 1;
: V7 |% }8 R; X5 @* i7 Q - if ( v23 >= 0 )4 J' l/ X0 L w; K Z' m% B1 J0 C
- {' l1 k+ N* o6 a7 {( c B
- v24 = (int)(v22 + 12);, ]7 U3 Y/ p) z" x; {
- do
. O" }6 o1 d! J! U4 ~$ ? - {
1 G# X& @5 @; {; Q - *(float *)(v24 - 4) = 0.0;% B6 U$ L- x2 d/ g' r0 k+ g
- v24 += 32;! q8 ?0 v% O. x9 b# d
- --v23;& u t+ G9 C* V3 A; [+ i/ U; o
- *(float *)(v24 - 32) = 0.0; R6 }5 q9 d8 j
- *(float *)(v24 - 44) = 0.0;" @6 k, O) L# D) G
- *(float *)(v24 - 40) = 0.0;
( b/ W0 ?# X3 N! q - *(float *)(v24 - 36) = 0.0;5 Q5 F0 L7 B: O; q0 q
- *(float *)(v24 - 32) = 0.0;, A$ d: q- M3 m. X {+ T/ d( Z* h
- }5 O2 F. P. R; V9 Y% b
- while ( v23 >= 0 );
( v! F2 i$ w0 C8 ~# `! r( C( m - }
; U' |1 ?2 ^7 U - }$ F3 ]. x" L8 j; Q. K( A
- else+ ^5 y$ v6 L0 _9 b, O
- {
; z9 d& d: g/ L4 k - v22 = 0;0 F) ~3 O+ @( u9 s F
- }' B* G- p ?' I* c2 s$ L( l
- *((_DWORD *)v11 + 5) = v22;; Z2 B1 M- r7 g v2 y. J* N
- SetRect(&rc, 0, 0, xRight, yBottom);" N0 i7 y# z& U5 v' e3 w; H
- v25 = (HBRUSH)GetStockObject(4);
/ @2 I# q" U4 b - FillRect(v18, &rc, v25);/ @7 X5 A) Y) K7 s0 P+ F3 B4 g! u
- SetBkColor(v18, 0);
( T" z L& T4 l - SetTextColor(v18, 0xFFFFFFu);
5 v" B# }4 z4 \) i/ |( _ - SetBkMode(v18, 1);
; N+ `1 D! w6 A3 {3 a7 } - v26 = 1;3 O- G# b* o \" r* ]& a' `/ l
- v41 = 1;% j# F( M r/ ?5 h
- v40 = 0;6 {( H E( w. R8 o. y+ _2 K8 w% y
- v43 = 0;
+ i$ D8 Q% A$ Z - if ( *((_DWORD *)v11 + 4) > 0 )
6 t# }. `" t5 y' E# |9 ^5 w1 h - {
1 S$ A2 i# t9 b/ R/ F1 ] - v27 = WideCharStr;* P( ^) |0 B/ C6 x; W
- v44 = 0;
* z+ K+ n& Q+ @! U - v42 = WideCharStr;! P2 r" i1 ?# d8 Z$ f { M# h
- v49 = (double)xRight;5 L, x$ f3 F8 F
- v50 = (double)yBottom;1 Y& p1 q9 y! [, S8 F% S
- while ( 1 )9 O. w B2 a9 [+ p' j5 p
- {) R4 L& A5 n" R
- v28 = v44 + *((_DWORD *)v11 + 5);
O7 P, @" C! a& j- Q - *(_WORD *)(v28 + 16) = *v27;; O/ g" _5 ^& R1 w. y# o
- GetCharABCWidthsW(v18, *v27, *v27, (LPABC)(v28 + 20));- y" k& V. r! {# z/ w8 r
- if ( *v42 >= 0x20u )$ x; E4 K1 ]" D
- {% i4 S' T+ V" f7 m, x# @1 f
- --*(_DWORD *)(v28 + 20);+ W! h: b8 w+ {" N
- *(_DWORD *)(v28 + 24) += 2;
; a2 C$ X+ s/ r4 d* P - --*(_DWORD *)(v28 + 28);
2 k. G! a- T; A2 C& y3 { L - }- Q8 s* M( y* V
- else
, k: R+ M0 H2 x/ T; {; z) a4 C5 | - {
4 R5 Y8 M* E) t& k - *(_DWORD *)(v28 + 20) = 0;
5 x: L/ Z4 Y4 J - *(_DWORD *)(v28 + 28) = 0;( K; Y8 t$ v( O" E& J
- }
" Y J4 D( y+ I4 d, @$ c8 C - v29 = *(_DWORD *)(v28 + 24);
8 M. i. n) |2 e) w* j) u1 H - v30 = v40;5 c; J. u5 d% [$ n: t5 I2 ~
- if ( v29 + v26 + 1 >= (unsigned int)xRight ) r2 L4 _0 u: x$ F ^ y
- {) e$ A" ?' n1 W. u5 V+ A
- v26 = 1;
; D0 u4 ?, E3 [ - v30 = v40 + *((_DWORD *)v11 + 3) + 1;6 z/ _2 h S; S
- v41 = 1;
I9 J: S% l/ x0 a - v40 += *((_DWORD *)v11 + 3) + 1;
3 I' x" ^4 S5 j - }
- b! a* K# w: W: s - *(float *)v28 = (double)v41 / v49;2 m" y: Y' \7 t. |: y: R
- *(float *)(v28 + 4) = (double)v40 / v50;
3 n& |6 s. E* l$ q - *(float *)(v28 + 8) = (double)(unsigned int)(v26 + v29) / v49;
# l6 Y+ x) l' ~+ v% b - v31 = v26 - *(_DWORD *)(v28 + 20);
+ o; {/ l) A9 s4 {) R6 u! k - *(float *)(v28 + 12) = (double)(v30 + *((_DWORD *)v11 + 3)) / v50;6 Z3 b' `- D, s1 g9 Z- W4 E# U
- TextOutW(v18, v31, v30, v42, 1);! Z: _8 J* _6 j! d1 O2 |
- v44 += 32;3 w: ^; X( H9 j" G* k- L6 }8 l6 Y
- ++v42;! \8 j* v; S+ T3 u4 U
- v33 = __OFSUB__(v43 + 1, *((_DWORD *)v11 + 4));
/ ^, p, u& m% W% A2 N - v32 = (signed int)&v43[-*((_DWORD *)v11 + 4) + 1] < 0;6 [. B6 W/ o7 `* B4 f+ S' r. Q3 g
- v26 += *(_DWORD *)(v28 + 24) + 1;
- J6 d( p/ \& G- X( g - v41 = v26;; W! w. E/ U) g3 v
- ++v43;
- z8 L% l* a' j5 m, ]4 T, H! E - if ( !(v32 ^ v33) )
- @: c$ A7 j9 q. i( S4 z% ? - break;
1 f, U' `' J1 u9 B8 i" F- c - v27 = v42;
$ h% ~7 m t7 r - }2 Y/ a$ ^3 B$ f3 y% [. a& C- v4 o
- }5 M, a% s( t1 {, o) F
- v34 = CKBitmapData::LockSurfacePtr((CKBitmapData *)(*((_DWORD *)v11 + 6) + 56), -1);
1 ]9 ~2 m4 Y- ^ - if ( v34 )
$ V6 U8 I1 | G) p5 z7 ~, q# s - {7 i4 ]5 G0 C7 |. ]/ ^
- GetObjectA(v45, 24, &v51); p/ G" b# V! J- A4 p* K: o; Y
- v35 = v53;
# Y) h9 j5 k. E1 P - v36 = v55 + v54 * (v53 - 1);/ q$ m! V/ p. D
- v40 = 0;
: ~6 Y5 i$ [9 ^* ]( u: N0 g5 Z - if ( v53 > 0 )
1 a6 k5 q0 T; M3 N - {# e' r7 e' v" e4 ?# o9 `5 u
- v37 = v52;
& {- v4 @& y0 w- h - do
7 b4 S) C& D5 a7 N% Y* V8 r - {
z$ ?& i, b$ }$ \ - v38 = 0;
6 \/ l( t5 Z( O( o - if ( v37 > 0 )
4 B3 }! `0 t% G& w - {
! U2 k8 ^* Z" T h! Y - v39 = (unsigned __int8 *)v36;. N* S% e* R/ B- {
- do
0 |" S* a1 c- s0 o: W' ~( P - {
1 W" Z+ z7 y, l A, i - *(_DWORD *)&v34[4 * v38] = (*v39 << 24) | 0xFFFFFF;
) G, Z( P% U3 F - v37 = v52;
. X2 U2 L1 r }& \6 | - ++v38;
( Z1 m# K |) G! q0 \5 | g' _2 W - v39 += 3;3 @' x0 G" _. W* d/ W% c% s
- }
$ h! j& v8 Q% O0 {$ m - while ( v38 < v52 );. T/ \& O% G. |$ ^8 H
- v35 = v53;
- G' g' D5 K0 L' \! y$ j! r - }
0 b+ R. l9 H1 R: p - v36 -= v54;9 h" {$ @& E* _- Z
- v33 = __OFSUB__(v40 + 1, v35);: i; e! f9 F7 K7 d1 X' l
- v32 = v40 + 1 - v35 < 0;# h# H; Q6 k3 f7 ^, ~8 N, \$ |6 k
- v34 += 4 * v37;0 M7 [+ K/ N$ \) T$ j. G4 [/ x
- ++v40;5 i5 P" O( [0 _+ X& U# h9 b
- }4 \8 K* j1 I I* U0 e/ t3 g# q `6 N
- while ( v32 ^ v33 );2 _& h, Q# p/ J$ r" `
- }
1 y7 d9 n5 W7 O6 x - }! y+ G( m5 T5 Y+ o) u4 J
- CKBitmapData::ReleaseSurfacePtr((CKBitmapData *)(*((_DWORD *)v11 + 6) + 56), -1);% O. H+ l$ K9 C6 T B0 ^6 f
- SelectObject(v18, v46);* L0 X" X& y' [! O, P$ p0 W0 H
- VxDeleteFont(v48);
* L9 B/ M. d% V* g+ B3 Z* H - SelectObject(v18, v47);
6 x% B" b9 y. U# l - VxDeleteBitmap(v45);
2 o% i% K/ B$ W+ ] - DeleteDC(v18);
9 F4 Y& L1 c2 V+ N! n7 z4 M/ u, x - CKObject::SetName(*((CKObject **)v11 + 6), (char *)a3, 0);8 Y; c& e/ x/ T' o% Q
- CKBitmapData::SetDesiredVideoFormat(*((_DWORD *)v11 + 6) + 56, 1);
+ U' T9 m" Y# w! M+ m - (*(void (__stdcall **)(_DWORD))(**((_DWORD **)v11 + 6) + 120))(0);
R- Q4 t; \) J/ r2 v0 T - return v40 + *((_DWORD *)v11 + 3) < yBottom;5 c" P. q6 A x, [$ m. L# D! Q
- }
7 Q3 P, L1 y. L" U% {
复制代码
7 ?1 T* ]% w- o, n: T( Q% k) ~) y+ }" t
|