冒险解谜游戏中文网 ChinaAVG

标题: 【Scummvm汉化 #3】The 7th Guest 第七访客 #1 字幕篇 [打印本页]

作者: shane007    时间: 2023-8-12 13:38
标题: 【Scummvm汉化 #3】The 7th Guest 第七访客 #1 字幕篇
本帖最后由 shane007 于 2023-8-12 13:57 编辑 # C% k# c1 H: M% z: t* D

$ \4 t, h7 @$ V. \) t$ Z- v这个游戏原本是没有字幕的,但是在Scummvm论坛上发现了一个帖子,
2 f) Z  c' z! }; i6 R0 ?讨论的内容是关于在原本没有字幕的游戏上加上字幕。(最初的缘由,是为了帮助一位失聪的朋友)
) }9 \2 h; _2 `: b1 Jhttps://forums.scummvm.org/viewtopic.php?t=7168
5 W3 `. {5 H3 Y" s6 n8 c[Scummvm-devel] Displaying subtitles in voice-only games (narkive.com)
! C& X2 @# f- r* h
) ^) g) C& h; _8 [. x4 A前段时间第七访客出了25周年纪念版(The 7th Guest 25th Anniversary Edition。
) p% _1 e. ?# T7 |* b2 p, |在这个版本中,游戏的视频是有字幕的,因此把这个视频的字幕用到Scummvm中就成为了可能。7 C( c1 R! V6 _) X

9 V& j$ Y$ V8 v' R我查看了一下最新版本的Scummvm的代码,发现老外已经加入了一部分代码。
  r. d3 e4 E- A& {) l/ m在此基础上,汉化是大有希望的。此种汉化方法,也是前所未有的,如果真的实现了将会有重要意义。2 ~& R" L2 z+ ~/ H% J
) p& `) W8 p9 r! f, l! V0 u  o) o
类似游戏还有
  1. · Groovie" o* J! T8 r* E! `, H2 t. o
  2. - The 7th Guest6 c) p* ^& t6 M- V( G. W8 R4 E0 \
  3. - The 11th Hour
    0 j7 P& \  b) _- |
  4. # d8 n# L- e4 `. b
  5. · MADE
    0 S2 q2 X% k* l3 K
  6. - Return to Zork (descriptions are text only, while spoken dialogs lack
    7 b, ]# G0 \3 K) \9 o3 w2 \& R9 f# ]
  7. any text)
    4 c, G* H3 _$ v7 ]1 [

  8. # D6 |1 x! g* z% a6 p; C4 l& M
  9. · SCI 1# J0 D* b6 I$ q" u6 j# ]2 m
  10. - King's Quest V (CD Version). In this case, just enabling voice and text7 P# b' v0 z8 A, W1 Q
  11. simultanously would allow a 3rd party to create a set of MSG files6 e! C% c( j& B  F7 S* p6 T8 N) i
  12. containing the voice transcription/translation, as it happened with Gabriel+ I: h; ]- o) w, m7 C
  13. Knight II.
    4 T4 J. B$ E, T5 Q9 B' V( R

  14. + P& e8 i$ d1 P8 @0 N
  15. & r! q9 q6 A; c/ F( i7 U5 ], U
  16. Future engines:
    8 ]; J7 c/ b0 ~1 y' i

  17.   o: @1 ~7 J& o. J) d  y
  18. · SCI 21' d7 @' h5 Z* Y
  19. - Gabriel Knight II: The Beast Within (Already a fan patch available in
    " a' A# E7 z+ B
  20. order to enable the text display feature)% X0 }' t. `) m9 C. A6 l% w, l
  21. - Phantasmagoria. l7 K2 Z* _3 T: I% S0 j; n- z
  22. - Rama( X* O# A# _9 Q/ C: {- A
  23. - Shivers
    / u: x; W4 o7 d% x
  24. - Phantasmagoria II: A Puzzle Of Flesh
    ! [3 L+ B7 l9 O7 K4 H, M
  25. % p. H: Z2 y$ B# i, b7 }0 E! j
  26. · SCI 3
    3 L: w8 e* {$ Q( [4 E( F
  27. - Lighthouse: The Dark Being7 Q6 p, k2 F# V* ~) h
  28. - k6 n' I% c; X* D: h
  29. · M4/MADS; ?, u  L: O0 W& u& S
  30. - Orion Burger
    6 V, T( k' ~% d& E& s% p
  31. ( h$ Z. L" o7 Y  I
  32. · Mohawk
    " q7 M8 [* v6 w* X3 c
  33. - Myst- s3 n# z: _9 z, @5 n- v3 E
  34. - Riven: The Sequel to Myst
复制代码

0 o% {7 p' L" p! e8 x! ~& T+ ^% C5 N. ?# v

5 c5 i* b: x* A8 v
7 H, a( q4 {" c1 T5 z相关代码如下
- R; x" _: I! D6 b9 V, d
  1. bool VideoPlayer::playFrame() {; l* L% M% P6 \5 L) `0 c
  2.         bool end = true;
    ( T  L, n7 S1 f7 X! ~; z
  3. ! T5 P  G" P7 h0 Q% O) D9 s
  4.         // Process the next frame while the file is open
    ; L) I1 R( a4 ?' ], z
  5.         if (_file) {
    9 {1 p0 y- ]5 u4 }* q
  6.                 end = playFrameInternal();3 d4 R% M2 h* J$ U9 V! r
  7. ( i$ G( E. C" T& H! x- ]" _
  8.                 _subtitles.drawSubtitle(_lastFrameTime - _startTime);6 F8 `' U4 X: ^1 o- [. s2 a/ W
  9.         }
复制代码
  1. bool Subtitles::drawSubtitle(uint32 timestamp, bool force) {/ R" j& P% X8 p6 e. A" A
  2.         Common::String subtitle;" I( ]5 A8 L7 M! T$ a
  3.         if (_loaded) {, q$ F! d  }) r" k% h* k& W5 I
  4.                 subtitle = _srtParser.getSubtitle(timestamp);
    % Q2 T' |6 q! @3 h( _! K$ ^" `
  5.         } else if (_subtitleDev) {
    " o$ X" C  c8 }9 l
  6.                 subtitle = _fname;4 E0 Q" L4 O2 N6 h+ O. u+ j+ h
  7.                 uint32 hours, mins, secs, msecs;
    6 L  h( e  l6 x7 `
  8.                 secs = timestamp / 1000;* c8 o$ C  x# ]
  9.                 hours = secs / 3600;
    5 E7 P7 E2 M4 k
  10.                 mins = (secs / 60) % 60;
    3 A" \/ G, e+ }7 ^( o7 w: H
  11.                 secs %= 60;
      c4 J2 p6 \* F; t+ Y
  12.                 msecs = timestamp % 1000;
    ' ~- ~) F2 g. w) y) Q( q' e) T
  13.                 subtitle += " " + Common::String::format("%02u:%02u:%02u,%03u", hours, mins, secs, msecs);
    & T- w1 ?( Z. J2 o$ \, x% u
  14.         } else {5 {/ _# Q+ L* k8 j% g) ~
  15.                 return false;" [7 Z1 F% D( [) F+ Q6 B1 C; l: G
  16.         }
    3 }; p" G/ Y" W% C9 E" X

  17. 3 v" R. {# p; G" W$ l% ]5 _
  18.         int16 width = g_system->getOverlayWidth(),/ b' y0 P7 G- l+ X7 S; Z
  19.                   height = g_system->getOverlayHeight();
    ( |* V5 X1 \, X1 C; C( |1 U
  20. * @* X  J' A' I% _' P4 b0 F8 D1 ^
  21.         if (width != _lastOverlayWidth ||
    ( d( \$ Q: C# F8 }: k: b
  22.                 height != _lastOverlayHeight) {# U1 x  ?1 L7 I) M! G0 |' m
  23.                 _lastOverlayWidth = width;2 P6 A; F. s6 [, [; {" Y7 _, d
  24.                 _lastOverlayHeight = height;6 D* ]0 A) N* S, a
  25. : `% M4 T4 D# q, m
  26.                 // Recalculate the real bounding box to use8 |& C# N& s" O7 h* k
  27.                 _realBBox = _requestedBBox;- x, V# a. h* P" Z- ~; z
  28. 4 s: ]% [( C9 f: i
  29.                 if (_realBBox.bottom > height) {
    8 O/ a' X8 k' j" u- M
  30.                         // First try to move the bounding box
    3 V( L2 N9 [5 G7 N7 Y# x7 f
  31.                         _realBBox.top -= _realBBox.bottom - height;1 V, d' B# o" O
  32.                         _realBBox.bottom = height;# k( f4 c4 W% \; t2 @& N
  33.                 }
    + @2 o  X4 w/ |3 E
  34.                 if (_realBBox.top < 0) {
    * i9 T" q  g: y; R- G& ^
  35.                         // Not enough space
    , K. V- \9 O4 |, l$ ]' J
  36.                         _realBBox.top = 0;4 E: v5 ?: a" v- p6 j
  37.                 }: v1 F7 a( f/ v& K3 r( g/ V' H

  38.   q* s( C5 d2 s
  39.                 if (_realBBox.right > width) {9 F  v6 v" u, G3 S! g
  40.                         // First try to move the bounding box* q" v9 {9 `5 U, p' H
  41.                         _realBBox.left -= _realBBox.right - width;
    . p. {8 I8 s- x
  42.                         _realBBox.right = width;  R5 F! A4 g5 n( w# [, c
  43.                 }2 i$ u$ Z  U" V7 g9 G1 i; v
  44.                 if (_realBBox.left < 0) {$ Q9 y  h* V" ~1 o& V" U& ^
  45.                         // Not enough space
    6 V8 q3 O, B5 l) `. Y& {4 k
  46.                         _realBBox.left = 0;6 |) G5 E; q2 W% ~' {4 E; i
  47.                 }3 X4 d9 O# P& l! p$ @
  48. 2 o/ s' Z# u, M% O
  49.                 force = true;& X: }+ b0 J; i# \( ~: {
  50.         }
    6 P4 a  `7 \- F' `$ l+ w% ?

  51. 6 s5 w- n/ z* r) R5 _; A2 l
  52.         if (!force && _overlayHasAlpha && subtitle == _subtitle)
    # x) l, S0 n) p/ a' A" z
  53.                 return false;
    / g; @8 l2 g: \) r2 m. Y' R
  54. ; x. \: L9 M$ A8 _
  55.         if (force || subtitle != _subtitle) {# A: O8 v/ ~! T9 P6 {3 }) g; j3 t
  56.                 debug(1, "%d: %s", timestamp, subtitle.c_str());% W" m1 r- F5 p0 S

  57. & w/ `! c' J1 S1 M3 M
  58.                 _subtitle = subtitle;  W4 f2 Y# O0 B" \! @/ g5 h
  59.                 renderSubtitle();
    ! b/ ^8 i/ \6 S. l5 S7 R. d) ^# A
  60.         }
    ' k, r  B2 I4 ?7 k) u/ g- S2 C
  61. 4 G0 `- A5 T. H3 q; {4 k4 a1 i
  62.         if (_overlayHasAlpha) {
    0 O1 L. v3 O7 h3 r
  63.                 // When we have alpha, draw the whole surface without thinking it more: m! d) l/ k9 U0 K
  64.                 g_system->copyRectToOverlay(_surface->getPixels(), _surface->pitch, _realBBox.left, _realBBox.top, _realBBox.width(), _realBBox.height());: I5 v! X  Z2 B, |' V
  65.         } else {
    $ [) G6 m7 I" \, s' `) b% s$ _: [, r
  66.                 // When overlay doesn't have alpha, showing it hides the underlying game screen
    ' X3 u$ L5 C% a4 ?9 T$ |( K
  67.                 // We force a copy of the game screen to the overlay by clearing it
    ) s# G. ^( j% w2 e4 {: t
  68.                 // We then draw the smallest possible surface to minimize black rectangle behind text3 R0 T+ q( J% H
  69.                 g_system->clearOverlay();
    & i! C% b! N! w) d2 l
  70.                 g_system->copyRectToOverlay((byte *)_surface->getPixels() + _drawRect.top * _surface->pitch + _drawRect.left * _surface->format.bytesPerPixel, _surface->pitch,
    " K* d7 D4 k/ s( _3 P( l
  71.                                 _realBBox.left + _drawRect.left, _realBBox.top + _drawRect.top, _drawRect.width(), _drawRect.height());0 b' z( W; t! @: u) B# l/ s
  72.         }) B' _! N8 i  v7 o" x) C; J2 I. _

  73. 1 Z4 q4 j5 }7 R% M1 Q- e
  74.         return true;1 v! T& k3 p  R$ N7 l8 J
  75. }0 q# s4 B7 e9 F5 p" X' y# n3 X+ A
复制代码

2 J3 @3 D$ r5 u: `
6 t& _' ]3 J; e, w5 n4 z& k, @- d: w9 A. M0 N

. T3 ?- {# \2 t2 c  d) M1 g2 `+ F
/ g1 Z: T7 L; Z, M* c2 A5 R0 X* v( o
8 G0 Z$ U5 d; e5 a  Q0 Z% ]
: S& ~$ P" t  u+ G$ I2 \




欢迎光临 冒险解谜游戏中文网 ChinaAVG (https://www.chinaavg.com/) Powered by Discuz! X3.2