HUGO: Cleanup : some refactoring and encapsulation (thanks fuzzie for the help)

svn-id: r55831
This commit is contained in:
Arnaud Boutonné 2011-02-08 20:52:26 +00:00
parent 72a9706950
commit 4917740b44
18 changed files with 173 additions and 159 deletions

View File

@ -574,14 +574,12 @@ void Screen::freeFonts() {
void Screen::selectInventoryObjId(const int16 objId) { void Screen::selectInventoryObjId(const int16 objId) {
status_t &gameStatus = _vm->getGameStatus(); _vm->_inventory->setInventoryObjId(objId); // Select new object
gameStatus.inventoryObjId = objId; // Select new object
// Find index of icon // Find index of icon
int16 iconId = 0; // Find index of dragged icon int16 iconId = 0; // Find index of dragged icon
for (; iconId < _vm->_maxInvent; iconId++) { for (; iconId < _vm->_maxInvent; iconId++) {
if (gameStatus.inventoryObjId == _vm->_invent[iconId]) if (objId == _vm->_invent[iconId])
break; break;
} }
@ -602,7 +600,7 @@ void Screen::selectInventoryObjId(const int16 objId) {
} }
void Screen::resetInventoryObjId() { void Screen::resetInventoryObjId() {
_vm->getGameStatus().inventoryObjId = -1; // Unselect object _vm->_inventory->setInventoryObjId(-1); // Unselect object
CursorMan.replaceCursor(stdMouseCursor, stdMouseCursorWidth, stdMouseCursorHeight, 1, 1, 1); CursorMan.replaceCursor(stdMouseCursor, stdMouseCursorWidth, stdMouseCursorHeight, 1, 1, 1);
} }

View File

@ -43,6 +43,7 @@
#include "hugo/util.h" #include "hugo/util.h"
#include "hugo/object.h" #include "hugo/object.h"
#include "hugo/text.h" #include "hugo/text.h"
#include "hugo/mouse.h"
namespace Hugo { namespace Hugo {
FileManager::FileManager(HugoEngine *vm) : _vm(vm) { FileManager::FileManager(HugoEngine *vm) : _vm(vm) {
@ -367,7 +368,7 @@ bool FileManager::saveGame(const int16 slot, const Common::String descrip) {
out->writeByte((gameStatus.storyModeFl) ? 1 : 0); out->writeByte((gameStatus.storyModeFl) ? 1 : 0);
// Save jumpexit mode // Save jumpexit mode
out->writeByte((gameStatus.jumpExitFl) ? 1 : 0); out->writeByte((_vm->_mouse->getJumpExitFl()) ? 1 : 0);
// Save gameover status // Save gameover status
out->writeByte((gameStatus.gameOverFl) ? 1 : 0); out->writeByte((gameStatus.gameOverFl) ? 1 : 0);
@ -477,7 +478,7 @@ bool FileManager::restoreGame(const int16 slot) {
_vm->setScore(score); _vm->setScore(score);
gameStatus.storyModeFl = (in->readByte() == 1); gameStatus.storyModeFl = (in->readByte() == 1);
gameStatus.jumpExitFl = (in->readByte() == 1); _vm->_mouse->setJumpExitFl(in->readByte() == 1);
gameStatus.gameOverFl = (in->readByte() == 1); gameStatus.gameOverFl = (in->readByte() == 1);
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();

View File

@ -58,7 +58,7 @@ overlay_t HugoEngine::_objBound;
maze_t _maze; // Default to not in maze 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), _mouseX(0), _mouseY(0), HugoEngine::HugoEngine(OSystem *syst, const HugoGameDescription *gd) : Engine(syst), _gameDescription(gd),
_arrayReqs(0), _hotspots(0), _invent(0), _uses(0), _catchallList(0), _backgroundObjects(0), _points(0), _cmdList(0), _arrayReqs(0), _hotspots(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), _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), _numScreens(0), _tunesNbr(0), _soundSilence(0), _soundTest(0), _screenStates(0), _score(0), _maxscore(0),
@ -266,14 +266,14 @@ Common::Error HugoEngine::run() {
_parser->keyHandler(event); _parser->keyHandler(event);
break; break;
case Common::EVENT_MOUSEMOVE: case Common::EVENT_MOUSEMOVE:
_mouseX = event.mouse.x; _mouse->setMouseX(event.mouse.x);
_mouseY = event.mouse.y; _mouse->setMouseY(event.mouse.y);
break; break;
case Common::EVENT_LBUTTONUP: case Common::EVENT_LBUTTONUP:
_status.leftButtonFl = true; _mouse->setLeftButton();
break; break;
case Common::EVENT_RBUTTONUP: case Common::EVENT_RBUTTONUP:
_status.rightButtonFl = true; _mouse->setRightButton();
break; break;
case Common::EVENT_QUIT: case Common::EVENT_QUIT:
_status.doQuitFl = true; _status.doQuitFl = true;
@ -374,14 +374,12 @@ bool HugoEngine::loadHugoDat() {
} }
// Read header // Read header
char buf[256]; char buf[4];
in.read(buf, 4); in.read(buf, 4);
buf[4] = '\0';
if (strcmp(buf, "HUGO")) { if (memcmp(buf, "HUGO", 4)) {
Common::String errorMessage = "File 'hugo.dat' is corrupt. Get it from the ScummVM website"; Common::String errorMessage = "File 'hugo.dat' is corrupt. Get it from the ScummVM website";
GUIErrorMessage(errorMessage); GUIErrorMessage(errorMessage);
warning("%s", errorMessage.c_str());
return false; return false;
} }
@ -389,17 +387,13 @@ bool HugoEngine::loadHugoDat() {
int minVer = in.readByte(); int minVer = in.readByte();
if ((majVer != HUGO_DAT_VER_MAJ) || (minVer != HUGO_DAT_VER_MIN)) { if ((majVer != HUGO_DAT_VER_MAJ) || (minVer != HUGO_DAT_VER_MIN)) {
snprintf(buf, 256, "File 'hugo.dat' is wrong version. Expected %d.%d but got %d.%d. Get it from the ScummVM website", HUGO_DAT_VER_MAJ, HUGO_DAT_VER_MIN, majVer, minVer); Common::String errorMessage = Common::String::format("File 'hugo.dat' is wrong version. Expected %d.%d but got %d.%d. Get it from the ScummVM website", HUGO_DAT_VER_MAJ, HUGO_DAT_VER_MIN, majVer, minVer);
GUIErrorMessage(buf); GUIErrorMessage(errorMessage);
warning("%s", buf);
return false; return false;
} }
_numVariant = in.readUint16BE(); _numVariant = in.readUint16BE();
_screen->loadPalette(in); _screen->loadPalette(in);
_text->loadAllTexts(in); _text->loadAllTexts(in);
// Read x_intro and y_intro // Read x_intro and y_intro
@ -524,7 +518,7 @@ bool HugoEngine::loadHugoDat() {
} }
} }
// Read _background_objects // Read _background_objects
for (int varnt = 0; varnt < _numVariant; varnt++) { for (int varnt = 0; varnt < _numVariant; varnt++) {
numElem = in.readUint16BE(); numElem = in.readUint16BE();
if (varnt == _gameVariant) { if (varnt == _gameVariant) {
@ -744,35 +738,26 @@ void HugoEngine::initStatus() {
debugC(1, kDebugEngine, "initStatus"); debugC(1, kDebugEngine, "initStatus");
_status.storyModeFl = false; // Not in story mode _status.storyModeFl = false; // Not in story mode
_status.gameOverFl = false; // Hero not knobbled yet _status.gameOverFl = false; // Hero not knobbled yet
_status.demoFl = false; // Not demo mode
_status.textBoxFl = false; // Not processing a text box _status.textBoxFl = false; // Not processing a text box
_status.lookFl = false; // Toolbar "look" button _status.lookFl = false; // Toolbar "look" button
_status.recallFl = false; // Toolbar "recall" button _status.recallFl = false; // Toolbar "recall" button
_status.leftButtonFl = false; // Left mouse button pressed
_status.rightButtonFl = false; // Right mouse button pressed
_status.newScreenFl = false; // Screen not just loaded _status.newScreenFl = false; // Screen not just loaded
_status.jumpExitFl = false; // Can't jump to a screen exit
_status.godModeFl = false; // No special cheats allowed _status.godModeFl = false; // No special cheats allowed
_status.helpFl = false; // Not calling WinHelp()
_status.doQuitFl = false; _status.doQuitFl = false;
_status.skipIntroFl = false; _status.skipIntroFl = false;
_status.path[0] = 0; // Path to write files
// Initialize every start of new game // Initialize every start of new game
_status.tick = 0; // Tick count _status.tick = 0; // Tick count
_status.viewState = kViewIdle; // View state _status.viewState = kViewIdle; // View state
_status.inventoryState = kInventoryOff; // Inventory icon bar state
_status.inventoryHeight = 0; // Inventory icon bar pos
_status.inventoryObjId = -1; // Inventory object selected (none)
_status.routeIndex = -1; // Hero not following a route
_status.go_for = kRouteSpace; // Hero walking to space
_status.go_id = -1; // Hero not walking to anything
// Strangerke - Suppress as related to playback // Strangerke - Suppress as related to playback
// _status.recordFl = false; // Not record mode // _status.recordFl = false; // Not record mode
// _status.playbackFl = false; // Not playback mode // _status.playbackFl = false; // Not playback mode
// Strangerke - Not used ? // Strangerke - Not used ?
// _status.mmtime = false; // Multimedia timer support // _status.mmtime = false; // Multimedia timer support
// _status.helpFl = false; // Not calling WinHelp()
// _status.demoFl = false; // Not demo mode
// _status.path[0] = 0; // Path to write files
// _status.screenWidth = 0; // Desktop screen width // _status.screenWidth = 0; // Desktop screen width
// _status.saveTick = 0; // Time of last save // _status.saveTick = 0; // Time of last save
// _status.saveSlot = 0; // Slot to save/restore game // _status.saveSlot = 0; // Slot to save/restore game

View File

@ -83,7 +83,6 @@ static const int kMaxPath = 256; // Max length of a full path
static const int kHeroMaxWidth = 24; // Maximum width of hero static const int kHeroMaxWidth = 24; // Maximum width of hero
static const int kHeroMinWidth = 16; // Minimum width of hero static const int kHeroMinWidth = 16; // Minimum width of hero
typedef char fpath_t[kMaxPath]; // File path
typedef char command_t[kMaxLineSize + 8]; // Command line (+spare for prompt,cursor) typedef char command_t[kMaxLineSize + 8]; // Command line (+spare for prompt,cursor)
struct config_t { // User's config (saved) struct config_t { // User's config (saved)
@ -181,38 +180,31 @@ struct HugoGameDescription;
struct status_t { // Game status (not saved) struct status_t { // Game status (not saved)
bool storyModeFl; // Game is telling story - no commands bool storyModeFl; // Game is telling story - no commands
bool gameOverFl; // Game is over - hero knobbled bool gameOverFl; // Game is over - hero knobbled
bool demoFl; // Game is in demo mode
bool textBoxFl; // Game is (halted) in text box bool textBoxFl; // Game is (halted) in text box
bool lookFl; // Toolbar "look" button pressed bool lookFl; // Toolbar "look" button pressed
bool recallFl; // Toolbar "recall" button pressed bool recallFl; // Toolbar "recall" button pressed
bool leftButtonFl; // Left mouse button pressed
bool rightButtonFl; // Right button pressed
bool newScreenFl; // New screen just loaded in dib_a bool newScreenFl; // New screen just loaded in dib_a
bool jumpExitFl; // Allowed to jump to a screen exit
bool godModeFl; // Allow DEBUG features in live version bool godModeFl; // Allow DEBUG features in live version
bool helpFl; // Calling WinHelp (don't disable music)
bool doQuitFl; bool doQuitFl;
bool skipIntroFl; bool skipIntroFl;
uint32 tick; // Current time in ticks uint32 tick; // Current time in ticks
vstate_t viewState; // View state machine vstate_t viewState; // View state machine
istate_t inventoryState; // Inventory icon bar state
int16 inventoryHeight; // Inventory icon bar height
int16 inventoryObjId; // Inventory object selected, or -1
int16 routeIndex; // Index into route list, or -1
go_t go_for; // Purpose of an automatic route
int16 go_id; // Index of exit of object walking to
fpath_t path; // Alternate path for saved files
int16 song; // Current song int16 song; // Current song
int16 cx, cy; // Cursor position (dib coords)
// Strangerke - Suppress as related to playback // Strangerke - Suppress as related to playback
// bool playbackFl; // Game is in playback mode // bool playbackFl; // Game is in playback mode
// bool recordFl; // Game is in record mode // bool recordFl; // Game is in record mode
// Strangerke - Not used ? // Strangerke - Not used ?
// bool helpFl; // Calling WinHelp (don't disable music)
// bool mmtimeFl; // Multimedia timer supported // bool mmtimeFl; // Multimedia timer supported
// bool demoFl; // Game is in demo mode
// int16 screenWidth; // Desktop screen width // int16 screenWidth; // Desktop screen width
// uint32 saveTick; // Time of last save in ticks
// int16 saveSlot; // Current slot to save/restore game // int16 saveSlot; // Current slot to save/restore game
// int16 cx, cy; // Cursor position (dib coords)
// uint32 saveTick; // Time of last save in ticks
//
// typedef char fpath_t[kMaxPath]; // File path
// fpath_t path; // Alternate path for saved files
}; };
/** /**
@ -332,13 +324,6 @@ public:
void storeBoundary(const int x1, const int x2, const int y); void storeBoundary(const int x1, const int x2, const int y);
void syncSoundSettings(); void syncSoundSettings();
int getMouseX() const {
return _mouseX;
}
int getMouseY() const {
return _mouseY;
}
overlay_t &getBoundaryOverlay() { overlay_t &getBoundaryOverlay() {
return _boundary; return _boundary;
} }
@ -409,8 +394,6 @@ protected:
private: private:
static const int kTurboTps = 16; // This many in turbo mode static const int kTurboTps = 16; // This many in turbo mode
int _mouseX;
int _mouseY;
byte _introXSize; byte _introXSize;
status_t _status; // Game status structure status_t _status; // Game status structure
uint32 _lastTime; uint32 _lastTime;

View File

@ -48,6 +48,9 @@ static const int kMaxDisp = (kXPix / kInvDx); // Max icons displayable
InventoryHandler::InventoryHandler(HugoEngine *vm) : _vm(vm) { InventoryHandler::InventoryHandler(HugoEngine *vm) : _vm(vm) {
_firstIconId = 0; _firstIconId = 0;
_inventoryState = kInventoryOff; // Inventory icon bar state
_inventoryHeight = 0; // Inventory icon bar pos
_inventoryObjId = -1; // Inventory object selected (none)
} }
/** /**
@ -173,47 +176,47 @@ void InventoryHandler::runInventory() {
debugC(1, kDebugInventory, "runInventory"); debugC(1, kDebugInventory, "runInventory");
switch (gameStatus.inventoryState) { switch (_inventoryState) {
case kInventoryOff: // Icon bar off screen case kInventoryOff: // Icon bar off screen
break; break;
case kInventoryUp: // Icon bar moving up case kInventoryUp: // Icon bar moving up
gameStatus.inventoryHeight -= kStepDy; // Move the icon bar up _inventoryHeight -= kStepDy; // Move the icon bar up
if (gameStatus.inventoryHeight <= 0) // Limit travel if (_inventoryHeight <= 0) // Limit travel
gameStatus.inventoryHeight = 0; _inventoryHeight = 0;
// Move visible portion to _frontBuffer, restore uncovered portion, display results // Move visible portion to _frontBuffer, restore uncovered portion, display results
_vm->_screen->moveImage(_vm->_screen->getIconBuffer(), 0, 0, kXPix, gameStatus.inventoryHeight, kXPix, _vm->_screen->getFrontBuffer(), 0, kDibOffY, kXPix); _vm->_screen->moveImage(_vm->_screen->getIconBuffer(), 0, 0, kXPix, _inventoryHeight, kXPix, _vm->_screen->getFrontBuffer(), 0, kDibOffY, kXPix);
_vm->_screen->moveImage(_vm->_screen->getBackBufferBackup(), 0, gameStatus.inventoryHeight + kDibOffY, kXPix, kStepDy, kXPix, _vm->_screen->getFrontBuffer(), 0, gameStatus.inventoryHeight + kDibOffY, kXPix); _vm->_screen->moveImage(_vm->_screen->getBackBufferBackup(), 0, _inventoryHeight + kDibOffY, kXPix, kStepDy, kXPix, _vm->_screen->getFrontBuffer(), 0, _inventoryHeight + kDibOffY, kXPix);
_vm->_screen->displayRect(0, kDibOffY, kXPix, gameStatus.inventoryHeight + kStepDy); _vm->_screen->displayRect(0, kDibOffY, kXPix, _inventoryHeight + kStepDy);
if (gameStatus.inventoryHeight == 0) { // Finished moving up? if (_inventoryHeight == 0) { // Finished moving up?
// Yes, restore dibs and exit back to game state machine // Yes, restore dibs and exit back to game state machine
_vm->_screen->moveImage(_vm->_screen->getBackBufferBackup(), 0, 0, kXPix, kYPix, kXPix, _vm->_screen->getBackBuffer(), 0, 0, kXPix); _vm->_screen->moveImage(_vm->_screen->getBackBufferBackup(), 0, 0, kXPix, kYPix, kXPix, _vm->_screen->getBackBuffer(), 0, 0, kXPix);
_vm->_screen->moveImage(_vm->_screen->getBackBuffer(), 0, 0, kXPix, kYPix, kXPix, _vm->_screen->getFrontBuffer(), 0, 0, kXPix); _vm->_screen->moveImage(_vm->_screen->getBackBuffer(), 0, 0, kXPix, kYPix, kXPix, _vm->_screen->getFrontBuffer(), 0, 0, kXPix);
_vm->_object->updateImages(); // Add objects back into display list for restore _vm->_object->updateImages(); // Add objects back into display list for restore
gameStatus.inventoryState = kInventoryOff; _inventoryState = kInventoryOff;
gameStatus.viewState = kViewPlay; gameStatus.viewState = kViewPlay;
} }
break; break;
case kInventoryDown: // Icon bar moving down case kInventoryDown: // Icon bar moving down
// If this is the first step, initialize dib_i // If this is the first step, initialize dib_i
// and get any icon/text out of _frontBuffer // and get any icon/text out of _frontBuffer
if (gameStatus.inventoryHeight == 0) { if (_inventoryHeight == 0) {
processInventory(kInventoryActionInit); // Initialize dib_i processInventory(kInventoryActionInit); // Initialize dib_i
_vm->_screen->displayList(kDisplayRestore); // Restore _frontBuffer _vm->_screen->displayList(kDisplayRestore); // Restore _frontBuffer
_vm->_object->updateImages(); // Rebuild _frontBuffer without icons/text _vm->_object->updateImages(); // Rebuild _frontBuffer without icons/text
_vm->_screen->displayList(kDisplayDisplay); // Blit display list to screen _vm->_screen->displayList(kDisplayDisplay); // Blit display list to screen
} }
gameStatus.inventoryHeight += kStepDy; // Move the icon bar down _inventoryHeight += kStepDy; // Move the icon bar down
if (gameStatus.inventoryHeight > kInvDy) // Limit travel if (_inventoryHeight > kInvDy) // Limit travel
gameStatus.inventoryHeight = kInvDy; _inventoryHeight = kInvDy;
// Move visible portion to _frontBuffer, display results // Move visible portion to _frontBuffer, display results
_vm->_screen->moveImage(_vm->_screen->getIconBuffer(), 0, 0, kXPix, gameStatus.inventoryHeight, kXPix, _vm->_screen->getFrontBuffer(), 0, kDibOffY, kXPix); _vm->_screen->moveImage(_vm->_screen->getIconBuffer(), 0, 0, kXPix, _inventoryHeight, kXPix, _vm->_screen->getFrontBuffer(), 0, kDibOffY, kXPix);
_vm->_screen->displayRect(0, kDibOffY, kXPix, gameStatus.inventoryHeight); _vm->_screen->displayRect(0, kDibOffY, kXPix, _inventoryHeight);
if (gameStatus.inventoryHeight == kInvDy) { // Finished moving down? if (_inventoryHeight == kInvDy) { // Finished moving down?
// Yes, prepare view dibs for special inventory display since // Yes, prepare view dibs for special inventory display since
// we can't refresh objects while icon bar overlayed... // we can't refresh objects while icon bar overlayed...
// 1. Save backing store _backBuffer in temporary dib_c // 1. Save backing store _backBuffer in temporary dib_c
@ -222,7 +225,7 @@ void InventoryHandler::runInventory() {
_vm->_screen->moveImage(_vm->_screen->getBackBuffer(), 0, 0, kXPix, kYPix, kXPix, _vm->_screen->getBackBufferBackup(), 0, 0, kXPix); _vm->_screen->moveImage(_vm->_screen->getBackBuffer(), 0, 0, kXPix, kYPix, kXPix, _vm->_screen->getBackBufferBackup(), 0, 0, kXPix);
_vm->_screen->moveImage(_vm->_screen->getFrontBuffer(), 0, 0, kXPix, kYPix, kXPix, _vm->_screen->getBackBuffer(), 0, 0, kXPix); _vm->_screen->moveImage(_vm->_screen->getFrontBuffer(), 0, 0, kXPix, kYPix, kXPix, _vm->_screen->getBackBuffer(), 0, 0, kXPix);
_vm->_screen->displayList(kDisplayInit); _vm->_screen->displayList(kDisplayInit);
gameStatus.inventoryState = kInventoryActive; _inventoryState = kInventoryActive;
} }
break; break;
case kInventoryActive: // Inventory active case kInventoryActive: // Inventory active

View File

@ -43,6 +43,11 @@ class InventoryHandler {
public: public:
InventoryHandler(HugoEngine *vm); InventoryHandler(HugoEngine *vm);
void setInventoryObjId(int16 objId) { _inventoryObjId = objId; }
int16 getInventoryObjId() { return _inventoryObjId; }
void setInventoryState(istate_t state) { _inventoryState = state; }
istate_t getInventoryState() { return _inventoryState; }
int16 processInventory(const invact_t action, ...); int16 processInventory(const invact_t action, ...);
void runInventory(); void runInventory();
@ -51,7 +56,10 @@ 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
istate_t _inventoryState; // Inventory icon bar state
int16 _inventoryHeight; // Inventory icon bar height
int16 _inventoryObjId; // Inventory object selected, or -1
void constructInventory(const int16 imageTotNumb, int displayNumb, const bool scrollFl, int16 firstObjId); void constructInventory(const int16 imageTotNumb, int displayNumb, const bool scrollFl, int16 firstObjId);
}; };

View File

@ -48,6 +48,11 @@
namespace Hugo { namespace Hugo {
MouseHandler::MouseHandler(HugoEngine *vm) : _vm(vm) { MouseHandler::MouseHandler(HugoEngine *vm) : _vm(vm) {
_leftButtonFl = false;
_rightButtonFl = false;
_jumpExitFl = false; // Can't jump to a screen exit
_mouseX = kXPix / 2;
_mouseY = kYPix / 2;
} }
/** /**
@ -64,7 +69,7 @@ void MouseHandler::cursorText(const char *buffer, const int16 cx, const int16 cy
int16 sx, sy; int16 sx, sy;
if (cx < kXPix / 2) { if (cx < kXPix / 2) {
sx = cx + kCursorNameOffX; sx = cx + kCursorNameOffX;
sy = (_vm->getGameStatus().inventoryObjId == -1) ? cy + kCursorNameOffY : cy + kCursorNameOffY - (_vm->_screen->fontHeight() + 1); sy = (_vm->_inventory->getInventoryObjId() == -1) ? cy + kCursorNameOffY : cy + kCursorNameOffY - (_vm->_screen->fontHeight() + 1);
} else { } else {
sx = cx - sdx - kCursorNameOffX / 2; sx = cx - sdx - kCursorNameOffX / 2;
sy = cy + kCursorNameOffY; sy = cy + kCursorNameOffY;
@ -103,12 +108,13 @@ void MouseHandler::processRightClick(const int16 objId, const int16 cx, const in
if (gameStatus.storyModeFl || _vm->_hero->pathType == kPathQuiet) // Make sure user has control if (gameStatus.storyModeFl || _vm->_hero->pathType == kPathQuiet) // Make sure user has control
return; return;
int16 inventObjId = _vm->_inventory->getInventoryObjId();
bool foundFl = false; // TRUE if route found to object bool foundFl = false; // TRUE if route found to object
// Check if this was over iconbar // Check if this was over iconbar
if ((gameStatus.inventoryState == kInventoryActive) && (cy < kInvDy + kDibOffY)) { // Clicked over iconbar object if ((_vm->_inventory->getInventoryState() == kInventoryActive) && (cy < kInvDy + kDibOffY)) { // Clicked over iconbar object
if (gameStatus.inventoryObjId == -1) if (inventObjId == -1)
_vm->_screen->selectInventoryObjId(objId); _vm->_screen->selectInventoryObjId(objId);
else if (gameStatus.inventoryObjId == objId) else if (inventObjId == objId)
_vm->_screen->resetInventoryObjId(); _vm->_screen->resetInventoryObjId();
else else
_vm->_object->useObject(objId); // Use status.objid on object _vm->_object->useObject(objId); // Use status.objid on object
@ -173,10 +179,10 @@ void MouseHandler::processLeftClick(const int16 objId, const int16 cx, const int
y = _vm->_hotspots[i].viewy; y = _vm->_hotspots[i].viewy;
if (x >= 0) { // Hotspot refers to an exit if (x >= 0) { // Hotspot refers to an exit
// Special case of immediate exit // Special case of immediate exit
if (gameStatus.jumpExitFl) { if (_jumpExitFl) {
// Get rid of iconbar if necessary // Get rid of iconbar if necessary
if (gameStatus.inventoryState != kInventoryOff) if (_vm->_inventory->getInventoryState() != kInventoryOff)
gameStatus.inventoryState = kInventoryUp; _vm->_inventory->setInventoryState(kInventoryUp);
_vm->_scheduler->insertActionList(_vm->_hotspots[i].actIndex); _vm->_scheduler->insertActionList(_vm->_hotspots[i].actIndex);
} else { // Set up route to exit spot } else { // Set up route to exit spot
if (_vm->_hotspots[i].direction == Common::KEYCODE_RIGHT) if (_vm->_hotspots[i].direction == Common::KEYCODE_RIGHT)
@ -195,7 +201,7 @@ void MouseHandler::processLeftClick(const int16 objId, const int16 cx, const int
obj = &_vm->_object->_objects[objId]; obj = &_vm->_object->_objects[objId];
// Over iconbar - immediate description // Over iconbar - immediate description
if ((gameStatus.inventoryState == kInventoryActive) && (cy < kInvDy + kDibOffY)) { if ((_vm->_inventory->getInventoryState() == kInventoryActive) && (cy < kInvDy + kDibOffY)) {
_vm->_object->lookObject(obj); _vm->_object->lookObject(obj);
} else { } else {
bool foundFl = false; // TRUE if route found to object bool foundFl = false; // TRUE if route found to object
@ -230,15 +236,15 @@ void MouseHandler::mouseHandler() {
debugC(2, kDebugMouse, "mouseHandler"); debugC(2, kDebugMouse, "mouseHandler");
status_t &gameStatus = _vm->getGameStatus(); status_t &gameStatus = _vm->getGameStatus();
istate_t inventState = _vm->_inventory->getInventoryState();
if ((gameStatus.viewState != kViewPlay) && (gameStatus.inventoryState != kInventoryActive)) if ((gameStatus.viewState != kViewPlay) && (inventState != kInventoryActive))
return; return;
int16 cx = _vm->getMouseX(); int16 cx = getMouseX();
int16 cy = _vm->getMouseY(); int16 cy = getMouseY();
gameStatus.cx = cx; // Save cursor coords // gameStatus.cx = cx; // Save cursor coords
gameStatus.cy = cy; // gameStatus.cy = cy;
// Don't process if outside client area // Don't process if outside client area
if ((cx < 0) || (cx > kXPix) || (cy < kDibOffY) || (cy > kViewSizeY + kDibOffY)) if ((cx < 0) || (cx > kXPix) || (cy < kDibOffY) || (cy > kViewSizeY + kDibOffY))
@ -246,7 +252,7 @@ void MouseHandler::mouseHandler() {
int16 objId = -1; // Current source object int16 objId = -1; // Current source object
// Process cursor over an object or icon // Process cursor over an object or icon
if (gameStatus.inventoryState == kInventoryActive) { // Check inventory icon bar first if (inventState == kInventoryActive) { // Check inventory icon bar first
objId = _vm->_inventory->processInventory(kInventoryActionGet, cx, cy); objId = _vm->_inventory->processInventory(kInventoryActionGet, cx, cy);
} else { } else {
if (cy < 5 && cy > 0) { if (cy < 5 && cy > 0) {
@ -266,7 +272,7 @@ void MouseHandler::mouseHandler() {
cursorText(name, cx, cy, U_FONT8, _TBRIGHTWHITE); cursorText(name, cx, cy, U_FONT8, _TBRIGHTWHITE);
// Process right click over object in view or iconbar // Process right click over object in view or iconbar
if (gameStatus.rightButtonFl) if (_rightButtonFl)
processRightClick(objId, cx, cy); processRightClick(objId, cx, cy);
} }
@ -280,12 +286,12 @@ void MouseHandler::mouseHandler() {
} }
} }
// Left click over icon, object or to move somewhere // Left click over icon, object or to move somewhere
if (gameStatus.leftButtonFl) if (_leftButtonFl)
processLeftClick(objId, cx, cy); processLeftClick(objId, cx, cy);
// Clear mouse click states // Clear mouse click states
gameStatus.leftButtonFl = false; resetLeftButton();
gameStatus.rightButtonFl = false; resetRightButton();
} }
} // End of namespace Hugo } // End of namespace Hugo

View File

@ -37,24 +37,40 @@ namespace Hugo {
class MouseHandler { class MouseHandler {
public: public:
MouseHandler(HugoEngine *vm); MouseHandler(HugoEngine *vm);
void mouseHandler(); void mouseHandler();
void resetLeftButton() { _leftButtonFl = false; }
void resetRightButton() { _rightButtonFl = false; }
void setLeftButton() { _leftButtonFl = true; }
void setRightButton() { _rightButtonFl = true; }
void setJumpExitFl(bool fl) { _jumpExitFl = fl; }
void setMouseX(int x) { _mouseX = x; }
void setMouseY(int y) { _mouseY = y; }
bool getJumpExitFl() const { return _jumpExitFl; }
int getMouseX() const { return _mouseX; }
int getMouseY() const { return _mouseY; }
private: private:
HugoEngine *_vm; HugoEngine *_vm;
static const char kCursorNochar = '~'; // Don't show name of object under cursor static const char kCursorNochar = '~'; // Don't show name of object under cursor
static const int kExitHotspot = -4; // Cursor over Exit hotspot
static const int kExitHotspot = -4; // Cursor over Exit hotspot static const int kCursorNameIndex = 2; // Index of name used under cursor
static const int kCursorNameIndex = 2; // Index of name used under cursor static const int kCursorNameOffX = 10; // Cursor offset to name string
static const int kCursorNameOffX = 10; // Cursor offset to name string static const int kCursorNameOffY = -2; // Cursor offset to name string
static const int kCursorNameOffY = -2; // Cursor offset to name string
enum seqTextMouse { enum seqTextMouse {
kMsNoWayText = 0, kMsNoWayText = 0,
kMsExit = 1 kMsExit = 1
}; };
bool _leftButtonFl; // Left mouse button pressed
bool _rightButtonFl; // Right button pressed
int _mouseX;
int _mouseY;
bool _jumpExitFl; // Allowed to jump to a screen exit
void cursorText(const char *buffer, const int16 cx, const int16 cy, const uif_t fontId, const int16 color); void cursorText(const char *buffer, const int16 cx, const int16 cy, const uif_t fontId, const int16 color);
int16 findExit(const int16 cx, const int16 cy); int16 findExit(const int16 cx, const int16 cy);
void processRightClick(const int16 objId, const int16 cx, const int16 cy); void processRightClick(const int16 objId, const int16 cx, const int16 cy);

View File

@ -43,6 +43,7 @@
#include "hugo/parser.h" #include "hugo/parser.h"
#include "hugo/schedule.h" #include "hugo/schedule.h"
#include "hugo/text.h" #include "hugo/text.h"
#include "hugo/inventory.h"
namespace Hugo { namespace Hugo {
@ -95,8 +96,9 @@ void ObjectHandler::useObject(int16 objId) {
debugC(1, kDebugObject, "useObject(%d)", objId); debugC(1, kDebugObject, "useObject(%d)", objId);
char *verb; // Background verb to use directly char *verb; // Background verb to use directly
int16 inventObjId = _vm->_inventory->getInventoryObjId();
object_t *obj = &_objects[objId]; // Ptr to object object_t *obj = &_objects[objId]; // Ptr to object
if (_vm->getGameStatus().inventoryObjId == -1) { if (inventObjId == -1) {
// Get or use objid directly // Get or use objid directly
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));
@ -109,13 +111,13 @@ void ObjectHandler::useObject(int16 objId) {
} 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[_vm->getGameStatus().inventoryObjId].cmdIndex][0].verbIndex, 0), sprintf(_vm->_line, "%s %s %s", _vm->_text->getVerb(_vm->_cmdList[_objects[inventObjId].cmdIndex][0].verbIndex, 0),
_vm->_text->getNoun(_objects[_vm->getGameStatus().inventoryObjId].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 = _vm->_uses; use->objId != _numObj; use++) {
if (_vm->getGameStatus().inventoryObjId == 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;
@ -123,14 +125,14 @@ void ObjectHandler::useObject(int16 objId) {
if (target->nounIndex == obj->nounIndex) { if (target->nounIndex == obj->nounIndex) {
foundFl = true; foundFl = true;
sprintf(_vm->_line, "%s %s %s", _vm->_text->getVerb(target->verbIndex, 0), sprintf(_vm->_line, "%s %s %s", _vm->_text->getVerb(target->verbIndex, 0),
_vm->_text->getNoun(_objects[_vm->getGameStatus().inventoryObjId].nounIndex, 0), _vm->_text->getNoun(_objects[inventObjId].nounIndex, 0),
_vm->_text->getNoun(obj->nounIndex, 0)); _vm->_text->getNoun(obj->nounIndex, 0));
} }
// No valid use of objects found, print failure string // No valid use of objects found, print failure string
if (!foundFl) { if (!foundFl) {
// Deselect dragged icon if inventory not active // Deselect dragged icon if inventory not active
if (_vm->getGameStatus().inventoryState != kInventoryActive) if (_vm->_inventory->getInventoryState() != kInventoryActive)
_vm->_screen->resetInventoryObjId(); _vm->_screen->resetInventoryObjId();
Utils::Box(kBoxAny, "%s", _vm->_text->getTextData(use->dataIndex)); Utils::Box(kBoxAny, "%s", _vm->_text->getTextData(use->dataIndex));
return; return;
@ -139,8 +141,8 @@ void ObjectHandler::useObject(int16 objId) {
} }
} }
if (_vm->getGameStatus().inventoryState == kInventoryActive) // If inventory active, remove it if (_vm->_inventory->getInventoryState() == kInventoryActive) // If inventory active, remove it
_vm->getGameStatus().inventoryState = kInventoryUp; _vm->_inventory->setInventoryState(kInventoryUp);
_vm->_screen->resetInventoryObjId(); _vm->_screen->resetInventoryObjId();

View File

@ -178,9 +178,8 @@ void ObjectHandler_v1d::moveObjects() {
debugC(4, kDebugObject, "moveObjects"); debugC(4, kDebugObject, "moveObjects");
// Added to DOS version in order to handle mouse properly // Added to DOS version in order to handle mouse properly
// If route mode enabled, do special route processing // Do special route processing
if (_vm->getGameStatus().routeIndex >= 0) _vm->_route->processRoute();
_vm->_route->processRoute();
// Perform any adjustments to velocity based on special path types // Perform any adjustments to velocity based on special path types
// and store all (visible) object baselines into the boundary file. // and store all (visible) object baselines into the boundary file.

View File

@ -175,9 +175,8 @@ void ObjectHandler_v1w::updateImages() {
void ObjectHandler_v1w::moveObjects() { void ObjectHandler_v1w::moveObjects() {
debugC(4, kDebugObject, "moveObjects"); debugC(4, kDebugObject, "moveObjects");
// If route mode enabled, do special route processing // Do special route processing
if (_vm->getGameStatus().routeIndex >= 0) _vm->_route->processRoute();
_vm->_route->processRoute();
// Perform any adjustments to velocity based on special path types // Perform any adjustments to velocity based on special path types
// and store all (visible) object baselines into the boundary file. // and store all (visible) object baselines into the boundary file.

View File

@ -178,9 +178,8 @@ void ObjectHandler_v2d::moveObjects() {
debugC(4, kDebugObject, "moveObjects"); debugC(4, kDebugObject, "moveObjects");
// Added to DOS version in order to handle mouse properly // Added to DOS version in order to handle mouse properly
// If route mode enabled, do special route processing // Do special route processing
if (_vm->getGameStatus().routeIndex >= 0) _vm->_route->processRoute();
_vm->_route->processRoute();
// Perform any adjustments to velocity based on special path types // Perform any adjustments to velocity based on special path types
// and store all (visible) object baselines into the boundary file. // and store all (visible) object baselines into the boundary file.

View File

@ -59,9 +59,8 @@ void ObjectHandler_v3d::moveObjects() {
debugC(4, kDebugObject, "moveObjects"); debugC(4, kDebugObject, "moveObjects");
// Added to DOS version in order to handle mouse properly // Added to DOS version in order to handle mouse properly
// If route mode enabled, do special route processing // Do special route processing
if (_vm->getGameStatus().routeIndex >= 0) _vm->_route->processRoute();
_vm->_route->processRoute();
// Perform any adjustments to velocity based on special path types // Perform any adjustments to velocity based on special path types
// and store all (visible) object baselines into the boundary file. // and store all (visible) object baselines into the boundary file.

View File

@ -47,6 +47,7 @@
#include "hugo/sound.h" #include "hugo/sound.h"
#include "hugo/object.h" #include "hugo/object.h"
#include "hugo/text.h" #include "hugo/text.h"
#include "hugo/inventory.h"
namespace Hugo { namespace Hugo {
@ -88,8 +89,8 @@ void Parser::charHandler() {
case Common::KEYCODE_RETURN: // EOL, pass line to line handler case Common::KEYCODE_RETURN: // EOL, pass line to line handler
if (_cmdLineIndex && (_vm->_hero->pathType != kPathQuiet)) { if (_cmdLineIndex && (_vm->_hero->pathType != kPathQuiet)) {
// Remove inventory bar if active // Remove inventory bar if active
if (gameStatus.inventoryState == kInventoryActive) if (_vm->_inventory->getInventoryState() == kInventoryActive)
gameStatus.inventoryState = kInventoryUp; _vm->_inventory->setInventoryState(kInventoryUp);
// Call Line handler and reset line // Call Line handler and reset line
command(_cmdLine); command(_cmdLine);
_cmdLine[_cmdLineIndex = 0] = '\0'; _cmdLine[_cmdLineIndex = 0] = '\0';
@ -172,8 +173,8 @@ void Parser::keyHandler(Common::Event event) {
if (gameStatus.viewState == kViewIntro) if (gameStatus.viewState == kViewIntro)
gameStatus.skipIntroFl = true; gameStatus.skipIntroFl = true;
else { else {
if (gameStatus.inventoryState == kInventoryActive) // Remove inventory, if displayed if (_vm->_inventory->getInventoryState() == kInventoryActive) // Remove inventory, if displayed
gameStatus.inventoryState = kInventoryUp; _vm->_inventory->setInventoryState(kInventoryUp);
_vm->_screen->resetInventoryObjId(); _vm->_screen->resetInventoryObjId();
} }
break; break;
@ -193,7 +194,7 @@ void Parser::keyHandler(Common::Event event) {
case Common::KEYCODE_KP6: case Common::KEYCODE_KP6:
case Common::KEYCODE_KP8: case Common::KEYCODE_KP8:
case Common::KEYCODE_KP2: case Common::KEYCODE_KP2:
gameStatus.routeIndex = -1; // Stop any automatic route _vm->_route->resetRoute(); // Stop any automatic route
_vm->_route->setWalk(nChar); // Direction of hero travel _vm->_route->setWalk(nChar); // Direction of hero travel
break; break;
case Common::KEYCODE_F1: // User Help (DOS) case Common::KEYCODE_F1: // User Help (DOS)

View File

@ -45,6 +45,7 @@
#include "hugo/sound.h" #include "hugo/sound.h"
#include "hugo/object.h" #include "hugo/object.h"
#include "hugo/text.h" #include "hugo/text.h"
#include "hugo/inventory.h"
namespace Hugo { namespace Hugo {
Parser_v1w::Parser_v1w(HugoEngine *vm) : Parser_v3d(vm) { Parser_v1w::Parser_v1w(HugoEngine *vm) : Parser_v3d(vm) {
@ -206,13 +207,14 @@ void Parser_v1w::lineHandler() {
void Parser_v1w::showInventory() const { void Parser_v1w::showInventory() const {
status_t &gameStatus = _vm->getGameStatus(); status_t &gameStatus = _vm->getGameStatus();
istate_t inventState = _vm->_inventory->getInventoryState();
if (gameStatus.gameOverFl) { if (gameStatus.gameOverFl) {
Utils::gameOverMsg(); Utils::gameOverMsg();
} else if ((gameStatus.inventoryState == kInventoryOff) && (gameStatus.viewState == kViewPlay)) { } else if ((inventState == kInventoryOff) && (gameStatus.viewState == kViewPlay)) {
gameStatus.inventoryState = kInventoryDown; _vm->_inventory->setInventoryState(kInventoryDown);
gameStatus.viewState = kViewInvent; gameStatus.viewState = kViewInvent;
} else if (gameStatus.inventoryState == kInventoryActive) { } else if (inventState == kInventoryActive) {
gameStatus.inventoryState = kInventoryUp; _vm->_inventory->setInventoryState(kInventoryUp);
gameStatus.viewState = kViewInvent; gameStatus.viewState = kViewInvent;
} }
} }

View File

@ -38,10 +38,14 @@
#include "hugo/game.h" #include "hugo/game.h"
#include "hugo/route.h" #include "hugo/route.h"
#include "hugo/object.h" #include "hugo/object.h"
#include "hugo/inventory.h"
namespace Hugo { namespace Hugo {
Route::Route(HugoEngine *vm) : _vm(vm) { Route::Route(HugoEngine *vm) : _vm(vm) {
_oldWalkDirection = 0; _oldWalkDirection = 0;
_routeIndex = -1; // Hero not following a route
_go_for = kRouteSpace; // Hero walking to space
_go_id = -1; // Hero not walking to anything
} }
/** /**
@ -417,11 +421,13 @@ void Route::processRoute() {
static bool turnedFl = false; // Used to get extra cylce for turning static bool turnedFl = false; // Used to get extra cylce for turning
if (_routeIndex < 0)
return;
// Current hero position // Current hero position
int16 herox = _vm->_hero->x + _vm->_hero->currImagePtr->x1; int16 herox = _vm->_hero->x + _vm->_hero->currImagePtr->x1;
int16 heroy = _vm->_hero->y + _vm->_hero->currImagePtr->y2; int16 heroy = _vm->_hero->y + _vm->_hero->currImagePtr->y2;
status_t &gameStatus = _vm->getGameStatus(); Point *routeNode = &_route[_routeIndex];
Point *routeNode = &_route[gameStatus.routeIndex];
// Arrived at node? // Arrived at node?
if (abs(herox - routeNode->x) < kStepDx + 1 && abs(heroy - routeNode->y) < kStepDy) { if (abs(herox - routeNode->x) < kStepDx + 1 && abs(heroy - routeNode->y) < kStepDy) {
@ -433,29 +439,29 @@ void Route::processRoute() {
_vm->_hero->cycling = kCycleNotCycling; _vm->_hero->cycling = kCycleNotCycling;
// Arrived at final node? // Arrived at final node?
if (--gameStatus.routeIndex < 0) { if (--_routeIndex < 0) {
// See why we walked here // See why we walked here
switch (gameStatus.go_for) { switch (_go_for) {
case kRouteExit: // Walked to an exit, proceed into it case kRouteExit: // Walked to an exit, proceed into it
setWalk(_vm->_hotspots[gameStatus.go_id].direction); setWalk(_vm->_hotspots[_go_id].direction);
break; break;
case kRouteLook: // Look at an object case kRouteLook: // Look at an object
if (turnedFl) { if (turnedFl) {
_vm->_object->lookObject(&_vm->_object->_objects[gameStatus.go_id]); _vm->_object->lookObject(&_vm->_object->_objects[_go_id]);
turnedFl = false; turnedFl = false;
} else { } else {
setDirection(_vm->_object->_objects[gameStatus.go_id].direction); setDirection(_vm->_object->_objects[_go_id].direction);
gameStatus.routeIndex++; // Come round again _routeIndex++; // Come round again
turnedFl = true; turnedFl = true;
} }
break; break;
case kRouteGet: // Get (or use) an object case kRouteGet: // Get (or use) an object
if (turnedFl) { if (turnedFl) {
_vm->_object->useObject(gameStatus.go_id); _vm->_object->useObject(_go_id);
turnedFl = false; turnedFl = false;
} else { } else {
setDirection(_vm->_object->_objects[gameStatus.go_id].direction); setDirection(_vm->_object->_objects[_go_id].direction);
gameStatus.routeIndex++; // Come round again _routeIndex++; // Come round again
turnedFl = true; turnedFl = true;
} }
break; break;
@ -493,21 +499,20 @@ bool Route::startRoute(const go_t go_for, const int16 id, int16 cx, int16 cy) {
if (_vm->_hero->pathType != kPathUser) if (_vm->_hero->pathType != kPathUser)
return false; return false;
status_t &gameStatus = _vm->getGameStatus();
// if inventory showing, make it go away // if inventory showing, make it go away
if (gameStatus.inventoryState != kInventoryOff) if (_vm->_inventory->getInventoryState() != kInventoryOff)
gameStatus.inventoryState = kInventoryUp; _vm->_inventory->setInventoryState(kInventoryUp);
gameStatus.go_for = go_for; // Purpose of trip _go_for = go_for; // Purpose of trip
gameStatus.go_id = id; // Index of exit/object _go_id = id; // Index of exit/object
// Adjust destination to center hero if walking to cursor // Adjust destination to center hero if walking to cursor
if (gameStatus.go_for == kRouteSpace) if (_go_for == kRouteSpace)
cx -= kHeroMinWidth / 2; cx -= kHeroMinWidth / 2;
bool foundFl = false; // TRUE if route found ok bool foundFl = false; // TRUE if route found ok
if ((foundFl = findRoute(cx, cy))) { // Found a route? if ((foundFl = findRoute(cx, cy))) { // Found a route?
gameStatus.routeIndex = _routeListIndex; // Node index _routeIndex = _routeListIndex; // Node index
_vm->_hero->vx = _vm->_hero->vy = 0; // Stop manual motion _vm->_hero->vx = _vm->_hero->vy = 0; // Stop manual motion
} }

View File

@ -49,6 +49,9 @@ class Route {
public: public:
Route(HugoEngine *vm); Route(HugoEngine *vm);
void resetRoute() {_routeIndex = -1; }
int16 getRouteIndex() {return _routeIndex; }
void processRoute(); void processRoute();
bool startRoute(const go_t go_for, const int16 id, int16 cx, int16 cy); bool startRoute(const go_t go_for, const int16 id, int16 cx, int16 cy);
void setDirection(const uint16 keyCode); void setDirection(const uint16 keyCode);
@ -64,6 +67,10 @@ private:
uint16 _oldWalkDirection; // Last direction char uint16 _oldWalkDirection; // Last direction char
int16 _routeIndex; // Index into route list, or -1
go_t _go_for; // Purpose of an automatic route
int16 _go_id; // Index of exit of object walking to
byte _boundaryMap[kYPix][kXPix]; // Boundary byte map byte _boundaryMap[kYPix][kXPix]; // Boundary byte map
segment_t _segment[kMaxSeg]; // List of points in fill-path segment_t _segment[kMaxSeg]; // List of points in fill-path
Point _route[kMaxNodes]; // List of nodes in route (global) Point _route[kMaxNodes]; // List of nodes in route (global)

View File

@ -43,6 +43,8 @@
#include "hugo/sound.h" #include "hugo/sound.h"
#include "hugo/parser.h" #include "hugo/parser.h"
#include "hugo/text.h" #include "hugo/text.h"
#include "hugo/route.h"
#include "hugo/mouse.h"
namespace Hugo { namespace Hugo {
@ -836,35 +838,33 @@ void Scheduler::freeActListArr() {
void Scheduler::processMaze(const int x1, const int x2, const int y1, const int y2) { void Scheduler::processMaze(const int x1, const int x2, const int y1, const int y2) {
debugC(1, kDebugSchedule, "processMaze"); debugC(1, kDebugSchedule, "processMaze");
status_t &gameStatus = _vm->getGameStatus();
if (x1 < _maze.x1) { if (x1 < _maze.x1) {
// Exit west // Exit west
_actListArr[_alNewscrIndex][3].a8.screenIndex = *_vm->_screen_p - 1; _actListArr[_alNewscrIndex][3].a8.screenIndex = *_vm->_screen_p - 1;
_actListArr[_alNewscrIndex][0].a2.x = _maze.x2 - kShiftSize - (x2 - x1); _actListArr[_alNewscrIndex][0].a2.x = _maze.x2 - kShiftSize - (x2 - x1);
_actListArr[_alNewscrIndex][0].a2.y = _vm->_hero->y; _actListArr[_alNewscrIndex][0].a2.y = _vm->_hero->y;
gameStatus.routeIndex = -1; _vm->_route->resetRoute();
insertActionList(_alNewscrIndex); insertActionList(_alNewscrIndex);
} else if (x2 > _maze.x2) { } else if (x2 > _maze.x2) {
// Exit east // Exit east
_actListArr[_alNewscrIndex][3].a8.screenIndex = *_vm->_screen_p + 1; _actListArr[_alNewscrIndex][3].a8.screenIndex = *_vm->_screen_p + 1;
_actListArr[_alNewscrIndex][0].a2.x = _maze.x1 + kShiftSize; _actListArr[_alNewscrIndex][0].a2.x = _maze.x1 + kShiftSize;
_actListArr[_alNewscrIndex][0].a2.y = _vm->_hero->y; _actListArr[_alNewscrIndex][0].a2.y = _vm->_hero->y;
gameStatus.routeIndex = -1; _vm->_route->resetRoute();
insertActionList(_alNewscrIndex); insertActionList(_alNewscrIndex);
} else if (y1 < _maze.y1 - kShiftSize) { } else if (y1 < _maze.y1 - kShiftSize) {
// Exit north // Exit north
_actListArr[_alNewscrIndex][3].a8.screenIndex = *_vm->_screen_p - _maze.size; _actListArr[_alNewscrIndex][3].a8.screenIndex = *_vm->_screen_p - _maze.size;
_actListArr[_alNewscrIndex][0].a2.x = _maze.x3; _actListArr[_alNewscrIndex][0].a2.x = _maze.x3;
_actListArr[_alNewscrIndex][0].a2.y = _maze.y2 - kShiftSize - (y2 - y1); _actListArr[_alNewscrIndex][0].a2.y = _maze.y2 - kShiftSize - (y2 - y1);
gameStatus.routeIndex = -1; _vm->_route->resetRoute();
insertActionList(_alNewscrIndex); insertActionList(_alNewscrIndex);
} else if (y2 > _maze.y2 - kShiftSize / 2) { } else if (y2 > _maze.y2 - kShiftSize / 2) {
// Exit south // Exit south
_actListArr[_alNewscrIndex][3].a8.screenIndex = *_vm->_screen_p + _maze.size; _actListArr[_alNewscrIndex][3].a8.screenIndex = *_vm->_screen_p + _maze.size;
_actListArr[_alNewscrIndex][0].a2.x = _maze.x4; _actListArr[_alNewscrIndex][0].a2.x = _maze.x4;
_actListArr[_alNewscrIndex][0].a2.y = _maze.y1 + kShiftSize; _actListArr[_alNewscrIndex][0].a2.y = _maze.y1 + kShiftSize;
gameStatus.routeIndex = -1; _vm->_route->resetRoute();
insertActionList(_alNewscrIndex); insertActionList(_alNewscrIndex);
} }
} }
@ -1259,7 +1259,8 @@ event_t *Scheduler::doAction(event_t *curEvent) {
gameStatus.storyModeFl = action->a39.storyModeFl; gameStatus.storyModeFl = action->a39.storyModeFl;
// End the game after story if this is special vendor demo mode // End the game after story if this is special vendor demo mode
if (gameStatus.demoFl && action->a39.storyModeFl == false) // if (gameStatus.demoFl && action->a39.storyModeFl == false)
if (action->a39.storyModeFl == false)
_vm->endGame(); _vm->endGame();
break; break;
case WARN: // act40: Text box (CF TEXT) case WARN: // act40: Text box (CF TEXT)
@ -1281,10 +1282,10 @@ event_t *Scheduler::doAction(event_t *curEvent) {
insertActionList(action->a43.actNoIndex); insertActionList(action->a43.actNoIndex);
break; break;
case STOP_ROUTE: // act44: Stop any route in progress case STOP_ROUTE: // act44: Stop any route in progress
gameStatus.routeIndex = -1; _vm->_route->resetRoute();
break; break;
case COND_ROUTE: // act45: Conditional on route in progress case COND_ROUTE: // act45: Conditional on route in progress
if (gameStatus.routeIndex >= action->a45.routeIndex) if (_vm->_route->getRouteIndex() >= action->a45.routeIndex)
insertActionList(action->a45.actPassIndex); insertActionList(action->a45.actPassIndex);
else else
insertActionList(action->a45.actFailIndex); insertActionList(action->a45.actFailIndex);
@ -1293,7 +1294,7 @@ event_t *Scheduler::doAction(event_t *curEvent) {
// This is to allow left click on exit to get there immediately // This is to allow left click on exit to get there immediately
// For example the plane crash in Hugo2 where hero is invisible // For example the plane crash in Hugo2 where hero is invisible
// Couldn't use INVISIBLE flag since conflicts with boat in Hugo1 // Couldn't use INVISIBLE flag since conflicts with boat in Hugo1
gameStatus.jumpExitFl = action->a46.jumpExitFl; _vm->_mouse->setJumpExitFl(action->a46.jumpExitFl);
break; break;
case INIT_VIEW: // act47: Init object.viewx, viewy, dir case INIT_VIEW: // act47: Init object.viewx, viewy, dir
_vm->_object->_objects[action->a47.objIndex].viewx = action->a47.viewx; _vm->_object->_objects[action->a47.objIndex].viewx = action->a47.viewx;