aboutsummaryrefslogtreecommitdiff
path: root/engines/draci
diff options
context:
space:
mode:
authorRobert Špalek2009-10-01 08:32:35 +0000
committerRobert Špalek2009-10-01 08:32:35 +0000
commit24d649b972235d85d0e4d96de4607fa87d4f26c1 (patch)
tree6e02d575205b5dd0a20871bb95ec3bcb0b5e7abe /engines/draci
parent2d29625f0e8afba7a447be49615742f6612d38a0 (diff)
downloadscummvm-rg350-24d649b972235d85d0e4d96de4607fa87d4f26c1.tar.gz
scummvm-rg350-24d649b972235d85d0e4d96de4607fa87d4f26c1.tar.bz2
scummvm-rg350-24d649b972235d85d0e4d96de4607fa87d4f26c1.zip
Clean up room changing code and support returning from the map.
Completely changed the interface, removing unused methods and attributes, renaming other ones to reflect what they do, and moving some methods into the private section. Code changing the location, originally scattered over many pieces of code, has been unified into one place. Remember the previous room when entering the map so that one can return there. Also, the event handler processes one event at a time, preventing lost clicks on touchpads. svn-id: r44508
Diffstat (limited to 'engines/draci')
-rw-r--r--engines/draci/draci.cpp39
-rw-r--r--engines/draci/draci.h1
-rw-r--r--engines/draci/game.cpp136
-rw-r--r--engines/draci/game.h16
-rw-r--r--engines/draci/script.cpp3
5 files changed, 82 insertions, 113 deletions
diff --git a/engines/draci/draci.cpp b/engines/draci/draci.cpp
index 55c42c9097..6290ee01dc 100644
--- a/engines/draci/draci.cpp
+++ b/engines/draci/draci.cpp
@@ -173,15 +173,6 @@ int DraciEngine::init() {
return Common::kNoError;
}
-int DraciEngine::go() {
- debugC(1, kDraciGeneralDebugLevel, "DraciEngine::go()");
-
- _game->init();
- _game->start();
-
- return Common::kNoError;
-}
-
bool DraciEngine::handleEvents() {
Common::Event event;
bool quit = false;
@@ -193,20 +184,19 @@ bool DraciEngine::handleEvents() {
break;
case Common::EVENT_KEYDOWN:
if (event.kbd.keycode == Common::KEYCODE_RIGHT) {
- _game->setRoomNum(_game->nextRoomNum());
- _game->setGateNum(0);
+ _game->scheduleEnteringRoomUsingGate(_game->nextRoomNum(), 0);
} else if (event.kbd.keycode == Common::KEYCODE_LEFT) {
- _game->setRoomNum(_game->prevRoomNum());
- _game->setGateNum(0);
+ _game->scheduleEnteringRoomUsingGate(_game->prevRoomNum(), 0);
} else if (event.kbd.keycode == Common::KEYCODE_ESCAPE) {
- int escRoom = _game->getEscRoom();
+ const int escRoom = _game->getRoomNum() != _game->getMapRoom()
+ ? _game->getEscRoom() : _game->getPreviousRoomNum();
// Check if there is an escape room defined for the current room
if (escRoom != kNoEscRoom) {
// Schedule room change
- _game->setRoomNum(_game->getEscRoom());
- _game->setGateNum(0);
+ // TODO: gate 0 is not always the best one for returning from the map
+ _game->scheduleEnteringRoomUsingGate(escRoom, 0);
_game->setExitLoop(true);
// End any currently running GPL programs
@@ -214,11 +204,9 @@ bool DraciEngine::handleEvents() {
}
} else if (event.kbd.keycode == Common::KEYCODE_m) {
if (_game->getLoopStatus() == kStatusOrdinary) {
- // TODO: record the current room number
- // so that we can quickly exit there
- // when Escape is pressed
- _game->setRoomNum(_game->getMapRoom());
- _game->setGateNum(0);
+ const int new_room = _game->getRoomNum() != _game->getMapRoom()
+ ? _game->getMapRoom() : _game->getPreviousRoomNum();
+ _game->scheduleEnteringRoomUsingGate(new_room, 0);
}
} else if (event.kbd.keycode == Common::KEYCODE_w) {
// Show walking map toggle
@@ -236,6 +224,12 @@ bool DraciEngine::handleEvents() {
default:
_mouse->handleEvent(event);
}
+
+ // TODO: I place the break here to make sure that each event is
+ // processed. If I don't do that and allow more than 1 event,
+ // then a very quick succession of mouse button down and up
+ // (occuring on a touchpad) cancels each other.
+ break;
}
// Show walking map overlay
@@ -282,7 +276,8 @@ DraciEngine::~DraciEngine() {
Common::Error DraciEngine::run() {
init();
- go();
+ _game->init();
+ _game->start();
return Common::kNoError;
}
diff --git a/engines/draci/draci.h b/engines/draci/draci.h
index 9ef229c686..926742732b 100644
--- a/engines/draci/draci.h
+++ b/engines/draci/draci.h
@@ -46,7 +46,6 @@ public:
~DraciEngine();
int init();
- int go();
Common::Error run();
bool hasFeature(Engine::EngineFeature f) const;
diff --git a/engines/draci/game.cpp b/engines/draci/game.cpp
index 053494c458..44a77f8f22 100644
--- a/engines/draci/game.cpp
+++ b/engines/draci/game.cpp
@@ -142,53 +142,13 @@ Game::Game(DraciEngine *vm) : _vm(vm) {
void Game::start() {
while (!shouldQuit()) {
+ debugC(1, kDraciGeneralDebugLevel, "Game::start()");
+
// Whenever the top-level loop is entered, it should not finish unless
// the exit is triggered by a script
_shouldExitLoop = false;
- // If the scheduled room differs from the current one, do a room change
- if (_newRoom != _currentRoom._roomNum) {
-
- // Set the first two variables to the new room / gate
- // Before setting these variables we have to convert the values to
- // 1-based indexing because this is how everything is stored in the data files
- _variables[0] = _newGate + 1;
- _variables[1] = _newRoom + 1;
-
- // If the new room is the map room, set the appropriate coordinates
- // for the dragon in the persons array
- if (_newRoom == _info._mapRoom) {
- _persons[kDragonObject]._x = 160;
- _persons[kDragonObject]._y = 0;
- }
-
- setLoopSubstatus(kSubstatusOrdinary);
-
- // Do the actual change
- changeRoom(_newRoom);
-
- // Set the current room / gate to the new value
- _currentRoom._roomNum = _newRoom;
- _currentGate = _newGate;
-
- // Run the program for the gate the dragon came through
- runGateProgram(_newGate);
-
- // Set cursor state
- // Need to do this after we set the palette since the cursors use it
- if (_currentRoom._mouseOn) {
- debugC(6, kDraciLogicDebugLevel, "Mouse: ON");
- _vm->_mouse->cursorOn();
- } else {
- debugC(6, kDraciLogicDebugLevel, "Mouse: OFF");
- _vm->_mouse->cursorOff();
- }
- }
-
- // Mimic the original engine by setting the loop status to Ordinary before
- // entering the main loop
- setLoopStatus(kStatusOrdinary);
-
+ enterNewRoom();
loop();
}
}
@@ -205,7 +165,6 @@ void Game::init() {
_vm->_mouse->setCursorType(kNormalCursor);
- _loopStatus = kStatusOrdinary;
_oldObjUnderCursor = _objUnderCursor = kOverlayImage;
// Set the inventory to empty initially
@@ -252,19 +211,9 @@ void Game::init() {
debugC(4, kDraciLogicDebugLevel, "Running init program for the dragon object...");
_vm->_script->run(dragon->_program, dragon->_init);
- _currentRoom._roomNum = _info._startRoom;
- _currentGate = 0;
-
- _newRoom = _currentRoom._roomNum;
- _newGate = _currentGate;
-
- // Before setting these variables we have to convert the values to 1-based indexing
- // because this is how everything is stored in the data files
- _variables[0] = _currentGate + 1;
- _variables[1] = _currentRoom._roomNum + 1;
-
- changeRoom(_currentRoom._roomNum);
- runGateProgram(_currentGate);
+ // Make sure we enter the right room in start().
+ _previousRoom = _currentRoom._roomNum = kNoEscRoom;
+ scheduleEnteringRoomUsingGate(_info._startRoom, 0);
}
void Game::loop() {
@@ -489,7 +438,7 @@ void Game::loop() {
_vm->_system->delayMillis(20);
// HACK: Won't be needed once the game loop is implemented properly
- _shouldExitLoop = _shouldExitLoop || (_newRoom != _currentRoom._roomNum &&
+ _shouldExitLoop = _shouldExitLoop || (_newRoom != getRoomNum() &&
(_loopStatus == kStatusOrdinary || _loopStatus == kStatusGate));
} while (!shouldExitLoop());
@@ -713,7 +662,7 @@ void Game::inventoryInit() {
_vm->_mouse->cursorOn();
// Set the appropriate loop status
- _loopStatus = kStatusInventory;
+ setLoopStatus(kStatusInventory);
// TODO: This will be used for exiting the inventory automatically when the mouse
// is outside it for some time
@@ -722,7 +671,7 @@ void Game::inventoryInit() {
void Game::inventoryDone() {
_vm->_mouse->cursorOn();
- _loopStatus = kStatusOrdinary;
+ setLoopStatus(kStatusOrdinary);
_vm->_anims->unpauseAnimations();
@@ -892,7 +841,7 @@ void Game::dialogueInit(int dialogID) {
_vm->_anims->play(_dialogueAnims[i]->getID());
}
- _loopStatus = kStatusDialogue;
+ setLoopStatus(kStatusDialogue);
_lastBlock = -1;
_dialogueBegin = true;
}
@@ -906,7 +855,7 @@ void Game::dialogueDone() {
delete[] _dialogueBlocks;
- _loopStatus = kStatusOrdinary;
+ setLoopStatus(kStatusOrdinary);
_vm->_mouse->setCursorType(kNormalCursor);
}
@@ -1261,7 +1210,7 @@ void Game::loadOverlays() {
const BAFile *overlayHeader;
- overlayHeader = _vm->_roomsArchive->getFile(_currentRoom._roomNum * 4 + 2);
+ overlayHeader = _vm->_roomsArchive->getFile(getRoomNum() * 4 + 2);
Common::MemoryReadStream overlayReader(overlayHeader->_data, overlayHeader->_length);
for (int i = 0; i < _currentRoom._numOverlays; i++) {
@@ -1282,8 +1231,11 @@ void Game::loadOverlays() {
_vm->_screen->getSurface()->markDirty();
}
-void Game::changeRoom(uint roomNum) {
- debugC(1, kDraciLogicDebugLevel, "Changing to room %d", roomNum);
+void Game::enterNewRoom() {
+ if (_newRoom == getRoomNum()) {
+ return;
+ }
+ debugC(1, kDraciLogicDebugLevel, "Entering room %d using gate %d", _newRoom, _newGate);
// Clear archives
_vm->_roomsArchive->clearCache();
@@ -1299,18 +1251,19 @@ void Game::changeRoom(uint roomNum) {
// Delete walking map testing overlay
_vm->_anims->deleteAnimation(kWalkingMapOverlay);
- int oldRoomNum = _currentRoom._roomNum;
-
// TODO: Make objects capable of stopping their own animations
const GameObject *dragon = getObject(kDragonObject);
for (uint i = 0; i < dragon->_anims.size(); ++i) {
_vm->_anims->stop(dragon->_anims[i]);
}
+ // Remember the previous room for returning back from the map.
+ _previousRoom = getRoomNum();
+
for (uint i = 0; i < _info._numObjects; ++i) {
GameObject *obj = &_objects[i];
- if (i != 0 && (obj->_location == oldRoomNum)) {
+ if (i != 0 && (obj->_location == _previousRoom)) {
for (uint j = 0; j < obj->_anims.size(); ++j) {
_vm->_anims->deleteAnimation(obj->_anims[j]);
}
@@ -1318,9 +1271,39 @@ void Game::changeRoom(uint roomNum) {
}
}
- _currentRoom._roomNum = roomNum;
- loadRoom(roomNum);
+ // Set the current room to the new value
+ _currentRoom._roomNum = _newRoom;
+
+ // Before setting these variables we have to convert the values to 1-based indexing
+ // because this is how everything is stored in the data files
+ _variables[0] = _newGate + 1;
+ _variables[1] = _newRoom + 1;
+
+ // If the new room is the map room, set the appropriate coordinates
+ // for the dragon in the persons array
+ if (_newRoom == _info._mapRoom) {
+ _persons[kDragonObject]._x = 160;
+ _persons[kDragonObject]._y = 0;
+ }
+
+ loadRoom(_newRoom);
loadOverlays();
+
+ // Run the program for the gate the dragon came through
+ runGateProgram(_newGate);
+
+ // Set cursor state
+ // Need to do this after we set the palette since the cursors use it
+ if (_currentRoom._mouseOn) {
+ debugC(6, kDraciLogicDebugLevel, "Mouse: ON");
+ _vm->_mouse->cursorOn();
+ } else {
+ debugC(6, kDraciLogicDebugLevel, "Mouse: OFF");
+ _vm->_mouse->cursorOff();
+ }
+
+ // Reset the loop status.
+ setLoopStatus(kStatusOrdinary);
}
void Game::runGateProgram(int gate) {
@@ -1328,6 +1311,7 @@ void Game::runGateProgram(int gate) {
// Set the appropriate loop statu before executing the gate program
setLoopStatus(kStatusGate);
+ setLoopSubstatus(kSubstatusOrdinary);
// Mark last animation
int lastAnimIndex = _vm->_anims->getLastIndex();
@@ -1388,20 +1372,16 @@ double Game::getPersStep() const {
return _currentRoom._persStep;
}
-
int Game::getRoomNum() const {
return _currentRoom._roomNum;
}
-void Game::setRoomNum(int room) {
- _newRoom = room;
+int Game::getPreviousRoomNum() const {
+ return _previousRoom;
}
-int Game::getGateNum() const {
- return _currentGate;
-}
-
-void Game::setGateNum(int gate) {
+void Game::scheduleEnteringRoomUsingGate(int room, int gate) {
+ _newRoom = room;
_newGate = gate;
}
diff --git a/engines/draci/game.h b/engines/draci/game.h
index 9e5fabd03d..9766e9a863 100644
--- a/engines/draci/game.h
+++ b/engines/draci/game.h
@@ -230,8 +230,6 @@ public:
void start();
void loop();
- void changeRoom(uint roomNum);
-
// HACK: this is only for testing
int nextRoomNum() const {
int n = _currentRoom._roomNum;
@@ -261,7 +259,6 @@ public:
int getHeroY() const;
void positionAnimAsHero(Animation *anim);
- void loadRoom(int roomNum);
int loadAnimation(uint animNum, uint z);
void loadOverlays();
void loadObject(uint numObj);
@@ -278,10 +275,8 @@ public:
const Person *getPerson(int personID) const;
int getRoomNum() const;
- void setRoomNum(int room);
-
- int getGateNum() const;
- void setGateNum(int gate);
+ int getPreviousRoomNum() const;
+ void scheduleEnteringRoomUsingGate(int room, int gate);
double getPers0() const;
double getPersStep() const;
@@ -311,8 +306,6 @@ public:
bool shouldExitLoop() const { return _shouldExitLoop; }
void setExitLoop(bool exit) { _shouldExitLoop = exit; }
- void runGateProgram(int gate);
-
void setSpeechTick(uint tick);
void updateTitle();
@@ -345,6 +338,9 @@ public:
private:
void deleteAnimationsAfterIndex(int lastAnimIndex);
+ void enterNewRoom();
+ void loadRoom(int roomNum);
+ void runGateProgram(int gate);
DraciEngine *_vm;
@@ -365,9 +361,9 @@ private:
bool _inventoryExit;
Room _currentRoom;
- int _currentGate;
int _newRoom;
int _newGate;
+ int _previousRoom;
uint *_dialogueOffsets;
int _currentDialogue;
diff --git a/engines/draci/script.cpp b/engines/draci/script.cpp
index aec95241e0..bb53308134 100644
--- a/engines/draci/script.cpp
+++ b/engines/draci/script.cpp
@@ -656,8 +656,7 @@ void Script::newRoom(Common::Queue<int> &params) {
int room = params.pop() - 1;
int gate = params.pop() - 1;
- _vm->_game->setRoomNum(room);
- _vm->_game->setGateNum(gate);
+ _vm->_game->scheduleEnteringRoomUsingGate(room, gate);
}
void Script::talk(Common::Queue<int> &params) {