diff options
| -rw-r--r-- | engines/draci/draci.cpp | 39 | ||||
| -rw-r--r-- | engines/draci/draci.h | 1 | ||||
| -rw-r--r-- | engines/draci/game.cpp | 136 | ||||
| -rw-r--r-- | engines/draci/game.h | 16 | ||||
| -rw-r--r-- | engines/draci/script.cpp | 3 | 
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> ¶ms) {  	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> ¶ms) { | 
