From 4a5c1af79f863992452344f7d02e58ef359c4ddd Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 11 Mar 2018 21:28:11 -0400 Subject: XEEN: Refactoring subtitles for use in location cutscenes, updated Reaper cutscene --- engines/xeen/cutscenes.h | 2 - engines/xeen/locations.cpp | 154 +++++---------------- engines/xeen/locations.h | 8 +- engines/xeen/subtitles.cpp | 50 +++---- engines/xeen/subtitles.h | 21 ++- engines/xeen/worldofxeen/clouds_cutscenes.cpp | 1 + engines/xeen/worldofxeen/clouds_cutscenes.h | 2 +- engines/xeen/worldofxeen/darkside_cutscenes.cpp | 2 + engines/xeen/worldofxeen/worldofxeen_cutscenes.cpp | 2 + 9 files changed, 75 insertions(+), 167 deletions(-) diff --git a/engines/xeen/cutscenes.h b/engines/xeen/cutscenes.h index 5ce7cababe..3c9d328f8d 100644 --- a/engines/xeen/cutscenes.h +++ b/engines/xeen/cutscenes.h @@ -29,8 +29,6 @@ namespace Xeen { -#define WAIT(TIME) if (_subtitles.wait(TIME)) return false - class XeenEngine; class Cutscenes { diff --git a/engines/xeen/locations.cpp b/engines/xeen/locations.cpp index b9c74025b4..ff54329227 100644 --- a/engines/xeen/locations.cpp +++ b/engines/xeen/locations.cpp @@ -29,6 +29,8 @@ #include "xeen/resources.h" #include "xeen/xeen.h" +#define WAIT(TIME) if (_subtitles.wait(TIME)) goto exit + namespace Xeen { namespace Locations { @@ -1234,19 +1236,11 @@ exit: /*------------------------------------------------------------------------*/ -CutsceneLocation::CutsceneLocation(LocationAction action) : BaseLocation(action), - _subtitleCtr(0), _mazeFlag(false) { +CutsceneLocation::CutsceneLocation(LocationAction action) : BaseLocation(action), _mazeFlag(false) { Party &party = *g_vm->_party; _mazeId = party._mazeId; _mazePos = party._mazePosition; _mazeDir = party._mazeDirection; - - loadStrings("special.bin"); - _boxSprites.load("box.vga"); -} - -void CutsceneLocation::updateSubtitles() { - // TODO } void CutsceneLocation::setNewLocation() { @@ -1299,10 +1293,7 @@ int ReaperCutscene::show() { sprites1.draw(0, party._isNight ? 3 : 2, Common::Point(REAPER_X3[idx], REAPER_Y1[1][idx]), 0, idx); } - events.wait(1); - checkEvents(g_vm); - if (g_vm->shouldExit() || _buttonValue) - goto exit; + WAIT(1); } if (_isDarkCc) { @@ -1314,10 +1305,7 @@ int ReaperCutscene::show() { sprites2.draw(0, 0, Common::Point(idx, 0), SPRFLAG_800); sprites2.draw(0, 5, Common::Point(160 + idx, 0), SPRFLAG_800); - events.wait(1); - checkEvents(g_vm); - if (g_vm->shouldExit() || _buttonValue) - goto exit; + WAIT(1); } } else { for (int idx = 200; idx >= 0; idx -= 16) { @@ -1325,10 +1313,7 @@ int ReaperCutscene::show() { sprites1.draw(0, 0, Common::Point(0, 0)); sprites2.draw(0, 0, Common::Point(idx, 0), SPRFLAG_800); - events.wait(1); - checkEvents(g_vm); - if (g_vm->shouldExit() || _buttonValue) - goto exit; + WAIT(1); } } @@ -1339,6 +1324,7 @@ int ReaperCutscene::show() { sprites1.draw(0, party._isNight ? 3 : 2); } + _subtitles.setLine(_mazeFlag ? 5 : 6); sound.playSound(_mazeFlag ? "reaper12.voc" : "reaper14.voc"); do { @@ -1352,19 +1338,16 @@ int ReaperCutscene::show() { sprites2.draw(0, frame); } - updateSubtitles(); + _subtitles.show(); - events.wait(1); - checkEvents(g_vm); - if (g_vm->shouldExit() || _buttonValue) - goto exit; - } while (sound.isSoundPlaying() || _subtitleCtr); + WAIT(1); + } while (sound.isSoundPlaying()); sprites2.draw(0, 0, Common::Point(0, 0)); if (_isDarkCc) sprites2.draw(0, 5, Common::Point(160, 0)); windows[0].update(); - events.wait(7); + WAIT(7); sound.playSound(_mazeFlag ? "reaper12.voc" : "reaper14.voc"); if (_mazeFlag) @@ -1383,21 +1366,14 @@ int ReaperCutscene::show() { sprites2.draw(0, frame); } - windows[0].update(); - - events.wait(1); - checkEvents(g_vm); - if (g_vm->shouldExit() || _buttonValue) - goto exit; - } while (!g_vm->shouldExit() && sound.isSoundPlaying()); + WAIT(1); + } while (_subtitles.lineActive()); sprites2.draw(0, 0, Common::Point(0, 0)); if (_isDarkCc) sprites2.draw(0, 5, Common::Point(160, 0)); windows[0].update(); - - events.updateGameCounter(); - events.wait(1); + WAIT(1); if (_mazeFlag) { for (int idx = 0; idx < 14; ++idx) { @@ -1411,11 +1387,7 @@ int ReaperCutscene::show() { } windows[0].update(); - - events.wait(1); - checkEvents(g_vm); - if (g_vm->shouldExit() || _buttonValue) - goto exit; + WAIT(1); } screen.blitFrom(savedBg); @@ -1591,11 +1563,7 @@ int GolemCutscene::show() { Common::Point(GOLEM_X2[_isDarkCc][idx], GOLEM_Y1[_isDarkCc][idx]), 0, idx); windows[0].update(); - - events.wait(1); - checkEvents(g_vm); - if (g_vm->shouldExit() || _buttonValue) - goto exit; + WAIT(1); } if (_isDarkCc) @@ -1615,10 +1583,7 @@ int GolemCutscene::show() { if (!_isDarkCc && !sound.isSoundPlaying()) sound.playSound("ogre.voc"); - events.wait(1); - checkEvents(g_vm); - if (g_vm->shouldExit() || _buttonValue) - goto exit; + WAIT(1); } sprites1.draw(0, 0, Common::Point(0, 0)); @@ -1630,12 +1595,7 @@ int GolemCutscene::show() { windows[0].update(); while (sound.isSoundPlaying()) { - events.updateGameCounter(); - - events.wait(1); - checkEvents(g_vm); - if (g_vm->shouldExit() || _buttonValue) - goto exit; + WAIT(1); } sound.setMusicPercent(38); sound.playSound(_mazeFlag ? "golem15.voc" : "golem13.voc"); @@ -1656,13 +1616,9 @@ int GolemCutscene::show() { g_vm->getRandomNumber(9) - 3)); } - updateSubtitles(); - - events.wait(1); - checkEvents(g_vm); - if (g_vm->shouldExit() || _buttonValue) - goto exit; - } while (sound.isSoundPlaying() || _subtitleCtr); + _subtitles.show(); + WAIT(1); + } while (_subtitles.lineActive()); sprites1.draw(0, 0, Common::Point(0, 0)); sprites1.draw(0, 1, Common::Point(160, 0)); @@ -1677,7 +1633,7 @@ int GolemCutscene::show() { if (!_isDarkCc) { sound.playSound("ogre.voc"); - while (!g_vm->shouldExit() && sound.isSoundPlaying()) + while (sound.isSoundPlaying()) events.pollEventsAndWait(); sound.playSound(_mazeFlag ? "golem16.voc" : "golem14.voc"); @@ -1702,12 +1658,8 @@ int GolemCutscene::show() { } windows[0].update(); - - events.wait(1); - checkEvents(g_vm); - if (g_vm->shouldExit() || _buttonValue) - goto exit; - } while (!g_vm->shouldExit() && sound.isSoundPlaying()); + WAIT(1); + } while (sound.isSoundPlaying()); sprites1.draw(0, 0, Common::Point(0, 0)); sprites1.draw(0, 1, Common::Point(160, 0)); @@ -1717,12 +1669,8 @@ int GolemCutscene::show() { sprites2[0].draw(0, 2); windows[0].update(); - while (!g_vm->shouldExit() && sound.isSoundPlaying()) { - events.updateGameCounter(); - events.wait(1); - checkEvents(g_vm); - if (g_vm->shouldExit() || _buttonValue) - goto exit; + while (sound.isSoundPlaying()) { + WAIT(1); } sound.setMusicPercent(75); @@ -1737,11 +1685,7 @@ int GolemCutscene::show() { Common::Point(GOLEM_X2[_isDarkCc][idx], GOLEM_Y1[_isDarkCc][idx]), 0, idx); windows[0].update(); - - events.wait(1); - checkEvents(g_vm); - if (g_vm->shouldExit() || _buttonValue) - goto exit; + WAIT(1); } } @@ -1911,11 +1855,7 @@ int DwarfCutscene::show() { Common::Point(DWARF_X2[idx], DWARF_Y[_isDarkCc][idx]), 0, idx); windows[0].update(); - - events.wait(1); - checkEvents(g_vm); - if (g_vm->shouldExit() || _buttonValue) - goto exit; + WAIT(1); } // Have character rise up from the bottom of the screen @@ -1928,11 +1868,7 @@ int DwarfCutscene::show() { screen.blitFrom(savedBg); sprites2.draw(0, 0, Common::Point(DWARF2_X[_isDarkCc][idx], DWARF2_Y[_isDarkCc][idx]), 0, idx); windows[0].update(); - - events.wait(1); - checkEvents(g_vm); - if (g_vm->shouldExit() || _buttonValue) - goto exit; + WAIT(1); } sound.setMusicPercent(38); @@ -1950,7 +1886,7 @@ int DwarfCutscene::show() { if (_isDarkCc) { sprites2.draw(0, 0); sprites3.draw(0, 0); - updateSubtitles(); + _subtitles.show(); events.timeMark5(); while (!g_vm->shouldExit() && events.timeElapsed5() < 7) @@ -1971,16 +1907,13 @@ int DwarfCutscene::show() { do { sprites2.draw(0, 0); sprites3.draw(0, g_vm->getRandomNumber(_isDarkCc ? 8 : 9)); - updateSubtitles(); + _subtitles.show(); events.timeMark5(); while (events.timeElapsed5() < 2) { - events.pollEventsAndWait(); - checkEvents(g_vm); - if (g_vm->shouldExit() || _buttonValue) - goto exit; + WAIT(1); } - } while (sound.isSoundPlaying() || _subtitleCtr); + } while (_subtitles.lineActive()); while (!g_vm->shouldExit() && events.timeElapsed() < 3) events.pollEventsAndWait(); @@ -2129,11 +2062,7 @@ int SphinxCutscene::show() { sprites1.draw(0, 0, Common::Point(SPHINX_X1[idx], SPHINX_Y1[idx]), 0, idx); sprites1.draw(0, 1, Common::Point(SPHINX_X2[idx], SPHINX_Y1[idx]), 0, idx); windows[0].update(); - - events.wait(1); - checkEvents(g_vm); - if (g_vm->shouldExit() || _buttonValue) - goto exit; + WAIT(1); } sound.setMusicPercent(38); @@ -2156,13 +2085,8 @@ int SphinxCutscene::show() { sprites1.draw(0, 0, Common::Point(0, 0)); sprites1.draw(0, 1, Common::Point(160, 0)); sprites1.draw(0, g_vm->getRandomNumber(2, 10)); - updateSubtitles(); - - events.wait(1); - checkEvents(g_vm); - if (g_vm->shouldExit() || _buttonValue) - goto exit; - } while (sound.isSoundPlaying() || _subtitleCtr); + WAIT(1); + } while (_subtitles.lineActive()); sprites1.draw(0, 0, Common::Point(0, 0)); sprites1.draw(0, 1, Common::Point(160, 0)); @@ -2177,11 +2101,7 @@ int SphinxCutscene::show() { sprites1.draw(0, 0, Common::Point(SPHINX_X1[idx], SPHINX_Y1[idx]), 0, idx); sprites1.draw(0, 1, Common::Point(SPHINX_X2[idx], SPHINX_Y1[idx]), 0, idx); windows[0].update(); - - events.wait(1); - checkEvents(g_vm); - if (g_vm->shouldExit() || _buttonValue) - goto exit; + WAIT(1); } screen.blitFrom(bgSurface); diff --git a/engines/xeen/locations.h b/engines/xeen/locations.h index bcc3c07209..9b3e36eed7 100644 --- a/engines/xeen/locations.h +++ b/engines/xeen/locations.h @@ -249,18 +249,12 @@ public: class CutsceneLocation : public BaseLocation { protected: - int _subtitleCtr; - SpriteResource _boxSprites; + Subtitles _subtitles; int _mazeId; Direction _mazeDir; Common::Point _mazePos; bool _mazeFlag; protected: - /** - * Handles updating cutscene subtitles - */ - void updateSubtitles(); - /** * Sets the new location */ diff --git a/engines/xeen/subtitles.cpp b/engines/xeen/subtitles.cpp index 9a5f250cf9..86dff2dac8 100644 --- a/engines/xeen/subtitles.cpp +++ b/engines/xeen/subtitles.cpp @@ -39,6 +39,24 @@ Subtitles::~Subtitles() { void Subtitles::loadSubtitles() { File f("special.bin"); + + if (!g_vm->_files->_isDarkCc) { + // The first subtitle line contains all the text for the Clouds intro. Since ScummVM allows + // both voice and subtitles at the same time, unlike the original, we need to split up the + // first subtitle into separate lines to allow them to better interleave with the voice + Common::String line = f.readString(); + for (;;) { + const char *lineSep = strstr(line.c_str(), " "); + if (!lineSep) + break; + + _lines.push_back(Common::String(line.c_str(), lineSep)); + line = Common::String(lineSep + 3); + while (line.hasPrefix(" ")) + line.deleteChar(0); + } + } + while (f.pos() < f.size()) _lines.push_back(f.readString()); f.close(); @@ -68,7 +86,11 @@ void Subtitles::setLine(int line) { } bool Subtitles::active() const { - return _lineNum != -1; + return !g_vm->shouldExit() && _lineNum != -1; +} + +bool Subtitles::lineActive() const { + return !g_vm->shouldExit() && (active() || g_vm->_sound->isSoundPlaying()); } bool Subtitles::wait(uint numFrames, bool interruptable) { @@ -133,30 +155,4 @@ void Subtitles::show() { } } -/*------------------------------------------------------------------------*/ - -void CloudsSubtitles::loadSubtitles() { - File f("special.bin"); - - // The first subtitle line contains all the text for the Clouds intro. Since ScummVM allows - // both voice and subtitles at the same time, unlike the original, we need to split up the - // first subtitle into separate lines to allow them to better interleave with the voice - Common::String line = f.readString(); - for (;;) { - const char *lineSep = strstr(line.c_str(), " "); - if (!lineSep) - break; - - _lines.push_back(Common::String(line.c_str(), lineSep)); - line = Common::String(lineSep + 3); - while (line.hasPrefix(" ")) - line.deleteChar(0); - } - - // Read in remaining lines - while (f.pos() < f.size()) - _lines.push_back(f.readString()); - f.close(); -} - } // End of namespace Xeen diff --git a/engines/xeen/subtitles.h b/engines/xeen/subtitles.h index 84f7a09d15..37148dbc92 100644 --- a/engines/xeen/subtitles.h +++ b/engines/xeen/subtitles.h @@ -29,17 +29,17 @@ namespace Xeen { class Subtitles { -protected: +private: Common::StringArray _lines; int _lineNum; SpriteResource *_boxSprites; int _lineEnd, _lineSize; Common::String _displayLine; -protected: +private: /** * Loads the string list of all subtitles */ - virtual void loadSubtitles(); + void loadSubtitles(); /** * Mark the current time @@ -76,6 +76,11 @@ public: */ bool active() const; + /** + * Returns true if a subtitle is active or a voice line is currently being played + */ + bool lineActive() const; + /** * Shows any active subtitle */ @@ -95,16 +100,6 @@ public: bool waitForLineOrSound(); }; -class CloudsSubtitles : public Subtitles { -protected: - /** - * Loads the string list of all subtitles - */ - virtual void loadSubtitles(); -public: - CloudsSubtitles() : Subtitles() {} -}; - } // End of namespace Xeen #endif /* XEEN_SUBTITLES_H */ diff --git a/engines/xeen/worldofxeen/clouds_cutscenes.cpp b/engines/xeen/worldofxeen/clouds_cutscenes.cpp index 78e85ba62e..ead66fa501 100644 --- a/engines/xeen/worldofxeen/clouds_cutscenes.cpp +++ b/engines/xeen/worldofxeen/clouds_cutscenes.cpp @@ -27,6 +27,7 @@ namespace Xeen { namespace WorldOfXeen { +#define WAIT(TIME) if (_subtitles.wait(TIME)) return false #define ROTATE_BG screen.horizMerge(_mergeX); \ _mergeX = (_mergeX + 1) % SCREEN_WIDTH #define LOAD_VORTEX loadScreen(Common::String::format("vort%02u.frm", cloudsCtr)); \ diff --git a/engines/xeen/worldofxeen/clouds_cutscenes.h b/engines/xeen/worldofxeen/clouds_cutscenes.h index 17cd6d3f08..39fded63ea 100644 --- a/engines/xeen/worldofxeen/clouds_cutscenes.h +++ b/engines/xeen/worldofxeen/clouds_cutscenes.h @@ -39,7 +39,7 @@ private: static const byte _DECODE_TABLE1[256]; static const byte _DECODE_TABLE2[256]; private: - CloudsSubtitles _subtitles; + Subtitles _subtitles; SpriteResource _mirror, _mirrBack; int _mergeX; private: diff --git a/engines/xeen/worldofxeen/darkside_cutscenes.cpp b/engines/xeen/worldofxeen/darkside_cutscenes.cpp index e37cbec7fc..be8b5cf62c 100644 --- a/engines/xeen/worldofxeen/darkside_cutscenes.cpp +++ b/engines/xeen/worldofxeen/darkside_cutscenes.cpp @@ -26,6 +26,8 @@ #include "xeen/worldofxeen/worldofxeen.h" #include "xeen/worldofxeen/worldofxeen_resources.h" +#define WAIT(TIME) if (_subtitles.wait(TIME)) return false + namespace Xeen { namespace WorldOfXeen { diff --git a/engines/xeen/worldofxeen/worldofxeen_cutscenes.cpp b/engines/xeen/worldofxeen/worldofxeen_cutscenes.cpp index 13d59c43c9..9d35733de9 100644 --- a/engines/xeen/worldofxeen/worldofxeen_cutscenes.cpp +++ b/engines/xeen/worldofxeen/worldofxeen_cutscenes.cpp @@ -24,6 +24,8 @@ #include "xeen/sound.h" #include "xeen/xeen.h" +#define WAIT(TIME) if (_subtitles.wait(TIME)) return false + namespace Xeen { namespace WorldOfXeen { -- cgit v1.2.3