aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/gob/game.cpp206
-rw-r--r--engines/gob/game.h60
-rw-r--r--engines/gob/game_v6.cpp13
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,