DIRECTOR: Give Stage ownership of movies

This commit is contained in:
djsrv 2020-07-03 14:57:31 -04:00
parent a8b779ee0e
commit 2c41b3f291
8 changed files with 268 additions and 253 deletions

View File

@ -23,9 +23,7 @@
#include "common/config-manager.h"
#include "common/debug-channels.h"
#include "common/error.h"
#include "common/substream.h"
#include "common/macresman.h"
#include "common/file.h"
#include "graphics/macgui/macwindowmanager.h"
@ -36,7 +34,6 @@
#include "director/score.h"
#include "director/sound.h"
#include "director/stage.h"
#include "director/util.h"
#include "director/lingo/lingo.h"
namespace Director {
@ -81,19 +78,11 @@ DirectorEngine::DirectorEngine(OSystem *syst, const DirectorGameDescription *gam
// Load key codes
loadKeyCodes();
_currentMovie = nullptr;
_soundManager = nullptr;
_currentPalette = nullptr;
_currentPaletteLength = 0;
_lingo = nullptr;
_mainArchive = nullptr;
_macBinary = nullptr;
_movies = nullptr;
_nextMovie.frameI = -1;
_wm = nullptr;
const Common::FSNode gameDataDir(ConfMan.get("path"));
@ -114,26 +103,19 @@ DirectorEngine::DirectorEngine(OSystem *syst, const DirectorGameDescription *gam
_draggingSprite = false;
_draggingSpriteId = 0;
_newMovieStarted = true;
}
DirectorEngine::~DirectorEngine() {
delete _currentMovie;
_wm->removeWindow(_currentStage);
if (_macBinary) {
delete _macBinary;
_macBinary = nullptr;
}
delete _soundManager;
delete _lingo;
delete _wm;
delete _surface;
}
Archive *DirectorEngine::getMainArchive() const { return _currentStage->getMainArchive(); }
Movie *DirectorEngine::getCurrentMovie() const { return _currentStage->getCurrentMovie(); }
Common::String DirectorEngine::getCurrentPath() const { return _currentStage->getCurrentPath(); }
Common::Error DirectorEngine::run() {
debug("Starting v%d Director game", getVersion());
@ -143,14 +125,13 @@ Common::Error DirectorEngine::run() {
_currentPalette = nullptr;
_macBinary = nullptr;
_soundManager = nullptr;
wmMode = debugChannelSet(-1, kDebugDesktop) ? wmModeDesktop : wmModeFullscreen;
_wm = new Graphics::MacWindowManager(wmMode, &_director3QuickDrawPatterns);
_wm->setEngine(this);
_currentStage = new Stage(_wm->getNextId(), false, false, false, _wm);
_currentStage = new Stage(_wm->getNextId(), false, false, false, _wm, this);
if (!debugChannelSet(-1, kDebugDesktop))
_currentStage->disableBorder();
@ -164,16 +145,12 @@ Common::Error DirectorEngine::run() {
_soundManager = new DirectorSound(this);
if (getGameGID() == GID_TEST) {
runTests();
_currentStage->runTests();
return Common::kNoError;
} else if (getGameGID() == GID_TESTALL) {
enqueueAllMovies();
_currentStage->enqueueAllMovies();
}
// FIXME
//_mainArchive = new RIFFArchive();
//_mainArchive->openFile("bookshelf_example.mmm");
if (getPlatform() == Common::kPlatformWindows)
_machineType = 256; // IBM PC-type machine
@ -191,141 +168,14 @@ Common::Error DirectorEngine::run() {
_sharedCastFile = "Shared.dir";
}
debug(0, "\n@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\nObtaining score name\n");
if (getGameGID() == GID_TESTALL) {
_nextMovie = getNextMovieFromQueue();
loadInitialMovie(_nextMovie.movie);
} else {
loadInitialMovie(getEXEName());
if (!_mainArchive) {
warning("Cannot open main movie");
return Common::kNoGameDataFoundError;
}
// Let's check if it is a projector file
// So far tested with Spaceship Warlock, D2
if (_mainArchive->hasResource(MKTAG('B', 'N', 'D', 'L'), "Projector")) {
warning("Detected Projector file");
if (_mainArchive->hasResource(MKTAG('X', 'C', 'O', 'D'), -1)) {
Common::Array<uint16> xcod = _mainArchive->getResourceIDList(MKTAG('X', 'C', 'O', 'D'));
for (Common::Array<uint16>::iterator iterator = xcod.begin(); iterator != xcod.end(); ++iterator) {
Resource res = _mainArchive->getResourceDetail(MKTAG('X', 'C', 'O', 'D'), *iterator);
debug(0, "Detected XObject '%s'", res.name.c_str());
g_lingo->openXLib(res.name, kXObj);
}
}
if (_mainArchive->hasResource(MKTAG('S', 'T', 'R', '#'), 0)) {
_currentMovie->setArchive(_mainArchive);
Common::SeekableSubReadStreamEndian *name = _mainArchive->getResource(MKTAG('S', 'T', 'R', '#'), 0);
int num = name->readUint16();
if (num != 1) {
warning("Incorrect number of strings in Projector file");
}
if (num == 0)
error("No strings in Projector file");
Common::String sname = name->readPascalString();
_nextMovie.movie = pathMakeRelative(sname);
warning("Replaced score name with: %s (from %s)", _nextMovie.movie.c_str(), sname.c_str());
delete _currentMovie;
_currentMovie = nullptr;
delete name;
}
}
}
if (_currentMovie)
_currentMovie->setArchive(_mainArchive);
Common::Error err = _currentStage->loadInitialMovie();
if (err.getCode() != Common::kNoError)
return err;
bool loop = true;
while (loop) {
loop = false;
if (_currentMovie) {
debug(0, "\n@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
debug(0, "@@@@ Movie name '%s' in '%s'", _currentMovie->getMacName().c_str(), _currentPath.c_str());
debug(0, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
bool goodMovie = _currentMovie->loadArchive();
// If we came in a loop, then skip as requested
if (!_nextMovie.frameS.empty()) {
_currentMovie->getScore()->setStartToLabel(_nextMovie.frameS);
_nextMovie.frameS.clear();
}
if (_nextMovie.frameI != -1) {
_currentMovie->getScore()->setCurrentFrame(_nextMovie.frameI);
_nextMovie.frameI = -1;
}
if (!debugChannelSet(-1, kDebugCompileOnly) && goodMovie) {
debugC(1, kDebugEvents, "Starting playback of movie '%s'", _currentMovie->getMacName().c_str());
_currentMovie->getScore()->startLoop();
debugC(1, kDebugEvents, "Finished playback of movie '%s'", _currentMovie->getMacName().c_str());
}
}
if (getGameGID() == GID_TESTALL) {
_nextMovie = getNextMovieFromQueue();
}
// If a loop was requested, do it
if (!_nextMovie.movie.empty()) {
_newMovieStarted = true;
_currentPath = getPath(_nextMovie.movie, _currentPath);
Cast *sharedCast = nullptr;
if (_currentMovie) {
sharedCast = _currentMovie->getSharedCast();
_currentMovie->_sharedCast = nullptr;
}
delete _currentMovie;
_currentMovie = nullptr;
Archive *mov = openMainArchive(_currentPath + Common::lastPathComponent(_nextMovie.movie, '/'));
if (!mov) {
warning("nextMovie: No movie is loaded");
if (getGameGID() == GID_TESTALL) {
loop = true;
continue;
}
return Common::kNoError;
}
_currentMovie = new Movie(this);
_currentMovie->setArchive(mov);
debug(0, "Switching to movie '%s'", _currentMovie->getMacName().c_str());
_lingo->resetLingo();
if (sharedCast && sharedCast->_castArchive
&& sharedCast->_castArchive->getFileName().equalsIgnoreCase(_currentPath + _sharedCastFile)) {
_currentMovie->_sharedCast = sharedCast;
} else {
delete sharedCast;
_currentMovie->loadSharedCastsFrom(_currentPath + _sharedCastFile);
}
_nextMovie.movie.clear();
loop = true;
}
loop = _currentStage->step();
}
return Common::kNoError;

View File

@ -135,11 +135,11 @@ public:
Common::String getEXEName() const;
DirectorSound *getSoundManager() const { return _soundManager; }
Graphics::MacWindowManager *getMacWindowManager() const { return _wm; }
Archive *getMainArchive() const { return _mainArchive; }
Archive *getMainArchive() const;
Lingo *getLingo() const { return _lingo; }
Stage *getStage() const { return _currentStage; }
Movie *getCurrentMovie() const { return _currentMovie; }
Common::String getCurrentPath() const { return _currentPath; }
Movie *getCurrentMovie() const;
Common::String getCurrentPath() const;
void setPalette(int id);
void setPalette(byte *palette, uint16 count);
bool hasFeature(EngineFeature f) const override;
@ -153,8 +153,6 @@ public:
void loadKeyCodes();
void loadInitialMovie(const Common::String movie);
Archive *openMainArchive(const Common::String movie);
Archive *createArchive();
// events.cpp
@ -165,8 +163,6 @@ public:
void waitForClick();
public:
Common::HashMap<Common::String, Score *> *_movies;
Common::RandomSource _rnd;
Graphics::ManagedSurface *_surface;
Graphics::MacWindowManager *_wm;
@ -180,10 +176,7 @@ public:
bool _playbackPaused;
bool _skipFrameAdvance;
MovieReference _nextMovie;
Common::List<MovieReference> _movieStack;
bool _newMovieStarted;
Common::String _sharedCastFile;
protected:
Common::Error run() override;
@ -191,49 +184,21 @@ protected:
private:
const DirectorGameDescription *_gameDescription;
Common::HashMap<Common::String, Movie *> *scanMovies(const Common::String &folder);
void loadEXE(const Common::String movie);
void loadEXEv3(Common::SeekableReadStream *stream);
void loadEXEv4(Common::SeekableReadStream *stream);
void loadEXEv5(Common::SeekableReadStream *stream);
void loadEXEv7(Common::SeekableReadStream *stream);
void loadEXERIFX(Common::SeekableReadStream *stream, uint32 offset);
void loadMac(const Common::String movie);
Archive *_mainArchive;
Common::MacResManager *_macBinary;
DirectorSound *_soundManager;
byte *_currentPalette;
uint16 _currentPaletteLength;
Lingo *_lingo;
Stage *_currentStage;
Movie *_currentMovie;
Common::String _currentPath;
Graphics::MacPatterns _director3Patterns;
Graphics::MacPatterns _director3QuickDrawPatterns;
Common::HashMap<int, PaletteV4 *> _director4Palettes;
Common::String _sharedCastFile;
bool _draggingSprite;
uint16 _draggingSpriteId;
Common::Point _draggingSpritePos;
Common::StringArray _movieQueue;
// tests.cpp
private:
void testFontScaling();
void testFonts();
void enqueueAllMovies();
MovieReference getNextMovieFromQueue();
void runTests();
};
extern DirectorEngine *g_director;

View File

@ -33,6 +33,7 @@
#include "director/movie.h"
#include "director/score.h"
#include "director/sound.h"
#include "director/stage.h"
#include "director/util.h"
#include "director/lingo/lingo.h"
@ -226,21 +227,23 @@ void Lingo::func_goto(Datum &frame, Datum &movie) {
return;
}
_vm->_nextMovie.movie = cleanedFilename;
_vm->getCurrentMovie()->getScore()->_stopPlay = true;
Stage *stage = _vm->getStage();
_vm->_nextMovie.frameS.clear();
_vm->_nextMovie.frameI = -1;
stage->_nextMovie.movie = cleanedFilename;
stage->getCurrentMovie()->getScore()->_stopPlay = true;
stage->_nextMovie.frameS.clear();
stage->_nextMovie.frameI = -1;
if (frame.type == VOID)
return;
if (frame.type == STRING) {
_vm->_nextMovie.frameS = *frame.u.s;
stage->_nextMovie.frameS = *frame.u.s;
return;
}
_vm->_nextMovie.frameI = frame.asInt();
stage->_nextMovie.frameI = frame.asInt();
return;
}
@ -289,6 +292,8 @@ void Lingo::func_gotoprevious() {
void Lingo::func_play(Datum &frame, Datum &movie) {
MovieReference ref;
Stage *stage = _vm->getStage();
// play #done
if (frame.type == SYMBOL) {
@ -296,12 +301,12 @@ void Lingo::func_play(Datum &frame, Datum &movie) {
warning("Lingo::func_play: unknown symbol: #%s", frame.u.s->c_str());
return;
}
if (_vm->_movieStack.empty()) { // No op if no nested movies
if (stage->_movieStack.empty()) { // No op if no nested movies
return;
}
ref = _vm->_movieStack.back();
ref = stage->_movieStack.back();
_vm->_movieStack.pop_back();
stage->_movieStack.pop_back();
Datum m, f;
@ -327,7 +332,7 @@ void Lingo::func_play(Datum &frame, Datum &movie) {
ref.frameI = _vm->getCurrentMovie()->getScore()->getCurrentFrame();
_vm->_movieStack.push_back(ref);
stage->_movieStack.push_back(ref);
func_goto(frame, movie);
}

View File

@ -21,13 +21,16 @@
*/
#include "common/config-manager.h"
#include "common/macresman.h"
#include "common/error.h"
#include "common/file.h"
#include "common/macresman.h"
#include "common/substream.h"
#include "director/director.h"
#include "director/cast.h"
#include "director/castmember.h"
#include "director/movie.h"
#include "director/stage.h"
#include "director/lingo/lingo.h"
#include "director/util.h"
@ -47,21 +50,72 @@ Archive *DirectorEngine::createArchive() {
}
}
void DirectorEngine::loadInitialMovie(const Common::String movie) {
if (getPlatform() == Common::kPlatformWindows)
Common::Error Stage::loadInitialMovie() {
debug(0, "\n@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\nObtaining movie name\n");
Common::String movie = (_vm->getGameGID() == GID_TESTALL) ? getNextMovieFromQueue().movie : _vm->getEXEName();
if (g_director->getPlatform() == Common::kPlatformWindows)
loadEXE(movie);
else
loadMac(movie);
_currentMovie = new Movie(this);
_currentPath = getPath(getEXEName(), _currentPath);
_currentMovie->loadSharedCastsFrom(_currentPath + _sharedCastFile);
if (!_mainArchive) {
warning("Cannot open main movie");
return Common::kNoGameDataFoundError;
}
_currentMovie = new Movie(_vm);
_currentPath = getPath(movie, _currentPath);
_currentMovie->loadSharedCastsFrom(_currentPath + g_director->_sharedCastFile);
// Let's check if it is a projector file
// So far tested with Spaceship Warlock, D2
if (_mainArchive->hasResource(MKTAG('B', 'N', 'D', 'L'), "Projector")) {
warning("Detected Projector file");
if (_mainArchive->hasResource(MKTAG('X', 'C', 'O', 'D'), -1)) {
Common::Array<uint16> xcod = _mainArchive->getResourceIDList(MKTAG('X', 'C', 'O', 'D'));
for (Common::Array<uint16>::iterator iterator = xcod.begin(); iterator != xcod.end(); ++iterator) {
Resource res = _mainArchive->getResourceDetail(MKTAG('X', 'C', 'O', 'D'), *iterator);
debug(0, "Detected XObject '%s'", res.name.c_str());
g_lingo->openXLib(res.name, kXObj);
}
}
if (_mainArchive->hasResource(MKTAG('S', 'T', 'R', '#'), 0)) {
_currentMovie->setArchive(_mainArchive);
Common::SeekableSubReadStreamEndian *name = _mainArchive->getResource(MKTAG('S', 'T', 'R', '#'), 0);
int num = name->readUint16();
if (num != 1) {
warning("Incorrect number of strings in Projector file");
}
if (num == 0)
error("No strings in Projector file");
Common::String sname = name->readPascalString();
_nextMovie.movie = pathMakeRelative(sname);
warning("Replaced score name with: %s (from %s)", _nextMovie.movie.c_str(), sname.c_str());
delete _currentMovie;
_currentMovie = nullptr;
delete name;
}
}
if (_currentMovie)
_currentMovie->setArchive(_mainArchive);
return Common::kNoError;
}
Archive *DirectorEngine::openMainArchive(const Common::String movie) {
Archive *Stage::openMainArchive(const Common::String movie) {
debug(1, "openMainArchive(\"%s\")", movie.c_str());
_mainArchive = createArchive();
_mainArchive = g_director->createArchive();
if (!_mainArchive->openFile(movie)) {
delete _mainArchive;
@ -74,15 +128,15 @@ Archive *DirectorEngine::openMainArchive(const Common::String movie) {
return _mainArchive;
}
void DirectorEngine::loadEXE(const Common::String movie) {
void Stage::loadEXE(const Common::String movie) {
Common::SeekableReadStream *iniStream = SearchMan.createReadStreamForMember("LINGO.INI");
if (iniStream) {
char *script = (char *)calloc(iniStream->size() + 1, 1);
iniStream->read(script, iniStream->size());
_currentMovie = new Movie(this);
_currentMovie = new Movie(_vm);
_currentMovie->getMainLingoArch()->addCode(script, kMovieScript, 0);
_lingo->processEvent(kEventStartUp);
g_lingo->processEvent(kEventStartUp);
delete _currentMovie;
_currentMovie = nullptr;
@ -93,7 +147,7 @@ void DirectorEngine::loadEXE(const Common::String movie) {
Common::SeekableReadStream *exeStream = SearchMan.createReadStreamForMember(movie);
if (!exeStream)
error("Failed to open EXE '%s'", getEXEName().c_str());
error("Failed to open EXE '%s'", g_director->getEXEName().c_str());
uint32 initialTag = exeStream->readUint32LE();
if (initialTag == MKTAG('R', 'I', 'F', 'X') || initialTag == MKTAG('X', 'F', 'I', 'R')) {
@ -108,7 +162,7 @@ void DirectorEngine::loadEXE(const Common::String movie) {
exeStream->seek(-4, SEEK_END);
exeStream->seek(exeStream->readUint32LE());
switch (getVersion()) {
switch (g_director->getVersion()) {
case 2:
case 3:
loadEXEv3(exeStream);
@ -123,14 +177,14 @@ void DirectorEngine::loadEXE(const Common::String movie) {
loadEXEv7(exeStream);
break;
default:
error("Unhandled Windows EXE version %d", getVersion());
error("Unhandled Windows EXE version %d", g_director->getVersion());
}
}
_mainArchive->setFileName(movie);
}
void DirectorEngine::loadEXEv3(Common::SeekableReadStream *stream) {
void Stage::loadEXEv3(Common::SeekableReadStream *stream) {
uint16 entryCount = stream->readUint16LE();
if (entryCount != 1)
error("Unhandled multiple entry v3 EXE");
@ -183,7 +237,7 @@ void DirectorEngine::loadEXEv3(Common::SeekableReadStream *stream) {
openMainArchive(mmmFileName);
}
void DirectorEngine::loadEXEv4(Common::SeekableReadStream *stream) {
void Stage::loadEXEv4(Common::SeekableReadStream *stream) {
if (stream->readUint32BE() != MKTAG('P', 'J', '9', '3'))
error("Invalid projector tag found in v4 EXE");
@ -201,7 +255,7 @@ void DirectorEngine::loadEXEv4(Common::SeekableReadStream *stream) {
loadEXERIFX(stream, rifxOffset);
}
void DirectorEngine::loadEXEv5(Common::SeekableReadStream *stream) {
void Stage::loadEXEv5(Common::SeekableReadStream *stream) {
uint32 ver = stream->readUint32LE();
if (ver != MKTAG('P', 'J', '9', '5'))
@ -223,7 +277,7 @@ void DirectorEngine::loadEXEv5(Common::SeekableReadStream *stream) {
loadEXERIFX(stream, rifxOffset);
}
void DirectorEngine::loadEXEv7(Common::SeekableReadStream *stream) {
void Stage::loadEXEv7(Common::SeekableReadStream *stream) {
if (stream->readUint32LE() != MKTAG('P', 'J', '0', '0'))
error("Invalid projector tag found in v7 EXE");
@ -237,15 +291,15 @@ void DirectorEngine::loadEXEv7(Common::SeekableReadStream *stream) {
loadEXERIFX(stream, rifxOffset);
}
void DirectorEngine::loadEXERIFX(Common::SeekableReadStream *stream, uint32 offset) {
void Stage::loadEXERIFX(Common::SeekableReadStream *stream, uint32 offset) {
_mainArchive = new RIFXArchive();
if (!_mainArchive->openStream(stream, offset))
error("Failed to load RIFX from EXE");
}
void DirectorEngine::loadMac(const Common::String movie) {
if (getVersion() < 4) {
void Stage::loadMac(const Common::String movie) {
if (g_director->getVersion() < 4) {
// The data is part of the resource fork of the executable
openMainArchive(movie);
} else {

View File

@ -448,7 +448,7 @@ void Score::update() {
if (g_system->getMillis() < _nextFrameTime && !debugChannelSet(-1, kDebugFast)) {
_vm->_wm->renderZoomBox(true);
if (!_vm->_newMovieStarted)
if (!_vm->getStage()->_newMovieStarted)
_vm->_wm->draw();
return;
@ -516,7 +516,7 @@ void Score::update() {
// Stage is drawn between the prepareFrame and enterFrame events (Lingo in a Nutshell, p.100)
renderFrame(_currentFrame);
_vm->_newMovieStarted = false;
_vm->getStage()->_newMovieStarted = false;
// Enter and exit from previous frame
if (!_vm->_playbackPaused) {
@ -597,7 +597,7 @@ bool Score::renderTransition(uint16 frameId) {
}
void Score::renderSprites(uint16 frameId, RenderMode mode) {
if (_vm->_newMovieStarted)
if (_vm->getStage()->_newMovieStarted)
mode = kRenderForceUpdate;
for (uint16 i = 0; i < _channels.size(); i++) {

View File

@ -21,23 +21,42 @@
*/
#include "common/system.h"
#include "common/macresman.h"
#include "graphics/primitives.h"
#include "graphics/macgui/macwindowmanager.h"
#include "director/director.h"
#include "director/cast.h"
#include "director/lingo/lingo.h"
#include "director/movie.h"
#include "director/stage.h"
#include "director/score.h"
#include "director/castmember.h"
#include "director/sprite.h"
#include "director/util.h"
namespace Director {
Stage::Stage(int id, bool scrollable, bool resizable, bool editable, Graphics::MacWindowManager *wm)
Stage::Stage(int id, bool scrollable, bool resizable, bool editable, Graphics::MacWindowManager *wm, DirectorEngine *vm)
: MacWindow(id, scrollable, resizable, editable, wm) {
_vm = vm;
_stageColor = 0;
_puppetTransition = nullptr;
_currentMovie = nullptr;
_mainArchive = nullptr;
_macBinary = nullptr;
_nextMovie.frameI = -1;
_newMovieStarted = true;
}
Stage::~Stage() {
delete _currentMovie;
if (_macBinary) {
delete _macBinary;
_macBinary = nullptr;
}
}
bool Stage::render(bool forceRedraw, Graphics::ManagedSurface *blitTo) {
@ -203,4 +222,85 @@ Common::Point Stage::getMousePos() {
return g_system->getEventManager()->getMousePos() - Common::Point(_dims.left, _dims.top);
}
bool Stage::step() {
bool loop = false;
if (_currentMovie) {
debug(0, "\n@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
debug(0, "@@@@ Movie name '%s' in '%s'", _currentMovie->getMacName().c_str(), _currentPath.c_str());
debug(0, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
bool goodMovie = _currentMovie->loadArchive();
// If we came in a loop, then skip as requested
if (!_nextMovie.frameS.empty()) {
_currentMovie->getScore()->setStartToLabel(_nextMovie.frameS);
_nextMovie.frameS.clear();
}
if (_nextMovie.frameI != -1) {
_currentMovie->getScore()->setCurrentFrame(_nextMovie.frameI);
_nextMovie.frameI = -1;
}
if (!debugChannelSet(-1, kDebugCompileOnly) && goodMovie) {
debugC(1, kDebugEvents, "Starting playback of movie '%s'", _currentMovie->getMacName().c_str());
_currentMovie->getScore()->startLoop();
debugC(1, kDebugEvents, "Finished playback of movie '%s'", _currentMovie->getMacName().c_str());
}
}
if (_vm->getGameGID() == GID_TESTALL) {
_nextMovie = getNextMovieFromQueue();
}
// If a loop was requested, do it
if (!_nextMovie.movie.empty()) {
_newMovieStarted = true;
_currentPath = getPath(_nextMovie.movie, _currentPath);
Cast *sharedCast = nullptr;
if (_currentMovie) {
sharedCast = _currentMovie->getSharedCast();
_currentMovie->_sharedCast = nullptr;
}
delete _currentMovie;
_currentMovie = nullptr;
Archive *mov = openMainArchive(_currentPath + Common::lastPathComponent(_nextMovie.movie, '/'));
if (!mov) {
warning("nextMovie: No movie is loaded");
if (_vm->getGameGID() == GID_TESTALL) {
return true;
}
return false;
}
_currentMovie = new Movie(_vm);
_currentMovie->setArchive(mov);
debug(0, "Switching to movie '%s'", _currentMovie->getMacName().c_str());
g_lingo->resetLingo();
if (sharedCast && sharedCast->_castArchive
&& sharedCast->_castArchive->getFileName().equalsIgnoreCase(_currentPath + _vm->_sharedCastFile)) {
_currentMovie->_sharedCast = sharedCast;
} else {
delete sharedCast;
_currentMovie->loadSharedCastsFrom(_currentPath + _vm->_sharedCastFile);
}
_nextMovie.movie.clear();
loop = true;
}
return loop;
}
} // end of namespace Director

View File

@ -25,6 +25,10 @@
#include "graphics/macgui/macwindow.h"
namespace Common {
class Error;
}
namespace Graphics {
class ManagedSurface;
class MacWindow;
@ -38,8 +42,8 @@ struct TransParams;
class Stage : public Graphics::MacWindow {
public:
Stage(int id, bool scrollable, bool resizable, bool editable, Graphics::MacWindowManager *wm);
// ~Stage();
Stage(int id, bool scrollable, bool resizable, bool editable, Graphics::MacWindowManager *wm, DirectorEngine *vm);
~Stage();
bool render(bool forceRedraw = false, Graphics::ManagedSurface *blitTo = nullptr);
@ -60,16 +64,52 @@ class Stage : public Graphics::MacWindow {
Common::Point getMousePos();
Archive *getMainArchive() const { return _mainArchive; }
Movie *getCurrentMovie() const { return _currentMovie; }
Common::String getCurrentPath() const { return _currentPath; }
bool step();
// tests.cpp
Common::HashMap<Common::String, Movie *> *scanMovies(const Common::String &folder);
void testFontScaling();
void testFonts();
void enqueueAllMovies();
MovieReference getNextMovieFromQueue();
void runTests();
// resource.cpp
Common::Error loadInitialMovie();
Archive *openMainArchive(const Common::String movie);
void loadEXE(const Common::String movie);
void loadEXEv3(Common::SeekableReadStream *stream);
void loadEXEv4(Common::SeekableReadStream *stream);
void loadEXEv5(Common::SeekableReadStream *stream);
void loadEXEv7(Common::SeekableReadStream *stream);
void loadEXERIFX(Common::SeekableReadStream *stream, uint32 offset);
void loadMac(const Common::String movie);
public:
Common::List<Common::Rect> _dirtyRects;
Common::List<Channel *> _dirtyChannels;
TransParams *_puppetTransition;
MovieReference _nextMovie;
Common::List<MovieReference> _movieStack;
bool _newMovieStarted;
private:
uint _stageColor;
void inkBlitFrom(Channel *channel, Common::Rect destRect, Graphics::ManagedSurface *blitTo = nullptr);
void drawReverseSprite(Channel *channel, Common::Rect &srcRect, Common::Rect &destRect, Graphics::ManagedSurface *blitTo);
void drawMatteSprite(Channel *channel, Common::Rect &srcRect, Common::Rect &destRect, Graphics::ManagedSurface *blitTo);
DirectorEngine *_vm;
Archive *_mainArchive;
Common::MacResManager *_macBinary;
Movie *_currentMovie;
Common::String _currentPath;
Common::StringArray _movieQueue;
};
} // end of namespace Director

View File

@ -36,6 +36,7 @@
#include "director/director.h"
#include "director/archive.h"
#include "director/movie.h"
#include "director/stage.h"
#include "director/lingo/lingo.h"
namespace Director {
@ -43,13 +44,13 @@ namespace Director {
//////////////////////
// Graphics tests
//////////////////////
void DirectorEngine::testFontScaling() {
void Stage::testFontScaling() {
int x = 10;
int y = 10;
int w = g_system->getWidth();
int h = g_system->getHeight();
setPalette(-1);
_vm->setPalette(-1);
Graphics::ManagedSurface surface;
@ -92,7 +93,7 @@ void DirectorEngine::testFontScaling() {
for (x = x1; x < x1 + 6; x++)
for (y = y1; y < y1 + 6; y++)
*((byte *)surface.getBasePtr(x, y)) = transformColor(i * 16 + j);
*((byte *)surface.getBasePtr(x, y)) = _vm->transformColor(i * 16 + j);
}
}
@ -110,7 +111,7 @@ void DirectorEngine::testFontScaling() {
}
}
void DirectorEngine::testFonts() {
void Stage::testFonts() {
Common::String fontName("Helvetica");
Common::MacResManager *fontFile = new Common::MacResManager();
@ -136,12 +137,12 @@ void DirectorEngine::testFonts() {
//////////////////////
// Movie iteration
//////////////////////
Common::HashMap<Common::String, Movie *> *DirectorEngine::scanMovies(const Common::String &folder) {
Common::HashMap<Common::String, Movie *> *Stage::scanMovies(const Common::String &folder) {
Common::FSNode directory(folder);
Common::FSList movies;
const char *sharedMMMname;
if (getPlatform() == Common::kPlatformWindows)
if (_vm->getPlatform() == Common::kPlatformWindows)
sharedMMMname = "SHARDCST.MMM";
else
sharedMMMname = "Shared Cast";
@ -156,17 +157,17 @@ Common::HashMap<Common::String, Movie *> *DirectorEngine::scanMovies(const Commo
debugC(2, kDebugLoading, "File: %s", i->getName().c_str());
if (Common::matchString(i->getName().c_str(), sharedMMMname, true)) {
_sharedCastFile = i->getName();
_vm->_sharedCastFile = i->getName();
debugC(2, kDebugLoading, "Shared cast detected: %s", i->getName().c_str());
continue;
}
Archive *arc = createArchive();
Archive *arc = _vm->createArchive();
warning("name: %s", i->getName().c_str());
arc->openFile(i->getName());
Movie *m = new Movie(this);
Movie *m = new Movie(_vm);
m->setArchive(arc);
nameMap->setVal(m->getMacName(), m);
@ -177,7 +178,7 @@ Common::HashMap<Common::String, Movie *> *DirectorEngine::scanMovies(const Commo
return nameMap;
}
void DirectorEngine::enqueueAllMovies() {
void Stage::enqueueAllMovies() {
Common::FSNode dir(ConfMan.get("path"));
Common::FSList files;
if (!dir.getChildren(files, Common::FSNode::kListFilesOnly)) {
@ -193,7 +194,7 @@ void DirectorEngine::enqueueAllMovies() {
debug(1, "=========> Enqueued %d movies", _movieQueue.size());
}
MovieReference DirectorEngine::getNextMovieFromQueue() {
MovieReference Stage::getNextMovieFromQueue() {
MovieReference res;
if (_movieQueue.empty())
@ -277,7 +278,7 @@ const byte testMovie[] = {
0x00, 0x00
};
void DirectorEngine::runTests() {
void Stage::runTests() {
Common::MemoryReadStream *movie = new Common::MemoryReadStream(testMovie, ARRAYSIZE(testMovie));
Common::SeekableReadStream *stream = Common::wrapCompressedReadStream(movie);
@ -287,7 +288,7 @@ void DirectorEngine::runTests() {
if (!_mainArchive->openStream(stream, 0)) {
error("DirectorEngine::runTests(): Bad movie data");
}
_currentMovie = new Movie(this);
_currentMovie = new Movie(_vm);
_currentMovie->setArchive(_mainArchive);
_currentMovie->loadArchive();
@ -296,7 +297,7 @@ void DirectorEngine::runTests() {
testFonts();
}
_lingo->runTests();
g_lingo->runTests();
}
} // End of namespace Director