[Scummvm-git-logs] scummvm master -> 3a17dcb024a77c7c95e404ee26844d0e744cbc28

djsrv dservilla at gmail.com
Fri Jul 24 00:15:15 UTC 2020


This automated email contains information about 3 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
a86b95a4f3 DIRECTOR: Remove processEvents from updateStage
f23ef93766 DIRECTOR: Move event handling to movie
3a17dcb024 DIRECTOR: Fix blank frame on loop


Commit: a86b95a4f3074d9693269ce2ce5c7a262ff339ac
    https://github.com/scummvm/scummvm/commit/a86b95a4f3074d9693269ce2ce5c7a262ff339ac
Author: djsrv (dservilla at gmail.com)
Date: 2020-07-23T20:05:49-04:00

Commit Message:
DIRECTOR: Remove processEvents from updateStage

I don't think this makes sense here...

Changed paths:
    engines/director/lingo/lingo-builtins.cpp


diff --git a/engines/director/lingo/lingo-builtins.cpp b/engines/director/lingo/lingo-builtins.cpp
index 5897013d24..1da221b802 100644
--- a/engines/director/lingo/lingo-builtins.cpp
+++ b/engines/director/lingo/lingo-builtins.cpp
@@ -1973,8 +1973,6 @@ void LB::b_updateStage(int nargs) {
 	if (movie->getStage()->render())
 		g_director->draw();
 
-	g_director->processEvents(true);
-
 	if (debugChannelSet(-1, kDebugFewFramesOnly)) {
 		score->_framesRan++;
 


Commit: f23ef937661ba0697347584c8b8e03e00197eb23
    https://github.com/scummvm/scummvm/commit/f23ef937661ba0697347584c8b8e03e00197eb23
Author: djsrv (dservilla at gmail.com)
Date: 2020-07-23T20:05:49-04:00

Commit Message:
DIRECTOR: Move event handling to movie

Changed paths:
    engines/director/director.cpp
    engines/director/director.h
    engines/director/events.cpp
    engines/director/lingo/lingo-events.cpp
    engines/director/lingo/lingo-the.cpp
    engines/director/lingo/lingo.cpp
    engines/director/lingo/lingo.h
    engines/director/movie.cpp
    engines/director/movie.h
    engines/director/resource.cpp
    engines/director/score.cpp
    engines/director/stage.h


diff --git a/engines/director/director.cpp b/engines/director/director.cpp
index 41ade86e79..b062ae0494 100644
--- a/engines/director/director.cpp
+++ b/engines/director/director.cpp
@@ -102,14 +102,9 @@ DirectorEngine::DirectorEngine(OSystem *syst, const DirectorGameDescription *gam
 	SearchMan.addSubDirectoryMatching(gameDataDir, "win_data", 0, 2);	// L-ZONE
 
 	_colorDepth = 8;	// 256-color
-	_key = 0;
-	_keyCode = 0;
-	_keyFlags = 0;
 	_machineType = 9; // Macintosh IIci
 	_playbackPaused = false;
 	_skipFrameAdvance = false;
-
-	_currentDraggedChannel = nullptr;
 }
 
 DirectorEngine::~DirectorEngine() {
@@ -130,6 +125,10 @@ Common::String DirectorEngine::getCurrentPath() const { return _currentStage->ge
 
 static void buildbotErrorHandler(const char *msg) { }
 
+void DirectorEngine::setCurrentMovie(Movie *movie) {
+	_currentStage = movie->getStage();
+}
+
 Common::Error DirectorEngine::run() {
 	debug("Starting v%d Director game", getVersion());
 
@@ -196,6 +195,8 @@ Common::Error DirectorEngine::run() {
 	bool loop = true;
 
 	while (loop) {
+		processEvents();
+
 		_currentStage = _mainStage;
 		loop = _currentStage->step();
 
diff --git a/engines/director/director.h b/engines/director/director.h
index 1bfdc1d0a9..1f1dd367ef 100644
--- a/engines/director/director.h
+++ b/engines/director/director.h
@@ -172,6 +172,7 @@ public:
 	Stage *getMainStage() const { return _mainStage; }
 	Stage *getCurrentStage() const { return _currentStage; }
 	Movie *getCurrentMovie() const;
+	void setCurrentMovie(Movie *movie);
 	Common::String getCurrentPath() const;
 
 	// graphics.cpp
@@ -192,7 +193,7 @@ public:
 	Archive *createArchive();
 
 	// events.cpp
-	void processEvents(bool bufferLingoEvents = false);
+	void processEvents();
 	uint32 getMacTicks();
 	void waitForClick();
 
@@ -203,9 +204,6 @@ public:
 
 public:
 	int _colorDepth;
-	unsigned char _key;
-	int _keyCode;
-	byte _keyFlags;
 	Common::HashMap<int, int> _macKeyCodes;
 	int _machineType;
 	bool _playbackPaused;
@@ -233,9 +231,6 @@ private:
 	Graphics::MacPatterns _director3QuickDrawPatterns;
 
 	Common::HashMap<int, PaletteV4 *> _director4Palettes;
-
-	Channel *_currentDraggedChannel;
-	Common::Point _draggingSpritePos;
 };
 
 extern DirectorEngine *g_director;
diff --git a/engines/director/events.cpp b/engines/director/events.cpp
index c19e526b72..f5ae2efeda 100644
--- a/engines/director/events.cpp
+++ b/engines/director/events.cpp
@@ -56,21 +56,15 @@ bool processQuitEvent(bool click) {
 
 uint32 DirectorEngine::getMacTicks() { return g_system->getMillis() * 60 / 1000.; }
 
-void DirectorEngine::processEvents(bool bufferLingoEvents) {
+void DirectorEngine::processEvents() {
+	debugC(3, kDebugEvents, "\n@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
+	debugC(3, kDebugEvents, "@@@@   Processing events");
+	debugC(3, kDebugEvents, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
+
 	Common::Event event;
 
 	uint endTime = g_system->getMillis() + 10;
 
-	Movie *m = getCurrentMovie();
-	Score *sc = m->getScore();
-	if (sc->getCurrentFrame() >= sc->_frames.size()) {
-		warning("processEvents: request to access frame %d of %d", sc->getCurrentFrame(), sc->_frames.size() - 1);
-		return;
-	}
-	uint16 spriteId = 0;
-
-	Common::Point pos;
-
 	while (g_system->getMillis() < endTime) {
 		while (g_system->getEventManager()->pollEvent(event)) {
 			if (_wm->processEvent(event))
@@ -78,116 +72,136 @@ void DirectorEngine::processEvents(bool bufferLingoEvents) {
 
 			switch (event.type) {
 			case Common::EVENT_QUIT:
-				sc->_playState = kPlayStopped;
+				_mainStage->getCurrentMovie()->getScore()->_playState = kPlayStopped;
 				break;
+			default:
+				break;
+			}
+		}
 
-			case Common::EVENT_MOUSEMOVE:
-				pos = _currentStage->getMousePos();
-
-				m->_lastEventTime = g_director->getMacTicks();
-				m->_lastRollTime =	 m->_lastEventTime;
+		g_system->delayMillis(10);
+	}
+}
 
-				sc->renderCursor(sc->getSpriteIDFromPos(pos));
+bool Stage::processEvent(Common::Event &event) {
+	if (MacWindow::processEvent(event))
+		return true;
+	
+	if (_currentMovie && _currentMovie->processEvent(event))
+		return true;
+	
+	return false;
+}
 
-				if (_currentDraggedChannel) {
-					if (_currentDraggedChannel->_sprite->_moveable) {
-						pos = getCurrentStage()->getMousePos();
+bool Movie::processEvent(Common::Event &event) {
+	_vm->setCurrentMovie(this);
 
-						_currentDraggedChannel->addDelta(pos - _draggingSpritePos);
-						_draggingSpritePos = pos;
-					} else {
-						_currentDraggedChannel = nullptr;
-					}
-				}
-				break;
+	Score *sc = getScore();
+	if (sc->getCurrentFrame() >= sc->_frames.size()) {
+		warning("processEvents: request to access frame %d of %d", sc->getCurrentFrame(), sc->_frames.size() - 1);
+		return false;
+	}
+	uint16 spriteId = 0;
 
-			case Common::EVENT_LBUTTONDOWN:
-				pos = _currentStage->getMousePos();
+	Common::Point pos;
 
-				// D3 doesn't have both mouse up and down.
-				// But we still want to know if the mouse is down for press effects.
-				spriteId = sc->getSpriteIDFromPos(pos, true);
-				m->_currentMouseDownSpriteId = spriteId;
-				m->_currentClickOnSpriteId = spriteId;
+	switch (event.type) {
+	case Common::EVENT_MOUSEMOVE:
+		pos = _stage->getMousePos();
 
-				if (spriteId > 0 && sc->_channels[spriteId]->_sprite->shouldHilite())
-					g_director->getCurrentStage()->invertChannel(sc->_channels[spriteId]);
+		_lastEventTime = g_director->getMacTicks();
+		_lastRollTime =	 _lastEventTime;
 
-				m->_lastEventTime = g_director->getMacTicks();
-				m->_lastClickTime = m->_lastEventTime;
-				m->_lastClickPos = pos;
+		sc->renderCursor(sc->getSpriteIDFromPos(pos));
 
-				debugC(3, kDebugEvents, "event: Button Down @(%d, %d), sprite id: %d", pos.x, pos.y, spriteId);
-				_lingo->registerEvent(kEventMouseDown, spriteId);
+		if (_currentDraggedChannel) {
+			if (_currentDraggedChannel->_sprite->_moveable) {
+				pos = _stage->getMousePos();
 
-				if (sc->_channels[spriteId]->_sprite->_moveable) {
-					_draggingSpritePos = _currentStage->getMousePos();
-					_currentDraggedChannel = sc->_channels[spriteId];
-				}
+				_currentDraggedChannel->addDelta(pos - _draggingSpritePos);
+				_draggingSpritePos = pos;
+			} else {
+				_currentDraggedChannel = nullptr;
+			}
+		}
+		return true;
 
-				break;
+	case Common::EVENT_LBUTTONDOWN:
+		pos = _stage->getMousePos();
 
-			case Common::EVENT_LBUTTONUP:
-				pos = _currentStage->getMousePos();
+		// D3 doesn't have both mouse up and down.
+		// But we still want to know if the mouse is down for press effects.
+		spriteId = sc->getSpriteIDFromPos(pos, true);
+		_currentMouseDownSpriteId = spriteId;
+		_currentClickOnSpriteId = spriteId;
 
-				spriteId = sc->getSpriteIDFromPos(pos, true);
+		if (spriteId > 0 && sc->_channels[spriteId]->_sprite->shouldHilite())
+			g_director->getCurrentStage()->invertChannel(sc->_channels[spriteId]);
 
-				if (!sc->getChannelById(m->_currentMouseDownSpriteId)->getBbox().contains(pos))
-					m->_currentMouseDownSpriteId = 0;
+		_lastEventTime = g_director->getMacTicks();
+		_lastClickTime = _lastEventTime;
+		_lastClickPos = pos;
 
-				if (spriteId > 0 && sc->_channels[spriteId]->_sprite->shouldHilite())
-					g_director->getCurrentStage()->invertChannel(sc->_channels[spriteId]);
+		debugC(3, kDebugEvents, "event: Button Down @(%d, %d), movie '%s', sprite id: %d", pos.x, pos.y, _macName.c_str(), spriteId);
+		registerEvent(kEventMouseDown, spriteId);
 
-				if (!(g_director->_wm->_mode & Graphics::kWMModeButtonDialogStyle))
-					m->_currentMouseDownSpriteId = spriteId;
+		if (sc->_channels[spriteId]->_sprite->_moveable) {
+			_draggingSpritePos = _stage->getMousePos();
+			_currentDraggedChannel = sc->_channels[spriteId];
+		}
 
-				debugC(3, kDebugEvents, "event: Button Up @(%d, %d), sprite id: %d", pos.x, pos.y, spriteId);
+		return true;
 
-				_currentDraggedChannel = nullptr;
+	case Common::EVENT_LBUTTONUP:
+		pos = _stage->getMousePos();
 
-				{
-					CastMember *cast = g_director->getCurrentMovie()->getCastMember(sc->getSpriteById(spriteId)->_castId);
-					if (cast && cast->_type == kCastButton)
-						cast->_hilite = !cast->_hilite;
-				}
+		spriteId = sc->getSpriteIDFromPos(pos, true);
 
-				_lingo->registerEvent(kEventMouseUp, spriteId);
-				sc->renderCursor(sc->getSpriteIDFromPos(pos));
-				m->_currentMouseDownSpriteId = 0;
-				break;
+		if (!sc->getChannelById(_currentMouseDownSpriteId)->getBbox().contains(pos))
+			_currentMouseDownSpriteId = 0;
 
-			case Common::EVENT_KEYDOWN:
-				_keyCode = _macKeyCodes.contains(event.kbd.keycode) ? _macKeyCodes[event.kbd.keycode] : 0;
-				_key = (unsigned char)(event.kbd.ascii & 0xff);
-				_keyFlags = event.kbd.flags;
+		if (spriteId > 0 && sc->_channels[spriteId]->_sprite->shouldHilite())
+			g_director->getCurrentStage()->invertChannel(sc->_channels[spriteId]);
 
-				debugC(1, kDebugEvents, "processEvents(): keycode: %d", _keyCode);
+		if (!(g_director->_wm->_mode & Graphics::kWMModeButtonDialogStyle))
+			_currentMouseDownSpriteId = spriteId;
 
-				m->_lastEventTime = g_director->getMacTicks();
-				m->_lastKeyTime = m->_lastEventTime;
-				_lingo->registerEvent(kEventKeyDown);
-				break;
+		debugC(3, kDebugEvents, "event: Button Up @(%d, %d), movie '%s', sprite id: %d", pos.x, pos.y, _macName.c_str(), spriteId);
 
-			case Common::EVENT_KEYUP:
-				_keyFlags = event.kbd.flags;
-				break;
+		_currentDraggedChannel = nullptr;
 
-			default:
-				break;
-			}
+		{
+			CastMember *cast = g_director->getCurrentMovie()->getCastMember(sc->getSpriteById(spriteId)->_castId);
+			if (cast && cast->_type == kCastButton)
+				cast->_hilite = !cast->_hilite;
 		}
 
-		if (!bufferLingoEvents)
-			_lingo->processEvents();
+		registerEvent(kEventMouseUp, spriteId);
+		sc->renderCursor(sc->getSpriteIDFromPos(pos));
+		_currentMouseDownSpriteId = 0;
+		return true;
 
-		g_system->delayMillis(10);
+	case Common::EVENT_KEYDOWN:
+		_keyCode = _vm->_macKeyCodes.contains(event.kbd.keycode) ? _vm->_macKeyCodes[event.kbd.keycode] : 0;
+		_key = (unsigned char)(event.kbd.ascii & 0xff);
+		_keyFlags = event.kbd.flags;
+
+		debugC(1, kDebugEvents, "processEvents(): movie '%s', keycode: %d", _macName.c_str(), _keyCode);
+
+		_lastEventTime = g_director->getMacTicks();
+		_lastKeyTime = _lastEventTime;
+		registerEvent(kEventKeyDown);
+		break;
 
-		if (getVersion() >= 3 && sc->getCurrentFrame() > 0 && sc->_playState != kPlayStopped && _lingo->getEventCount() == 0)
-			_lingo->registerEvent(kEventIdle);
+	case Common::EVENT_KEYUP:
+		_keyFlags = event.kbd.flags;
+		return true;
 
-		if (!bufferLingoEvents)
-			_lingo->processEvents();
+	default:
+		break;
 	}
+
+	return false;
 }
 
 void DirectorEngine::waitForClick() {
diff --git a/engines/director/lingo/lingo-events.cpp b/engines/director/lingo/lingo-events.cpp
index b061862479..ac4f1e6626 100644
--- a/engines/director/lingo/lingo-events.cpp
+++ b/engines/director/lingo/lingo-events.cpp
@@ -101,18 +101,18 @@ ScriptType Lingo::event2script(LEvent ev) {
 	return kNoneScript;
 }
 
-int Lingo::getEventCount() {
+int Movie::getEventCount() {
 	return _eventQueue.size();
 }
 
-void Lingo::setPrimaryEventHandler(LEvent event, const Common::String &code) {
-	debugC(3, kDebugLingoExec, "setting primary event handler (%s)", _eventHandlerTypes[event]);
-	LingoArchive *mainArchive = g_director->getCurrentMovie()->getMainLingoArch();
+void Movie::setPrimaryEventHandler(LEvent event, const Common::String &code) {
+	debugC(3, kDebugLingoExec, "setting primary event handler (%s)", _lingo->_eventHandlerTypes[event]);
+	LingoArchive *mainArchive = getMainLingoArch();
 	mainArchive->primaryEventHandlers[event] = code;
 	mainArchive->addCode(code.c_str(), kGlobalScript, event);
 }
 
-void Lingo::queueSpriteEvent(LEvent event, int eventId, int spriteId) {
+void Movie::queueSpriteEvent(LEvent event, int eventId, int spriteId) {
 	/* When the mouseDown or mouseUp occurs over a sprite, the message
 	 * goes first to the sprite script, then to the script of the cast
 	 * member, to the frame script and finally to the movie scripts.
@@ -151,7 +151,7 @@ void Lingo::queueSpriteEvent(LEvent event, int eventId, int spriteId) {
 	}
 }
 
-void Lingo::queueFrameEvent(LEvent event, int eventId) {
+void Movie::queueFrameEvent(LEvent event, int eventId) {
 	/* [in D4] the enterFrame, exitFrame, idle and timeout messages
 	 * are sent to a frame script and then a movie script.	If the
 	 * current frame has no frame script when the event occurs, the
@@ -182,7 +182,7 @@ void Lingo::queueFrameEvent(LEvent event, int eventId) {
 	}
 }
 
-void Lingo::queueMovieEvent(LEvent event, int eventId) {
+void Movie::queueMovieEvent(LEvent event, int eventId) {
 	/* If more than one movie script handles the same message, Lingo
 	 * searches the movie scripts according to their order in the cast
 	 * window [p.81 of D4 docs]
@@ -210,7 +210,7 @@ void Lingo::queueMovieEvent(LEvent event, int eventId) {
 	}
 }
 
-void Lingo::registerEvent(LEvent event, int spriteId) {
+void Movie::registerEvent(LEvent event, int spriteId) {
 	int eventId = _nextEventId++;
 	if (_nextEventId < 0)
 		_nextEventId = 0;
@@ -265,7 +265,7 @@ void Lingo::registerEvent(LEvent event, int spriteId) {
 			break;
 
 		default:
-			warning("registerEvent: Unhandled event %s", _eventHandlerTypes[event]);	
+			warning("registerEvent: Unhandled event %s", _lingo->_eventHandlerTypes[event]);	
 		}
 	} else {
 		/* In D4+, queue any objects that responds to this event, in order of precedence.
@@ -299,27 +299,33 @@ void Lingo::registerEvent(LEvent event, int spriteId) {
 			break;
 
 		default:
-			warning("registerEvent: Unhandled event %s", _eventHandlerTypes[event]);
+			warning("registerEvent: Unhandled event %s", _lingo->_eventHandlerTypes[event]);
 		}
 	}
 
 	if (oldQueueSize == _eventQueue.size()) {
-		debugC(9, kDebugEvents, "Lingo::registerEvent(%s): no event handler", _eventHandlerTypes[event]);
+		debugC(9, kDebugEvents, "Lingo::registerEvent(%s): no event handler", _lingo->_eventHandlerTypes[event]);
 	}
 }
 
-void Lingo::processEvent(LEvent event, int spriteId) {
+void Movie::processEvent(LEvent event, int spriteId) {
 	registerEvent(event, spriteId);
-	processEvents();
+	_vm->setCurrentMovie(this);
+	_lingo->processEvents();
 }
 
 void Lingo::processEvents() {
 	int lastEventId = -1;
+	Movie *movie = _vm->getCurrentMovie();
+	Score *sc = movie->getScore();
+
+	if (_vm->getVersion() >= 3 && sc->getCurrentFrame() > 0 && sc->_playState != kPlayStopped && movie->_eventQueue.empty())
+		movie->registerEvent(kEventIdle);
 
-	while (!_eventQueue.empty()) {
-		LingoEvent el = _eventQueue.pop();
+	while (!movie->_eventQueue.empty()) {
+		LingoEvent el = movie->_eventQueue.pop();
 
-		if (_vm->getCurrentMovie()->getScore()->_playState == kPlayStopped && el.event != kEventStopMovie)
+		if (sc->_playState == kPlayStopped && el.event != kEventStopMovie)
 			continue;
 
 		if (lastEventId == el.eventId && !_passEvent)
diff --git a/engines/director/lingo/lingo-the.cpp b/engines/director/lingo/lingo-the.cpp
index ddd6cdd793..a85f6bfccf 100644
--- a/engines/director/lingo/lingo-the.cpp
+++ b/engines/director/lingo/lingo-the.cpp
@@ -398,11 +398,11 @@ Datum Lingo::getTheEntity(int entity, Datum &id, int field) {
 		break;
 	case kTheCommandDown:
 		d.type = INT;
-		d.u.i = (g_director->_keyFlags & Common::KBD_META) ? 1 : 0;
+		d.u.i = (_vm->getCurrentMovie()->_keyFlags & Common::KBD_META) ? 1 : 0;
 		break;
 	case kTheControlDown:
 		d.type = INT;
-		d.u.i = (g_director->_keyFlags & Common::KBD_CTRL) ? 1 : 0;
+		d.u.i = (_vm->getCurrentMovie()->_keyFlags & Common::KBD_CTRL) ? 1 : 0;
 		break;
 	case kTheDate:
 		d = getTheDate(field);
@@ -454,11 +454,11 @@ Datum Lingo::getTheEntity(int entity, Datum &id, int field) {
 		break;
 	case kTheKey:
 		d.type = STRING;
-		d.u.s = new Common::String(_vm->_key);
+		d.u.s = new Common::String(_vm->getCurrentMovie()->_key);
 		break;
 	case kTheKeyCode:
 		d.type = INT;
-		d.u.i = _vm->_keyCode;
+		d.u.i = _vm->getCurrentMovie()->_keyCode;
 		break;
 	case kTheKeyDownScript:
 		d.type = STRING;
@@ -636,7 +636,7 @@ Datum Lingo::getTheEntity(int entity, Datum &id, int field) {
 		break;
 	case kTheOptionDown:
 		d.type = INT;
-		d.u.i = (g_director->_keyFlags & Common::KBD_ALT) ? 1 : 0;
+		d.u.i = (_vm->getCurrentMovie()->_keyFlags & Common::KBD_ALT) ? 1 : 0;
 		break;
 	case kThePauseState:
 		getTheEntitySTUB(kThePauseState);
@@ -692,7 +692,7 @@ Datum Lingo::getTheEntity(int entity, Datum &id, int field) {
 		break;
 	case kTheShiftDown:
 		d.type = INT;
-		d.u.i = (g_director->_keyFlags & Common::KBD_SHIFT) ? 1 : 0;
+		d.u.i = (_vm->getCurrentMovie()->_keyFlags & Common::KBD_SHIFT) ? 1 : 0;
 		break;
 	case kTheSoundEnabled:
 		getTheEntitySTUB(kTheSoundEnabled);
@@ -883,10 +883,10 @@ void Lingo::setTheEntity(int entity, Datum &id, int field, Datum &d) {
 		setTheEntitySTUB(kTheItemDelimiter);
 		break;
 	case kTheKeyDownScript:
-		setPrimaryEventHandler(kEventKeyDown, d.asString());
+		_vm->getCurrentMovie()->setPrimaryEventHandler(kEventKeyDown, d.asString());
 		break;
 	case kTheKeyUpScript:
-		setPrimaryEventHandler(kEventKeyUp, d.asString());
+		_vm->getCurrentMovie()->setPrimaryEventHandler(kEventKeyUp, d.asString());
 		break;
 	case kTheMenu:
 		setTheEntitySTUB(kTheMenu);
@@ -895,10 +895,10 @@ void Lingo::setTheEntity(int entity, Datum &id, int field, Datum &d) {
 		setTheEntitySTUB(kTheMenuItem);
 		break;
 	case kTheMouseDownScript:
-		setPrimaryEventHandler(kEventMouseDown, d.asString());
+		_vm->getCurrentMovie()->setPrimaryEventHandler(kEventMouseDown, d.asString());
 		break;
 	case kTheMouseUpScript:
-		setPrimaryEventHandler(kEventMouseUp, d.asString());
+		_vm->getCurrentMovie()->setPrimaryEventHandler(kEventMouseUp, d.asString());
 		break;
 	case kThePerFrameHook:
 		_perFrameHook = d;
@@ -982,7 +982,7 @@ void Lingo::setTheEntity(int entity, Datum &id, int field, Datum &d) {
 		setTheEntitySTUB(kTheTimeoutPlay);
 		break;
 	case kTheTimeoutScript:
-		setPrimaryEventHandler(kEventTimeout, d.asString());
+		_vm->getCurrentMovie()->setPrimaryEventHandler(kEventTimeout, d.asString());
 		break;
 	case kTheTimer:
 		setTheEntitySTUB(kTheTimer);
diff --git a/engines/director/lingo/lingo.cpp b/engines/director/lingo/lingo.cpp
index 01be16a3ff..5766926a30 100644
--- a/engines/director/lingo/lingo.cpp
+++ b/engines/director/lingo/lingo.cpp
@@ -169,7 +169,6 @@ Lingo::Lingo(DirectorEngine *vm) : _vm(vm) {
 	_localvars = NULL;
 
 	// events
-	_nextEventId = 0;
 	_passEvent = false;
 	_perFrameHook = Datum();
 
diff --git a/engines/director/lingo/lingo.h b/engines/director/lingo/lingo.h
index 0637a7fba1..01aa6e6882 100644
--- a/engines/director/lingo/lingo.h
+++ b/engines/director/lingo/lingo.h
@@ -268,23 +268,13 @@ private:
 	// lingo-events.cpp
 private:
 	void initEventHandlerTypes();
-	void setPrimaryEventHandler(LEvent event, const Common::String &code);
-	void queueSpriteEvent(LEvent event, int eventId, int spriteId);
-	void queueFrameEvent(LEvent event, int eventId);
-	void queueMovieEvent(LEvent event, int eventId);
 	void processEvent(LEvent event, ScriptType st, int entityId, int channelId = -1);
 
-	int _nextEventId;
-	Common::Queue<LingoEvent> _eventQueue;
-
 public:
 	ScriptType event2script(LEvent ev);
 	Symbol getHandler(const Common::String &name);
 
-	int getEventCount();
-	void processEvent(LEvent event, int spriteId = 0);
 	void processEvents();
-	void registerEvent(LEvent event, int spriteId = 0);
 
 public:
 	void execute(uint pc);
diff --git a/engines/director/movie.cpp b/engines/director/movie.cpp
index b13a996ad4..7dac046c6e 100644
--- a/engines/director/movie.cpp
+++ b/engines/director/movie.cpp
@@ -52,6 +52,13 @@ Movie::Movie(Stage *stage) {
 	_lastClickTime = _lastEventTime;
 	_lastRollTime = _lastEventTime;
 	_lastTimerReset = _lastEventTime;
+	_nextEventId = 0;
+
+	_key = 0;
+	_keyCode = 0;
+	_keyFlags = 0;
+
+	_currentDraggedChannel = nullptr;
 
 	_allowOutdatedLingo = false;
 
diff --git a/engines/director/movie.h b/engines/director/movie.h
index 7c1f9e76ed..e8103101c5 100644
--- a/engines/director/movie.h
+++ b/engines/director/movie.h
@@ -24,6 +24,7 @@
 #define DIRECTOR_MOVIE_H
 
 namespace Common {
+struct Event;
 class ReadStreamEndian;
 class SeekableSubReadStreamEndian;
 }
@@ -37,6 +38,7 @@ class CastMember;
 class DirectorEngine;
 class Lingo;
 struct LingoArchive;
+struct LingoEvent;
 class ScriptContext;
 class Stage;
 struct Symbol;
@@ -110,9 +112,22 @@ public:
 	ScriptContext *getScriptContext(ScriptType type, uint16 id);
 	Symbol getHandler(const Common::String &name);
 
+	// events.cpp
+	bool processEvent(Common::Event &event);
+
+	// lingo/lingo-events.cpp
+	void setPrimaryEventHandler(LEvent event, const Common::String &code);
+	int getEventCount();
+	void processEvent(LEvent event, int spriteId = 0);
+	void registerEvent(LEvent event, int spriteId = 0);
+
 private:
 	void loadFileInfo(Common::SeekableSubReadStreamEndian &stream);
 
+	void queueSpriteEvent(LEvent event, int eventId, int spriteId);
+	void queueFrameEvent(LEvent event, int eventId);
+	void queueMovieEvent(LEvent event, int eventId);
+
 public:
 	Archive *_movieArchive;
 	Common::Rect _movieRect;
@@ -129,6 +144,13 @@ public:
 	Cast *_sharedCast;
 	bool _allowOutdatedLingo;
 
+	int _nextEventId;
+	Common::Queue<LingoEvent> _eventQueue;
+
+	unsigned char _key;
+	int _keyCode;
+	byte _keyFlags;
+
 private:
 	Stage *_stage;
 	DirectorEngine *_vm;
@@ -143,6 +165,9 @@ private:
 	Common::String _changedBy;
 	Common::String _script;
 	Common::String _directory;
+
+	Channel *_currentDraggedChannel;
+	Common::Point _draggingSpritePos;
 };
 
 } // End of namespace Director
diff --git a/engines/director/resource.cpp b/engines/director/resource.cpp
index 26c07a83ea..5970d3a405 100644
--- a/engines/director/resource.cpp
+++ b/engines/director/resource.cpp
@@ -152,7 +152,7 @@ void Stage::loadEXE(const Common::String movie) {
 
 		_currentMovie = new Movie(this);
 		_currentMovie->getMainLingoArch()->addCode(script, kMovieScript, 0);
-		g_lingo->processEvent(kEventStartUp);
+		_currentMovie->processEvent(kEventStartUp);
 		delete _currentMovie;
 		_currentMovie = nullptr;
 
diff --git a/engines/director/score.cpp b/engines/director/score.cpp
index 2b46f1637a..a68fd074e9 100644
--- a/engines/director/score.cpp
+++ b/engines/director/score.cpp
@@ -232,24 +232,14 @@ void Score::startPlay() {
 			_channels.push_back(new Channel(_frames[1]->_sprites[i]));
 
 	if (_vm->getVersion() >= 3)
-		_lingo->processEvent(kEventStartMovie);
+		_movie->processEvent(kEventStartMovie);
 }
 
 void Score::step() {
-	if (_currentFrame >= _frames.size()) {
-		if (debugChannelSet(-1, kDebugNoLoop)) {
-			_playState = kPlayStopped;
-			return;
-		}
-
-		_currentFrame = 0;
-	}
+	_lingo->processEvents();
 
 	update();
 
-	if (_currentFrame < _frames.size())
-		_vm->processEvents();
-
 	if (debugChannelSet(-1, kDebugFewFramesOnly) || debugChannelSet(-1, kDebugScreenshot)) {
 		warning("Score::startLoop(): ran frame %0d", _framesRan);
 		_framesRan++;
@@ -267,7 +257,7 @@ void Score::step() {
 
 void Score::stopPlay() {
 	if (_vm->getVersion() >= 3)
-		_lingo->processEvent(kEventStopMovie);
+		_movie->processEvent(kEventStopMovie);
 	_lingo->executePerFrameHook(-1, 0);
 }
 
@@ -300,11 +290,11 @@ void Score::update() {
 		if (_vm->_skipFrameAdvance) {
 			uint16 nextFrameCache = _nextFrame;
 			if (_vm->getVersion() >= 4)
-				_lingo->processEvent(kEventExitFrame);
+				_movie->processEvent(kEventExitFrame);
 			_nextFrame = nextFrameCache;
 		} else {
 			if (_vm->getVersion() >= 4)
-				_lingo->processEvent(kEventExitFrame);
+				_movie->processEvent(kEventExitFrame);
 		}
 
 		// If there is a transition, the perFrameHook is called
@@ -325,8 +315,14 @@ void Score::update() {
 
 	_vm->_skipFrameAdvance = false;
 
-	if (_currentFrame >= _frames.size())
-		return;
+	if (_currentFrame >= _frames.size()) {
+		if (debugChannelSet(-1, kDebugNoLoop)) {
+			_playState = kPlayStopped;
+			return;
+		}
+
+		_currentFrame = 0;
+	}
 
 	Common::SortedArray<Label *>::iterator i;
 	if (_labels != NULL) {
@@ -342,9 +338,9 @@ void Score::update() {
 	_lingo->executeImmediateScripts(_frames[_currentFrame]);
 
 	if (_vm->getVersion() >= 6) {
-		// _lingo->processEvent(kEventBeginSprite);
+		// _movie->processEvent(kEventBeginSprite);
 		// TODO Director 6 step: send beginSprite event to any sprites whose span begin in the upcoming frame
-		// _lingo->processEvent(kEventPrepareFrame);
+		// _movie->processEvent(kEventPrepareFrame);
 		// TODO: Director 6 step: send prepareFrame event to all sprites and the script channel in upcoming frame
 	}
 
@@ -354,12 +350,12 @@ void Score::update() {
 
 	// Enter and exit from previous frame
 	if (!_vm->_playbackPaused) {
-		_lingo->processEvent(kEventEnterFrame); // Triggers the frame script in D2-3, explicit enterFrame handlers in D4+
+		_movie->processEvent(kEventEnterFrame); // Triggers the frame script in D2-3, explicit enterFrame handlers in D4+
 		if (_vm->getVersion() == 3) {
 			// Movie version of enterFrame, for D3 only. The Lingo Dictionary claims
 			// "This handler executes before anything else when the playback head moves."
 			// but this is incorrect. The frame script is executed first.
-			_lingo->processEvent(kEventStepMovie);
+			_movie->processEvent(kEventStepMovie);
 		}
 	}
 	// TODO Director 6 - another order
diff --git a/engines/director/stage.h b/engines/director/stage.h
index 387ed46bc5..5791c8fe0a 100644
--- a/engines/director/stage.h
+++ b/engines/director/stage.h
@@ -121,6 +121,9 @@ class Stage : public Graphics::MacWindow, public Object<Stage> {
 
 	bool step();
 
+	// events.cpp
+	virtual bool processEvent(Common::Event &event);
+
 	// tests.cpp
 	Common::HashMap<Common::String, Movie *> *scanMovies(const Common::String &folder);
 	void testFontScaling();


Commit: 3a17dcb024a77c7c95e404ee26844d0e744cbc28
    https://github.com/scummvm/scummvm/commit/3a17dcb024a77c7c95e404ee26844d0e744cbc28
Author: djsrv (dservilla at gmail.com)
Date: 2020-07-23T20:05:49-04:00

Commit Message:
DIRECTOR: Fix blank frame on loop

Changed paths:
    engines/director/score.cpp


diff --git a/engines/director/score.cpp b/engines/director/score.cpp
index a68fd074e9..d7791eff2e 100644
--- a/engines/director/score.cpp
+++ b/engines/director/score.cpp
@@ -321,7 +321,7 @@ void Score::update() {
 			return;
 		}
 
-		_currentFrame = 0;
+		_currentFrame = 1;
 	}
 
 	Common::SortedArray<Label *>::iterator i;




More information about the Scummvm-git-logs mailing list