冒险解谜游戏中文网 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 编辑 + T* B. @: J7 B, }+ e" R# P5 @1 [

7 s' f" @/ m! J" f# Y+ Q9 K, ]+ T这个游戏原本是没有字幕的,但是在Scummvm论坛上发现了一个帖子,5 a, `1 d: {7 [# W! k
讨论的内容是关于在原本没有字幕的游戏上加上字幕。(最初的缘由,是为了帮助一位失聪的朋友)
$ v9 Z% l5 ~% ~5 ^, S0 phttps://forums.scummvm.org/viewtopic.php?t=7168, z/ K, }) l# e4 m' l2 t; O" _
[Scummvm-devel] Displaying subtitles in voice-only games (narkive.com)
( _4 X  `1 G1 E5 D; Q5 }; X6 [( e% u* O  }6 ^  a
前段时间第七访客出了25周年纪念版(The 7th Guest 25th Anniversary Edition。! K# Y6 O) J$ S- S, w: b% i
在这个版本中,游戏的视频是有字幕的,因此把这个视频的字幕用到Scummvm中就成为了可能。8 D. u  D2 h1 `" c" q( H7 J

1 j% D/ n! R, z& p7 [我查看了一下最新版本的Scummvm的代码,发现老外已经加入了一部分代码。
- C0 O( p& r# {( J. O  O! I0 f; o在此基础上,汉化是大有希望的。此种汉化方法,也是前所未有的,如果真的实现了将会有重要意义。4 J9 f3 M  T: C; j& H& m$ g

$ }1 k* h9 @& H- ~+ x# r& Y类似游戏还有
  1. · Groovie
    / O& Q  l8 o9 m6 T5 W  Y$ r
  2. - The 7th Guest
    9 ^: a  A& |; y, H' w; R, M
  3. - The 11th Hour+ j1 ?! J8 g7 c# z
  4. 1 X/ j% |" h' c) B7 _& t4 t1 B# h  v
  5. · MADE7 W" G* j( e: d( x' {
  6. - Return to Zork (descriptions are text only, while spoken dialogs lack, x5 y" Z  D0 ]0 n6 x1 ^$ G6 ?3 J
  7. any text)
    3 X6 ~3 Z- h, m" ~4 |3 v- g

  8. ) h6 H! Z) ], r
  9. · SCI 1: d  r8 n8 C* ?' n( {2 p
  10. - King's Quest V (CD Version). In this case, just enabling voice and text
    3 n# O7 Y. y! }2 s9 n' L
  11. simultanously would allow a 3rd party to create a set of MSG files1 T9 L- t3 W- n
  12. containing the voice transcription/translation, as it happened with Gabriel( }: t$ i/ r+ W- `  Q0 y" T
  13. Knight II.0 Z6 b, @6 a9 k- C7 }
  14. " o1 O7 P) Q  W7 w: p  f& P: Q
  15. - N. B' A# R! G2 G! D# S
  16. Future engines:
    4 N# o+ r: L3 V: D! q- K9 D
  17. , r. h3 r( Z/ q" d+ q: W  w  R
  18. · SCI 21  u* A3 {1 [4 C
  19. - Gabriel Knight II: The Beast Within (Already a fan patch available in! h& Z/ \5 U3 v% k1 ?
  20. order to enable the text display feature)( z! Z6 A( i7 J' }! B4 y, z2 C4 r
  21. - Phantasmagoria
    $ {0 G1 z+ T* U# `9 |2 p6 N
  22. - Rama/ R6 l/ N( S- D0 s; e
  23. - Shivers
    " @; f+ D: q4 J& ]$ p. L% ?+ l
  24. - Phantasmagoria II: A Puzzle Of Flesh3 A- O8 B; p2 P3 U" L! z
  25. 8 P- L" u& ?2 u
  26. · SCI 32 F' q6 E3 k' V" X. h% J
  27. - Lighthouse: The Dark Being
    ; C' {  @6 y, C- V: V9 D

  28. 6 M" [% b! o3 w
  29. · M4/MADS
    / p/ n( b0 [! |* ~& W3 D7 J
  30. - Orion Burger: N) w, O% Q* M5 \* T

  31. 4 G# p- ]" Q6 g
  32. · Mohawk+ P3 ~0 T1 R( i, m$ p8 X, S  j
  33. - Myst; i' Y0 G  u# p
  34. - Riven: The Sequel to Myst
复制代码
3 i  R3 h! c- E7 _6 }( Y. c- m

! Q* ^9 N- N+ ^3 w5 G$ I* ~2 q8 A. Z' x3 G# W' q) T& _
2 s' ~) a* p- V/ a- x, p: z
相关代码如下& c+ B2 z- `5 \. f
  1. bool VideoPlayer::playFrame() {
    ' C5 @' p& V, e1 q1 D$ t" g
  2.         bool end = true;  y; T2 {6 \& u& g% p
  3. & F. q! \9 c, ^' y2 K
  4.         // Process the next frame while the file is open; T; X( {4 i6 \/ u' u7 ]9 d& I
  5.         if (_file) {
    7 b7 J) t% |0 r. q! i$ ^
  6.                 end = playFrameInternal();& P) H3 i) o8 F0 c/ e' Z. d1 y- U/ r

  7. 0 ]0 Z; I! Z- S# }  E/ [
  8.                 _subtitles.drawSubtitle(_lastFrameTime - _startTime);! j8 }1 N; L& g; ^" }* n4 M8 S
  9.         }
复制代码
  1. bool Subtitles::drawSubtitle(uint32 timestamp, bool force) {
    , Z: a  ^$ x+ c2 u
  2.         Common::String subtitle;9 `6 T* E  J5 i( M
  3.         if (_loaded) {; {; H+ u& Y. i8 |) U& l  n, [
  4.                 subtitle = _srtParser.getSubtitle(timestamp);+ k" h$ @7 X0 P3 q( D5 r
  5.         } else if (_subtitleDev) {- ~# G( [5 t; F$ U
  6.                 subtitle = _fname;
    ; b0 H- X+ W( @+ t" g% d; z6 j
  7.                 uint32 hours, mins, secs, msecs;2 S8 G) ~& }5 D: b! S( m2 R
  8.                 secs = timestamp / 1000;
    ' [3 {8 Q- {  ~! p  w. ]; \: b: Q
  9.                 hours = secs / 3600;
    & ^' T5 H2 V  T# ^
  10.                 mins = (secs / 60) % 60;
    0 s0 a2 X9 V$ k* T
  11.                 secs %= 60;6 x, ~/ I7 w4 o  r3 W5 S7 L
  12.                 msecs = timestamp % 1000;
    ) @! T5 w- u% Y7 O4 b
  13.                 subtitle += " " + Common::String::format("%02u:%02u:%02u,%03u", hours, mins, secs, msecs);
    4 e9 F" P4 L. r% h9 x
  14.         } else {
    8 h3 E, y3 L" V+ `! P
  15.                 return false;1 J9 D# M2 x9 [7 x3 \1 M4 y
  16.         }) W6 c9 |; l" P9 U  v% i4 U

  17. . }( N- j9 x( w. ^
  18.         int16 width = g_system->getOverlayWidth(),8 z6 T# B! U9 C3 b) ]. v) M. F+ T" q
  19.                   height = g_system->getOverlayHeight();
    5 ^3 v' I: f  Z  _
  20. 4 E# J/ H1 s# u* V4 w. t
  21.         if (width != _lastOverlayWidth ||
    3 g6 E( r. {; S3 u# L
  22.                 height != _lastOverlayHeight) {
    ( L, d/ {( k7 A" r$ m7 x; t
  23.                 _lastOverlayWidth = width;2 F/ k6 T7 ^5 b! u" {/ j
  24.                 _lastOverlayHeight = height;
    ) x) w2 V5 V$ Z1 E

  25. # W$ G# n9 R- Q
  26.                 // Recalculate the real bounding box to use
    3 {/ m. y  \/ m+ w2 l" M
  27.                 _realBBox = _requestedBBox;/ Z. {8 L4 l3 S) B( Y

  28. ; e6 y' j0 y6 E. R  S6 U9 p1 ]) x7 B
  29.                 if (_realBBox.bottom > height) {" C3 Q5 S9 _9 F" Q4 [( X
  30.                         // First try to move the bounding box
    ; f) k1 E  M" k/ w, f8 u$ l/ \& }3 C
  31.                         _realBBox.top -= _realBBox.bottom - height;
    % y# T2 g% M! p- k. X' d& P/ i
  32.                         _realBBox.bottom = height;
    + E) f) W  i( O7 T& s( N, y
  33.                 }
    1 N. G6 J" U8 ?' y% ]/ c" m* d
  34.                 if (_realBBox.top < 0) {* @+ y; \# W, T( V- P" T. I* Z8 h
  35.                         // Not enough space7 I/ w! t7 V, k8 M
  36.                         _realBBox.top = 0;
    ( f3 z' Y+ |1 J4 l0 B  c8 j
  37.                 }
    9 C9 z- T0 F# x7 r- \$ ?: h1 ^* A

  38. 8 b) N- M& h# u" R* t
  39.                 if (_realBBox.right > width) {& \' e) E' y# e7 C
  40.                         // First try to move the bounding box
    5 x! |' L5 d9 H6 e; g9 {' P6 G0 G5 X/ E
  41.                         _realBBox.left -= _realBBox.right - width;
      C5 {$ }- a* W5 O1 d4 S0 B
  42.                         _realBBox.right = width;
    # |  [( q6 G5 I" n6 B
  43.                 }
    , x+ ^: q0 c8 T' f, W5 m* j5 f1 I
  44.                 if (_realBBox.left < 0) {
    . v/ n5 P" z- a8 p0 Q' b' ^
  45.                         // Not enough space
    + b0 T3 P* O; S. X( x# L- b
  46.                         _realBBox.left = 0;% I1 O& g4 w, e7 @$ A  K0 i
  47.                 }, ^; S. q* U  Z; D  w- U. Q3 I

  48. / i5 O" W: E3 F
  49.                 force = true;2 u; O! m. W: T5 s. f9 Q5 I5 P
  50.         }  q6 i& x. p* X& J
  51. + t6 g& L9 h& X1 G
  52.         if (!force && _overlayHasAlpha && subtitle == _subtitle)/ y) U4 [& [1 H+ r; f
  53.                 return false;% @' b2 N) O3 L6 J7 r2 u$ R* ?; w+ A
  54. 7 u) S, X; S' C
  55.         if (force || subtitle != _subtitle) {
    / i* L( Z% Y# G+ r9 |/ `7 E; u( G
  56.                 debug(1, "%d: %s", timestamp, subtitle.c_str());
    - g/ i* [5 |6 g. Z, z

  57. 5 g0 t+ s7 [* n2 X
  58.                 _subtitle = subtitle;
    & ^7 _# @2 l& m" D' T
  59.                 renderSubtitle();
    * }3 h/ E* Y4 @7 f
  60.         }
    / l, j" `# n3 j4 g
  61. 1 @" a2 ^7 |0 [, t# J& `2 v7 D5 K
  62.         if (_overlayHasAlpha) {1 H$ ]5 }) O& [# q0 z3 ~
  63.                 // When we have alpha, draw the whole surface without thinking it more
    9 I# P3 G6 h4 P$ z; q: g' e
  64.                 g_system->copyRectToOverlay(_surface->getPixels(), _surface->pitch, _realBBox.left, _realBBox.top, _realBBox.width(), _realBBox.height());
    & S* g! F. l" ~, W+ ^( M
  65.         } else {4 O: E+ H# y: ?6 h9 h  a
  66.                 // When overlay doesn't have alpha, showing it hides the underlying game screen
    % J* ~! G* a7 Z6 D& m
  67.                 // We force a copy of the game screen to the overlay by clearing it
    + @$ p; J1 y% F3 @5 \  E; X
  68.                 // We then draw the smallest possible surface to minimize black rectangle behind text/ e  [0 g5 h4 o0 o
  69.                 g_system->clearOverlay();
    # O- }) z: z3 L7 _
  70.                 g_system->copyRectToOverlay((byte *)_surface->getPixels() + _drawRect.top * _surface->pitch + _drawRect.left * _surface->format.bytesPerPixel, _surface->pitch,
    " b% j. Y6 f% @/ }- z
  71.                                 _realBBox.left + _drawRect.left, _realBBox.top + _drawRect.top, _drawRect.width(), _drawRect.height());6 U, s8 `3 g% o
  72.         }! c  [: G2 m1 O4 j2 t

  73. 0 {: d) X, F  a. x( `, f; s
  74.         return true;& o$ m, i$ c6 n8 d
  75. }
    + {, T; \1 ~" n! t+ q
复制代码
" E, ~, w; I. Y7 V7 a0 I
( K8 W: ]) u- I# H
* N, Z' `- y: B- E( K
/ P8 V; _) g, @. \+ m$ d/ P# ^

  t# I& x* P/ K+ l2 Y
0 Z1 j7 h" F. k' V
) J# }  s& Z0 H/ x% i# v




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