HUGO: more refactoring and encapsulation
This commit is contained in:
parent
f1030515d0
commit
402ac930fe
18 changed files with 496 additions and 371 deletions
|
@ -607,11 +607,7 @@ void Screen::selectInventoryObjId(const int16 objId) {
|
||||||
_vm->_inventory->setInventoryObjId(objId); // Select new object
|
_vm->_inventory->setInventoryObjId(objId); // Select new object
|
||||||
|
|
||||||
// Find index of icon
|
// Find index of icon
|
||||||
int16 iconId = 0; // Find index of dragged icon
|
int16 iconId = _vm->_inventory->findIconId(objId);
|
||||||
for (; iconId < _vm->_maxInvent; iconId++) {
|
|
||||||
if (objId == _vm->_invent[iconId])
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Compute source coordinates in dib_u
|
// Compute source coordinates in dib_u
|
||||||
int16 ux = (iconId + kArrowNumb) * kInvDx % kXPix;
|
int16 ux = (iconId + kArrowNumb) * kInvDx % kXPix;
|
||||||
|
|
|
@ -369,11 +369,7 @@ bool FileManager::saveGame(const int16 slot, const Common::String &descrip) {
|
||||||
for (int i = 0; i < _vm->_numScreens; i++)
|
for (int i = 0; i < _vm->_numScreens; i++)
|
||||||
out->writeByte(_vm->_screenStates[i]);
|
out->writeByte(_vm->_screenStates[i]);
|
||||||
|
|
||||||
// Save points table
|
_vm->_scheduler->savePoints(out);
|
||||||
for (int i = 0; i < _vm->_numBonuses; i++) {
|
|
||||||
out->writeByte(_vm->_points[i].score);
|
|
||||||
out->writeByte((_vm->_points[i].scoredFl) ? 1 : 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Now save current time and all current events in event queue
|
// Now save current time and all current events in event queue
|
||||||
_vm->_scheduler->saveEvents(out);
|
_vm->_scheduler->saveEvents(out);
|
||||||
|
@ -475,12 +471,7 @@ bool FileManager::restoreGame(const int16 slot) {
|
||||||
for (int i = 0; i < _vm->_numScreens; i++)
|
for (int i = 0; i < _vm->_numScreens; i++)
|
||||||
_vm->_screenStates[i] = in->readByte();
|
_vm->_screenStates[i] = in->readByte();
|
||||||
|
|
||||||
// Restore points table
|
_vm->_scheduler->restorePoints(in);
|
||||||
for (int i = 0; i < _vm->_numBonuses; i++) {
|
|
||||||
_vm->_points[i].score = in->readByte();
|
|
||||||
_vm->_points[i].scoredFl = (in->readByte() == 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
_vm->_object->restoreAllSeq();
|
_vm->_object->restoreAllSeq();
|
||||||
|
|
||||||
// Now restore time of the save and the event queue
|
// Now restore time of the save and the event queue
|
||||||
|
|
|
@ -54,10 +54,8 @@ maze_t _maze; // Default to not in maze
|
||||||
hugo_boot_t _boot; // Boot info structure file
|
hugo_boot_t _boot; // Boot info structure file
|
||||||
|
|
||||||
HugoEngine::HugoEngine(OSystem *syst, const HugoGameDescription *gd) : Engine(syst), _gameDescription(gd),
|
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),
|
_hero(0), _heroImage(0), _defltTunes(0), _numScreens(0), _tunesNbr(0), _soundSilence(0), _soundTest(0),
|
||||||
_screenActs(0), _hero(0), _heroImage(0), _defltTunes(0), _introX(0), _introY(0), _maxInvent(0), _numBonuses(0),
|
_screenStates(0), _score(0), _maxscore(0), _lastTime(0), _curTime(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)
|
|
||||||
{
|
{
|
||||||
_system = syst;
|
_system = syst;
|
||||||
DebugMan.addDebugChannel(kDebugSchedule, "Schedule", "Script Schedule debug level");
|
DebugMan.addDebugChannel(kDebugSchedule, "Schedule", "Script Schedule debug level");
|
||||||
|
@ -80,47 +78,16 @@ HugoEngine::~HugoEngine() {
|
||||||
|
|
||||||
_screen->freePalette();
|
_screen->freePalette();
|
||||||
_text->freeAllTexts();
|
_text->freeAllTexts();
|
||||||
|
_intro->freeIntroData();
|
||||||
free(_introX);
|
_parser->freeArrayReqs();
|
||||||
free(_introY);
|
|
||||||
|
|
||||||
if (_arrayReqs) {
|
|
||||||
for (int i = 0; _arrayReqs[i] != 0; i++)
|
|
||||||
free(_arrayReqs[i]);
|
|
||||||
free(_arrayReqs);
|
|
||||||
}
|
|
||||||
|
|
||||||
_mouse->freeHotspots();
|
_mouse->freeHotspots();
|
||||||
free(_invent);
|
_inventory->freeInvent();
|
||||||
|
_object->freeObjectUses();
|
||||||
if (_uses) {
|
_parser->freeCatchallList();
|
||||||
for (int i = 0; i < _usesSize; i++)
|
_parser->freeBackgroundObjects();
|
||||||
free(_uses[i].targets);
|
_scheduler->freePoints();
|
||||||
free(_uses);
|
_parser->freeCmdList();
|
||||||
}
|
_scheduler->freeScreenAct();
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
_object->freeObjectArr();
|
_object->freeObjectArr();
|
||||||
_scheduler->freeActListArr();
|
_scheduler->freeActListArr();
|
||||||
|
|
||||||
|
@ -388,207 +355,23 @@ bool HugoEngine::loadHugoDat() {
|
||||||
}
|
}
|
||||||
|
|
||||||
_numVariant = in.readUint16BE();
|
_numVariant = in.readUint16BE();
|
||||||
|
|
||||||
_screen->loadPalette(in);
|
_screen->loadPalette(in);
|
||||||
_text->loadAllTexts(in);
|
_text->loadAllTexts(in);
|
||||||
|
_intro->loadIntroData(in);
|
||||||
// Read x_intro and y_intro
|
_parser->loadArrayReqs(in);
|
||||||
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);
|
|
||||||
|
|
||||||
_mouse->loadHotspots(in);
|
_mouse->loadHotspots(in);
|
||||||
|
_inventory->loadInvent(in);
|
||||||
int numElem, numSubElem;
|
_object->loadObjectUses(in);
|
||||||
//Read _invent
|
_parser->loadCatchallList(in);
|
||||||
for (int varnt = 0; varnt < _numVariant; varnt++) {
|
_parser->loadBackgroundObjects(in);
|
||||||
numElem = in.readUint16BE();
|
_scheduler->loadPoints(in);
|
||||||
if (varnt == _gameVariant) {
|
_parser->loadCmdList(in);
|
||||||
_maxInvent = numElem;
|
_scheduler->loadScreenAct(in);
|
||||||
_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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_object->loadObjectArr(in);
|
_object->loadObjectArr(in);
|
||||||
|
|
||||||
_hero = &_object->_objects[kHeroIndex]; // This always points to hero
|
_hero = &_object->_objects[kHeroIndex]; // This always points to hero
|
||||||
_screen_p = &(_object->_objects[kHeroIndex].screenIndex); // Current screen is hero's
|
_screen_p = &(_object->_objects[kHeroIndex].screenIndex); // Current screen is hero's
|
||||||
_heroImage = kHeroIndex; // Current in use hero image
|
_heroImage = kHeroIndex; // Current in use hero image
|
||||||
|
|
||||||
_scheduler->loadActListArr(in);
|
_scheduler->loadActListArr(in);
|
||||||
|
|
||||||
for (int varnt = 0; varnt < _numVariant; varnt++) {
|
for (int varnt = 0; varnt < _numVariant; varnt++) {
|
||||||
|
@ -603,6 +386,8 @@ bool HugoEngine::loadHugoDat() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int numElem;
|
||||||
|
|
||||||
//Read _defltTunes
|
//Read _defltTunes
|
||||||
for (int varnt = 0; varnt < _numVariant; varnt++) {
|
for (int varnt = 0; varnt < _numVariant; varnt++) {
|
||||||
numElem = in.readUint16BE();
|
numElem = in.readUint16BE();
|
||||||
|
@ -819,37 +604,6 @@ void HugoEngine::readScreenFiles(const int screenNum) {
|
||||||
_object->clearScreenBoundary(50, 311, 152);
|
_object->clearScreenBoundary(50, 311, 152);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 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
|
* Set the new screen number into the hero object and any carried objects
|
||||||
*/
|
*/
|
||||||
|
@ -866,10 +620,7 @@ void HugoEngine::setNewScreen(const int screenNum) {
|
||||||
void HugoEngine::calcMaxScore() {
|
void HugoEngine::calcMaxScore() {
|
||||||
debugC(1, kDebugEngine, "calcMaxScore");
|
debugC(1, kDebugEngine, "calcMaxScore");
|
||||||
|
|
||||||
_maxscore = _object->calcMaxScore();
|
_maxscore = _object->calcMaxScore() + _scheduler->calcMaxPoints();
|
||||||
|
|
||||||
for (int i = 0; i < _numBonuses; i++)
|
|
||||||
_maxscore += _points[i].score;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -233,8 +233,6 @@ public:
|
||||||
|
|
||||||
byte _numVariant;
|
byte _numVariant;
|
||||||
byte _gameVariant;
|
byte _gameVariant;
|
||||||
byte _maxInvent;
|
|
||||||
byte _numBonuses;
|
|
||||||
int8 _soundSilence;
|
int8 _soundSilence;
|
||||||
int8 _soundTest;
|
int8 _soundTest;
|
||||||
int8 _tunesNbr;
|
int8 _tunesNbr;
|
||||||
|
@ -245,23 +243,9 @@ public:
|
||||||
byte *_screen_p;
|
byte *_screen_p;
|
||||||
byte _heroImage;
|
byte _heroImage;
|
||||||
|
|
||||||
byte *_introX;
|
|
||||||
byte *_introY;
|
|
||||||
byte *_screenStates;
|
byte *_screenStates;
|
||||||
command_t _line; // Line of user text input
|
command_t _line; // Line of user text input
|
||||||
config_t _config; // User's config
|
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;
|
int16 *_defltTunes;
|
||||||
uint16 _look;
|
uint16 _look;
|
||||||
uint16 _take;
|
uint16 _take;
|
||||||
|
@ -295,8 +279,6 @@ public:
|
||||||
virtual bool canSaveGameStateCurrently();
|
virtual bool canSaveGameStateCurrently();
|
||||||
bool loadHugoDat();
|
bool loadHugoDat();
|
||||||
|
|
||||||
const char *useBG(const char *name);
|
|
||||||
|
|
||||||
int8 getTPS() const;
|
int8 getTPS() const;
|
||||||
|
|
||||||
void initGame(const HugoGameDescription *gd);
|
void initGame(const HugoGameDescription *gd);
|
||||||
|
@ -304,7 +286,6 @@ public:
|
||||||
void endGame();
|
void endGame();
|
||||||
void initStatus();
|
void initStatus();
|
||||||
void readScreenFiles(const int screen);
|
void readScreenFiles(const int screen);
|
||||||
void screenActions(const int screen);
|
|
||||||
void setNewScreen(const int screen);
|
void setNewScreen(const int screen);
|
||||||
void shutdown();
|
void shutdown();
|
||||||
void syncSoundSettings();
|
void syncSoundSettings();
|
||||||
|
@ -327,9 +308,6 @@ public:
|
||||||
void setMaxScore(const int newScore) {
|
void setMaxScore(const int newScore) {
|
||||||
_maxscore = newScore;
|
_maxscore = newScore;
|
||||||
}
|
}
|
||||||
byte getIntroSize() {
|
|
||||||
return _introXSize;
|
|
||||||
}
|
|
||||||
Common::Error saveGameState(int slot, const char *desc) {
|
Common::Error saveGameState(int slot, const char *desc) {
|
||||||
return (_file->saveGame(slot, desc) ? Common::kWritingFailed : Common::kNoError);
|
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."; }
|
const char *getCopyrightString() const { return "Copyright 1989-1997 David P Gray, All Rights Reserved."; }
|
||||||
|
|
||||||
Common::String getSavegameFilename(int slot);
|
Common::String getSavegameFilename(int slot);
|
||||||
|
uint16 **loadLongArray(Common::ReadStream &in);
|
||||||
|
|
||||||
FileManager *_file;
|
FileManager *_file;
|
||||||
Scheduler *_scheduler;
|
Scheduler *_scheduler;
|
||||||
|
@ -357,7 +336,6 @@ public:
|
||||||
IntroHandler *_intro;
|
IntroHandler *_intro;
|
||||||
ObjectHandler *_object;
|
ObjectHandler *_object;
|
||||||
TextHandler *_text;
|
TextHandler *_text;
|
||||||
|
|
||||||
TopMenu *_topMenu;
|
TopMenu *_topMenu;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -368,7 +346,6 @@ protected:
|
||||||
private:
|
private:
|
||||||
static const int kTurboTps = 16; // This many in turbo mode
|
static const int kTurboTps = 16; // This many in turbo mode
|
||||||
|
|
||||||
byte _introXSize;
|
|
||||||
status_t _status; // Game status structure
|
status_t _status; // Game status structure
|
||||||
uint32 _lastTime;
|
uint32 _lastTime;
|
||||||
uint32 _curTime;
|
uint32 _curTime;
|
||||||
|
@ -384,8 +361,6 @@ private:
|
||||||
int _score; // Holds current score
|
int _score; // Holds current score
|
||||||
int _maxscore; // Holds maximum score
|
int _maxscore; // Holds maximum score
|
||||||
|
|
||||||
uint16 **loadLongArray(Common::ReadStream &in);
|
|
||||||
|
|
||||||
void initPlaylist(bool playlist[kMaxTunes]);
|
void initPlaylist(bool playlist[kMaxTunes]);
|
||||||
void initConfig();
|
void initConfig();
|
||||||
void initialize();
|
void initialize();
|
||||||
|
|
|
@ -41,12 +41,41 @@
|
||||||
|
|
||||||
namespace Hugo {
|
namespace Hugo {
|
||||||
|
|
||||||
IntroHandler::IntroHandler(HugoEngine *vm) : _vm(vm) {
|
IntroHandler::IntroHandler(HugoEngine *vm) : _vm(vm), _introX(0), _introY(0) {
|
||||||
|
_introXSize = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
IntroHandler::~IntroHandler() {
|
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) {
|
intro_v1d::intro_v1d(HugoEngine *vm) : IntroHandler(vm) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,7 +97,7 @@ void intro_v1d::introInit() {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool intro_v1d::introPlay() {
|
bool intro_v1d::introPlay() {
|
||||||
byte introSize = _vm->getIntroSize();
|
byte introSize = getIntroSize();
|
||||||
|
|
||||||
if (_vm->getGameStatus().skipIntroFl)
|
if (_vm->getGameStatus().skipIntroFl)
|
||||||
return true;
|
return true;
|
||||||
|
@ -296,8 +325,8 @@ bool intro_v3d::introPlay() {
|
||||||
if (_vm->getGameStatus().skipIntroFl)
|
if (_vm->getGameStatus().skipIntroFl)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (introTicks < _vm->getIntroSize()) {
|
if (introTicks < getIntroSize()) {
|
||||||
font.drawString(&surf, ".", _vm->_introX[introTicks], _vm->_introY[introTicks] - kDibOffY, 320, _TBRIGHTWHITE);
|
font.drawString(&surf, ".", _introX[introTicks], _introY[introTicks] - kDibOffY, 320, _TBRIGHTWHITE);
|
||||||
_vm->_screen->displayBackground();
|
_vm->_screen->displayBackground();
|
||||||
|
|
||||||
// Text boxes at various times
|
// 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) {
|
intro_v1w::intro_v1w(HugoEngine *vm) : IntroHandler(vm) {
|
||||||
|
@ -387,9 +416,9 @@ bool intro_v3w::introPlay() {
|
||||||
if (_vm->getGameStatus().skipIntroFl)
|
if (_vm->getGameStatus().skipIntroFl)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (introTicks < _vm->getIntroSize()) {
|
if (introTicks < getIntroSize()) {
|
||||||
// Scale viewport x_intro,y_intro to screen (offsetting y)
|
// 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();
|
_vm->_screen->displayBackground();
|
||||||
|
|
||||||
// Text boxes at various times
|
// Text boxes at various times
|
||||||
|
@ -406,6 +435,6 @@ bool intro_v3w::introPlay() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return (++introTicks >= _vm->getIntroSize());
|
return (++introTicks >= getIntroSize());
|
||||||
}
|
}
|
||||||
} // End of namespace Hugo
|
} // End of namespace Hugo
|
||||||
|
|
|
@ -54,9 +54,18 @@ public:
|
||||||
virtual void introInit() = 0;
|
virtual void introInit() = 0;
|
||||||
virtual bool introPlay() = 0;
|
virtual bool introPlay() = 0;
|
||||||
|
|
||||||
|
void freeIntroData();
|
||||||
|
void loadIntroData(Common::ReadStream &in);
|
||||||
|
|
||||||
|
byte getIntroSize() const { return _introXSize; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
HugoEngine *_vm;
|
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 {
|
class intro_v1w : public IntroHandler {
|
||||||
|
|
|
@ -46,11 +46,30 @@ namespace Hugo {
|
||||||
|
|
||||||
static const int kMaxDisp = (kXPix / kInvDx); // Max icons displayable
|
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;
|
_firstIconId = 0;
|
||||||
_inventoryState = kInventoryOff; // Inventory icon bar state
|
_inventoryState = kInventoryOff; // Inventory icon bar state
|
||||||
_inventoryHeight = 0; // Inventory icon bar pos
|
_inventoryHeight = 0; // Inventory icon bar pos
|
||||||
_inventoryObjId = -1; // Inventory object selected (none)
|
_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 displayed = 0;
|
||||||
int16 carried = 0;
|
int16 carried = 0;
|
||||||
for (int16 i = 0; (i < imageTotNumb) && (displayed < displayNumb); i++) {
|
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
|
// Check still room to display and past first scroll index
|
||||||
if (displayed < displayNumb && carried >= firstObjId) {
|
if (displayed < displayNumb && carried >= firstObjId) {
|
||||||
// Compute source coordinates in dib_u
|
// Compute source coordinates in dib_u
|
||||||
|
@ -107,8 +126,8 @@ int16 InventoryHandler::processInventory(const invact_t action, ...) {
|
||||||
int16 imageNumb; // Total number of inventory items
|
int16 imageNumb; // Total number of inventory items
|
||||||
int displayNumb; // Total number displayed/carried
|
int displayNumb; // Total number displayed/carried
|
||||||
// Compute total number and number displayed, i.e. number carried
|
// Compute total number and number displayed, i.e. number carried
|
||||||
for (imageNumb = 0, displayNumb = 0; imageNumb < _vm->_maxInvent && _vm->_invent[imageNumb] != -1; imageNumb++) {
|
for (imageNumb = 0, displayNumb = 0; imageNumb < _maxInvent && _invent[imageNumb] != -1; imageNumb++) {
|
||||||
if (_vm->_object->isCarried(_vm->_invent[imageNumb]))
|
if (_vm->_object->isCarried(_invent[imageNumb]))
|
||||||
displayNumb++;
|
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
|
} // End of namespace Hugo
|
||||||
|
|
|
@ -45,11 +45,15 @@ public:
|
||||||
|
|
||||||
void setInventoryObjId(int16 objId) { _inventoryObjId = objId; }
|
void setInventoryObjId(int16 objId) { _inventoryObjId = objId; }
|
||||||
void setInventoryState(istate_t state) { _inventoryState = state; }
|
void setInventoryState(istate_t state) { _inventoryState = state; }
|
||||||
|
void freeInvent() { free(_invent); }
|
||||||
|
|
||||||
int16 getInventoryObjId() const { return _inventoryObjId; }
|
int16 getInventoryObjId() const { return _inventoryObjId; }
|
||||||
istate_t getInventoryState() const { return _inventoryState; }
|
istate_t getInventoryState() const { return _inventoryState; }
|
||||||
|
|
||||||
|
int16 findIconId(int16 objId);
|
||||||
|
void loadInvent(Common::ReadStream &in);
|
||||||
int16 processInventory(const invact_t action, ...);
|
int16 processInventory(const invact_t action, ...);
|
||||||
void runInventory();
|
void runInventory();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
HugoEngine *_vm;
|
HugoEngine *_vm;
|
||||||
|
@ -57,9 +61,11 @@ private:
|
||||||
static const int kStepDy = 8; // Pixels per step movement
|
static const int kStepDy = 8; // Pixels per step movement
|
||||||
|
|
||||||
int16 _firstIconId; // Index of first icon to display
|
int16 _firstIconId; // Index of first icon to display
|
||||||
|
int16 *_invent;
|
||||||
istate_t _inventoryState; // Inventory icon bar state
|
istate_t _inventoryState; // Inventory icon bar state
|
||||||
int16 _inventoryHeight; // Inventory icon bar height
|
int16 _inventoryHeight; // Inventory icon bar height
|
||||||
int16 _inventoryObjId; // Inventory object selected, or -1
|
int16 _inventoryObjId; // Inventory object selected, or -1
|
||||||
|
byte _maxInvent;
|
||||||
|
|
||||||
void constructInventory(const int16 imageTotNumb, int displayNumb, const bool scrollFl, int16 firstObjId);
|
void constructInventory(const int16 imageTotNumb, int displayNumb, const bool scrollFl, int16 firstObjId);
|
||||||
};
|
};
|
||||||
|
|
|
@ -48,9 +48,10 @@
|
||||||
|
|
||||||
namespace Hugo {
|
namespace Hugo {
|
||||||
|
|
||||||
ObjectHandler::ObjectHandler(HugoEngine *vm) : _vm(vm), _objects(0) {
|
ObjectHandler::ObjectHandler(HugoEngine *vm) : _vm(vm), _objects(0), _uses(0) {
|
||||||
_numObj = 0;
|
_numObj = 0;
|
||||||
_objCount = 0;
|
_objCount = 0;
|
||||||
|
_usesSize = 0;
|
||||||
memset(_objBound, '\0', sizeof(overlay_t));
|
memset(_objBound, '\0', sizeof(overlay_t));
|
||||||
memset(_boundary, '\0', sizeof(overlay_t));
|
memset(_boundary, '\0', sizeof(overlay_t));
|
||||||
memset(_overlay, '\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
|
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));
|
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
|
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));
|
sprintf(_vm->_line, "%s %s", _vm->_text->getVerb(_vm->_parser->getCmdDefaultVerbIdx(obj->cmdIndex), 0), _vm->_text->getNoun(obj->nounIndex, 0));
|
||||||
else if ((verb = _vm->useBG(_vm->_text->getNoun(obj->nounIndex, 0))) != 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));
|
sprintf(_vm->_line, "%s %s", verb, _vm->_text->getNoun(obj->nounIndex, 0));
|
||||||
else
|
else
|
||||||
return; // Can't use object directly
|
return; // Can't use object directly
|
||||||
} else {
|
} else {
|
||||||
// Use status.objid on objid
|
// Use status.objid on objid
|
||||||
// Default to first cmd verb
|
// 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(_objects[inventObjId].nounIndex, 0),
|
||||||
_vm->_text->getNoun(obj->nounIndex, 0));
|
_vm->_text->getNoun(obj->nounIndex, 0));
|
||||||
|
|
||||||
// Check valid use of objects and override verb if necessary
|
// 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) {
|
if (inventObjId == use->objId) {
|
||||||
// Look for secondary object, if found use matching verb
|
// Look for secondary object, if found use matching verb
|
||||||
bool foundFl = false;
|
bool foundFl = false;
|
||||||
|
@ -248,6 +249,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
|
* Compare function for the quicksort. The sort is to order the objects in
|
||||||
* increasing vertical position, using y+y2 as the baseline
|
* increasing vertical position, using y+y2 as the baseline
|
||||||
|
@ -367,6 +378,37 @@ void ObjectHandler::freeObjectArr() {
|
||||||
_objects = 0;
|
_objects = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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
|
* Load ObjectArr from Hugo.dat
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -73,7 +73,9 @@ public:
|
||||||
int calcMaxScore();
|
int calcMaxScore();
|
||||||
int16 findObject(uint16 x, uint16 y);
|
int16 findObject(uint16 x, uint16 y);
|
||||||
void freeObjects();
|
void freeObjects();
|
||||||
|
void freeObjectUses();
|
||||||
void loadObjectArr(Common::ReadStream &in);
|
void loadObjectArr(Common::ReadStream &in);
|
||||||
|
void loadObjectUses(Common::ReadStream &in);
|
||||||
void freeObjectArr();
|
void freeObjectArr();
|
||||||
void loadNumObj(Common::ReadStream &in);
|
void loadNumObj(Common::ReadStream &in);
|
||||||
void lookObject(object_t *obj);
|
void lookObject(object_t *obj);
|
||||||
|
@ -114,6 +116,8 @@ protected:
|
||||||
static const int kMaxObjNumb = 128; // Used in Update_images()
|
static const int kMaxObjNumb = 128; // Used in Update_images()
|
||||||
|
|
||||||
uint16 _objCount;
|
uint16 _objCount;
|
||||||
|
uses_t *_uses;
|
||||||
|
uint16 _usesSize;
|
||||||
|
|
||||||
void restoreSeq(object_t *obj);
|
void restoreSeq(object_t *obj);
|
||||||
|
|
||||||
|
|
|
@ -51,17 +51,167 @@
|
||||||
|
|
||||||
namespace Hugo {
|
namespace Hugo {
|
||||||
|
|
||||||
Parser::Parser(HugoEngine *vm) :
|
Parser::Parser(HugoEngine *vm) : _vm(vm), _putIndex(0), _getIndex(0), _arrayReqs(0), _catchallList(0), _backgroundObjects(0), _cmdList(0) {
|
||||||
_vm(vm), _putIndex(0), _getIndex(0), _checkDoubleF1Fl(false) {
|
|
||||||
_cmdLineIndex = 0;
|
_cmdLineIndex = 0;
|
||||||
_cmdLineTick = 0;
|
_cmdLineTick = 0;
|
||||||
_cmdLineCursor = '_';
|
_cmdLineCursor = '_';
|
||||||
_cmdLine[0] = '\0';
|
_cmdLine[0] = '\0';
|
||||||
|
_cmdListSize = 0;
|
||||||
|
_checkDoubleF1Fl = false;
|
||||||
|
_backgroundObjectsSize = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Parser::~Parser() {
|
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() {
|
void Parser::switchTurbo() {
|
||||||
_vm->_config.turboFl = !_vm->_config.turboFl;
|
_vm->_config.turboFl = !_vm->_config.turboFl;
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,11 +48,22 @@ public:
|
||||||
virtual ~Parser();
|
virtual ~Parser();
|
||||||
|
|
||||||
bool isWordPresent(char **wordArr) const;
|
bool isWordPresent(char **wordArr) const;
|
||||||
|
|
||||||
|
uint16 getCmdDefaultVerbIdx(const uint16 index) const { return _cmdList[index][0].verbIndex; }
|
||||||
|
|
||||||
void charHandler();
|
void charHandler();
|
||||||
void command(const char *format, ...);
|
void command(const char *format, ...);
|
||||||
|
void freeArrayReqs();
|
||||||
|
void freeBackgroundObjects();
|
||||||
|
void freeCatchallList();
|
||||||
|
void freeCmdList();
|
||||||
void keyHandler(Common::Event event);
|
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();
|
void switchTurbo();
|
||||||
|
const char *useBG(const char *name);
|
||||||
|
|
||||||
virtual void lineHandler() = 0;
|
virtual void lineHandler() = 0;
|
||||||
virtual void showInventory() const = 0;
|
virtual void showInventory() const = 0;
|
||||||
|
@ -64,6 +75,13 @@ protected:
|
||||||
uint32 _cmdLineTick; // For flashing cursor
|
uint32 _cmdLineTick; // For flashing cursor
|
||||||
char _cmdLineCursor;
|
char _cmdLineCursor;
|
||||||
command_t _cmdLine; // Build command line
|
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 *findNoun() const;
|
||||||
const char *findVerb() const;
|
const char *findVerb() const;
|
||||||
|
|
|
@ -192,18 +192,18 @@ bool Parser_v1d::isObjectVerb_v1(const char *word, object_t *obj) {
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; _vm->_cmdList[cmdIndex][i].verbIndex != 0; i++) { // For each cmd
|
for (i = 0; _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?
|
if (!strcmp(word, _vm->_text->getVerb(_cmdList[cmdIndex][i].verbIndex, 0))) // Is this verb catered for?
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_vm->_cmdList[cmdIndex][i].verbIndex == 0) // No
|
if (_cmdList[cmdIndex][i].verbIndex == 0) // No
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Verb match found, check all required objects are being carried
|
// 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
|
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
|
for (i = 0; reqs[i]; i++) { // for each obj
|
||||||
if (!_vm->_object->isCarrying(reqs[i])) {
|
if (!_vm->_object->isCarrying(reqs[i])) {
|
||||||
Utils::Box(kBoxAny, "%s", _vm->_text->getTextData(cmnd->textDataNoCarryIndex));
|
Utils::Box(kBoxAny, "%s", _vm->_text->getTextData(cmnd->textDataNoCarryIndex));
|
||||||
|
@ -413,16 +413,16 @@ void Parser_v1d::lineHandler() {
|
||||||
return;
|
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;
|
return;
|
||||||
} while (noun);
|
} while (noun);
|
||||||
}
|
}
|
||||||
noun = findNextNoun(noun);
|
noun = findNextNoun(noun);
|
||||||
if (*farComment != '\0') // An object matched but not near enough
|
if (*farComment != '\0') // An object matched but not near enough
|
||||||
Utils::Box(kBoxAny, "%s", farComment);
|
Utils::Box(kBoxAny, "%s", farComment);
|
||||||
else if (!isCatchallVerb_v1(true, noun, verb, _vm->_catchallList) &&
|
else if (!isCatchallVerb_v1(true, noun, verb, _catchallList) &&
|
||||||
!isCatchallVerb_v1(false, noun, verb, _vm->_backgroundObjects[*_vm->_screen_p]) &&
|
!isCatchallVerb_v1(false, noun, verb, _backgroundObjects[*_vm->_screen_p]) &&
|
||||||
!isCatchallVerb_v1(false, noun, verb, _vm->_catchallList))
|
!isCatchallVerb_v1(false, noun, verb, _catchallList))
|
||||||
Utils::Box(kBoxAny, "%s", _vm->_text->getTextParser(kTBEh_1d));
|
Utils::Box(kBoxAny, "%s", _vm->_text->getTextParser(kTBEh_1d));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -172,14 +172,14 @@ void Parser_v1w::lineHandler() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// No objects match command line, try background and catchall commands
|
// 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;
|
return;
|
||||||
if (isCatchallVerb_v3(_vm->_backgroundObjects[*_vm->_screen_p]))
|
if (isCatchallVerb_v3(_backgroundObjects[*_vm->_screen_p]))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (isBackgroundWord_v3(_vm->_catchallList))
|
if (isBackgroundWord_v3(_catchallList))
|
||||||
return;
|
return;
|
||||||
if (isCatchallVerb_v3(_vm->_catchallList))
|
if (isCatchallVerb_v3(_catchallList))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// If a not-near comment was generated, print it
|
// If a not-near comment was generated, print it
|
||||||
|
|
|
@ -165,16 +165,16 @@ void Parser_v2d::lineHandler() {
|
||||||
return;
|
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;
|
return;
|
||||||
} while (noun);
|
} while (noun);
|
||||||
}
|
}
|
||||||
|
|
||||||
noun = findNextNoun(noun);
|
noun = findNextNoun(noun);
|
||||||
if ( !isCatchallVerb_v1(true, noun, verb, _vm->_backgroundObjects[*_vm->_screen_p])
|
if ( !isCatchallVerb_v1(true, noun, verb, _backgroundObjects[*_vm->_screen_p])
|
||||||
&& !isCatchallVerb_v1(true, noun, verb, _vm->_catchallList)
|
&& !isCatchallVerb_v1(true, noun, verb, _catchallList)
|
||||||
&& !isCatchallVerb_v1(false, noun, verb, _vm->_backgroundObjects[*_vm->_screen_p])
|
&& !isCatchallVerb_v1(false, noun, verb, _backgroundObjects[*_vm->_screen_p])
|
||||||
&& !isCatchallVerb_v1(false, noun, verb, _vm->_catchallList)) {
|
&& !isCatchallVerb_v1(false, noun, verb, _catchallList)) {
|
||||||
if (*farComment != '\0') { // An object matched but not near enough
|
if (*farComment != '\0') { // An object matched but not near enough
|
||||||
Utils::Box(kBoxAny, "%s", farComment);
|
Utils::Box(kBoxAny, "%s", farComment);
|
||||||
} else if (_maze.enabledFl && (verb == _vm->_text->getVerb(_vm->_look, 0))) {
|
} else if (_maze.enabledFl && (verb == _vm->_text->getVerb(_vm->_look, 0))) {
|
||||||
|
|
|
@ -174,14 +174,14 @@ void Parser_v3d::lineHandler() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// No objects match command line, try background and catchall commands
|
// 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;
|
return;
|
||||||
if (isCatchallVerb_v3(_vm->_backgroundObjects[*_vm->_screen_p]))
|
if (isCatchallVerb_v3(_backgroundObjects[*_vm->_screen_p]))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (isBackgroundWord_v3(_vm->_catchallList))
|
if (isBackgroundWord_v3(_catchallList))
|
||||||
return;
|
return;
|
||||||
if (isCatchallVerb_v3(_vm->_catchallList))
|
if (isCatchallVerb_v3(_catchallList))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// If a not-near comment was generated, print it
|
// 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;
|
return false;
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; _vm->_cmdList[cmdIndex][i].verbIndex != 0; i++) { // For each cmd
|
for (i = 0; _cmdList[cmdIndex][i].verbIndex != 0; i++) { // For each cmd
|
||||||
if (isWordPresent(_vm->_text->getVerbArray(_vm->_cmdList[cmdIndex][i].verbIndex))) // Was this verb used?
|
if (isWordPresent(_vm->_text->getVerbArray(_cmdList[cmdIndex][i].verbIndex))) // Was this verb used?
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_vm->_cmdList[cmdIndex][i].verbIndex == 0) // No verbs used.
|
if (_cmdList[cmdIndex][i].verbIndex == 0) // No verbs used.
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Verb match found. Check if object is Near
|
// 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))
|
if (!isNear_v3(obj, verb, comment))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Check all required objects are being carried
|
// 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
|
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
|
for (i = 0; reqs[i]; i++) { // for each obj
|
||||||
if (!_vm->_object->isCarrying(reqs[i])) {
|
if (!_vm->_object->isCarrying(reqs[i])) {
|
||||||
Utils::Box(kBoxAny, "%s", _vm->_text->getTextData(cmnd->textDataNoCarryIndex));
|
Utils::Box(kBoxAny, "%s", _vm->_text->getTextData(cmnd->textDataNoCarryIndex));
|
||||||
|
|
|
@ -48,8 +48,10 @@
|
||||||
|
|
||||||
namespace Hugo {
|
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));
|
memset(_events, 0, sizeof(_events));
|
||||||
|
_numBonuses = 0;
|
||||||
|
_screenActsSize = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Scheduler::~Scheduler() {
|
Scheduler::~Scheduler() {
|
||||||
|
@ -142,9 +144,9 @@ uint32 Scheduler::getDosTicks(const bool updateFl) {
|
||||||
void Scheduler::processBonus(const int bonusIndex) {
|
void Scheduler::processBonus(const int bonusIndex) {
|
||||||
debugC(1, kDebugSchedule, "processBonus(%d)", bonusIndex);
|
debugC(1, kDebugSchedule, "processBonus(%d)", bonusIndex);
|
||||||
|
|
||||||
if (!_vm->_points[bonusIndex].scoredFl) {
|
if (!_points[bonusIndex].scoredFl) {
|
||||||
_vm->adjustScore(_vm->_points[bonusIndex].score);
|
_vm->adjustScore(_points[bonusIndex].score);
|
||||||
_vm->_points[bonusIndex].scoredFl = true;
|
_points[bonusIndex].scoredFl = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -186,7 +188,7 @@ void Scheduler::newScreen(const int screenIndex) {
|
||||||
_vm->readScreenFiles(screenIndex);
|
_vm->readScreenFiles(screenIndex);
|
||||||
|
|
||||||
// 4. Schedule action list for this screen
|
// 4. Schedule action list for this screen
|
||||||
_vm->screenActions(screenIndex);
|
_vm->_scheduler->screenActions(screenIndex);
|
||||||
|
|
||||||
// 5. Initialise prompt line and status line
|
// 5. Initialise prompt line and status line
|
||||||
_vm->_screen->initNewScreenDisplay();
|
_vm->_screen->initNewScreenDisplay();
|
||||||
|
@ -244,6 +246,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
|
* Load actListArr from Hugo.dat
|
||||||
*/
|
*/
|
||||||
|
@ -831,6 +855,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
|
* Maze mode is enabled. Check to see whether hero has crossed the maze
|
||||||
* bounding box, if so, go to the next room
|
* 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
|
* 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));
|
Utils::Box(kBoxOk, "%s", _vm->_file->fetchString(action->a40.stringIndex));
|
||||||
break;
|
break;
|
||||||
case COND_BONUS: // act41: Perform action if got bonus
|
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);
|
insertActionList(action->a41.actPassIndex);
|
||||||
else
|
else
|
||||||
insertActionList(action->a41.actFailIndex);
|
insertActionList(action->a41.actFailIndex);
|
||||||
|
@ -1354,6 +1436,9 @@ void Scheduler::delQueue(event_t *curEvent) {
|
||||||
_freeEvent = curEvent;
|
_freeEvent = curEvent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete all the active events of a given type
|
||||||
|
*/
|
||||||
void Scheduler::delEventType(const action_t actTypeDel) {
|
void Scheduler::delEventType(const action_t actTypeDel) {
|
||||||
// Note: actions are not deleted here, simply turned into NOPs!
|
// Note: actions are not deleted here, simply turned into NOPs!
|
||||||
event_t *wrkEvent = _headEvent; // The earliest event
|
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) {
|
Scheduler_v1d::Scheduler_v1d(HugoEngine *vm) : Scheduler(vm) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -458,17 +458,27 @@ public:
|
||||||
virtual void decodeString(char *line) = 0;
|
virtual void decodeString(char *line) = 0;
|
||||||
virtual void runScheduler() = 0;
|
virtual void runScheduler() = 0;
|
||||||
|
|
||||||
|
void freePoints() { free(_points); }
|
||||||
|
|
||||||
|
int16 calcMaxPoints() const;
|
||||||
|
|
||||||
void freeActListArr();
|
void freeActListArr();
|
||||||
|
void freeScreenAct();
|
||||||
void initEventQueue();
|
void initEventQueue();
|
||||||
void insertActionList(const uint16 actIndex);
|
void insertActionList(const uint16 actIndex);
|
||||||
void loadActListArr(Common::ReadStream &in);
|
void loadActListArr(Common::ReadStream &in);
|
||||||
void loadAlNewscrIndex(Common::ReadStream &in);
|
void loadAlNewscrIndex(Common::ReadStream &in);
|
||||||
|
void loadPoints(Common::ReadStream &in);
|
||||||
|
void loadScreenAct(Common::ReadStream &in);
|
||||||
void newScreen(const int screenIndex);
|
void newScreen(const int screenIndex);
|
||||||
void processBonus(const int bonusIndex);
|
void processBonus(const int bonusIndex);
|
||||||
void processMaze(const int x1, const int x2, const int y1, const int y2);
|
void processMaze(const int x1, const int x2, const int y1, const int y2);
|
||||||
void restoreScreen(const int screenIndex);
|
void restoreScreen(const int screenIndex);
|
||||||
void restoreEvents(Common::ReadStream *f);
|
void restoreEvents(Common::ReadStream *f);
|
||||||
|
void restorePoints(Common::ReadStream *in);
|
||||||
void saveEvents(Common::WriteStream *f);
|
void saveEvents(Common::WriteStream *f);
|
||||||
|
void savePoints(Common::WriteStream *out);
|
||||||
|
void screenActions(const int screenNum);
|
||||||
void waitForRefresh();
|
void waitForRefresh();
|
||||||
|
|
||||||
void findAction(act* action, int16* index, int16* subElem);
|
void findAction(act* action, int16* index, int16* subElem);
|
||||||
|
@ -483,6 +493,11 @@ protected:
|
||||||
|
|
||||||
uint16 _actListArrSize;
|
uint16 _actListArrSize;
|
||||||
uint16 _alNewscrIndex;
|
uint16 _alNewscrIndex;
|
||||||
|
uint16 _screenActsSize;
|
||||||
|
uint16 **_screenActs;
|
||||||
|
|
||||||
|
byte _numBonuses;
|
||||||
|
point_t *_points;
|
||||||
|
|
||||||
uint32 _curTick; // Current system time in ticks
|
uint32 _curTick; // Current system time in ticks
|
||||||
uint32 _oldTime; // The previous wall time in ticks
|
uint32 _oldTime; // The previous wall time in ticks
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue