mirror of
https://github.com/libretro/scummvm.git
synced 2025-02-25 13:42:37 +00:00
XEEN: Refactoring subtitles for use in location cutscenes, updated Reaper cutscene
This commit is contained in:
parent
392db4ed33
commit
4a5c1af79f
@ -29,8 +29,6 @@
|
||||
|
||||
namespace Xeen {
|
||||
|
||||
#define WAIT(TIME) if (_subtitles.wait(TIME)) return false
|
||||
|
||||
class XeenEngine;
|
||||
|
||||
class Cutscenes {
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -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
|
||||
|
@ -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 */
|
||||
|
@ -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)); \
|
||||
|
@ -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:
|
||||
|
@ -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 {
|
||||
|
||||
|
@ -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 {
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user