[Scummvm-cvs-logs] scummvm master -> 402ac930fe440af42354bd0c635abb07a69cfc4a

Strangerke arnaud.boutonne at gmail.com
Tue Feb 15 10:15:37 CET 2011


This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
402ac930fe HUGO: more refactoring and encapsulation


Commit: 402ac930fe440af42354bd0c635abb07a69cfc4a
    https://github.com/scummvm/scummvm/commit/402ac930fe440af42354bd0c635abb07a69cfc4a
Author: strangerke (arnaud.boutonne at gmail.com)
Date: 2011-02-15T01:15:21-08:00

Commit Message:
HUGO: more refactoring and encapsulation

Changed paths:
    engines/hugo/display.cpp
    engines/hugo/file.cpp
    engines/hugo/hugo.cpp
    engines/hugo/hugo.h
    engines/hugo/intro.cpp
    engines/hugo/intro.h
    engines/hugo/inventory.cpp
    engines/hugo/inventory.h
    engines/hugo/object.cpp
    engines/hugo/object.h
    engines/hugo/parser.cpp
    engines/hugo/parser.h
    engines/hugo/parser_v1d.cpp
    engines/hugo/parser_v1w.cpp
    engines/hugo/parser_v2d.cpp
    engines/hugo/parser_v3d.cpp
    engines/hugo/schedule.cpp
    engines/hugo/schedule.h



