mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-16 22:58:09 +00:00
DIRECTOR: Move event handling to movie
This commit is contained in:
parent
a86b95a4f3
commit
f23ef93766
@ -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();
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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,118 +72,138 @@ void DirectorEngine::processEvents(bool bufferLingoEvents) {
|
||||
|
||||
switch (event.type) {
|
||||
case Common::EVENT_QUIT:
|
||||
sc->_playState = kPlayStopped;
|
||||
_mainStage->getCurrentMovie()->getScore()->_playState = kPlayStopped;
|
||||
break;
|
||||
|
||||
case Common::EVENT_MOUSEMOVE:
|
||||
pos = _currentStage->getMousePos();
|
||||
|
||||
m->_lastEventTime = g_director->getMacTicks();
|
||||
m->_lastRollTime = m->_lastEventTime;
|
||||
|
||||
sc->renderCursor(sc->getSpriteIDFromPos(pos));
|
||||
|
||||
if (_currentDraggedChannel) {
|
||||
if (_currentDraggedChannel->_sprite->_moveable) {
|
||||
pos = getCurrentStage()->getMousePos();
|
||||
|
||||
_currentDraggedChannel->addDelta(pos - _draggingSpritePos);
|
||||
_draggingSpritePos = pos;
|
||||
} else {
|
||||
_currentDraggedChannel = nullptr;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case Common::EVENT_LBUTTONDOWN:
|
||||
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);
|
||||
m->_currentMouseDownSpriteId = spriteId;
|
||||
m->_currentClickOnSpriteId = spriteId;
|
||||
|
||||
if (spriteId > 0 && sc->_channels[spriteId]->_sprite->shouldHilite())
|
||||
g_director->getCurrentStage()->invertChannel(sc->_channels[spriteId]);
|
||||
|
||||
m->_lastEventTime = g_director->getMacTicks();
|
||||
m->_lastClickTime = m->_lastEventTime;
|
||||
m->_lastClickPos = pos;
|
||||
|
||||
debugC(3, kDebugEvents, "event: Button Down @(%d, %d), sprite id: %d", pos.x, pos.y, spriteId);
|
||||
_lingo->registerEvent(kEventMouseDown, spriteId);
|
||||
|
||||
if (sc->_channels[spriteId]->_sprite->_moveable) {
|
||||
_draggingSpritePos = _currentStage->getMousePos();
|
||||
_currentDraggedChannel = sc->_channels[spriteId];
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case Common::EVENT_LBUTTONUP:
|
||||
pos = _currentStage->getMousePos();
|
||||
|
||||
spriteId = sc->getSpriteIDFromPos(pos, true);
|
||||
|
||||
if (!sc->getChannelById(m->_currentMouseDownSpriteId)->getBbox().contains(pos))
|
||||
m->_currentMouseDownSpriteId = 0;
|
||||
|
||||
if (spriteId > 0 && sc->_channels[spriteId]->_sprite->shouldHilite())
|
||||
g_director->getCurrentStage()->invertChannel(sc->_channels[spriteId]);
|
||||
|
||||
if (!(g_director->_wm->_mode & Graphics::kWMModeButtonDialogStyle))
|
||||
m->_currentMouseDownSpriteId = spriteId;
|
||||
|
||||
debugC(3, kDebugEvents, "event: Button Up @(%d, %d), sprite id: %d", pos.x, pos.y, spriteId);
|
||||
|
||||
_currentDraggedChannel = nullptr;
|
||||
|
||||
{
|
||||
CastMember *cast = g_director->getCurrentMovie()->getCastMember(sc->getSpriteById(spriteId)->_castId);
|
||||
if (cast && cast->_type == kCastButton)
|
||||
cast->_hilite = !cast->_hilite;
|
||||
}
|
||||
|
||||
_lingo->registerEvent(kEventMouseUp, spriteId);
|
||||
sc->renderCursor(sc->getSpriteIDFromPos(pos));
|
||||
m->_currentMouseDownSpriteId = 0;
|
||||
break;
|
||||
|
||||
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;
|
||||
|
||||
debugC(1, kDebugEvents, "processEvents(): keycode: %d", _keyCode);
|
||||
|
||||
m->_lastEventTime = g_director->getMacTicks();
|
||||
m->_lastKeyTime = m->_lastEventTime;
|
||||
_lingo->registerEvent(kEventKeyDown);
|
||||
break;
|
||||
|
||||
case Common::EVENT_KEYUP:
|
||||
_keyFlags = event.kbd.flags;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!bufferLingoEvents)
|
||||
_lingo->processEvents();
|
||||
|
||||
g_system->delayMillis(10);
|
||||
|
||||
if (getVersion() >= 3 && sc->getCurrentFrame() > 0 && sc->_playState != kPlayStopped && _lingo->getEventCount() == 0)
|
||||
_lingo->registerEvent(kEventIdle);
|
||||
|
||||
if (!bufferLingoEvents)
|
||||
_lingo->processEvents();
|
||||
}
|
||||
}
|
||||
|
||||
bool Stage::processEvent(Common::Event &event) {
|
||||
if (MacWindow::processEvent(event))
|
||||
return true;
|
||||
|
||||
if (_currentMovie && _currentMovie->processEvent(event))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Movie::processEvent(Common::Event &event) {
|
||||
_vm->setCurrentMovie(this);
|
||||
|
||||
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;
|
||||
|
||||
Common::Point pos;
|
||||
|
||||
switch (event.type) {
|
||||
case Common::EVENT_MOUSEMOVE:
|
||||
pos = _stage->getMousePos();
|
||||
|
||||
_lastEventTime = g_director->getMacTicks();
|
||||
_lastRollTime = _lastEventTime;
|
||||
|
||||
sc->renderCursor(sc->getSpriteIDFromPos(pos));
|
||||
|
||||
if (_currentDraggedChannel) {
|
||||
if (_currentDraggedChannel->_sprite->_moveable) {
|
||||
pos = _stage->getMousePos();
|
||||
|
||||
_currentDraggedChannel->addDelta(pos - _draggingSpritePos);
|
||||
_draggingSpritePos = pos;
|
||||
} else {
|
||||
_currentDraggedChannel = nullptr;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
||||
case Common::EVENT_LBUTTONDOWN:
|
||||
pos = _stage->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;
|
||||
|
||||
if (spriteId > 0 && sc->_channels[spriteId]->_sprite->shouldHilite())
|
||||
g_director->getCurrentStage()->invertChannel(sc->_channels[spriteId]);
|
||||
|
||||
_lastEventTime = g_director->getMacTicks();
|
||||
_lastClickTime = _lastEventTime;
|
||||
_lastClickPos = pos;
|
||||
|
||||
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 (sc->_channels[spriteId]->_sprite->_moveable) {
|
||||
_draggingSpritePos = _stage->getMousePos();
|
||||
_currentDraggedChannel = sc->_channels[spriteId];
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
case Common::EVENT_LBUTTONUP:
|
||||
pos = _stage->getMousePos();
|
||||
|
||||
spriteId = sc->getSpriteIDFromPos(pos, true);
|
||||
|
||||
if (!sc->getChannelById(_currentMouseDownSpriteId)->getBbox().contains(pos))
|
||||
_currentMouseDownSpriteId = 0;
|
||||
|
||||
if (spriteId > 0 && sc->_channels[spriteId]->_sprite->shouldHilite())
|
||||
g_director->getCurrentStage()->invertChannel(sc->_channels[spriteId]);
|
||||
|
||||
if (!(g_director->_wm->_mode & Graphics::kWMModeButtonDialogStyle))
|
||||
_currentMouseDownSpriteId = spriteId;
|
||||
|
||||
debugC(3, kDebugEvents, "event: Button Up @(%d, %d), movie '%s', sprite id: %d", pos.x, pos.y, _macName.c_str(), spriteId);
|
||||
|
||||
_currentDraggedChannel = nullptr;
|
||||
|
||||
{
|
||||
CastMember *cast = g_director->getCurrentMovie()->getCastMember(sc->getSpriteById(spriteId)->_castId);
|
||||
if (cast && cast->_type == kCastButton)
|
||||
cast->_hilite = !cast->_hilite;
|
||||
}
|
||||
|
||||
registerEvent(kEventMouseUp, spriteId);
|
||||
sc->renderCursor(sc->getSpriteIDFromPos(pos));
|
||||
_currentMouseDownSpriteId = 0;
|
||||
return true;
|
||||
|
||||
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;
|
||||
|
||||
case Common::EVENT_KEYUP:
|
||||
_keyFlags = event.kbd.flags;
|
||||
return true;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void DirectorEngine::waitForClick() {
|
||||
setCursor(kCursorMouseUp);
|
||||
|
||||
|
@ -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();
|
||||
|
||||
while (!_eventQueue.empty()) {
|
||||
LingoEvent el = _eventQueue.pop();
|
||||
if (_vm->getVersion() >= 3 && sc->getCurrentFrame() > 0 && sc->_playState != kPlayStopped && movie->_eventQueue.empty())
|
||||
movie->registerEvent(kEventIdle);
|
||||
|
||||
if (_vm->getCurrentMovie()->getScore()->_playState == kPlayStopped && el.event != kEventStopMovie)
|
||||
while (!movie->_eventQueue.empty()) {
|
||||
LingoEvent el = movie->_eventQueue.pop();
|
||||
|
||||
if (sc->_playState == kPlayStopped && el.event != kEventStopMovie)
|
||||
continue;
|
||||
|
||||
if (lastEventId == el.eventId && !_passEvent)
|
||||
|
@ -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);
|
||||
|
@ -169,7 +169,6 @@ Lingo::Lingo(DirectorEngine *vm) : _vm(vm) {
|
||||
_localvars = NULL;
|
||||
|
||||
// events
|
||||
_nextEventId = 0;
|
||||
_passEvent = false;
|
||||
_perFrameHook = Datum();
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
|
Loading…
Reference in New Issue
Block a user