* 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
This commit is contained in:
Denis Kasak 2009-07-29 01:11:53 +00:00
parent dd9303d27e
commit e9669b8e2b
4 changed files with 80 additions and 56 deletions

View File

@ -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

View File

@ -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;
};

View File

@ -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<Text *>(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<Text *>(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

View File

@ -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
};