diff --git a/engines/hugo/display.cpp b/engines/hugo/display.cpp
index a2902e3..69ca064 100644
--- a/engines/hugo/display.cpp
+++ b/engines/hugo/display.cpp
@@ -607,11 +607,7 @@ void Screen::selectInventoryObjId(const int16 objId) {
 	_vm->_inventory->setInventoryObjId(objId);      // Select new object
 
 	// Find index of icon
-	int16 iconId = 0;                               // Find index of dragged icon
-	for (; iconId < _vm->_maxInvent; iconId++) {
-		if (objId == _vm->_invent[iconId])
-			break;
-	}
+	int16 iconId = _vm->_inventory->findIconId(objId);
 
 	// Compute source coordinates in dib_u
 	int16 ux = (iconId + kArrowNumb) * kInvDx % kXPix;
diff --git a/engines/hugo/file.cpp b/engines/hugo/file.cpp
index 7427771..2e23247 100644
--- a/engines/hugo/file.cpp
+++ b/engines/hugo/file.cpp
@@ -369,11 +369,7 @@ bool FileManager::saveGame(const int16 slot, const Common::String &descrip) {
 	for (int i = 0; i < _vm->_numScreens; i++)
 		out->writeByte(_vm->_screenStates[i]);
 
-	// Save points table
-	for (int i = 0; i < _vm->_numBonuses; i++) {
-		out->writeByte(_vm->_points[i].score);
-		out->writeByte((_vm->_points[i].scoredFl) ? 1 : 0);
-	}
+	_vm->_scheduler->savePoints(out);
 
 	// Now save current time and all current events in event queue
 	_vm->_scheduler->saveEvents(out);
@@ -475,12 +471,7 @@ bool FileManager::restoreGame(const int16 slot) {
 	for (int i = 0; i < _vm->_numScreens; i++)
 		_vm->_screenStates[i] = in->readByte();
 
-	// Restore points table
-	for (int i = 0; i < _vm->_numBonuses; i++) {
-		_vm->_points[i].score = in->readByte();
-		_vm->_points[i].scoredFl = (in->readByte() == 1);
-	}
-
+	_vm->_scheduler->restorePoints(in);
 	_vm->_object->restoreAllSeq();
 
 	// Now restore time of the save and the event queue
diff --git a/engines/hugo/hugo.cpp b/engines/hugo/hugo.cpp
index 4a8b74f..76898c6 100644
--- a/engines/hugo/hugo.cpp
+++ b/engines/hugo/hugo.cpp
@@ -54,10 +54,8 @@ maze_t      _maze;                              // Default to not in maze
 hugo_boot_t _boot;                              // Boot info structure file
 
 HugoEngine::HugoEngine(OSystem *syst, const HugoGameDescription *gd) : Engine(syst), _gameDescription(gd),
-	_arrayReqs(0), _invent(0), _uses(0), _catchallList(0), _backgroundObjects(0),	_points(0), _cmdList(0), 
-	_screenActs(0), _hero(0), _heroImage(0), _defltTunes(0), _introX(0), _introY(0), _maxInvent(0), _numBonuses(0),
-	_numScreens(0), _tunesNbr(0), _soundSilence(0), _soundTest(0), _screenStates(0), _score(0), _maxscore(0),
-	_backgroundObjectsSize(0), _screenActsSize(0), _usesSize(0), _lastTime(0), _curTime(0)
+	_hero(0), _heroImage(0), _defltTunes(0), _numScreens(0), _tunesNbr(0), _soundSilence(0), _soundTest(0),
+	_screenStates(0), _score(0), _maxscore(0), _lastTime(0), _curTime(0)
 {
 	_system = syst;
 	DebugMan.addDebugChannel(kDebugSchedule, "Schedule", "Script Schedule debug level");
@@ -80,47 +78,16 @@ HugoEngine::~HugoEngine() {
 
 	_screen->freePalette();
 	_text->freeAllTexts();
-
-	free(_introX);
-	free(_introY);
-
-	if (_arrayReqs) {
-		for (int i = 0; _arrayReqs[i] != 0; i++)
-			free(_arrayReqs[i]);
-		free(_arrayReqs);
-	}
-
+	_intro->freeIntroData();
+	_parser->freeArrayReqs();
 	_mouse->freeHotspots();
-	free(_invent);
-
-	if (_uses) {
-		for (int i = 0; i < _usesSize; i++)
-			free(_uses[i].targets);
-		free(_uses);
-	}
-
-	free(_catchallList);
-
-	if (_backgroundObjects) {
-		for (int i = 0; i < _backgroundObjectsSize; i++)
-			free(_backgroundObjects[i]);
-		free(_backgroundObjects);
-	}
-
-	free(_points);
-
-	if (_cmdList) {
-		for (int i = 0; i < _cmdListSize; i++)
-			free(_cmdList[i]);
-		free(_cmdList);
-	}
-
-	if (_screenActs) {
-		for (int i = 0; i < _screenActsSize; i++)
-			free(_screenActs[i]);
-		free(_screenActs);
-	}
-
+	_inventory->freeInvent();
+	_object->freeObjectUses();
+	_parser->freeCatchallList();
+	_parser->freeBackgroundObjects();
+	_scheduler->freePoints();
+	_parser->freeCmdList();
+	_scheduler->freeScreenAct();
 	_object->freeObjectArr();
 	_scheduler->freeActListArr();
 
@@ -388,207 +355,23 @@ bool HugoEngine::loadHugoDat() {
 	}
 
 	_numVariant = in.readUint16BE();
+
 	_screen->loadPalette(in);
 	_text->loadAllTexts(in);
-
-	// Read x_intro and y_intro
-	for (int varnt = 0; varnt < _numVariant; varnt++) {
-		int numRows = in.readUint16BE();
-		if (varnt == _gameVariant) {
-			_introXSize = numRows;
-			_introX = (byte *)malloc(sizeof(byte) * _introXSize);
-			_introY = (byte *)malloc(sizeof(byte) * _introXSize);
-			for (int i = 0; i < _introXSize; i++) {
-				_introX[i] = in.readByte();
-				_introY[i] = in.readByte();
-			}
-		} else {
-			for (int i = 0; i < numRows; i++) {
-				in.readByte();
-				in.readByte();
-			}
-		}
-	}
-
-	// Read _arrayReqs
-	_arrayReqs = loadLongArray(in);
-
+	_intro->loadIntroData(in);
+	_parser->loadArrayReqs(in);
 	_mouse->loadHotspots(in);
-
-	int numElem, numSubElem;
-	//Read _invent
-	for (int varnt = 0; varnt < _numVariant; varnt++) {
-		numElem = in.readUint16BE();
-		if (varnt == _gameVariant) {
-			_maxInvent = numElem;
-			_invent = (int16 *)malloc(sizeof(int16) * numElem);
-			for (int i = 0; i < numElem; i++)
-				_invent[i] = in.readSint16BE();
-		} else {
-			for (int i = 0; i < numElem; i++)
-				in.readSint16BE();
-		}
-	}
-
-	//Read _uses
-	for (int varnt = 0; varnt < _numVariant; varnt++) {
-		numElem = in.readUint16BE();
-		uses_t *wrkUses = (uses_t *)malloc(sizeof(uses_t) * numElem);
-
-		for (int i = 0; i < numElem; i++) {
-			wrkUses[i].objId = in.readSint16BE();
-			wrkUses[i].dataIndex = in.readUint16BE();
-			numSubElem = in.readUint16BE();
-			wrkUses[i].targets = (target_t *)malloc(sizeof(target_t) * numSubElem);
-			for (int j = 0; j < numSubElem; j++) {
-				wrkUses[i].targets[j].nounIndex = in.readUint16BE();
-				wrkUses[i].targets[j].verbIndex = in.readUint16BE();
-			}
-		}
-
-		if (varnt == _gameVariant) {
-			_usesSize = numElem;
-			_uses = wrkUses;
-		} else {
-			for (int i = 0; i < numElem; i++)
-				free(wrkUses[i].targets);
-			free(wrkUses);
-		}
-	}
-
-	//Read _catchallList
-	for (int varnt = 0; varnt < _numVariant; varnt++) {
-		numElem = in.readUint16BE();
-		background_t *wrkCatchallList = (background_t *)malloc(sizeof(background_t) * numElem);
-
-		for (int i = 0; i < numElem; i++) {
-			wrkCatchallList[i].verbIndex = in.readUint16BE();
-			wrkCatchallList[i].nounIndex = in.readUint16BE();
-			wrkCatchallList[i].commentIndex = in.readSint16BE();
-			wrkCatchallList[i].matchFl = (in.readByte() != 0);
-			wrkCatchallList[i].roomState = in.readByte();
-			wrkCatchallList[i].bonusIndex = in.readByte();
-		}
-
-		if (varnt == _gameVariant)
-			_catchallList = wrkCatchallList;
-		else
-			free(wrkCatchallList);
-	}
-
-	// Read _background_objects
-	for (int varnt = 0; varnt < _numVariant; varnt++) {
-		numElem = in.readUint16BE();
-
-		background_t **wrkBackgroundObjects = (background_t **)malloc(sizeof(background_t *) * numElem);
-
-		for (int i = 0; i < numElem; i++) {
-			numSubElem = in.readUint16BE();
-			wrkBackgroundObjects[i] = (background_t *)malloc(sizeof(background_t) * numSubElem);
-			for (int j = 0; j < numSubElem; j++) {
-				wrkBackgroundObjects[i][j].verbIndex = in.readUint16BE();
-				wrkBackgroundObjects[i][j].nounIndex = in.readUint16BE();
-				wrkBackgroundObjects[i][j].commentIndex = in.readSint16BE();
-				wrkBackgroundObjects[i][j].matchFl = (in.readByte() != 0);
-				wrkBackgroundObjects[i][j].roomState = in.readByte();
-				wrkBackgroundObjects[i][j].bonusIndex = in.readByte();
-			}
-		}
-
-		if (varnt == _gameVariant) {
-			_backgroundObjectsSize = numElem;
-			_backgroundObjects = wrkBackgroundObjects;
-		} else {
-			for (int i = 0; i < numElem; i++)
-				free(wrkBackgroundObjects[i]);
-			free(wrkBackgroundObjects);
-		}
-	}
-
-	// Read _points
-	for (int varnt = 0; varnt < _numVariant; varnt++) {
-		numElem = in.readUint16BE();
-		if (varnt == _gameVariant) {
-			_numBonuses = numElem;
-			_points = (point_t *)malloc(sizeof(point_t) * _numBonuses);
-			for (int i = 0; i < _numBonuses; i++) {
-				_points[i].score = in.readByte();
-				_points[i].scoredFl = false;
-			}
-		} else {
-			for (int i = 0; i < numElem; i++)
-				in.readByte();
-		}
-	}
-
-	// Read _cmdList
-	for (int varnt = 0; varnt < _numVariant; varnt++) {
-		numElem = in.readUint16BE();
-		if (varnt == _gameVariant) {
-			_cmdListSize = numElem;
-			_cmdList = (cmd **)malloc(sizeof(cmd *) * _cmdListSize);
-			for (int i = 0; i < _cmdListSize; i++) {
-				numSubElem = in.readUint16BE();
-				_cmdList[i] = (cmd *)malloc(sizeof(cmd) * numSubElem);
-				for (int j = 0; j < numSubElem; j++) {
-					_cmdList[i][j].verbIndex = in.readUint16BE();
-					_cmdList[i][j].reqIndex = in.readUint16BE();
-					_cmdList[i][j].textDataNoCarryIndex = in.readUint16BE();
-					_cmdList[i][j].reqState = in.readByte();
-					_cmdList[i][j].newState = in.readByte();
-					_cmdList[i][j].textDataWrongIndex = in.readUint16BE();
-					_cmdList[i][j].textDataDoneIndex = in.readUint16BE();
-					_cmdList[i][j].actIndex = in.readUint16BE();
-				}
-			}
-		} else {
-			for (int i = 0; i < numElem; i++) {
-				numSubElem = in.readUint16BE();
-				for (int j = 0; j < numSubElem; j++) {
-					in.readUint16BE();
-					in.readUint16BE();
-					in.readUint16BE();
-					in.readByte();
-					in.readByte();
-					in.readUint16BE();
-					in.readUint16BE();
-					in.readUint16BE();
-				}
-			}
-		}
-	}
-
-	// Read _screenActs
-	for (int varnt = 0; varnt < _numVariant; varnt++) {
-		numElem = in.readUint16BE();
-
-		uint16 **wrkScreenActs = (uint16 **)malloc(sizeof(uint16 *) * numElem);
-		for (int i = 0; i < numElem; i++) {
-			numSubElem = in.readUint16BE();
-			if (numSubElem == 0) {
-				wrkScreenActs[i] = 0;
-			} else {
-				wrkScreenActs[i] = (uint16 *)malloc(sizeof(uint16) * numSubElem);
-				for (int j = 0; j < numSubElem; j++)
-					wrkScreenActs[i][j] = in.readUint16BE();
-			}
-		}
-
-		if (varnt == _gameVariant) {
-			_screenActsSize = numElem;
-			_screenActs = wrkScreenActs;
-		} else {
-			for (int i = 0; i < numElem; i++)
-				free(wrkScreenActs[i]);
-			free(wrkScreenActs);
-		}
-	}
+	_inventory->loadInvent(in);
+	_object->loadObjectUses(in);
+	_parser->loadCatchallList(in);
+	_parser->loadBackgroundObjects(in);
+	_scheduler->loadPoints(in);
+	_parser->loadCmdList(in);
+	_scheduler->loadScreenAct(in);
 	_object->loadObjectArr(in);
-
 	_hero = &_object->_objects[kHeroIndex];         // This always points to hero
 	_screen_p = &(_object->_objects[kHeroIndex].screenIndex); // Current screen is hero's
 	_heroImage = kHeroIndex;                        // Current in use hero image
-
 	_scheduler->loadActListArr(in);
 
 	for (int varnt = 0; varnt < _numVariant; varnt++) {
@@ -603,6 +386,8 @@ bool HugoEngine::loadHugoDat() {
 		}
 	}
 
+	int numElem;
+
 	//Read _defltTunes
 	for (int varnt = 0; varnt < _numVariant; varnt++) {
 		numElem = in.readUint16BE();
@@ -820,37 +605,6 @@ void HugoEngine::readScreenFiles(const int screenNum) {
 }
 
 /**
- * Search background command list for this screen for supplied object.
- * Return first associated verb (not "look") or 0 if none found.
- */
-const char *HugoEngine::useBG(const char *name) {
-	debugC(1, kDebugEngine, "useBG(%s)", name);
-
-	objectList_t p = _backgroundObjects[*_screen_p];
-	for (int i = 0; p[i].verbIndex != 0; i++) {
-		if ((name == _text->getNoun(p[i].nounIndex, 0) &&
-		     p[i].verbIndex != _look) &&
-		    ((p[i].roomState == kStateDontCare) || (p[i].roomState == _screenStates[*_screen_p])))
-			return _text->getVerb(p[i].verbIndex, 0);
-	}
-
-	return 0;
-}
-
-/**
- * Add action lists for this screen to event queue
- */
-void HugoEngine::screenActions(const int screenNum) {
-	debugC(1, kDebugEngine, "screenActions(%d)", screenNum);
-
-	uint16 *screenAct = _screenActs[screenNum];
-	if (screenAct) {
-		for (int i = 0; screenAct[i]; i++)
-			_scheduler->insertActionList(screenAct[i]);
-	}
-}
-
-/**
  * Set the new screen number into the hero object and any carried objects
  */
 void HugoEngine::setNewScreen(const int screenNum) {
@@ -866,10 +620,7 @@ void HugoEngine::setNewScreen(const int screenNum) {
 void HugoEngine::calcMaxScore() {
 	debugC(1, kDebugEngine, "calcMaxScore");
 
-	_maxscore = _object->calcMaxScore();
-
-	for (int i = 0; i < _numBonuses; i++)
-		_maxscore += _points[i].score;
+	_maxscore = _object->calcMaxScore() + _scheduler->calcMaxPoints();
 }
 
 /**
diff --git a/engines/hugo/hugo.h b/engines/hugo/hugo.h
index b73b24e..7c12fcd 100644
--- a/engines/hugo/hugo.h
+++ b/engines/hugo/hugo.h
@@ -233,8 +233,6 @@ public:
 
 	byte   _numVariant;
 	byte   _gameVariant;
-	byte   _maxInvent;
-	byte   _numBonuses;
 	int8   _soundSilence;
 	int8   _soundTest;
 	int8   _tunesNbr;
@@ -245,23 +243,9 @@ public:
 	byte  *_screen_p;
 	byte  _heroImage;
 
-	byte  *_introX;
-	byte  *_introY;
 	byte  *_screenStates;
 	command_t _line;                                // Line of user text input
 	config_t  _config;                              // User's config
-	uint16    **_arrayReqs;
-	int16     *_invent;
-	uses_t    *_uses;
-	uint16     _usesSize;
-	background_t *_catchallList;
-	background_t **_backgroundObjects;
-	uint16    _backgroundObjectsSize;
-	point_t   *_points;
-	cmd       **_cmdList;
-	uint16    _cmdListSize;
-	uint16    **_screenActs;
-	uint16    _screenActsSize;
 	int16     *_defltTunes;
 	uint16    _look;
 	uint16    _take;
@@ -295,8 +279,6 @@ public:
 	virtual bool canSaveGameStateCurrently();
 	bool loadHugoDat();
 
-	const char *useBG(const char *name);
-
 	int8 getTPS() const;
 
 	void initGame(const HugoGameDescription *gd);
@@ -304,7 +286,6 @@ public:
 	void endGame();
 	void initStatus();
 	void readScreenFiles(const int screen);
-	void screenActions(const int screen);
 	void setNewScreen(const int screen);
 	void shutdown();
 	void syncSoundSettings();
@@ -327,9 +308,6 @@ public:
 	void setMaxScore(const int newScore) {
 		_maxscore = newScore;
 	}
-	byte getIntroSize() {
-		return _introXSize;
-	}
 	Common::Error saveGameState(int slot, const char *desc) {
 		return (_file->saveGame(slot, desc) ? Common::kWritingFailed : Common::kNoError);
 	}
@@ -345,6 +323,7 @@ public:
 	const char *getCopyrightString() const { return "Copyright 1989-1997 David P Gray, All Rights Reserved."; }
 
 	Common::String getSavegameFilename(int slot);
+	uint16 **loadLongArray(Common::ReadStream &in);
 
 	FileManager *_file;
 	Scheduler *_scheduler;
@@ -357,7 +336,6 @@ public:
 	IntroHandler *_intro;
 	ObjectHandler *_object;
 	TextHandler *_text;
-
 	TopMenu *_topMenu;
 
 protected:
@@ -368,7 +346,6 @@ protected:
 private:
 	static const int kTurboTps = 16;                // This many in turbo mode
 
-	byte _introXSize;
 	status_t _status;                               // Game status structure
 	uint32 _lastTime;
 	uint32 _curTime;
@@ -384,8 +361,6 @@ private:
 	int _score;                                     // Holds current score
 	int _maxscore;                                  // Holds maximum score
 
-	uint16 **loadLongArray(Common::ReadStream &in);
-
 	void initPlaylist(bool playlist[kMaxTunes]);
 	void initConfig();
 	void initialize();
diff --git a/engines/hugo/intro.cpp b/engines/hugo/intro.cpp
index 02fb94c..4ee46f8 100644
--- a/engines/hugo/intro.cpp
+++ b/engines/hugo/intro.cpp
@@ -41,12 +41,41 @@
 
 namespace Hugo {
 
-IntroHandler::IntroHandler(HugoEngine *vm) : _vm(vm) {
+IntroHandler::IntroHandler(HugoEngine *vm) : _vm(vm), _introX(0), _introY(0) {
+	_introXSize = 0;
 }
 
 IntroHandler::~IntroHandler() {
 }
 
+/**
+ * Read _introX and _introY from hugo.dat
+ */
+void IntroHandler::loadIntroData(Common::ReadStream &in) {
+	for (int varnt = 0; varnt < _vm->_numVariant; varnt++) {
+		int numRows = in.readUint16BE();
+		if (varnt == _vm->_gameVariant) {
+			_introXSize = numRows;
+			_introX = (byte *)malloc(sizeof(byte) * _introXSize);
+			_introY = (byte *)malloc(sizeof(byte) * _introXSize);
+			for (int i = 0; i < _introXSize; i++) {
+				_introX[i] = in.readByte();
+				_introY[i] = in.readByte();
+			}
+		} else {
+			for (int i = 0; i < numRows; i++) {
+				in.readByte();
+				in.readByte();
+			}
+		}
+	}
+}
+
+void IntroHandler::freeIntroData() {
+	free(_introX);
+	free(_introY);
+}
+
 intro_v1d::intro_v1d(HugoEngine *vm) : IntroHandler(vm) {
 }
 
@@ -68,7 +97,7 @@ void intro_v1d::introInit() {
 }
 
 bool intro_v1d::introPlay() {
-	byte introSize = _vm->getIntroSize();
+	byte introSize = getIntroSize();
 
 	if (_vm->getGameStatus().skipIntroFl)
 		return true;
@@ -296,8 +325,8 @@ bool intro_v3d::introPlay() {
 	if (_vm->getGameStatus().skipIntroFl)
 		return true;
 
-	if (introTicks < _vm->getIntroSize()) {
-		font.drawString(&surf, ".", _vm->_introX[introTicks], _vm->_introY[introTicks] - kDibOffY, 320, _TBRIGHTWHITE);
+	if (introTicks < getIntroSize()) {
+		font.drawString(&surf, ".", _introX[introTicks], _introY[introTicks] - kDibOffY, 320, _TBRIGHTWHITE);
 		_vm->_screen->displayBackground();
 
 		// Text boxes at various times
@@ -314,7 +343,7 @@ bool intro_v3d::introPlay() {
 		}
 	}
 
-	return (++introTicks >= _vm->getIntroSize());
+	return (++introTicks >= getIntroSize());
 }
 
 intro_v1w::intro_v1w(HugoEngine *vm) : IntroHandler(vm) {
@@ -387,9 +416,9 @@ bool intro_v3w::introPlay() {
 	if (_vm->getGameStatus().skipIntroFl)
 		return true;
 
-	if (introTicks < _vm->getIntroSize()) {
+	if (introTicks < getIntroSize()) {
 		// Scale viewport x_intro,y_intro to screen (offsetting y)
-		_vm->_screen->writeStr(_vm->_introX[introTicks], _vm->_introY[introTicks] - kDibOffY, "x", _TBRIGHTWHITE);
+		_vm->_screen->writeStr(_introX[introTicks], _introY[introTicks] - kDibOffY, "x", _TBRIGHTWHITE);
 		_vm->_screen->displayBackground();
 
 		// Text boxes at various times
@@ -406,6 +435,6 @@ bool intro_v3w::introPlay() {
 		}
 	}
 
-	return (++introTicks >= _vm->getIntroSize());
+	return (++introTicks >= getIntroSize());
 }
 } // End of namespace Hugo
diff --git a/engines/hugo/intro.h b/engines/hugo/intro.h
index 37c846f..3513525 100644
--- a/engines/hugo/intro.h
+++ b/engines/hugo/intro.h
@@ -54,9 +54,18 @@ public:
 	virtual void introInit() = 0;
 	virtual bool introPlay() = 0;
 
+	void freeIntroData();
+	void loadIntroData(Common::ReadStream &in);
+
+	byte getIntroSize() const { return _introXSize; }
+
 protected:
 	HugoEngine *_vm;
-	int16 introTicks;                               // Count calls to introPlay()
+
+	byte *_introX;
+	byte *_introY;
+	byte  _introXSize;
+	int16  introTicks;                              // Count calls to introPlay()
 };
 
 class intro_v1w : public IntroHandler {
diff --git a/engines/hugo/inventory.cpp b/engines/hugo/inventory.cpp
index 4bf1075..a45df7e 100644
--- a/engines/hugo/inventory.cpp
+++ b/engines/hugo/inventory.cpp
@@ -46,11 +46,30 @@ namespace Hugo {
 
 static const int kMaxDisp = (kXPix / kInvDx);       // Max icons displayable
 
-InventoryHandler::InventoryHandler(HugoEngine *vm) : _vm(vm) {
+InventoryHandler::InventoryHandler(HugoEngine *vm) : _vm(vm), _invent(0) {
 	_firstIconId = 0;
 	_inventoryState  = kInventoryOff;               // Inventory icon bar state
 	_inventoryHeight = 0;                           // Inventory icon bar pos
 	_inventoryObjId  = -1;                          // Inventory object selected (none)
+	_maxInvent = 0;
+}
+
+/**
+ * Read _invent from Hugo.dat
+ */
+void InventoryHandler::loadInvent(Common::ReadStream &in) {
+	for (int varnt = 0; varnt < _vm->_numVariant; varnt++) {
+		int16 numElem = in.readUint16BE();
+		if (varnt == _vm->_gameVariant) {
+			_maxInvent = numElem;
+			_invent = (int16 *)malloc(sizeof(int16) * numElem);
+			for (int i = 0; i < numElem; i++)
+				_invent[i] = in.readSint16BE();
+		} else {
+			for (int i = 0; i < numElem; i++)
+				in.readSint16BE();
+		}
+	}
 }
 
 /**
@@ -78,7 +97,7 @@ void InventoryHandler::constructInventory(const int16 imageTotNumb, int displayN
 	int16 displayed = 0;
 	int16 carried = 0;
 	for (int16 i = 0; (i < imageTotNumb) && (displayed < displayNumb); i++) {
-		if (_vm->_object->isCarried(_vm->_invent[i])) {
+		if (_vm->_object->isCarried(_invent[i])) {
 			// Check still room to display and past first scroll index
 			if (displayed < displayNumb && carried >= firstObjId) {
 				// Compute source coordinates in dib_u
@@ -107,8 +126,8 @@ int16 InventoryHandler::processInventory(const invact_t action, ...) {
 	int16 imageNumb;                                // Total number of inventory items
 	int displayNumb;                                // Total number displayed/carried
 	// Compute total number and number displayed, i.e. number carried
-	for (imageNumb = 0, displayNumb = 0; imageNumb < _vm->_maxInvent && _vm->_invent[imageNumb] != -1; imageNumb++) {
-		if (_vm->_object->isCarried(_vm->_invent[imageNumb]))
+	for (imageNumb = 0, displayNumb = 0; imageNumb < _maxInvent && _invent[imageNumb] != -1; imageNumb++) {
+		if (_vm->_object->isCarried(_invent[imageNumb]))
 			displayNumb++;
 	}
 
@@ -236,4 +255,18 @@ void InventoryHandler::runInventory() {
 	}
 }
 
+
+/**
+ * Find index of dragged icon
+ */
+int16 InventoryHandler::findIconId(int16 objId) {
+	int16 iconId = 0;
+	for (; iconId < _maxInvent; iconId++) {
+		if (objId == _invent[iconId])
+			break;
+	}
+
+	return iconId;
+}
+
 } // End of namespace Hugo
diff --git a/engines/hugo/inventory.h b/engines/hugo/inventory.h
index deb22cf..8d60904 100644
--- a/engines/hugo/inventory.h
+++ b/engines/hugo/inventory.h
@@ -45,11 +45,15 @@ public:
 
 	void     setInventoryObjId(int16 objId)    { _inventoryObjId = objId; }
 	void     setInventoryState(istate_t state) { _inventoryState = state; }
+	void     freeInvent()                      { free(_invent);           }
+
 	int16    getInventoryObjId() const         { return _inventoryObjId;  }
 	istate_t getInventoryState() const         { return _inventoryState;  }
 
+	int16 findIconId(int16 objId);
+	void  loadInvent(Common::ReadStream &in);
 	int16 processInventory(const invact_t action, ...);
-	void runInventory();
+	void  runInventory();
 
 private:
 	HugoEngine *_vm;
@@ -57,9 +61,11 @@ private:
 	static const int kStepDy = 8;                   // Pixels per step movement
 	
 	int16    _firstIconId;                          // Index of first icon to display
+	int16   *_invent;
 	istate_t _inventoryState;                       // Inventory icon bar state
 	int16    _inventoryHeight;                      // Inventory icon bar height
 	int16    _inventoryObjId;                       // Inventory object selected, or -1
+	byte     _maxInvent;
 
 	void constructInventory(const int16 imageTotNumb, int displayNumb, const bool scrollFl, int16 firstObjId);
 };
diff --git a/engines/hugo/object.cpp b/engines/hugo/object.cpp
index b909df4..c2bcffb 100644
--- a/engines/hugo/object.cpp
+++ b/engines/hugo/object.cpp
@@ -48,9 +48,10 @@
 
 namespace Hugo {
 
-ObjectHandler::ObjectHandler(HugoEngine *vm) : _vm(vm), _objects(0) {
+ObjectHandler::ObjectHandler(HugoEngine *vm) : _vm(vm), _objects(0), _uses(0) {
 	_numObj = 0;
 	_objCount = 0;
+	_usesSize = 0;
 	memset(_objBound, '\0', sizeof(overlay_t));
 	memset(_boundary, '\0', sizeof(overlay_t));
 	memset(_overlay,  '\0', sizeof(overlay_t));
@@ -108,20 +109,20 @@ void ObjectHandler::useObject(int16 objId) {
 		if ((obj->genericCmd & TAKE) || obj->objValue)  // Get collectible item
 			sprintf(_vm->_line, "%s %s", _vm->_text->getVerb(_vm->_take, 0), _vm->_text->getNoun(obj->nounIndex, 0));
 		else if (obj->cmdIndex != 0)                // Use non-collectible item if able
-			sprintf(_vm->_line, "%s %s", _vm->_text->getVerb(_vm->_cmdList[obj->cmdIndex][0].verbIndex, 0), _vm->_text->getNoun(obj->nounIndex, 0));
-		else if ((verb = _vm->useBG(_vm->_text->getNoun(obj->nounIndex, 0))) != 0)
+			sprintf(_vm->_line, "%s %s", _vm->_text->getVerb(_vm->_parser->getCmdDefaultVerbIdx(obj->cmdIndex), 0), _vm->_text->getNoun(obj->nounIndex, 0));
+		else if ((verb = _vm->_parser->useBG(_vm->_text->getNoun(obj->nounIndex, 0))) != 0)
 			sprintf(_vm->_line, "%s %s", verb, _vm->_text->getNoun(obj->nounIndex, 0));
 		else
 			return;                                 // Can't use object directly
 	} else {
 		// Use status.objid on objid
 		// Default to first cmd verb
-		sprintf(_vm->_line, "%s %s %s", _vm->_text->getVerb(_vm->_cmdList[_objects[inventObjId].cmdIndex][0].verbIndex, 0),
+		sprintf(_vm->_line, "%s %s %s", _vm->_text->getVerb(_vm->_parser->getCmdDefaultVerbIdx(_objects[inventObjId].cmdIndex), 0),
 			                       _vm->_text->getNoun(_objects[inventObjId].nounIndex, 0),
 			                       _vm->_text->getNoun(obj->nounIndex, 0));
 
 		// Check valid use of objects and override verb if necessary
-		for (uses_t *use = _vm->_uses; use->objId != _numObj; use++) {
+		for (uses_t *use = _uses; use->objId != _numObj; use++) {
 			if (inventObjId == use->objId) {
 				// Look for secondary object, if found use matching verb
 				bool foundFl = false;
@@ -249,6 +250,16 @@ void ObjectHandler::freeObjects() {
 }
 
 /**
+ * Free all object uses
+ */
+void ObjectHandler::freeObjectUses() {
+	if (_uses) {
+		for (int i = 0; i < _usesSize; i++)
+			free(_uses[i].targets);
+		free(_uses);
+	}
+}
+/**
  * Compare function for the quicksort.  The sort is to order the objects in
  * increasing vertical position, using y+y2 as the baseline
  * Returns -1 if ay2 < by2 else 1 if ay2 > by2 else 0
@@ -368,6 +379,37 @@ void ObjectHandler::freeObjectArr() {
 }
 
 /**
+ * Load _uses from Hugo.dat
+ */
+void ObjectHandler::loadObjectUses(Common::ReadStream &in) {
+	//Read _uses
+	for (int varnt = 0; varnt < _vm->_numVariant; varnt++) {
+		uint16 numElem = in.readUint16BE();
+		uses_t *wrkUses = (uses_t *)malloc(sizeof(uses_t) * numElem);
+
+		for (int i = 0; i < numElem; i++) {
+			wrkUses[i].objId = in.readSint16BE();
+			wrkUses[i].dataIndex = in.readUint16BE();
+			uint16 numSubElem = in.readUint16BE();
+			wrkUses[i].targets = (target_t *)malloc(sizeof(target_t) * numSubElem);
+			for (int j = 0; j < numSubElem; j++) {
+				wrkUses[i].targets[j].nounIndex = in.readUint16BE();
+				wrkUses[i].targets[j].verbIndex = in.readUint16BE();
+			}
+		}
+
+		if (varnt == _vm->_gameVariant) {
+			_usesSize = numElem;
+			_uses = wrkUses;
+		} else {
+			for (int i = 0; i < numElem; i++)
+				free(wrkUses[i].targets);
+			free(wrkUses);
+		}
+	}
+}
+
+/**
  * Load ObjectArr from Hugo.dat
  */
 void ObjectHandler::loadObjectArr(Common::ReadStream &in) {
diff --git a/engines/hugo/object.h b/engines/hugo/object.h
index aa2ed9b..09dcfeb 100644
--- a/engines/hugo/object.h
+++ b/engines/hugo/object.h
@@ -73,7 +73,9 @@ public:
 	int   calcMaxScore();
 	int16 findObject(uint16 x, uint16 y);
 	void freeObjects();
+	void freeObjectUses();
 	void loadObjectArr(Common::ReadStream &in);
+	void loadObjectUses(Common::ReadStream &in);
 	void freeObjectArr();
 	void loadNumObj(Common::ReadStream &in);
 	void lookObject(object_t *obj);
@@ -114,6 +116,8 @@ protected:
 	static const int kMaxObjNumb = 128;             // Used in Update_images()
 
 	uint16     _objCount;
+	uses_t    *_uses;
+	uint16     _usesSize;
 
 	void restoreSeq(object_t *obj);
 
diff --git a/engines/hugo/parser.cpp b/engines/hugo/parser.cpp
index 001ddac..5cc704e 100644
--- a/engines/hugo/parser.cpp
+++ b/engines/hugo/parser.cpp
@@ -51,17 +51,167 @@
 
 namespace Hugo {
 
-Parser::Parser(HugoEngine *vm) :
-	_vm(vm), _putIndex(0), _getIndex(0), _checkDoubleF1Fl(false) {
+Parser::Parser(HugoEngine *vm) : _vm(vm), _putIndex(0), _getIndex(0), _arrayReqs(0), _catchallList(0), _backgroundObjects(0), _cmdList(0) {
 	_cmdLineIndex = 0;
 	_cmdLineTick = 0;
 	_cmdLineCursor = '_';
 	_cmdLine[0] = '\0';
+	_cmdListSize = 0;
+	_checkDoubleF1Fl = false;
+	_backgroundObjectsSize = 0;
 }
 
 Parser::~Parser() {
 }
 
+/**
+ * Read _cmdList from Hugo.dat
+ */
+void Parser::loadCmdList(Common::ReadStream &in) {
+	for (int varnt = 0; varnt < _vm->_numVariant; varnt++) {
+		uint16 numElem = in.readUint16BE();
+		if (varnt == _vm->_gameVariant) {
+			_cmdListSize = numElem;
+			_cmdList = (cmd **)malloc(sizeof(cmd *) * _cmdListSize);
+			for (int i = 0; i < _cmdListSize; i++) {
+				uint16 numSubElem = in.readUint16BE();
+				_cmdList[i] = (cmd *)malloc(sizeof(cmd) * numSubElem);
+				for (int j = 0; j < numSubElem; j++) {
+					_cmdList[i][j].verbIndex = in.readUint16BE();
+					_cmdList[i][j].reqIndex = in.readUint16BE();
+					_cmdList[i][j].textDataNoCarryIndex = in.readUint16BE();
+					_cmdList[i][j].reqState = in.readByte();
+					_cmdList[i][j].newState = in.readByte();
+					_cmdList[i][j].textDataWrongIndex = in.readUint16BE();
+					_cmdList[i][j].textDataDoneIndex = in.readUint16BE();
+					_cmdList[i][j].actIndex = in.readUint16BE();
+				}
+			}
+		} else {
+			for (int i = 0; i < numElem; i++) {
+				uint16 numSubElem = in.readUint16BE();
+				for (int j = 0; j < numSubElem; j++) {
+					in.readUint16BE();
+					in.readUint16BE();
+					in.readUint16BE();
+					in.readByte();
+					in.readByte();
+					in.readUint16BE();
+					in.readUint16BE();
+					in.readUint16BE();
+				}
+			}
+		}
+	}
+}
+
+void Parser::freeCmdList() {
+	if (_cmdList) {
+		for (int i = 0; i < _cmdListSize; i++)
+			free(_cmdList[i]);
+		free(_cmdList);
+	}
+}
+
+/**
+ * Read _backgrounObjects from Hugo.dat
+ */
+void Parser::loadBackgroundObjects(Common::ReadStream &in) {
+	for (int varnt = 0; varnt < _vm->_numVariant; varnt++) {
+		uint16 numElem = in.readUint16BE();
+
+		background_t **wrkBackgroundObjects = (background_t **)malloc(sizeof(background_t *) * numElem);
+
+		for (int i = 0; i < numElem; i++) {
+			uint16 numSubElem = in.readUint16BE();
+			wrkBackgroundObjects[i] = (background_t *)malloc(sizeof(background_t) * numSubElem);
+			for (int j = 0; j < numSubElem; j++) {
+				wrkBackgroundObjects[i][j].verbIndex = in.readUint16BE();
+				wrkBackgroundObjects[i][j].nounIndex = in.readUint16BE();
+				wrkBackgroundObjects[i][j].commentIndex = in.readSint16BE();
+				wrkBackgroundObjects[i][j].matchFl = (in.readByte() != 0);
+				wrkBackgroundObjects[i][j].roomState = in.readByte();
+				wrkBackgroundObjects[i][j].bonusIndex = in.readByte();
+			}
+		}
+
+		if (varnt == _vm->_gameVariant) {
+			_backgroundObjectsSize = numElem;
+			_backgroundObjects = wrkBackgroundObjects;
+		} else {
+			for (int i = 0; i < numElem; i++)
+				free(wrkBackgroundObjects[i]);
+			free(wrkBackgroundObjects);
+		}
+	}
+}
+
+void Parser::freeBackgroundObjects() {
+	if (_backgroundObjects) {
+		for (int i = 0; i < _backgroundObjectsSize; i++)
+			free(_backgroundObjects[i]);
+		free(_backgroundObjects);
+	}
+}
+
+/**
+ * Read _catchallList from Hugo.dat
+ */
+void Parser::loadCatchallList(Common::ReadStream &in) {
+	for (int varnt = 0; varnt < _vm->_numVariant; varnt++) {
+		uint16 numElem = in.readUint16BE();
+		background_t *wrkCatchallList = (background_t *)malloc(sizeof(background_t) * numElem);
+
+		for (int i = 0; i < numElem; i++) {
+			wrkCatchallList[i].verbIndex = in.readUint16BE();
+			wrkCatchallList[i].nounIndex = in.readUint16BE();
+			wrkCatchallList[i].commentIndex = in.readSint16BE();
+			wrkCatchallList[i].matchFl = (in.readByte() != 0);
+			wrkCatchallList[i].roomState = in.readByte();
+			wrkCatchallList[i].bonusIndex = in.readByte();
+		}
+
+		if (varnt == _vm->_gameVariant)
+			_catchallList = wrkCatchallList;
+		else
+			free(wrkCatchallList);
+	}
+}
+
+void Parser::freeCatchallList() {
+	free(_catchallList);
+}
+
+void Parser::loadArrayReqs(Common::ReadStream &in) {
+	_arrayReqs = _vm->loadLongArray(in);
+}
+
+/**
+ * Search background command list for this screen for supplied object.
+ * Return first associated verb (not "look") or 0 if none found.
+ */
+const char *Parser::useBG(const char *name) {
+	debugC(1, kDebugEngine, "useBG(%s)", name);
+
+	objectList_t p = _backgroundObjects[*_vm->_screen_p];
+	for (int i = 0; p[i].verbIndex != 0; i++) {
+		if ((name == _vm->_text->getNoun(p[i].nounIndex, 0) &&
+		     p[i].verbIndex != _vm->_look) &&
+		    ((p[i].roomState == kStateDontCare) || (p[i].roomState == _vm->_screenStates[*_vm->_screen_p])))
+			return _vm->_text->getVerb(p[i].verbIndex, 0);
+	}
+
+	return 0;
+}
+
+void Parser::freeArrayReqs() {
+	if (_arrayReqs) {
+		for (int i = 0; _arrayReqs[i] != 0; i++)
+			free(_arrayReqs[i]);
+		free(_arrayReqs);
+	}
+}
+
 void Parser::switchTurbo() {
 	_vm->_config.turboFl = !_vm->_config.turboFl;
 }
diff --git a/engines/hugo/parser.h b/engines/hugo/parser.h
index 2e807e5..283bcd4 100644
--- a/engines/hugo/parser.h
+++ b/engines/hugo/parser.h
@@ -48,11 +48,22 @@ public:
 	virtual ~Parser();
 
 	bool isWordPresent(char **wordArr) const;
-
+	
+	uint16 getCmdDefaultVerbIdx(const uint16 index) const { return _cmdList[index][0].verbIndex; }
+	
 	void charHandler();
 	void command(const char *format, ...);
+	void freeArrayReqs();
+	void freeBackgroundObjects();
+	void freeCatchallList();
+	void freeCmdList();
 	void keyHandler(Common::Event event);
+	void loadArrayReqs(Common::ReadStream &in);
+	void loadBackgroundObjects(Common::ReadStream &in);
+	void loadCatchallList(Common::ReadStream &in);
+	void loadCmdList(Common::ReadStream &in);
 	void switchTurbo();
+	const char *useBG(const char *name);
 
 	virtual void lineHandler() = 0;
 	virtual void showInventory() const = 0;
@@ -64,6 +75,13 @@ protected:
 	uint32    _cmdLineTick;                         // For flashing cursor
 	char      _cmdLineCursor;
 	command_t _cmdLine;                             // Build command line
+	uint16    _backgroundObjectsSize;
+	uint16    _cmdListSize;
+
+	uint16       **_arrayReqs;
+	background_t **_backgroundObjects;
+	background_t  *_catchallList;
+	cmd          **_cmdList;
 
 	const char *findNoun() const;
 	const char *findVerb() const;
diff --git a/engines/hugo/parser_v1d.cpp b/engines/hugo/parser_v1d.cpp
index 1565490..5796749 100644
--- a/engines/hugo/parser_v1d.cpp
+++ b/engines/hugo/parser_v1d.cpp
@@ -192,18 +192,18 @@ bool Parser_v1d::isObjectVerb_v1(const char *word, object_t *obj) {
 		return false;
 
 	int i;
-	for (i = 0; _vm->_cmdList[cmdIndex][i].verbIndex != 0; i++) { // For each cmd
-		if (!strcmp(word, _vm->_text->getVerb(_vm->_cmdList[cmdIndex][i].verbIndex, 0))) // Is this verb catered for?
+	for (i = 0; _cmdList[cmdIndex][i].verbIndex != 0; i++) { // For each cmd
+		if (!strcmp(word, _vm->_text->getVerb(_cmdList[cmdIndex][i].verbIndex, 0))) // Is this verb catered for?
 			break;
 	}
 
-	if (_vm->_cmdList[cmdIndex][i].verbIndex == 0)  // No
+	if (_cmdList[cmdIndex][i].verbIndex == 0)       // No
 		return false;
 
 	// Verb match found, check all required objects are being carried
-	cmd *cmnd = &_vm->_cmdList[cmdIndex][i];        // ptr to struct cmd
+	cmd *cmnd = &_cmdList[cmdIndex][i];             // ptr to struct cmd
 	if (cmnd->reqIndex) {                           // At least 1 thing in list
-		uint16 *reqs = _vm->_arrayReqs[cmnd->reqIndex]; // ptr to list of required objects
+		uint16 *reqs = _arrayReqs[cmnd->reqIndex];  // ptr to list of required objects
 		for (i = 0; reqs[i]; i++) {                 // for each obj
 			if (!_vm->_object->isCarrying(reqs[i])) {
 				Utils::Box(kBoxAny, "%s", _vm->_text->getTextData(cmnd->textDataNoCarryIndex));
@@ -413,16 +413,16 @@ void Parser_v1d::lineHandler() {
 						return;
 				}
 			}
-			if ((*farComment == '\0') && isBackgroundWord_v1(noun, verb, _vm->_backgroundObjects[*_vm->_screen_p]))
+			if ((*farComment == '\0') && isBackgroundWord_v1(noun, verb, _backgroundObjects[*_vm->_screen_p]))
 				return;
 		} while (noun);
 	}
 	noun = findNextNoun(noun);
 	if (*farComment != '\0')                        // An object matched but not near enough
 		Utils::Box(kBoxAny, "%s", farComment);
-	else if (!isCatchallVerb_v1(true, noun, verb, _vm->_catchallList) &&
-		     !isCatchallVerb_v1(false, noun, verb, _vm->_backgroundObjects[*_vm->_screen_p])  &&
-		     !isCatchallVerb_v1(false, noun, verb, _vm->_catchallList))
+	else if (!isCatchallVerb_v1(true, noun, verb, _catchallList) &&
+		     !isCatchallVerb_v1(false, noun, verb, _backgroundObjects[*_vm->_screen_p])  &&
+		     !isCatchallVerb_v1(false, noun, verb, _catchallList))
 		Utils::Box(kBoxAny, "%s", _vm->_text->getTextParser(kTBEh_1d));
 }
 
diff --git a/engines/hugo/parser_v1w.cpp b/engines/hugo/parser_v1w.cpp
index 2b6741d..ad00549 100644
--- a/engines/hugo/parser_v1w.cpp
+++ b/engines/hugo/parser_v1w.cpp
@@ -172,14 +172,14 @@ void Parser_v1w::lineHandler() {
 	}
 
 	// No objects match command line, try background and catchall commands
-	if (isBackgroundWord_v3(_vm->_backgroundObjects[*_vm->_screen_p]))
+	if (isBackgroundWord_v3(_backgroundObjects[*_vm->_screen_p]))
 		return;
-	if (isCatchallVerb_v3(_vm->_backgroundObjects[*_vm->_screen_p]))
+	if (isCatchallVerb_v3(_backgroundObjects[*_vm->_screen_p]))
 		return;
 
-	if (isBackgroundWord_v3(_vm->_catchallList))
+	if (isBackgroundWord_v3(_catchallList))
 		return;
-	if (isCatchallVerb_v3(_vm->_catchallList))
+	if (isCatchallVerb_v3(_catchallList))
 		return;
 
 	// If a not-near comment was generated, print it
diff --git a/engines/hugo/parser_v2d.cpp b/engines/hugo/parser_v2d.cpp
index cd7928e..c963441 100644
--- a/engines/hugo/parser_v2d.cpp
+++ b/engines/hugo/parser_v2d.cpp
@@ -165,16 +165,16 @@ void Parser_v2d::lineHandler() {
 						return;
 				}
 			}
-			if ((*farComment != '\0') && isBackgroundWord_v1(noun, verb, _vm->_backgroundObjects[*_vm->_screen_p]))
+			if ((*farComment != '\0') && isBackgroundWord_v1(noun, verb, _backgroundObjects[*_vm->_screen_p]))
 				return;
 		} while (noun);
 	}
 
 	noun = findNextNoun(noun);
-	if (   !isCatchallVerb_v1(true, noun, verb, _vm->_backgroundObjects[*_vm->_screen_p])
-		&& !isCatchallVerb_v1(true, noun, verb, _vm->_catchallList)
-		&& !isCatchallVerb_v1(false, noun, verb, _vm->_backgroundObjects[*_vm->_screen_p])
-		&& !isCatchallVerb_v1(false, noun, verb, _vm->_catchallList)) {
+	if (   !isCatchallVerb_v1(true, noun, verb, _backgroundObjects[*_vm->_screen_p])
+		&& !isCatchallVerb_v1(true, noun, verb, _catchallList)
+		&& !isCatchallVerb_v1(false, noun, verb, _backgroundObjects[*_vm->_screen_p])
+		&& !isCatchallVerb_v1(false, noun, verb, _catchallList)) {
 		if (*farComment != '\0') {                  // An object matched but not near enough
 			Utils::Box(kBoxAny, "%s", farComment);
 		} else if (_maze.enabledFl && (verb == _vm->_text->getVerb(_vm->_look, 0))) {
diff --git a/engines/hugo/parser_v3d.cpp b/engines/hugo/parser_v3d.cpp
index 532b1f9..670f6ef 100644
--- a/engines/hugo/parser_v3d.cpp
+++ b/engines/hugo/parser_v3d.cpp
@@ -174,14 +174,14 @@ void Parser_v3d::lineHandler() {
 	}
 
 	// No objects match command line, try background and catchall commands
-	if (isBackgroundWord_v3(_vm->_backgroundObjects[*_vm->_screen_p]))
+	if (isBackgroundWord_v3(_backgroundObjects[*_vm->_screen_p]))
 		return;
-	if (isCatchallVerb_v3(_vm->_backgroundObjects[*_vm->_screen_p]))
+	if (isCatchallVerb_v3(_backgroundObjects[*_vm->_screen_p]))
 		return;
 
-	if (isBackgroundWord_v3(_vm->_catchallList))
+	if (isBackgroundWord_v3(_catchallList))
 		return;
-	if (isCatchallVerb_v3(_vm->_catchallList))
+	if (isCatchallVerb_v3(_catchallList))
 		return;
 
 	// If a not-near comment was generated, print it
@@ -219,23 +219,23 @@ bool Parser_v3d::isObjectVerb_v3(object_t *obj, char *comment) {
 		return false;
 
 	int i;
-	for (i = 0; _vm->_cmdList[cmdIndex][i].verbIndex != 0; i++) {                 // For each cmd
-		if (isWordPresent(_vm->_text->getVerbArray(_vm->_cmdList[cmdIndex][i].verbIndex)))        // Was this verb used?
+	for (i = 0; _cmdList[cmdIndex][i].verbIndex != 0; i++) {                           // For each cmd
+		if (isWordPresent(_vm->_text->getVerbArray(_cmdList[cmdIndex][i].verbIndex)))  // Was this verb used?
 			break;
 	}
 
-	if (_vm->_cmdList[cmdIndex][i].verbIndex == 0)   // No verbs used.
+	if (_cmdList[cmdIndex][i].verbIndex == 0)       // No verbs used.
 		return false;
 
 	// Verb match found.  Check if object is Near
-	char *verb = *_vm->_text->getVerbArray(_vm->_cmdList[cmdIndex][i].verbIndex);
+	char *verb = *_vm->_text->getVerbArray(_cmdList[cmdIndex][i].verbIndex);
 	if (!isNear_v3(obj, verb, comment))
 		return false;
 
 	// Check all required objects are being carried
-	cmd *cmnd = &_vm->_cmdList[cmdIndex][i];         // ptr to struct cmd
+	cmd *cmnd = &_cmdList[cmdIndex][i];             // ptr to struct cmd
 	if (cmnd->reqIndex) {                           // At least 1 thing in list
-		uint16 *reqs = _vm->_arrayReqs[cmnd->reqIndex];      // ptr to list of required objects
+		uint16 *reqs = _arrayReqs[cmnd->reqIndex];  // ptr to list of required objects
 		for (i = 0; reqs[i]; i++) {                 // for each obj
 			if (!_vm->_object->isCarrying(reqs[i])) {
 				Utils::Box(kBoxAny, "%s", _vm->_text->getTextData(cmnd->textDataNoCarryIndex));
diff --git a/engines/hugo/schedule.cpp b/engines/hugo/schedule.cpp
index b36ce70..02f8e48 100644
--- a/engines/hugo/schedule.cpp
+++ b/engines/hugo/schedule.cpp
@@ -48,8 +48,10 @@
 
 namespace Hugo {
 
-Scheduler::Scheduler(HugoEngine *vm) : _vm(vm), _actListArr(0), _curTick(0), _oldTime(0), _refreshTimeout(0) {
+Scheduler::Scheduler(HugoEngine *vm) : _vm(vm), _actListArr(0), _curTick(0), _oldTime(0), _refreshTimeout(0), _points(0), _screenActs(0) {
 	memset(_events, 0, sizeof(_events));
+	_numBonuses = 0;
+	_screenActsSize = 0;
 }
 
 Scheduler::~Scheduler() {
@@ -142,9 +144,9 @@ uint32 Scheduler::getDosTicks(const bool updateFl) {
 void Scheduler::processBonus(const int bonusIndex) {
 	debugC(1, kDebugSchedule, "processBonus(%d)", bonusIndex);
 
-	if (!_vm->_points[bonusIndex].scoredFl) {
-		_vm->adjustScore(_vm->_points[bonusIndex].score);
-		_vm->_points[bonusIndex].scoredFl = true;
+	if (!_points[bonusIndex].scoredFl) {
+		_vm->adjustScore(_points[bonusIndex].score);
+		_points[bonusIndex].scoredFl = true;
 	}
 }
 
@@ -186,7 +188,7 @@ void Scheduler::newScreen(const int screenIndex) {
 	_vm->readScreenFiles(screenIndex);
 
 	// 4. Schedule action list for this screen
-	_vm->screenActions(screenIndex);
+	_vm->_scheduler->screenActions(screenIndex);
 
 	// 5. Initialise prompt line and status line
 	_vm->_screen->initNewScreenDisplay();
@@ -245,6 +247,28 @@ void Scheduler::loadAlNewscrIndex(Common::ReadStream &in) {
 }
 
 /**
+ * Load Points from Hugo.dat
+ */
+void Scheduler::loadPoints(Common::ReadStream &in) {
+	debugC(6, kDebugSchedule, "loadPoints(&in)");
+
+	for (int varnt = 0; varnt < _vm->_numVariant; varnt++) {
+		uint16 numElem = in.readUint16BE();
+		if (varnt == _vm->_gameVariant) {
+			_numBonuses = numElem;
+			_points = (point_t *)malloc(sizeof(point_t) * _numBonuses);
+			for (int i = 0; i < _numBonuses; i++) {
+				_points[i].score = in.readByte();
+				_points[i].scoredFl = false;
+			}
+		} else {
+			for (int i = 0; i < numElem; i++)
+				in.readByte();
+		}
+	}
+}
+
+/**
  * Load actListArr from Hugo.dat
  */
 void Scheduler::loadActListArr(Common::ReadStream &in) {
@@ -832,6 +856,57 @@ void Scheduler::freeActListArr() {
 }
 
 /**
+ * Read _screenActs
+ */
+void Scheduler::loadScreenAct(Common::ReadStream &in) {
+	for (int varnt = 0; varnt < _vm->_numVariant; varnt++) {
+		uint16 numElem = in.readUint16BE();
+
+		uint16 **wrkScreenActs = (uint16 **)malloc(sizeof(uint16 *) * numElem);
+		for (int i = 0; i < numElem; i++) {
+			uint16 numSubElem = in.readUint16BE();
+			if (numSubElem == 0) {
+				wrkScreenActs[i] = 0;
+			} else {
+				wrkScreenActs[i] = (uint16 *)malloc(sizeof(uint16) * numSubElem);
+				for (int j = 0; j < numSubElem; j++)
+					wrkScreenActs[i][j] = in.readUint16BE();
+			}
+		}
+
+		if (varnt == _vm->_gameVariant) {
+			_screenActsSize = numElem;
+			_screenActs = wrkScreenActs;
+		} else {
+			for (int i = 0; i < numElem; i++)
+				free(wrkScreenActs[i]);
+			free(wrkScreenActs);
+		}
+	}
+}
+
+void Scheduler::freeScreenAct() {
+	if (_screenActs) {
+		for (int i = 0; i < _screenActsSize; i++)
+			free(_screenActs[i]);
+		free(_screenActs);
+	}
+}
+
+/**
+ * Add action lists for this screen to event queue
+ */
+void Scheduler::screenActions(const int screenNum) {
+	debugC(1, kDebugEngine, "screenActions(%d)", screenNum);
+
+	uint16 *screenAct = _screenActs[screenNum];
+	if (screenAct) {
+		for (int i = 0; screenAct[i]; i++)
+			insertActionList(screenAct[i]);
+	}
+}
+
+/**
  * Maze mode is enabled.  Check to see whether hero has crossed the maze
  * bounding box, if so, go to the next room
  */
@@ -935,6 +1010,13 @@ void Scheduler::restoreActions(Common::ReadStream *f) {
 	}
 }
 
+int16 Scheduler::calcMaxPoints() const {
+	int16 tmpScore = 0;
+	for (int i = 0; i < _numBonuses; i++)
+		tmpScore += _points[i].score;
+	return tmpScore;
+}
+
 /*
 * Save the action data in the file with handle f
 */
@@ -1262,7 +1344,7 @@ event_t *Scheduler::doAction(event_t *curEvent) {
 		Utils::Box(kBoxOk, "%s", _vm->_file->fetchString(action->a40.stringIndex));
 		break;
 	case COND_BONUS:                                // act41: Perform action if got bonus
-		if (_vm->_points[action->a41.BonusIndex].scoredFl)
+		if (_points[action->a41.BonusIndex].scoredFl)
 			insertActionList(action->a41.actPassIndex);
 		else
 			insertActionList(action->a41.actFailIndex);
@@ -1354,6 +1436,9 @@ void Scheduler::delQueue(event_t *curEvent) {
 	_freeEvent = curEvent;
 }
 
+/**
+ * Delete all the active events of a given type
+ */
 void Scheduler::delEventType(const action_t actTypeDel) {
 	// Note: actions are not deleted here, simply turned into NOPs!
 	event_t *wrkEvent = _headEvent;                 // The earliest event
@@ -1367,6 +1452,27 @@ void Scheduler::delEventType(const action_t actTypeDel) {
 	}
 }
 
+/**
+ * Save the points table
+ */
+void Scheduler::savePoints(Common::WriteStream *out) {
+	for (int i = 0; i < _numBonuses; i++) {
+		out->writeByte(_points[i].score);
+		out->writeByte((_points[i].scoredFl) ? 1 : 0);
+	}
+}
+
+/**
+ * Restore the points table
+ */
+void Scheduler::restorePoints(Common::ReadStream *in) {
+	// Restore points table
+	for (int i = 0; i < _numBonuses; i++) {
+		_points[i].score = in->readByte();
+		_points[i].scoredFl = (in->readByte() == 1);
+	}
+}
+
 Scheduler_v1d::Scheduler_v1d(HugoEngine *vm) : Scheduler(vm) {
 }
 
diff --git a/engines/hugo/schedule.h b/engines/hugo/schedule.h
index b4889aa..c621a61 100644
--- a/engines/hugo/schedule.h
+++ b/engines/hugo/schedule.h
@@ -458,17 +458,27 @@ public:
 	virtual void decodeString(char *line) = 0;
 	virtual void runScheduler() = 0;
 
+	void freePoints() { free(_points); }
+
+	int16 calcMaxPoints() const;
+
 	void freeActListArr();
+	void freeScreenAct();
 	void initEventQueue();
 	void insertActionList(const uint16 actIndex);
 	void loadActListArr(Common::ReadStream &in);
 	void loadAlNewscrIndex(Common::ReadStream &in);
+	void loadPoints(Common::ReadStream &in);
+	void loadScreenAct(Common::ReadStream &in);
 	void newScreen(const int screenIndex);
 	void processBonus(const int bonusIndex);
 	void processMaze(const int x1, const int x2, const int y1, const int y2);
 	void restoreScreen(const int screenIndex);
 	void restoreEvents(Common::ReadStream *f);
+	void restorePoints(Common::ReadStream *in);
 	void saveEvents(Common::WriteStream *f);
+	void savePoints(Common::WriteStream *out);
+	void screenActions(const int screenNum);
 	void waitForRefresh();
 
 	void findAction(act* action, int16* index, int16* subElem);
@@ -483,6 +493,11 @@ protected:
 
 	uint16   _actListArrSize;
 	uint16   _alNewscrIndex;
+	uint16   _screenActsSize;
+	uint16 **_screenActs;
+
+	byte     _numBonuses;
+	point_t *_points;
 
 	uint32 _curTick;                                // Current system time in ticks
 	uint32 _oldTime;                                // The previous wall time in ticks






More information about the Scummvm-git-logs mailing list