From e9669b8e2bcc4a65d5cc1225e9328d9171726690 Mon Sep 17 00:00:00 2001 From: Denis Kasak Date: Wed, 29 Jul 2009 01:11:53 +0000 Subject: [PATCH] * Moved event handling to DraciEngine::handleEvents() * Added Game::start() method which is called from DraciEngine::go() * Made Game::loop() suitable for calling from other places (like GPL scripts) by handling events, redrawing the screen, etc from inside. This way it doesn't freeze the game if it doesn't return immediately. * Added Game::shouldQuit() and Game::setQuit() which can be used to signal the engine to quit. * Fixed race condition related to mouse buttons not getting released. * Instead of deleting frames for the title animation and adding a new one, reset the text for its frame. svn-id: r42875 --- engines/draci/draci.cpp | 83 ++++++++++++++++++++--------------------- engines/draci/draci.h | 4 ++ engines/draci/game.cpp | 40 +++++++++++++++----- engines/draci/game.h | 9 +++-- 4 files changed, 80 insertions(+), 56 deletions(-) diff --git a/engines/draci/draci.cpp b/engines/draci/draci.cpp index 057000c7caf..ae4f154755c 100644 --- a/engines/draci/draci.cpp +++ b/engines/draci/draci.cpp @@ -142,6 +142,8 @@ int DraciEngine::init() { return Common::kUnknownError; } + _showWalkingMap = false; + // Basic archive test debugC(2, kDraciGeneralDebugLevel, "Running archive tests..."); Common::String path("INIT.DFW"); @@ -167,54 +169,49 @@ int DraciEngine::init() { int DraciEngine::go() { debugC(1, kDraciGeneralDebugLevel, "DraciEngine::go()"); - debugC(2, kDraciGeneralDebugLevel, "Running graphics/animation test..."); - _game->init(); - - Common::Event event; - bool quit = false; - bool showWalkingMap = false; - while (!quit) { - while (_eventMan->pollEvent(event)) { - switch (event.type) { - case Common::EVENT_QUIT: - quit = true; - break; - case Common::EVENT_KEYDOWN: - if (event.kbd.keycode == Common::KEYCODE_RIGHT) - _game->changeRoom(_game->nextRoomNum()); - - else if (event.kbd.keycode == Common::KEYCODE_LEFT) - _game->changeRoom(_game->prevRoomNum()); - - // Show walking map toggle - else if (event.kbd.keycode == Common::KEYCODE_w) { - showWalkingMap = !showWalkingMap; - } - break; - default: - _mouse->handleEvent(event); - } - } - - // Show walking map overlay - // If the walking map overlay is already in the wanted state don't - // start / stop it constantly - if (showWalkingMap && !_anims->getAnimation(kWalkingMapOverlay)->isPlaying()) { - _anims->play(kWalkingMapOverlay); - } else if (!showWalkingMap && _anims->getAnimation(kWalkingMapOverlay)->isPlaying()) { - _anims->stop(kWalkingMapOverlay); - } - - _game->loop(); - _anims->drawScene(_screen->getSurface()); - _screen->copyToScreen(); - _system->delayMillis(20); - } + _game->start(); return Common::kNoError; } +bool DraciEngine::handleEvents() { + Common::Event event; + bool quit = false; + + while (_eventMan->pollEvent(event)) { + switch (event.type) { + case Common::EVENT_QUIT: + _game->setQuit(true); + break; + case Common::EVENT_KEYDOWN: + if (event.kbd.keycode == Common::KEYCODE_RIGHT) + _game->changeRoom(_game->nextRoomNum()); + + else if (event.kbd.keycode == Common::KEYCODE_LEFT) + _game->changeRoom(_game->prevRoomNum()); + + // Show walking map toggle + else if (event.kbd.keycode == Common::KEYCODE_w) { + _showWalkingMap = !_showWalkingMap; + } + break; + default: + _mouse->handleEvent(event); + } + } + + // Show walking map overlay + // If the walking map overlay is already in the wanted state don't + // start / stop it constantly + if (_showWalkingMap && !_anims->getAnimation(kWalkingMapOverlay)->isPlaying()) { + _anims->play(kWalkingMapOverlay); + } else if (!_showWalkingMap && _anims->getAnimation(kWalkingMapOverlay)->isPlaying()) { + _anims->stop(kWalkingMapOverlay); + } + + return quit; +} DraciEngine::~DraciEngine() { // Dispose your resources here diff --git a/engines/draci/draci.h b/engines/draci/draci.h index e6b78f310ab..1f43fc8f689 100644 --- a/engines/draci/draci.h +++ b/engines/draci/draci.h @@ -50,6 +50,8 @@ public: Common::Error run(); bool hasFeature(Engine::EngineFeature f) const; + + bool handleEvents(); Screen *_screen; Mouse *_mouse; @@ -70,6 +72,8 @@ public: BArchive *_walkingMapsArchive; BArchive *_initArchive; + bool _showWalkingMap; + Common::RandomSource _rnd; }; diff --git a/engines/draci/game.cpp b/engines/draci/game.cpp index 620a8ca9e7f..094364be6c5 100644 --- a/engines/draci/game.cpp +++ b/engines/draci/game.cpp @@ -151,11 +151,21 @@ Game::Game(DraciEngine *vm) : _vm(vm) { assert(numIcons == _info._numIcons); } +void Game::start() { + while (!shouldQuit()) { + Game::loop(); + } +} + void Game::init() { + _shouldQuit = false; _loopStatus = kStatusOrdinary; _objUnderCursor = kOverlayImage; - _vm->_anims->addText(kTitleText, true); + // Initialize animation for object / room titles + Animation *titleAnim = _vm->_anims->addText(kTitleText, true); + Text *title = new Text ("", _vm->_bigFont, kFontColour3, 0, 0); + titleAnim->addFrame(title); loadObject(kDragonObject); @@ -169,6 +179,11 @@ void Game::init() { void Game::loop() { + _vm->handleEvents(); + + if (shouldQuit()) + return; + if (_currentRoom._mouseOn) { int x = _vm->_mouse->getPosX(); int y = _vm->_mouse->getPosY(); @@ -178,36 +193,40 @@ void Game::loop() { } int animUnderCursor = _vm->_anims->getTopAnimationID(x, y); - Animation *anim = _vm->_anims->getAnimation(animUnderCursor); + //Animation *anim = _vm->_anims->getAnimation(animUnderCursor); int curObject = getObjectWithAnimation(animUnderCursor); GameObject *obj = &_objects[curObject]; - Animation *atitle = _vm->_anims->getAnimation(kTitleText); + Animation *titleAnim = _vm->_anims->getAnimation(kTitleText); // TODO: Handle displaying title in the proper location - atitle->deleteFrames(); if (curObject != kNotFound) { - Text *title = new Text (obj->_title, _vm->_bigFont, kFontColour1, 0, 0); - atitle->addFrame(title); + titleAnim->markDirtyRect(_vm->_screen->getSurface()); + reinterpret_cast(titleAnim->getFrame())->setText(obj->_title); // HACK: Test running look and use scripts if (_vm->_mouse->lButtonPressed()) { - _vm->_script->run(obj->_program, obj->_look); _vm->_mouse->lButtonSet(false); + _vm->_script->run(obj->_program, obj->_look); } if (_vm->_mouse->rButtonPressed()) { + _vm->_mouse->rButtonSet(false); _vm->_script->run(obj->_program, obj->_use); - _vm->_mouse->rButtonSet(false); } + } else { + titleAnim->markDirtyRect(_vm->_screen->getSurface()); + reinterpret_cast(titleAnim->getFrame())->setText(""); } debugC(2, kDraciAnimationDebugLevel, "Anim under cursor: %d", animUnderCursor); - - } + + _vm->_anims->drawScene(_vm->_screen->getSurface()); + _vm->_screen->copyToScreen(); + _vm->_system->delayMillis(20); } int Game::getObjectWithAnimation(int animID) { @@ -626,6 +645,7 @@ Game::~Game() { delete[] _objects; } + bool WalkingMap::isWalkable(int x, int y) { // Convert to map pixels diff --git a/engines/draci/game.h b/engines/draci/game.h index fbc1d3283ef..5cfa5d894ee 100644 --- a/engines/draci/game.h +++ b/engines/draci/game.h @@ -86,8 +86,6 @@ private: struct GameObject { - GameObject() {} - uint _init, _look, _use, _canUse; bool _imInit, _imLook, _imUse; byte _walkDir; @@ -162,6 +160,7 @@ public: ~Game(); void init(); + void start(); void loop(); void changeRoom(uint roomNum); @@ -213,6 +212,9 @@ public: void setLoopStatus(LoopStatus status); LoopStatus getLoopStatus(); + bool shouldQuit() { return _shouldQuit; } + void setQuit(bool quit) { _shouldQuit = quit; } + private: DraciEngine *_vm; @@ -227,8 +229,9 @@ private: Room _currentRoom; LoopStatus _loopStatus; - int _objUnderCursor; + bool _shouldQuit; + int _objUnderCursor; int _markedAnimationIndex; //!< Used by the Mark GPL command };