mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-16 22:58:09 +00:00
DIRECTOR: Give Stage ownership of movies
This commit is contained in:
parent
a8b779ee0e
commit
2c41b3f291
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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++) {
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user