本帖最后由 shane007 于 2023-8-26 17:10 编辑
! N; e, Y& G$ b$ v7 n, O# B" Q2 @
* H1 n! k4 j5 L& t% i" s这个游戏的主要修改点在\player\BuildingBlocks目录下的Adventure.dll中。
1 [) b! w* c- R3 X$ [( U" o" c. |用API monitor对本DLL的CreateFontA函数进行跟踪,发现确实有调用, 参数如下。
) y& I, i: S- m9 C' I7 A, U. ]& u4 @
- # Type Name Pre-Call Value Post-Call Value
2 `7 T+ E; s, ^6 E0 { - 1 int nHeight 0xfffffff0 0xfffffff08 S$ T; E! Z- Q1 n
- 2 int nWidth 0x00000000 0x000000009 G- w% N4 x1 H% q1 w* B* z) r4 I
- 3 int nEscapement 0x00000000 0x00000000% a3 C: i$ O+ B" R% g( C% d
- 4 int nOrientation 0x00000000 0x00000000
; s2 B/ W# D) W' z* ^ - 5 int fnWeight FW_NORMAL FW_NORMAL
& \0 c" }4 L j' K% j8 s3 F - 6 DWORD fdwItalic 0x00000000 0x00000000) J* |! ?, S }4 F p: a) [; u+ n& q3 E
- 7 DWORD fdwUnderline 0x00000000 0x00000000
9 q5 M d4 y7 X7 @5 L% I - 8 DWORD fdwStrikeOut 0x00000000 0x00000000
% m/ p6 }' u: r0 I - 9 DWORD fdwCharSet DEFAULT_CHARSET DEFAULT_CHARSET$ P, |( n. S2 |) {: d9 N
- 10 DWORD fdwOutputPrecision OUT_TT_ONLY_PRECIS OUT_TT_ONLY_PRECIS+ p. {% P* {# }3 t4 |/ [" ~4 Y
- 11 DWORD fdwClipPrecision CLIP_DEFAULT_PRECIS CLIP_DEFAULT_PRECIS
% c$ e5 Q) U V* P& x+ \; h - 12 DWORD fdwQuality PROOF_QUALITY PROOF_QUALITY' H- t f9 i, X+ ]7 l+ W- | l
- 13 DWORD fdwPitchAndFamily FF_DONTCARE | DEFAULT_PITCH FF_DONTCARE | DEFAULT_PITCH
9 W& ~: z! y( E' p - 14 LPCTSTR lpszFace 0x09148a58 "Arial" 0x09148a58 "Arial"2 r( b" F4 e0 V( b% L/ v
复制代码 ) K; z/ i1 R* X. D: G
$ P% w: W$ A: @; B4 i# z* Z
用ida pro找到调用CreateFontA的源头函数如下。$ c1 C1 ~* F! m1 E
从函数的参数可以看出,这应该就是字幕显示函数了。3 u# f$ y) X. ~& c2 t
关于后续修改,先修改CreateFontA函数的fdwCharSet,lpszFace这2个参数,也许就能出中文。( ]# h+ F" G7 ~. a7 w
还不行的话,就自己写一个显示函数。以下函数中lpMultiByteStr就是指向字幕的指针。
1 T) O8 M2 U% n+ X9 y2 T4 M4 M- ! q$ T3 N3 r" O; u
- 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+ c. T; b( B& J: {
- {
" z& C: L. k; N2 n - void *v11; // edi
$ k3 I4 w% K/ P - int v12; // eax& \0 p9 ]1 v2 H d# _( m8 o) V
- int v14; // ecx
- Q" j6 D% V8 b+ K" n: _ - int v15; // eax
$ D( y! Z U$ u - char *v16; // eax4 Z5 R# L# z$ w8 A1 U
- int v17; // eax
3 y$ u. |9 K" s& t - HDC v18; // ebp
: T1 n: Q* _; z$ V0 o - int v19; // eax
: T) [) R9 s* u0 ]% r' \3 v& O* T - int v20; // eax
2 W2 J$ p y* f/ V3 b - int v21; // esi" N5 m. Q0 x% _! I5 _) i! A
- char *v22; // eax
/ h- s2 r- ` T9 a: Q" ^ - int v23; // esi9 l4 J8 |; G3 @9 j+ v
- int v24; // ecx |9 E$ z3 K4 l) \5 ^/ E5 Q8 J
- HBRUSH v25; // eax! Q. _7 ?' B, z. _ @$ F
- signed int v26; // ebx
$ }* e% M/ E$ f& z( s% Q - WCHAR *v27; // eax6 R6 j) J9 _7 P3 y
- int v28; // esi
: Y0 d/ J% o- Z4 o' T! _ - int v29; // ecx5 G. B! k" V5 X* X
- int v30; // eax
& [6 c5 e, c! ^7 ` - int v31; // ST28_4$ S; Z; `4 T3 L( C% \1 \
- bool v32; // sf" p4 }' i4 ^! n" \% U- \
- unsigned __int8 v33; // of6 V9 k, T: W6 `0 l o
- unsigned __int8 *v34; // ebx
/ O ^# A) M' r7 v v% m0 G - int v35; // ecx; @# W- ~# F" d6 h
- int v36; // esi
6 O3 I/ G+ G: [1 K" ^: S* j+ e* e! ? - int v37; // edx
& m- S& C W! e5 @6 h, E( V G - int v38; // eax
3 O6 _. l2 K, I9 G' c$ s; k! L- b. ^ - unsigned __int8 *v39; // ecx
3 d, J3 v0 s: P. T1 i$ h0 { - int v40; // [esp+40h] [ebp-2098h]
. |" Q# g; ^# I+ }- a' O) [ - signed int v41; // [esp+44h] [ebp-2094h]% k& \" M) T4 a4 Z- s" o
- WCHAR *v42; // [esp+48h] [ebp-2090h]/ y: N2 G0 s9 h* w$ M. o
- LPCSTR v43; // [esp+4Ch] [ebp-208Ch]
5 u4 `* o* \3 S& f" @8 e2 ] - int v44; // [esp+50h] [ebp-2088h]! ]. z M: B/ _7 r
- HGDIOBJ v45; // [esp+54h] [ebp-2084h]
/ E5 o F5 {5 ` P7 u - HGDIOBJ v46; // [esp+58h] [ebp-2080h]
* q& q2 i+ G. Y8 b - HGDIOBJ v47; // [esp+60h] [ebp-2078h]0 Y6 c( n0 l, [- S9 e
- HFONT v48; // [esp+64h] [ebp-2074h]" ]. u% m' z" [* { C; [
- float v49; // [esp+68h] [ebp-2070h]' p! h5 J: ?- [- U7 Q7 _
- float v50; // [esp+6Ch] [ebp-206Ch]) a: d) p: ]: j6 a
- char v51; // [esp+70h] [ebp-2068h]6 j/ U8 s, p/ X/ ?
- int v52; // [esp+74h] [ebp-2064h]4 M, B8 a( M5 Q
- int v53; // [esp+78h] [ebp-2060h]
0 t( }& n, S" a# M- S& n - int v54; // [esp+7Ch] [ebp-205Ch], W3 k" u# M7 w ]% J8 R# W
- int v55; // [esp+84h] [ebp-2054h]
3 [7 j+ g$ n6 F/ ` - struct tagSIZE v56; // [esp+88h] [ebp-2050h]/ F3 T2 j: ], g ?
- struct tagRECT rc; // [esp+90h] [ebp-2048h]3 G" u* W; i, `3 A2 q
- int v58; // [esp+A0h] [ebp-2038h]: {! k% O9 `; U/ ]* \0 i
- char v59; // [esp+A4h] [ebp-2034h]
$ U) c2 [! h5 i; y - WCHAR WideCharStr[4096]; // [esp+D4h] [ebp-2004h]- x& x! x3 p. h( T6 v/ e, O$ A% b1 J
4 B, n& H- p7 O, T, h- v11 = this;4 Q( c9 x( B1 b X7 O+ w: q
- v58 = 52;- i$ _- d8 W, y; k: {# ?
- memset(&v59, 0, 0x30u);+ X, _& q2 a- s- ~1 |
- if ( *lpMultiByteStr )
`* `$ L5 H q. f3 Q7 w/ f - {: T* H9 a; `' T% V; t1 B
- v12 = MultiByteToWideChar(0xFDE9u, 0, lpMultiByteStr, -1, WideCharStr, 4096);
: A6 v7 P7 P" L# o - *((_DWORD *)v11 + 4) = v12;2 R* F3 H: E4 M0 Z+ J; Z7 n
- if ( v12 <= 1 )
2 p+ T6 ?! K8 h P - return 0;
5 i) \6 }0 U2 e: _: m - *((_DWORD *)v11 + 4) = v12 - 1;: v) ^' `5 R9 J6 }6 I: H ]
- qsort(WideCharStr, v12 - 1, 2u, sub_10057A40);/ x% ?" K8 W1 M7 k! }2 D$ A5 K) z
- }8 l% d- S/ \+ D. X, i
- else- q% o4 {: K n) g
- {
( j: t' V" K* Q A' C% u; N - *((_DWORD *)v11 + 4) = 352;. F% h1 H; \0 b4 k3 y1 r( L& ^
- v14 = *((_DWORD *)v11 + 4);
3 P+ \. F: ~: q! c' W - v15 = 0;: P4 s. j: A% }1 m- d) B: Z" A
- do. i% O' \ M* e0 ]. @" g
- {9 b; Z' |$ H7 D8 X
- WideCharStr[v15] = v15 + 32;
! b7 {2 M1 y& v" T# O1 u6 M4 K - ++v15;
, x- y% Z% e7 ?( K' `1 A - }% Z9 ]# P4 t* n2 ]7 k! c2 F
- while ( v15 < v14 );/ {: K( Q0 k; {3 L3 `. J
- }0 h$ m: M: k6 @' [/ q0 Y
- v16 = *(char **)v11;
! {. x- {3 R# c8 K - if ( !*(_DWORD *)v11 )8 D ~" R6 b6 X, u1 f
- v16 = byte_100B2D6E;
l) k( N0 b0 T' y1 l. d - v17 = CKContext::CreateObject(a2, 31, v16, 0, 0);- S- S1 e& k0 d2 w& A7 d
- *((_DWORD *)v11 + 6) = v17; ]; ?* n( o5 i0 f+ ~, |! ?9 K
- if ( !(*(int (__thiscall **)(int, int, int, signed int, _DWORD))(*(_DWORD *)v17 + 84))(v17, xRight, yBottom, 32, 0) )7 r* I& {. S4 [
- return 0;- M% t, h1 V& L8 i) S+ I6 V
- (*(void (__stdcall **)(int *))(**((_DWORD **)v11 + 6) + 136))(&v58);; l0 b8 B0 \2 z# Q
- v18 = CreateCompatibleDC(0);/ m. f5 o6 \2 u& v, ^/ h/ o( v% k7 C
- v45 = VxCreateBitmap((const struct VxImageDescEx *)&v58);/ k7 D1 B5 M, A& Z; X+ x* C
- v47 = SelectObject(v18, v45);0 g: h5 {, c* Z9 m$ H# s; ~
- XString::operator=(v11, a3);9 V! A, ~7 J/ r! }# }, }* k
- *((_DWORD *)v11 + 2) = nNumber;
- u5 V* r3 Y3 d; w) i - v19 = GetDeviceCaps(v18, 90);
- L9 s, G5 A# u- Z4 l - v20 = MulDiv(nNumber, v19, 72);
" j4 [0 f5 J1 S! I7 m! z; e4 E - v48 = CreateFontA(-v20, 0, 0, 0, a6, a8 & 1, ((unsigned int)a8 >> 1) & 1, 0, 1u, 7u, 0, a7, 0, (LPCSTR)a4);
& ~7 |1 A# j$ N+ W! B - v46 = SelectObject(v18, v48);
; R5 B6 F. V+ U: E% v& ^ - GetTextExtentPointA(v18, "A", 1, &v56);
- N4 w- _( A, D, w, t/ \( | - v21 = *((_DWORD *)v11 + 4);9 f3 [$ Z- y4 d4 @/ C8 {% G
- *((_DWORD *)v11 + 3) = v56.cy;
, E! \( i: p% H* s - v22 = (char *)operator new(32 * v21);' T- V& _) B, ]* ^8 f9 B
- if ( v22 )' }% h y4 n7 a5 Y, y& k0 |
- {
) e5 x# v* ], N" L - v23 = v21 - 1;) N+ l2 Q+ B8 |8 ~
- if ( v23 >= 0 )2 w" C; p6 b) \0 n! X, e
- {
% S) L+ [2 H* v% ? - v24 = (int)(v22 + 12);8 ], _& p! |4 m; J( ~) @1 }) e# N
- do
2 s2 }. c- C7 r I" ?+ Q - {
) T: Q3 X: F( T" i - *(float *)(v24 - 4) = 0.0;
2 Y x% p- y# V6 P( h8 k - v24 += 32;
y; E: I+ k" r% {; ^ - --v23;1 R. K. L% `" `" P: O' R* V) D) v
- *(float *)(v24 - 32) = 0.0;
/ F3 O0 M, q0 }7 c/ a1 a5 h - *(float *)(v24 - 44) = 0.0;
6 Z) _$ C& d7 C5 `5 K9 j! S d - *(float *)(v24 - 40) = 0.0;% Y2 \; S% k0 K8 t. P2 T
- *(float *)(v24 - 36) = 0.0;
9 }0 E7 d) t7 s9 ]& D - *(float *)(v24 - 32) = 0.0;0 U( j9 _9 c0 R
- }
1 B: _, Z4 G7 e+ z# T" L8 E) f; [ - while ( v23 >= 0 );
: o- d+ M. W# M2 b- y! { - }
" q. X9 t0 `# u) o0 J" \8 m' A# p - }
4 t' I1 n- a$ A9 B; j - else
7 G2 _) D7 p3 F0 \: T3 ?( V2 I - {$ l- S1 r! L! s. R+ A1 n# |
- v22 = 0;
! ]$ S4 @. W5 U" ?' [) E+ L% j& b - }
4 X1 ^3 w; q1 r4 ] - *((_DWORD *)v11 + 5) = v22;4 J- `# M9 E: q4 V" Q& o
- SetRect(&rc, 0, 0, xRight, yBottom);+ j' d2 g- i( w
- v25 = (HBRUSH)GetStockObject(4);
$ P7 i" |; i, B0 P- N* e/ b3 s( f - FillRect(v18, &rc, v25);
1 {6 M) M% d0 P - SetBkColor(v18, 0);# n( _: G9 q0 R6 V1 q; E! O
- SetTextColor(v18, 0xFFFFFFu);
, [" M! G, y$ m0 y3 m0 c) d - SetBkMode(v18, 1);, y! x9 X# J# @ ^! y
- v26 = 1;
5 g- d, W* R* V% [0 G* O - v41 = 1;. I5 `3 u2 s5 v! g8 l- r) Z" ~
- v40 = 0;
: d+ P) u4 a8 L2 N+ X" } - v43 = 0;9 l. c* G) Z, P- Z2 n$ C
- if ( *((_DWORD *)v11 + 4) > 0 )
6 K1 Z+ a2 F0 o/ ^6 \/ T: N- v - {1 ^* P5 J7 u% [& |1 W0 I0 \
- v27 = WideCharStr;
* A: n p, D: {3 R, r - v44 = 0;$ h0 Z S6 [ `2 f7 ~2 x
- v42 = WideCharStr;" X# k. O# Q$ X
- v49 = (double)xRight;3 M' H, M8 W1 c
- v50 = (double)yBottom;
6 o) @5 ?0 \( x1 H; E0 C0 h - while ( 1 )
9 n+ F5 q6 K; v. q6 D# x! Z0 x - {: l3 ]* f4 x0 M3 X
- v28 = v44 + *((_DWORD *)v11 + 5);
! f7 p# |( O7 B- K+ g# j2 ^ - *(_WORD *)(v28 + 16) = *v27;/ b1 C1 d) z. e1 J; @: `5 p1 t% T
- GetCharABCWidthsW(v18, *v27, *v27, (LPABC)(v28 + 20)); s7 p! w0 J% v( O- u/ Y' y
- if ( *v42 >= 0x20u ), k8 L+ @* q3 _1 r( u) F
- {
a) T+ T' D- q( J - --*(_DWORD *)(v28 + 20);
, s2 U4 m- q1 i9 y' F$ a2 Q& ^ - *(_DWORD *)(v28 + 24) += 2;3 r* x; w+ Q. B+ e1 y
- --*(_DWORD *)(v28 + 28);/ |& w9 e. A/ t- M) j# J
- }/ c6 F* Y+ y( Z% s7 M
- else
0 G9 j) V) J, z( N& k- f - {
9 q$ O* z2 s4 w1 |4 V4 H+ K1 A - *(_DWORD *)(v28 + 20) = 0;, f4 @ M7 m+ F0 k/ e* I. {1 H
- *(_DWORD *)(v28 + 28) = 0;
6 N G( ~# V; E# ? - }% _ q6 |5 d8 ], D
- v29 = *(_DWORD *)(v28 + 24);# ~& k" b/ V% ^- p4 {
- v30 = v40;3 ]6 \7 P7 m6 o4 l! a9 s. [$ @
- if ( v29 + v26 + 1 >= (unsigned int)xRight )+ i+ [0 B7 Q0 Q) M
- {& g5 ?$ K8 Y4 A) y5 @3 j2 ^$ x
- v26 = 1;( a% P S$ ?+ l+ D
- v30 = v40 + *((_DWORD *)v11 + 3) + 1;
/ T" c S# D: _9 o. P5 J - v41 = 1;: B5 i, i( Z0 T3 X( D
- v40 += *((_DWORD *)v11 + 3) + 1;% _% S" u x! O$ j6 H; z. L
- }
7 i( U0 T& f& B6 [ - *(float *)v28 = (double)v41 / v49;
( F4 q+ A1 h- ]% u0 ]! q( y - *(float *)(v28 + 4) = (double)v40 / v50;" N& ~( i- @9 ^0 x/ o
- *(float *)(v28 + 8) = (double)(unsigned int)(v26 + v29) / v49;
7 X+ ^7 t0 `: d( `" k - v31 = v26 - *(_DWORD *)(v28 + 20);
6 a1 T5 f( L: v+ n - *(float *)(v28 + 12) = (double)(v30 + *((_DWORD *)v11 + 3)) / v50;$ P2 M8 T, a8 k6 e9 N
- TextOutW(v18, v31, v30, v42, 1);
0 f& I' t2 o6 A$ ?- P: f& F, k - v44 += 32;
) L9 D( N+ |; u5 n - ++v42;. t3 ]- t& b$ d* {1 L) q
- v33 = __OFSUB__(v43 + 1, *((_DWORD *)v11 + 4));
; f" q$ _- q, ?- i+ \8 } - v32 = (signed int)&v43[-*((_DWORD *)v11 + 4) + 1] < 0;
: v5 X- n8 c* T' B6 }6 ]8 S - v26 += *(_DWORD *)(v28 + 24) + 1;
0 T/ M% k) X% ~& E, j) n - v41 = v26;/ |0 H- ^% m Y: K6 Z# P1 O
- ++v43;
7 i* M" X7 {# a - if ( !(v32 ^ v33) )
, K; ~- e- }# m9 W& ?7 p; a - break;
! h# c; L( s# b$ F! _; C - v27 = v42;& D& a5 w! ~! w+ C
- }; J' ]1 ?: R; d7 [1 B/ B8 D) F: b
- }) {$ |& A% R1 E2 R
- v34 = CKBitmapData::LockSurfacePtr((CKBitmapData *)(*((_DWORD *)v11 + 6) + 56), -1);7 Q: b( B5 s. G
- if ( v34 )7 o0 G* c2 j3 d- C9 g0 G4 i; L: w
- {
+ Z$ B9 U$ J$ H - GetObjectA(v45, 24, &v51);- S( L, Q; X8 N8 @/ \4 Z& I8 L3 k; q z
- v35 = v53;: @' F! h3 t% h( c# b$ m4 A6 v
- v36 = v55 + v54 * (v53 - 1);+ z# C/ b6 X2 \: V. C
- v40 = 0;
' N( o9 M; G1 \5 @ - if ( v53 > 0 )
' U5 H9 A4 u6 M$ W+ \% w I - {0 j$ ?8 @+ t: `. n/ ^" k) B
- v37 = v52;: ?7 T. w. u! c+ @; `
- do
8 g/ T" a! P) Z5 g" P" X - {4 [, R) P/ |) L" x& Z7 U# O
- v38 = 0;& ~6 n$ L1 |, Y8 G4 H
- if ( v37 > 0 )/ t+ Z: H# b* H
- {
1 m7 j) P9 J! z0 T - v39 = (unsigned __int8 *)v36;
! O) n; C) L5 W7 s6 z9 U* A! y: T - do/ G3 O0 T. D4 d- T! H" |3 Y; ]
- {3 j& n- [4 z+ ~. |- `" D
- *(_DWORD *)&v34[4 * v38] = (*v39 << 24) | 0xFFFFFF;
7 d. j: s0 \6 [% Z) D, n( ? - v37 = v52;
, |& y; H! t& \' u6 w3 E% W" [ - ++v38;# Z; i3 V% I( {- G. t5 A" r
- v39 += 3;4 G6 t' _) h7 U: I9 R9 g
- }
7 j5 U5 c# c$ s! E& Z. V - while ( v38 < v52 );; U) p& }/ ^1 {& u2 E1 N
- v35 = v53;# \$ `! {1 P. x. L
- }1 m- `9 K. }; W* k
- v36 -= v54;
4 w0 A5 a0 h3 K V - v33 = __OFSUB__(v40 + 1, v35);
0 T2 ]! m1 Y. ^/ |* @& ? - v32 = v40 + 1 - v35 < 0;& K/ F9 \" H6 `; z( o
- v34 += 4 * v37;' r$ a8 O0 R% ]4 k# h7 R# S% u
- ++v40;
. F9 N/ @5 B) \* A# `/ t# H* o& } - }
) {6 [& b( v- p2 C - while ( v32 ^ v33 );* [( P \8 M( g$ c, u3 a4 U6 E
- }1 a# b! I+ `; F# S' N
- }
/ o. h3 i; _1 k& U9 X - CKBitmapData::ReleaseSurfacePtr((CKBitmapData *)(*((_DWORD *)v11 + 6) + 56), -1);5 v( z, _6 n# m, t# D; Y. h
- SelectObject(v18, v46);: T8 Q0 F A) D/ G
- VxDeleteFont(v48);
% p$ v' b; S6 Z3 Y" T - SelectObject(v18, v47);
# N1 i0 N; Z! p! W - VxDeleteBitmap(v45);% m, ?: F& B4 A8 g9 N* g& M: z+ S5 T
- DeleteDC(v18);
% w, h$ p$ K x9 g - CKObject::SetName(*((CKObject **)v11 + 6), (char *)a3, 0);
4 e8 k: c$ F8 V: I, ]/ T - CKBitmapData::SetDesiredVideoFormat(*((_DWORD *)v11 + 6) + 56, 1);- r' w+ P6 |3 F2 _! a% \4 z Z
- (*(void (__stdcall **)(_DWORD))(**((_DWORD **)v11 + 6) + 120))(0);
/ k+ c8 U. W; D2 S) E7 u0 E - return v40 + *((_DWORD *)v11 + 3) < yBottom;
% Z8 I0 _: m* I1 z/ P - }
+ i2 b8 V$ e& ~- {8 O c
复制代码
* W9 J1 }# w% {4 ]
0 q" {9 s- e: g' S' }. Z |