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

View File

@ -43,6 +43,7 @@
#include "hugo/util.h"
#include "hugo/object.h"
#include "hugo/text.h"
#include "hugo/mouse.h"
namespace Hugo {
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);
// Save jumpexit mode
out->writeByte((gameStatus.jumpExitFl) ? 1 : 0);
out->writeByte((_vm->_mouse->getJumpExitFl()) ? 1 : 0);
// Save gameover status
out->writeByte((gameStatus.gameOverFl) ? 1 : 0);
@ -477,7 +478,7 @@ bool FileManager::restoreGame(const int16 slot) {
_vm->setScore(score);
gameStatus.storyModeFl = (in->readByte() == 1);
gameStatus.jumpExitFl = (in->readByte() == 1);
_vm->_mouse->setJumpExitFl(in->readByte() == 1);
gameStatus.gameOverFl = (in->readByte() == 1);
for (int i = 0; i < _vm->_numScreens; i++)
_vm->_screenStates[i] = in->readByte();

View File

@ -58,7 +58,7 @@ overlay_t HugoEngine::_objBound;
maze_t _maze; // Default to not in maze
hugo_boot_t _boot; // Boot info structure file
HugoEngine::HugoEngine(OSystem *syst, const HugoGameDescription *gd) : Engine(syst), _gameDescription(gd), _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),
_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),
@ -266,14 +266,14 @@ Common::Error HugoEngine::run() {
_parser->keyHandler(event);
break;
case Common::EVENT_MOUSEMOVE:
_mouseX = event.mouse.x;
_mouseY = event.mouse.y;
_mouse->setMouseX(event.mouse.x);
_mouse->setMouseY(event.mouse.y);
break;
case Common::EVENT_LBUTTONUP:
_status.leftButtonFl = true;
_mouse->setLeftButton();
break;
case Common::EVENT_RBUTTONUP:
_status.rightButtonFl = true;
_mouse->setRightButton();
break;
case Common::EVENT_QUIT:
_status.doQuitFl = true;
@ -374,14 +374,12 @@ bool HugoEngine::loadHugoDat() {
}
// Read header
char buf[256];
char 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";
GUIErrorMessage(errorMessage);
warning("%s", errorMessage.c_str());
return false;
}
@ -389,17 +387,13 @@ bool HugoEngine::loadHugoDat() {
int minVer = in.readByte();
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);
GUIErrorMessage(buf);
warning("%s", buf);
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(errorMessage);
return false;
}
_numVariant = in.readUint16BE();
_screen->loadPalette(in);
_text->loadAllTexts(in);
// 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++) {
numElem = in.readUint16BE();
if (varnt == _gameVariant) {
@ -744,35 +738,26 @@ void HugoEngine::initStatus() {
debugC(1, kDebugEngine, "initStatus");
_status.storyModeFl = false; // Not in story mode
_status.gameOverFl = false; // Hero not knobbled yet
_status.demoFl = false; // Not demo mode
_status.textBoxFl = false; // Not processing a text box
_status.lookFl = false; // Toolbar "look" 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.jumpExitFl = false; // Can't jump to a screen exit
_status.godModeFl = false; // No special cheats allowed
_status.helpFl = false; // Not calling WinHelp()
_status.doQuitFl = false;
_status.skipIntroFl = false;
_status.path[0] = 0; // Path to write files
// Initialize every start of new game
_status.tick = 0; // Tick count
_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
// _status.recordFl = false; // Not record mode
// _status.playbackFl = false; // Not playback mode
// Strangerke - Not used ?
// _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.saveTick = 0; // Time of last save
// _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 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)
struct config_t { // User's config (saved)
@ -181,38 +180,31 @@ struct HugoGameDescription;
struct status_t { // Game status (not saved)
bool storyModeFl; // Game is telling story - no commands
bool gameOverFl; // Game is over - hero knobbled
bool demoFl; // Game is in demo mode
bool textBoxFl; // Game is (halted) in text box
bool lookFl; // Toolbar "look" 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 jumpExitFl; // Allowed to jump to a screen exit
bool godModeFl; // Allow DEBUG features in live version
bool helpFl; // Calling WinHelp (don't disable music)
bool doQuitFl;
bool skipIntroFl;
uint32 tick; // Current time in ticks
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 cx, cy; // Cursor position (dib coords)
// Strangerke - Suppress as related to playback
// bool playbackFl; // Game is in playback mode
// bool recordFl; // Game is in record mode
// Strangerke - Not used ?
// bool helpFl; // Calling WinHelp (don't disable music)
// bool mmtimeFl; // Multimedia timer supported
// bool demoFl; // Game is in demo mode
// int16 screenWidth; // Desktop screen width
// uint32 saveTick; // Time of last save in ticks
// 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 syncSoundSettings();
int getMouseX() const {
return _mouseX;
}
int getMouseY() const {
return _mouseY;
}
overlay_t &getBoundaryOverlay() {
return _boundary;
}
@ -409,8 +394,6 @@ protected:
private:
static const int kTurboTps = 16; // This many in turbo mode
int _mouseX;
int _mouseY;
byte _introXSize;
status_t _status; // Game status structure
uint32 _lastTime;

View File

@ -48,6 +48,9 @@ static const int kMaxDisp = (kXPix / kInvDx); // Max icons displayable
InventoryHandler::InventoryHandler(HugoEngine *vm) : _vm(vm) {
_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");
switch (gameStatus.inventoryState) {
switch (_inventoryState) {
case kInventoryOff: // Icon bar off screen
break;
case kInventoryUp: // Icon bar moving up
gameStatus.inventoryHeight -= kStepDy; // Move the icon bar up
if (gameStatus.inventoryHeight <= 0) // Limit travel
gameStatus.inventoryHeight = 0;
_inventoryHeight -= kStepDy; // Move the icon bar up
if (_inventoryHeight <= 0) // Limit travel
_inventoryHeight = 0;
// 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->getBackBufferBackup(), 0, gameStatus.inventoryHeight + kDibOffY, kXPix, kStepDy, kXPix, _vm->_screen->getFrontBuffer(), 0, gameStatus.inventoryHeight + kDibOffY, kXPix);
_vm->_screen->displayRect(0, kDibOffY, kXPix, gameStatus.inventoryHeight + kStepDy);
_vm->_screen->moveImage(_vm->_screen->getIconBuffer(), 0, 0, kXPix, _inventoryHeight, kXPix, _vm->_screen->getFrontBuffer(), 0, 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, _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
_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->_object->updateImages(); // Add objects back into display list for restore
gameStatus.inventoryState = kInventoryOff;
_inventoryState = kInventoryOff;
gameStatus.viewState = kViewPlay;
}
break;
case kInventoryDown: // Icon bar moving down
// If this is the first step, initialize dib_i
// and get any icon/text out of _frontBuffer
if (gameStatus.inventoryHeight == 0) {
if (_inventoryHeight == 0) {
processInventory(kInventoryActionInit); // Initialize dib_i
_vm->_screen->displayList(kDisplayRestore); // Restore _frontBuffer
_vm->_object->updateImages(); // Rebuild _frontBuffer without icons/text
_vm->_screen->displayList(kDisplayDisplay); // Blit display list to screen
}
gameStatus.inventoryHeight += kStepDy; // Move the icon bar down
if (gameStatus.inventoryHeight > kInvDy) // Limit travel
gameStatus.inventoryHeight = kInvDy;
_inventoryHeight += kStepDy; // Move the icon bar down
if (_inventoryHeight > kInvDy) // Limit travel
_inventoryHeight = kInvDy;
// 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->displayRect(0, kDibOffY, kXPix, gameStatus.inventoryHeight);
_vm->_screen->moveImage(_vm->_screen->getIconBuffer(), 0, 0, kXPix, _inventoryHeight, kXPix, _vm->_screen->getFrontBuffer(), 0, kDibOffY, kXPix);
_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
// we can't refresh objects while icon bar overlayed...
// 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->getFrontBuffer(), 0, 0, kXPix, kYPix, kXPix, _vm->_screen->getBackBuffer(), 0, 0, kXPix);
_vm->_screen->displayList(kDisplayInit);
gameStatus.inventoryState = kInventoryActive;
_inventoryState = kInventoryActive;
}
break;
case kInventoryActive: // Inventory active

View File

@ -43,6 +43,11 @@ class InventoryHandler {
public:
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, ...);
void runInventory();
@ -51,7 +56,10 @@ private:
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);
};

View File

@ -48,6 +48,11 @@
namespace Hugo {
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;
if (cx < kXPix / 2) {
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 {
sx = cx - sdx - kCursorNameOffX / 2;
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
return;
int16 inventObjId = _vm->_inventory->getInventoryObjId();
bool foundFl = false; // TRUE if route found to object
// Check if this was over iconbar
if ((gameStatus.inventoryState == kInventoryActive) && (cy < kInvDy + kDibOffY)) { // Clicked over iconbar object
if (gameStatus.inventoryObjId == -1)
if ((_vm->_inventory->getInventoryState() == kInventoryActive) && (cy < kInvDy + kDibOffY)) { // Clicked over iconbar object
if (inventObjId == -1)
_vm->_screen->selectInventoryObjId(objId);
else if (gameStatus.inventoryObjId == objId)
else if (inventObjId == objId)
_vm->_screen->resetInventoryObjId();
else
_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;
if (x >= 0) { // Hotspot refers to an exit
// Special case of immediate exit
if (gameStatus.jumpExitFl) {
if (_jumpExitFl) {
// Get rid of iconbar if necessary
if (gameStatus.inventoryState != kInventoryOff)
gameStatus.inventoryState = kInventoryUp;
if (_vm->_inventory->getInventoryState() != kInventoryOff)
_vm->_inventory->setInventoryState(kInventoryUp);
_vm->_scheduler->insertActionList(_vm->_hotspots[i].actIndex);
} else { // Set up route to exit spot
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];
// Over iconbar - immediate description
if ((gameStatus.inventoryState == kInventoryActive) && (cy < kInvDy + kDibOffY)) {
if ((_vm->_inventory->getInventoryState() == kInventoryActive) && (cy < kInvDy + kDibOffY)) {
_vm->_object->lookObject(obj);
} else {
bool foundFl = false; // TRUE if route found to object
@ -230,15 +236,15 @@ void MouseHandler::mouseHandler() {
debugC(2, kDebugMouse, "mouseHandler");
status_t &gameStatus = _vm->getGameStatus();
if ((gameStatus.viewState != kViewPlay) && (gameStatus.inventoryState != kInventoryActive))
istate_t inventState = _vm->_inventory->getInventoryState();
if ((gameStatus.viewState != kViewPlay) && (inventState != kInventoryActive))
return;
int16 cx = _vm->getMouseX();
int16 cy = _vm->getMouseY();
int16 cx = getMouseX();
int16 cy = getMouseY();
gameStatus.cx = cx; // Save cursor coords
gameStatus.cy = cy;
// gameStatus.cx = cx; // Save cursor coords
// gameStatus.cy = cy;
// Don't process if outside client area
if ((cx < 0) || (cx > kXPix) || (cy < kDibOffY) || (cy > kViewSizeY + kDibOffY))
@ -246,7 +252,7 @@ void MouseHandler::mouseHandler() {
int16 objId = -1; // Current source object
// 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);
} else {
if (cy < 5 && cy > 0) {
@ -266,7 +272,7 @@ void MouseHandler::mouseHandler() {
cursorText(name, cx, cy, U_FONT8, _TBRIGHTWHITE);
// Process right click over object in view or iconbar
if (gameStatus.rightButtonFl)
if (_rightButtonFl)
processRightClick(objId, cx, cy);
}
@ -280,12 +286,12 @@ void MouseHandler::mouseHandler() {
}
}
// Left click over icon, object or to move somewhere
if (gameStatus.leftButtonFl)
if (_leftButtonFl)
processLeftClick(objId, cx, cy);
// Clear mouse click states
gameStatus.leftButtonFl = false;
gameStatus.rightButtonFl = false;
resetLeftButton();
resetRightButton();
}
} // End of namespace Hugo

View File

@ -37,24 +37,40 @@ namespace Hugo {
class MouseHandler {
public:
MouseHandler(HugoEngine *vm);
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:
HugoEngine *_vm;
static const char kCursorNochar = '~'; // Don't show name of object under cursor
static const int kExitHotspot = -4; // Cursor over Exit hotspot
static const int kCursorNameIndex = 2; // Index of name used under cursor
static const int kCursorNameOffX = 10; // Cursor offset to name string
static const int kCursorNameOffY = -2; // Cursor offset to name string
static const int kExitHotspot = -4; // Cursor over Exit hotspot
static const int kCursorNameIndex = 2; // Index of name used under cursor
static const int kCursorNameOffX = 10; // Cursor offset to name string
static const int kCursorNameOffY = -2; // Cursor offset to name string
enum seqTextMouse {
kMsNoWayText = 0,
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);
int16 findExit(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/schedule.h"
#include "hugo/text.h"
#include "hugo/inventory.h"
namespace Hugo {
@ -95,8 +96,9 @@ void ObjectHandler::useObject(int16 objId) {
debugC(1, kDebugObject, "useObject(%d)", objId);
char *verb; // Background verb to use directly
int16 inventObjId = _vm->_inventory->getInventoryObjId();
object_t *obj = &_objects[objId]; // Ptr to object
if (_vm->getGameStatus().inventoryObjId == -1) {
if (inventObjId == -1) {
// Get or use objid directly
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));
@ -109,13 +111,13 @@ void ObjectHandler::useObject(int16 objId) {
} else {
// Use status.objid on objid
// Default to first cmd verb
sprintf(_vm->_line, "%s %s %s", _vm->_text->getVerb(_vm->_cmdList[_objects[_vm->getGameStatus().inventoryObjId].cmdIndex][0].verbIndex, 0),
_vm->_text->getNoun(_objects[_vm->getGameStatus().inventoryObjId].nounIndex, 0),
sprintf(_vm->_line, "%s %s %s", _vm->_text->getVerb(_vm->_cmdList[_objects[inventObjId].cmdIndex][0].verbIndex, 0),
_vm->_text->getNoun(_objects[inventObjId].nounIndex, 0),
_vm->_text->getNoun(obj->nounIndex, 0));
// Check valid use of objects and override verb if necessary
for (uses_t *use = _vm->_uses; use->objId != _numObj; use++) {
if (_vm->getGameStatus().inventoryObjId == use->objId) {
if (inventObjId == use->objId) {
// Look for secondary object, if found use matching verb
bool foundFl = false;
@ -123,14 +125,14 @@ void ObjectHandler::useObject(int16 objId) {
if (target->nounIndex == obj->nounIndex) {
foundFl = true;
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));
}
// No valid use of objects found, print failure string
if (!foundFl) {
// Deselect dragged icon if inventory not active
if (_vm->getGameStatus().inventoryState != kInventoryActive)
if (_vm->_inventory->getInventoryState() != kInventoryActive)
_vm->_screen->resetInventoryObjId();
Utils::Box(kBoxAny, "%s", _vm->_text->getTextData(use->dataIndex));
return;
@ -139,8 +141,8 @@ void ObjectHandler::useObject(int16 objId) {
}
}
if (_vm->getGameStatus().inventoryState == kInventoryActive) // If inventory active, remove it
_vm->getGameStatus().inventoryState = kInventoryUp;
if (_vm->_inventory->getInventoryState() == kInventoryActive) // If inventory active, remove it
_vm->_inventory->setInventoryState(kInventoryUp);
_vm->_screen->resetInventoryObjId();

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -38,10 +38,14 @@
#include "hugo/game.h"
#include "hugo/route.h"
#include "hugo/object.h"
#include "hugo/inventory.h"
namespace Hugo {
Route::Route(HugoEngine *vm) : _vm(vm) {
_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
if (_routeIndex < 0)
return;
// Current hero position
int16 herox = _vm->_hero->x + _vm->_hero->currImagePtr->x1;
int16 heroy = _vm->_hero->y + _vm->_hero->currImagePtr->y2;
status_t &gameStatus = _vm->getGameStatus();
Point *routeNode = &_route[gameStatus.routeIndex];
Point *routeNode = &_route[_routeIndex];
// Arrived at node?
if (abs(herox - routeNode->x) < kStepDx + 1 && abs(heroy - routeNode->y) < kStepDy) {
@ -433,29 +439,29 @@ void Route::processRoute() {
_vm->_hero->cycling = kCycleNotCycling;
// Arrived at final node?
if (--gameStatus.routeIndex < 0) {
if (--_routeIndex < 0) {
// See why we walked here
switch (gameStatus.go_for) {
switch (_go_for) {
case kRouteExit: // Walked to an exit, proceed into it
setWalk(_vm->_hotspots[gameStatus.go_id].direction);
setWalk(_vm->_hotspots[_go_id].direction);
break;
case kRouteLook: // Look at an object
if (turnedFl) {
_vm->_object->lookObject(&_vm->_object->_objects[gameStatus.go_id]);
_vm->_object->lookObject(&_vm->_object->_objects[_go_id]);
turnedFl = false;
} else {
setDirection(_vm->_object->_objects[gameStatus.go_id].direction);
gameStatus.routeIndex++; // Come round again
setDirection(_vm->_object->_objects[_go_id].direction);
_routeIndex++; // Come round again
turnedFl = true;
}
break;
case kRouteGet: // Get (or use) an object
if (turnedFl) {
_vm->_object->useObject(gameStatus.go_id);
_vm->_object->useObject(_go_id);
turnedFl = false;
} else {
setDirection(_vm->_object->_objects[gameStatus.go_id].direction);
gameStatus.routeIndex++; // Come round again
setDirection(_vm->_object->_objects[_go_id].direction);
_routeIndex++; // Come round again
turnedFl = true;
}
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)
return false;
status_t &gameStatus = _vm->getGameStatus();
// if inventory showing, make it go away
if (gameStatus.inventoryState != kInventoryOff)
gameStatus.inventoryState = kInventoryUp;
if (_vm->_inventory->getInventoryState() != kInventoryOff)
_vm->_inventory->setInventoryState(kInventoryUp);
gameStatus.go_for = go_for; // Purpose of trip
gameStatus.go_id = id; // Index of exit/object
_go_for = go_for; // Purpose of trip
_go_id = id; // Index of exit/object
// Adjust destination to center hero if walking to cursor
if (gameStatus.go_for == kRouteSpace)
if (_go_for == kRouteSpace)
cx -= kHeroMinWidth / 2;
bool foundFl = false; // TRUE if route found ok
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
}

View File

@ -49,6 +49,9 @@ class Route {
public:
Route(HugoEngine *vm);
void resetRoute() {_routeIndex = -1; }
int16 getRouteIndex() {return _routeIndex; }
void processRoute();
bool startRoute(const go_t go_for, const int16 id, int16 cx, int16 cy);
void setDirection(const uint16 keyCode);
@ -64,6 +67,10 @@ private:
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
segment_t _segment[kMaxSeg]; // List of points in fill-path
Point _route[kMaxNodes]; // List of nodes in route (global)

View File

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