本帖最后由 shane007 于 2023-8-26 17:10 编辑
6 T+ U8 Q! Y6 Z8 W1 C: Q+ C! k: ^7 T! _! ^! N1 E% e9 w
这个游戏的主要修改点在\player\BuildingBlocks目录下的Adventure.dll中。
! ~2 K3 C/ R8 W; K+ F用API monitor对本DLL的CreateFontA函数进行跟踪,发现确实有调用, 参数如下。
7 d3 z: r# |$ H) j; I9 K; G$ ]0 m" j g: U, ~0 q0 j, V
- # Type Name Pre-Call Value Post-Call Value/ F( C2 F. r& D9 r l- s* E
- 1 int nHeight 0xfffffff0 0xfffffff0/ e Z, V; W: N( ^
- 2 int nWidth 0x00000000 0x00000000
& g2 B# v% S1 u8 M' D1 r* |1 g- P - 3 int nEscapement 0x00000000 0x00000000
9 G+ c- B( N( m - 4 int nOrientation 0x00000000 0x000000004 ^ a( k* f5 K
- 5 int fnWeight FW_NORMAL FW_NORMAL
: Z2 V! o) j4 ^; k0 I/ i7 k - 6 DWORD fdwItalic 0x00000000 0x000000003 y1 |# B4 D$ h" S! M \! v
- 7 DWORD fdwUnderline 0x00000000 0x00000000: q5 U/ x/ n& |
- 8 DWORD fdwStrikeOut 0x00000000 0x00000000
+ H% f1 R2 l; t' F; M$ `! t - 9 DWORD fdwCharSet DEFAULT_CHARSET DEFAULT_CHARSET
& m# l0 g) K/ o" M - 10 DWORD fdwOutputPrecision OUT_TT_ONLY_PRECIS OUT_TT_ONLY_PRECIS
8 Y/ G. a2 G J9 k/ {: g" m- B# x - 11 DWORD fdwClipPrecision CLIP_DEFAULT_PRECIS CLIP_DEFAULT_PRECIS* T) s! N" r ]" v% J; B: \
- 12 DWORD fdwQuality PROOF_QUALITY PROOF_QUALITY
! ?. B. P* W p5 S6 ~2 g+ Z - 13 DWORD fdwPitchAndFamily FF_DONTCARE | DEFAULT_PITCH FF_DONTCARE | DEFAULT_PITCH
6 Y! {6 X" S- U! R, V7 {5 ]# q; i - 14 LPCTSTR lpszFace 0x09148a58 "Arial" 0x09148a58 "Arial"
3 {4 r& K. E( {4 A
复制代码 8 {# a8 o: `: s" t- R5 I3 r
) c: m) j# {! J& M D
用ida pro找到调用CreateFontA的源头函数如下。
5 n4 u# m' K$ {) b; Q从函数的参数可以看出,这应该就是字幕显示函数了。
3 z$ g1 a2 Z5 y1 w3 T" t- s关于后续修改,先修改CreateFontA函数的fdwCharSet,lpszFace这2个参数,也许就能出中文。
, _5 a# N! N$ O2 H- c* ?. l, D0 S还不行的话,就自己写一个显示函数。以下函数中lpMultiByteStr就是指向字幕的指针。
& u+ Q$ h5 d- G: H8 J$ `- 1 E; v3 W9 e6 ?: k# L. s n0 R
- 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)4 c- @9 W X" i4 B" |! p2 @6 u
- {
( j$ U5 b- K2 P4 G! L: O - void *v11; // edi
- K: o. g' Z" a" Y5 T7 n - int v12; // eax' P* b& m; r' f" P
- int v14; // ecx- v& P E, _. B) {4 N
- int v15; // eax
0 h+ I3 L% ~# c# y3 M - char *v16; // eax" J" b$ Q& p B( O
- int v17; // eax4 L8 n! P, C( ?4 C1 J4 g
- HDC v18; // ebp
. c3 ~7 V: u' X) v) m) _* R - int v19; // eax4 r- v: w. m3 y9 V$ U
- int v20; // eax
5 r' Z* I$ D+ O. Z - int v21; // esi
2 |! q* z: {9 S8 { j# H5 E- M: ? - char *v22; // eax
* O+ t( {! `- `6 E+ M - int v23; // esi! A7 g/ c& v1 E; o) T! n
- int v24; // ecx
% l. {4 E8 p$ o# B4 _ - HBRUSH v25; // eax. ]: Y6 K( S! D; i9 z7 g/ f5 K, f
- signed int v26; // ebx
3 X o$ s8 k7 I0 b - WCHAR *v27; // eax) T" s* X3 E; J7 s- J
- int v28; // esi
- A: Z& V! \: \ - int v29; // ecx& \7 c: ]" |( y* k5 h
- int v30; // eax5 Y) C& D& g: }) ^/ Y0 X7 F# I
- int v31; // ST28_4
0 \: J/ H% X5 D- O3 z4 I6 a1 t - bool v32; // sf
4 c5 C9 O- \) B+ b - unsigned __int8 v33; // of8 L# H4 N6 z' }4 M( }: k7 F D
- unsigned __int8 *v34; // ebx
' Q" C! D$ b$ g h y# R - int v35; // ecx
0 B) e0 V9 ]% l! |; v - int v36; // esi. A& l9 u% ?0 i* }2 k4 M
- int v37; // edx
/ N$ w. t- g+ K! }# X% V4 U% Z - int v38; // eax- }- B9 \2 s: e$ {
- unsigned __int8 *v39; // ecx
" B8 q) L3 h8 s# i7 q9 T/ w5 L - int v40; // [esp+40h] [ebp-2098h]
+ o) E! \7 R6 }' P9 o) a) [ - signed int v41; // [esp+44h] [ebp-2094h]. ] u9 u5 N. q! k* e
- WCHAR *v42; // [esp+48h] [ebp-2090h]! c+ G ~2 m. Q$ H
- LPCSTR v43; // [esp+4Ch] [ebp-208Ch]" r$ X* g8 ]( N
- int v44; // [esp+50h] [ebp-2088h]5 ^2 T9 p7 s) K- |
- HGDIOBJ v45; // [esp+54h] [ebp-2084h] l2 c+ R- |7 T( f t: N
- HGDIOBJ v46; // [esp+58h] [ebp-2080h]
, U+ S8 F4 ^% y0 E% k8 p - HGDIOBJ v47; // [esp+60h] [ebp-2078h]9 O; k' t% R! r" t8 i/ L
- HFONT v48; // [esp+64h] [ebp-2074h]
- t4 h* ?- V# E0 G& S& k' f - float v49; // [esp+68h] [ebp-2070h]6 @: V- h. r" l
- float v50; // [esp+6Ch] [ebp-206Ch]
5 E/ C' Y! H1 Z# {+ c - char v51; // [esp+70h] [ebp-2068h]9 w2 c# Z, g& Q8 B
- int v52; // [esp+74h] [ebp-2064h]5 p/ f7 F+ x; ~2 S" x
- int v53; // [esp+78h] [ebp-2060h]
, r* K+ F" ^( J1 G& c1 B - int v54; // [esp+7Ch] [ebp-205Ch]0 M7 U6 ]* ^- D4 H1 Z
- int v55; // [esp+84h] [ebp-2054h]' r" K* A% s: n
- struct tagSIZE v56; // [esp+88h] [ebp-2050h]! I5 f H' p) i7 [1 R
- struct tagRECT rc; // [esp+90h] [ebp-2048h]; [2 K% Q. N1 S6 X* }0 J
- int v58; // [esp+A0h] [ebp-2038h]( l9 Q: V. ]1 p6 B# F) F1 S
- char v59; // [esp+A4h] [ebp-2034h]* V2 D' t/ N+ U
- WCHAR WideCharStr[4096]; // [esp+D4h] [ebp-2004h]+ W) K# v- b( x0 t- L4 r4 j" m+ Y& w
- $ A! D1 \4 d4 c
- v11 = this;
& C- M% h0 a/ ^6 K! a" e - v58 = 52;( i/ W, f+ @' [- h, R' _
- memset(&v59, 0, 0x30u);5 W; f3 b9 z# y- K9 E. L
- if ( *lpMultiByteStr )
$ V- A+ A3 Y/ U- c - {$ G8 {# h/ S B
- v12 = MultiByteToWideChar(0xFDE9u, 0, lpMultiByteStr, -1, WideCharStr, 4096);$ s: ?* s- _* ^ B9 z2 J6 C4 Q
- *((_DWORD *)v11 + 4) = v12;
5 o% j8 _8 r$ m - if ( v12 <= 1 )
1 f9 g, a4 e: i& ]. ]/ v( F: y - return 0;# L9 C, y( q: x( O M: Q8 ^1 a: G
- *((_DWORD *)v11 + 4) = v12 - 1;
" O" Q; h+ G1 T8 { - qsort(WideCharStr, v12 - 1, 2u, sub_10057A40);
" Y) |0 p) y1 o$ C7 b6 t5 p - }" l& L6 P: Z5 K
- else
: g0 d* V% y8 S' [6 \! ^ - {
2 C$ c+ ~# d8 _, _! K6 j' ^7 x% ~ - *((_DWORD *)v11 + 4) = 352;: i: k" C8 _0 E9 N8 ]! l6 A; w
- v14 = *((_DWORD *)v11 + 4);
" l K$ r2 q+ [, A/ f; e - v15 = 0;8 e, `/ [( D( P4 Q7 T
- do
* P0 }1 |4 |: ?5 @( {' E - {
7 D6 O; `5 [2 N' q: m - WideCharStr[v15] = v15 + 32;+ P: e: E( y0 W
- ++v15;1 `/ f! B3 `6 g; }% f
- }
( C+ K, j* k* E) ~1 { - while ( v15 < v14 );4 S+ f D B$ {, x
- }4 C- X/ ]2 r# ? r
- v16 = *(char **)v11;
; E9 M* ~( x R$ _( m4 ]+ U+ ` - if ( !*(_DWORD *)v11 )
: Y* H% r: i- H, s6 J0 v - v16 = byte_100B2D6E;7 F1 r9 F% P; g! d5 F7 S' F' }/ y
- v17 = CKContext::CreateObject(a2, 31, v16, 0, 0);& N7 r( T. g5 U3 t8 F# x
- *((_DWORD *)v11 + 6) = v17;
+ W: Z6 F [$ \ - if ( !(*(int (__thiscall **)(int, int, int, signed int, _DWORD))(*(_DWORD *)v17 + 84))(v17, xRight, yBottom, 32, 0) )0 k6 t" x" X* ]) V
- return 0;
3 [* o" e8 i. ^6 r: { - (*(void (__stdcall **)(int *))(**((_DWORD **)v11 + 6) + 136))(&v58);- U" y7 W9 G( X) Y
- v18 = CreateCompatibleDC(0);
: n6 [5 p# f7 ~' [4 ]2 `6 C+ ^ - v45 = VxCreateBitmap((const struct VxImageDescEx *)&v58);
; \0 }( ?, P$ q% F: g* D - v47 = SelectObject(v18, v45);
: D" Q2 _( z- ]/ w8 u - XString::operator=(v11, a3);" H& H6 y4 E* j; L# K) I$ {, Y
- *((_DWORD *)v11 + 2) = nNumber;& T# {% |6 M$ d8 H! ~
- v19 = GetDeviceCaps(v18, 90);% B& O) |: |$ k3 @: p6 H
- v20 = MulDiv(nNumber, v19, 72);
/ U8 M- \2 S# r3 P - v48 = CreateFontA(-v20, 0, 0, 0, a6, a8 & 1, ((unsigned int)a8 >> 1) & 1, 0, 1u, 7u, 0, a7, 0, (LPCSTR)a4);2 x3 k3 N+ k( Z+ W" b7 b& t% X7 L
- v46 = SelectObject(v18, v48);
* G" w- c% W) J - GetTextExtentPointA(v18, "A", 1, &v56);1 I# ]$ d% M- A G9 d# |+ l
- v21 = *((_DWORD *)v11 + 4);2 q! l, ^; f+ G* e/ a5 _/ X- [
- *((_DWORD *)v11 + 3) = v56.cy;
9 w& X2 U* e6 y X6 j - v22 = (char *)operator new(32 * v21);
9 }& K* ~1 M; ]0 Z( D - if ( v22 )
) m7 @. L% N { j' O6 D+ K - {# _1 M. T; W |- K/ B" W) ~
- v23 = v21 - 1;
, p& w+ n9 J3 X3 ^# y- M) p - if ( v23 >= 0 )
/ G1 C( [# z& s" G5 q3 g4 }, z- t - {
* @! `- C! ]1 X- i3 A0 }* E - v24 = (int)(v22 + 12);, U3 W b5 c- j3 r; O1 j
- do7 l* M# k+ B% s* r- M
- {% C/ n/ e# Q: U: p( r
- *(float *)(v24 - 4) = 0.0;0 g- C+ R( @1 ? p1 E% [* ^
- v24 += 32;
# G- |5 A& ~7 `. Z6 E - --v23;
; f1 ]$ r/ j3 F% b - *(float *)(v24 - 32) = 0.0;
: f9 p- l/ L B. e3 D - *(float *)(v24 - 44) = 0.0;
; c6 {6 z) f3 G1 j% a - *(float *)(v24 - 40) = 0.0;
2 n( X) Z, L! Z; p - *(float *)(v24 - 36) = 0.0;8 \) | \, ^2 M0 o: M* `5 o9 Z) v
- *(float *)(v24 - 32) = 0.0;" ]* N. I6 z# T! n: z
- }$ |1 v0 U5 i$ D5 U6 o1 u7 I
- while ( v23 >= 0 );8 n% Z- X; H1 J$ B3 L
- }
! O1 [# P. U m G/ k8 i7 {! f - }7 w1 x" }1 Z+ O
- else! s6 u3 e v* F* u
- {
4 z" ^7 e2 u M3 [ N - v22 = 0;
3 \% O% ]& G: z$ D! w6 g - }/ ?" v; z! z8 c8 T
- *((_DWORD *)v11 + 5) = v22;9 k9 O7 d* |3 D
- SetRect(&rc, 0, 0, xRight, yBottom);; M) Z5 K2 K+ U2 m( \; t \
- v25 = (HBRUSH)GetStockObject(4);
- y i C+ q+ n9 j4 H* Q - FillRect(v18, &rc, v25);
$ U8 u7 | o O3 `" `6 s - SetBkColor(v18, 0);
" }6 a" \$ L/ ` - SetTextColor(v18, 0xFFFFFFu);9 {5 P( X6 [/ J6 F
- SetBkMode(v18, 1);3 G: J: a3 @, ]; |
- v26 = 1;3 n2 n& b1 R- m2 u6 x& o
- v41 = 1;
1 ?" T! U2 u' u' }1 p- d4 g) V% h& h - v40 = 0;' p7 [+ n/ ]# p- Y) L4 m
- v43 = 0;
( `: ^; {. E% ]9 E - if ( *((_DWORD *)v11 + 4) > 0 )
' _1 I5 M! O& S# _* j# M - {
8 d7 }0 Z$ M+ U9 L# g! R$ N4 z - v27 = WideCharStr;
0 b6 W1 V& L4 y/ o' l( s: ] - v44 = 0;
1 I* N$ x: Z3 [9 ]8 E4 ^# L, H - v42 = WideCharStr;
# `+ _6 V, F" a! w: `0 Y+ y - v49 = (double)xRight;
4 G" g( \6 f* \7 E" p - v50 = (double)yBottom;. r& B! n) v4 w7 {: V4 A
- while ( 1 )
; H& e% G$ U7 Y* m! }+ b - {2 `+ l/ R* B% Y/ I$ l
- v28 = v44 + *((_DWORD *)v11 + 5);# H/ [) k. B" O) C8 j l
- *(_WORD *)(v28 + 16) = *v27;
, X; x5 b$ e N5 W - GetCharABCWidthsW(v18, *v27, *v27, (LPABC)(v28 + 20));
8 W1 j" `* w( p, z3 E - if ( *v42 >= 0x20u ). H' E* k7 E* y( H
- {9 ^* u8 ^" a2 X: h& A0 X
- --*(_DWORD *)(v28 + 20);
& ~" Z0 u' v0 f. U# i5 t; ~ - *(_DWORD *)(v28 + 24) += 2;0 G, ?2 }* o" I. {+ X! ^, V+ Z
- --*(_DWORD *)(v28 + 28);- D2 W$ v n* { [: j
- }
& M! Z" H2 {# ]6 ^9 r - else
1 ?; ^$ i, W$ h - {
4 _8 \9 z- I, i - *(_DWORD *)(v28 + 20) = 0;5 s$ b) A% ~9 I+ e
- *(_DWORD *)(v28 + 28) = 0;
8 J4 Y- i" n% @" B' S. p - }. v/ ~- O7 e. Z+ |
- v29 = *(_DWORD *)(v28 + 24);% g' \! g9 v' P7 @ C) w
- v30 = v40;
# \: R& u' d. j6 e9 e. u0 s$ Z. s - if ( v29 + v26 + 1 >= (unsigned int)xRight )
* A& o% X; j1 [* b5 O% @ M+ ^ - {0 n6 Z; d. ?+ A5 x0 p& E6 E/ K
- v26 = 1;
( |" P5 N h9 _% Y$ x% k0 A" p# I! o - v30 = v40 + *((_DWORD *)v11 + 3) + 1;
5 `: ?1 j% y0 o% w! k - v41 = 1;6 ~/ C4 r% @! B& T1 f9 Z" i
- v40 += *((_DWORD *)v11 + 3) + 1;/ s1 Y- a2 `( o2 E# P' `
- }. j& g% j! }. j# n$ c2 h+ ^- m5 z
- *(float *)v28 = (double)v41 / v49;
. q1 I/ j- [8 Z+ b8 Y - *(float *)(v28 + 4) = (double)v40 / v50;
/ G0 h- f( t/ a2 b" q9 D% `7 v - *(float *)(v28 + 8) = (double)(unsigned int)(v26 + v29) / v49;4 M: J% u8 |4 D) J4 Y& |3 S: b
- v31 = v26 - *(_DWORD *)(v28 + 20);
7 r: ]0 C( l, x O$ P& T( W - *(float *)(v28 + 12) = (double)(v30 + *((_DWORD *)v11 + 3)) / v50;
0 U8 a$ V0 E6 t( S; C/ [ - TextOutW(v18, v31, v30, v42, 1);
( B8 E# N# G2 L2 a$ E - v44 += 32;, m# \2 v7 k/ w3 h% f$ a! b' E
- ++v42;& O/ ~8 ^5 Q2 A4 e# }0 w; C) s
- v33 = __OFSUB__(v43 + 1, *((_DWORD *)v11 + 4));
" h1 F; N- w3 {1 n6 F1 B3 D - v32 = (signed int)&v43[-*((_DWORD *)v11 + 4) + 1] < 0;% }+ L" i6 Q: Z
- v26 += *(_DWORD *)(v28 + 24) + 1;. F1 |0 r/ X+ ]# t J! p9 p) G( [9 e, D
- v41 = v26;
, r9 c/ g' C- W5 s" i - ++v43;
( G1 K% _$ c1 s; K) k - if ( !(v32 ^ v33) )( c/ s7 V% h4 N3 }& C) F
- break;, D2 \# [) |" y& Q" D4 U
- v27 = v42;
: Q7 r# ?8 H5 b0 @' Z - }
' O8 T5 [8 H! x8 A$ [5 N! G3 @9 d - }- f# g; s; j& K4 K% Q
- v34 = CKBitmapData::LockSurfacePtr((CKBitmapData *)(*((_DWORD *)v11 + 6) + 56), -1);8 |$ V- X, [6 c* W( G* E. t4 r) e1 X. R
- if ( v34 )- o# U- t/ H% I# q/ i& b. n/ c8 n
- {8 t+ ^6 }( R2 i5 s
- GetObjectA(v45, 24, &v51);7 o! T0 [( b; l; S* b
- v35 = v53;
, O" A {, A9 W7 B* Q& q - v36 = v55 + v54 * (v53 - 1);$ k4 D8 f* C- m
- v40 = 0;: \+ `% c3 m% e0 R
- if ( v53 > 0 )
+ @" G, S- j+ P - {( k& p' _) Z8 G1 M2 S
- v37 = v52;9 t2 @" t( e3 S/ s' e3 L
- do: G+ ?! w" v( [# V/ b
- {
7 u+ i3 E8 R% i+ h& o - v38 = 0;; {4 g9 Q. `& a% m
- if ( v37 > 0 )6 P. m0 t4 y1 ]4 \4 M X3 Q8 Q3 X) |
- {: u0 @+ u0 ?$ p% a l- l
- v39 = (unsigned __int8 *)v36;' l( t; J* p; {2 d, @& D% d- `+ d. F
- do
6 j3 R/ r. { w - {
6 V k" ]$ A. i/ @. P - *(_DWORD *)&v34[4 * v38] = (*v39 << 24) | 0xFFFFFF;8 V: L2 W$ n/ J7 O
- v37 = v52;
% }, v' f2 L$ {1 Z. n; L8 {% S - ++v38;5 a0 g. c' r! i+ j
- v39 += 3;
" [* u3 T* u/ L6 ]+ W u - }
. S, q" p4 j. ?$ b% K* N9 W - while ( v38 < v52 );
$ y1 m7 a) T' U9 W; T - v35 = v53;9 l# o' s% u1 v; G* `8 H1 w: H
- }% P$ s% h# R; x! R( I2 K
- v36 -= v54;8 q3 u2 ^3 J3 t5 M+ p
- v33 = __OFSUB__(v40 + 1, v35);
% L$ `2 |& G0 F! n. B - v32 = v40 + 1 - v35 < 0;
5 M1 Z! J4 D7 `* q$ p% a) ? - v34 += 4 * v37;
$ W4 R$ @0 h- K - ++v40;
: b. F9 @$ f8 Q0 Q* ?3 B - }
3 D2 d1 \! F& ^9 F" @. @ - while ( v32 ^ v33 );
6 s3 n9 Q2 ?2 H6 R1 N - }1 q/ ?! X7 x+ z4 O5 `
- }
" f! _4 I9 o4 q2 | - CKBitmapData::ReleaseSurfacePtr((CKBitmapData *)(*((_DWORD *)v11 + 6) + 56), -1);# h ]. \& _4 [0 D9 ]9 ~* w
- SelectObject(v18, v46);
" r( a' A9 R! [/ [3 ^! l2 d* W4 R" A - VxDeleteFont(v48);
3 I( E& S+ c/ V$ g - SelectObject(v18, v47);
/ j. y+ S% }5 b! h. d - VxDeleteBitmap(v45);
( k" ]8 n1 k) q1 E" v" \: b - DeleteDC(v18);+ ?, U B; a+ S/ h' N @; m( \( I
- CKObject::SetName(*((CKObject **)v11 + 6), (char *)a3, 0);, q4 o8 i) m9 d$ I% n. j
- CKBitmapData::SetDesiredVideoFormat(*((_DWORD *)v11 + 6) + 56, 1); m. S4 G3 N' @) P6 M* Y1 I2 t& _1 R4 l
- (*(void (__stdcall **)(_DWORD))(**((_DWORD **)v11 + 6) + 120))(0);
9 w O+ Q' [4 a* ^ - return v40 + *((_DWORD *)v11 + 3) < yBottom;% Y6 m5 n/ e; I+ Q6 ~
- }$ n! e8 U7 O# e+ K
复制代码 5 N5 U4 S4 m5 O! F2 e
' u* w, b3 _5 j9 A. `( N7 n8 Z |