本帖最后由 shane007 于 2023-8-26 17:10 编辑
: ]+ c4 Z9 x) u
& J3 @! A7 o) E: d0 j, r这个游戏的主要修改点在\player\BuildingBlocks目录下的Adventure.dll中。
3 a6 m; u. F& ?! w/ a# }5 L用API monitor对本DLL的CreateFontA函数进行跟踪,发现确实有调用, 参数如下。
0 M: |' B5 }/ }2 u" u
4 h8 W4 _) E+ x; e. `: `5 t; o, |- # Type Name Pre-Call Value Post-Call Value! ?; H; X$ R% X+ J1 l/ [" [ H
- 1 int nHeight 0xfffffff0 0xfffffff0: c1 L! O A: j& V" w
- 2 int nWidth 0x00000000 0x00000000# k5 J! y8 x& `2 b& K8 q$ z
- 3 int nEscapement 0x00000000 0x00000000$ D: m0 X1 p4 p' }* z
- 4 int nOrientation 0x00000000 0x000000004 i7 d3 F5 B& d! Z6 P$ P3 u6 a
- 5 int fnWeight FW_NORMAL FW_NORMAL
0 a) r' [: u# \: J7 P9 h - 6 DWORD fdwItalic 0x00000000 0x00000000
D; M' M `. i6 N7 f$ Q - 7 DWORD fdwUnderline 0x00000000 0x00000000
" w# {$ G6 q, R7 c$ ]' `( i - 8 DWORD fdwStrikeOut 0x00000000 0x00000000( |' ?8 j1 g$ q1 X
- 9 DWORD fdwCharSet DEFAULT_CHARSET DEFAULT_CHARSET* p8 F) W3 a5 T; \- ]
- 10 DWORD fdwOutputPrecision OUT_TT_ONLY_PRECIS OUT_TT_ONLY_PRECIS
0 A. w% y% R& c# C) I5 S - 11 DWORD fdwClipPrecision CLIP_DEFAULT_PRECIS CLIP_DEFAULT_PRECIS
" z3 ^; p% \7 @+ O! n - 12 DWORD fdwQuality PROOF_QUALITY PROOF_QUALITY2 ?1 a8 x: F$ H. B2 [+ ]8 q
- 13 DWORD fdwPitchAndFamily FF_DONTCARE | DEFAULT_PITCH FF_DONTCARE | DEFAULT_PITCH
! \0 {! E. _! m0 {" b# T" Q( t - 14 LPCTSTR lpszFace 0x09148a58 "Arial" 0x09148a58 "Arial"
# P @$ @9 ~ T% C, `
复制代码 % L% {6 f4 I$ G) v
8 Y8 ^6 a" d, [0 h9 P用ida pro找到调用CreateFontA的源头函数如下。
: Z* C; @/ M6 f6 _' M从函数的参数可以看出,这应该就是字幕显示函数了。 E8 [( R8 G9 B. t) i
关于后续修改,先修改CreateFontA函数的fdwCharSet,lpszFace这2个参数,也许就能出中文。! u; e' r. X# [
还不行的话,就自己写一个显示函数。以下函数中lpMultiByteStr就是指向字幕的指针。+ O' w% V3 H; M4 `& u0 N6 ^' {8 y' `$ x
- # q1 O; C! p; ^, j6 Y! }5 B
- 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) V' j1 q4 f& j( w- F c
- {
7 z8 m5 O; C2 M+ G - void *v11; // edi4 A. d" u a( U! ]+ q+ u' `
- int v12; // eax
) L0 U4 R9 \$ [; k* g4 o5 ~ - int v14; // ecx! ~& r8 c- _4 e1 t* [9 M
- int v15; // eax) c# O% s# v, b! o
- char *v16; // eax
3 L, ^: g$ |( F1 M1 D) d. l8 p - int v17; // eax0 b4 J' h* u" i4 {5 e
- HDC v18; // ebp
* G' J6 J+ l( U3 n# e; o) q. @! U3 K - int v19; // eax0 E5 W! f! |4 y) C% D8 l& {3 Z
- int v20; // eax- \3 b Z' x' X% N3 ~4 |
- int v21; // esi
( m4 U6 T7 i3 U K. x7 l+ c7 z - char *v22; // eax) F3 [4 ]8 _, ~* A% ]
- int v23; // esi6 _/ u6 k7 F1 |$ Y
- int v24; // ecx6 j( d( O& M5 j1 F6 m4 w- l. W
- HBRUSH v25; // eax
4 W+ \# y; ~# Q) e( m - signed int v26; // ebx2 e6 |6 [/ |. u/ z6 R" a+ T( e6 s
- WCHAR *v27; // eax
M& B) p, F( O, O K* h - int v28; // esi
9 I0 x$ `2 Z0 G4 f9 g9 k0 } - int v29; // ecx
, H' t( I5 I- n) n - int v30; // eax
% j! i4 ^4 J0 L - int v31; // ST28_4
, S6 E% W4 ?/ \ - bool v32; // sf2 G7 @# o {6 d' k' _& |! @
- unsigned __int8 v33; // of* _8 }$ E! I9 ]2 ~/ }) A4 w
- unsigned __int8 *v34; // ebx% L/ Z1 W3 l5 Y8 F
- int v35; // ecx. e% M3 f* P/ E0 m( K; S2 {) E
- int v36; // esi
# q) i6 s5 B5 k - int v37; // edx2 W! v2 X3 w7 E, b0 d _ ]
- int v38; // eax
$ O7 r g" P& B0 s - unsigned __int8 *v39; // ecx
' b$ N! b3 x K4 n' |0 M - int v40; // [esp+40h] [ebp-2098h]
, U# o' M, Z6 N8 b& P4 @, X - signed int v41; // [esp+44h] [ebp-2094h]0 ~0 w! D# f y0 P/ }& j% F
- WCHAR *v42; // [esp+48h] [ebp-2090h]
~9 w' u+ w: q% o6 z - LPCSTR v43; // [esp+4Ch] [ebp-208Ch]% \; V8 I& E1 V& s; [
- int v44; // [esp+50h] [ebp-2088h]- w. k6 }! l, B
- HGDIOBJ v45; // [esp+54h] [ebp-2084h]
! F4 }) O3 Q" [2 M7 h% {2 u: d) E - HGDIOBJ v46; // [esp+58h] [ebp-2080h]
8 R Q3 s1 b$ B$ P+ s' f' }, F - HGDIOBJ v47; // [esp+60h] [ebp-2078h]
, U. r$ N; x( \/ x - HFONT v48; // [esp+64h] [ebp-2074h]) O( Z/ {" C! h( g
- float v49; // [esp+68h] [ebp-2070h]4 S- H; J; Q5 h0 Y6 a: ^3 T
- float v50; // [esp+6Ch] [ebp-206Ch]
6 l l: f& V% D; B* T - char v51; // [esp+70h] [ebp-2068h]6 ?4 B9 m' Q; _: y: N
- int v52; // [esp+74h] [ebp-2064h]5 I$ c2 R/ T# v8 R
- int v53; // [esp+78h] [ebp-2060h]8 F6 ~7 U1 U1 o& T
- int v54; // [esp+7Ch] [ebp-205Ch]4 a: x+ I$ ]' w. m8 R
- int v55; // [esp+84h] [ebp-2054h]; ~0 d8 C8 C+ S3 S" ?
- struct tagSIZE v56; // [esp+88h] [ebp-2050h]
$ g! \( A& B# L& {% J" b$ c" x - struct tagRECT rc; // [esp+90h] [ebp-2048h]
$ V4 V- y6 Q! I& R; s) m - int v58; // [esp+A0h] [ebp-2038h]. ~: O# J3 m) g
- char v59; // [esp+A4h] [ebp-2034h]9 ?2 m0 P; Q+ ^* l# W% h; e
- WCHAR WideCharStr[4096]; // [esp+D4h] [ebp-2004h]' l d- ~2 ~: p. ^7 Y2 ^, \' q! z4 ?) q9 w
- 0 d& K, r6 F! y% C/ P. I( s) n6 \! `
- v11 = this;* |/ S+ X6 Q* E7 z) x1 V$ Z, Q/ [
- v58 = 52;# |# l5 z% |% N
- memset(&v59, 0, 0x30u);) ^. b4 \9 S! [2 Y1 b! A
- if ( *lpMultiByteStr )1 R1 v; q! u; g$ `( u. m
- {
! c. G, R+ v( B" I S - v12 = MultiByteToWideChar(0xFDE9u, 0, lpMultiByteStr, -1, WideCharStr, 4096);# m5 H. P1 z- j7 O; k8 z( i& [6 u
- *((_DWORD *)v11 + 4) = v12;3 e1 E$ h- _6 w% \4 A5 `
- if ( v12 <= 1 )
# P( Q) v. Y( d - return 0;* _5 Y& @- r/ ]7 a# `6 U
- *((_DWORD *)v11 + 4) = v12 - 1;" Q1 Z, ]: \: w
- qsort(WideCharStr, v12 - 1, 2u, sub_10057A40);
& Y5 W1 e6 k+ G# Z. z - }$ }, U$ ]5 ~9 R
- else& E9 \/ s) V* b H! Y
- {8 P7 b+ b' }% g6 A+ ~6 o
- *((_DWORD *)v11 + 4) = 352;
: `7 A3 H! n4 `. P1 W3 [ - v14 = *((_DWORD *)v11 + 4);
t& j4 m% M D3 m4 J) x - v15 = 0;- S9 Y5 B1 U$ X3 Y k
- do
0 b9 t( a& @3 h) S5 M+ l" ` - {0 ]0 P( x8 M, y- o- u
- WideCharStr[v15] = v15 + 32;
3 o5 Y, I' h1 A/ S& ? - ++v15;; g8 ^: J5 O- a0 b
- } @7 [8 e+ R3 Z4 P
- while ( v15 < v14 );% f! a( F0 e2 \: c0 ]
- }1 T# N& g6 n: w) i' w, H
- v16 = *(char **)v11;7 i7 S) q$ y" H: j% S W' G, R
- if ( !*(_DWORD *)v11 )! N8 ~6 h: W2 W9 @
- v16 = byte_100B2D6E;
! Z% v+ W/ i3 E2 ^9 A' }& N8 c2 Z - v17 = CKContext::CreateObject(a2, 31, v16, 0, 0);
. {( W6 A& i. n9 {! d: g/ _1 m; @ - *((_DWORD *)v11 + 6) = v17;7 B# }% d( y" P% E" i% S3 u) c) t- o
- if ( !(*(int (__thiscall **)(int, int, int, signed int, _DWORD))(*(_DWORD *)v17 + 84))(v17, xRight, yBottom, 32, 0) )
1 {( D" v/ N+ O3 G* | - return 0;
5 `5 x1 |# v* U3 U- M7 O - (*(void (__stdcall **)(int *))(**((_DWORD **)v11 + 6) + 136))(&v58);
; N1 u1 A, H5 k) Z - v18 = CreateCompatibleDC(0);9 o3 o3 d; i9 m& N+ \
- v45 = VxCreateBitmap((const struct VxImageDescEx *)&v58);! W1 I8 x) ?$ k+ f7 I2 y
- v47 = SelectObject(v18, v45);0 S) N9 o% W4 h+ `+ z$ p
- XString::operator=(v11, a3);0 v+ B+ L" `. H' `, A9 D
- *((_DWORD *)v11 + 2) = nNumber;2 E4 a- @' V9 X9 z* A
- v19 = GetDeviceCaps(v18, 90);$ Q" e3 H) |1 n. t; `9 C/ ^/ b6 F) |# ]
- v20 = MulDiv(nNumber, v19, 72);" z# { j, c. c- P( I
- v48 = CreateFontA(-v20, 0, 0, 0, a6, a8 & 1, ((unsigned int)a8 >> 1) & 1, 0, 1u, 7u, 0, a7, 0, (LPCSTR)a4);
* s" X, }7 k; c9 A - v46 = SelectObject(v18, v48);' _& q+ t2 ?3 x& \9 B
- GetTextExtentPointA(v18, "A", 1, &v56);
. o x0 _0 d6 Y1 b - v21 = *((_DWORD *)v11 + 4);5 S1 `! v! m+ y; r' N& l6 ]
- *((_DWORD *)v11 + 3) = v56.cy;( i% e0 U3 u' w" {; ], v! a
- v22 = (char *)operator new(32 * v21);2 Z. h% b+ o6 u+ Q& M
- if ( v22 )
) ^: H6 _/ H: O1 P - {) X; D* K8 N T. m9 u0 y
- v23 = v21 - 1;7 \* l1 H( z: M3 |
- if ( v23 >= 0 )
" N8 P6 N4 U% a* I - {
; R$ o* o/ c% f( X5 E/ q4 V - v24 = (int)(v22 + 12); c) r# ^8 N; Y+ M
- do- Y# |+ `" J, Z" i
- {0 e- [) }1 C0 \2 L/ ]/ K' v
- *(float *)(v24 - 4) = 0.0;. ~) i7 V* \0 c. W# X6 D, h
- v24 += 32;
; r- S- S1 o1 k& c) T: N- t4 P - --v23;; _( I4 X! ]2 b& ^
- *(float *)(v24 - 32) = 0.0;3 ] C5 `( a$ u( @' \ Q6 U
- *(float *)(v24 - 44) = 0.0;
9 w- v1 Z! \4 _) H6 ^ - *(float *)(v24 - 40) = 0.0;) s- S# \9 g% k% G/ t& ]& ~* D* A
- *(float *)(v24 - 36) = 0.0;+ z. K; p4 P" s+ X
- *(float *)(v24 - 32) = 0.0;, O! R2 p: |- R) v
- }
$ z2 F, |$ u/ i/ {" m/ ~ - while ( v23 >= 0 );0 f0 i5 e4 T; U( h/ H
- }
. A6 p, N5 b% h% H - }
4 u! m9 ~( t; ^( i8 b' j - else$ t, v6 {7 o+ w4 ]
- {& c0 o0 \" u/ R. U
- v22 = 0;
; t% b' _7 c* [8 O8 m - }+ ^" D A* \% z/ g
- *((_DWORD *)v11 + 5) = v22;! Z9 k/ W1 | g6 d
- SetRect(&rc, 0, 0, xRight, yBottom);
5 F% X+ E& t$ D - v25 = (HBRUSH)GetStockObject(4);
" b8 k# N' x1 B - FillRect(v18, &rc, v25);7 R$ x5 V$ l' f) Y9 Z
- SetBkColor(v18, 0);. G( q, ~2 w# ]
- SetTextColor(v18, 0xFFFFFFu);7 C! W* M/ B8 L/ J1 k0 U! R' A
- SetBkMode(v18, 1);
9 W& @- d j. I1 a6 Y - v26 = 1;
$ z) C' F }6 K$ P/ L) e - v41 = 1;1 u4 Y$ I6 z, T9 U4 y
- v40 = 0;/ E+ `! s! _$ R8 u' x( c
- v43 = 0;6 b- i5 m* ^, t* o; s& u( i
- if ( *((_DWORD *)v11 + 4) > 0 )
9 M1 D" S( u. G) e& s - {; s% x" L7 _- X9 D- Q! K
- v27 = WideCharStr;2 r; f5 y/ K1 S# s
- v44 = 0;
, W! B4 Y: i8 W, ] - v42 = WideCharStr;9 N3 ~+ b/ [8 B9 E+ W/ p$ [" d* r
- v49 = (double)xRight;
' K) i; n: e* T7 u- |7 `/ ]; ` - v50 = (double)yBottom;
) e+ S% @, p% ^( g - while ( 1 )# u+ r8 ~3 L+ v3 s4 p3 b- x7 n
- {+ _* B! `* J; a" m/ k9 ]' L' s0 V
- v28 = v44 + *((_DWORD *)v11 + 5);% i$ |& @: c J* ]5 W4 T
- *(_WORD *)(v28 + 16) = *v27;
% D( f4 w" p2 G6 e. ?' p5 s - GetCharABCWidthsW(v18, *v27, *v27, (LPABC)(v28 + 20));- l. w) _4 |' j' K# ]# l$ k$ E
- if ( *v42 >= 0x20u )
" P' Q$ v/ U' k0 x4 G4 @* }& Z - {
& {5 B8 p; ^. F: `) j - --*(_DWORD *)(v28 + 20);# S4 w$ T& k3 D) I0 g4 I' p! M
- *(_DWORD *)(v28 + 24) += 2;% O+ e. P6 c0 n& y! K4 i
- --*(_DWORD *)(v28 + 28);9 G/ o+ n8 n& B
- }
$ B' V6 x) I5 V4 y - else% K& \& S* W; U) g
- {
# W) O, `# G5 M$ Q P - *(_DWORD *)(v28 + 20) = 0;
6 D1 T, j' [: D9 n2 i) d! o - *(_DWORD *)(v28 + 28) = 0;. m$ H" y1 r! E: E% ^0 E5 h8 u4 G' m+ n
- }
I; N' s- o* q - v29 = *(_DWORD *)(v28 + 24); U' `( w6 c9 ?: \( G4 j# q% P
- v30 = v40;! a/ b' p4 k5 \( M3 i6 d
- if ( v29 + v26 + 1 >= (unsigned int)xRight )( b$ p$ b! \ F* l
- {6 o4 M% ?1 H- C3 _) M3 ]4 S
- v26 = 1;, a% s8 X; y) {5 V- X. j( N( y/ k
- v30 = v40 + *((_DWORD *)v11 + 3) + 1;
* u4 p- {/ x. L0 D- Q - v41 = 1;: w* c4 P& Y4 l* Q d) ?
- v40 += *((_DWORD *)v11 + 3) + 1;1 ^3 }' l) _6 n6 r0 ^
- }
& `( a- w0 O; C) A, Y/ m, r1 I - *(float *)v28 = (double)v41 / v49;% j( P( O/ A+ W" Z4 B1 x
- *(float *)(v28 + 4) = (double)v40 / v50;
( E* y- c2 E$ N6 l- i9 p4 A - *(float *)(v28 + 8) = (double)(unsigned int)(v26 + v29) / v49;" n8 [$ g( y- g7 ~# I1 s' b
- v31 = v26 - *(_DWORD *)(v28 + 20);& E( n& G$ X! l
- *(float *)(v28 + 12) = (double)(v30 + *((_DWORD *)v11 + 3)) / v50;
" P/ D# i* W& }( E - TextOutW(v18, v31, v30, v42, 1); l# p3 X' t. N g5 V: B6 Q6 z
- v44 += 32;
2 n b. V' B* u' V0 m! @8 O b6 R - ++v42;) o# _+ i8 l3 y
- v33 = __OFSUB__(v43 + 1, *((_DWORD *)v11 + 4));
" F& R- \: G: l0 O0 Z/ j! [2 n. e - v32 = (signed int)&v43[-*((_DWORD *)v11 + 4) + 1] < 0;" O0 U/ ^3 ?2 i2 ~7 ^/ l
- v26 += *(_DWORD *)(v28 + 24) + 1;: N/ j b( D8 H$ M
- v41 = v26;8 h3 r. {3 u. Q* v" G$ W. a
- ++v43;
& b' t# D8 x' N+ R$ k - if ( !(v32 ^ v33) )& `" K+ B X# D! L/ E8 d5 v
- break;
" v) ` ~5 [3 U) y$ Y" l* b - v27 = v42;
* h7 l! X. R3 h0 H- D- { - }
% V8 }. ?. b; F2 N/ w' c! L0 _ - }
4 j* ]; _9 g9 j$ U - v34 = CKBitmapData::LockSurfacePtr((CKBitmapData *)(*((_DWORD *)v11 + 6) + 56), -1);
' y. E+ u" c w, q, Y3 @ - if ( v34 )
3 e' g! Y* ]# n; Z8 | - {
6 N3 k. y1 i) B, P7 g% v$ X7 g" s0 h - GetObjectA(v45, 24, &v51);
- p# P: k+ {4 Z# |! u; o" ?7 r - v35 = v53;
0 {7 E8 l; v' |/ \% F! d - v36 = v55 + v54 * (v53 - 1);8 i+ m- N. K1 H) ]
- v40 = 0;
# c6 V2 O* N" L8 |# e1 q - if ( v53 > 0 )
$ s) o6 | C P9 G9 u - {
( q1 S9 s3 i [ - v37 = v52;9 J" `. A% B# D( G
- do8 ]2 L/ o+ J& e0 {8 I' q
- {8 P0 ?& u/ O+ P" p! Y) c0 E, `
- v38 = 0;- f& N* T6 l: a
- if ( v37 > 0 )# |1 i1 a! }% B; L8 v% o8 \/ U; X
- {$ e" Y( t6 m' ~/ t+ S( C& Y( b5 B
- v39 = (unsigned __int8 *)v36;# K% J" t* _1 N3 E! X$ u
- do+ z; p9 u+ j) G. w
- {
; `9 T3 O( I5 q( T( ^/ i/ y' c0 V - *(_DWORD *)&v34[4 * v38] = (*v39 << 24) | 0xFFFFFF;$ m4 N% L; D( Z. S
- v37 = v52;* x/ O a. a _# _2 o4 p% K8 v
- ++v38;
- \. H# d# U: Q& ]( S" h9 W3 r; U - v39 += 3;
$ X6 ?2 y8 g" W: e; P; D- f - }8 P) K2 ?- U v3 n- O% \) q
- while ( v38 < v52 );
# ?5 q5 r1 A$ s& y2 b8 o% x - v35 = v53;
* W3 W6 C5 _! ? Q$ @( w - }
" C8 E1 X9 d3 f+ R) N# L' H - v36 -= v54;/ O7 q) J9 y8 [6 `. f
- v33 = __OFSUB__(v40 + 1, v35);
8 e2 v- p2 Q8 T, I9 b* |" B - v32 = v40 + 1 - v35 < 0;
% E q0 a8 w9 M" I( e2 a T# V8 C5 r - v34 += 4 * v37;+ D; `% O. F2 D' N& ^; f) }9 B
- ++v40;: h# ]: h3 ?% l8 P
- }3 l6 x" i* h( p1 k7 L2 ~: r) m
- while ( v32 ^ v33 );; X( p; p. [# V+ {. A0 G! G1 U) s& t
- }8 @- w1 T/ A2 Z* H% S
- }# u: ^0 D: H7 T/ h5 p/ U0 M' @
- CKBitmapData::ReleaseSurfacePtr((CKBitmapData *)(*((_DWORD *)v11 + 6) + 56), -1);" i# m1 I2 V0 {# E7 R/ h
- SelectObject(v18, v46);
9 c* k0 i" q( H; O* L1 m6 ^ - VxDeleteFont(v48);& ~! o5 V" f* g$ R2 n
- SelectObject(v18, v47);( `' {3 m% {! O
- VxDeleteBitmap(v45);
5 j: J# \5 l6 C3 T5 I - DeleteDC(v18);
1 z7 Q9 n0 {* R# C# f" p- _ - CKObject::SetName(*((CKObject **)v11 + 6), (char *)a3, 0);
+ Q0 [+ ]! Q p. \3 w' X - CKBitmapData::SetDesiredVideoFormat(*((_DWORD *)v11 + 6) + 56, 1);0 H" X0 ^4 Z |
- (*(void (__stdcall **)(_DWORD))(**((_DWORD **)v11 + 6) + 120))(0);1 R- a" K# p% h) {( }0 I! P& @: r+ a8 }
- return v40 + *((_DWORD *)v11 + 3) < yBottom;# g* {' s8 ^9 f- Q" T/ g0 N
- }$ c3 p: t: }% T* }" W
复制代码 7 e2 { S3 H" q9 R$ C
, M, ~, R! V& Q# b7 d; N
|