diff options
-rw-r--r-- | engines/gob/game.cpp | 206 | ||||
-rw-r--r-- | engines/gob/game.h | 60 | ||||
-rw-r--r-- | engines/gob/game_v6.cpp | 13 |
3 files changed, 198 insertions, 81 deletions
diff --git a/engines/gob/game.cpp b/engines/gob/game.cpp index fe48f645ab..5771ee9f76 100644 --- a/engines/gob/game.cpp +++ b/engines/gob/game.cpp @@ -42,44 +42,130 @@ namespace Gob { -Game::Environment::Environment(GobEngine *vm) : _vm(vm) { - _cursorHotspotX = 0; - _cursorHotspotY = 0; - _variables = 0; - _script = 0; - _resources = 0; - _curTotFile[0] = '\0'; +Environments::Environments(GobEngine *vm) : _vm(vm) { + _environments = new Environment[kEnvironmentCount]; + + for (uint i = 0; i < kEnvironmentCount; i++) { + Environment &e = _environments[i]; + + e.cursorHotspotX = 0; + e.cursorHotspotY = 0; + e.variables = 0; + e.script = 0; + e.resources = 0; + e.curTotFile[0] = '\0'; + } } -Game::Environment::~Environment() { - if (_script != _vm->_game->_script) - delete _script; - if (_resources != _vm->_game->_resources) - delete _resources; - if (_variables != _vm->_inter->_variables) - delete _variables; +Environments::~Environments() { + clear(); + + delete[] _environments; +} + +void Environments::clear() { + // Deleting unique variables, script and resources + + for (uint i = 0; i < kEnvironmentCount; i++) { + if (_environments[i].variables == _vm->_inter->_variables) + continue; + + if (!has(_environments[i].variables, i + 1)) + delete _environments[i].variables; + } + + for (uint i = 0; i < kEnvironmentCount; i++) { + if (_environments[i].script == _vm->_game->_script) + continue; + + if (!has(_environments[i].script, i + 1)) + delete _environments[i].script; + } + + for (uint i = 0; i < kEnvironmentCount; i++) { + if (_environments[i].resources == _vm->_game->_resources) + continue; + + if (!has(_environments[i].resources, i + 1)) + delete _environments[i].resources; + } } -void Game::Environment::set() { - _cursorHotspotX = _vm->_draw->_cursorHotspotXVar; - _cursorHotspotY = _vm->_draw->_cursorHotspotYVar; - _script = _vm->_game->_script; - _resources = _vm->_game->_resources; - _variables = _vm->_inter->_variables; - strncpy(_curTotFile, _vm->_game->_curTotFile, 14); +void Environments::set(uint8 env) { + if (env >= kEnvironmentCount) + return; + + Environment &e = _environments[env]; + + // If it already has a unique script or resource assigned, delete them + if ((e.script != _vm->_game->_script) && !has(e.script, 0, env)) + delete e.script; + if ((e.resources != _vm->_game->_resources) && !has(e.resources, 0, env)) + delete e.resources; + + e.cursorHotspotX = _vm->_draw->_cursorHotspotXVar; + e.cursorHotspotY = _vm->_draw->_cursorHotspotYVar; + e.script = _vm->_game->_script; + e.resources = _vm->_game->_resources; + e.variables = _vm->_inter->_variables; + strncpy(e.curTotFile, _vm->_game->_curTotFile, 14); } -void Game::Environment::get() { - _vm->_draw->_cursorHotspotXVar = _cursorHotspotX; - _vm->_draw->_cursorHotspotYVar = _cursorHotspotY; - _vm->_game->_script = _script; - _vm->_game->_resources = _resources; - _vm->_inter->_variables = _variables; - strncpy(_vm->_game->_curTotFile, _curTotFile, 14); +void Environments::get(uint8 env) const { + if (env >= kEnvironmentCount) + return; + + const Environment &e = _environments[env]; + + _vm->_draw->_cursorHotspotXVar = e.cursorHotspotX; + _vm->_draw->_cursorHotspotYVar = e.cursorHotspotY; + _vm->_game->_script = e.script; + _vm->_game->_resources = e.resources; + _vm->_inter->_variables = e.variables; + strncpy(_vm->_game->_curTotFile, e.curTotFile, 14); } -const char *Game::Environment::getTotFile() const { - return _curTotFile; +const char *Environments::getTotFile(uint8 env) const { + if (env >= kEnvironmentCount) + return ""; + + return _environments[env].curTotFile; +} + +bool Environments::has(Variables *variables, uint8 startEnv, int16 except) const { + for (uint i = startEnv; i < kEnvironmentCount; i++) { + if ((except >= 0) && (((uint16) except) == i)) + continue; + + if (_environments[i].variables == variables) + return true; + } + + return false; +} + +bool Environments::has(Script *script, uint8 startEnv, int16 except) const { + for (uint i = startEnv; i < kEnvironmentCount; i++) { + if ((except >= 0) && (((uint16) except) == i)) + continue; + + if (_environments[i].script == script) + return true; + } + + return false; +} + +bool Environments::has(Resources *resources, uint8 startEnv, int16 except) const { + for (uint i = startEnv; i < kEnvironmentCount; i++) { + if ((except >= 0) && (((uint16) except) == i)) + continue; + + if (_environments[i].resources == resources) + return true; + } + + return false; } @@ -123,17 +209,13 @@ Game::Game(GobEngine *vm) : _vm(vm) { _numEnvironments = 0; _curEnvironment = 0; - for (int i = 0; i < kMaxEnvironments; i++) - _environments[i] = new Environment(_vm); - - _script = new Script(_vm); - _resources = new Resources(_vm); + _environments = new Environments(_vm); + _script = new Script(_vm); + _resources = new Resources(_vm); } Game::~Game() { - for (int i = 0; i < kMaxEnvironments; i++) - delete _environments[i]; - + delete _environments; delete _script; delete _resources; } @@ -324,10 +406,10 @@ void Game::start(void) { void Game::totSub(int8 flags, const char *newTotFile) { int8 curBackupPos; - if (_numEnvironments >= kMaxEnvironments) + if (_numEnvironments >= Environments::kEnvironmentCount) return; - _environments[_numEnvironments]->set(); + _environments->set(_numEnvironments); curBackupPos = _curEnvironment; _numEnvironments++; @@ -344,8 +426,10 @@ void Game::totSub(int8 flags, const char *newTotFile) { // else strcat(_curTotFile, ".TOT"); - if (_vm->_inter->_terminate != 0) + if (_vm->_inter->_terminate != 0) { + clearUnusedEnvironment(); return; + } pushCollisions(0); @@ -363,10 +447,11 @@ void Game::totSub(int8 flags, const char *newTotFile) { _vm->_inter->delocateVars(); } + clearUnusedEnvironment(); + _numEnvironments--; _curEnvironment = curBackupPos; - - _environments[_numEnvironments]->get(); + _environments->get(_numEnvironments); } void Game::switchTotSub(int16 index, int16 skipPlay) { @@ -377,29 +462,32 @@ void Game::switchTotSub(int16 index, int16 skipPlay) { return; int16 newPos = _curEnvironment - index - ((index >= 0) ? 1 : 0); - if (newPos >= kMaxEnvironments) + if (newPos >= Environments::kEnvironmentCount) return; // WORKAROUND: Some versions don't make the MOVEMENT menu item unselectable // in the dreamland screen, resulting in a crash when it's clicked. if ((_vm->getGameType() == kGameTypeGob2) && (index == -1) && (skipPlay == 7) && - !scumm_stricmp(_environments[newPos]->getTotFile(), "gob06.tot")) + !scumm_stricmp(_environments->getTotFile(newPos), "gob06.tot")) return; curBackupPos = _curEnvironment; backupedCount = _numEnvironments; - if (_curEnvironment == _numEnvironments) { - _environments[_numEnvironments]->set(); - _numEnvironments++; - } + if (_curEnvironment == _numEnvironments) + _environments->set(_numEnvironments++); + _curEnvironment -= index; if (index >= 0) _curEnvironment--; - _environments[_curEnvironment]->get(); + clearUnusedEnvironment(); + + _environments->get(_curEnvironment); - if (_vm->_inter->_terminate != 0) + if (_vm->_inter->_terminate != 0) { + clearUnusedEnvironment(); return; + } pushCollisions(0); playTot(skipPlay); @@ -409,9 +497,11 @@ void Game::switchTotSub(int16 index, int16 skipPlay) { popCollisions(); + clearUnusedEnvironment(); + _curEnvironment = curBackupPos; _numEnvironments = backupedCount; - _environments[_curEnvironment]->get(); + _environments->get(_curEnvironment); } void Game::setCollisions(byte arg_0) { @@ -495,4 +585,16 @@ void Game::collAreaSub(int16 index, int8 enter) { } } +void Game::clearUnusedEnvironment() { + if (!_environments->has(_script)) { + delete _script; + _script = 0; + } + if (!_environments->has(_resources)) { + delete _resources; + _resources = 0; + } + +} + } // End of namespace Gob diff --git a/engines/gob/game.h b/engines/gob/game.h index e01fe53641..ead4a56492 100644 --- a/engines/gob/game.h +++ b/engines/gob/game.h @@ -32,6 +32,39 @@ class Script; class Resources; class Variables; +class Environments { +public: + static const uint8 kEnvironmentCount = 5; + + Environments(GobEngine *vm); + ~Environments(); + + void set(uint8 env); + void get(uint8 env) const; + + const char *getTotFile(uint8 env) const; + + bool has(Variables *variables, uint8 startEnv = 0, int16 except = -1) const; + bool has(Script *script , uint8 startEnv = 0, int16 except = -1) const; + bool has(Resources *resources, uint8 startEnv = 0, int16 except = -1) const; + + void clear(); + +private: + struct Environment { + int16 cursorHotspotX; + int16 cursorHotspotY; + char curTotFile[14]; + Variables *variables; + Script *script; + Resources *resources; + }; + + GobEngine *_vm; + + Environment *_environments; +}; + class Game { public: @@ -120,29 +153,6 @@ public: virtual void popCollisions(void) = 0; protected: - static const int kMaxEnvironments = 5; - - class Environment { - public: - Environment(GobEngine *vm); - ~Environment(); - - void set(); - void get(); - - const char *getTotFile() const; - - private: - GobEngine *_vm; - - int16 _cursorHotspotX; - int16 _cursorHotspotY; - char _curTotFile[14]; - Variables *_variables; - Script *_script; - Resources *_resources; - }; - int16 _lastCollKey; int16 _lastCollAreaIndex; int16 _lastCollId; @@ -169,7 +179,7 @@ protected: // For totSub() int8 _curEnvironment; int8 _numEnvironments; - Environment *_environments[kMaxEnvironments]; + Environments *_environments; GobEngine *_vm; @@ -181,6 +191,8 @@ protected: virtual void collSub(uint16 offset); virtual int16 checkMousePoint(int16 all, int16 *resId, int16 *resIndex) = 0; + + void clearUnusedEnvironment(); }; class Game_v1 : public Game { diff --git a/engines/gob/game_v6.cpp b/engines/gob/game_v6.cpp index 78579b8c38..8d40d41acc 100644 --- a/engines/gob/game_v6.cpp +++ b/engines/gob/game_v6.cpp @@ -49,10 +49,10 @@ void Game_v6::totSub(int8 flags, const char *newTotFile) { if ((flags == 16) || (flags == 17)) warning("Urban Stub: Game_v6::totSub(), flags == %d", flags); - if (_numEnvironments >= kMaxEnvironments) + if (_numEnvironments >= Environments::kEnvironmentCount) return; - _environments[_numEnvironments]->set(); + _environments->set(_numEnvironments); curBackupPos = _curEnvironment; _numEnvironments++; @@ -70,8 +70,10 @@ void Game_v6::totSub(int8 flags, const char *newTotFile) { strncpy0(_curTotFile, newTotFile, 9); strcat(_curTotFile, ".TOT"); - if (_vm->_inter->_terminate != 0) + if (_vm->_inter->_terminate != 0) { + clearUnusedEnvironment(); return; + } pushCollisions(0); @@ -90,10 +92,11 @@ void Game_v6::totSub(int8 flags, const char *newTotFile) { _vm->_inter->delocateVars(); } + clearUnusedEnvironment(); + _numEnvironments--; _curEnvironment = curBackupPos; - - _environments[_numEnvironments]->get(); + _environments->get(_numEnvironments); } int16 Game_v6::addNewCollision(int16 id, uint16 left, uint16 top, |