aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Kasak2009-07-31 04:32:33 +0000
committerDenis Kasak2009-07-31 04:32:33 +0000
commit18a8b5b3af96bc0d74167db27552956b646cd0d0 (patch)
tree73d27e06aa7d265b781019b0a106800d8e686a5a
parent167b6da23050a60ee0d56c6b435c3c1bbb159d8a (diff)
downloadscummvm-rg350-18a8b5b3af96bc0d74167db27552956b646cd0d0.tar.gz
scummvm-rg350-18a8b5b3af96bc0d74167db27552956b646cd0d0.tar.bz2
scummvm-rg350-18a8b5b3af96bc0d74167db27552956b646cd0d0.zip
* Added Game::runGateProgram()
* Added a separate mechanism to Game to keep track both of the current room number and the next room/gate. Periodically, I check whether the new room differs from the old one and, if it does, I do the change. Doing it any other would is nearly impossible because of the way the original scripts were written. * Added GPL command Script::newRoom(). Rooms can now be traversed by clicking on their exits. Also, the intro animation partly works. Some parts go by far too soon. I assume this is because the engine still lacks a dialogue GPL command. * Fixed bug where the gates array of a room was not cleared between uses. * Save old jump value when we enter Script::run() and restore it in the end (mimicking the original engine). * Fixed small bug where the gate was supposed to be stored as the first in-game variable and not the room number. svn-id: r42957
-rw-r--r--engines/draci/game.cpp72
-rw-r--r--engines/draci/game.h7
-rw-r--r--engines/draci/script.cpp24
-rw-r--r--engines/draci/script.h1
4 files changed, 94 insertions, 10 deletions
diff --git a/engines/draci/game.cpp b/engines/draci/game.cpp
index 7b6e3608e7..3665c09d71 100644
--- a/engines/draci/game.cpp
+++ b/engines/draci/game.cpp
@@ -153,13 +153,31 @@ Game::Game(DraciEngine *vm) : _vm(vm) {
void Game::start() {
while (!shouldQuit()) {
- Game::loop();
+
+ if (_newRoom != _currentRoom._roomNum) {
+
+ changeRoom(_newRoom);
+
+ _currentRoom._roomNum = _newRoom;
+ _currentGate = _newGate;
+
+ // HACK: Won't be needed once I've implemented the loop properly
+ _roomChange = false;
+
+ runGateProgram(_newGate);
+ }
+
+ loop();
}
}
void Game::init() {
_shouldQuit = false;
_shouldExitLoop = false;
+
+ // HACK: Won't be needed once I've implemented the loop properly
+ _roomChange = false;
+
_loopStatus = kStatusOrdinary;
_objUnderCursor = kOverlayImage;
@@ -177,15 +195,20 @@ void Game::init() {
_currentRoom._roomNum = _info._startRoom;
_currentGate = 0;
- _variables[0] = _currentRoom._roomNum;
- _variables[1] = _currentGate;
+ _newRoom = _currentRoom._roomNum;
+ _newGate = _currentGate;
- changeRoom(_info._startRoom);
+ _variables[0] = _currentGate;
+ _variables[1] = _currentRoom._roomNum;
+
+ changeRoom(_currentRoom._roomNum);
+ runGateProgram(_currentGate);
}
void Game::loop() {
-
+
do {
+
_vm->handleEvents();
if (_currentRoom._mouseOn) {
@@ -235,6 +258,9 @@ void Game::loop() {
_vm->_screen->copyToScreen();
_vm->_system->delayMillis(20);
+ // HACK: Won't be needed once the game loop is implemented properly
+ _shouldExitLoop = _shouldExitLoop || _roomChange;
+
} while (!shouldExitLoop());
}
@@ -352,10 +378,11 @@ void Game::loadRoom(int roomNum) {
debugC(4, kDraciLogicDebugLevel, "Gates: %d", _currentRoom._numGates);
// Read in the gates' numbers
- Common::Array<int> gates;
+
+ _currentRoom._gates.clear();
for (uint i = 0; i < _currentRoom._numGates; ++i) {
- gates.push_back(roomReader.readSint16LE() - 1);
+ _currentRoom._gates.push_back(roomReader.readSint16LE());
}
// Load the room's objects
@@ -605,12 +632,39 @@ void Game::changeRoom(uint roomNum) {
loadOverlays();
}
+void Game::runGateProgram(int gate) {
+
+ // Mark last animation
+ int lastAnimIndex = _vm->_anims->getLastIndex();
+
+ // Run gate program
+ _vm->_script->run(_currentRoom._program, _currentRoom._gates[gate]);
+
+ // Delete all animations loaded after the marked one
+ // (from objects and from the AnimationManager)
+ for (uint i = 0; i < getNumObjects(); ++i) {
+ GameObject *obj = &_objects[i];
+
+ for (uint j = 0; j < obj->_anims.size(); ++j) {
+ Animation *anim;
+
+ anim = _vm->_anims->getAnimation(obj->_anims[j]);
+ if (anim != NULL && anim->getIndex() > lastAnimIndex)
+ obj->_anims.remove_at(j);
+ }
+ }
+
+ _vm->_anims->deleteAfterIndex(lastAnimIndex);
+
+ setExitLoop(false);
+}
+
int Game::getRoomNum() {
return _currentRoom._roomNum;
}
void Game::setRoomNum(int room) {
- _currentRoom._roomNum = room;
+ _newRoom = room;
}
int Game::getGateNum() {
@@ -618,7 +672,7 @@ int Game::getGateNum() {
}
void Game::setGateNum(int gate) {
- _currentGate = gate;
+ _newGate = gate;
}
void Game::setLoopStatus(LoopStatus status) {
diff --git a/engines/draci/game.h b/engines/draci/game.h
index c6168d6d49..1e488ca083 100644
--- a/engines/draci/game.h
+++ b/engines/draci/game.h
@@ -131,6 +131,7 @@ struct Room {
double _pers0, _persStep;
byte _escRoom;
byte _numGates;
+ Common::Array<int> _gates;
GPL2Program _program;
};
@@ -223,6 +224,10 @@ public:
bool shouldExitLoop() { return _shouldExitLoop; }
void setExitLoop(bool exit) { _shouldExitLoop = exit; }
+ void runGateProgram(int gate);
+
+ bool _roomChange;
+
private:
DraciEngine *_vm;
@@ -236,6 +241,8 @@ private:
Room _currentRoom;
int _currentGate;
+ int _newRoom;
+ int _newGate;
LoopStatus _loopStatus;
diff --git a/engines/draci/script.cpp b/engines/draci/script.cpp
index 8ec9e5f582..78ea91b3f7 100644
--- a/engines/draci/script.cpp
+++ b/engines/draci/script.cpp
@@ -66,7 +66,7 @@ void Script::setupCommandList() {
{ 12, 2, "BlackPalette", 0, { 0 }, NULL },
{ 13, 1, "FadePalette", 3, { 1, 1, 1 }, NULL },
{ 13, 2, "FadePalettePlay", 3, { 1, 1, 1 }, NULL },
- { 14, 1, "NewRoom", 2, { 3, 1 }, NULL },
+ { 14, 1, "NewRoom", 2, { 3, 1 }, &Script::newRoom },
{ 15, 1, "ExecInit", 1, { 3 }, &Script::execInit },
{ 15, 2, "ExecLook", 1, { 3 }, &Script::execLook },
{ 15, 3, "ExecUse", 1, { 3 }, &Script::execUse },
@@ -516,6 +516,23 @@ void Script::walkOn(Common::Queue<int> &params) {
_vm->_game->walkHero(x, y);
}
+
+void Script::newRoom(Common::Queue<int> &params) {
+
+ if (_vm->_game->getLoopStatus() == kStatusInventory) {
+ return;
+ }
+
+ int room = params.pop() - 1;
+ int gate = params.pop() - 1;
+
+ _vm->_game->setRoomNum(room);
+ _vm->_game->setGateNum(gate);
+
+ // HACK: Won't be needed once I've implemented the loop properly
+ _vm->_game->_roomChange = true;
+}
+
/**
* @brief Evaluates mathematical expressions
* @param reader Stream reader set to the beginning of the expression
@@ -679,6 +696,8 @@ const GPL2Command *Script::findCommand(byte num, byte subnum) {
int Script::run(GPL2Program program, uint16 offset) {
+ int oldJump = _jump;
+
// Mark the last animation index before we do anything so a Release command
// doesn't unload too many animations if we forget to use a Mark command first
_vm->_game->setMarkedAnimationIndex(_vm->_anims->getLastIndex());
@@ -748,6 +767,7 @@ int Script::run(GPL2Program program, uint16 offset) {
else {
debugC(1, kDraciBytecodeDebugLevel, "Unknown opcode %d, %d",
num, subnum);
+ abort();
}
GPLHandler handler = cmd->_handler;
@@ -759,6 +779,8 @@ int Script::run(GPL2Program program, uint16 offset) {
} while (cmd->_name != "gplend" && cmd->_name != "exit");
+ _jump = oldJump;
+
return 0;
}
diff --git a/engines/draci/script.h b/engines/draci/script.h
index 69effbedf0..d799dcaed5 100644
--- a/engines/draci/script.h
+++ b/engines/draci/script.h
@@ -114,6 +114,7 @@ private:
void walkOn(Common::Queue<int> &params);
void play(Common::Queue<int> &params);
void startPlay(Common::Queue<int> &params);
+ void newRoom(Common::Queue<int> &params);
int operAnd(int op1, int op2);
int operOr(int op1, int op2);