diff options
author | Torbjörn Andersson | 2004-09-08 07:10:54 +0000 |
---|---|---|
committer | Torbjörn Andersson | 2004-09-08 07:10:54 +0000 |
commit | 412f7105f06343c6a592a58df4b575fd64b74024 (patch) | |
tree | 70a5b6f55392470120ea4329c84f8f4ffa355251 | |
parent | d662863db152e85c85f82220e37eed20d89d7fdd (diff) | |
download | scummvm-rg350-412f7105f06343c6a592a58df4b575fd64b74024.tar.gz scummvm-rg350-412f7105f06343c6a592a58df4b575fd64b74024.tar.bz2 scummvm-rg350-412f7105f06343c6a592a58df4b575fd64b74024.zip |
Fixed evil regression #2. Restarting the game, or using the "start" debug
command, would close the global script variables and player object
resources, without reopening them again. This made them fair game for the
resource expiration mechanism. The player object is probably referenced
often enough to stay alive, but the variables died on me pretty quickly,
causing ScummVM to crash.
I've also added a "reslist" debug command to make this sort of things
easier to spot. By default it only lists resources with refCount > 0. Use
"reslist 0" to see all the cached resources as well.
svn-id: r14958
-rw-r--r-- | sword2/console.cpp | 12 | ||||
-rw-r--r-- | sword2/console.h | 1 | ||||
-rw-r--r-- | sword2/controls.cpp | 5 | ||||
-rw-r--r-- | sword2/layers.cpp | 2 | ||||
-rw-r--r-- | sword2/logic.cpp | 10 | ||||
-rw-r--r-- | sword2/logic.h | 2 | ||||
-rw-r--r-- | sword2/resman.cpp | 11 | ||||
-rw-r--r-- | sword2/resman.h | 3 | ||||
-rw-r--r-- | sword2/startup.cpp | 9 | ||||
-rw-r--r-- | sword2/sword2.cpp | 27 | ||||
-rw-r--r-- | sword2/sword2.h | 1 |
11 files changed, 48 insertions, 35 deletions
diff --git a/sword2/console.cpp b/sword2/console.cpp index fdb0088751..990807712c 100644 --- a/sword2/console.cpp +++ b/sword2/console.cpp @@ -80,6 +80,7 @@ Debugger::Debugger(Sword2Engine *vm) DCmd_Register("mem", &Debugger::Cmd_Mem); DCmd_Register("tony", &Debugger::Cmd_Tony); DCmd_Register("res", &Debugger::Cmd_Res); + DCmd_Register("reslist", &Debugger::Cmd_ResList); DCmd_Register("starts", &Debugger::Cmd_Starts); DCmd_Register("start", &Debugger::Cmd_Start); DCmd_Register("s", &Debugger::Cmd_Start); @@ -191,6 +192,17 @@ bool Debugger::Cmd_Res(int argc, const char **argv) { return true; } +bool Debugger::Cmd_ResList(int argc, const char **argv) { + // By default, list only resources that are being held open. + uint minCount = 1; + + if (argc > 1) + minCount = atoi(argv[1]); + + _vm->_resman->listResources(minCount); + return true; +} + bool Debugger::Cmd_Starts(int argc, const char **argv) { _vm->_logic->conPrintStartMenu(); return true; diff --git a/sword2/console.h b/sword2/console.h index 396f7e5de4..dd95670264 100644 --- a/sword2/console.h +++ b/sword2/console.h @@ -87,6 +87,7 @@ protected: bool Cmd_Mem(int argc, const char **argv); bool Cmd_Tony(int argc, const char **argv); bool Cmd_Res(int argc, const char **argv); + bool Cmd_ResList(int argc, const char **argv); bool Cmd_Starts(int argc, const char **argv); bool Cmd_Start(int argc, const char **argv); bool Cmd_Info(int argc, const char **argv); diff --git a/sword2/controls.cpp b/sword2/controls.cpp index 6b8b5462b7..452dff64f4 100644 --- a/sword2/controls.cpp +++ b/sword2/controls.cpp @@ -1598,9 +1598,8 @@ void Gui::restartControl(void) { // global variables _vm->_resman->removeAll(); - // Reopen global variables resource & send address to interpreter - - // it won't be moving - _vm->_logic->resetScriptVars(); + // Reopen global variables resource and player object + _vm->setupPersistentResources(); Logic::_scriptVars[DEMO] = temp_demo_flag; diff --git a/sword2/layers.cpp b/sword2/layers.cpp index b5070e7b32..c4cc23e085 100644 --- a/sword2/layers.cpp +++ b/sword2/layers.cpp @@ -58,7 +58,7 @@ int32 Sword2Engine::initBackground(int32 res, int32 new_palette) { // The resources age every time a new room is entered. _resman->passTime(); - _resman->expelOldResources(); + _resman->expireOldResources(); clearFxQueue(); _graphics->waitForFade(); diff --git a/sword2/logic.cpp b/sword2/logic.cpp index ef6855dc35..aa5f3c7627 100644 --- a/sword2/logic.cpp +++ b/sword2/logic.cpp @@ -32,16 +32,6 @@ namespace Sword2 { /** - * Reset the script variables. If the resource is already open, this won't do - * anything, I beleive. - */ - -void Logic::resetScriptVars(void) { - _scriptVars = (uint32 *) (_vm->_resman->openResource(1) + sizeof(StandardHeader)); - _vm->_resman->closeResource(1); -} - -/** * Do one cycle of the current session. */ diff --git a/sword2/logic.h b/sword2/logic.h index 90992c7a6a..aac49a7404 100644 --- a/sword2/logic.h +++ b/sword2/logic.h @@ -197,8 +197,6 @@ public: // could alternately use logic->looping of course bool _choosing; - void resetScriptVars(void); - void conPrintStartMenu(void); void conStart(int start); diff --git a/sword2/resman.cpp b/sword2/resman.cpp index bd4eddd450..1882fa045e 100644 --- a/sword2/resman.cpp +++ b/sword2/resman.cpp @@ -633,7 +633,7 @@ uint32 ResourceManager::fetchLen(uint32 res) { return file.readUint32LE(); } -void ResourceManager::expelOldResources() { +void ResourceManager::expireOldResources() { int nuked = 0; for (uint i = 0; i < _totalResFiles; i++) { @@ -673,6 +673,15 @@ void ResourceManager::printConsoleClusters(void) { Debug_Printf("Argh! No resources!\n"); } +void ResourceManager::listResources(uint minCount) { + for (uint i = 0; i < _totalResFiles; i++) { + if (_resList[i].ptr && _resList[i].refCount >= minCount) { + StandardHeader *head = (StandardHeader *) _resList[i].ptr; + Debug_Printf("%-4d: %-35s refCount: %-3d age: %-2d\n", i, head->name, _resList[i].refCount, _resTime - _resList[i].refTime); + } + } +} + void ResourceManager::examine(int res) { if (res < 0 || res >= (int) _totalResFiles) Debug_Printf("Illegal resource %d (there are %d resources 0-%d)\n", res, _totalResFiles, _totalResFiles - 1); diff --git a/sword2/resman.h b/sword2/resman.h index 35cca72ef2..e90b38916e 100644 --- a/sword2/resman.h +++ b/sword2/resman.h @@ -44,7 +44,7 @@ public: bool checkValid(uint32 res); uint32 fetchLen(uint32 res); - void expelOldResources(void); + void expireOldResources(void); void passTime(void); @@ -60,6 +60,7 @@ public: // ----console commands void printConsoleClusters(void); + void listResources(uint minCount); void examine(int res); void kill(int res); void killAll(bool wantInfo); diff --git a/sword2/startup.cpp b/sword2/startup.cpp index f5899c1dc9..c7b5a49ac3 100644 --- a/sword2/startup.cpp +++ b/sword2/startup.cpp @@ -21,6 +21,7 @@ #include "common/file.h" #include "sword2/sword2.h" #include "sword2/console.h" +#include "sword2/defs.h" #include "sword2/interpreter.h" #include "sword2/logic.h" #include "sword2/maketext.h" @@ -188,8 +189,8 @@ void Logic::conStart(int start) { _vm->_resman->removeAll(); - // Reopen global variables resource and send address to interpreter - _vm->_logic->resetScriptVars(); + // Reopen global variables resource and player object + _vm->setupPersistentResources(); // Free all the route memory blocks from previous game _router->freeAllRouteMem(); @@ -201,7 +202,7 @@ void Logic::conStart(int start) { } // Open George - char *raw_data_ad = (char *) _vm->_resman->openResource(8); + char *raw_data_ad = (char *) _vm->_resman->openResource(CUR_PLAYER_ID); char *raw_script = (char *) _vm->_resman->openResource(_startList[start].start_res_id); // Denotes script to run @@ -211,7 +212,7 @@ void Logic::conStart(int start) { runScript(raw_script, raw_data_ad, &null_pc); _vm->_resman->closeResource(_startList[start].start_res_id); - _vm->_resman->closeResource(8); + _vm->_resman->closeResource(CUR_PLAYER_ID); // Make sure there's a mouse, in case restarting while mouse not // available diff --git a/sword2/sword2.cpp b/sword2/sword2.cpp index e91ead0895..45a0f75edc 100644 --- a/sword2/sword2.cpp +++ b/sword2/sword2.cpp @@ -232,22 +232,23 @@ void Sword2Engine::errorString(const char *buf1, char *buf2) { } } +/** + * The global script variables and player object should be kept open throughout + * the game, so that they are never expelled by the resource manager. + */ + +void Sword2Engine::setupPersistentResources(void) { + Logic::_scriptVars = (uint32 *) (_resman->openResource(1) + sizeof(StandardHeader)); + _resman->openResource(CUR_PLAYER_ID); +} + int32 Sword2Engine::initialiseGame(void) { // During normal gameplay, we care neither about mouse button releases // nor the scroll wheel. setEventFilter(RD_LEFTBUTTONUP | RD_RIGHTBUTTONUP | RD_WHEELUP | RD_WHEELDOWN); - // initialise global script variables - // res 1 is the globals list - Logic::_scriptVars = (uint32 *) (_resman->openResource(1) + sizeof(StandardHeader)); - - // DON'T CLOSE VARIABLES RESOURCE - KEEP IT OPEN AT VERY START OF - // MEMORY SO IT CAN'T MOVE! - - // DON'T CLOSE PLAYER OBJECT RESOURCE - KEEP IT OPEN IN MEMORY SO IT - // CAN'T MOVE! - - _resman->openResource(8); + // Initialise global script variables and player object + setupPersistentResources(); // Set up font resource variables for this language version @@ -555,7 +556,7 @@ void Sword2Engine::startGame(void) { uint32 null_pc = 1; // open george object, ready for start script to reference - raw_data_ad = (char *) _resman->openResource(8); + raw_data_ad = (char *) _resman->openResource(CUR_PLAYER_ID); // open the ScreenManager object raw_script = (char *) _resman->openResource(screen_manager_id); @@ -567,7 +568,7 @@ void Sword2Engine::startGame(void) { _resman->closeResource(screen_manager_id); // close george - _resman->closeResource(8); + _resman->closeResource(CUR_PLAYER_ID); debug(5, "startGame() DONE."); } diff --git a/sword2/sword2.h b/sword2/sword2.h index 0c7027847b..69cbc42b45 100644 --- a/sword2/sword2.h +++ b/sword2/sword2.h @@ -173,6 +173,7 @@ public: Sword2Engine(GameDetector *detector, OSystem *syst); ~Sword2Engine(); void go(void); + void setupPersistentResources(void); int32 initialiseGame(void); bool _quit; |