HUGO: Moved _objects to a separate file
also suppressed some dereferencing svn-id: r53674
This commit is contained in:
parent
d251521f63
commit
0101a0e0bb
41 changed files with 1548 additions and 1424 deletions
|
@ -48,7 +48,7 @@ namespace Hugo {
|
||||||
#define INY(Y, B) (Y >= B->y && Y <= B->y + B->dy)
|
#define INY(Y, B) (Y >= B->y && Y <= B->y + B->dy)
|
||||||
#define OVERLAP(A, B) ((INX(A->x, B) || INX(A->x + A->dx, B) || INX(B->x, A) || INX(B->x + B->dx, A)) && (INY(A->y, B) || INY(A->y + A->dy, B) || INY(B->y, A) || INY(B->y + B->dy, A)))
|
#define OVERLAP(A, B) ((INX(A->x, B) || INX(A->x + A->dx, B) || INX(B->x, A) || INX(B->x + B->dx, A)) && (INY(A->y, B) || INY(A->y + A->dy, B) || INY(B->y, A) || INY(B->y + B->dy, A)))
|
||||||
|
|
||||||
Screen::Screen(HugoEngine &vm) : _vm(vm) {
|
Screen::Screen(HugoEngine *vm) : _vm(vm) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,7 +58,7 @@ Screen::~Screen() {
|
||||||
void Screen::createPal() {
|
void Screen::createPal() {
|
||||||
debugC(1, kDebugDisplay, "createPal");
|
debugC(1, kDebugDisplay, "createPal");
|
||||||
|
|
||||||
g_system->setPalette(_vm._palette, 0, NUM_COLORS);
|
g_system->setPalette(_vm->_palette, 0, NUM_COLORS);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Screen::initDisplay() {
|
void Screen::initDisplay() {
|
||||||
|
@ -135,7 +135,7 @@ overlayState_t Screen::findOvl(seq_t *seq_p, image_pt dst_p, uint16 y) {
|
||||||
debugC(4, kDebugDisplay, "findOvl");
|
debugC(4, kDebugDisplay, "findOvl");
|
||||||
|
|
||||||
for (; y < seq_p->lines; y++) { // Each line in object
|
for (; y < seq_p->lines; y++) { // Each line in object
|
||||||
image_pt ovb_p = _vm.getBaseBoundaryOverlay() + ((uint16)(dst_p - _frontBuffer) >> 3); // Ptr into overlay bits
|
image_pt ovb_p = _vm->getBaseBoundaryOverlay() + ((uint16)(dst_p - _frontBuffer) >> 3); // Ptr into overlay bits
|
||||||
if (*ovb_p & (0x80 >> ((uint16)(dst_p - _frontBuffer) & 7))) // Overlay bit is set
|
if (*ovb_p & (0x80 >> ((uint16)(dst_p - _frontBuffer) & 7))) // Overlay bit is set
|
||||||
return FG; // Found a bit - must be foreground
|
return FG; // Found a bit - must be foreground
|
||||||
dst_p += XPIX;
|
dst_p += XPIX;
|
||||||
|
@ -151,7 +151,7 @@ void Screen::displayFrame(int sx, int sy, seq_t *seq, bool foreFl) {
|
||||||
|
|
||||||
image_pt image = seq->imagePtr; // Ptr to object image data
|
image_pt image = seq->imagePtr; // Ptr to object image data
|
||||||
image_pt subFrontBuffer = &_frontBuffer[sy * XPIX + sx]; // Ptr to offset in _frontBuffer
|
image_pt subFrontBuffer = &_frontBuffer[sy * XPIX + sx]; // Ptr to offset in _frontBuffer
|
||||||
image_pt overlay = &_vm.getFirstOverlay()[(sy * XPIX + sx) >> 3]; // Ptr to overlay data
|
image_pt overlay = &_vm->getFirstOverlay()[(sy * XPIX + sx) >> 3]; // Ptr to overlay data
|
||||||
int16 frontBufferwrap = XPIX - seq->x2 - 1; // Wraps dest_p after each line
|
int16 frontBufferwrap = XPIX - seq->x2 - 1; // Wraps dest_p after each line
|
||||||
int16 imageWrap = seq->bytesPerLine8 - seq->x2 - 1;
|
int16 imageWrap = seq->bytesPerLine8 - seq->x2 - 1;
|
||||||
|
|
||||||
|
@ -159,7 +159,7 @@ void Screen::displayFrame(int sx, int sy, seq_t *seq, bool foreFl) {
|
||||||
for (uint16 y = 0; y < seq->lines; y++) { // Each line in object
|
for (uint16 y = 0; y < seq->lines; y++) { // Each line in object
|
||||||
for (uint16 x = 0; x <= seq->x2; x++) {
|
for (uint16 x = 0; x <= seq->x2; x++) {
|
||||||
if (*image) { // Non-transparent
|
if (*image) { // Non-transparent
|
||||||
overlay = _vm.getFirstOverlay() + ((uint16)(subFrontBuffer - _frontBuffer) >> 3); // Ptr into overlay bits
|
overlay = _vm->getFirstOverlay() + ((uint16)(subFrontBuffer - _frontBuffer) >> 3); // Ptr into overlay bits
|
||||||
if (*overlay & (0x80 >> ((uint16)(subFrontBuffer - _frontBuffer) & 7))) { // Overlay bit is set
|
if (*overlay & (0x80 >> ((uint16)(subFrontBuffer - _frontBuffer) & 7))) { // Overlay bit is set
|
||||||
if (overlayState == UNDEF) // Overlay defined yet?
|
if (overlayState == UNDEF) // Overlay defined yet?
|
||||||
overlayState = findOvl(seq, subFrontBuffer, y);// No, find it.
|
overlayState = findOvl(seq, subFrontBuffer, y);// No, find it.
|
||||||
|
@ -269,8 +269,8 @@ void Screen::displayList(dupdate_t update, ...) {
|
||||||
// Don't blit if newscreen just loaded because _frontBuffer will
|
// Don't blit if newscreen just loaded because _frontBuffer will
|
||||||
// get blitted via InvalidateRect() at end of this cycle
|
// get blitted via InvalidateRect() at end of this cycle
|
||||||
// and blitting here causes objects to appear too soon.
|
// and blitting here causes objects to appear too soon.
|
||||||
if (_vm.getGameStatus().newScreenFl) {
|
if (_vm->getGameStatus().newScreenFl) {
|
||||||
_vm.getGameStatus().newScreenFl = false;
|
_vm->getGameStatus().newScreenFl = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -394,18 +394,18 @@ void Screen::drawStatusText() {
|
||||||
debugC(4, kDebugDisplay, "drawStatusText");
|
debugC(4, kDebugDisplay, "drawStatusText");
|
||||||
|
|
||||||
loadFont(U_FONT8);
|
loadFont(U_FONT8);
|
||||||
uint16 sdx = stringLength(_vm._statusLine);
|
uint16 sdx = stringLength(_vm->_statusLine);
|
||||||
uint16 sdy = fontHeight() + 1; // + 1 for shadow
|
uint16 sdy = fontHeight() + 1; // + 1 for shadow
|
||||||
uint16 posX = 0;
|
uint16 posX = 0;
|
||||||
uint16 posY = YPIX - sdy;
|
uint16 posY = YPIX - sdy;
|
||||||
|
|
||||||
// Display the string and add rect to display list
|
// Display the string and add rect to display list
|
||||||
writeStr(posX, posY, _vm._statusLine, _TLIGHTYELLOW);
|
writeStr(posX, posY, _vm->_statusLine, _TLIGHTYELLOW);
|
||||||
displayList(D_ADD, posX, posY, sdx, sdy);
|
displayList(D_ADD, posX, posY, sdx, sdy);
|
||||||
|
|
||||||
sdx = stringLength(_vm._scoreLine);
|
sdx = stringLength(_vm->_scoreLine);
|
||||||
posY = 0;
|
posY = 0;
|
||||||
writeStr(posX, posY, _vm._scoreLine, _TCYAN);
|
writeStr(posX, posY, _vm->_scoreLine, _TCYAN);
|
||||||
displayList(D_ADD, posX, posY, sdx, sdy);
|
displayList(D_ADD, posX, posY, sdx, sdy);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -447,7 +447,7 @@ void Screen::initNewScreenDisplay() {
|
||||||
displayBackground();
|
displayBackground();
|
||||||
|
|
||||||
// Stop premature object display in Display_list(D_DISPLAY)
|
// Stop premature object display in Display_list(D_DISPLAY)
|
||||||
_vm.getGameStatus().newScreenFl = true;
|
_vm->getGameStatus().newScreenFl = true;
|
||||||
}
|
}
|
||||||
} // End of namespace Hugo
|
} // End of namespace Hugo
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,7 @@ struct rect_t { // Rectangle used in Display
|
||||||
|
|
||||||
class Screen {
|
class Screen {
|
||||||
public:
|
public:
|
||||||
Screen(HugoEngine &vm);
|
Screen(HugoEngine *vm);
|
||||||
virtual ~Screen();
|
virtual ~Screen();
|
||||||
|
|
||||||
int16 fontHeight();
|
int16 fontHeight();
|
||||||
|
@ -93,7 +93,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
HugoEngine &_vm;
|
HugoEngine *_vm;
|
||||||
|
|
||||||
// Fonts used in dib (non-GDI)
|
// Fonts used in dib (non-GDI)
|
||||||
byte _fnt; // Current font number
|
byte _fnt; // Current font number
|
||||||
|
@ -116,7 +116,7 @@ private:
|
||||||
|
|
||||||
class Screen_v1d : public Screen {
|
class Screen_v1d : public Screen {
|
||||||
public:
|
public:
|
||||||
Screen_v1d(HugoEngine &vm);
|
Screen_v1d(HugoEngine *vm);
|
||||||
~Screen_v1d();
|
~Screen_v1d();
|
||||||
|
|
||||||
virtual void loadFont(int16 fontId);
|
virtual void loadFont(int16 fontId);
|
||||||
|
@ -124,7 +124,7 @@ public:
|
||||||
|
|
||||||
class Screen_v1w : public Screen {
|
class Screen_v1w : public Screen {
|
||||||
public:
|
public:
|
||||||
Screen_v1w(HugoEngine &vm);
|
Screen_v1w(HugoEngine *vm);
|
||||||
~Screen_v1w();
|
~Screen_v1w();
|
||||||
|
|
||||||
virtual void loadFont(int16 fontId);
|
virtual void loadFont(int16 fontId);
|
||||||
|
|
|
@ -40,7 +40,7 @@
|
||||||
|
|
||||||
namespace Hugo {
|
namespace Hugo {
|
||||||
|
|
||||||
Screen_v1d::Screen_v1d(HugoEngine &vm) : Screen(vm) {
|
Screen_v1d::Screen_v1d(HugoEngine *vm) : Screen(vm) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Screen_v1d::~Screen_v1d() {
|
Screen_v1d::~Screen_v1d() {
|
||||||
|
@ -61,7 +61,7 @@ void Screen_v1d::loadFont(int16 fontId) {
|
||||||
|
|
||||||
fontLoadedFl[_fnt] = true;
|
fontLoadedFl[_fnt] = true;
|
||||||
|
|
||||||
memcpy(_fontdata[_fnt], _vm._arrayFont[_fnt], _vm._arrayFontSize[_fnt]);
|
memcpy(_fontdata[_fnt], _vm->_arrayFont[_fnt], _vm->_arrayFontSize[_fnt]);
|
||||||
_font[_fnt][0] = _fontdata[_fnt]; // Store height,width of fonts
|
_font[_fnt][0] = _fontdata[_fnt]; // Store height,width of fonts
|
||||||
|
|
||||||
int16 offset = 2; // Start at fontdata[2] ([0],[1] used for height,width)
|
int16 offset = 2; // Start at fontdata[2] ([0],[1] used for height,width)
|
||||||
|
|
|
@ -41,7 +41,7 @@
|
||||||
|
|
||||||
namespace Hugo {
|
namespace Hugo {
|
||||||
|
|
||||||
Screen_v1w::Screen_v1w(HugoEngine &vm) : Screen(vm) {
|
Screen_v1w::Screen_v1w(HugoEngine *vm) : Screen(vm) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Screen_v1w::~Screen_v1w() {
|
Screen_v1w::~Screen_v1w() {
|
||||||
|
@ -59,7 +59,7 @@ void Screen_v1w::loadFont(int16 fontId) {
|
||||||
return;
|
return;
|
||||||
|
|
||||||
fontLoadedFl[_fnt] = true;
|
fontLoadedFl[_fnt] = true;
|
||||||
_vm.file().readUIFItem(fontId, _fontdata[_fnt]);
|
_vm->_file->readUIFItem(fontId, _fontdata[_fnt]);
|
||||||
|
|
||||||
// Compile font ptrs. Note: First ptr points to height,width of font
|
// Compile font ptrs. Note: First ptr points to height,width of font
|
||||||
_font[_fnt][0] = _fontdata[_fnt]; // Store height,width of fonts
|
_font[_fnt][0] = _fontdata[_fnt]; // Store height,width of fonts
|
||||||
|
|
|
@ -39,9 +39,10 @@
|
||||||
#include "hugo/schedule.h"
|
#include "hugo/schedule.h"
|
||||||
#include "hugo/display.h"
|
#include "hugo/display.h"
|
||||||
#include "hugo/util.h"
|
#include "hugo/util.h"
|
||||||
|
#include "hugo/object.h"
|
||||||
|
|
||||||
namespace Hugo {
|
namespace Hugo {
|
||||||
FileManager::FileManager(HugoEngine &vm) : _vm(vm) {
|
FileManager::FileManager(HugoEngine *vm) : _vm(vm) {
|
||||||
}
|
}
|
||||||
|
|
||||||
FileManager::~FileManager() {
|
FileManager::~FileManager() {
|
||||||
|
@ -143,7 +144,7 @@ void FileManager::readImage(int objNum, object_t *objPtr) {
|
||||||
if (!objPtr->seqNumb) // This object has no images
|
if (!objPtr->seqNumb) // This object has no images
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (_vm.isPacked()) {
|
if (_vm->isPacked()) {
|
||||||
_objectsArchive.seek((uint32)objNum * sizeof(objBlock_t), SEEK_SET);
|
_objectsArchive.seek((uint32)objNum * sizeof(objBlock_t), SEEK_SET);
|
||||||
|
|
||||||
objBlock_t objBlock; // Info on file within database
|
objBlock_t objBlock; // Info on file within database
|
||||||
|
@ -153,10 +154,10 @@ void FileManager::readImage(int objNum, object_t *objPtr) {
|
||||||
_objectsArchive.seek(objBlock.objOffset, SEEK_SET);
|
_objectsArchive.seek(objBlock.objOffset, SEEK_SET);
|
||||||
} else {
|
} else {
|
||||||
char *buf = (char *) malloc(2048 + 1); // Buffer for file access
|
char *buf = (char *) malloc(2048 + 1); // Buffer for file access
|
||||||
strcat(strcat(strcpy(buf, _vm._picDir), _vm._arrayNouns[objPtr->nounIndex][0]), OBJEXT);
|
strcat(strcat(strcpy(buf, _vm->_picDir), _vm->_arrayNouns[objPtr->nounIndex][0]), OBJEXT);
|
||||||
if (!_objectsArchive.open(buf)) {
|
if (!_objectsArchive.open(buf)) {
|
||||||
warning("File %s not found, trying again with %s%s", buf, _vm._arrayNouns[objPtr->nounIndex][0], OBJEXT);
|
warning("File %s not found, trying again with %s%s", buf, _vm->_arrayNouns[objPtr->nounIndex][0], OBJEXT);
|
||||||
strcat(strcpy(buf, _vm._arrayNouns[objPtr->nounIndex][0]), OBJEXT);
|
strcat(strcpy(buf, _vm->_arrayNouns[objPtr->nounIndex][0]), OBJEXT);
|
||||||
if (!_objectsArchive.open(buf))
|
if (!_objectsArchive.open(buf))
|
||||||
Utils::Error(FILE_ERR, "%s", buf);
|
Utils::Error(FILE_ERR, "%s", buf);
|
||||||
}
|
}
|
||||||
|
@ -170,12 +171,12 @@ void FileManager::readImage(int objNum, object_t *objPtr) {
|
||||||
for (int k = 0; k < objPtr->seqList[j].imageNbr; k++) { // each image
|
for (int k = 0; k < objPtr->seqList[j].imageNbr; k++) { // each image
|
||||||
if (k == 0) { // First image
|
if (k == 0) { // First image
|
||||||
// Read this image - allocate both seq and image memory
|
// Read this image - allocate both seq and image memory
|
||||||
seqPtr = readPCX(_objectsArchive, 0, 0, firstFl, _vm._arrayNouns[objPtr->nounIndex][0]);
|
seqPtr = readPCX(_objectsArchive, 0, 0, firstFl, _vm->_arrayNouns[objPtr->nounIndex][0]);
|
||||||
objPtr->seqList[j].seqPtr = seqPtr;
|
objPtr->seqList[j].seqPtr = seqPtr;
|
||||||
firstFl = false;
|
firstFl = false;
|
||||||
} else { // Subsequent image
|
} else { // Subsequent image
|
||||||
// Read this image - allocate both seq and image memory
|
// Read this image - allocate both seq and image memory
|
||||||
seqPtr->nextSeqPtr = readPCX(_objectsArchive, 0, 0, firstFl, _vm._arrayNouns[objPtr->nounIndex][0]);
|
seqPtr->nextSeqPtr = readPCX(_objectsArchive, 0, 0, firstFl, _vm->_arrayNouns[objPtr->nounIndex][0]);
|
||||||
seqPtr = seqPtr->nextSeqPtr;
|
seqPtr = seqPtr->nextSeqPtr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -222,7 +223,7 @@ void FileManager::readImage(int objNum, object_t *objPtr) {
|
||||||
warning("Unexpected cycling: %d", objPtr->cycling);
|
warning("Unexpected cycling: %d", objPtr->cycling);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_vm.isPacked())
|
if (!_vm->isPacked())
|
||||||
_objectsArchive.close();
|
_objectsArchive.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -232,7 +233,7 @@ sound_pt FileManager::getSound(int16 sound, uint16 *size) {
|
||||||
debugC(1, kDebugFile, "getSound(%d, %d)", sound, *size);
|
debugC(1, kDebugFile, "getSound(%d, %d)", sound, *size);
|
||||||
|
|
||||||
// No more to do if SILENCE (called for cleanup purposes)
|
// No more to do if SILENCE (called for cleanup purposes)
|
||||||
if (sound == _vm._soundSilence)
|
if (sound == _vm->_soundSilence)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
// Open sounds file
|
// Open sounds file
|
||||||
|
@ -283,35 +284,6 @@ bool FileManager::fileExists(char *filename) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileManager::saveSeq(object_t *obj) {
|
|
||||||
// Save sequence number and image number in given object
|
|
||||||
debugC(1, kDebugFile, "saveSeq");
|
|
||||||
|
|
||||||
bool found = false;
|
|
||||||
for (int j = 0; !found && (j < obj->seqNumb); j++) {
|
|
||||||
seq_t *q = obj->seqList[j].seqPtr;
|
|
||||||
for (int k = 0; !found && (k < obj->seqList[j].imageNbr); k++) {
|
|
||||||
if (obj->currImagePtr == q) {
|
|
||||||
found = true;
|
|
||||||
obj->curSeqNum = j;
|
|
||||||
obj->curImageNum = k;
|
|
||||||
} else {
|
|
||||||
q = q->nextSeqPtr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void FileManager::restoreSeq(object_t *obj) {
|
|
||||||
// Set up cur_seq_p from stored sequence and image number in object
|
|
||||||
debugC(1, kDebugFile, "restoreSeq");
|
|
||||||
|
|
||||||
seq_t *q = obj->seqList[obj->curSeqNum].seqPtr;
|
|
||||||
for (int j = 0; j < obj->curImageNum; j++)
|
|
||||||
q = q->nextSeqPtr;
|
|
||||||
obj->currImagePtr = q;
|
|
||||||
}
|
|
||||||
|
|
||||||
void FileManager::saveGame(int16 slot, const char *descrip) {
|
void FileManager::saveGame(int16 slot, const char *descrip) {
|
||||||
// Save game to supplied slot (-1 is INITFILE)
|
// Save game to supplied slot (-1 is INITFILE)
|
||||||
debugC(1, kDebugFile, "saveGame(%d, %s)", slot, descrip);
|
debugC(1, kDebugFile, "saveGame(%d, %s)", slot, descrip);
|
||||||
|
@ -320,11 +292,11 @@ void FileManager::saveGame(int16 slot, const char *descrip) {
|
||||||
Common::String path; // Full path of saved game
|
Common::String path; // Full path of saved game
|
||||||
|
|
||||||
if (slot == -1)
|
if (slot == -1)
|
||||||
path = _vm._initFilename;
|
path = _vm->_initFilename;
|
||||||
else
|
else
|
||||||
path = Common::String::printf(_vm._saveFilename.c_str(), slot);
|
path = Common::String::printf(_vm->_saveFilename.c_str(), slot);
|
||||||
|
|
||||||
Common::WriteStream *out = _vm.getSaveFileManager()->openForSaving(path);
|
Common::WriteStream *out = _vm->getSaveFileManager()->openForSaving(path);
|
||||||
if (!out) {
|
if (!out) {
|
||||||
warning("Can't create file '%s', game not saved", path.c_str());
|
warning("Can't create file '%s', game not saved", path.c_str());
|
||||||
return;
|
return;
|
||||||
|
@ -337,19 +309,19 @@ void FileManager::saveGame(int16 slot, const char *descrip) {
|
||||||
out->write(descrip, DESCRIPLEN);
|
out->write(descrip, DESCRIPLEN);
|
||||||
|
|
||||||
// Save objects
|
// Save objects
|
||||||
for (int i = 0; i < _vm._numObj; i++) {
|
for (int i = 0; i < _vm->_numObj; i++) {
|
||||||
// Save where curr_seq_p is pointing to
|
// Save where curr_seq_p is pointing to
|
||||||
saveSeq(&_vm._objects[i]);
|
_vm->_object->saveSeq(&_vm->_object->_objects[i]);
|
||||||
out->write(&_vm._objects[i], sizeof(object_t));
|
out->write(&_vm->_object->_objects[i], sizeof(object_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
const status_t &gameStatus = _vm.getGameStatus();
|
const status_t &gameStatus = _vm->getGameStatus();
|
||||||
|
|
||||||
// Save whether hero image is swapped
|
// Save whether hero image is swapped
|
||||||
out->write(&_vm._heroImage, sizeof(_vm._heroImage));
|
out->write(&_vm->_heroImage, sizeof(_vm->_heroImage));
|
||||||
|
|
||||||
// Save score
|
// Save score
|
||||||
int score = _vm.getScore();
|
int score = _vm->getScore();
|
||||||
out->write(&score, sizeof(score));
|
out->write(&score, sizeof(score));
|
||||||
|
|
||||||
// Save story mode
|
// Save story mode
|
||||||
|
@ -362,16 +334,16 @@ void FileManager::saveGame(int16 slot, const char *descrip) {
|
||||||
out->write(&gameStatus.gameOverFl, sizeof(gameStatus.gameOverFl));
|
out->write(&gameStatus.gameOverFl, sizeof(gameStatus.gameOverFl));
|
||||||
|
|
||||||
// Save screen states
|
// Save screen states
|
||||||
out->write(_vm._screenStates, sizeof(*_vm._screenStates) * _vm._numScreens);
|
out->write(_vm->_screenStates, sizeof(*_vm->_screenStates) * _vm->_numScreens);
|
||||||
|
|
||||||
// Save points table
|
// Save points table
|
||||||
out->write(_vm._points, sizeof(point_t) * _vm._numBonuses);
|
out->write(_vm->_points, sizeof(point_t) * _vm->_numBonuses);
|
||||||
|
|
||||||
// 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);
|
||||||
|
|
||||||
// Save palette table
|
// Save palette table
|
||||||
_vm.screen().savePal(out);
|
_vm->_screen->savePal(out);
|
||||||
|
|
||||||
// Save maze status
|
// Save maze status
|
||||||
out->write(&_maze, sizeof(maze_t));
|
out->write(&_maze, sizeof(maze_t));
|
||||||
|
@ -386,17 +358,17 @@ void FileManager::restoreGame(int16 slot) {
|
||||||
debugC(1, kDebugFile, "restoreGame(%d)", slot);
|
debugC(1, kDebugFile, "restoreGame(%d)", slot);
|
||||||
|
|
||||||
// Initialize new-game status
|
// Initialize new-game status
|
||||||
_vm.initStatus();
|
_vm->initStatus();
|
||||||
|
|
||||||
// Get full path of saved game file - note test for INITFILE
|
// Get full path of saved game file - note test for INITFILE
|
||||||
Common::String path; // Full path of saved game
|
Common::String path; // Full path of saved game
|
||||||
|
|
||||||
if (slot == -1)
|
if (slot == -1)
|
||||||
path = _vm._initFilename;
|
path = _vm->_initFilename;
|
||||||
else
|
else
|
||||||
path = Common::String::printf(_vm._saveFilename.c_str(), slot);
|
path = Common::String::printf(_vm->_saveFilename.c_str(), slot);
|
||||||
|
|
||||||
Common::SeekableReadStream *in = _vm.getSaveFileManager()->openForLoading(path);
|
Common::SeekableReadStream *in = _vm->getSaveFileManager()->openForLoading(path);
|
||||||
if (!in)
|
if (!in)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -412,13 +384,13 @@ void FileManager::restoreGame(int16 slot) {
|
||||||
in->seek(DESCRIPLEN, SEEK_CUR);
|
in->seek(DESCRIPLEN, SEEK_CUR);
|
||||||
|
|
||||||
// If hero image is currently swapped, swap it back before restore
|
// If hero image is currently swapped, swap it back before restore
|
||||||
if (_vm._heroImage != HERO)
|
if (_vm->_heroImage != HERO)
|
||||||
_vm.scheduler().swapImages(HERO, _vm._heroImage);
|
_vm->_object->swapImages(HERO, _vm->_heroImage);
|
||||||
|
|
||||||
// Restore objects, retain current seqList which points to dynamic mem
|
// Restore objects, retain current seqList which points to dynamic mem
|
||||||
// Also, retain cmnd_t pointers
|
// Also, retain cmnd_t pointers
|
||||||
for (int i = 0; i < _vm._numObj; i++) {
|
for (int i = 0; i < _vm->_numObj; i++) {
|
||||||
object_t *p = &_vm._objects[i];
|
object_t *p = &_vm->_object->_objects[i];
|
||||||
seqList_t seqList[MAX_SEQUENCES];
|
seqList_t seqList[MAX_SEQUENCES];
|
||||||
memcpy(seqList, p->seqList, sizeof(seqList_t));
|
memcpy(seqList, p->seqList, sizeof(seqList_t));
|
||||||
uint16 cmdIndex = p->cmdIndex;
|
uint16 cmdIndex = p->cmdIndex;
|
||||||
|
@ -427,37 +399,37 @@ void FileManager::restoreGame(int16 slot) {
|
||||||
memcpy(p->seqList, seqList, sizeof(seqList_t));
|
memcpy(p->seqList, seqList, sizeof(seqList_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
in->read(&_vm._heroImage, sizeof(_vm._heroImage));
|
in->read(&_vm->_heroImage, sizeof(_vm->_heroImage));
|
||||||
|
|
||||||
// If hero swapped in saved game, swap it
|
// If hero swapped in saved game, swap it
|
||||||
int heroImg = _vm._heroImage;
|
int heroImg = _vm->_heroImage;
|
||||||
if (heroImg != HERO)
|
if (heroImg != HERO)
|
||||||
_vm.scheduler().swapImages(HERO, _vm._heroImage);
|
_vm->_object->swapImages(HERO, _vm->_heroImage);
|
||||||
_vm._heroImage = heroImg;
|
_vm->_heroImage = heroImg;
|
||||||
|
|
||||||
status_t &gameStatus = _vm.getGameStatus();
|
status_t &gameStatus = _vm->getGameStatus();
|
||||||
|
|
||||||
int score;
|
int score;
|
||||||
in->read(&score, sizeof(score));
|
in->read(&score, sizeof(score));
|
||||||
_vm.setScore(score);
|
_vm->setScore(score);
|
||||||
|
|
||||||
in->read(&gameStatus.storyModeFl, sizeof(gameStatus.storyModeFl));
|
in->read(&gameStatus.storyModeFl, sizeof(gameStatus.storyModeFl));
|
||||||
in->read(&gameStatus.jumpExitFl, sizeof(gameStatus.jumpExitFl));
|
in->read(&gameStatus.jumpExitFl, sizeof(gameStatus.jumpExitFl));
|
||||||
in->read(&gameStatus.gameOverFl, sizeof(gameStatus.gameOverFl));
|
in->read(&gameStatus.gameOverFl, sizeof(gameStatus.gameOverFl));
|
||||||
in->read(_vm._screenStates, sizeof(*_vm._screenStates) * _vm._numScreens);
|
in->read(_vm->_screenStates, sizeof(*_vm->_screenStates) * _vm->_numScreens);
|
||||||
|
|
||||||
// Restore points table
|
// Restore points table
|
||||||
in->read(_vm._points, sizeof(point_t) * _vm._numBonuses);
|
in->read(_vm->_points, sizeof(point_t) * _vm->_numBonuses);
|
||||||
|
|
||||||
// Restore ptrs to currently loaded objects
|
// Restore ptrs to currently loaded objects
|
||||||
for (int i = 0; i < _vm._numObj; i++)
|
for (int i = 0; i < _vm->_numObj; i++)
|
||||||
restoreSeq(&_vm._objects[i]);
|
_vm->_object->restoreSeq(&_vm->_object->_objects[i]);
|
||||||
|
|
||||||
// Now restore time of the save and the event queue
|
// Now restore time of the save and the event queue
|
||||||
_vm.scheduler().restoreEvents(in);
|
_vm->_scheduler->restoreEvents(in);
|
||||||
|
|
||||||
// Restore palette and change it if necessary
|
// Restore palette and change it if necessary
|
||||||
_vm.screen().restorePal(in);
|
_vm->_screen->restorePal(in);
|
||||||
|
|
||||||
// Restore maze status
|
// Restore maze status
|
||||||
in->read(&_maze, sizeof(maze_t));
|
in->read(&_maze, sizeof(maze_t));
|
||||||
|
@ -475,27 +447,27 @@ void FileManager::initSavedGame() {
|
||||||
debugC(1, kDebugFile, "initSavedGame");
|
debugC(1, kDebugFile, "initSavedGame");
|
||||||
|
|
||||||
// Force save of initial game
|
// Force save of initial game
|
||||||
if (_vm.getGameStatus().initSaveFl)
|
if (_vm->getGameStatus().initSaveFl)
|
||||||
saveGame(-1, "");
|
saveGame(-1, "");
|
||||||
|
|
||||||
// If initial game doesn't exist, create it
|
// If initial game doesn't exist, create it
|
||||||
Common::SeekableReadStream *in = _vm.getSaveFileManager()->openForLoading(_vm._initFilename);
|
Common::SeekableReadStream *in = _vm->getSaveFileManager()->openForLoading(_vm->_initFilename);
|
||||||
if (!in) {
|
if (!in) {
|
||||||
saveGame(-1, "");
|
saveGame(-1, "");
|
||||||
in = _vm.getSaveFileManager()->openForLoading(_vm._initFilename);
|
in = _vm->getSaveFileManager()->openForLoading(_vm->_initFilename);
|
||||||
if (!in) {
|
if (!in) {
|
||||||
Utils::Error(WRITE_ERR, "%s", _vm._initFilename.c_str());
|
Utils::Error(WRITE_ERR, "%s", _vm->_initFilename.c_str());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Must have an open saved game now
|
// Must have an open saved game now
|
||||||
_vm.getGameStatus().saveSize = in->size();
|
_vm->getGameStatus().saveSize = in->size();
|
||||||
delete in;
|
delete in;
|
||||||
|
|
||||||
// Check sanity - maybe disk full or path set to read-only drive?
|
// Check sanity - maybe disk full or path set to read-only drive?
|
||||||
if (_vm.getGameStatus().saveSize == -1)
|
if (_vm->getGameStatus().saveSize == -1)
|
||||||
Utils::Error(WRITE_ERR, "%s", _vm._initFilename.c_str());
|
Utils::Error(WRITE_ERR, "%s", _vm->_initFilename.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileManager::openPlaybackFile(bool playbackFl, bool recordFl) {
|
void FileManager::openPlaybackFile(bool playbackFl, bool recordFl) {
|
||||||
|
@ -520,7 +492,7 @@ void FileManager::printBootText() {
|
||||||
|
|
||||||
Common::File ofp;
|
Common::File ofp;
|
||||||
if (!ofp.open(BOOTFILE)) {
|
if (!ofp.open(BOOTFILE)) {
|
||||||
if (_vm._gameVariant == 3) {
|
if (_vm->_gameVariant == 3) {
|
||||||
//TODO initialize properly _boot structure
|
//TODO initialize properly _boot structure
|
||||||
warning("printBootText - Skipping as H1 Dos may be a freeware");
|
warning("printBootText - Skipping as H1 Dos may be a freeware");
|
||||||
return;
|
return;
|
||||||
|
@ -559,7 +531,7 @@ void FileManager::readBootFile() {
|
||||||
|
|
||||||
Common::File ofp;
|
Common::File ofp;
|
||||||
if (!ofp.open(BOOTFILE)) {
|
if (!ofp.open(BOOTFILE)) {
|
||||||
if (_vm._gameVariant == 3) {
|
if (_vm->_gameVariant == 3) {
|
||||||
//TODO initialize properly _boot structure
|
//TODO initialize properly _boot structure
|
||||||
warning("readBootFile - Skipping as H1 Dos may be a freeware");
|
warning("readBootFile - Skipping as H1 Dos may be a freeware");
|
||||||
return;
|
return;
|
||||||
|
@ -673,5 +645,12 @@ void FileManager::instructions() {
|
||||||
f.close();
|
f.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Read the uif image file (inventory icons)
|
||||||
|
void FileManager::readUIFImages() {
|
||||||
|
debugC(1, kDebugFile, "readUIFImages");
|
||||||
|
|
||||||
|
readUIFItem(UIF_IMAGES, _vm->_screen->getGUIBuffer()); // Read all uif images
|
||||||
|
}
|
||||||
|
|
||||||
} // End of namespace Hugo
|
} // End of namespace Hugo
|
||||||
|
|
||||||
|
|
|
@ -57,7 +57,7 @@ namespace Hugo {
|
||||||
|
|
||||||
class FileManager {
|
class FileManager {
|
||||||
public:
|
public:
|
||||||
FileManager(HugoEngine &vm);
|
FileManager(HugoEngine *vm);
|
||||||
virtual ~FileManager();
|
virtual ~FileManager();
|
||||||
|
|
||||||
|
|
||||||
|
@ -69,11 +69,10 @@ public:
|
||||||
void instructions();
|
void instructions();
|
||||||
void readBootFile();
|
void readBootFile();
|
||||||
void readImage(int objNum, object_t *objPtr);
|
void readImage(int objNum, object_t *objPtr);
|
||||||
|
void readUIFImages();
|
||||||
void readUIFItem(short id, byte *buf);
|
void readUIFItem(short id, byte *buf);
|
||||||
void restoreGame(short slot);
|
void restoreGame(short slot);
|
||||||
void restoreSeq(object_t *obj);
|
|
||||||
void saveGame(short slot, const char *descrip);
|
void saveGame(short slot, const char *descrip);
|
||||||
void saveSeq(object_t *obj);
|
|
||||||
|
|
||||||
virtual void openDatabaseFiles() = 0;
|
virtual void openDatabaseFiles() = 0;
|
||||||
virtual void closeDatabaseFiles() = 0;
|
virtual void closeDatabaseFiles() = 0;
|
||||||
|
@ -84,7 +83,7 @@ public:
|
||||||
virtual char *fetchString(int index) = 0;
|
virtual char *fetchString(int index) = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
HugoEngine &_vm;
|
HugoEngine *_vm;
|
||||||
|
|
||||||
Common::File _stringArchive; // Handle for string file
|
Common::File _stringArchive; // Handle for string file
|
||||||
Common::File _sceneryArchive1; // Handle for scenery file
|
Common::File _sceneryArchive1; // Handle for scenery file
|
||||||
|
@ -108,7 +107,7 @@ private:
|
||||||
|
|
||||||
class FileManager_v1d : public FileManager {
|
class FileManager_v1d : public FileManager {
|
||||||
public:
|
public:
|
||||||
FileManager_v1d(HugoEngine &vm);
|
FileManager_v1d(HugoEngine *vm);
|
||||||
~FileManager_v1d();
|
~FileManager_v1d();
|
||||||
|
|
||||||
void openDatabaseFiles();
|
void openDatabaseFiles();
|
||||||
|
@ -120,7 +119,7 @@ public:
|
||||||
|
|
||||||
class FileManager_v2d : public FileManager {
|
class FileManager_v2d : public FileManager {
|
||||||
public:
|
public:
|
||||||
FileManager_v2d(HugoEngine &vm);
|
FileManager_v2d(HugoEngine *vm);
|
||||||
~FileManager_v2d();
|
~FileManager_v2d();
|
||||||
|
|
||||||
void openDatabaseFiles();
|
void openDatabaseFiles();
|
||||||
|
@ -132,7 +131,7 @@ public:
|
||||||
|
|
||||||
class FileManager_v3d : public FileManager_v2d {
|
class FileManager_v3d : public FileManager_v2d {
|
||||||
public:
|
public:
|
||||||
FileManager_v3d(HugoEngine &vm);
|
FileManager_v3d(HugoEngine *vm);
|
||||||
~FileManager_v3d();
|
~FileManager_v3d();
|
||||||
|
|
||||||
void openDatabaseFiles();
|
void openDatabaseFiles();
|
||||||
|
@ -145,7 +144,7 @@ private:
|
||||||
|
|
||||||
class FileManager_v1w : public FileManager_v2d {
|
class FileManager_v1w : public FileManager_v2d {
|
||||||
public:
|
public:
|
||||||
FileManager_v1w(HugoEngine &vm);
|
FileManager_v1w(HugoEngine *vm);
|
||||||
~FileManager_v1w();
|
~FileManager_v1w();
|
||||||
|
|
||||||
void readOverlay(int screenNum, image_pt image, ovl_t overlayType);
|
void readOverlay(int screenNum, image_pt image, ovl_t overlayType);
|
||||||
|
|
|
@ -38,7 +38,7 @@
|
||||||
#include "hugo/util.h"
|
#include "hugo/util.h"
|
||||||
|
|
||||||
namespace Hugo {
|
namespace Hugo {
|
||||||
FileManager_v1d::FileManager_v1d(HugoEngine &vm) : FileManager(vm) {
|
FileManager_v1d::FileManager_v1d(HugoEngine *vm) : FileManager(vm) {
|
||||||
}
|
}
|
||||||
|
|
||||||
FileManager_v1d::~FileManager_v1d() {
|
FileManager_v1d::~FileManager_v1d() {
|
||||||
|
@ -59,7 +59,7 @@ void FileManager_v1d::readOverlay(int screenNum, image_pt image, ovl_t overlayTy
|
||||||
const char *ovl_ext[] = {".b", ".o", ".ob"};
|
const char *ovl_ext[] = {".b", ".o", ".ob"};
|
||||||
char *buf = (char *) malloc(2048 + 1); // Buffer for file access
|
char *buf = (char *) malloc(2048 + 1); // Buffer for file access
|
||||||
|
|
||||||
strcat(strcpy(buf, _vm._screenNames[screenNum]), ovl_ext[overlayType]);
|
strcat(strcpy(buf, _vm->_screenNames[screenNum]), ovl_ext[overlayType]);
|
||||||
|
|
||||||
if (!fileExists(buf)) {
|
if (!fileExists(buf)) {
|
||||||
for (uint32 i = 0; i < OVL_SIZE; i++)
|
for (uint32 i = 0; i < OVL_SIZE; i++)
|
||||||
|
@ -81,12 +81,12 @@ void FileManager_v1d::readBackground(int screenIndex) {
|
||||||
debugC(1, kDebugFile, "readBackground(%d)", screenIndex);
|
debugC(1, kDebugFile, "readBackground(%d)", screenIndex);
|
||||||
|
|
||||||
char *buf = (char *) malloc(2048 + 1); // Buffer for file access
|
char *buf = (char *) malloc(2048 + 1); // Buffer for file access
|
||||||
strcat(strcpy(buf, _vm._screenNames[screenIndex]), ".ART");
|
strcat(strcpy(buf, _vm->_screenNames[screenIndex]), ".ART");
|
||||||
if (!_sceneryArchive1.open(buf))
|
if (!_sceneryArchive1.open(buf))
|
||||||
Utils::Error(FILE_ERR, "%s", buf);
|
Utils::Error(FILE_ERR, "%s", buf);
|
||||||
// Read the image into dummy seq and static dib_a
|
// Read the image into dummy seq and static dib_a
|
||||||
seq_t dummySeq; // Image sequence structure for Read_pcx
|
seq_t dummySeq; // Image sequence structure for Read_pcx
|
||||||
readPCX(_sceneryArchive1, &dummySeq, _vm.screen().getFrontBuffer(), true, _vm._screenNames[screenIndex]);
|
readPCX(_sceneryArchive1, &dummySeq, _vm->_screen->getFrontBuffer(), true, _vm->_screenNames[screenIndex]);
|
||||||
|
|
||||||
_sceneryArchive1.close();
|
_sceneryArchive1.close();
|
||||||
}
|
}
|
||||||
|
@ -94,7 +94,7 @@ void FileManager_v1d::readBackground(int screenIndex) {
|
||||||
char *FileManager_v1d::fetchString(int index) {
|
char *FileManager_v1d::fetchString(int index) {
|
||||||
debugC(1, kDebugFile, "fetchString(%d)", index);
|
debugC(1, kDebugFile, "fetchString(%d)", index);
|
||||||
|
|
||||||
return _vm._stringtData[index];
|
return _vm->_stringtData[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
} // End of namespace Hugo
|
} // End of namespace Hugo
|
||||||
|
|
|
@ -37,7 +37,7 @@
|
||||||
#include "hugo/util.h"
|
#include "hugo/util.h"
|
||||||
|
|
||||||
namespace Hugo {
|
namespace Hugo {
|
||||||
FileManager_v1w::FileManager_v1w(HugoEngine &vm) : FileManager_v2d(vm) {
|
FileManager_v1w::FileManager_v1w(HugoEngine *vm) : FileManager_v2d(vm) {
|
||||||
}
|
}
|
||||||
|
|
||||||
FileManager_v1w::~FileManager_v1w() {
|
FileManager_v1w::~FileManager_v1w() {
|
||||||
|
|
|
@ -40,7 +40,7 @@
|
||||||
#include "hugo/util.h"
|
#include "hugo/util.h"
|
||||||
|
|
||||||
namespace Hugo {
|
namespace Hugo {
|
||||||
FileManager_v2d::FileManager_v2d(HugoEngine &vm) : FileManager(vm) {
|
FileManager_v2d::FileManager_v2d(HugoEngine *vm) : FileManager(vm) {
|
||||||
}
|
}
|
||||||
|
|
||||||
FileManager_v2d::~FileManager_v2d() {
|
FileManager_v2d::~FileManager_v2d() {
|
||||||
|
@ -85,7 +85,7 @@ void FileManager_v2d::readBackground(int screenIndex) {
|
||||||
|
|
||||||
// Read the image into dummy seq and static dib_a
|
// Read the image into dummy seq and static dib_a
|
||||||
seq_t dummySeq; // Image sequence structure for Read_pcx
|
seq_t dummySeq; // Image sequence structure for Read_pcx
|
||||||
readPCX(_sceneryArchive1, &dummySeq, _vm.screen().getFrontBuffer(), true, _vm._screenNames[screenIndex]);
|
readPCX(_sceneryArchive1, &dummySeq, _vm->_screen->getFrontBuffer(), true, _vm->_screenNames[screenIndex]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileManager_v2d::readOverlay(int screenNum, image_pt image, ovl_t overlayType) {
|
void FileManager_v2d::readOverlay(int screenNum, image_pt image, ovl_t overlayType) {
|
||||||
|
@ -170,7 +170,7 @@ char *FileManager_v2d::fetchString(int index) {
|
||||||
|
|
||||||
// Null terminate, decode and return it
|
// Null terminate, decode and return it
|
||||||
_textBoxBuffer[off2-off1] = '\0';
|
_textBoxBuffer[off2-off1] = '\0';
|
||||||
_vm.scheduler().decodeString(_textBoxBuffer);
|
_vm->_scheduler->decodeString(_textBoxBuffer);
|
||||||
return _textBoxBuffer;
|
return _textBoxBuffer;
|
||||||
}
|
}
|
||||||
} // End of namespace Hugo
|
} // End of namespace Hugo
|
||||||
|
|
|
@ -39,7 +39,7 @@
|
||||||
#include "hugo/util.h"
|
#include "hugo/util.h"
|
||||||
|
|
||||||
namespace Hugo {
|
namespace Hugo {
|
||||||
FileManager_v3d::FileManager_v3d(HugoEngine &vm) : FileManager_v2d(vm) {
|
FileManager_v3d::FileManager_v3d(HugoEngine *vm) : FileManager_v2d(vm) {
|
||||||
}
|
}
|
||||||
|
|
||||||
FileManager_v3d::~FileManager_v3d() {
|
FileManager_v3d::~FileManager_v3d() {
|
||||||
|
@ -65,11 +65,11 @@ void FileManager_v3d::readBackground(int screenIndex) {
|
||||||
if (screenIndex < 20) {
|
if (screenIndex < 20) {
|
||||||
_sceneryArchive1.seek(sceneBlock.scene_off, SEEK_SET);
|
_sceneryArchive1.seek(sceneBlock.scene_off, SEEK_SET);
|
||||||
// Read the image into dummy seq and static dib_a
|
// Read the image into dummy seq and static dib_a
|
||||||
readPCX(_sceneryArchive1, &dummySeq, _vm.screen().getFrontBuffer(), true, _vm._screenNames[screenIndex]);
|
readPCX(_sceneryArchive1, &dummySeq, _vm->_screen->getFrontBuffer(), true, _vm->_screenNames[screenIndex]);
|
||||||
} else {
|
} else {
|
||||||
_sceneryArchive2.seek(sceneBlock.scene_off, SEEK_SET);
|
_sceneryArchive2.seek(sceneBlock.scene_off, SEEK_SET);
|
||||||
// Read the image into dummy seq and static dib_a
|
// Read the image into dummy seq and static dib_a
|
||||||
readPCX(_sceneryArchive2, &dummySeq, _vm.screen().getFrontBuffer(), true, _vm._screenNames[screenIndex]);
|
readPCX(_sceneryArchive2, &dummySeq, _vm->_screen->getFrontBuffer(), true, _vm->_screenNames[screenIndex]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -42,6 +42,7 @@
|
||||||
#include "hugo/util.h"
|
#include "hugo/util.h"
|
||||||
#include "hugo/sound.h"
|
#include "hugo/sound.h"
|
||||||
#include "hugo/intro.h"
|
#include "hugo/intro.h"
|
||||||
|
#include "hugo/object.h"
|
||||||
|
|
||||||
#include "engines/util.h"
|
#include "engines/util.h"
|
||||||
|
|
||||||
|
@ -63,8 +64,8 @@ command_t _line; // Line of user text input
|
||||||
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), _mouseX(0), _mouseY(0),
|
||||||
_textData(0), _stringtData(0), _screenNames(0), _textEngine(0), _textIntro(0), _textMouse(0), _textParser(0), _textSchedule(0), _textUtil(0),
|
_textData(0), _stringtData(0), _screenNames(0), _textEngine(0), _textIntro(0), _textMouse(0), _textParser(0), _textSchedule(0), _textUtil(0),
|
||||||
_arrayNouns(0), _arrayVerbs(0), _arrayReqs(0), _hotspots(0), _invent(0), _uses(0), _catchallList(0), _backgroundObjects(0),
|
_arrayNouns(0), _arrayVerbs(0), _arrayReqs(0), _hotspots(0), _invent(0), _uses(0), _catchallList(0), _backgroundObjects(0),
|
||||||
_points(0), _cmdList(0), _screenActs(0), _objects(0), _actListArr(0), _heroImage(0), _defltTunes(0), _palette(0), _introX(0),
|
_points(0), _cmdList(0), _screenActs(0), _actListArr(0), _heroImage(0), _defltTunes(0), _palette(0), _introX(0), _introY(0),
|
||||||
_introY(0), _maxInvent(0), _numBonuses(0), _numScreens(0), _tunesNbr(0), _soundSilence(0), _soundTest(0), _screenStates(0), _numObj(0),
|
_maxInvent(0), _numBonuses(0), _numScreens(0), _tunesNbr(0), _soundSilence(0), _soundTest(0), _screenStates(0), _numObj(0),
|
||||||
_score(0), _maxscore(0)
|
_score(0), _maxscore(0)
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -82,14 +83,15 @@ HugoEngine::HugoEngine(OSystem *syst, const HugoGameDescription *gd) : Engine(sy
|
||||||
}
|
}
|
||||||
|
|
||||||
HugoEngine::~HugoEngine() {
|
HugoEngine::~HugoEngine() {
|
||||||
delete _soundHandler;
|
delete _object;
|
||||||
|
delete _sound;
|
||||||
delete _route;
|
delete _route;
|
||||||
delete _parser;
|
delete _parser;
|
||||||
delete _inventoryHandler;
|
delete _inventory;
|
||||||
delete _mouseHandler;
|
delete _mouse;
|
||||||
delete _screen;
|
delete _screen;
|
||||||
delete _scheduler;
|
delete _scheduler;
|
||||||
delete _fileManager;
|
delete _file;
|
||||||
|
|
||||||
free(_palette);
|
free(_palette);
|
||||||
free(_introX);
|
free(_introX);
|
||||||
|
@ -161,53 +163,54 @@ Common::Error HugoEngine::run() {
|
||||||
s_Engine = this;
|
s_Engine = this;
|
||||||
initGraphics(320, 200, false);
|
initGraphics(320, 200, false);
|
||||||
|
|
||||||
_mouseHandler = new MouseHandler(*this);
|
_mouse = new MouseHandler(this);
|
||||||
_inventoryHandler = new InventoryHandler(*this);
|
_inventory = new InventoryHandler(this);
|
||||||
_route = new Route(*this);
|
_route = new Route(this);
|
||||||
_soundHandler = new SoundHandler(*this);
|
_sound = new SoundHandler(this);
|
||||||
|
_object = new ObjectHandler(this);
|
||||||
|
|
||||||
switch (_gameVariant) {
|
switch (_gameVariant) {
|
||||||
case 0: // H1 Win
|
case 0: // H1 Win
|
||||||
_fileManager = new FileManager_v1w(*this);
|
_file = new FileManager_v1w(this);
|
||||||
_scheduler = new Scheduler_v3d(*this);
|
_scheduler = new Scheduler_v3d(this);
|
||||||
_introHandler = new intro_v1w(*this);
|
_intro = new intro_v1w(this);
|
||||||
_screen = new Screen_v1w(*this);
|
_screen = new Screen_v1w(this);
|
||||||
_parser = new Parser_v1w(*this);
|
_parser = new Parser_v1w(this);
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
_fileManager = new FileManager_v2d(*this);
|
_file = new FileManager_v2d(this);
|
||||||
_scheduler = new Scheduler_v3d(*this);
|
_scheduler = new Scheduler_v3d(this);
|
||||||
_introHandler = new intro_v2w(*this);
|
_intro = new intro_v2w(this);
|
||||||
_screen = new Screen_v1w(*this);
|
_screen = new Screen_v1w(this);
|
||||||
_parser = new Parser_v1w(*this);
|
_parser = new Parser_v1w(this);
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
_fileManager = new FileManager_v2d(*this);
|
_file = new FileManager_v2d(this);
|
||||||
_scheduler = new Scheduler_v3d(*this);
|
_scheduler = new Scheduler_v3d(this);
|
||||||
_introHandler = new intro_v3w(*this);
|
_intro = new intro_v3w(this);
|
||||||
_screen = new Screen_v1w(*this);
|
_screen = new Screen_v1w(this);
|
||||||
_parser = new Parser_v1w(*this);
|
_parser = new Parser_v1w(this);
|
||||||
break;
|
break;
|
||||||
case 3: // H1 DOS
|
case 3: // H1 DOS
|
||||||
_fileManager = new FileManager_v1d(*this);
|
_file = new FileManager_v1d(this);
|
||||||
_scheduler = new Scheduler_v1d(*this);
|
_scheduler = new Scheduler_v1d(this);
|
||||||
_introHandler = new intro_v1d(*this);
|
_intro = new intro_v1d(this);
|
||||||
_screen = new Screen_v1d(*this);
|
_screen = new Screen_v1d(this);
|
||||||
_parser = new Parser_v1d(*this);
|
_parser = new Parser_v1d(this);
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
_fileManager = new FileManager_v2d(*this);
|
_file = new FileManager_v2d(this);
|
||||||
_scheduler = new Scheduler_v1d(*this);
|
_scheduler = new Scheduler_v1d(this);
|
||||||
_introHandler = new intro_v2d(*this);
|
_intro = new intro_v2d(this);
|
||||||
_screen = new Screen_v1d(*this);
|
_screen = new Screen_v1d(this);
|
||||||
_parser = new Parser_v2d(*this);
|
_parser = new Parser_v2d(this);
|
||||||
break;
|
break;
|
||||||
case 5:
|
case 5:
|
||||||
_fileManager = new FileManager_v3d(*this);
|
_file = new FileManager_v3d(this);
|
||||||
_scheduler = new Scheduler_v3d(*this);
|
_scheduler = new Scheduler_v3d(this);
|
||||||
_introHandler = new intro_v3d(*this);
|
_intro = new intro_v3d(this);
|
||||||
_screen = new Screen_v1d(*this);
|
_screen = new Screen_v1d(this);
|
||||||
_parser = new Parser_v3d(*this);
|
_parser = new Parser_v3d(this);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -225,7 +228,7 @@ Common::Error HugoEngine::run() {
|
||||||
initialize();
|
initialize();
|
||||||
initConfig(RESET); // Reset user's config
|
initConfig(RESET); // Reset user's config
|
||||||
|
|
||||||
file().restoreGame(-1);
|
_file->restoreGame(-1);
|
||||||
|
|
||||||
initMachine();
|
initMachine();
|
||||||
|
|
||||||
|
@ -243,7 +246,7 @@ Common::Error HugoEngine::run() {
|
||||||
while (_eventMan->pollEvent(event)) {
|
while (_eventMan->pollEvent(event)) {
|
||||||
switch (event.type) {
|
switch (event.type) {
|
||||||
case Common::EVENT_KEYDOWN:
|
case Common::EVENT_KEYDOWN:
|
||||||
parser().keyHandler(event.kbd.keycode, 0);
|
_parser->keyHandler(event.kbd.keycode, 0);
|
||||||
break;
|
break;
|
||||||
case Common::EVENT_MOUSEMOVE:
|
case Common::EVENT_MOUSEMOVE:
|
||||||
_mouseX = event.mouse.x;
|
_mouseX = event.mouse.x;
|
||||||
|
@ -276,10 +279,10 @@ void HugoEngine::initMachine() {
|
||||||
if (_gameVariant == kGameVariantH1Dos)
|
if (_gameVariant == kGameVariantH1Dos)
|
||||||
readScreenFiles(0);
|
readScreenFiles(0);
|
||||||
else
|
else
|
||||||
file().readBackground(_numScreens - 1); // Splash screen
|
_file->readBackground(_numScreens - 1); // Splash screen
|
||||||
readObjectImages(); // Read all object images
|
readObjectImages(); // Read all object images
|
||||||
if (_platform == Common::kPlatformWindows)
|
if (_platform == Common::kPlatformWindows)
|
||||||
readUIFImages(); // Read all uif images (only in Win versions)
|
_file->readUIFImages(); // Read all uif images (only in Win versions)
|
||||||
}
|
}
|
||||||
|
|
||||||
void HugoEngine::runMachine() {
|
void HugoEngine::runMachine() {
|
||||||
|
@ -302,32 +305,32 @@ void HugoEngine::runMachine() {
|
||||||
|
|
||||||
switch (gameStatus.viewState) {
|
switch (gameStatus.viewState) {
|
||||||
case V_IDLE: // Not processing state machine
|
case V_IDLE: // Not processing state machine
|
||||||
intro().preNewGame(); // Any processing before New Game selected
|
_intro->preNewGame(); // Any processing before New Game selected
|
||||||
break;
|
break;
|
||||||
case V_INTROINIT: // Initialization before intro begins
|
case V_INTROINIT: // Initialization before intro begins
|
||||||
intro().introInit();
|
_intro->introInit();
|
||||||
g_system->showMouse(false);
|
g_system->showMouse(false);
|
||||||
gameStatus.viewState = V_INTRO;
|
gameStatus.viewState = V_INTRO;
|
||||||
break;
|
break;
|
||||||
case V_INTRO: // Do any game-dependant preamble
|
case V_INTRO: // Do any game-dependant preamble
|
||||||
if (intro().introPlay()) { // Process intro screen
|
if (_intro->introPlay()) { // Process intro screen
|
||||||
scheduler().newScreen(0); // Initialize first screen
|
_scheduler->newScreen(0); // Initialize first screen
|
||||||
gameStatus.viewState = V_PLAY;
|
gameStatus.viewState = V_PLAY;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case V_PLAY: // Playing game
|
case V_PLAY: // Playing game
|
||||||
g_system->showMouse(true);
|
g_system->showMouse(true);
|
||||||
parser().charHandler(); // Process user cmd input
|
_parser->charHandler(); // Process user cmd input
|
||||||
moveObjects(); // Process object movement
|
_object->moveObjects(); // Process object movement
|
||||||
scheduler().runScheduler(); // Process any actions
|
_scheduler->runScheduler(); // Process any actions
|
||||||
screen().displayList(D_RESTORE); // Restore previous background
|
_screen->displayList(D_RESTORE); // Restore previous background
|
||||||
updateImages(); // Draw into _frontBuffer, compile display list
|
_object->updateImages(); // Draw into _frontBuffer, compile display list
|
||||||
mouse().mouseHandler(); // Mouse activity - adds to display list
|
_mouse->mouseHandler(); // Mouse activity - adds to display list
|
||||||
screen().drawStatusText();
|
_screen->drawStatusText();
|
||||||
screen().displayList(D_DISPLAY); // Blit the display list to screen
|
_screen->displayList(D_DISPLAY); // Blit the display list to screen
|
||||||
break;
|
break;
|
||||||
case V_INVENT: // Accessing inventory
|
case V_INVENT: // Accessing inventory
|
||||||
inventory().runInventory(); // Process Inventory state machine
|
_inventory->runInventory(); // Process Inventory state machine
|
||||||
break;
|
break;
|
||||||
case V_EXIT: // Game over or user exited
|
case V_EXIT: // Game over or user exited
|
||||||
gameStatus.viewState = V_IDLE;
|
gameStatus.viewState = V_IDLE;
|
||||||
|
@ -642,108 +645,10 @@ bool HugoEngine::loadHugoDat() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: For Hugo3, if not in story mode, set _objects[2].state to 3
|
_object->loadObject(in);
|
||||||
for (int varnt = 0; varnt < _numVariant; varnt++) {
|
|
||||||
numElem = in.readUint16BE();
|
|
||||||
if (varnt == _gameVariant) {
|
|
||||||
_objects = (object_t *)malloc(sizeof(object_t) * numElem);
|
|
||||||
for (int i = 0; i < numElem; i++) {
|
|
||||||
_objects[i].nounIndex = in.readUint16BE();
|
|
||||||
_objects[i].dataIndex = in.readUint16BE();
|
|
||||||
numSubElem = in.readUint16BE();
|
|
||||||
if (numSubElem == 0)
|
|
||||||
_objects[i].stateDataIndex = 0;
|
|
||||||
else
|
|
||||||
_objects[i].stateDataIndex = (uint16 *)malloc(sizeof(uint16) * numSubElem);
|
|
||||||
for (int j = 0; j < numSubElem; j++)
|
|
||||||
_objects[i].stateDataIndex[j] = in.readUint16BE();
|
|
||||||
_objects[i].pathType = (path_t) in.readSint16BE();
|
|
||||||
_objects[i].vxPath = in.readSint16BE();
|
|
||||||
_objects[i].vyPath = in.readSint16BE();
|
|
||||||
_objects[i].actIndex = in.readUint16BE();
|
|
||||||
_objects[i].seqNumb = in.readByte();
|
|
||||||
_objects[i].currImagePtr = 0;
|
|
||||||
if (_objects[i].seqNumb == 0) {
|
|
||||||
_objects[i].seqList[0].imageNbr = 0;
|
|
||||||
_objects[i].seqList[0].seqPtr = 0;
|
|
||||||
}
|
|
||||||
for (int j = 0; j < _objects[i].seqNumb; j++) {
|
|
||||||
_objects[i].seqList[j].imageNbr = in.readUint16BE();
|
|
||||||
_objects[i].seqList[j].seqPtr = 0;
|
|
||||||
}
|
|
||||||
_objects[i].cycling = (cycle_t)in.readByte();
|
|
||||||
_objects[i].cycleNumb = in.readByte();
|
|
||||||
_objects[i].frameInterval = in.readByte();
|
|
||||||
_objects[i].frameTimer = in.readByte();
|
|
||||||
_objects[i].radius = in.readByte();
|
|
||||||
_objects[i].screenIndex = in.readByte();
|
|
||||||
_objects[i].x = in.readSint16BE();
|
|
||||||
_objects[i].y = in.readSint16BE();
|
|
||||||
_objects[i].oldx = in.readSint16BE();
|
|
||||||
_objects[i].oldy = in.readSint16BE();
|
|
||||||
_objects[i].vx = in.readByte();
|
|
||||||
_objects[i].vy = in.readByte();
|
|
||||||
_objects[i].objValue = in.readByte();
|
|
||||||
_objects[i].genericCmd = in.readSint16BE();
|
|
||||||
_objects[i].cmdIndex = in.readUint16BE();
|
|
||||||
_objects[i].carriedFl = (in.readByte() != 0);
|
|
||||||
_objects[i].state = in.readByte();
|
|
||||||
_objects[i].verbOnlyFl = (in.readByte() != 0);
|
|
||||||
_objects[i].priority = in.readByte();
|
|
||||||
_objects[i].viewx = in.readSint16BE();
|
|
||||||
_objects[i].viewy = in.readSint16BE();
|
|
||||||
_objects[i].direction = in.readSint16BE();
|
|
||||||
_objects[i].curSeqNum = in.readByte();
|
|
||||||
_objects[i].curImageNum = in.readByte();
|
|
||||||
_objects[i].oldvx = in.readByte();
|
|
||||||
_objects[i].oldvy = in.readByte();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for (int i = 0; i < numElem; i++) {
|
|
||||||
in.readUint16BE();
|
|
||||||
in.readUint16BE();
|
|
||||||
numSubElem = in.readUint16BE();
|
|
||||||
for (int j = 0; j < numSubElem; j++)
|
|
||||||
in.readUint16BE();
|
|
||||||
in.readSint16BE();
|
|
||||||
in.readSint16BE();
|
|
||||||
in.readSint16BE();
|
|
||||||
in.readUint16BE();
|
|
||||||
numSubElem = in.readByte();
|
|
||||||
for (int j = 0; j < numSubElem; j++)
|
|
||||||
in.readUint16BE();
|
|
||||||
in.readByte();
|
|
||||||
in.readByte();
|
|
||||||
in.readByte();
|
|
||||||
in.readByte();
|
|
||||||
in.readByte();
|
|
||||||
in.readByte();
|
|
||||||
in.readSint16BE();
|
|
||||||
in.readSint16BE();
|
|
||||||
in.readSint16BE();
|
|
||||||
in.readSint16BE();
|
|
||||||
in.readByte();
|
|
||||||
in.readByte();
|
|
||||||
in.readByte();
|
|
||||||
in.readSint16BE();
|
|
||||||
in.readUint16BE();
|
|
||||||
in.readByte();
|
|
||||||
in.readByte();
|
|
||||||
in.readByte();
|
|
||||||
in.readByte();
|
|
||||||
in.readSint16BE();
|
|
||||||
in.readSint16BE();
|
|
||||||
in.readUint16BE();
|
|
||||||
in.readByte();
|
|
||||||
in.readByte();
|
|
||||||
in.readByte();
|
|
||||||
in.readByte();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//#define HERO 0
|
//#define HERO 0
|
||||||
_hero = &_objects[HERO]; // This always points to hero
|
_hero = &_object->_objects[HERO]; // This always points to hero
|
||||||
_screen_p = &(_objects[HERO].screenIndex); // Current screen is hero's
|
_screen_p = &(_object->_objects[HERO].screenIndex); // Current screen is hero's
|
||||||
_heroImage = HERO; // Current in use hero image
|
_heroImage = HERO; // Current in use hero image
|
||||||
|
|
||||||
//read _actListArr
|
//read _actListArr
|
||||||
|
@ -1599,18 +1504,18 @@ void HugoEngine::initConfig(inst_t action) {
|
||||||
_config.soundVolume = 100; // Sound volume %
|
_config.soundVolume = 100; // Sound volume %
|
||||||
initPlaylist(_config.playlist); // Initialize default tune playlist
|
initPlaylist(_config.playlist); // Initialize default tune playlist
|
||||||
|
|
||||||
file().readBootFile(); // Read startup structure
|
_file->readBootFile(); // Read startup structure
|
||||||
break;
|
break;
|
||||||
case RESET:
|
case RESET:
|
||||||
// Find first tune and play it
|
// Find first tune and play it
|
||||||
for (int16 i = 0; i < MAX_TUNES; i++) {
|
for (int16 i = 0; i < MAX_TUNES; i++) {
|
||||||
if (_config.playlist[i]) {
|
if (_config.playlist[i]) {
|
||||||
sound().playMusic(i);
|
_sound->playMusic(i);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
file().initSavedGame(); // Initialize saved game
|
_file->initSavedGame(); // Initialize saved game
|
||||||
break;
|
break;
|
||||||
case RESTORE:
|
case RESTORE:
|
||||||
warning("Unhandled action RESTORE");
|
warning("Unhandled action RESTORE");
|
||||||
|
@ -1624,10 +1529,10 @@ void HugoEngine::initialize() {
|
||||||
_maze.enabledFl = false;
|
_maze.enabledFl = false;
|
||||||
_line[0] = '\0';
|
_line[0] = '\0';
|
||||||
|
|
||||||
sound().initSound();
|
_sound->initSound();
|
||||||
scheduler().initEventQueue(); // Init scheduler stuff
|
_scheduler->initEventQueue(); // Init scheduler stuff
|
||||||
screen().initDisplay(); // Create Dibs and palette
|
_screen->initDisplay(); // Create Dibs and palette
|
||||||
file().openDatabaseFiles(); // Open database files
|
_file->openDatabaseFiles(); // Open database files
|
||||||
calcMaxScore(); // Initialise maxscore
|
calcMaxScore(); // Initialise maxscore
|
||||||
|
|
||||||
_rnd = new Common::RandomSource();
|
_rnd = new Common::RandomSource();
|
||||||
|
@ -1657,214 +1562,28 @@ void HugoEngine::initialize() {
|
||||||
void HugoEngine::shutdown() {
|
void HugoEngine::shutdown() {
|
||||||
debugC(1, kDebugEngine, "shutdown");
|
debugC(1, kDebugEngine, "shutdown");
|
||||||
|
|
||||||
file().closeDatabaseFiles();
|
_file->closeDatabaseFiles();
|
||||||
if (_status.recordFl || _status.playbackFl)
|
if (_status.recordFl || _status.playbackFl)
|
||||||
file().closePlaybackFile();
|
_file->closePlaybackFile();
|
||||||
freeObjects();
|
_object->freeObjects();
|
||||||
}
|
}
|
||||||
|
|
||||||
void HugoEngine::readObjectImages() {
|
void HugoEngine::readObjectImages() {
|
||||||
debugC(1, kDebugEngine, "readObjectImages");
|
debugC(1, kDebugEngine, "readObjectImages");
|
||||||
|
|
||||||
for (int i = 0; i < _numObj; i++)
|
for (int i = 0; i < _numObj; i++)
|
||||||
file().readImage(i, &_objects[i]);
|
_file->readImage(i, &_object->_objects[i]);
|
||||||
}
|
|
||||||
|
|
||||||
// Read the uif image file (inventory icons)
|
|
||||||
void HugoEngine::readUIFImages() {
|
|
||||||
debugC(1, kDebugEngine, "readUIFImages");
|
|
||||||
|
|
||||||
file().readUIFItem(UIF_IMAGES, screen().getGUIBuffer()); // Read all uif images
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read scenery, overlay files for given screen number
|
// Read scenery, overlay files for given screen number
|
||||||
void HugoEngine::readScreenFiles(int screenNum) {
|
void HugoEngine::readScreenFiles(int screenNum) {
|
||||||
debugC(1, kDebugEngine, "readScreenFiles(%d)", screenNum);
|
debugC(1, kDebugEngine, "readScreenFiles(%d)", screenNum);
|
||||||
|
|
||||||
file().readBackground(screenNum); // Scenery file
|
_file->readBackground(screenNum); // Scenery file
|
||||||
memcpy(screen().getBackBuffer(), screen().getFrontBuffer(), sizeof(screen().getFrontBuffer()));// Make a copy
|
memcpy(_screen->getBackBuffer(), _screen->getFrontBuffer(), sizeof(_screen->getFrontBuffer()));// Make a copy
|
||||||
file().readOverlay(screenNum, _boundary, BOUNDARY); // Boundary file
|
_file->readOverlay(screenNum, _boundary, BOUNDARY); // Boundary file
|
||||||
file().readOverlay(screenNum, _overlay, OVERLAY); // Overlay file
|
_file->readOverlay(screenNum, _overlay, OVERLAY); // Overlay file
|
||||||
file().readOverlay(screenNum, _ovlBase, OVLBASE); // Overlay base file
|
_file->readOverlay(screenNum, _ovlBase, OVLBASE); // Overlay base file
|
||||||
}
|
|
||||||
|
|
||||||
// Update all object positions. Process object 'local' events
|
|
||||||
// including boundary events and collisions
|
|
||||||
void HugoEngine::moveObjects() {
|
|
||||||
debugC(4, kDebugEngine, "moveObjects");
|
|
||||||
|
|
||||||
// If route mode enabled, do special route processing
|
|
||||||
if (_status.routeIndex >= 0)
|
|
||||||
route().processRoute();
|
|
||||||
|
|
||||||
// Perform any adjustments to velocity based on special path types
|
|
||||||
// and store all (visible) object baselines into the boundary file.
|
|
||||||
// Don't store foreground or background objects
|
|
||||||
for (int i = 0; i < _numObj; i++) {
|
|
||||||
object_t *obj = &_objects[i]; // Get pointer to object
|
|
||||||
seq_t *currImage = obj->currImagePtr; // Get ptr to current image
|
|
||||||
if (obj->screenIndex == *_screen_p) {
|
|
||||||
switch (obj->pathType) {
|
|
||||||
case CHASE:
|
|
||||||
case CHASE2: {
|
|
||||||
int8 radius = obj->radius; // Default to object's radius
|
|
||||||
if (radius < 0) // If radius infinity, use closer value
|
|
||||||
radius = DX;
|
|
||||||
|
|
||||||
// Allowable motion wrt boundary
|
|
||||||
int dx = _hero->x + _hero->currImagePtr->x1 - obj->x - currImage->x1;
|
|
||||||
int dy = _hero->y + _hero->currImagePtr->y2 - obj->y - currImage->y2 - 1;
|
|
||||||
if (abs(dx) <= radius)
|
|
||||||
obj->vx = 0;
|
|
||||||
else
|
|
||||||
obj->vx = (dx > 0) ? MIN(dx, obj->vxPath) : MAX(dx, -obj->vxPath);
|
|
||||||
if (abs(dy) <= radius)
|
|
||||||
obj->vy = 0;
|
|
||||||
else
|
|
||||||
obj->vy = (dy > 0) ? MIN(dy, obj->vyPath) : MAX(dy, -obj->vyPath);
|
|
||||||
|
|
||||||
// Set first image in sequence (if multi-seq object)
|
|
||||||
switch (obj->seqNumb) {
|
|
||||||
case 4:
|
|
||||||
if (!obj->vx) { // Got 4 directions
|
|
||||||
if (obj->vx != obj->oldvx) { // vx just stopped
|
|
||||||
if (dy >= 0)
|
|
||||||
obj->currImagePtr = obj->seqList[DOWN].seqPtr;
|
|
||||||
else
|
|
||||||
obj->currImagePtr = obj->seqList[_UP].seqPtr;
|
|
||||||
}
|
|
||||||
} else if (obj->vx != obj->oldvx) {
|
|
||||||
if (dx > 0)
|
|
||||||
obj->currImagePtr = obj->seqList[RIGHT].seqPtr;
|
|
||||||
else
|
|
||||||
obj->currImagePtr = obj->seqList[LEFT].seqPtr;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
case 2:
|
|
||||||
if (obj->vx != obj->oldvx) { // vx just stopped
|
|
||||||
if (dx > 0) // Left & right only
|
|
||||||
obj->currImagePtr = obj->seqList[RIGHT].seqPtr;
|
|
||||||
else
|
|
||||||
obj->currImagePtr = obj->seqList[LEFT].seqPtr;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (obj->vx || obj->vy)
|
|
||||||
obj->cycling = CYCLE_FORWARD;
|
|
||||||
else {
|
|
||||||
obj->cycling = NOT_CYCLING;
|
|
||||||
boundaryCollision(obj); // Must have got hero!
|
|
||||||
}
|
|
||||||
obj->oldvx = obj->vx;
|
|
||||||
obj->oldvy = obj->vy;
|
|
||||||
currImage = obj->currImagePtr; // Get (new) ptr to current image
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case WANDER2:
|
|
||||||
case WANDER:
|
|
||||||
if (!_rnd->getRandomNumber(3 * NORMAL_TPS)) { // Kick on random interval
|
|
||||||
obj->vx = _rnd->getRandomNumber(obj->vxPath << 1) - obj->vxPath;
|
|
||||||
obj->vy = _rnd->getRandomNumber(obj->vyPath << 1) - obj->vyPath;
|
|
||||||
|
|
||||||
// Set first image in sequence (if multi-seq object)
|
|
||||||
if (obj->seqNumb > 1) {
|
|
||||||
if (!obj->vx && (obj->seqNumb >= 4)) {
|
|
||||||
if (obj->vx != obj->oldvx) { // vx just stopped
|
|
||||||
if (obj->vy > 0)
|
|
||||||
obj->currImagePtr = obj->seqList[DOWN].seqPtr;
|
|
||||||
else
|
|
||||||
obj->currImagePtr = obj->seqList[_UP].seqPtr;
|
|
||||||
}
|
|
||||||
} else if (obj->vx != obj->oldvx) {
|
|
||||||
if (obj->vx > 0)
|
|
||||||
obj->currImagePtr = obj->seqList[RIGHT].seqPtr;
|
|
||||||
else
|
|
||||||
obj->currImagePtr = obj->seqList[LEFT].seqPtr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
obj->oldvx = obj->vx;
|
|
||||||
obj->oldvy = obj->vy;
|
|
||||||
currImage = obj->currImagePtr; // Get (new) ptr to current image
|
|
||||||
}
|
|
||||||
if (obj->vx || obj->vy)
|
|
||||||
obj->cycling = CYCLE_FORWARD;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
; // Really, nothing
|
|
||||||
}
|
|
||||||
// Store boundaries
|
|
||||||
if ((obj->cycling > ALMOST_INVISIBLE) && (obj->priority == FLOATING))
|
|
||||||
storeBoundary(obj->x + currImage->x1, obj->x + currImage->x2, obj->y + currImage->y2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Move objects, allowing for boundaries
|
|
||||||
for (int i = 0; i < _numObj; i++) {
|
|
||||||
object_t *obj = &_objects[i]; // Get pointer to object
|
|
||||||
if ((obj->screenIndex == *_screen_p) && (obj->vx || obj->vy)) {
|
|
||||||
// Only process if it's moving
|
|
||||||
|
|
||||||
// Do object movement. Delta_x,y return allowed movement in x,y
|
|
||||||
// to move as close to a boundary as possible without crossing it.
|
|
||||||
seq_t *currImage = obj->currImagePtr; // Get ptr to current image
|
|
||||||
// object coordinates
|
|
||||||
int x1 = obj->x + currImage->x1; // Left edge of object
|
|
||||||
int x2 = obj->x + currImage->x2; // Right edge
|
|
||||||
int y1 = obj->y + currImage->y1; // Top edge
|
|
||||||
int y2 = obj->y + currImage->y2; // Bottom edge
|
|
||||||
|
|
||||||
if ((obj->cycling > ALMOST_INVISIBLE) && (obj->priority == FLOATING))
|
|
||||||
clearBoundary(x1, x2, y2); // Clear our own boundary
|
|
||||||
|
|
||||||
// Allowable motion wrt boundary
|
|
||||||
int dx = deltaX(x1, x2, obj->vx, y2);
|
|
||||||
if (dx != obj->vx) {
|
|
||||||
// An object boundary collision!
|
|
||||||
boundaryCollision(obj);
|
|
||||||
obj->vx = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int dy = deltaY(x1, x2, obj->vy, y2);
|
|
||||||
if (dy != obj->vy) {
|
|
||||||
// An object boundary collision!
|
|
||||||
boundaryCollision(obj);
|
|
||||||
obj->vy = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((obj->cycling > ALMOST_INVISIBLE) && (obj->priority == FLOATING))
|
|
||||||
storeBoundary(x1, x2, y2); // Re-store our own boundary
|
|
||||||
|
|
||||||
obj->x += dx; // Update object position
|
|
||||||
obj->y += dy;
|
|
||||||
|
|
||||||
// Don't let object go outside screen
|
|
||||||
if (x1 < EDGE)
|
|
||||||
obj->x = EDGE2;
|
|
||||||
if (x2 > (XPIX - EDGE))
|
|
||||||
obj->x = XPIX - EDGE2 - (x2 - x1);
|
|
||||||
if (y1 < EDGE)
|
|
||||||
obj->y = EDGE2;
|
|
||||||
if (y2 > (YPIX - EDGE))
|
|
||||||
obj->y = YPIX - EDGE2 - (y2 - y1);
|
|
||||||
|
|
||||||
if ((obj->vx == 0) && (obj->vy == 0) && (obj->pathType != WANDER2) && (obj->pathType != CHASE2))
|
|
||||||
obj->cycling = NOT_CYCLING;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clear all object baselines from the boundary file.
|
|
||||||
for (int i = 0; i < _numObj; i++) {
|
|
||||||
object_t *obj = &_objects[i]; // Get pointer to object
|
|
||||||
seq_t *currImage = obj->currImagePtr; // Get ptr to current image
|
|
||||||
if ((obj->screenIndex == *_screen_p) && (obj->cycling > ALMOST_INVISIBLE) && (obj->priority == FLOATING))
|
|
||||||
clearBoundary(obj->oldx + currImage->x1, obj->oldx + currImage->x2, obj->oldy + currImage->y2);
|
|
||||||
}
|
|
||||||
|
|
||||||
// If maze mode is enabled, do special maze processing
|
|
||||||
if (_maze.enabledFl)
|
|
||||||
processMaze();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return maximum allowed movement (from zero to vx) such that object does
|
// Return maximum allowed movement (from zero to vx) such that object does
|
||||||
|
@ -1993,218 +1712,31 @@ void HugoEngine::processMaze() {
|
||||||
_actListArr[_alNewscrIndex][0].a2.x = _maze.x2 - SHIFT - (x2 - x1);
|
_actListArr[_alNewscrIndex][0].a2.x = _maze.x2 - SHIFT - (x2 - x1);
|
||||||
_actListArr[_alNewscrIndex][0].a2.y = _hero->y;
|
_actListArr[_alNewscrIndex][0].a2.y = _hero->y;
|
||||||
_status.routeIndex = -1;
|
_status.routeIndex = -1;
|
||||||
scheduler().insertActionList(_alNewscrIndex);
|
_scheduler->insertActionList(_alNewscrIndex);
|
||||||
} else if (x2 > _maze.x2) {
|
} else if (x2 > _maze.x2) {
|
||||||
// Exit east
|
// Exit east
|
||||||
_actListArr[_alNewscrIndex][3].a8.screenIndex = *_screen_p + 1;
|
_actListArr[_alNewscrIndex][3].a8.screenIndex = *_screen_p + 1;
|
||||||
_actListArr[_alNewscrIndex][0].a2.x = _maze.x1 + SHIFT;
|
_actListArr[_alNewscrIndex][0].a2.x = _maze.x1 + SHIFT;
|
||||||
_actListArr[_alNewscrIndex][0].a2.y = _hero->y;
|
_actListArr[_alNewscrIndex][0].a2.y = _hero->y;
|
||||||
_status.routeIndex = -1;
|
_status.routeIndex = -1;
|
||||||
scheduler().insertActionList(_alNewscrIndex);
|
_scheduler->insertActionList(_alNewscrIndex);
|
||||||
} else if (y1 < _maze.y1 - SHIFT) {
|
} else if (y1 < _maze.y1 - SHIFT) {
|
||||||
// Exit north
|
// Exit north
|
||||||
_actListArr[_alNewscrIndex][3].a8.screenIndex = *_screen_p - _maze.size;
|
_actListArr[_alNewscrIndex][3].a8.screenIndex = *_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 - SHIFT - (y2 - y1);
|
_actListArr[_alNewscrIndex][0].a2.y = _maze.y2 - SHIFT - (y2 - y1);
|
||||||
_status.routeIndex = -1;
|
_status.routeIndex = -1;
|
||||||
scheduler().insertActionList(_alNewscrIndex);
|
_scheduler->insertActionList(_alNewscrIndex);
|
||||||
} else if (y2 > _maze.y2 - SHIFT / 2) {
|
} else if (y2 > _maze.y2 - SHIFT / 2) {
|
||||||
// Exit south
|
// Exit south
|
||||||
_actListArr[_alNewscrIndex][3].a8.screenIndex = *_screen_p + _maze.size;
|
_actListArr[_alNewscrIndex][3].a8.screenIndex = *_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 + SHIFT;
|
_actListArr[_alNewscrIndex][0].a2.y = _maze.y1 + SHIFT;
|
||||||
_status.routeIndex = -1;
|
_status.routeIndex = -1;
|
||||||
scheduler().insertActionList(_alNewscrIndex);
|
_scheduler->insertActionList(_alNewscrIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compare function for the quicksort. The sort is to order the objects in
|
|
||||||
// increasing vertical position, using y+y2 as the baseline
|
|
||||||
// Returns -1 if ay2 < by2 else 1 if ay2 > by2 else 0
|
|
||||||
int HugoEngine::y2comp(const void *a, const void *b) {
|
|
||||||
debugC(6, kDebugEngine, "y2comp");
|
|
||||||
|
|
||||||
const object_t *p1 = &s_Engine->_objects[*(const byte *)a];
|
|
||||||
const object_t *p2 = &s_Engine->_objects[*(const byte *)b];
|
|
||||||
|
|
||||||
if (p1 == p2)
|
|
||||||
// Why does qsort try the same indexes?
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (p1->priority == BACKGROUND)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (p2->priority == BACKGROUND)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
if (p1->priority == FOREGROUND)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
if (p2->priority == FOREGROUND)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
int ay2 = p1->y + p1->currImagePtr->y2;
|
|
||||||
int by2 = p2->y + p2->currImagePtr->y2;
|
|
||||||
|
|
||||||
return ay2 - by2;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Draw all objects on screen as follows:
|
|
||||||
// 1. Sort 'FLOATING' objects in order of y2 (base of object)
|
|
||||||
// 2. Display new object frames/positions in dib
|
|
||||||
// Finally, cycle any animating objects to next frame
|
|
||||||
void HugoEngine::updateImages() {
|
|
||||||
debugC(5, kDebugEngine, "updateImages");
|
|
||||||
|
|
||||||
// Initialise the index array to visible objects in current screen
|
|
||||||
int num_objs = 0;
|
|
||||||
byte objindex[MAX_OBJECTS]; // Array of indeces to objects
|
|
||||||
|
|
||||||
for (int i = 0; i < _numObj; i++) {
|
|
||||||
object_t *obj = &_objects[i];
|
|
||||||
if ((obj->screenIndex == *_screen_p) && (obj->cycling >= ALMOST_INVISIBLE))
|
|
||||||
objindex[num_objs++] = i;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sort the objects into increasing y+y2 (painter's algorithm)
|
|
||||||
qsort(objindex, num_objs, sizeof(objindex[0]), y2comp);
|
|
||||||
|
|
||||||
// Add each visible object to display list
|
|
||||||
for (int i = 0; i < num_objs; i++) {
|
|
||||||
object_t *obj = &_objects[objindex[i]];
|
|
||||||
// Count down inter-frame timer
|
|
||||||
if (obj->frameTimer)
|
|
||||||
obj->frameTimer--;
|
|
||||||
|
|
||||||
if (obj->cycling > ALMOST_INVISIBLE) { // Only if visible
|
|
||||||
switch (obj->cycling) {
|
|
||||||
case NOT_CYCLING:
|
|
||||||
screen().displayFrame(obj->x, obj->y, obj->currImagePtr, obj->priority == OVEROVL);
|
|
||||||
break;
|
|
||||||
case CYCLE_FORWARD:
|
|
||||||
if (obj->frameTimer) // Not time to see next frame yet
|
|
||||||
screen().displayFrame(obj->x, obj->y, obj->currImagePtr, obj->priority == OVEROVL);
|
|
||||||
else
|
|
||||||
screen().displayFrame(obj->x, obj->y, obj->currImagePtr->nextSeqPtr, obj->priority == OVEROVL);
|
|
||||||
break;
|
|
||||||
case CYCLE_BACKWARD: {
|
|
||||||
seq_t *seqPtr = obj->currImagePtr;
|
|
||||||
if (!obj->frameTimer) { // Show next frame
|
|
||||||
while (seqPtr->nextSeqPtr != obj->currImagePtr)
|
|
||||||
seqPtr = seqPtr->nextSeqPtr;
|
|
||||||
}
|
|
||||||
screen().displayFrame(obj->x, obj->y, seqPtr, obj->priority == OVEROVL);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Cycle any animating objects
|
|
||||||
for (int i = 0; i < num_objs; i++) {
|
|
||||||
object_t *obj = &_objects[objindex[i]];
|
|
||||||
if (obj->cycling != INVISIBLE) {
|
|
||||||
// Only if it's visible
|
|
||||||
if (obj->cycling == ALMOST_INVISIBLE)
|
|
||||||
obj->cycling = INVISIBLE;
|
|
||||||
|
|
||||||
// Now Rotate to next picture in sequence
|
|
||||||
switch (obj->cycling) {
|
|
||||||
case NOT_CYCLING:
|
|
||||||
break;
|
|
||||||
case CYCLE_FORWARD:
|
|
||||||
if (!obj->frameTimer) {
|
|
||||||
// Time to step to next frame
|
|
||||||
obj->currImagePtr = obj->currImagePtr->nextSeqPtr;
|
|
||||||
// Find out if this is last frame of sequence
|
|
||||||
// If so, reset frame_timer and decrement n_cycle
|
|
||||||
if (obj->frameInterval || obj->cycleNumb) {
|
|
||||||
obj->frameTimer = obj->frameInterval;
|
|
||||||
for (int j = 0; j < obj->seqNumb; j++) {
|
|
||||||
if (obj->currImagePtr->nextSeqPtr == obj->seqList[j].seqPtr) {
|
|
||||||
if (obj->cycleNumb) { // Decr cycleNumb if Non-continous
|
|
||||||
if (!--obj->cycleNumb)
|
|
||||||
obj->cycling = NOT_CYCLING;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case CYCLE_BACKWARD: {
|
|
||||||
if (!obj->frameTimer) {
|
|
||||||
// Time to step to prev frame
|
|
||||||
seq_t *seqPtr = obj->currImagePtr;
|
|
||||||
while (obj->currImagePtr->nextSeqPtr != seqPtr)
|
|
||||||
obj->currImagePtr = obj->currImagePtr->nextSeqPtr;
|
|
||||||
// Find out if this is first frame of sequence
|
|
||||||
// If so, reset frame_timer and decrement n_cycle
|
|
||||||
if (obj->frameInterval || obj->cycleNumb) {
|
|
||||||
obj->frameTimer = obj->frameInterval;
|
|
||||||
for (int j = 0; j < obj->seqNumb; j++) {
|
|
||||||
if (obj->currImagePtr == obj->seqList[j].seqPtr) {
|
|
||||||
if (obj->cycleNumb){ // Decr cycleNumb if Non-continous
|
|
||||||
if (!--obj->cycleNumb)
|
|
||||||
obj->cycling = NOT_CYCLING;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
obj->oldx = obj->x;
|
|
||||||
obj->oldy = obj->y;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return object index of the topmost object under the cursor, or -1 if none
|
|
||||||
// Objects are filtered if not "useful"
|
|
||||||
int16 HugoEngine::findObject(uint16 x, uint16 y) {
|
|
||||||
debugC(3, kDebugEngine, "findObject(%d, %d)", x, y);
|
|
||||||
|
|
||||||
int16 objIndex = -1; // Index of found object
|
|
||||||
uint16 y2Max = 0; // Greatest y2
|
|
||||||
object_t *obj = _objects;
|
|
||||||
// Check objects on screen
|
|
||||||
for (int i = 0; i < _numObj; i++, obj++) {
|
|
||||||
// Object must be in current screen and "useful"
|
|
||||||
if (obj->screenIndex == *_screen_p && (obj->genericCmd || obj->objValue || obj->cmdIndex)) {
|
|
||||||
seq_t *curImage = obj->currImagePtr;
|
|
||||||
// Object must have a visible image...
|
|
||||||
if (curImage != 0 && obj->cycling != INVISIBLE) {
|
|
||||||
// If cursor inside object
|
|
||||||
if (x >= (uint16)obj->x && x <= obj->x + curImage->x2 && y >= (uint16)obj->y && y <= obj->y + curImage->y2) {
|
|
||||||
// If object is closest so far
|
|
||||||
if (obj->y + curImage->y2 > y2Max) {
|
|
||||||
y2Max = obj->y + curImage->y2;
|
|
||||||
objIndex = i; // Found an object!
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// ...or a dummy object that has a hotspot rectangle
|
|
||||||
if (curImage == 0 && obj->vxPath != 0 && !obj->carriedFl) {
|
|
||||||
// If cursor inside special rectangle
|
|
||||||
if ((int16)x >= obj->oldx && (int16)x < obj->oldx + obj->vxPath && (int16)y >= obj->oldy && (int16)y < obj->oldy + obj->vyPath) {
|
|
||||||
// If object is closest so far
|
|
||||||
if (obj->oldy + obj->vyPath - 1 > (int16)y2Max) {
|
|
||||||
y2Max = obj->oldy + obj->vyPath - 1;
|
|
||||||
objIndex = i; // Found an object!
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return objIndex;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find a clear space around supplied object that hero can walk to
|
// Find a clear space around supplied object that hero can walk to
|
||||||
bool HugoEngine::findObjectSpace(object_t *obj, int16 *destx, int16 *desty) {
|
bool HugoEngine::findObjectSpace(object_t *obj, int16 *destx, int16 *desty) {
|
||||||
debugC(1, kDebugEngine, "findObjectSpace(obj, %d, %d)", *destx, *desty);
|
debugC(1, kDebugEngine, "findObjectSpace(obj, %d, %d)", *destx, *desty);
|
||||||
|
@ -2264,97 +1796,6 @@ char *HugoEngine::useBG(char *name) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If status.objid = -1, pick up objid, else use status.objid on objid,
|
|
||||||
// if objid can't be picked up, use it directly
|
|
||||||
void HugoEngine::useObject(int16 objId) {
|
|
||||||
debugC(1, kDebugEngine, "useObject(%d)", objId);
|
|
||||||
|
|
||||||
char *verb; // Background verb to use directly
|
|
||||||
object_t *obj = &_objects[objId]; // Ptr to object
|
|
||||||
if (_status.inventoryObjId == -1) {
|
|
||||||
// Get or use objid directly
|
|
||||||
if ((obj->genericCmd & TAKE) || obj->objValue) // Get collectible item
|
|
||||||
sprintf(_line, "%s %s", _arrayVerbs[_take][0], _arrayNouns[obj->nounIndex][0]);
|
|
||||||
else if (obj->genericCmd & LOOK) // Look item
|
|
||||||
sprintf(_line, "%s %s", _arrayVerbs[_look][0], _arrayNouns[obj->nounIndex][0]);
|
|
||||||
else if (obj->genericCmd & DROP) // Drop item
|
|
||||||
sprintf(_line, "%s %s", _arrayVerbs[_drop][0], _arrayNouns[obj->nounIndex][0]);
|
|
||||||
else if (obj->cmdIndex != 0) // Use non-collectible item if able
|
|
||||||
sprintf(_line, "%s %s", _arrayVerbs[_cmdList[obj->cmdIndex][1].verbIndex][0], _arrayNouns[obj->nounIndex][0]);
|
|
||||||
else if ((verb = useBG(_arrayNouns[obj->nounIndex][0])) != 0)
|
|
||||||
sprintf(_line, "%s %s", verb, _arrayNouns[obj->nounIndex][0]);
|
|
||||||
else
|
|
||||||
return; // Can't use object directly
|
|
||||||
} else {
|
|
||||||
// Use status.objid on objid
|
|
||||||
// Default to first cmd verb
|
|
||||||
sprintf(_line, "%s %s %s", _arrayVerbs[_cmdList[_objects[_status.inventoryObjId].cmdIndex][1].verbIndex][0], _arrayNouns[_objects[_status.inventoryObjId].nounIndex][0], _arrayNouns[obj->nounIndex][0]);
|
|
||||||
|
|
||||||
// Check valid use of objects and override verb if necessary
|
|
||||||
for (uses_t *use = _uses; use->objId != _numObj; use++) {
|
|
||||||
if (_status.inventoryObjId == use->objId) {
|
|
||||||
// Look for secondary object, if found use matching verb
|
|
||||||
bool foundFl = false;
|
|
||||||
for (target_t *target = use->targets; _arrayNouns[target->nounIndex] != 0; target++)
|
|
||||||
if (_arrayNouns[target->nounIndex][0] == _arrayNouns[obj->nounIndex][0]) {
|
|
||||||
foundFl = true;
|
|
||||||
sprintf(_line, "%s %s %s", _arrayVerbs[target->verbIndex][0], _arrayNouns[_objects[_status.inventoryObjId].nounIndex][0], _arrayNouns[obj->nounIndex][0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// No valid use of objects found, print failure string
|
|
||||||
if (!foundFl) {
|
|
||||||
// Deselect dragged icon if inventory not active
|
|
||||||
if (_status.inventoryState != I_ACTIVE)
|
|
||||||
_status.inventoryObjId = -1;
|
|
||||||
Utils::Box(BOX_ANY, "%s", _textData[use->dataIndex]);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_status.inventoryState == I_ACTIVE) // If inventory active, remove it
|
|
||||||
_status.inventoryState = I_UP;
|
|
||||||
_status.inventoryObjId = -1; // Deselect any dragged icon
|
|
||||||
parser().lineHandler(); // and process command
|
|
||||||
}
|
|
||||||
|
|
||||||
// Issue "Look at <object>" command
|
|
||||||
// Note special case of swapped hero image
|
|
||||||
void HugoEngine::lookObject(object_t *obj) {
|
|
||||||
debugC(1, kDebugEngine, "lookObject");
|
|
||||||
|
|
||||||
if (obj == _hero)
|
|
||||||
// Hero swapped - look at other
|
|
||||||
obj = &_objects[_heroImage];
|
|
||||||
|
|
||||||
parser().command("%s %s", _arrayVerbs[_look][0], _arrayNouns[obj->nounIndex][0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Free all object images
|
|
||||||
void HugoEngine::freeObjects() {
|
|
||||||
debugC(1, kDebugEngine, "freeObjects");
|
|
||||||
|
|
||||||
// Nothing to do if not allocated yet
|
|
||||||
if (_hero->seqList[0].seqPtr == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Free all sequence lists and image data
|
|
||||||
for (int i = 0; i < _numObj; i++) {
|
|
||||||
object_t *obj = &_objects[i];
|
|
||||||
for (int j = 0; j < obj->seqNumb; j++) { // for each sequence
|
|
||||||
seq_t *seq = obj->seqList[j].seqPtr; // Free image
|
|
||||||
if (seq == 0) // Failure during database load
|
|
||||||
break;
|
|
||||||
do {
|
|
||||||
free(seq->imagePtr);
|
|
||||||
seq = seq->nextSeqPtr;
|
|
||||||
} while (seq != obj->seqList[j].seqPtr);
|
|
||||||
free(seq); // Free sequence record
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add action lists for this screen to event queue
|
// Add action lists for this screen to event queue
|
||||||
void HugoEngine::screenActions(int screenNum) {
|
void HugoEngine::screenActions(int screenNum) {
|
||||||
debugC(1, kDebugEngine, "screenActions(%d)", screenNum);
|
debugC(1, kDebugEngine, "screenActions(%d)", screenNum);
|
||||||
|
@ -2362,7 +1803,7 @@ void HugoEngine::screenActions(int screenNum) {
|
||||||
uint16 *screenAct = _screenActs[screenNum];
|
uint16 *screenAct = _screenActs[screenNum];
|
||||||
if (screenAct) {
|
if (screenAct) {
|
||||||
for (int i = 0; screenAct[i]; i++)
|
for (int i = 0; screenAct[i]; i++)
|
||||||
scheduler().insertActionList(screenAct[i]);
|
_scheduler->insertActionList(screenAct[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2372,8 +1813,8 @@ void HugoEngine::setNewScreen(int screenNum) {
|
||||||
|
|
||||||
*_screen_p = screenNum; // HERO object
|
*_screen_p = screenNum; // HERO object
|
||||||
for (int i = HERO + 1; i < _numObj; i++) { // Any others
|
for (int i = HERO + 1; i < _numObj; i++) { // Any others
|
||||||
if (_objects[i].carriedFl) // being carried
|
if (_object->isCarried(i)) // being carried
|
||||||
_objects[i].screenIndex = screenNum;
|
_object->_objects[i].screenIndex = screenNum;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2394,7 +1835,7 @@ void HugoEngine::boundaryCollision(object_t *obj) {
|
||||||
hotspot_t *hotspot = &_hotspots[i];
|
hotspot_t *hotspot = &_hotspots[i];
|
||||||
if (hotspot->screenIndex == obj->screenIndex)
|
if (hotspot->screenIndex == obj->screenIndex)
|
||||||
if ((x >= hotspot->x1) && (x <= hotspot->x2) && (y >= hotspot->y1) && (y <= hotspot->y2)) {
|
if ((x >= hotspot->x1) && (x <= hotspot->x2) && (y >= hotspot->y1) && (y <= hotspot->y2)) {
|
||||||
scheduler().insertActionList(hotspot->actIndex);
|
_scheduler->insertActionList(hotspot->actIndex);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2407,7 +1848,7 @@ void HugoEngine::boundaryCollision(object_t *obj) {
|
||||||
if (radius < 0)
|
if (radius < 0)
|
||||||
radius = DX * 2;
|
radius = DX * 2;
|
||||||
if ((abs(dx) <= radius) && (abs(dy) <= radius))
|
if ((abs(dx) <= radius) && (abs(dy) <= radius))
|
||||||
scheduler().insertActionList(obj->actIndex);
|
_scheduler->insertActionList(obj->actIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2416,7 +1857,7 @@ void HugoEngine::calcMaxScore() {
|
||||||
debugC(1, kDebugEngine, "calcMaxScore");
|
debugC(1, kDebugEngine, "calcMaxScore");
|
||||||
|
|
||||||
for (int i = 0; i < _numObj; i++)
|
for (int i = 0; i < _numObj; i++)
|
||||||
_maxscore += _objects[i].objValue;
|
_maxscore += _object->_objects[i].objValue;
|
||||||
|
|
||||||
for (int i = 0; i < _numBonuses; i++)
|
for (int i = 0; i < _numBonuses; i++)
|
||||||
_maxscore += _points[i].score;
|
_maxscore += _points[i].score;
|
||||||
|
|
|
@ -38,7 +38,6 @@
|
||||||
#define EDGE 10 // Closest object can get to edge of screen
|
#define EDGE 10 // Closest object can get to edge of screen
|
||||||
#define EDGE2 (EDGE * 2) // Push object further back on edge collision
|
#define EDGE2 (EDGE * 2) // Push object further back on edge collision
|
||||||
#define SHIFT 8 // Place hero this far inside bounding box
|
#define SHIFT 8 // Place hero this far inside bounding box
|
||||||
#define MAX_OBJECTS 128 // Used in Update_images()
|
|
||||||
#define BOUND(X, Y) ((_boundary[Y * XBYTES + X / 8] & (0x80 >> X % 8)) != 0) // Boundary bit set
|
#define BOUND(X, Y) ((_boundary[Y * XBYTES + X / 8] & (0x80 >> X % 8)) != 0) // Boundary bit set
|
||||||
|
|
||||||
namespace Common {
|
namespace Common {
|
||||||
|
@ -103,6 +102,7 @@ class Parser;
|
||||||
class Route;
|
class Route;
|
||||||
class SoundHandler;
|
class SoundHandler;
|
||||||
class IntroHandler;
|
class IntroHandler;
|
||||||
|
class ObjectHandler;
|
||||||
|
|
||||||
|
|
||||||
class HugoEngine : public Engine {
|
class HugoEngine : public Engine {
|
||||||
|
@ -149,7 +149,6 @@ public:
|
||||||
point_t *_points;
|
point_t *_points;
|
||||||
cmd **_cmdList;
|
cmd **_cmdList;
|
||||||
uint16 **_screenActs;
|
uint16 **_screenActs;
|
||||||
object_t *_objects;
|
|
||||||
act **_actListArr;
|
act **_actListArr;
|
||||||
int16 *_defltTunes;
|
int16 *_defltTunes;
|
||||||
uint16 _look;
|
uint16 _look;
|
||||||
|
@ -181,34 +180,6 @@ public:
|
||||||
return *s_Engine;
|
return *s_Engine;
|
||||||
}
|
}
|
||||||
|
|
||||||
FileManager &file() {
|
|
||||||
return *_fileManager;
|
|
||||||
}
|
|
||||||
Scheduler &scheduler() {
|
|
||||||
return *_scheduler;
|
|
||||||
}
|
|
||||||
Screen &screen() {
|
|
||||||
return *_screen;
|
|
||||||
}
|
|
||||||
MouseHandler &mouse() {
|
|
||||||
return *_mouseHandler;
|
|
||||||
}
|
|
||||||
InventoryHandler &inventory() {
|
|
||||||
return *_inventoryHandler;
|
|
||||||
}
|
|
||||||
Parser &parser() {
|
|
||||||
return *_parser;
|
|
||||||
}
|
|
||||||
Route &route() {
|
|
||||||
return *_route;
|
|
||||||
}
|
|
||||||
SoundHandler &sound() {
|
|
||||||
return *_soundHandler;
|
|
||||||
}
|
|
||||||
IntroHandler &intro() {
|
|
||||||
return *_introHandler;
|
|
||||||
}
|
|
||||||
|
|
||||||
void initGame(const HugoGameDescription *gd);
|
void initGame(const HugoGameDescription *gd);
|
||||||
void initGamePart(const HugoGameDescription *gd);
|
void initGamePart(const HugoGameDescription *gd);
|
||||||
bool loadHugoDat();
|
bool loadHugoDat();
|
||||||
|
@ -220,22 +191,24 @@ public:
|
||||||
return _mouseY;
|
return _mouseY;
|
||||||
}
|
}
|
||||||
|
|
||||||
void initStatus();
|
|
||||||
void readObjectImages();
|
|
||||||
void readUIFImages();
|
|
||||||
void updateImages();
|
|
||||||
void moveObjects();
|
|
||||||
void useObject(int16 objId);
|
|
||||||
bool findObjectSpace(object_t *obj, int16 *destx, int16 *desty);
|
bool findObjectSpace(object_t *obj, int16 *destx, int16 *desty);
|
||||||
int16 findObject(uint16 x, uint16 y);
|
|
||||||
void lookObject(object_t *obj);
|
void boundaryCollision(object_t *obj);
|
||||||
void storeBoundary(int x1, int x2, int y);
|
|
||||||
void clearBoundary(int x1, int x2, int y);
|
void clearBoundary(int x1, int x2, int y);
|
||||||
void endGame();
|
void endGame();
|
||||||
|
void initStatus();
|
||||||
|
void processMaze();
|
||||||
|
void readObjectImages();
|
||||||
void readScreenFiles(int screen);
|
void readScreenFiles(int screen);
|
||||||
void setNewScreen(int screen);
|
|
||||||
void screenActions(int screen);
|
void screenActions(int screen);
|
||||||
|
void setNewScreen(int screen);
|
||||||
void shutdown();
|
void shutdown();
|
||||||
|
void storeBoundary(int x1, int x2, int y);
|
||||||
|
|
||||||
|
char *useBG(char *name);
|
||||||
|
|
||||||
|
int deltaX(int x1, int x2, int vx, int y);
|
||||||
|
int deltaY(int x1, int x2, int vy, int y);
|
||||||
|
|
||||||
overlay_t &getBoundaryOverlay() {
|
overlay_t &getBoundaryOverlay() {
|
||||||
return _boundary;
|
return _boundary;
|
||||||
|
@ -271,6 +244,17 @@ public:
|
||||||
return _introXSize;
|
return _introXSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FileManager *_file;
|
||||||
|
Scheduler *_scheduler;
|
||||||
|
Screen *_screen;
|
||||||
|
MouseHandler *_mouse;
|
||||||
|
InventoryHandler *_inventory;
|
||||||
|
Parser *_parser;
|
||||||
|
Route *_route;
|
||||||
|
SoundHandler *_sound;
|
||||||
|
IntroHandler *_intro;
|
||||||
|
ObjectHandler *_object;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
// Engine APIs
|
// Engine APIs
|
||||||
|
@ -301,16 +285,6 @@ private:
|
||||||
Common::Platform _platform;
|
Common::Platform _platform;
|
||||||
bool _packedFl;
|
bool _packedFl;
|
||||||
|
|
||||||
FileManager *_fileManager;
|
|
||||||
Scheduler *_scheduler;
|
|
||||||
Screen *_screen;
|
|
||||||
MouseHandler *_mouseHandler;
|
|
||||||
InventoryHandler *_inventoryHandler;
|
|
||||||
Parser *_parser;
|
|
||||||
Route *_route;
|
|
||||||
SoundHandler *_soundHandler;
|
|
||||||
IntroHandler *_introHandler;
|
|
||||||
|
|
||||||
int _score; // Holds current score
|
int _score; // Holds current score
|
||||||
int _maxscore; // Holds maximum score
|
int _maxscore; // Holds maximum score
|
||||||
|
|
||||||
|
@ -323,19 +297,10 @@ private:
|
||||||
void initPlaylist(bool playlist[MAX_TUNES]);
|
void initPlaylist(bool playlist[MAX_TUNES]);
|
||||||
void initConfig(inst_t action);
|
void initConfig(inst_t action);
|
||||||
void initialize();
|
void initialize();
|
||||||
int deltaX(int x1, int x2, int vx, int y);
|
|
||||||
int deltaY(int x1, int x2, int vy, int y);
|
|
||||||
void processMaze();
|
|
||||||
//int y2comp (const void *a, const void *b);
|
|
||||||
char *useBG(char *name);
|
|
||||||
void freeObjects();
|
|
||||||
void boundaryCollision(object_t *obj);
|
|
||||||
void calcMaxScore();
|
void calcMaxScore();
|
||||||
void initMachine();
|
void initMachine();
|
||||||
void runMachine();
|
void runMachine();
|
||||||
|
|
||||||
static int y2comp(const void *a, const void *b);
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // End of namespace Hugo
|
} // End of namespace Hugo
|
||||||
|
|
|
@ -37,7 +37,7 @@
|
||||||
|
|
||||||
namespace Hugo {
|
namespace Hugo {
|
||||||
|
|
||||||
IntroHandler::IntroHandler(HugoEngine &vm) : _vm(vm) {
|
IntroHandler::IntroHandler(HugoEngine *vm) : _vm(vm) {
|
||||||
}
|
}
|
||||||
|
|
||||||
IntroHandler::~IntroHandler() {
|
IntroHandler::~IntroHandler() {
|
||||||
|
|
|
@ -43,7 +43,7 @@ enum seqTextIntro {
|
||||||
|
|
||||||
class IntroHandler {
|
class IntroHandler {
|
||||||
public:
|
public:
|
||||||
IntroHandler(HugoEngine &vm);
|
IntroHandler(HugoEngine *vm);
|
||||||
virtual ~IntroHandler();
|
virtual ~IntroHandler();
|
||||||
|
|
||||||
virtual void preNewGame() = 0;
|
virtual void preNewGame() = 0;
|
||||||
|
@ -51,13 +51,13 @@ public:
|
||||||
virtual bool introPlay() = 0;
|
virtual bool introPlay() = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
HugoEngine &_vm;
|
HugoEngine *_vm;
|
||||||
int16 introTicks; // Count calls to introPlay()
|
int16 introTicks; // Count calls to introPlay()
|
||||||
};
|
};
|
||||||
|
|
||||||
class intro_v1w : public IntroHandler {
|
class intro_v1w : public IntroHandler {
|
||||||
public:
|
public:
|
||||||
intro_v1w(HugoEngine &vm);
|
intro_v1w(HugoEngine *vm);
|
||||||
~intro_v1w();
|
~intro_v1w();
|
||||||
|
|
||||||
void preNewGame();
|
void preNewGame();
|
||||||
|
@ -67,7 +67,7 @@ public:
|
||||||
|
|
||||||
class intro_v1d : public IntroHandler {
|
class intro_v1d : public IntroHandler {
|
||||||
public:
|
public:
|
||||||
intro_v1d(HugoEngine &vm);
|
intro_v1d(HugoEngine *vm);
|
||||||
~intro_v1d();
|
~intro_v1d();
|
||||||
|
|
||||||
void preNewGame();
|
void preNewGame();
|
||||||
|
@ -77,7 +77,7 @@ public:
|
||||||
|
|
||||||
class intro_v2w : public IntroHandler {
|
class intro_v2w : public IntroHandler {
|
||||||
public:
|
public:
|
||||||
intro_v2w(HugoEngine &vm);
|
intro_v2w(HugoEngine *vm);
|
||||||
~intro_v2w();
|
~intro_v2w();
|
||||||
|
|
||||||
void preNewGame();
|
void preNewGame();
|
||||||
|
@ -87,7 +87,7 @@ public:
|
||||||
|
|
||||||
class intro_v2d : public IntroHandler {
|
class intro_v2d : public IntroHandler {
|
||||||
public:
|
public:
|
||||||
intro_v2d(HugoEngine &vm);
|
intro_v2d(HugoEngine *vm);
|
||||||
~intro_v2d();
|
~intro_v2d();
|
||||||
|
|
||||||
void preNewGame();
|
void preNewGame();
|
||||||
|
@ -97,7 +97,7 @@ public:
|
||||||
|
|
||||||
class intro_v3w : public IntroHandler {
|
class intro_v3w : public IntroHandler {
|
||||||
public:
|
public:
|
||||||
intro_v3w(HugoEngine &vm);
|
intro_v3w(HugoEngine *vm);
|
||||||
~intro_v3w();
|
~intro_v3w();
|
||||||
|
|
||||||
void preNewGame();
|
void preNewGame();
|
||||||
|
@ -107,7 +107,7 @@ public:
|
||||||
|
|
||||||
class intro_v3d : public IntroHandler {
|
class intro_v3d : public IntroHandler {
|
||||||
public:
|
public:
|
||||||
intro_v3d(HugoEngine &vm);
|
intro_v3d(HugoEngine *vm);
|
||||||
~intro_v3d();
|
~intro_v3d();
|
||||||
|
|
||||||
void preNewGame();
|
void preNewGame();
|
||||||
|
|
|
@ -37,7 +37,7 @@
|
||||||
#include "hugo/display.h"
|
#include "hugo/display.h"
|
||||||
|
|
||||||
namespace Hugo {
|
namespace Hugo {
|
||||||
intro_v1d::intro_v1d(HugoEngine &vm) : IntroHandler(vm) {
|
intro_v1d::intro_v1d(HugoEngine *vm) : IntroHandler(vm) {
|
||||||
}
|
}
|
||||||
|
|
||||||
intro_v1d::~intro_v1d() {
|
intro_v1d::~intro_v1d() {
|
||||||
|
@ -52,116 +52,116 @@ void intro_v1d::introInit() {
|
||||||
|
|
||||||
bool intro_v1d::introPlay() {
|
bool intro_v1d::introPlay() {
|
||||||
static int state = 0;
|
static int state = 0;
|
||||||
byte introSize = _vm.getIntroSize();
|
byte introSize = _vm->getIntroSize();
|
||||||
|
|
||||||
if (introTicks < introSize) {
|
if (introTicks < introSize) {
|
||||||
switch (state++) {
|
switch (state++) {
|
||||||
case 0:
|
case 0:
|
||||||
_vm.screen().drawRectangle(true, 0, 0, 319, 199, _TMAGENTA);
|
_vm->_screen->drawRectangle(true, 0, 0, 319, 199, _TMAGENTA);
|
||||||
_vm.screen().drawRectangle(true, 10, 10, 309, 189, _TBLACK);
|
_vm->_screen->drawRectangle(true, 10, 10, 309, 189, _TBLACK);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
_vm.screen().drawShape(20, 92,_TLIGHTMAGENTA,_TMAGENTA);
|
_vm->_screen->drawShape(20, 92,_TLIGHTMAGENTA,_TMAGENTA);
|
||||||
_vm.screen().drawShape(250,92,_TLIGHTMAGENTA,_TMAGENTA);
|
_vm->_screen->drawShape(250,92,_TLIGHTMAGENTA,_TMAGENTA);
|
||||||
|
|
||||||
// HACK: use of TROMAN, size 10-5
|
// HACK: use of TROMAN, size 10-5
|
||||||
_vm.screen().loadFont(0);
|
_vm->_screen->loadFont(0);
|
||||||
|
|
||||||
char buffer[80];
|
char buffer[80];
|
||||||
if (_boot.registered)
|
if (_boot.registered)
|
||||||
strcpy(buffer, "Registered Version");
|
strcpy(buffer, "Registered Version");
|
||||||
else
|
else
|
||||||
strcpy(buffer, "Shareware Version");
|
strcpy(buffer, "Shareware Version");
|
||||||
_vm.screen().writeStr(CENTER, 163, buffer, _TLIGHTMAGENTA);
|
_vm->_screen->writeStr(CENTER, 163, buffer, _TLIGHTMAGENTA);
|
||||||
_vm.screen().writeStr(CENTER, 176, COPYRIGHT, _TLIGHTMAGENTA);
|
_vm->_screen->writeStr(CENTER, 176, COPYRIGHT, _TLIGHTMAGENTA);
|
||||||
|
|
||||||
if (scumm_stricmp(_boot.distrib, "David P. Gray")) {
|
if (scumm_stricmp(_boot.distrib, "David P. Gray")) {
|
||||||
sprintf(buffer, "Distributed by %s.", _boot.distrib);
|
sprintf(buffer, "Distributed by %s.", _boot.distrib);
|
||||||
_vm.screen().writeStr(CENTER, 75, buffer, _TMAGENTA);
|
_vm->_screen->writeStr(CENTER, 75, buffer, _TMAGENTA);
|
||||||
}
|
}
|
||||||
|
|
||||||
// HACK: use of SCRIPT size 24-16
|
// HACK: use of SCRIPT size 24-16
|
||||||
_vm.screen().loadFont(2);
|
_vm->_screen->loadFont(2);
|
||||||
|
|
||||||
strcpy(buffer, "Hugo's");
|
strcpy(buffer, "Hugo's");
|
||||||
_vm.screen().writeStr(CENTER, 20, buffer, _TMAGENTA);
|
_vm->_screen->writeStr(CENTER, 20, buffer, _TMAGENTA);
|
||||||
|
|
||||||
// HACK: use of TROMAN, size 30-24
|
// HACK: use of TROMAN, size 30-24
|
||||||
strcpy(buffer, "House of Horrors !");
|
strcpy(buffer, "House of Horrors !");
|
||||||
_vm.screen().writeStr(CENTER, 50, buffer, _TLIGHTMAGENTA);
|
_vm->_screen->writeStr(CENTER, 50, buffer, _TLIGHTMAGENTA);
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
_vm.screen().drawRectangle(true, 82, 92, 237, 138, _TBLACK);
|
_vm->_screen->drawRectangle(true, 82, 92, 237, 138, _TBLACK);
|
||||||
// HACK: use of TROMAN, size 16-9
|
// HACK: use of TROMAN, size 16-9
|
||||||
_vm.screen().loadFont(2);
|
_vm->_screen->loadFont(2);
|
||||||
|
|
||||||
strcpy(buffer, "S t a r r i n g :");
|
strcpy(buffer, "S t a r r i n g :");
|
||||||
_vm.screen().writeStr(CENTER, 95, buffer, _TMAGENTA);
|
_vm->_screen->writeStr(CENTER, 95, buffer, _TMAGENTA);
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
// HACK: use of TROMAN size 20-9
|
// HACK: use of TROMAN size 20-9
|
||||||
_vm.screen().loadFont(2);
|
_vm->_screen->loadFont(2);
|
||||||
|
|
||||||
strcpy(buffer, "Hugo !");
|
strcpy(buffer, "Hugo !");
|
||||||
_vm.screen().writeStr(CENTER, 115, buffer, _TLIGHTMAGENTA);
|
_vm->_screen->writeStr(CENTER, 115, buffer, _TLIGHTMAGENTA);
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
_vm.screen().drawRectangle(true, 82, 92, 237, 138, _TBLACK);
|
_vm->_screen->drawRectangle(true, 82, 92, 237, 138, _TBLACK);
|
||||||
// HACK: use of TROMAN size 16-9
|
// HACK: use of TROMAN size 16-9
|
||||||
_vm.screen().loadFont(2);
|
_vm->_screen->loadFont(2);
|
||||||
|
|
||||||
strcpy(buffer, "P r o d u c e d b y :");
|
strcpy(buffer, "P r o d u c e d b y :");
|
||||||
_vm.screen().writeStr(CENTER, 95, buffer, _TMAGENTA);
|
_vm->_screen->writeStr(CENTER, 95, buffer, _TMAGENTA);
|
||||||
break;
|
break;
|
||||||
case 5:
|
case 5:
|
||||||
// HACK: use of TROMAN size 16-9
|
// HACK: use of TROMAN size 16-9
|
||||||
_vm.screen().loadFont(2);
|
_vm->_screen->loadFont(2);
|
||||||
|
|
||||||
strcpy(buffer, "David P Gray !");
|
strcpy(buffer, "David P Gray !");
|
||||||
_vm.screen().writeStr(CENTER, 115, buffer, _TLIGHTMAGENTA);
|
_vm->_screen->writeStr(CENTER, 115, buffer, _TLIGHTMAGENTA);
|
||||||
break;
|
break;
|
||||||
case 6:
|
case 6:
|
||||||
_vm.screen().drawRectangle(true, 82, 92, 237, 138, _TBLACK);
|
_vm->_screen->drawRectangle(true, 82, 92, 237, 138, _TBLACK);
|
||||||
// HACK: use of TROMAN size 16-9
|
// HACK: use of TROMAN size 16-9
|
||||||
_vm.screen().loadFont(2);
|
_vm->_screen->loadFont(2);
|
||||||
|
|
||||||
strcpy(buffer, "D i r e c t e d b y :");
|
strcpy(buffer, "D i r e c t e d b y :");
|
||||||
_vm.screen().writeStr(CENTER, 95, buffer, _TMAGENTA);
|
_vm->_screen->writeStr(CENTER, 95, buffer, _TMAGENTA);
|
||||||
break;
|
break;
|
||||||
case 7:
|
case 7:
|
||||||
// HACK: use of TROMAN size 16-9
|
// HACK: use of TROMAN size 16-9
|
||||||
_vm.screen().loadFont(2);
|
_vm->_screen->loadFont(2);
|
||||||
|
|
||||||
strcpy(buffer, "David P Gray !");
|
strcpy(buffer, "David P Gray !");
|
||||||
_vm.screen().writeStr(CENTER, 115, buffer, _TLIGHTMAGENTA);
|
_vm->_screen->writeStr(CENTER, 115, buffer, _TLIGHTMAGENTA);
|
||||||
break;
|
break;
|
||||||
case 8:
|
case 8:
|
||||||
_vm.screen().drawRectangle(true, 82, 92, 237, 138, _TBLACK);
|
_vm->_screen->drawRectangle(true, 82, 92, 237, 138, _TBLACK);
|
||||||
// HACK: use of TROMAN size 16-9
|
// HACK: use of TROMAN size 16-9
|
||||||
_vm.screen().loadFont(2);
|
_vm->_screen->loadFont(2);
|
||||||
|
|
||||||
strcpy(buffer, "M u s i c b y :");
|
strcpy(buffer, "M u s i c b y :");
|
||||||
_vm.screen().writeStr(CENTER, 95, buffer, _TMAGENTA);
|
_vm->_screen->writeStr(CENTER, 95, buffer, _TMAGENTA);
|
||||||
break;
|
break;
|
||||||
case 9:
|
case 9:
|
||||||
// HACK: use of TROMAN size 16-9
|
// HACK: use of TROMAN size 16-9
|
||||||
_vm.screen().loadFont(2);
|
_vm->_screen->loadFont(2);
|
||||||
|
|
||||||
strcpy(buffer, "David P Gray !");
|
strcpy(buffer, "David P Gray !");
|
||||||
_vm.screen().writeStr(CENTER, 115, buffer, _TLIGHTMAGENTA);
|
_vm->_screen->writeStr(CENTER, 115, buffer, _TLIGHTMAGENTA);
|
||||||
break;
|
break;
|
||||||
case 10:
|
case 10:
|
||||||
_vm.screen().drawRectangle(true, 82, 92, 237, 138, _TBLACK);
|
_vm->_screen->drawRectangle(true, 82, 92, 237, 138, _TBLACK);
|
||||||
// HACK: use of TROMAN size 20-14
|
// HACK: use of TROMAN size 20-14
|
||||||
_vm.screen().loadFont(2);
|
_vm->_screen->loadFont(2);
|
||||||
|
|
||||||
strcpy(buffer, "E n j o y !");
|
strcpy(buffer, "E n j o y !");
|
||||||
_vm.screen().writeStr(CENTER, 100, buffer, _TLIGHTMAGENTA);
|
_vm->_screen->writeStr(CENTER, 100, buffer, _TLIGHTMAGENTA);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
_vm.screen().displayBackground();
|
_vm->_screen->displayBackground();
|
||||||
g_system->updateScreen();
|
g_system->updateScreen();
|
||||||
g_system->delayMillis(1000);
|
g_system->delayMillis(1000);
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,7 @@
|
||||||
|
|
||||||
|
|
||||||
namespace Hugo {
|
namespace Hugo {
|
||||||
intro_v1w::intro_v1w(HugoEngine &vm) : IntroHandler(vm) {
|
intro_v1w::intro_v1w(HugoEngine *vm) : IntroHandler(vm) {
|
||||||
}
|
}
|
||||||
|
|
||||||
intro_v1w::~intro_v1w() {
|
intro_v1w::~intro_v1w() {
|
||||||
|
@ -47,8 +47,8 @@ intro_v1w::~intro_v1w() {
|
||||||
|
|
||||||
void intro_v1w::preNewGame() {
|
void intro_v1w::preNewGame() {
|
||||||
// Auto-start a new game
|
// Auto-start a new game
|
||||||
_vm.file().restoreGame(-1);
|
_vm->_file->restoreGame(-1);
|
||||||
_vm.getGameStatus().viewState = V_INTROINIT;
|
_vm->getGameStatus().viewState = V_INTROINIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
void intro_v1w::introInit() {
|
void intro_v1w::introInit() {
|
||||||
|
|
|
@ -39,7 +39,7 @@
|
||||||
|
|
||||||
namespace Hugo {
|
namespace Hugo {
|
||||||
|
|
||||||
intro_v2d::intro_v2d(HugoEngine &vm) : IntroHandler(vm) {
|
intro_v2d::intro_v2d(HugoEngine *vm) : IntroHandler(vm) {
|
||||||
}
|
}
|
||||||
|
|
||||||
intro_v2d::~intro_v2d() {
|
intro_v2d::~intro_v2d() {
|
||||||
|
@ -49,8 +49,8 @@ void intro_v2d::preNewGame() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void intro_v2d::introInit() {
|
void intro_v2d::introInit() {
|
||||||
_vm.screen().loadFont(0);
|
_vm->_screen->loadFont(0);
|
||||||
_vm.file().readBackground(_vm._numScreens - 1); // display splash screen
|
_vm->_file->readBackground(_vm->_numScreens - 1); // display splash screen
|
||||||
|
|
||||||
char buffer[128];
|
char buffer[128];
|
||||||
|
|
||||||
|
@ -58,14 +58,14 @@ void intro_v2d::introInit() {
|
||||||
sprintf(buffer, "%s Registered Version", COPYRIGHT);
|
sprintf(buffer, "%s Registered Version", COPYRIGHT);
|
||||||
else
|
else
|
||||||
sprintf(buffer, "%s Shareware Version", COPYRIGHT);
|
sprintf(buffer, "%s Shareware Version", COPYRIGHT);
|
||||||
_vm.screen().writeStr(CENTER, 186, buffer, _TLIGHTRED);
|
_vm->_screen->writeStr(CENTER, 186, buffer, _TLIGHTRED);
|
||||||
|
|
||||||
if (scumm_stricmp(_boot.distrib, "David P. Gray")) {
|
if (scumm_stricmp(_boot.distrib, "David P. Gray")) {
|
||||||
sprintf(buffer, "Distributed by %s.", _boot.distrib);
|
sprintf(buffer, "Distributed by %s.", _boot.distrib);
|
||||||
_vm.screen().writeStr(CENTER, 1, buffer, _TLIGHTRED);
|
_vm->_screen->writeStr(CENTER, 1, buffer, _TLIGHTRED);
|
||||||
}
|
}
|
||||||
|
|
||||||
_vm.screen().displayBackground();
|
_vm->_screen->displayBackground();
|
||||||
g_system->updateScreen();
|
g_system->updateScreen();
|
||||||
g_system->delayMillis(5000);
|
g_system->delayMillis(5000);
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,7 +38,7 @@
|
||||||
|
|
||||||
namespace Hugo {
|
namespace Hugo {
|
||||||
|
|
||||||
intro_v2w::intro_v2w(HugoEngine &vm) : IntroHandler(vm) {
|
intro_v2w::intro_v2w(HugoEngine *vm) : IntroHandler(vm) {
|
||||||
}
|
}
|
||||||
|
|
||||||
intro_v2w::~intro_v2w() {
|
intro_v2w::~intro_v2w() {
|
||||||
|
|
|
@ -40,7 +40,7 @@
|
||||||
|
|
||||||
|
|
||||||
namespace Hugo {
|
namespace Hugo {
|
||||||
intro_v3d::intro_v3d(HugoEngine &vm) : IntroHandler(vm) {
|
intro_v3d::intro_v3d(HugoEngine *vm) : IntroHandler(vm) {
|
||||||
}
|
}
|
||||||
|
|
||||||
intro_v3d::~intro_v3d() {
|
intro_v3d::~intro_v3d() {
|
||||||
|
@ -50,8 +50,8 @@ void intro_v3d::preNewGame() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void intro_v3d::introInit() {
|
void intro_v3d::introInit() {
|
||||||
_vm.screen().loadFont(0);
|
_vm->_screen->loadFont(0);
|
||||||
_vm.file().readBackground(_vm._numScreens - 1); // display splash screen
|
_vm->_file->readBackground(_vm->_numScreens - 1); // display splash screen
|
||||||
|
|
||||||
char buffer[128];
|
char buffer[128];
|
||||||
if (_boot.registered)
|
if (_boot.registered)
|
||||||
|
@ -59,43 +59,43 @@ void intro_v3d::introInit() {
|
||||||
else
|
else
|
||||||
sprintf(buffer,"%s Shareware Version", COPYRIGHT);
|
sprintf(buffer,"%s Shareware Version", COPYRIGHT);
|
||||||
|
|
||||||
_vm.screen().writeStr(CENTER, 190, buffer, _TBROWN);
|
_vm->_screen->writeStr(CENTER, 190, buffer, _TBROWN);
|
||||||
|
|
||||||
if (scumm_stricmp(_boot.distrib, "David P. Gray")) {
|
if (scumm_stricmp(_boot.distrib, "David P. Gray")) {
|
||||||
sprintf(buffer, "Distributed by %s.", _boot.distrib);
|
sprintf(buffer, "Distributed by %s.", _boot.distrib);
|
||||||
_vm.screen().writeStr(CENTER, 0, buffer, _TBROWN);
|
_vm->_screen->writeStr(CENTER, 0, buffer, _TBROWN);
|
||||||
}
|
}
|
||||||
|
|
||||||
_vm.screen().displayBackground();
|
_vm->_screen->displayBackground();
|
||||||
g_system->updateScreen();
|
g_system->updateScreen();
|
||||||
g_system->delayMillis(5000);
|
g_system->delayMillis(5000);
|
||||||
|
|
||||||
_vm.file().readBackground(22); // display screen MAP_3d
|
_vm->_file->readBackground(22); // display screen MAP_3d
|
||||||
_vm.screen().displayBackground();
|
_vm->_screen->displayBackground();
|
||||||
introTicks = 0;
|
introTicks = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool intro_v3d::introPlay() {
|
bool intro_v3d::introPlay() {
|
||||||
byte introSize = _vm.getIntroSize();
|
byte introSize = _vm->getIntroSize();
|
||||||
|
|
||||||
// Hugo 3 - Preamble screen before going into game. Draws path of Hugo's plane.
|
// Hugo 3 - Preamble screen before going into game. Draws path of Hugo's plane.
|
||||||
// Called every tick. Returns TRUE when complete
|
// Called every tick. Returns TRUE when complete
|
||||||
//TODO : Add proper check of story mode
|
//TODO : Add proper check of story mode
|
||||||
//#if STORY
|
//#if STORY
|
||||||
if (introTicks < introSize) {
|
if (introTicks < introSize) {
|
||||||
_vm.screen().writeStr(_vm._introX[introTicks], _vm._introY[introTicks] - DIBOFF_Y, "x", _TBRIGHTWHITE);
|
_vm->_screen->writeStr(_vm->_introX[introTicks], _vm->_introY[introTicks] - DIBOFF_Y, "x", _TBRIGHTWHITE);
|
||||||
_vm.screen().displayBackground();
|
_vm->_screen->displayBackground();
|
||||||
|
|
||||||
// Text boxes at various times
|
// Text boxes at various times
|
||||||
switch (introTicks) {
|
switch (introTicks) {
|
||||||
case 4:
|
case 4:
|
||||||
Utils::Box(BOX_OK, "%s", _vm._textIntro[kIntro1]);
|
Utils::Box(BOX_OK, "%s", _vm->_textIntro[kIntro1]);
|
||||||
break;
|
break;
|
||||||
case 9:
|
case 9:
|
||||||
Utils::Box(BOX_OK, "%s", _vm._textIntro[kIntro2]);
|
Utils::Box(BOX_OK, "%s", _vm->_textIntro[kIntro2]);
|
||||||
break;
|
break;
|
||||||
case 35:
|
case 35:
|
||||||
Utils::Box(BOX_OK, "%s", _vm._textIntro[kIntro3]);
|
Utils::Box(BOX_OK, "%s", _vm->_textIntro[kIntro3]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,7 +40,7 @@
|
||||||
|
|
||||||
namespace Hugo {
|
namespace Hugo {
|
||||||
|
|
||||||
intro_v3w::intro_v3w(HugoEngine &vm) : IntroHandler(vm) {
|
intro_v3w::intro_v3w(HugoEngine *vm) : IntroHandler(vm) {
|
||||||
}
|
}
|
||||||
|
|
||||||
intro_v3w::~intro_v3w() {
|
intro_v3w::~intro_v3w() {
|
||||||
|
@ -52,15 +52,15 @@ void intro_v3w::preNewGame() {
|
||||||
void intro_v3w::introInit() {
|
void intro_v3w::introInit() {
|
||||||
// Hugo 3 - show map and set up for introPlay()
|
// Hugo 3 - show map and set up for introPlay()
|
||||||
//#if STORY
|
//#if STORY
|
||||||
_vm.file().readBackground(22); // display screen MAP_3w
|
_vm->_file->readBackground(22); // display screen MAP_3w
|
||||||
_vm.screen().displayBackground();
|
_vm->_screen->displayBackground();
|
||||||
introTicks = 0;
|
introTicks = 0;
|
||||||
_vm.screen().loadFont(0);
|
_vm->_screen->loadFont(0);
|
||||||
//#endif
|
//#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
bool intro_v3w::introPlay() {
|
bool intro_v3w::introPlay() {
|
||||||
byte introSize = _vm.getIntroSize();
|
byte introSize = _vm->getIntroSize();
|
||||||
|
|
||||||
// Hugo 3 - Preamble screen before going into game. Draws path of Hugo's plane.
|
// Hugo 3 - Preamble screen before going into game. Draws path of Hugo's plane.
|
||||||
// Called every tick. Returns TRUE when complete
|
// Called every tick. Returns TRUE when complete
|
||||||
|
@ -68,20 +68,20 @@ bool intro_v3w::introPlay() {
|
||||||
//#if STORY
|
//#if STORY
|
||||||
if (introTicks < introSize) {
|
if (introTicks < introSize) {
|
||||||
// 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] - DIBOFF_Y, "x", _TBRIGHTWHITE);
|
_vm->_screen->writeStr(_vm->_introX[introTicks], _vm->_introY[introTicks] - DIBOFF_Y, "x", _TBRIGHTWHITE);
|
||||||
_vm.screen().displayBackground();
|
_vm->_screen->displayBackground();
|
||||||
|
|
||||||
|
|
||||||
// Text boxes at various times
|
// Text boxes at various times
|
||||||
switch (introTicks) {
|
switch (introTicks) {
|
||||||
case 4:
|
case 4:
|
||||||
Utils::Box(BOX_OK, "%s", _vm._textIntro[kIntro1]);
|
Utils::Box(BOX_OK, "%s", _vm->_textIntro[kIntro1]);
|
||||||
break;
|
break;
|
||||||
case 9:
|
case 9:
|
||||||
Utils::Box(BOX_OK, "%s", _vm._textIntro[kIntro2]);
|
Utils::Box(BOX_OK, "%s", _vm->_textIntro[kIntro2]);
|
||||||
break;
|
break;
|
||||||
case 35:
|
case 35:
|
||||||
Utils::Box(BOX_OK, "%s", _vm._textIntro[kIntro3]);
|
Utils::Box(BOX_OK, "%s", _vm->_textIntro[kIntro3]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,12 +40,13 @@
|
||||||
#include "hugo/mouse.h"
|
#include "hugo/mouse.h"
|
||||||
#include "hugo/inventory.h"
|
#include "hugo/inventory.h"
|
||||||
#include "hugo/parser.h"
|
#include "hugo/parser.h"
|
||||||
|
#include "hugo/object.h"
|
||||||
|
|
||||||
namespace Hugo {
|
namespace Hugo {
|
||||||
|
|
||||||
#define MAX_DISP (XPIX / INV_DX) // Max icons displayable
|
#define MAX_DISP (XPIX / INV_DX) // Max icons displayable
|
||||||
|
|
||||||
InventoryHandler::InventoryHandler(HugoEngine &vm) : _vm(vm) {
|
InventoryHandler::InventoryHandler(HugoEngine *vm) : _vm(vm) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Construct the inventory scrollbar in dib_i
|
// Construct the inventory scrollbar in dib_i
|
||||||
|
@ -57,12 +58,12 @@ void InventoryHandler::constructInventory(int16 imageTotNumb, int displayNumb, b
|
||||||
debugC(1, kDebugInventory, "constructInventory(%d, %d, %d, %d)", imageTotNumb, displayNumb, (scrollFl) ? 0 : 1, firstObjId);
|
debugC(1, kDebugInventory, "constructInventory(%d, %d, %d, %d)", imageTotNumb, displayNumb, (scrollFl) ? 0 : 1, firstObjId);
|
||||||
|
|
||||||
// Clear out icon buffer
|
// Clear out icon buffer
|
||||||
memset(_vm.screen().getIconBuffer(), 0, sizeof(_vm.screen().getIconBuffer()));
|
memset(_vm->_screen->getIconBuffer(), 0, sizeof(_vm->_screen->getIconBuffer()));
|
||||||
|
|
||||||
// If needed, copy arrows - reduce number of icons displayable
|
// If needed, copy arrows - reduce number of icons displayable
|
||||||
if (scrollFl) { // Display at first and last icon positions
|
if (scrollFl) { // Display at first and last icon positions
|
||||||
_vm.screen().moveImage(_vm.screen().getGUIBuffer(), 0, 0, INV_DX, INV_DY, XPIX, _vm.screen().getIconBuffer(), 0, 0, XPIX);
|
_vm->_screen->moveImage(_vm->_screen->getGUIBuffer(), 0, 0, INV_DX, INV_DY, XPIX, _vm->_screen->getIconBuffer(), 0, 0, XPIX);
|
||||||
_vm.screen().moveImage(_vm.screen().getGUIBuffer(), INV_DX, 0, INV_DX, INV_DY, XPIX, _vm.screen().getIconBuffer(), INV_DX *(MAX_DISP - 1), 0, XPIX);
|
_vm->_screen->moveImage(_vm->_screen->getGUIBuffer(), INV_DX, 0, INV_DX, INV_DY, XPIX, _vm->_screen->getIconBuffer(), INV_DX *(MAX_DISP - 1), 0, XPIX);
|
||||||
displayNumb = MIN(displayNumb, MAX_DISP - NUM_ARROWS);
|
displayNumb = MIN(displayNumb, MAX_DISP - NUM_ARROWS);
|
||||||
} else // No, override first index - we can show 'em all!
|
} else // No, override first index - we can show 'em all!
|
||||||
firstObjId = 0;
|
firstObjId = 0;
|
||||||
|
@ -71,7 +72,7 @@ void InventoryHandler::constructInventory(int16 imageTotNumb, int displayNumb, b
|
||||||
int16 displayed = 0;
|
int16 displayed = 0;
|
||||||
int16 carried = 0;
|
int16 carried = 0;
|
||||||
for (int16 i = 0; i < imageTotNumb; i++) {
|
for (int16 i = 0; i < imageTotNumb; i++) {
|
||||||
if (_vm._objects[_vm._invent[i]].carriedFl) {
|
if (_vm->_object->isCarried(_vm->_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
|
||||||
|
@ -83,7 +84,7 @@ void InventoryHandler::constructInventory(int16 imageTotNumb, int displayNumb, b
|
||||||
displayed++; // Count number displayed
|
displayed++; // Count number displayed
|
||||||
|
|
||||||
// Copy the icon
|
// Copy the icon
|
||||||
_vm.screen().moveImage(_vm.screen().getGUIBuffer(), ux, uy, INV_DX, INV_DY, XPIX, _vm.screen().getIconBuffer(), ix, 0, XPIX);
|
_vm->_screen->moveImage(_vm->_screen->getGUIBuffer(), ux, uy, INV_DX, INV_DY, XPIX, _vm->_screen->getIconBuffer(), ix, 0, XPIX);
|
||||||
}
|
}
|
||||||
carried++; // Count number carried
|
carried++; // Count number carried
|
||||||
}
|
}
|
||||||
|
@ -100,8 +101,8 @@ int16 InventoryHandler::processInventory(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 < _vm->_maxInvent && _vm->_invent[imageNumb] != -1; imageNumb++) {
|
||||||
if (_vm._objects[_vm._invent[imageNumb]].carriedFl)
|
if (_vm->_object->isCarried(_vm->_invent[imageNumb]))
|
||||||
displayNumb++;
|
displayNumb++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -148,8 +149,8 @@ int16 InventoryHandler::processInventory(invact_t action, ...) {
|
||||||
if (objId == -1 && i < displayNumb) {
|
if (objId == -1 && i < displayNumb) {
|
||||||
// Find objid by counting # carried objects == i+1
|
// Find objid by counting # carried objects == i+1
|
||||||
int16 j;
|
int16 j;
|
||||||
for (j = 0, i++; i > 0 && j < _vm._numObj; j++) {
|
for (j = 0, i++; i > 0 && j < _vm->_numObj; j++) {
|
||||||
if (_vm._objects[j].carriedFl) {
|
if (_vm->_object->isCarried(j)) {
|
||||||
if (--i == 0)
|
if (--i == 0)
|
||||||
objId = j;
|
objId = j;
|
||||||
}
|
}
|
||||||
|
@ -162,7 +163,7 @@ int16 InventoryHandler::processInventory(invact_t action, ...) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void InventoryHandler::runInventory() {
|
void InventoryHandler::runInventory() {
|
||||||
status_t &gameStatus = _vm.getGameStatus();
|
status_t &gameStatus = _vm->getGameStatus();
|
||||||
|
|
||||||
debugC(1, kDebugInventory, "runInventory");
|
debugC(1, kDebugInventory, "runInventory");
|
||||||
|
|
||||||
|
@ -176,15 +177,15 @@ void InventoryHandler::runInventory() {
|
||||||
gameStatus.inventoryHeight = 0;
|
gameStatus.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, XPIX, gameStatus.inventoryHeight, XPIX, _vm.screen().getFrontBuffer(), 0, DIBOFF_Y, XPIX);
|
_vm->_screen->moveImage(_vm->_screen->getIconBuffer(), 0, 0, XPIX, gameStatus.inventoryHeight, XPIX, _vm->_screen->getFrontBuffer(), 0, DIBOFF_Y, XPIX);
|
||||||
_vm.screen().moveImage(_vm.screen().getBackBufferBackup(), 0, gameStatus.inventoryHeight + DIBOFF_Y, XPIX, STEP_DY, XPIX, _vm.screen().getFrontBuffer(), 0, gameStatus.inventoryHeight + DIBOFF_Y, XPIX);
|
_vm->_screen->moveImage(_vm->_screen->getBackBufferBackup(), 0, gameStatus.inventoryHeight + DIBOFF_Y, XPIX, STEP_DY, XPIX, _vm->_screen->getFrontBuffer(), 0, gameStatus.inventoryHeight + DIBOFF_Y, XPIX);
|
||||||
_vm.screen().displayRect(0, DIBOFF_Y, XPIX, gameStatus.inventoryHeight + STEP_DY);
|
_vm->_screen->displayRect(0, DIBOFF_Y, XPIX, gameStatus.inventoryHeight + STEP_DY);
|
||||||
|
|
||||||
if (gameStatus.inventoryHeight == 0) { // Finished moving up?
|
if (gameStatus.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, XPIX, YPIX, XPIX, _vm.screen().getBackBuffer(), 0, 0, XPIX);
|
_vm->_screen->moveImage(_vm->_screen->getBackBufferBackup(), 0, 0, XPIX, YPIX, XPIX, _vm->_screen->getBackBuffer(), 0, 0, XPIX);
|
||||||
_vm.screen().moveImage(_vm.screen().getBackBuffer(), 0, 0, XPIX, YPIX, XPIX, _vm.screen().getFrontBuffer(), 0, 0, XPIX);
|
_vm->_screen->moveImage(_vm->_screen->getBackBuffer(), 0, 0, XPIX, YPIX, XPIX, _vm->_screen->getFrontBuffer(), 0, 0, XPIX);
|
||||||
_vm.updateImages(); // Add objects back into display list for restore
|
_vm->_object->updateImages(); // Add objects back into display list for restore
|
||||||
gameStatus.inventoryState = I_OFF;
|
gameStatus.inventoryState = I_OFF;
|
||||||
gameStatus.viewState = V_PLAY;
|
gameStatus.viewState = V_PLAY;
|
||||||
}
|
}
|
||||||
|
@ -194,9 +195,9 @@ void InventoryHandler::runInventory() {
|
||||||
// and get any icon/text out of _frontBuffer
|
// and get any icon/text out of _frontBuffer
|
||||||
if (gameStatus.inventoryHeight == 0) {
|
if (gameStatus.inventoryHeight == 0) {
|
||||||
processInventory(INV_INIT); // Initialize dib_i
|
processInventory(INV_INIT); // Initialize dib_i
|
||||||
_vm.screen().displayList(D_RESTORE); // Restore _frontBuffer
|
_vm->_screen->displayList(D_RESTORE); // Restore _frontBuffer
|
||||||
_vm.updateImages(); // Rebuild _frontBuffer without icons/text
|
_vm->_object->updateImages(); // Rebuild _frontBuffer without icons/text
|
||||||
_vm.screen().displayList(D_DISPLAY); // Blit display list to screen
|
_vm->_screen->displayList(D_DISPLAY); // Blit display list to screen
|
||||||
}
|
}
|
||||||
|
|
||||||
gameStatus.inventoryHeight += STEP_DY; // Move the icon bar down
|
gameStatus.inventoryHeight += STEP_DY; // Move the icon bar down
|
||||||
|
@ -204,8 +205,8 @@ void InventoryHandler::runInventory() {
|
||||||
gameStatus.inventoryHeight = INV_DY;
|
gameStatus.inventoryHeight = INV_DY;
|
||||||
|
|
||||||
// Move visible portion to _frontBuffer, display results
|
// Move visible portion to _frontBuffer, display results
|
||||||
_vm.screen().moveImage(_vm.screen().getIconBuffer(), 0, 0, XPIX, gameStatus.inventoryHeight, XPIX, _vm.screen().getFrontBuffer(), 0, DIBOFF_Y, XPIX);
|
_vm->_screen->moveImage(_vm->_screen->getIconBuffer(), 0, 0, XPIX, gameStatus.inventoryHeight, XPIX, _vm->_screen->getFrontBuffer(), 0, DIBOFF_Y, XPIX);
|
||||||
_vm.screen().displayRect(0, DIBOFF_Y, XPIX, gameStatus.inventoryHeight);
|
_vm->_screen->displayRect(0, DIBOFF_Y, XPIX, gameStatus.inventoryHeight);
|
||||||
|
|
||||||
if (gameStatus.inventoryHeight == INV_DY) { // Finished moving down?
|
if (gameStatus.inventoryHeight == INV_DY) { // Finished moving down?
|
||||||
// Yes, prepare view dibs for special inventory display since
|
// Yes, prepare view dibs for special inventory display since
|
||||||
|
@ -213,17 +214,17 @@ void InventoryHandler::runInventory() {
|
||||||
// 1. Save backing store _backBuffer in temporary dib_c
|
// 1. Save backing store _backBuffer in temporary dib_c
|
||||||
// 2. Make snapshot of _frontBuffer the new _backBuffer backing store
|
// 2. Make snapshot of _frontBuffer the new _backBuffer backing store
|
||||||
// 3. Reset the display list
|
// 3. Reset the display list
|
||||||
_vm.screen().moveImage(_vm.screen().getBackBuffer(), 0, 0, XPIX, YPIX, XPIX, _vm.screen().getBackBufferBackup(), 0, 0, XPIX);
|
_vm->_screen->moveImage(_vm->_screen->getBackBuffer(), 0, 0, XPIX, YPIX, XPIX, _vm->_screen->getBackBufferBackup(), 0, 0, XPIX);
|
||||||
_vm.screen().moveImage(_vm.screen().getFrontBuffer(), 0, 0, XPIX, YPIX, XPIX, _vm.screen().getBackBuffer(), 0, 0, XPIX);
|
_vm->_screen->moveImage(_vm->_screen->getFrontBuffer(), 0, 0, XPIX, YPIX, XPIX, _vm->_screen->getBackBuffer(), 0, 0, XPIX);
|
||||||
_vm.screen().displayList(D_INIT);
|
_vm->_screen->displayList(D_INIT);
|
||||||
gameStatus.inventoryState = I_ACTIVE;
|
gameStatus.inventoryState = I_ACTIVE;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case I_ACTIVE: // Inventory active
|
case I_ACTIVE: // Inventory active
|
||||||
_vm.parser().charHandler(); // Still allow commands
|
_vm->_parser->charHandler(); // Still allow commands
|
||||||
_vm.screen().displayList(D_RESTORE); // Restore previous background
|
_vm->_screen->displayList(D_RESTORE); // Restore previous background
|
||||||
_vm.mouse().mouseHandler(); // Mouse activity - adds to display list
|
_vm->_mouse->mouseHandler(); // Mouse activity - adds to display list
|
||||||
_vm.screen().displayList(D_DISPLAY); // Blit the display list to screen
|
_vm->_screen->displayList(D_DISPLAY); // Blit the display list to screen
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,13 +40,13 @@ namespace Hugo {
|
||||||
|
|
||||||
class InventoryHandler {
|
class InventoryHandler {
|
||||||
public:
|
public:
|
||||||
InventoryHandler(HugoEngine &vm);
|
InventoryHandler(HugoEngine *vm);
|
||||||
|
|
||||||
int16 processInventory(invact_t action, ...);
|
int16 processInventory(invact_t action, ...);
|
||||||
void runInventory();
|
void runInventory();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
HugoEngine &_vm;
|
HugoEngine *_vm;
|
||||||
|
|
||||||
void constructInventory(int16 imageTotNumb, int displayNumb, bool scrollFl, int16 firstObjId);
|
void constructInventory(int16 imageTotNumb, int displayNumb, bool scrollFl, int16 firstObjId);
|
||||||
};
|
};
|
||||||
|
|
|
@ -20,6 +20,7 @@ MODULE_OBJS := \
|
||||||
intro_v3w.o \
|
intro_v3w.o \
|
||||||
inventory.o \
|
inventory.o \
|
||||||
mouse.o \
|
mouse.o \
|
||||||
|
object.o \
|
||||||
parser.o \
|
parser.o \
|
||||||
parser_v1w.o \
|
parser_v1w.o \
|
||||||
parser_v1d.o \
|
parser_v1d.o \
|
||||||
|
|
|
@ -43,6 +43,7 @@
|
||||||
#include "hugo/inventory.h"
|
#include "hugo/inventory.h"
|
||||||
#include "hugo/route.h"
|
#include "hugo/route.h"
|
||||||
#include "hugo/util.h"
|
#include "hugo/util.h"
|
||||||
|
#include "hugo/object.h"
|
||||||
|
|
||||||
namespace Hugo {
|
namespace Hugo {
|
||||||
|
|
||||||
|
@ -59,24 +60,24 @@ enum seqTextMouse {
|
||||||
kMsExit = 1
|
kMsExit = 1
|
||||||
};
|
};
|
||||||
|
|
||||||
MouseHandler::MouseHandler(HugoEngine &vm) : _vm(vm) {
|
MouseHandler::MouseHandler(HugoEngine *vm) : _vm(vm) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Shadow-blit supplied string into dib_a at cx,cy and add to display list
|
// Shadow-blit supplied string into dib_a at cx,cy and add to display list
|
||||||
void MouseHandler::cursorText(char *buffer, int16 cx, int16 cy, uif_t fontId, int16 color) {
|
void MouseHandler::cursorText(char *buffer, int16 cx, int16 cy, uif_t fontId, int16 color) {
|
||||||
debugC(1, kDebugMouse, "cursorText(%s, %d, %d, %d, %d)", buffer, cx, cy, fontId, color);
|
debugC(1, kDebugMouse, "cursorText(%s, %d, %d, %d, %d)", buffer, cx, cy, fontId, color);
|
||||||
|
|
||||||
_vm.screen().loadFont(fontId);
|
_vm->_screen->loadFont(fontId);
|
||||||
|
|
||||||
// Find bounding rect for string
|
// Find bounding rect for string
|
||||||
int16 sdx = _vm.screen().stringLength(buffer);
|
int16 sdx = _vm->_screen->stringLength(buffer);
|
||||||
int16 sdy = _vm.screen().fontHeight() + 1; // + 1 for shadow
|
int16 sdy = _vm->_screen->fontHeight() + 1; // + 1 for shadow
|
||||||
int16 sx = (cx < XPIX / 2) ? cx + SX_OFF : cx - sdx - SX_OFF / 2;
|
int16 sx = (cx < XPIX / 2) ? cx + SX_OFF : cx - sdx - SX_OFF / 2;
|
||||||
int16 sy = cy + SY_OFF;
|
int16 sy = cy + SY_OFF;
|
||||||
|
|
||||||
// Display the string and add rect to display list
|
// Display the string and add rect to display list
|
||||||
_vm.screen().shadowStr(sx, sy, buffer, _TBRIGHTWHITE);
|
_vm->_screen->shadowStr(sx, sy, buffer, _TBRIGHTWHITE);
|
||||||
_vm.screen().displayList(D_ADD, sx, sy, sdx, sdy);
|
_vm->_screen->displayList(D_ADD, sx, sy, sdx, sdy);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find the exit hotspot containing cx, cy.
|
// Find the exit hotspot containing cx, cy.
|
||||||
|
@ -85,8 +86,8 @@ int16 MouseHandler::findExit(int16 cx, int16 cy) {
|
||||||
debugC(2, kDebugMouse, "findExit(%d, %d)", cx, cy);
|
debugC(2, kDebugMouse, "findExit(%d, %d)", cx, cy);
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (hotspot_t *hotspot = _vm._hotspots; hotspot->screenIndex >= 0; i++, hotspot++) {
|
for (hotspot_t *hotspot = _vm->_hotspots; hotspot->screenIndex >= 0; i++, hotspot++) {
|
||||||
if (hotspot->screenIndex == *_vm._screen_p) {
|
if (hotspot->screenIndex == *_vm->_screen_p) {
|
||||||
if (cx >= hotspot->x1 && cx <= hotspot->x2 && cy >= hotspot->y1 && cy <= hotspot->y2)
|
if (cx >= hotspot->x1 && cx <= hotspot->x2 && cy >= hotspot->y1 && cy <= hotspot->y2)
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
@ -98,9 +99,9 @@ int16 MouseHandler::findExit(int16 cx, int16 cy) {
|
||||||
void MouseHandler::processRightClick(int16 objId, int16 cx, int16 cy) {
|
void MouseHandler::processRightClick(int16 objId, int16 cx, int16 cy) {
|
||||||
debugC(1, kDebugMouse, "Process_rclick(%d, %d, %d)", objId, cx, cy);
|
debugC(1, kDebugMouse, "Process_rclick(%d, %d, %d)", objId, cx, cy);
|
||||||
|
|
||||||
status_t &gameStatus = _vm.getGameStatus();
|
status_t &gameStatus = _vm->getGameStatus();
|
||||||
|
|
||||||
if (gameStatus.storyModeFl || _vm._hero->pathType == QUIET) // Make sure user has control
|
if (gameStatus.storyModeFl || _vm->_hero->pathType == QUIET) // Make sure user has control
|
||||||
return;
|
return;
|
||||||
|
|
||||||
bool foundFl = false; // TRUE if route found to object
|
bool foundFl = false; // TRUE if route found to object
|
||||||
|
@ -111,26 +112,26 @@ void MouseHandler::processRightClick(int16 objId, int16 cx, int16 cy) {
|
||||||
else if (gameStatus.inventoryObjId == objId)
|
else if (gameStatus.inventoryObjId == objId)
|
||||||
gameStatus.inventoryObjId = -1; // Same icon - deselect it
|
gameStatus.inventoryObjId = -1; // Same icon - deselect it
|
||||||
else
|
else
|
||||||
_vm.useObject(objId); // Use status.objid on object
|
_vm->_object->useObject(objId); // Use status.objid on object
|
||||||
} else { // Clicked over viewport object
|
} else { // Clicked over viewport object
|
||||||
object_t *obj = &_vm._objects[objId];
|
object_t *obj = &_vm->_object->_objects[objId];
|
||||||
int16 x, y;
|
int16 x, y;
|
||||||
switch (obj->viewx) { // Where to walk to
|
switch (obj->viewx) { // Where to walk to
|
||||||
case -1: // Walk to object position
|
case -1: // Walk to object position
|
||||||
if (_vm.findObjectSpace(obj, &x, &y))
|
if (_vm->findObjectSpace(obj, &x, &y))
|
||||||
foundFl = _vm.route().startRoute(GO_GET, objId, x, y);
|
foundFl = _vm->_route->startRoute(GO_GET, objId, x, y);
|
||||||
if (!foundFl) // Can't get there, try to use from here
|
if (!foundFl) // Can't get there, try to use from here
|
||||||
_vm.useObject(objId);
|
_vm->_object->useObject(objId);
|
||||||
break;
|
break;
|
||||||
case 0: // Immediate use
|
case 0: // Immediate use
|
||||||
_vm.useObject(objId); // Pick up or use object
|
_vm->_object->useObject(objId); // Pick up or use object
|
||||||
break;
|
break;
|
||||||
default: // Walk to view point if possible
|
default: // Walk to view point if possible
|
||||||
if (!_vm.route().startRoute(GO_GET, objId, obj->viewx, obj->viewy)) {
|
if (!_vm->_route->startRoute(GO_GET, objId, obj->viewx, obj->viewy)) {
|
||||||
if (_vm._hero->cycling == INVISIBLE)// If invisible do
|
if (_vm->_hero->cycling == INVISIBLE)// If invisible do
|
||||||
_vm.useObject(objId); // immediate use
|
_vm->_object->useObject(objId); // immediate use
|
||||||
else
|
else
|
||||||
Utils::Box(BOX_ANY, "%s", _vm._textMouse[kMsNoWayText]); // Can't get there
|
Utils::Box(BOX_ANY, "%s", _vm->_textMouse[kMsNoWayText]); // Can't get there
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -149,41 +150,41 @@ void MouseHandler::processLeftClick(int16 objId, int16 cx, int16 cy) {
|
||||||
int16 i, x, y;
|
int16 i, x, y;
|
||||||
object_t *obj;
|
object_t *obj;
|
||||||
|
|
||||||
status_t &gameStatus = _vm.getGameStatus();
|
status_t &gameStatus = _vm->getGameStatus();
|
||||||
|
|
||||||
if (gameStatus.storyModeFl || _vm._hero->pathType == QUIET) // Make sure user has control
|
if (gameStatus.storyModeFl || _vm->_hero->pathType == QUIET) // Make sure user has control
|
||||||
return;
|
return;
|
||||||
|
|
||||||
switch (objId) {
|
switch (objId) {
|
||||||
case -1: // Empty space - attempt to walk there
|
case -1: // Empty space - attempt to walk there
|
||||||
_vm.route().startRoute(GO_SPACE, 0, cx, cy);
|
_vm->_route->startRoute(GO_SPACE, 0, cx, cy);
|
||||||
break;
|
break;
|
||||||
case LEFT_ARROW: // A scroll arrow - scroll the iconbar
|
case LEFT_ARROW: // A scroll arrow - scroll the iconbar
|
||||||
case RIGHT_ARROW:
|
case RIGHT_ARROW:
|
||||||
// Scroll the iconbar and display results
|
// Scroll the iconbar and display results
|
||||||
_vm.inventory().processInventory((objId == LEFT_ARROW) ? INV_LEFT : INV_RIGHT);
|
_vm->_inventory->processInventory((objId == LEFT_ARROW) ? INV_LEFT : INV_RIGHT);
|
||||||
_vm.screen().moveImage(_vm.screen().getIconBuffer(), 0, 0, XPIX, INV_DY, XPIX, _vm.screen().getFrontBuffer(), 0, DIBOFF_Y, XPIX);
|
_vm->_screen->moveImage(_vm->_screen->getIconBuffer(), 0, 0, XPIX, INV_DY, XPIX, _vm->_screen->getFrontBuffer(), 0, DIBOFF_Y, XPIX);
|
||||||
_vm.screen().moveImage(_vm.screen().getIconBuffer(), 0, 0, XPIX, INV_DY, XPIX, _vm.screen().getBackBuffer(), 0, DIBOFF_Y, XPIX);
|
_vm->_screen->moveImage(_vm->_screen->getIconBuffer(), 0, 0, XPIX, INV_DY, XPIX, _vm->_screen->getBackBuffer(), 0, DIBOFF_Y, XPIX);
|
||||||
_vm.screen().displayList(D_ADD, 0, DIBOFF_Y, XPIX, INV_DY);
|
_vm->_screen->displayList(D_ADD, 0, DIBOFF_Y, XPIX, INV_DY);
|
||||||
break;
|
break;
|
||||||
case EXIT_HOTSPOT: // Walk to exit hotspot
|
case EXIT_HOTSPOT: // Walk to exit hotspot
|
||||||
i = findExit(cx, cy);
|
i = findExit(cx, cy);
|
||||||
x = _vm._hotspots[i].viewx;
|
x = _vm->_hotspots[i].viewx;
|
||||||
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 (gameStatus.jumpExitFl) {
|
||||||
// Get rid of iconbar if necessary
|
// Get rid of iconbar if necessary
|
||||||
if (gameStatus.inventoryState != I_OFF)
|
if (gameStatus.inventoryState != I_OFF)
|
||||||
gameStatus.inventoryState = I_UP;
|
gameStatus.inventoryState = I_UP;
|
||||||
_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)
|
||||||
x -= HERO_MAX_WIDTH;
|
x -= HERO_MAX_WIDTH;
|
||||||
else if (_vm._hotspots[i].direction == Common::KEYCODE_LEFT)
|
else if (_vm->_hotspots[i].direction == Common::KEYCODE_LEFT)
|
||||||
x += HERO_MAX_WIDTH;
|
x += HERO_MAX_WIDTH;
|
||||||
if (!_vm.route().startRoute(GO_EXIT, i, x, y))
|
if (!_vm->_route->startRoute(GO_EXIT, i, x, y))
|
||||||
Utils::Box(BOX_ANY, "%s", _vm._textMouse[kMsNoWayText]); // Can't get there
|
Utils::Box(BOX_ANY, "%s", _vm->_textMouse[kMsNoWayText]); // Can't get there
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get rid of any attached icon
|
// Get rid of any attached icon
|
||||||
|
@ -191,29 +192,29 @@ void MouseHandler::processLeftClick(int16 objId, int16 cx, int16 cy) {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default: // Look at an icon or object
|
default: // Look at an icon or object
|
||||||
obj = &_vm._objects[objId];
|
obj = &_vm->_object->_objects[objId];
|
||||||
|
|
||||||
// Over iconbar - immediate description
|
// Over iconbar - immediate description
|
||||||
if (gameStatus.inventoryState == I_ACTIVE && cy < INV_DY + DIBOFF_Y)
|
if (gameStatus.inventoryState == I_ACTIVE && cy < INV_DY + DIBOFF_Y)
|
||||||
_vm.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
|
||||||
switch (obj->viewx) { // Clicked over viewport object
|
switch (obj->viewx) { // Clicked over viewport object
|
||||||
case -1: // Walk to object position
|
case -1: // Walk to object position
|
||||||
if (_vm.findObjectSpace(obj, &x, &y))
|
if (_vm->findObjectSpace(obj, &x, &y))
|
||||||
foundFl = _vm.route().startRoute(GO_LOOK, objId, x, y);
|
foundFl = _vm->_route->startRoute(GO_LOOK, objId, x, y);
|
||||||
if (!foundFl) // Can't get there, immediate description
|
if (!foundFl) // Can't get there, immediate description
|
||||||
_vm.lookObject(obj);
|
_vm->_object->lookObject(obj);
|
||||||
break;
|
break;
|
||||||
case 0: // Immediate description
|
case 0: // Immediate description
|
||||||
_vm.lookObject(obj);
|
_vm->_object->lookObject(obj);
|
||||||
break;
|
break;
|
||||||
default: // Walk to view point if possible
|
default: // Walk to view point if possible
|
||||||
if (!_vm.route().startRoute(GO_LOOK, objId, obj->viewx, obj->viewy)) {
|
if (!_vm->_route->startRoute(GO_LOOK, objId, obj->viewx, obj->viewy)) {
|
||||||
if (_vm._hero->cycling == INVISIBLE) // If invisible do
|
if (_vm->_hero->cycling == INVISIBLE) // If invisible do
|
||||||
_vm.lookObject(obj); // immediate decription
|
_vm->_object->lookObject(obj); // immediate decription
|
||||||
else
|
else
|
||||||
Utils::Box(BOX_ANY, "%s", _vm._textMouse[kMsNoWayText]); // Can't get there
|
Utils::Box(BOX_ANY, "%s", _vm->_textMouse[kMsNoWayText]); // Can't get there
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -226,10 +227,10 @@ void MouseHandler::processLeftClick(int16 objId, int16 cx, int16 cy) {
|
||||||
void MouseHandler::mouseHandler() {
|
void MouseHandler::mouseHandler() {
|
||||||
debugC(2, kDebugMouse, "mouseHandler");
|
debugC(2, kDebugMouse, "mouseHandler");
|
||||||
|
|
||||||
int16 cx = _vm.getMouseX();
|
int16 cx = _vm->getMouseX();
|
||||||
int16 cy = _vm.getMouseY();
|
int16 cy = _vm->getMouseY();
|
||||||
|
|
||||||
status_t &gameStatus = _vm.getGameStatus();
|
status_t &gameStatus = _vm->getGameStatus();
|
||||||
|
|
||||||
gameStatus.cx = cx; // Save cursor coords
|
gameStatus.cx = cx; // Save cursor coords
|
||||||
gameStatus.cy = cy;
|
gameStatus.cy = cy;
|
||||||
|
@ -242,8 +243,8 @@ void MouseHandler::mouseHandler() {
|
||||||
if (gameStatus.inventoryObjId != -1) {
|
if (gameStatus.inventoryObjId != -1) {
|
||||||
// Find index of icon
|
// Find index of icon
|
||||||
int16 iconId; // Find index of dragged icon
|
int16 iconId; // Find index of dragged icon
|
||||||
for (iconId = 0; iconId < _vm._maxInvent; iconId++) {
|
for (iconId = 0; iconId < _vm->_maxInvent; iconId++) {
|
||||||
if (gameStatus.inventoryObjId == _vm._invent[iconId])
|
if (gameStatus.inventoryObjId == _vm->_invent[iconId])
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -260,20 +261,20 @@ void MouseHandler::mouseHandler() {
|
||||||
icony = MIN(icony, YPIX - INV_DY);
|
icony = MIN(icony, YPIX - INV_DY);
|
||||||
|
|
||||||
// Copy the icon and add to display list
|
// Copy the icon and add to display list
|
||||||
_vm.screen().moveImage(_vm.screen().getGUIBuffer(), ux, uy, INV_DX, INV_DY, XPIX, _vm.screen().getFrontBuffer(), iconx, icony, XPIX);
|
_vm->_screen->moveImage(_vm->_screen->getGUIBuffer(), ux, uy, INV_DX, INV_DY, XPIX, _vm->_screen->getFrontBuffer(), iconx, icony, XPIX);
|
||||||
_vm.screen().displayList(D_ADD, iconx, icony, INV_DX, INV_DY);
|
_vm->_screen->displayList(D_ADD, iconx, icony, INV_DX, INV_DY);
|
||||||
}
|
}
|
||||||
|
|
||||||
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 == I_ACTIVE) // Check inventory icon bar first
|
if (gameStatus.inventoryState == I_ACTIVE) // Check inventory icon bar first
|
||||||
objId = _vm.inventory().processInventory(INV_GET, cx, cy);
|
objId = _vm->_inventory->processInventory(INV_GET, cx, cy);
|
||||||
if (objId == -1) // No match, check rest of view
|
if (objId == -1) // No match, check rest of view
|
||||||
objId = _vm.findObject(cx, cy);
|
objId = _vm->_object->findObject(cx, cy);
|
||||||
if (objId >= 0) { // Got a match
|
if (objId >= 0) { // Got a match
|
||||||
// Display object name next to cursor (unless CURSOR_NOCHAR)
|
// Display object name next to cursor (unless CURSOR_NOCHAR)
|
||||||
// Note test for swapped hero name
|
// Note test for swapped hero name
|
||||||
char *name = _vm._arrayNouns[_vm._objects[(objId == HERO) ? _vm._heroImage : objId].nounIndex][CURSOR_NAME];
|
char *name = _vm->_arrayNouns[_vm->_object->_objects[(objId == HERO) ? _vm->_heroImage : objId].nounIndex][CURSOR_NAME];
|
||||||
if (name[0] != CURSOR_NOCHAR)
|
if (name[0] != CURSOR_NOCHAR)
|
||||||
cursorText(name, cx, cy, U_FONT8, _TBRIGHTWHITE);
|
cursorText(name, cx, cy, U_FONT8, _TBRIGHTWHITE);
|
||||||
|
|
||||||
|
@ -285,9 +286,9 @@ void MouseHandler::mouseHandler() {
|
||||||
// Process cursor over an exit hotspot
|
// Process cursor over an exit hotspot
|
||||||
if (objId == -1) {
|
if (objId == -1) {
|
||||||
int i = findExit(cx, cy);
|
int i = findExit(cx, cy);
|
||||||
if (i != -1 && _vm._hotspots[i].viewx >= 0) {
|
if (i != -1 && _vm->_hotspots[i].viewx >= 0) {
|
||||||
objId = EXIT_HOTSPOT;
|
objId = EXIT_HOTSPOT;
|
||||||
cursorText(_vm._textMouse[kMsExit], cx, cy, U_FONT8, _TBRIGHTWHITE);
|
cursorText(_vm->_textMouse[kMsExit], cx, cy, U_FONT8, _TBRIGHTWHITE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,12 +36,12 @@ namespace Hugo {
|
||||||
|
|
||||||
class MouseHandler {
|
class MouseHandler {
|
||||||
public:
|
public:
|
||||||
MouseHandler(HugoEngine &vm);
|
MouseHandler(HugoEngine *vm);
|
||||||
|
|
||||||
void mouseHandler();
|
void mouseHandler();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
HugoEngine &_vm;
|
HugoEngine *_vm;
|
||||||
|
|
||||||
void cursorText(char *buffer, int16 cx, int16 cy, uif_t fontId, int16 color);
|
void cursorText(char *buffer, int16 cx, int16 cy, uif_t fontId, int16 color);
|
||||||
int16 findExit(int16 cx, int16 cy);
|
int16 findExit(int16 cx, int16 cy);
|
||||||
|
|
695
engines/hugo/object.cpp
Normal file
695
engines/hugo/object.cpp
Normal file
|
@ -0,0 +1,695 @@
|
||||||
|
/* ScummVM - Graphic Adventure Engine
|
||||||
|
*
|
||||||
|
* ScummVM is the legal property of its developers, whose names
|
||||||
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||||
|
* file distributed with this source distribution.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* $URL$
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This code is based on original Hugo Trilogy source code
|
||||||
|
*
|
||||||
|
* Copyright (c) 1989-1995 David P. Gray
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "common/system.h"
|
||||||
|
#include "common/random.h"
|
||||||
|
|
||||||
|
#include "hugo/game.h"
|
||||||
|
#include "hugo/hugo.h"
|
||||||
|
#include "hugo/object.h"
|
||||||
|
#include "hugo/global.h"
|
||||||
|
#include "hugo/display.h"
|
||||||
|
#include "hugo/file.h"
|
||||||
|
#include "hugo/route.h"
|
||||||
|
#include "hugo/util.h"
|
||||||
|
#include "hugo/parser.h"
|
||||||
|
|
||||||
|
namespace Hugo {
|
||||||
|
|
||||||
|
ObjectHandler::ObjectHandler(HugoEngine *vm) : _vm(vm) {
|
||||||
|
}
|
||||||
|
|
||||||
|
ObjectHandler::~ObjectHandler() {
|
||||||
|
}
|
||||||
|
|
||||||
|
// Draw all objects on screen as follows:
|
||||||
|
// 1. Sort 'FLOATING' objects in order of y2 (base of object)
|
||||||
|
// 2. Display new object frames/positions in dib
|
||||||
|
// Finally, cycle any animating objects to next frame
|
||||||
|
void ObjectHandler::updateImages() {
|
||||||
|
debugC(5, kDebugEngine, "updateImages");
|
||||||
|
|
||||||
|
// Initialise the index array to visible objects in current screen
|
||||||
|
int num_objs = 0;
|
||||||
|
byte objindex[MAXOBJECTS]; // Array of indeces to objects
|
||||||
|
|
||||||
|
for (int i = 0; i < _vm->_numObj; i++) {
|
||||||
|
object_t *obj = &_objects[i];
|
||||||
|
if ((obj->screenIndex == *_vm->_screen_p) && (obj->cycling >= ALMOST_INVISIBLE))
|
||||||
|
objindex[num_objs++] = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sort the objects into increasing y+y2 (painter's algorithm)
|
||||||
|
qsort(objindex, num_objs, sizeof(objindex[0]), y2comp);
|
||||||
|
|
||||||
|
// Add each visible object to display list
|
||||||
|
for (int i = 0; i < num_objs; i++) {
|
||||||
|
object_t *obj = &_objects[objindex[i]];
|
||||||
|
// Count down inter-frame timer
|
||||||
|
if (obj->frameTimer)
|
||||||
|
obj->frameTimer--;
|
||||||
|
|
||||||
|
if (obj->cycling > ALMOST_INVISIBLE) { // Only if visible
|
||||||
|
switch (obj->cycling) {
|
||||||
|
case NOT_CYCLING:
|
||||||
|
_vm->_screen->displayFrame(obj->x, obj->y, obj->currImagePtr, obj->priority == OVEROVL);
|
||||||
|
break;
|
||||||
|
case CYCLE_FORWARD:
|
||||||
|
if (obj->frameTimer) // Not time to see next frame yet
|
||||||
|
_vm->_screen->displayFrame(obj->x, obj->y, obj->currImagePtr, obj->priority == OVEROVL);
|
||||||
|
else
|
||||||
|
_vm->_screen->displayFrame(obj->x, obj->y, obj->currImagePtr->nextSeqPtr, obj->priority == OVEROVL);
|
||||||
|
break;
|
||||||
|
case CYCLE_BACKWARD: {
|
||||||
|
seq_t *seqPtr = obj->currImagePtr;
|
||||||
|
if (!obj->frameTimer) { // Show next frame
|
||||||
|
while (seqPtr->nextSeqPtr != obj->currImagePtr)
|
||||||
|
seqPtr = seqPtr->nextSeqPtr;
|
||||||
|
}
|
||||||
|
_vm->_screen->displayFrame(obj->x, obj->y, seqPtr, obj->priority == OVEROVL);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cycle any animating objects
|
||||||
|
for (int i = 0; i < num_objs; i++) {
|
||||||
|
object_t *obj = &_objects[objindex[i]];
|
||||||
|
if (obj->cycling != INVISIBLE) {
|
||||||
|
// Only if it's visible
|
||||||
|
if (obj->cycling == ALMOST_INVISIBLE)
|
||||||
|
obj->cycling = INVISIBLE;
|
||||||
|
|
||||||
|
// Now Rotate to next picture in sequence
|
||||||
|
switch (obj->cycling) {
|
||||||
|
case NOT_CYCLING:
|
||||||
|
break;
|
||||||
|
case CYCLE_FORWARD:
|
||||||
|
if (!obj->frameTimer) {
|
||||||
|
// Time to step to next frame
|
||||||
|
obj->currImagePtr = obj->currImagePtr->nextSeqPtr;
|
||||||
|
// Find out if this is last frame of sequence
|
||||||
|
// If so, reset frame_timer and decrement n_cycle
|
||||||
|
if (obj->frameInterval || obj->cycleNumb) {
|
||||||
|
obj->frameTimer = obj->frameInterval;
|
||||||
|
for (int j = 0; j < obj->seqNumb; j++) {
|
||||||
|
if (obj->currImagePtr->nextSeqPtr == obj->seqList[j].seqPtr) {
|
||||||
|
if (obj->cycleNumb) { // Decr cycleNumb if Non-continous
|
||||||
|
if (!--obj->cycleNumb)
|
||||||
|
obj->cycling = NOT_CYCLING;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case CYCLE_BACKWARD: {
|
||||||
|
if (!obj->frameTimer) {
|
||||||
|
// Time to step to prev frame
|
||||||
|
seq_t *seqPtr = obj->currImagePtr;
|
||||||
|
while (obj->currImagePtr->nextSeqPtr != seqPtr)
|
||||||
|
obj->currImagePtr = obj->currImagePtr->nextSeqPtr;
|
||||||
|
// Find out if this is first frame of sequence
|
||||||
|
// If so, reset frame_timer and decrement n_cycle
|
||||||
|
if (obj->frameInterval || obj->cycleNumb) {
|
||||||
|
obj->frameTimer = obj->frameInterval;
|
||||||
|
for (int j = 0; j < obj->seqNumb; j++) {
|
||||||
|
if (obj->currImagePtr == obj->seqList[j].seqPtr) {
|
||||||
|
if (obj->cycleNumb){ // Decr cycleNumb if Non-continous
|
||||||
|
if (!--obj->cycleNumb)
|
||||||
|
obj->cycling = NOT_CYCLING;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
obj->oldx = obj->x;
|
||||||
|
obj->oldy = obj->y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ObjectHandler::swapImages(int objNumb1, int objNumb2) {
|
||||||
|
// Swap all the images of one object with another. Set hero_image (we make
|
||||||
|
// the assumption for now that the first obj is always the HERO) to the object
|
||||||
|
// number of the swapped image
|
||||||
|
debugC(1, kDebugSchedule, "swapImages(%d, %d)", objNumb1, objNumb2);
|
||||||
|
|
||||||
|
saveSeq(&_objects[objNumb1]);
|
||||||
|
|
||||||
|
seqList_t tmpSeqList[MAX_SEQUENCES];
|
||||||
|
int seqListSize = sizeof(seqList_t) * MAX_SEQUENCES;
|
||||||
|
|
||||||
|
memcpy(tmpSeqList, _objects[objNumb1].seqList, seqListSize);
|
||||||
|
memcpy(_objects[objNumb1].seqList, _objects[objNumb2].seqList, seqListSize);
|
||||||
|
memcpy(_objects[objNumb2].seqList, tmpSeqList, seqListSize);
|
||||||
|
restoreSeq(&_objects[objNumb1]);
|
||||||
|
_objects[objNumb2].currImagePtr = _objects[objNumb2].seqList[0].seqPtr;
|
||||||
|
_vm->_heroImage = (_vm->_heroImage == HERO) ? objNumb2 : HERO;
|
||||||
|
|
||||||
|
// Make sure baseline stays constant
|
||||||
|
_objects[objNumb1].y += _objects[objNumb2].currImagePtr->y2 - _objects[objNumb1].currImagePtr->y2;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ObjectHandler::saveSeq(object_t *obj) {
|
||||||
|
// Save sequence number and image number in given object
|
||||||
|
debugC(1, kDebugFile, "saveSeq");
|
||||||
|
|
||||||
|
bool found = false;
|
||||||
|
for (int j = 0; !found && (j < obj->seqNumb); j++) {
|
||||||
|
seq_t *q = obj->seqList[j].seqPtr;
|
||||||
|
for (int k = 0; !found && (k < obj->seqList[j].imageNbr); k++) {
|
||||||
|
if (obj->currImagePtr == q) {
|
||||||
|
found = true;
|
||||||
|
obj->curSeqNum = j;
|
||||||
|
obj->curImageNum = k;
|
||||||
|
} else {
|
||||||
|
q = q->nextSeqPtr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ObjectHandler::restoreSeq(object_t *obj) {
|
||||||
|
// Set up cur_seq_p from stored sequence and image number in object
|
||||||
|
debugC(1, kDebugFile, "restoreSeq");
|
||||||
|
|
||||||
|
seq_t *q = obj->seqList[obj->curSeqNum].seqPtr;
|
||||||
|
for (int j = 0; j < obj->curImageNum; j++)
|
||||||
|
q = q->nextSeqPtr;
|
||||||
|
obj->currImagePtr = q;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update all object positions. Process object 'local' events
|
||||||
|
// including boundary events and collisions
|
||||||
|
void ObjectHandler::moveObjects() {
|
||||||
|
debugC(4, kDebugEngine, "moveObjects");
|
||||||
|
|
||||||
|
// If route mode enabled, do special route processing
|
||||||
|
if (_vm->getGameStatus().routeIndex >= 0)
|
||||||
|
_vm->_route->processRoute();
|
||||||
|
|
||||||
|
// Perform any adjustments to velocity based on special path types
|
||||||
|
// and store all (visible) object baselines into the boundary file.
|
||||||
|
// Don't store foreground or background objects
|
||||||
|
for (int i = 0; i < _vm->_numObj; i++) {
|
||||||
|
object_t *obj = &_objects[i]; // Get pointer to object
|
||||||
|
seq_t *currImage = obj->currImagePtr; // Get ptr to current image
|
||||||
|
if (obj->screenIndex == *_vm->_screen_p) {
|
||||||
|
switch (obj->pathType) {
|
||||||
|
case CHASE:
|
||||||
|
case CHASE2: {
|
||||||
|
int8 radius = obj->radius; // Default to object's radius
|
||||||
|
if (radius < 0) // If radius infinity, use closer value
|
||||||
|
radius = DX;
|
||||||
|
|
||||||
|
// Allowable motion wrt boundary
|
||||||
|
int dx = _vm->_hero->x + _vm->_hero->currImagePtr->x1 - obj->x - currImage->x1;
|
||||||
|
int dy = _vm->_hero->y + _vm->_hero->currImagePtr->y2 - obj->y - currImage->y2 - 1;
|
||||||
|
if (abs(dx) <= radius)
|
||||||
|
obj->vx = 0;
|
||||||
|
else
|
||||||
|
obj->vx = (dx > 0) ? MIN(dx, obj->vxPath) : MAX(dx, -obj->vxPath);
|
||||||
|
if (abs(dy) <= radius)
|
||||||
|
obj->vy = 0;
|
||||||
|
else
|
||||||
|
obj->vy = (dy > 0) ? MIN(dy, obj->vyPath) : MAX(dy, -obj->vyPath);
|
||||||
|
|
||||||
|
// Set first image in sequence (if multi-seq object)
|
||||||
|
switch (obj->seqNumb) {
|
||||||
|
case 4:
|
||||||
|
if (!obj->vx) { // Got 4 directions
|
||||||
|
if (obj->vx != obj->oldvx) { // vx just stopped
|
||||||
|
if (dy >= 0)
|
||||||
|
obj->currImagePtr = obj->seqList[DOWN].seqPtr;
|
||||||
|
else
|
||||||
|
obj->currImagePtr = obj->seqList[_UP].seqPtr;
|
||||||
|
}
|
||||||
|
} else if (obj->vx != obj->oldvx) {
|
||||||
|
if (dx > 0)
|
||||||
|
obj->currImagePtr = obj->seqList[RIGHT].seqPtr;
|
||||||
|
else
|
||||||
|
obj->currImagePtr = obj->seqList[LEFT].seqPtr;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
case 2:
|
||||||
|
if (obj->vx != obj->oldvx) { // vx just stopped
|
||||||
|
if (dx > 0) // Left & right only
|
||||||
|
obj->currImagePtr = obj->seqList[RIGHT].seqPtr;
|
||||||
|
else
|
||||||
|
obj->currImagePtr = obj->seqList[LEFT].seqPtr;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (obj->vx || obj->vy)
|
||||||
|
obj->cycling = CYCLE_FORWARD;
|
||||||
|
else {
|
||||||
|
obj->cycling = NOT_CYCLING;
|
||||||
|
_vm->boundaryCollision(obj); // Must have got hero!
|
||||||
|
}
|
||||||
|
obj->oldvx = obj->vx;
|
||||||
|
obj->oldvy = obj->vy;
|
||||||
|
currImage = obj->currImagePtr; // Get (new) ptr to current image
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case WANDER2:
|
||||||
|
case WANDER:
|
||||||
|
if (!_vm->_rnd->getRandomNumber(3 * NORMAL_TPS)) { // Kick on random interval
|
||||||
|
obj->vx = _vm->_rnd->getRandomNumber(obj->vxPath << 1) - obj->vxPath;
|
||||||
|
obj->vy = _vm->_rnd->getRandomNumber(obj->vyPath << 1) - obj->vyPath;
|
||||||
|
|
||||||
|
// Set first image in sequence (if multi-seq object)
|
||||||
|
if (obj->seqNumb > 1) {
|
||||||
|
if (!obj->vx && (obj->seqNumb >= 4)) {
|
||||||
|
if (obj->vx != obj->oldvx) { // vx just stopped
|
||||||
|
if (obj->vy > 0)
|
||||||
|
obj->currImagePtr = obj->seqList[DOWN].seqPtr;
|
||||||
|
else
|
||||||
|
obj->currImagePtr = obj->seqList[_UP].seqPtr;
|
||||||
|
}
|
||||||
|
} else if (obj->vx != obj->oldvx) {
|
||||||
|
if (obj->vx > 0)
|
||||||
|
obj->currImagePtr = obj->seqList[RIGHT].seqPtr;
|
||||||
|
else
|
||||||
|
obj->currImagePtr = obj->seqList[LEFT].seqPtr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
obj->oldvx = obj->vx;
|
||||||
|
obj->oldvy = obj->vy;
|
||||||
|
currImage = obj->currImagePtr; // Get (new) ptr to current image
|
||||||
|
}
|
||||||
|
if (obj->vx || obj->vy)
|
||||||
|
obj->cycling = CYCLE_FORWARD;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
; // Really, nothing
|
||||||
|
}
|
||||||
|
// Store boundaries
|
||||||
|
if ((obj->cycling > ALMOST_INVISIBLE) && (obj->priority == FLOATING))
|
||||||
|
_vm->storeBoundary(obj->x + currImage->x1, obj->x + currImage->x2, obj->y + currImage->y2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Move objects, allowing for boundaries
|
||||||
|
for (int i = 0; i < _vm->_numObj; i++) {
|
||||||
|
object_t *obj = &_objects[i]; // Get pointer to object
|
||||||
|
if ((obj->screenIndex == *_vm->_screen_p) && (obj->vx || obj->vy)) {
|
||||||
|
// Only process if it's moving
|
||||||
|
|
||||||
|
// Do object movement. Delta_x,y return allowed movement in x,y
|
||||||
|
// to move as close to a boundary as possible without crossing it.
|
||||||
|
seq_t *currImage = obj->currImagePtr; // Get ptr to current image
|
||||||
|
// object coordinates
|
||||||
|
int x1 = obj->x + currImage->x1; // Left edge of object
|
||||||
|
int x2 = obj->x + currImage->x2; // Right edge
|
||||||
|
int y1 = obj->y + currImage->y1; // Top edge
|
||||||
|
int y2 = obj->y + currImage->y2; // Bottom edge
|
||||||
|
|
||||||
|
if ((obj->cycling > ALMOST_INVISIBLE) && (obj->priority == FLOATING))
|
||||||
|
_vm->clearBoundary(x1, x2, y2); // Clear our own boundary
|
||||||
|
|
||||||
|
// Allowable motion wrt boundary
|
||||||
|
int dx = _vm->deltaX(x1, x2, obj->vx, y2);
|
||||||
|
if (dx != obj->vx) {
|
||||||
|
// An object boundary collision!
|
||||||
|
_vm->boundaryCollision(obj);
|
||||||
|
obj->vx = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int dy = _vm->deltaY(x1, x2, obj->vy, y2);
|
||||||
|
if (dy != obj->vy) {
|
||||||
|
// An object boundary collision!
|
||||||
|
_vm->boundaryCollision(obj);
|
||||||
|
obj->vy = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((obj->cycling > ALMOST_INVISIBLE) && (obj->priority == FLOATING))
|
||||||
|
_vm->storeBoundary(x1, x2, y2); // Re-store our own boundary
|
||||||
|
|
||||||
|
obj->x += dx; // Update object position
|
||||||
|
obj->y += dy;
|
||||||
|
|
||||||
|
// Don't let object go outside screen
|
||||||
|
if (x1 < EDGE)
|
||||||
|
obj->x = EDGE2;
|
||||||
|
if (x2 > (XPIX - EDGE))
|
||||||
|
obj->x = XPIX - EDGE2 - (x2 - x1);
|
||||||
|
if (y1 < EDGE)
|
||||||
|
obj->y = EDGE2;
|
||||||
|
if (y2 > (YPIX - EDGE))
|
||||||
|
obj->y = YPIX - EDGE2 - (y2 - y1);
|
||||||
|
|
||||||
|
if ((obj->vx == 0) && (obj->vy == 0) && (obj->pathType != WANDER2) && (obj->pathType != CHASE2))
|
||||||
|
obj->cycling = NOT_CYCLING;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clear all object baselines from the boundary file.
|
||||||
|
for (int i = 0; i < _vm->_numObj; i++) {
|
||||||
|
object_t *obj = &_objects[i]; // Get pointer to object
|
||||||
|
seq_t *currImage = obj->currImagePtr; // Get ptr to current image
|
||||||
|
if ((obj->screenIndex == *_vm->_screen_p) && (obj->cycling > ALMOST_INVISIBLE) && (obj->priority == FLOATING))
|
||||||
|
_vm->clearBoundary(obj->oldx + currImage->x1, obj->oldx + currImage->x2, obj->oldy + currImage->y2);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If maze mode is enabled, do special maze processing
|
||||||
|
if (_maze.enabledFl)
|
||||||
|
_vm->processMaze();
|
||||||
|
}
|
||||||
|
|
||||||
|
// If status.objid = -1, pick up objid, else use status.objid on objid,
|
||||||
|
// if objid can't be picked up, use it directly
|
||||||
|
void ObjectHandler::useObject(int16 objId) {
|
||||||
|
debugC(1, kDebugEngine, "useObject(%d)", objId);
|
||||||
|
|
||||||
|
char *verb; // Background verb to use directly
|
||||||
|
object_t *obj = &_objects[objId]; // Ptr to object
|
||||||
|
if (_vm->getGameStatus().inventoryObjId == -1) {
|
||||||
|
// Get or use objid directly
|
||||||
|
if ((obj->genericCmd & TAKE) || obj->objValue) // Get collectible item
|
||||||
|
sprintf(_line, "%s %s", _vm->_arrayVerbs[_vm->_take][0], _vm->_arrayNouns[obj->nounIndex][0]);
|
||||||
|
else if (obj->genericCmd & LOOK) // Look item
|
||||||
|
sprintf(_line, "%s %s", _vm->_arrayVerbs[_vm->_look][0], _vm->_arrayNouns[obj->nounIndex][0]);
|
||||||
|
else if (obj->genericCmd & DROP) // Drop item
|
||||||
|
sprintf(_line, "%s %s", _vm->_arrayVerbs[_vm->_drop][0], _vm->_arrayNouns[obj->nounIndex][0]);
|
||||||
|
else if (obj->cmdIndex != 0) // Use non-collectible item if able
|
||||||
|
sprintf(_line, "%s %s", _vm->_arrayVerbs[_vm->_cmdList[obj->cmdIndex][1].verbIndex][0], _vm->_arrayNouns[obj->nounIndex][0]);
|
||||||
|
else if ((verb = _vm->useBG(_vm->_arrayNouns[obj->nounIndex][0])) != 0)
|
||||||
|
sprintf(_line, "%s %s", verb, _vm->_arrayNouns[obj->nounIndex][0]);
|
||||||
|
else
|
||||||
|
return; // Can't use object directly
|
||||||
|
} else {
|
||||||
|
// Use status.objid on objid
|
||||||
|
// Default to first cmd verb
|
||||||
|
sprintf(_line, "%s %s %s", _vm->_arrayVerbs[_vm->_cmdList[_objects[_vm->getGameStatus().inventoryObjId].cmdIndex][1].verbIndex][0],
|
||||||
|
_vm->_arrayNouns[_objects[_vm->getGameStatus().inventoryObjId].nounIndex][0],
|
||||||
|
_vm->_arrayNouns[obj->nounIndex][0]);
|
||||||
|
|
||||||
|
// Check valid use of objects and override verb if necessary
|
||||||
|
for (uses_t *use = _vm->_uses; use->objId != _vm->_numObj; use++) {
|
||||||
|
if (_vm->getGameStatus().inventoryObjId == use->objId) {
|
||||||
|
// Look for secondary object, if found use matching verb
|
||||||
|
bool foundFl = false;
|
||||||
|
for (target_t *target = use->targets; _vm->_arrayNouns[target->nounIndex] != 0; target++)
|
||||||
|
if (_vm->_arrayNouns[target->nounIndex][0] == _vm->_arrayNouns[obj->nounIndex][0]) {
|
||||||
|
foundFl = true;
|
||||||
|
sprintf(_line, "%s %s %s", _vm->_arrayVerbs[target->verbIndex][0],
|
||||||
|
_vm->_arrayNouns[_objects[_vm->getGameStatus().inventoryObjId].nounIndex][0],
|
||||||
|
_vm->_arrayNouns[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 != I_ACTIVE)
|
||||||
|
_vm->getGameStatus().inventoryObjId = -1;
|
||||||
|
Utils::Box(BOX_ANY, "%s", _vm->_textData[use->dataIndex]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_vm->getGameStatus().inventoryState == I_ACTIVE) // If inventory active, remove it
|
||||||
|
_vm->getGameStatus().inventoryState = I_UP;
|
||||||
|
_vm->getGameStatus().inventoryObjId = -1; // Deselect any dragged icon
|
||||||
|
_vm->_parser->lineHandler(); // and process command
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return object index of the topmost object under the cursor, or -1 if none
|
||||||
|
// Objects are filtered if not "useful"
|
||||||
|
int16 ObjectHandler::findObject(uint16 x, uint16 y) {
|
||||||
|
debugC(3, kDebugEngine, "findObject(%d, %d)", x, y);
|
||||||
|
|
||||||
|
int16 objIndex = -1; // Index of found object
|
||||||
|
uint16 y2Max = 0; // Greatest y2
|
||||||
|
object_t *obj = _objects;
|
||||||
|
// Check objects on screen
|
||||||
|
for (int i = 0; i < _vm->_numObj; i++, obj++) {
|
||||||
|
// Object must be in current screen and "useful"
|
||||||
|
if (obj->screenIndex == *_vm->_screen_p && (obj->genericCmd || obj->objValue || obj->cmdIndex)) {
|
||||||
|
seq_t *curImage = obj->currImagePtr;
|
||||||
|
// Object must have a visible image...
|
||||||
|
if (curImage != 0 && obj->cycling != INVISIBLE) {
|
||||||
|
// If cursor inside object
|
||||||
|
if (x >= (uint16)obj->x && x <= obj->x + curImage->x2 && y >= (uint16)obj->y && y <= obj->y + curImage->y2) {
|
||||||
|
// If object is closest so far
|
||||||
|
if (obj->y + curImage->y2 > y2Max) {
|
||||||
|
y2Max = obj->y + curImage->y2;
|
||||||
|
objIndex = i; // Found an object!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// ...or a dummy object that has a hotspot rectangle
|
||||||
|
if (curImage == 0 && obj->vxPath != 0 && !obj->carriedFl) {
|
||||||
|
// If cursor inside special rectangle
|
||||||
|
if ((int16)x >= obj->oldx && (int16)x < obj->oldx + obj->vxPath && (int16)y >= obj->oldy && (int16)y < obj->oldy + obj->vyPath) {
|
||||||
|
// If object is closest so far
|
||||||
|
if (obj->oldy + obj->vyPath - 1 > (int16)y2Max) {
|
||||||
|
y2Max = obj->oldy + obj->vyPath - 1;
|
||||||
|
objIndex = i; // Found an object!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return objIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Issue "Look at <object>" command
|
||||||
|
// Note special case of swapped hero image
|
||||||
|
void ObjectHandler::lookObject(object_t *obj) {
|
||||||
|
debugC(1, kDebugEngine, "lookObject");
|
||||||
|
|
||||||
|
if (obj == _vm->_hero)
|
||||||
|
// Hero swapped - look at other
|
||||||
|
obj = &_objects[_vm->_heroImage];
|
||||||
|
|
||||||
|
_vm->_parser->command("%s %s", _vm->_arrayVerbs[_vm->_look][0], _vm->_arrayNouns[obj->nounIndex][0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Free all object images
|
||||||
|
void ObjectHandler::freeObjects() {
|
||||||
|
debugC(1, kDebugEngine, "freeObjects");
|
||||||
|
|
||||||
|
// Nothing to do if not allocated yet
|
||||||
|
if (_vm->_hero->seqList[0].seqPtr == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Free all sequence lists and image data
|
||||||
|
for (int i = 0; i < _vm->_numObj; i++) {
|
||||||
|
object_t *obj = &_objects[i];
|
||||||
|
for (int j = 0; j < obj->seqNumb; j++) { // for each sequence
|
||||||
|
seq_t *seq = obj->seqList[j].seqPtr; // Free image
|
||||||
|
if (seq == 0) // Failure during database load
|
||||||
|
break;
|
||||||
|
do {
|
||||||
|
free(seq->imagePtr);
|
||||||
|
seq = seq->nextSeqPtr;
|
||||||
|
} while (seq != obj->seqList[j].seqPtr);
|
||||||
|
free(seq); // Free sequence record
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compare function for the quicksort. The sort is to order the objects in
|
||||||
|
// increasing vertical position, using y+y2 as the baseline
|
||||||
|
// Returns -1 if ay2 < by2 else 1 if ay2 > by2 else 0
|
||||||
|
int ObjectHandler::y2comp(const void *a, const void *b) {
|
||||||
|
debugC(6, kDebugEngine, "y2comp");
|
||||||
|
|
||||||
|
// const object_t *p1 = &s_Engine->_objects[*(const byte *)a];
|
||||||
|
// const object_t *p2 = &s_Engine->_objects[*(const byte *)b];
|
||||||
|
const object_t *p1 = &HugoEngine::get()._object->_objects[*(const byte *)a];
|
||||||
|
const object_t *p2 = &HugoEngine::get()._object->_objects[*(const byte *)b];
|
||||||
|
|
||||||
|
if (p1 == p2)
|
||||||
|
// Why does qsort try the same indexes?
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (p1->priority == BACKGROUND)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (p2->priority == BACKGROUND)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
if (p1->priority == FOREGROUND)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
if (p2->priority == FOREGROUND)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
int ay2 = p1->y + p1->currImagePtr->y2;
|
||||||
|
int by2 = p2->y + p2->currImagePtr->y2;
|
||||||
|
|
||||||
|
return ay2 - by2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return TRUE if object being carried by hero
|
||||||
|
bool ObjectHandler::isCarrying(uint16 wordIndex) {
|
||||||
|
debugC(1, kDebugParser, "isCarrying(%d)", wordIndex);
|
||||||
|
|
||||||
|
for (int i = 0; i < _vm->_numObj; i++) {
|
||||||
|
if ((wordIndex == _objects[i].nounIndex) && _objects[i].carriedFl)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Describe any takeable objects visible in this screen
|
||||||
|
void ObjectHandler::showTakeables() {
|
||||||
|
debugC(1, kDebugParser, "showTakeables");
|
||||||
|
|
||||||
|
for (int j = 0; j < _vm->_numObj; j++) {
|
||||||
|
object_t *obj = &_objects[j];
|
||||||
|
if ((obj->cycling != INVISIBLE) &&
|
||||||
|
(obj->screenIndex == *_vm->_screen_p) &&
|
||||||
|
(((TAKE & obj->genericCmd) == TAKE) || obj->objValue)) {
|
||||||
|
Utils::Box(BOX_ANY, "You can also see:\n%s.", _vm->_arrayNouns[obj->nounIndex][LOOK_NAME]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ObjectHandler::loadObject(Common::File &in) {
|
||||||
|
// TODO: For Hugo3, if not in story mode, set _objects[2].state to 3
|
||||||
|
for (int varnt = 0; varnt < _vm->_numVariant; varnt++) {
|
||||||
|
uint16 numElem = in.readUint16BE();
|
||||||
|
if (varnt == _vm->_gameVariant) {
|
||||||
|
_objects = (object_t *)malloc(sizeof(object_t) * numElem);
|
||||||
|
for (int i = 0; i < numElem; i++) {
|
||||||
|
_objects[i].nounIndex = in.readUint16BE();
|
||||||
|
_objects[i].dataIndex = in.readUint16BE();
|
||||||
|
uint16 numSubElem = in.readUint16BE();
|
||||||
|
if (numSubElem == 0)
|
||||||
|
_objects[i].stateDataIndex = 0;
|
||||||
|
else
|
||||||
|
_objects[i].stateDataIndex = (uint16 *)malloc(sizeof(uint16) * numSubElem);
|
||||||
|
for (int j = 0; j < numSubElem; j++)
|
||||||
|
_objects[i].stateDataIndex[j] = in.readUint16BE();
|
||||||
|
_objects[i].pathType = (path_t) in.readSint16BE();
|
||||||
|
_objects[i].vxPath = in.readSint16BE();
|
||||||
|
_objects[i].vyPath = in.readSint16BE();
|
||||||
|
_objects[i].actIndex = in.readUint16BE();
|
||||||
|
_objects[i].seqNumb = in.readByte();
|
||||||
|
_objects[i].currImagePtr = 0;
|
||||||
|
if (_objects[i].seqNumb == 0) {
|
||||||
|
_objects[i].seqList[0].imageNbr = 0;
|
||||||
|
_objects[i].seqList[0].seqPtr = 0;
|
||||||
|
}
|
||||||
|
for (int j = 0; j < _objects[i].seqNumb; j++) {
|
||||||
|
_objects[i].seqList[j].imageNbr = in.readUint16BE();
|
||||||
|
_objects[i].seqList[j].seqPtr = 0;
|
||||||
|
}
|
||||||
|
_objects[i].cycling = (cycle_t)in.readByte();
|
||||||
|
_objects[i].cycleNumb = in.readByte();
|
||||||
|
_objects[i].frameInterval = in.readByte();
|
||||||
|
_objects[i].frameTimer = in.readByte();
|
||||||
|
_objects[i].radius = in.readByte();
|
||||||
|
_objects[i].screenIndex = in.readByte();
|
||||||
|
_objects[i].x = in.readSint16BE();
|
||||||
|
_objects[i].y = in.readSint16BE();
|
||||||
|
_objects[i].oldx = in.readSint16BE();
|
||||||
|
_objects[i].oldy = in.readSint16BE();
|
||||||
|
_objects[i].vx = in.readByte();
|
||||||
|
_objects[i].vy = in.readByte();
|
||||||
|
_objects[i].objValue = in.readByte();
|
||||||
|
_objects[i].genericCmd = in.readSint16BE();
|
||||||
|
_objects[i].cmdIndex = in.readUint16BE();
|
||||||
|
_objects[i].carriedFl = (in.readByte() != 0);
|
||||||
|
_objects[i].state = in.readByte();
|
||||||
|
_objects[i].verbOnlyFl = (in.readByte() != 0);
|
||||||
|
_objects[i].priority = in.readByte();
|
||||||
|
_objects[i].viewx = in.readSint16BE();
|
||||||
|
_objects[i].viewy = in.readSint16BE();
|
||||||
|
_objects[i].direction = in.readSint16BE();
|
||||||
|
_objects[i].curSeqNum = in.readByte();
|
||||||
|
_objects[i].curImageNum = in.readByte();
|
||||||
|
_objects[i].oldvx = in.readByte();
|
||||||
|
_objects[i].oldvy = in.readByte();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (int i = 0; i < numElem; i++) {
|
||||||
|
in.readUint16BE();
|
||||||
|
in.readUint16BE();
|
||||||
|
uint16 numSubElem = in.readUint16BE();
|
||||||
|
for (int j = 0; j < numSubElem; j++)
|
||||||
|
in.readUint16BE();
|
||||||
|
in.readSint16BE();
|
||||||
|
in.readSint16BE();
|
||||||
|
in.readSint16BE();
|
||||||
|
in.readUint16BE();
|
||||||
|
numSubElem = in.readByte();
|
||||||
|
for (int j = 0; j < numSubElem; j++)
|
||||||
|
in.readUint16BE();
|
||||||
|
in.readByte();
|
||||||
|
in.readByte();
|
||||||
|
in.readByte();
|
||||||
|
in.readByte();
|
||||||
|
in.readByte();
|
||||||
|
in.readByte();
|
||||||
|
in.readSint16BE();
|
||||||
|
in.readSint16BE();
|
||||||
|
in.readSint16BE();
|
||||||
|
in.readSint16BE();
|
||||||
|
in.readByte();
|
||||||
|
in.readByte();
|
||||||
|
in.readByte();
|
||||||
|
in.readSint16BE();
|
||||||
|
in.readUint16BE();
|
||||||
|
in.readByte();
|
||||||
|
in.readByte();
|
||||||
|
in.readByte();
|
||||||
|
in.readByte();
|
||||||
|
in.readSint16BE();
|
||||||
|
in.readSint16BE();
|
||||||
|
in.readUint16BE();
|
||||||
|
in.readByte();
|
||||||
|
in.readByte();
|
||||||
|
in.readByte();
|
||||||
|
in.readByte();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // End of namespace Hugo
|
90
engines/hugo/object.h
Normal file
90
engines/hugo/object.h
Normal file
|
@ -0,0 +1,90 @@
|
||||||
|
/* ScummVM - Graphic Adventure Engine
|
||||||
|
*
|
||||||
|
* ScummVM is the legal property of its developers, whose names
|
||||||
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||||
|
* file distributed with this source distribution.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* as published by the Free Software Foundation; either version 2
|
||||||
|
* of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*
|
||||||
|
* $URL$
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This code is based on original Hugo Trilogy source code
|
||||||
|
*
|
||||||
|
* Copyright (c) 1989-1995 David P. Gray
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef HUGO_OBJECT_H
|
||||||
|
#define HUGO_OBJECT_H
|
||||||
|
|
||||||
|
#include "common/file.h"
|
||||||
|
|
||||||
|
#define MAXOBJECTS 128 // Used in Update_images()
|
||||||
|
|
||||||
|
namespace Hugo {
|
||||||
|
|
||||||
|
class ObjectHandler {
|
||||||
|
public:
|
||||||
|
ObjectHandler(HugoEngine *vm);
|
||||||
|
~ObjectHandler();
|
||||||
|
|
||||||
|
object_t *_objects;
|
||||||
|
|
||||||
|
bool isCarrying(uint16 wordIndex);
|
||||||
|
|
||||||
|
int16 findObject(uint16 x, uint16 y);
|
||||||
|
|
||||||
|
void lookObject(object_t *obj);
|
||||||
|
void freeObjects();
|
||||||
|
void loadObject(Common::File &in);
|
||||||
|
void moveObjects();
|
||||||
|
void restoreSeq(object_t *obj);
|
||||||
|
void saveSeq(object_t *obj);
|
||||||
|
void showTakeables();
|
||||||
|
void swapImages(int objNumb1, int objNumb2);
|
||||||
|
void updateImages();
|
||||||
|
void useObject(int16 objId);
|
||||||
|
|
||||||
|
static int y2comp(const void *a, const void *b);
|
||||||
|
|
||||||
|
bool isCarried(int objIndex) {
|
||||||
|
return _objects[objIndex].carriedFl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setCarry(int objIndex, bool val) {
|
||||||
|
_objects[objIndex].carriedFl = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setVelocity(int objIndex, int8 vx, int8 vy) {
|
||||||
|
_objects[objIndex].vx = vx;
|
||||||
|
_objects[objIndex].vy = vy;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setPath(int objIndex, path_t pathType, int16 vxPath, int16 vyPath) {
|
||||||
|
_objects[objIndex].pathType = pathType;
|
||||||
|
_objects[objIndex].vxPath = vxPath;
|
||||||
|
_objects[objIndex].vyPath = vyPath;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
HugoEngine *_vm;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // End of namespace Hugo
|
||||||
|
|
||||||
|
#endif //HUGO_OBJECT_H
|
|
@ -39,6 +39,7 @@
|
||||||
#include "hugo/route.h"
|
#include "hugo/route.h"
|
||||||
#include "hugo/util.h"
|
#include "hugo/util.h"
|
||||||
#include "hugo/sound.h"
|
#include "hugo/sound.h"
|
||||||
|
#include "hugo/object.h"
|
||||||
|
|
||||||
namespace Hugo {
|
namespace Hugo {
|
||||||
|
|
||||||
|
@ -46,7 +47,7 @@ namespace Hugo {
|
||||||
#define CX(X) LOWORD(X)
|
#define CX(X) LOWORD(X)
|
||||||
#define CY(Y) HIWORD(Y)
|
#define CY(Y) HIWORD(Y)
|
||||||
|
|
||||||
Parser::Parser(HugoEngine &vm) :
|
Parser::Parser(HugoEngine *vm) :
|
||||||
_vm(vm), _putIndex(0), _getIndex(0), _checkDoubleF1Fl(false) {
|
_vm(vm), _putIndex(0), _getIndex(0), _checkDoubleF1Fl(false) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,7 +57,7 @@ Parser::~Parser() {
|
||||||
void Parser::keyHandler(uint16 nChar, uint16 nFlags) {
|
void Parser::keyHandler(uint16 nChar, uint16 nFlags) {
|
||||||
debugC(1, kDebugParser, "keyHandler(%d, %d)", nChar, nFlags);
|
debugC(1, kDebugParser, "keyHandler(%d, %d)", nChar, nFlags);
|
||||||
|
|
||||||
status_t &gameStatus = _vm.getGameStatus();
|
status_t &gameStatus = _vm->getGameStatus();
|
||||||
bool repeatedFl = (nFlags & 0x4000); // TRUE if key is a repeat
|
bool repeatedFl = (nFlags & 0x4000); // TRUE if key is a repeat
|
||||||
|
|
||||||
// Process key down event - called from OnKeyDown()
|
// Process key down event - called from OnKeyDown()
|
||||||
|
@ -74,14 +75,14 @@ void Parser::keyHandler(uint16 nChar, uint16 nFlags) {
|
||||||
case Common::KEYCODE_DOWN:
|
case Common::KEYCODE_DOWN:
|
||||||
if (!repeatedFl) {
|
if (!repeatedFl) {
|
||||||
gameStatus.routeIndex = -1; // Stop any automatic route
|
gameStatus.routeIndex = -1; // 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)
|
||||||
if (_checkDoubleF1Fl)
|
if (_checkDoubleF1Fl)
|
||||||
_vm.file().instructions();
|
_vm->_file->instructions();
|
||||||
else
|
else
|
||||||
_vm.screen().userHelp();
|
_vm->_screen->userHelp();
|
||||||
_checkDoubleF1Fl = !_checkDoubleF1Fl;
|
_checkDoubleF1Fl = !_checkDoubleF1Fl;
|
||||||
break;
|
break;
|
||||||
case Common::KEYCODE_F6: // Inventory
|
case Common::KEYCODE_F6: // Inventory
|
||||||
|
@ -91,8 +92,8 @@ void Parser::keyHandler(uint16 nChar, uint16 nFlags) {
|
||||||
_config.turboFl = !_config.turboFl;
|
_config.turboFl = !_config.turboFl;
|
||||||
break;
|
break;
|
||||||
case Common::KEYCODE_F2: // Toggle sound
|
case Common::KEYCODE_F2: // Toggle sound
|
||||||
_vm.sound().toggleSound();
|
_vm->_sound->toggleSound();
|
||||||
_vm.sound().toggleMusic();
|
_vm->_sound->toggleMusic();
|
||||||
break;
|
break;
|
||||||
case Common::KEYCODE_F3: // Repeat last line
|
case Common::KEYCODE_F3: // Repeat last line
|
||||||
gameStatus.recallFl = true;
|
gameStatus.recallFl = true;
|
||||||
|
@ -129,7 +130,7 @@ void Parser::charHandler() {
|
||||||
static uint32 tick = 0; // For flashing cursor
|
static uint32 tick = 0; // For flashing cursor
|
||||||
static char cursor = '_';
|
static char cursor = '_';
|
||||||
static command_t cmdLine; // Build command line
|
static command_t cmdLine; // Build command line
|
||||||
status_t &gameStatus = _vm.getGameStatus();
|
status_t &gameStatus = _vm->getGameStatus();
|
||||||
|
|
||||||
// Check for one or more characters in ring buffer
|
// Check for one or more characters in ring buffer
|
||||||
while (_getIndex != _putIndex) {
|
while (_getIndex != _putIndex) {
|
||||||
|
@ -143,7 +144,7 @@ void Parser::charHandler() {
|
||||||
cmdLine[--lineIndex] = '\0';
|
cmdLine[--lineIndex] = '\0';
|
||||||
break;
|
break;
|
||||||
case Common::KEYCODE_RETURN: // EOL, pass line to line handler
|
case Common::KEYCODE_RETURN: // EOL, pass line to line handler
|
||||||
if (lineIndex && (_vm._hero->pathType != QUIET)) {
|
if (lineIndex && (_vm->_hero->pathType != QUIET)) {
|
||||||
// Remove inventory bar if active
|
// Remove inventory bar if active
|
||||||
if (gameStatus.inventoryState == I_ACTIVE)
|
if (gameStatus.inventoryState == I_ACTIVE)
|
||||||
gameStatus.inventoryState = I_UP;
|
gameStatus.inventoryState = I_UP;
|
||||||
|
@ -176,8 +177,8 @@ void Parser::charHandler() {
|
||||||
lineIndex = strlen(cmdLine);
|
lineIndex = strlen(cmdLine);
|
||||||
}
|
}
|
||||||
|
|
||||||
sprintf(_vm._statusLine, ">%s%c", cmdLine, cursor);
|
sprintf(_vm->_statusLine, ">%s%c", cmdLine, cursor);
|
||||||
sprintf(_vm._scoreLine, "F1-Help %s Score: %d of %d Sound %s", (_config.turboFl) ? "T" : " ", _vm.getScore(), _vm.getMaxScore(), (_config.soundFl) ? "On" : "Off");
|
sprintf(_vm->_scoreLine, "F1-Help %s Score: %d of %d Sound %s", (_config.turboFl) ? "T" : " ", _vm->getScore(), _vm->getMaxScore(), (_config.soundFl) ? "On" : "Off");
|
||||||
|
|
||||||
// See if "look" button pressed
|
// See if "look" button pressed
|
||||||
if (gameStatus.lookFl) {
|
if (gameStatus.lookFl) {
|
||||||
|
@ -216,10 +217,10 @@ bool Parser::isWordPresent(char **wordArr) {
|
||||||
char *Parser::findNoun() {
|
char *Parser::findNoun() {
|
||||||
debugC(1, kDebugParser, "findNoun()");
|
debugC(1, kDebugParser, "findNoun()");
|
||||||
|
|
||||||
for (int i = 0; _vm._arrayNouns[i]; i++) {
|
for (int i = 0; _vm->_arrayNouns[i]; i++) {
|
||||||
for (int j = 0; strlen(_vm._arrayNouns[i][j]); j++) {
|
for (int j = 0; strlen(_vm->_arrayNouns[i][j]); j++) {
|
||||||
if (strstr(_line, _vm._arrayNouns[i][j]))
|
if (strstr(_line, _vm->_arrayNouns[i][j]))
|
||||||
return _vm._arrayNouns[i][0];
|
return _vm->_arrayNouns[i][0];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -229,49 +230,24 @@ char *Parser::findNoun() {
|
||||||
char *Parser::findVerb() {
|
char *Parser::findVerb() {
|
||||||
debugC(1, kDebugParser, "findVerb()");
|
debugC(1, kDebugParser, "findVerb()");
|
||||||
|
|
||||||
for (int i = 0; _vm._arrayVerbs[i]; i++) {
|
for (int i = 0; _vm->_arrayVerbs[i]; i++) {
|
||||||
for (int j = 0; strlen(_vm._arrayVerbs[i][j]); j++) {
|
for (int j = 0; strlen(_vm->_arrayVerbs[i][j]); j++) {
|
||||||
if (strstr(_line, _vm._arrayVerbs[i][j]))
|
if (strstr(_line, _vm->_arrayVerbs[i][j]))
|
||||||
return _vm._arrayVerbs[i][0];
|
return _vm->_arrayVerbs[i][0];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Describe any takeable objects visible in this screen
|
|
||||||
void Parser::showTakeables() {
|
|
||||||
debugC(1, kDebugParser, "showTakeables");
|
|
||||||
|
|
||||||
for (int j = 0; j < _vm._numObj; j++) {
|
|
||||||
object_t *obj = &_vm._objects[j];
|
|
||||||
if ((obj->cycling != INVISIBLE) &&
|
|
||||||
(obj->screenIndex == *_vm._screen_p) &&
|
|
||||||
(((TAKE & obj->genericCmd) == TAKE) || obj->objValue)) {
|
|
||||||
Utils::Box(BOX_ANY, "You can also see:\n%s.", _vm._arrayNouns[obj->nounIndex][LOOK_NAME]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return TRUE if object being carried by hero
|
|
||||||
bool Parser::isCarrying(uint16 wordIndex) {
|
|
||||||
debugC(1, kDebugParser, "isCarrying(%d)", wordIndex);
|
|
||||||
|
|
||||||
for (int i = 0; i < _vm._numObj; i++) {
|
|
||||||
if ((wordIndex == _vm._objects[i].nounIndex) && _vm._objects[i].carriedFl)
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Show user all objects being carried in a variable width 2 column format
|
// Show user all objects being carried in a variable width 2 column format
|
||||||
void Parser::showDosInventory() {
|
void Parser::showDosInventory() {
|
||||||
debugC(1, kDebugParser, "showDosInventory()");
|
debugC(1, kDebugParser, "showDosInventory()");
|
||||||
static const char *blanks = " ";
|
static const char *blanks = " ";
|
||||||
uint16 index = 0, len1 = 0, len2 = 0;
|
uint16 index = 0, len1 = 0, len2 = 0;
|
||||||
|
|
||||||
for (int i = 0; i < _vm._numObj; i++) { // Find widths of 2 columns
|
for (int i = 0; i < _vm->_numObj; i++) { // Find widths of 2 columns
|
||||||
if (_vm._objects[i].carriedFl) {
|
if (_vm->_object->isCarried(i)) {
|
||||||
uint16 len = strlen(_vm._arrayNouns[_vm._objects[i].nounIndex][1]);
|
uint16 len = strlen(_vm->_arrayNouns[_vm->_object->_objects[i].nounIndex][1]);
|
||||||
if (index++ & 1) // Right hand column
|
if (index++ & 1) // Right hand column
|
||||||
len2 = (len > len2) ? len : len2;
|
len2 = (len > len2) ? len : len2;
|
||||||
else
|
else
|
||||||
|
@ -280,24 +256,24 @@ void Parser::showDosInventory() {
|
||||||
}
|
}
|
||||||
len1 += 1; // For gap between columns
|
len1 += 1; // For gap between columns
|
||||||
|
|
||||||
if (len1 + len2 < (uint16)strlen(_vm._textParser[kTBOutro]))
|
if (len1 + len2 < (uint16)strlen(_vm->_textParser[kTBOutro]))
|
||||||
len1 = strlen(_vm._textParser[kTBOutro]);
|
len1 = strlen(_vm->_textParser[kTBOutro]);
|
||||||
|
|
||||||
char buffer[XBYTES *NUM_ROWS] = "\0";
|
char buffer[XBYTES *NUM_ROWS] = "\0";
|
||||||
strncat(buffer, blanks, (len1 + len2 - strlen(_vm._textParser[kTBIntro])) / 2);
|
strncat(buffer, blanks, (len1 + len2 - strlen(_vm->_textParser[kTBIntro])) / 2);
|
||||||
strcat(strcat(buffer, _vm._textParser[kTBIntro]), "\n");
|
strcat(strcat(buffer, _vm->_textParser[kTBIntro]), "\n");
|
||||||
index = 0;
|
index = 0;
|
||||||
for (int i = 0; i < _vm._numObj; i++) { // Assign strings
|
for (int i = 0; i < _vm->_numObj; i++) { // Assign strings
|
||||||
if (_vm._objects[i].carriedFl) {
|
if (_vm->_object->isCarried(i)) {
|
||||||
if (index++ & 1)
|
if (index++ & 1)
|
||||||
strcat(strcat(buffer, _vm._arrayNouns[_vm._objects[i].nounIndex][1]), "\n");
|
strcat(strcat(buffer, _vm->_arrayNouns[_vm->_object->_objects[i].nounIndex][1]), "\n");
|
||||||
else
|
else
|
||||||
strncat(strcat(buffer, _vm._arrayNouns[_vm._objects[i].nounIndex][1]), blanks, len1 - strlen(_vm._arrayNouns[_vm._objects[i].nounIndex][1]));
|
strncat(strcat(buffer, _vm->_arrayNouns[_vm->_object->_objects[i].nounIndex][1]), blanks, len1 - strlen(_vm->_arrayNouns[_vm->_object->_objects[i].nounIndex][1]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (index & 1)
|
if (index & 1)
|
||||||
strcat(buffer, "\n");
|
strcat(buffer, "\n");
|
||||||
strcat(buffer, _vm._textParser[kTBOutro]);
|
strcat(buffer, _vm->_textParser[kTBOutro]);
|
||||||
|
|
||||||
Utils::Box(BOX_ANY, "%s", buffer);
|
Utils::Box(BOX_ANY, "%s", buffer);
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,7 +44,7 @@ enum seqTextParser {
|
||||||
|
|
||||||
class Parser {
|
class Parser {
|
||||||
public:
|
public:
|
||||||
Parser(HugoEngine &vm);
|
Parser(HugoEngine *vm);
|
||||||
virtual ~Parser();
|
virtual ~Parser();
|
||||||
|
|
||||||
bool isWordPresent(char **wordArr);
|
bool isWordPresent(char **wordArr);
|
||||||
|
@ -55,16 +55,12 @@ public:
|
||||||
virtual void lineHandler() = 0;
|
virtual void lineHandler() = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
HugoEngine &_vm;
|
HugoEngine *_vm;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool isCarrying(uint16 wordIndex);
|
|
||||||
|
|
||||||
char *findNoun();
|
char *findNoun();
|
||||||
char *findVerb();
|
char *findVerb();
|
||||||
|
|
||||||
void showTakeables();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
char _ringBuffer[32]; // Ring buffer
|
char _ringBuffer[32]; // Ring buffer
|
||||||
uint16 _putIndex;
|
uint16 _putIndex;
|
||||||
|
@ -76,7 +72,7 @@ private:
|
||||||
|
|
||||||
class Parser_v1w : public Parser {
|
class Parser_v1w : public Parser {
|
||||||
public:
|
public:
|
||||||
Parser_v1w(HugoEngine &vm);
|
Parser_v1w(HugoEngine *vm);
|
||||||
~Parser_v1w();
|
~Parser_v1w();
|
||||||
|
|
||||||
virtual void lineHandler();
|
virtual void lineHandler();
|
||||||
|
@ -95,7 +91,7 @@ private:
|
||||||
|
|
||||||
class Parser_v1d : public Parser {
|
class Parser_v1d : public Parser {
|
||||||
public:
|
public:
|
||||||
Parser_v1d(HugoEngine &vm);
|
Parser_v1d(HugoEngine *vm);
|
||||||
~Parser_v1d();
|
~Parser_v1d();
|
||||||
|
|
||||||
virtual void lineHandler();
|
virtual void lineHandler();
|
||||||
|
@ -113,7 +109,7 @@ protected:
|
||||||
|
|
||||||
class Parser_v2d : public Parser_v1d {
|
class Parser_v2d : public Parser_v1d {
|
||||||
public:
|
public:
|
||||||
Parser_v2d(HugoEngine &vm);
|
Parser_v2d(HugoEngine *vm);
|
||||||
~Parser_v2d();
|
~Parser_v2d();
|
||||||
|
|
||||||
void lineHandler();
|
void lineHandler();
|
||||||
|
@ -121,7 +117,7 @@ public:
|
||||||
|
|
||||||
class Parser_v3d : public Parser_v1w {
|
class Parser_v3d : public Parser_v1w {
|
||||||
public:
|
public:
|
||||||
Parser_v3d(HugoEngine &vm);
|
Parser_v3d(HugoEngine *vm);
|
||||||
~Parser_v3d();
|
~Parser_v3d();
|
||||||
|
|
||||||
void lineHandler();
|
void lineHandler();
|
||||||
|
|
|
@ -39,10 +39,11 @@
|
||||||
#include "hugo/file.h"
|
#include "hugo/file.h"
|
||||||
#include "hugo/schedule.h"
|
#include "hugo/schedule.h"
|
||||||
#include "hugo/util.h"
|
#include "hugo/util.h"
|
||||||
|
#include "hugo/object.h"
|
||||||
|
|
||||||
namespace Hugo {
|
namespace Hugo {
|
||||||
|
|
||||||
Parser_v1d::Parser_v1d(HugoEngine &vm) : Parser(vm) {
|
Parser_v1d::Parser_v1d(HugoEngine *vm) : Parser(vm) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Parser_v1d::~Parser_v1d() {
|
Parser_v1d::~Parser_v1d() {
|
||||||
|
@ -55,15 +56,15 @@ char *Parser_v1d::findNextNoun(char *noun) {
|
||||||
|
|
||||||
int currNounIndex = -1;
|
int currNounIndex = -1;
|
||||||
if (noun) { // If noun not NULL, find index
|
if (noun) { // If noun not NULL, find index
|
||||||
for (currNounIndex = 0; _vm._arrayNouns[currNounIndex]; currNounIndex++) {
|
for (currNounIndex = 0; _vm->_arrayNouns[currNounIndex]; currNounIndex++) {
|
||||||
if (noun == _vm._arrayNouns[currNounIndex][0])
|
if (noun == _vm->_arrayNouns[currNounIndex][0])
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (int i = currNounIndex + 1; _vm._arrayNouns[i]; i++) {
|
for (int i = currNounIndex + 1; _vm->_arrayNouns[i]; i++) {
|
||||||
for (int j = 0; strlen(_vm._arrayNouns[i][j]); j++) {
|
for (int j = 0; strlen(_vm->_arrayNouns[i][j]); j++) {
|
||||||
if (strstr(_line, _vm._arrayNouns[i][j]))
|
if (strstr(_line, _vm->_arrayNouns[i][j]))
|
||||||
return _vm._arrayNouns[i][0];
|
return _vm->_arrayNouns[i][0];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -78,33 +79,33 @@ bool Parser_v1d::isNear(char *verb, char *noun, object_t *obj, char *comment) {
|
||||||
|
|
||||||
if (!noun && !obj->verbOnlyFl) { // No noun specified & object not context senesitive
|
if (!noun && !obj->verbOnlyFl) { // No noun specified & object not context senesitive
|
||||||
return false;
|
return false;
|
||||||
} else if (noun && (noun != _vm._arrayNouns[obj->nounIndex][0])) { // Noun specified & not same as object
|
} else if (noun && (noun != _vm->_arrayNouns[obj->nounIndex][0])) { // Noun specified & not same as object
|
||||||
return false;
|
return false;
|
||||||
} else if (obj->carriedFl) { // Object is being carried
|
} else if (obj->carriedFl) { // Object is being carried
|
||||||
return true;
|
return true;
|
||||||
} else if (obj->screenIndex != *_vm._screen_p) { // Not in same screen
|
} else if (obj->screenIndex != *_vm->_screen_p) { // Not in same screen
|
||||||
if (obj->objValue)
|
if (obj->objValue)
|
||||||
strcpy (comment, _vm._textParser[kCmtAny4]);
|
strcpy (comment, _vm->_textParser[kCmtAny4]);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (obj->cycling == INVISIBLE) {
|
if (obj->cycling == INVISIBLE) {
|
||||||
if (obj->seqNumb) { // There is an image
|
if (obj->seqNumb) { // There is an image
|
||||||
strcpy(comment, _vm._textParser[kCmtAny5]);
|
strcpy(comment, _vm->_textParser[kCmtAny5]);
|
||||||
return false;
|
return false;
|
||||||
} else { // No image, assume visible
|
} else { // No image, assume visible
|
||||||
if ((obj->radius < 0) ||
|
if ((obj->radius < 0) ||
|
||||||
((abs(obj->x - _vm._hero->x) <= obj->radius) &&
|
((abs(obj->x - _vm->_hero->x) <= obj->radius) &&
|
||||||
(abs(obj->y - _vm._hero->y - _vm._hero->currImagePtr->y2) <= obj->radius))) {
|
(abs(obj->y - _vm->_hero->y - _vm->_hero->currImagePtr->y2) <= obj->radius))) {
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
// User is either not close enough (stationary, valueless objects)
|
// User is either not close enough (stationary, valueless objects)
|
||||||
// or is not carrying it (small, portable objects of value)
|
// or is not carrying it (small, portable objects of value)
|
||||||
if (noun) { // Don't say unless object specified
|
if (noun) { // Don't say unless object specified
|
||||||
if (obj->objValue && (verb != _vm._arrayVerbs[_vm._take][0]))
|
if (obj->objValue && (verb != _vm->_arrayVerbs[_vm->_take][0]))
|
||||||
strcpy(comment, _vm._textParser[kCmtAny4]);
|
strcpy(comment, _vm->_textParser[kCmtAny4]);
|
||||||
else
|
else
|
||||||
strcpy(comment, _vm._textParser[kCmtClose]);
|
strcpy(comment, _vm->_textParser[kCmtClose]);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -112,17 +113,17 @@ bool Parser_v1d::isNear(char *verb, char *noun, object_t *obj, char *comment) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((obj->radius < 0) ||
|
if ((obj->radius < 0) ||
|
||||||
((abs(obj->x - _vm._hero->x) <= obj->radius) &&
|
((abs(obj->x - _vm->_hero->x) <= obj->radius) &&
|
||||||
(abs(obj->y + obj->currImagePtr->y2 - _vm._hero->y - _vm._hero->currImagePtr->y2) <= obj->radius))) {
|
(abs(obj->y + obj->currImagePtr->y2 - _vm->_hero->y - _vm->_hero->currImagePtr->y2) <= obj->radius))) {
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
// User is either not close enough (stationary, valueless objects)
|
// User is either not close enough (stationary, valueless objects)
|
||||||
// or is not carrying it (small, portable objects of value)
|
// or is not carrying it (small, portable objects of value)
|
||||||
if (noun) { // Don't say unless object specified
|
if (noun) { // Don't say unless object specified
|
||||||
if (obj->objValue && (verb != _vm._arrayVerbs[_vm._take][0]))
|
if (obj->objValue && (verb != _vm->_arrayVerbs[_vm->_take][0]))
|
||||||
strcpy(comment, _vm._textParser[kCmtAny4]);
|
strcpy(comment, _vm->_textParser[kCmtAny4]);
|
||||||
else
|
else
|
||||||
strcpy(comment, _vm._textParser[kCmtClose]);
|
strcpy(comment, _vm->_textParser[kCmtClose]);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -140,27 +141,27 @@ bool Parser_v1d::isGenericVerb(char *word, object_t *obj) {
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Following is equivalent to switch, but couldn't do one
|
// Following is equivalent to switch, but couldn't do one
|
||||||
if (word == _vm._arrayVerbs[_vm._look][0]) {
|
if (word == _vm->_arrayVerbs[_vm->_look][0]) {
|
||||||
if ((LOOK & obj->genericCmd) == LOOK)
|
if ((LOOK & obj->genericCmd) == LOOK)
|
||||||
Utils::Box(BOX_ANY, "%s", _vm._textData[obj->dataIndex]);
|
Utils::Box(BOX_ANY, "%s", _vm->_textData[obj->dataIndex]);
|
||||||
else
|
else
|
||||||
Utils::Box(BOX_ANY, "%s", _vm._textParser[kTBUnusual_1d]);
|
Utils::Box(BOX_ANY, "%s", _vm->_textParser[kTBUnusual_1d]);
|
||||||
} else if (word == _vm._arrayVerbs[_vm._take][0]) {
|
} else if (word == _vm->_arrayVerbs[_vm->_take][0]) {
|
||||||
if (obj->carriedFl)
|
if (obj->carriedFl)
|
||||||
Utils::Box(BOX_ANY, "%s", _vm._textParser[kTBHave]);
|
Utils::Box(BOX_ANY, "%s", _vm->_textParser[kTBHave]);
|
||||||
else if ((TAKE & obj->genericCmd) == TAKE)
|
else if ((TAKE & obj->genericCmd) == TAKE)
|
||||||
takeObject(obj);
|
takeObject(obj);
|
||||||
else if (!obj->verbOnlyFl) // Make sure not taking object in context!
|
else if (!obj->verbOnlyFl) // Make sure not taking object in context!
|
||||||
Utils::Box(BOX_ANY, "%s", _vm._textParser[kTBNoUse]);
|
Utils::Box(BOX_ANY, "%s", _vm->_textParser[kTBNoUse]);
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
} else if (word == _vm._arrayVerbs[_vm._drop][0]) {
|
} else if (word == _vm->_arrayVerbs[_vm->_drop][0]) {
|
||||||
if (!obj->carriedFl)
|
if (!obj->carriedFl)
|
||||||
Utils::Box(BOX_ANY, "%s", _vm._textParser[kTBDontHave]);
|
Utils::Box(BOX_ANY, "%s", _vm->_textParser[kTBDontHave]);
|
||||||
else if ((DROP & obj->genericCmd) == DROP)
|
else if ((DROP & obj->genericCmd) == DROP)
|
||||||
dropObject(obj);
|
dropObject(obj);
|
||||||
else
|
else
|
||||||
Utils::Box(BOX_ANY, "%s", _vm._textParser[kTBNeed]);
|
Utils::Box(BOX_ANY, "%s", _vm->_textParser[kTBNeed]);
|
||||||
} else { // It was not a generic cmd
|
} else { // It was not a generic cmd
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -181,21 +182,21 @@ bool Parser_v1d::isObjectVerb(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; _vm->_cmdList[cmdIndex][i].verbIndex != 0; i++) { // For each cmd
|
||||||
if (!strcmp(word, _vm._arrayVerbs[_vm._cmdList[cmdIndex][i].verbIndex][0])) // Is this verb catered for?
|
if (!strcmp(word, _vm->_arrayVerbs[_vm->_cmdList[cmdIndex][i].verbIndex][0])) // Is this verb catered for?
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_vm._cmdList[cmdIndex][i].verbIndex == 0) // No
|
if (_vm->_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 = &_vm->_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 = _vm->_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 (!isCarrying(reqs[i])) {
|
if (!_vm->_object->isCarrying(reqs[i])) {
|
||||||
Utils::Box(BOX_ANY, "%s", _vm._textData[cmnd->textDataNoCarryIndex]);
|
Utils::Box(BOX_ANY, "%s", _vm->_textData[cmnd->textDataNoCarryIndex]);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -203,17 +204,17 @@ bool Parser_v1d::isObjectVerb(char *word, object_t *obj) {
|
||||||
|
|
||||||
// Required objects are present, now check state is correct
|
// Required objects are present, now check state is correct
|
||||||
if ((obj->state != cmnd->reqState) && (cmnd->reqState != DONT_CARE)){
|
if ((obj->state != cmnd->reqState) && (cmnd->reqState != DONT_CARE)){
|
||||||
Utils::Box(BOX_ANY, "%s", _vm._textData[cmnd->textDataWrongIndex]);
|
Utils::Box(BOX_ANY, "%s", _vm->_textData[cmnd->textDataWrongIndex]);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Everything checked. Change the state and carry out any actions
|
// Everything checked. Change the state and carry out any actions
|
||||||
if (cmnd->reqState != DONT_CARE) // Don't change new state if required state didn't care
|
if (cmnd->reqState != DONT_CARE) // Don't change new state if required state didn't care
|
||||||
obj->state = cmnd->newState;
|
obj->state = cmnd->newState;
|
||||||
Utils::Box(BOX_ANY, "%s", _vm._textData[cmnd->textDataDoneIndex]);
|
Utils::Box(BOX_ANY, "%s", _vm->_textData[cmnd->textDataDoneIndex]);
|
||||||
_vm.scheduler().insertActionList(cmnd->actIndex);
|
_vm->_scheduler->insertActionList(cmnd->actIndex);
|
||||||
// Special case if verb is Take or Drop. Assume additional generic actions
|
// Special case if verb is Take or Drop. Assume additional generic actions
|
||||||
if ((word == _vm._arrayVerbs[_vm._take][0]) || (word == _vm._arrayVerbs[_vm._drop][0]))
|
if ((word == _vm->_arrayVerbs[_vm->_take][0]) || (word == _vm->_arrayVerbs[_vm->_drop][0]))
|
||||||
isGenericVerb(word, obj);
|
isGenericVerb(word, obj);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -227,8 +228,8 @@ bool Parser_v1d::isBackgroundWord(char *noun, char *verb, objectList_t obj) {
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
for (int i = 0; obj[i].verbIndex; i++) {
|
for (int i = 0; obj[i].verbIndex; i++) {
|
||||||
if ((verb == _vm._arrayVerbs[obj[i].verbIndex][0]) && (noun == _vm._arrayNouns[obj[i].nounIndex][0])) {
|
if ((verb == _vm->_arrayVerbs[obj[i].verbIndex][0]) && (noun == _vm->_arrayNouns[obj[i].nounIndex][0])) {
|
||||||
Utils::Box(BOX_ANY, "%s", _vm.file().fetchString(obj[i].commentIndex));
|
Utils::Box(BOX_ANY, "%s", _vm->_file->fetchString(obj[i].commentIndex));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -243,9 +244,9 @@ void Parser_v1d::takeObject(object_t *obj) {
|
||||||
if (obj->seqNumb) // Don't change if no image to display
|
if (obj->seqNumb) // Don't change if no image to display
|
||||||
obj->cycling = ALMOST_INVISIBLE;
|
obj->cycling = ALMOST_INVISIBLE;
|
||||||
|
|
||||||
_vm.adjustScore(obj->objValue);
|
_vm->adjustScore(obj->objValue);
|
||||||
|
|
||||||
Utils::Box(BOX_ANY, TAKE_TEXT, _vm._arrayNouns[obj->nounIndex][TAKE_NAME]);
|
Utils::Box(BOX_ANY, TAKE_TEXT, _vm->_arrayNouns[obj->nounIndex][TAKE_NAME]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do all necessary things to drop an object
|
// Do all necessary things to drop an object
|
||||||
|
@ -253,13 +254,13 @@ void Parser_v1d::dropObject(object_t *obj) {
|
||||||
debugC(1, kDebugParser, "dropObject(object_t *obj)");
|
debugC(1, kDebugParser, "dropObject(object_t *obj)");
|
||||||
|
|
||||||
obj->carriedFl = false;
|
obj->carriedFl = false;
|
||||||
obj->screenIndex = *_vm._screen_p;
|
obj->screenIndex = *_vm->_screen_p;
|
||||||
if (obj->seqNumb) // Don't change if no image to display
|
if (obj->seqNumb) // Don't change if no image to display
|
||||||
obj->cycling = NOT_CYCLING;
|
obj->cycling = NOT_CYCLING;
|
||||||
obj->x = _vm._hero->x - 1;
|
obj->x = _vm->_hero->x - 1;
|
||||||
obj->y = _vm._hero->y + _vm._hero->currImagePtr->y2 - 1;
|
obj->y = _vm->_hero->y + _vm->_hero->currImagePtr->y2 - 1;
|
||||||
_vm.adjustScore(-obj->objValue);
|
_vm->adjustScore(-obj->objValue);
|
||||||
Utils::Box(BOX_ANY, "%s", _vm._textParser[kTBOk]);
|
Utils::Box(BOX_ANY, "%s", _vm->_textParser[kTBOk]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Print text for possible background object. Return TRUE if match found
|
// Print text for possible background object. Return TRUE if match found
|
||||||
|
@ -271,8 +272,8 @@ bool Parser_v1d::isCatchallVerb(bool testNounFl, char *noun, char *verb, objectL
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
for (int i = 0; obj[i].verbIndex; i++) {
|
for (int i = 0; obj[i].verbIndex; i++) {
|
||||||
if ((verb == _vm._arrayVerbs[obj[i].verbIndex][0]) && ((noun == _vm._arrayNouns[obj[i].nounIndex][0]) || (obj[i].nounIndex == 0))) {
|
if ((verb == _vm->_arrayVerbs[obj[i].verbIndex][0]) && ((noun == _vm->_arrayNouns[obj[i].nounIndex][0]) || (obj[i].nounIndex == 0))) {
|
||||||
Utils::Box(BOX_ANY, "%s", _vm.file().fetchString(obj[i].commentIndex));
|
Utils::Box(BOX_ANY, "%s", _vm->_file->fetchString(obj[i].commentIndex));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -284,15 +285,15 @@ void Parser_v1d::lineHandler() {
|
||||||
debugC(1, kDebugParser, "lineHandler()");
|
debugC(1, kDebugParser, "lineHandler()");
|
||||||
|
|
||||||
object_t *obj;
|
object_t *obj;
|
||||||
status_t &gameStatus = _vm.getGameStatus();
|
status_t &gameStatus = _vm->getGameStatus();
|
||||||
char farComment[XBYTES * 5] = ""; // hold 5 line comment if object not nearby
|
char farComment[XBYTES * 5] = ""; // hold 5 line comment if object not nearby
|
||||||
|
|
||||||
// Reset_prompt_line ();
|
// Reset_prompt_line ();
|
||||||
Utils::strlwr(_line); // Convert to lower case
|
Utils::strlwr(_line); // Convert to lower case
|
||||||
|
|
||||||
if (!strcmp("exit", _line) || strstr(_line, "quit")) {
|
if (!strcmp("exit", _line) || strstr(_line, "quit")) {
|
||||||
if (Utils::Box(BOX_YESNO, "%s", _vm._textParser[kTBExit_1d]) != 0)
|
if (Utils::Box(BOX_YESNO, "%s", _vm->_textParser[kTBExit_1d]) != 0)
|
||||||
_vm.endGame();
|
_vm->endGame();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -301,13 +302,13 @@ void Parser_v1d::lineHandler() {
|
||||||
if (gameStatus.gameOverFl)
|
if (gameStatus.gameOverFl)
|
||||||
Utils::gameOverMsg();
|
Utils::gameOverMsg();
|
||||||
else
|
else
|
||||||
// _vm.file().saveOrRestore(true);
|
// _vm->_file->saveOrRestore(true);
|
||||||
warning("STUB: saveOrRestore()");
|
warning("STUB: saveOrRestore()");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!strcmp("restore", _line)) {
|
if (!strcmp("restore", _line)) {
|
||||||
// _vm.file().saveOrRestore(false);
|
// _vm->_file->saveOrRestore(false);
|
||||||
warning("STUB: saveOrRestore()");
|
warning("STUB: saveOrRestore()");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -331,25 +332,25 @@ void Parser_v1d::lineHandler() {
|
||||||
do {
|
do {
|
||||||
noun = findNextNoun(noun); // Find a noun in the line
|
noun = findNextNoun(noun); // Find a noun in the line
|
||||||
// Must try at least once for objects allowing verb-context
|
// Must try at least once for objects allowing verb-context
|
||||||
for (int i = 0; i < _vm._numObj; i++) {
|
for (int i = 0; i < _vm->_numObj; i++) {
|
||||||
obj = &_vm._objects[i];
|
obj = &_vm->_object->_objects[i];
|
||||||
if (isNear(verb, noun, obj, farComment)) {
|
if (isNear(verb, noun, obj, farComment)) {
|
||||||
if (isObjectVerb(verb, obj) // Foreground object
|
if (isObjectVerb(verb, obj) // Foreground object
|
||||||
|| isGenericVerb(verb, obj)) // Common action type
|
|| isGenericVerb(verb, obj)) // Common action type
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((*farComment == '\0') && isBackgroundWord(noun, verb, _vm._backgroundObjects[*_vm._screen_p]))
|
if ((*farComment == '\0') && isBackgroundWord(noun, verb, _vm->_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(BOX_ANY, "%s", farComment);
|
Utils::Box(BOX_ANY, "%s", farComment);
|
||||||
else if (!isCatchallVerb(true, noun, verb, _vm._catchallList) &&
|
else if (!isCatchallVerb(true, noun, verb, _vm->_catchallList) &&
|
||||||
!isCatchallVerb(false, noun, verb, _vm._backgroundObjects[*_vm._screen_p]) &&
|
!isCatchallVerb(false, noun, verb, _vm->_backgroundObjects[*_vm->_screen_p]) &&
|
||||||
!isCatchallVerb(false, noun, verb, _vm._catchallList))
|
!isCatchallVerb(false, noun, verb, _vm->_catchallList))
|
||||||
Utils::Box(BOX_ANY, "%s", _vm._textParser[kTBEh_1d]);
|
Utils::Box(BOX_ANY, "%s", _vm->_textParser[kTBEh_1d]);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // End of namespace Hugo
|
} // End of namespace Hugo
|
||||||
|
|
|
@ -40,9 +40,10 @@
|
||||||
#include "hugo/schedule.h"
|
#include "hugo/schedule.h"
|
||||||
#include "hugo/util.h"
|
#include "hugo/util.h"
|
||||||
#include "hugo/sound.h"
|
#include "hugo/sound.h"
|
||||||
|
#include "hugo/object.h"
|
||||||
|
|
||||||
namespace Hugo {
|
namespace Hugo {
|
||||||
Parser_v1w::Parser_v1w(HugoEngine &vm) : Parser(vm) {
|
Parser_v1w::Parser_v1w(HugoEngine *vm) : Parser(vm) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Parser_v1w::~Parser_v1w() {
|
Parser_v1w::~Parser_v1w() {
|
||||||
|
@ -60,26 +61,26 @@ bool Parser_v1w::isObjectVerb(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; _vm->_cmdList[cmdIndex][i].verbIndex != 0; i++) { // For each cmd
|
||||||
if (isWordPresent(_vm._arrayVerbs[_vm._cmdList[cmdIndex][i].verbIndex])) // Was this verb used?
|
if (isWordPresent(_vm->_arrayVerbs[_vm->_cmdList[cmdIndex][i].verbIndex])) // Was this verb used?
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_vm._cmdList[cmdIndex][i].verbIndex == 0) // No verbs used.
|
if (_vm->_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._arrayVerbs[_vm._cmdList[cmdIndex][i].verbIndex];
|
char *verb = *_vm->_arrayVerbs[_vm->_cmdList[cmdIndex][i].verbIndex];
|
||||||
if (!isNear(obj, verb, comment))
|
if (!isNear(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 = &_vm->_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 = _vm->_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 (!isCarrying(reqs[i])) {
|
if (!_vm->_object->isCarrying(reqs[i])) {
|
||||||
Utils::Box(BOX_ANY, "%s", _vm._textData[cmnd->textDataNoCarryIndex]);
|
Utils::Box(BOX_ANY, "%s", _vm->_textData[cmnd->textDataNoCarryIndex]);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -87,18 +88,18 @@ bool Parser_v1w::isObjectVerb(object_t *obj, char *comment) {
|
||||||
|
|
||||||
// Required objects are present, now check state is correct
|
// Required objects are present, now check state is correct
|
||||||
if ((obj->state != cmnd->reqState) && (cmnd->reqState != DONT_CARE)) {
|
if ((obj->state != cmnd->reqState) && (cmnd->reqState != DONT_CARE)) {
|
||||||
Utils::Box(BOX_ANY, "%s", _vm._textData[cmnd->textDataWrongIndex]);
|
Utils::Box(BOX_ANY, "%s", _vm->_textData[cmnd->textDataWrongIndex]);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Everything checked. Change the state and carry out any actions
|
// Everything checked. Change the state and carry out any actions
|
||||||
if (cmnd->reqState != DONT_CARE) // Don't change new state if required state didn't care
|
if (cmnd->reqState != DONT_CARE) // Don't change new state if required state didn't care
|
||||||
obj->state = cmnd->newState;
|
obj->state = cmnd->newState;
|
||||||
Utils::Box(BOX_ANY, "%s", _vm._textData[cmnd->textDataDoneIndex]);
|
Utils::Box(BOX_ANY, "%s", _vm->_textData[cmnd->textDataDoneIndex]);
|
||||||
_vm.scheduler().insertActionList(cmnd->actIndex);
|
_vm->_scheduler->insertActionList(cmnd->actIndex);
|
||||||
|
|
||||||
// See if any additional generic actions
|
// See if any additional generic actions
|
||||||
if ((verb == _vm._arrayVerbs[_vm._look][0]) || (verb == _vm._arrayVerbs[_vm._take][0]) || (verb == _vm._arrayVerbs[_vm._drop][0]))
|
if ((verb == _vm->_arrayVerbs[_vm->_look][0]) || (verb == _vm->_arrayVerbs[_vm->_take][0]) || (verb == _vm->_arrayVerbs[_vm->_drop][0]))
|
||||||
isGenericVerb(obj, comment);
|
isGenericVerb(obj, comment);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -111,39 +112,39 @@ bool Parser_v1w::isGenericVerb(object_t *obj, char *comment) {
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Following is equivalent to switch, but couldn't do one
|
// Following is equivalent to switch, but couldn't do one
|
||||||
if (isWordPresent(_vm._arrayVerbs[_vm._look]) && isNear(obj, _vm._arrayVerbs[_vm._look][0], comment)) {
|
if (isWordPresent(_vm->_arrayVerbs[_vm->_look]) && isNear(obj, _vm->_arrayVerbs[_vm->_look][0], comment)) {
|
||||||
// Test state-dependent look before general look
|
// Test state-dependent look before general look
|
||||||
if ((obj->genericCmd & LOOK_S) == LOOK_S) {
|
if ((obj->genericCmd & LOOK_S) == LOOK_S) {
|
||||||
Utils::Box(BOX_ANY, "%s", _vm._textData[obj->stateDataIndex[obj->state]]);
|
Utils::Box(BOX_ANY, "%s", _vm->_textData[obj->stateDataIndex[obj->state]]);
|
||||||
warning("isGenericVerb: use of state dependant look - To be validated");
|
warning("isGenericVerb: use of state dependant look - To be validated");
|
||||||
} else {
|
} else {
|
||||||
if ((LOOK & obj->genericCmd) == LOOK) {
|
if ((LOOK & obj->genericCmd) == LOOK) {
|
||||||
if (_vm._textData[obj->dataIndex])
|
if (_vm->_textData[obj->dataIndex])
|
||||||
Utils::Box(BOX_ANY, "%s", _vm._textData[obj->dataIndex]);
|
Utils::Box(BOX_ANY, "%s", _vm->_textData[obj->dataIndex]);
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
Utils::Box(BOX_ANY, "%s", _vm._textParser[kTBUnusual]);
|
Utils::Box(BOX_ANY, "%s", _vm->_textParser[kTBUnusual]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (isWordPresent(_vm._arrayVerbs[_vm._take]) && isNear(obj, _vm._arrayVerbs[_vm._take][0], comment)) {
|
} else if (isWordPresent(_vm->_arrayVerbs[_vm->_take]) && isNear(obj, _vm->_arrayVerbs[_vm->_take][0], comment)) {
|
||||||
if (obj->carriedFl)
|
if (obj->carriedFl)
|
||||||
Utils::Box(BOX_ANY, "%s", _vm._textParser[kTBHave]);
|
Utils::Box(BOX_ANY, "%s", _vm->_textParser[kTBHave]);
|
||||||
else if ((TAKE & obj->genericCmd) == TAKE)
|
else if ((TAKE & obj->genericCmd) == TAKE)
|
||||||
takeObject(obj);
|
takeObject(obj);
|
||||||
else if (obj->cmdIndex != 0) // No comment if possible commands
|
else if (obj->cmdIndex != 0) // No comment if possible commands
|
||||||
return false;
|
return false;
|
||||||
else if (!obj->verbOnlyFl && (TAKE & obj->genericCmd) == TAKE) // Make sure not taking object in context!
|
else if (!obj->verbOnlyFl && (TAKE & obj->genericCmd) == TAKE) // Make sure not taking object in context!
|
||||||
Utils::Box(BOX_ANY, "%s", _vm._textParser[kTBNoUse]);
|
Utils::Box(BOX_ANY, "%s", _vm->_textParser[kTBNoUse]);
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
} else if (isWordPresent(_vm._arrayVerbs[_vm._drop])) {
|
} else if (isWordPresent(_vm->_arrayVerbs[_vm->_drop])) {
|
||||||
if (!obj->carriedFl && ((DROP & obj->genericCmd) == DROP))
|
if (!obj->carriedFl && ((DROP & obj->genericCmd) == DROP))
|
||||||
Utils::Box(BOX_ANY, "%s", _vm._textParser[kTBDontHave]);
|
Utils::Box(BOX_ANY, "%s", _vm->_textParser[kTBDontHave]);
|
||||||
else if (obj->carriedFl && ((DROP & obj->genericCmd) == DROP))
|
else if (obj->carriedFl && ((DROP & obj->genericCmd) == DROP))
|
||||||
dropObject(obj);
|
dropObject(obj);
|
||||||
else if (obj->cmdIndex == 0)
|
else if (obj->cmdIndex == 0)
|
||||||
Utils::Box(BOX_ANY, "%s", _vm._textParser[kTBNeed]);
|
Utils::Box(BOX_ANY, "%s", _vm->_textParser[kTBNeed]);
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
} else { // It was not a generic cmd
|
} else { // It was not a generic cmd
|
||||||
|
@ -163,47 +164,47 @@ bool Parser_v1w::isNear(object_t *obj, char *verb, char *comment) {
|
||||||
if (obj->carriedFl) // Object is being carried
|
if (obj->carriedFl) // Object is being carried
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (obj->screenIndex != *_vm._screen_p) {
|
if (obj->screenIndex != *_vm->_screen_p) {
|
||||||
// Not in same screen
|
// Not in same screen
|
||||||
if (obj->objValue)
|
if (obj->objValue)
|
||||||
strcpy(comment, _vm._textParser[kCmtAny1]);
|
strcpy(comment, _vm->_textParser[kCmtAny1]);
|
||||||
else
|
else
|
||||||
strcpy(comment, _vm._textParser[kCmtAny2]);
|
strcpy(comment, _vm->_textParser[kCmtAny2]);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (obj->cycling == INVISIBLE) {
|
if (obj->cycling == INVISIBLE) {
|
||||||
if (obj->seqNumb) {
|
if (obj->seqNumb) {
|
||||||
// There is an image
|
// There is an image
|
||||||
strcpy(comment, _vm._textParser[kCmtAny3]);
|
strcpy(comment, _vm->_textParser[kCmtAny3]);
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
// No image, assume visible
|
// No image, assume visible
|
||||||
if ((obj->radius < 0) ||
|
if ((obj->radius < 0) ||
|
||||||
((abs(obj->x - _vm._hero->x) <= obj->radius) &&
|
((abs(obj->x - _vm->_hero->x) <= obj->radius) &&
|
||||||
(abs(obj->y - _vm._hero->y - _vm._hero->currImagePtr->y2) <= obj->radius))) {
|
(abs(obj->y - _vm->_hero->y - _vm->_hero->currImagePtr->y2) <= obj->radius))) {
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
// User is not close enough
|
// User is not close enough
|
||||||
if (obj->objValue && (verb != _vm._arrayVerbs[_vm._take][0]))
|
if (obj->objValue && (verb != _vm->_arrayVerbs[_vm->_take][0]))
|
||||||
strcpy(comment, _vm._textParser[kCmtAny1]);
|
strcpy(comment, _vm->_textParser[kCmtAny1]);
|
||||||
else
|
else
|
||||||
strcpy(comment, _vm._textParser[kCmtClose]);
|
strcpy(comment, _vm->_textParser[kCmtClose]);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((obj->radius < 0) ||
|
if ((obj->radius < 0) ||
|
||||||
((abs(obj->x - _vm._hero->x) <= obj->radius) &&
|
((abs(obj->x - _vm->_hero->x) <= obj->radius) &&
|
||||||
(abs(obj->y + obj->currImagePtr->y2 - _vm._hero->y - _vm._hero->currImagePtr->y2) <= obj->radius))) {
|
(abs(obj->y + obj->currImagePtr->y2 - _vm->_hero->y - _vm->_hero->currImagePtr->y2) <= obj->radius))) {
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
// User is not close enough
|
// User is not close enough
|
||||||
if (obj->objValue && (verb != _vm._arrayVerbs[_vm._take][0]))
|
if (obj->objValue && (verb != _vm->_arrayVerbs[_vm->_take][0]))
|
||||||
strcpy(comment, _vm._textParser[kCmtAny1]);
|
strcpy(comment, _vm->_textParser[kCmtAny1]);
|
||||||
else
|
else
|
||||||
strcpy(comment, _vm._textParser[kCmtClose]);
|
strcpy(comment, _vm->_textParser[kCmtClose]);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -217,11 +218,11 @@ void Parser_v1w::takeObject(object_t *obj) {
|
||||||
if (obj->seqNumb) { // Don't change if no image to display
|
if (obj->seqNumb) { // Don't change if no image to display
|
||||||
obj->cycling = INVISIBLE;
|
obj->cycling = INVISIBLE;
|
||||||
}
|
}
|
||||||
_vm.adjustScore(obj->objValue);
|
_vm->adjustScore(obj->objValue);
|
||||||
|
|
||||||
if (obj->seqNumb > 0) // If object has an image, force walk to dropped
|
if (obj->seqNumb > 0) // If object has an image, force walk to dropped
|
||||||
obj->viewx = -1; // (possibly moved) object next time taken!
|
obj->viewx = -1; // (possibly moved) object next time taken!
|
||||||
Utils::Box(BOX_ANY, TAKE_TEXT, _vm._arrayNouns[obj->nounIndex][TAKE_NAME]);
|
Utils::Box(BOX_ANY, TAKE_TEXT, _vm->_arrayNouns[obj->nounIndex][TAKE_NAME]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do all necessary things to drop an object
|
// Do all necessary things to drop an object
|
||||||
|
@ -229,16 +230,16 @@ void Parser_v1w::dropObject(object_t *obj) {
|
||||||
debugC(1, kDebugParser, "dropObject(object_t *obj)");
|
debugC(1, kDebugParser, "dropObject(object_t *obj)");
|
||||||
|
|
||||||
obj->carriedFl = false;
|
obj->carriedFl = false;
|
||||||
obj->screenIndex = *_vm._screen_p;
|
obj->screenIndex = *_vm->_screen_p;
|
||||||
if ((obj->seqNumb > 1) || (obj->seqList[0].imageNbr > 1))
|
if ((obj->seqNumb > 1) || (obj->seqList[0].imageNbr > 1))
|
||||||
obj->cycling = CYCLE_FORWARD;
|
obj->cycling = CYCLE_FORWARD;
|
||||||
else
|
else
|
||||||
obj->cycling = NOT_CYCLING;
|
obj->cycling = NOT_CYCLING;
|
||||||
obj->x = _vm._hero->x - 1;
|
obj->x = _vm->_hero->x - 1;
|
||||||
obj->y = _vm._hero->y + _vm._hero->currImagePtr->y2 - 1;
|
obj->y = _vm->_hero->y + _vm->_hero->currImagePtr->y2 - 1;
|
||||||
obj->y = (obj->y + obj->currImagePtr->y2 < YPIX) ? obj->y : YPIX - obj->currImagePtr->y2 - 10;
|
obj->y = (obj->y + obj->currImagePtr->y2 < YPIX) ? obj->y : YPIX - obj->currImagePtr->y2 - 10;
|
||||||
_vm.adjustScore(-obj->objValue);
|
_vm->adjustScore(-obj->objValue);
|
||||||
Utils::Box(BOX_ANY, "%s", _vm._textParser[kTBOk]);
|
Utils::Box(BOX_ANY, "%s", _vm->_textParser[kTBOk]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Search for matching verbs in background command list.
|
// Search for matching verbs in background command list.
|
||||||
|
@ -249,16 +250,16 @@ bool Parser_v1w::isCatchallVerb(objectList_t obj) {
|
||||||
debugC(1, kDebugParser, "isCatchallVerb(object_list_t obj)");
|
debugC(1, kDebugParser, "isCatchallVerb(object_list_t obj)");
|
||||||
|
|
||||||
for (int i = 0; obj[i].verbIndex != 0; i++) {
|
for (int i = 0; obj[i].verbIndex != 0; i++) {
|
||||||
if (isWordPresent(_vm._arrayVerbs[obj[i].verbIndex]) && obj[i].nounIndex == 0 &&
|
if (isWordPresent(_vm->_arrayVerbs[obj[i].verbIndex]) && obj[i].nounIndex == 0 &&
|
||||||
(!obj[i].matchFl || !findNoun()) &&
|
(!obj[i].matchFl || !findNoun()) &&
|
||||||
((obj[i].roomState == DONT_CARE) ||
|
((obj[i].roomState == DONT_CARE) ||
|
||||||
(obj[i].roomState == _vm._screenStates[*_vm._screen_p]))) {
|
(obj[i].roomState == _vm->_screenStates[*_vm->_screen_p]))) {
|
||||||
Utils::Box(BOX_ANY, "%s", _vm.file().fetchString(obj[i].commentIndex));
|
Utils::Box(BOX_ANY, "%s", _vm->_file->fetchString(obj[i].commentIndex));
|
||||||
_vm.scheduler().processBonus(obj[i].bonusIndex);
|
_vm->_scheduler->processBonus(obj[i].bonusIndex);
|
||||||
|
|
||||||
// If this is LOOK (without a noun), show any takeable objects
|
// If this is LOOK (without a noun), show any takeable objects
|
||||||
if (*(_vm._arrayVerbs[obj[i].verbIndex]) == _vm._arrayVerbs[_vm._look][0])
|
if (*(_vm->_arrayVerbs[obj[i].verbIndex]) == _vm->_arrayVerbs[_vm->_look][0])
|
||||||
showTakeables();
|
_vm->_object->showTakeables();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -272,12 +273,12 @@ bool Parser_v1w::isBackgroundWord(objectList_t obj) {
|
||||||
debugC(1, kDebugParser, "isBackgroundWord(object_list_t obj)");
|
debugC(1, kDebugParser, "isBackgroundWord(object_list_t obj)");
|
||||||
|
|
||||||
for (int i = 0; obj[i].verbIndex != 0; i++) {
|
for (int i = 0; obj[i].verbIndex != 0; i++) {
|
||||||
if (isWordPresent(_vm._arrayVerbs[obj[i].verbIndex]) &&
|
if (isWordPresent(_vm->_arrayVerbs[obj[i].verbIndex]) &&
|
||||||
isWordPresent(_vm._arrayNouns[obj[i].nounIndex]) &&
|
isWordPresent(_vm->_arrayNouns[obj[i].nounIndex]) &&
|
||||||
((obj[i].roomState == DONT_CARE) ||
|
((obj[i].roomState == DONT_CARE) ||
|
||||||
(obj[i].roomState == _vm._screenStates[*_vm._screen_p]))) {
|
(obj[i].roomState == _vm->_screenStates[*_vm->_screen_p]))) {
|
||||||
Utils::Box(BOX_ANY, "%s", _vm.file().fetchString(obj[i].commentIndex));
|
Utils::Box(BOX_ANY, "%s", _vm->_file->fetchString(obj[i].commentIndex));
|
||||||
_vm.scheduler().processBonus(obj[i].bonusIndex);
|
_vm->_scheduler->processBonus(obj[i].bonusIndex);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -288,11 +289,11 @@ bool Parser_v1w::isBackgroundWord(objectList_t obj) {
|
||||||
void Parser_v1w::lineHandler() {
|
void Parser_v1w::lineHandler() {
|
||||||
debugC(1, kDebugParser, "lineHandler()");
|
debugC(1, kDebugParser, "lineHandler()");
|
||||||
|
|
||||||
status_t &gameStatus = _vm.getGameStatus();
|
status_t &gameStatus = _vm->getGameStatus();
|
||||||
|
|
||||||
// Toggle God Mode
|
// Toggle God Mode
|
||||||
if (!strncmp(_line, "PPG", 3)) {
|
if (!strncmp(_line, "PPG", 3)) {
|
||||||
_vm.sound().playSound(!_vm._soundTest, BOTH_CHANNELS, HIGH_PRI);
|
_vm->_sound->playSound(!_vm->_soundTest, BOTH_CHANNELS, HIGH_PRI);
|
||||||
gameStatus.godModeFl ^= 1;
|
gameStatus.godModeFl ^= 1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -307,9 +308,9 @@ void Parser_v1w::lineHandler() {
|
||||||
if (gameStatus.godModeFl) {
|
if (gameStatus.godModeFl) {
|
||||||
// Special code to allow me to go straight to any screen
|
// Special code to allow me to go straight to any screen
|
||||||
if (strstr(_line, "goto")) {
|
if (strstr(_line, "goto")) {
|
||||||
for (int i = 0; i < _vm._numScreens; i++) {
|
for (int i = 0; i < _vm->_numScreens; i++) {
|
||||||
if (!strcmp(&_line[strlen("goto") + 1], _vm._screenNames[i])) {
|
if (!strcmp(&_line[strlen("goto") + 1], _vm->_screenNames[i])) {
|
||||||
_vm.scheduler().newScreen(i);
|
_vm->_scheduler->newScreen(i);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -317,17 +318,17 @@ void Parser_v1w::lineHandler() {
|
||||||
|
|
||||||
// Special code to allow me to get objects from anywhere
|
// Special code to allow me to get objects from anywhere
|
||||||
if (strstr(_line, "fetch all")) {
|
if (strstr(_line, "fetch all")) {
|
||||||
for (int i = 0; i < _vm._numObj; i++) {
|
for (int i = 0; i < _vm->_numObj; i++) {
|
||||||
if (_vm._objects[i].genericCmd & TAKE)
|
if (_vm->_object->_objects[i].genericCmd & TAKE)
|
||||||
takeObject(&_vm._objects[i]);
|
takeObject(&_vm->_object->_objects[i]);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strstr(_line, "fetch")) {
|
if (strstr(_line, "fetch")) {
|
||||||
for (int i = 0; i < _vm._numObj; i++) {
|
for (int i = 0; i < _vm->_numObj; i++) {
|
||||||
if (!strcmp(&_line[strlen("fetch") + 1], _vm._arrayNouns[_vm._objects[i].nounIndex][0])) {
|
if (!strcmp(&_line[strlen("fetch") + 1], _vm->_arrayNouns[_vm->_object->_objects[i].nounIndex][0])) {
|
||||||
takeObject(&_vm._objects[i]);
|
takeObject(&_vm->_object->_objects[i]);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -335,9 +336,9 @@ void Parser_v1w::lineHandler() {
|
||||||
|
|
||||||
// Special code to allow me to goto objects
|
// Special code to allow me to goto objects
|
||||||
if (strstr(_line, "find")) {
|
if (strstr(_line, "find")) {
|
||||||
for (int i = 0; i < _vm._numObj; i++) {
|
for (int i = 0; i < _vm->_numObj; i++) {
|
||||||
if (!strcmp(&_line[strlen("find") + 1], _vm._arrayNouns[_vm._objects[i].nounIndex][0])) {
|
if (!strcmp(&_line[strlen("find") + 1], _vm->_arrayNouns[_vm->_object->_objects[i].nounIndex][0])) {
|
||||||
_vm.scheduler().newScreen(_vm._objects[i].screenIndex);
|
_vm->_scheduler->newScreen(_vm->_object->_objects[i].screenIndex);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -347,19 +348,19 @@ void Parser_v1w::lineHandler() {
|
||||||
// Special meta commands
|
// Special meta commands
|
||||||
// EXIT/QUIT
|
// EXIT/QUIT
|
||||||
if (!strcmp("exit", _line) || strstr(_line, "quit")) {
|
if (!strcmp("exit", _line) || strstr(_line, "quit")) {
|
||||||
Utils::Box(BOX_ANY, "%s", _vm._textParser[kTBExit]);
|
Utils::Box(BOX_ANY, "%s", _vm->_textParser[kTBExit]);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// SAVE/RESTORE
|
// SAVE/RESTORE
|
||||||
if (!strcmp("save", _line) && gameStatus.viewState == V_PLAY) {
|
if (!strcmp("save", _line) && gameStatus.viewState == V_PLAY) {
|
||||||
_vm.file().saveGame(gameStatus.saveSlot, "Current game");
|
_vm->_file->saveGame(gameStatus.saveSlot, "Current game");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!strcmp("restore", _line) && (gameStatus.viewState == V_PLAY || gameStatus.viewState == V_IDLE)) {
|
if (!strcmp("restore", _line) && (gameStatus.viewState == V_PLAY || gameStatus.viewState == V_IDLE)) {
|
||||||
_vm.file().restoreGame(gameStatus.saveSlot);
|
_vm->_file->restoreGame(gameStatus.saveSlot);
|
||||||
_vm.scheduler().restoreScreen(*_vm._screen_p);
|
_vm->_scheduler->restoreScreen(*_vm->_screen_p);
|
||||||
gameStatus.viewState = V_PLAY;
|
gameStatus.viewState = V_PLAY;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -379,9 +380,9 @@ void Parser_v1w::lineHandler() {
|
||||||
char farComment[XBYTES * 5] = ""; // hold 5 line comment if object not nearby
|
char farComment[XBYTES * 5] = ""; // hold 5 line comment if object not nearby
|
||||||
|
|
||||||
// Test for nearby objects referenced explicitly
|
// Test for nearby objects referenced explicitly
|
||||||
for (int i = 0; i < _vm._numObj; i++) {
|
for (int i = 0; i < _vm->_numObj; i++) {
|
||||||
object_t *obj = &_vm._objects[i];
|
object_t *obj = &_vm->_object->_objects[i];
|
||||||
if (isWordPresent(_vm._arrayNouns[obj->nounIndex])) {
|
if (isWordPresent(_vm->_arrayNouns[obj->nounIndex])) {
|
||||||
if (isObjectVerb(obj, farComment) || isGenericVerb(obj, farComment))
|
if (isObjectVerb(obj, farComment) || isGenericVerb(obj, farComment))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -389,8 +390,8 @@ void Parser_v1w::lineHandler() {
|
||||||
|
|
||||||
// Test for nearby objects that only require a verb
|
// Test for nearby objects that only require a verb
|
||||||
// Note comment is unused if not near.
|
// Note comment is unused if not near.
|
||||||
for (int i = 0; i < _vm._numObj; i++) {
|
for (int i = 0; i < _vm->_numObj; i++) {
|
||||||
object_t *obj = &_vm._objects[i];
|
object_t *obj = &_vm->_object->_objects[i];
|
||||||
if (obj->verbOnlyFl) {
|
if (obj->verbOnlyFl) {
|
||||||
char contextComment[XBYTES * 5] = ""; // Unused comment for context objects
|
char contextComment[XBYTES * 5] = ""; // Unused comment for context objects
|
||||||
if (isObjectVerb(obj, contextComment) || isGenericVerb(obj, contextComment))
|
if (isObjectVerb(obj, contextComment) || isGenericVerb(obj, contextComment))
|
||||||
|
@ -399,13 +400,13 @@ 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(_vm._backgroundObjects[*_vm._screen_p]))
|
if (isBackgroundWord(_vm->_backgroundObjects[*_vm->_screen_p]))
|
||||||
return;
|
return;
|
||||||
if (isCatchallVerb(_vm._backgroundObjects[*_vm._screen_p]))
|
if (isCatchallVerb(_vm->_backgroundObjects[*_vm->_screen_p]))
|
||||||
return;
|
return;
|
||||||
if (isBackgroundWord(_vm._catchallList))
|
if (isBackgroundWord(_vm->_catchallList))
|
||||||
return;
|
return;
|
||||||
if (isCatchallVerb(_vm._catchallList))
|
if (isCatchallVerb(_vm->_catchallList))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// If a not-near comment was generated, print it
|
// If a not-near comment was generated, print it
|
||||||
|
@ -417,17 +418,17 @@ void Parser_v1w::lineHandler() {
|
||||||
// Nothing matches. Report recognition success to user.
|
// Nothing matches. Report recognition success to user.
|
||||||
char *verb = findVerb();
|
char *verb = findVerb();
|
||||||
char *noun = findNoun();
|
char *noun = findNoun();
|
||||||
if (verb == _vm._arrayVerbs[_vm._look][0] && _maze.enabledFl) {
|
if (verb == _vm->_arrayVerbs[_vm->_look][0] && _maze.enabledFl) {
|
||||||
Utils::Box(BOX_ANY, "%s", _vm._textParser[kTBMaze]);
|
Utils::Box(BOX_ANY, "%s", _vm->_textParser[kTBMaze]);
|
||||||
showTakeables();
|
_vm->_object->showTakeables();
|
||||||
} else if (verb && noun) { // A combination I didn't think of
|
} else if (verb && noun) { // A combination I didn't think of
|
||||||
Utils::Box(BOX_ANY, "%s", _vm._textParser[kTBNoPoint]);
|
Utils::Box(BOX_ANY, "%s", _vm->_textParser[kTBNoPoint]);
|
||||||
} else if (noun) {
|
} else if (noun) {
|
||||||
Utils::Box(BOX_ANY, "%s", _vm._textParser[kTBNoun]);
|
Utils::Box(BOX_ANY, "%s", _vm->_textParser[kTBNoun]);
|
||||||
} else if (verb) {
|
} else if (verb) {
|
||||||
Utils::Box(BOX_ANY, "%s", _vm._textParser[kTBVerb]);
|
Utils::Box(BOX_ANY, "%s", _vm->_textParser[kTBVerb]);
|
||||||
} else {
|
} else {
|
||||||
Utils::Box(BOX_ANY, "%s", _vm._textParser[kTBEh]);
|
Utils::Box(BOX_ANY, "%s", _vm->_textParser[kTBEh]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -37,10 +37,11 @@
|
||||||
#include "hugo/hugo.h"
|
#include "hugo/hugo.h"
|
||||||
#include "hugo/parser.h"
|
#include "hugo/parser.h"
|
||||||
#include "hugo/util.h"
|
#include "hugo/util.h"
|
||||||
|
#include "hugo/object.h"
|
||||||
|
|
||||||
namespace Hugo {
|
namespace Hugo {
|
||||||
|
|
||||||
Parser_v2d::Parser_v2d(HugoEngine &vm) : Parser_v1d(vm) {
|
Parser_v2d::Parser_v2d(HugoEngine *vm) : Parser_v1d(vm) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Parser_v2d::~Parser_v2d() {
|
Parser_v2d::~Parser_v2d() {
|
||||||
|
@ -51,15 +52,15 @@ void Parser_v2d::lineHandler() {
|
||||||
debugC(1, kDebugParser, "lineHandler()");
|
debugC(1, kDebugParser, "lineHandler()");
|
||||||
|
|
||||||
object_t *obj;
|
object_t *obj;
|
||||||
status_t &gameStatus = _vm.getGameStatus();
|
status_t &gameStatus = _vm->getGameStatus();
|
||||||
char farComment[XBYTES * 5] = ""; // hold 5 line comment if object not nearby
|
char farComment[XBYTES * 5] = ""; // hold 5 line comment if object not nearby
|
||||||
|
|
||||||
// Reset_prompt_line ();
|
// Reset_prompt_line ();
|
||||||
Utils::strlwr(_line); // Convert to lower case
|
Utils::strlwr(_line); // Convert to lower case
|
||||||
|
|
||||||
if (!strcmp("exit", _line) || strstr(_line, "quit")) {
|
if (!strcmp("exit", _line) || strstr(_line, "quit")) {
|
||||||
if (Utils::Box(BOX_YESNO, "%s", _vm._textParser[kTBExit_1d]) != 0)
|
if (Utils::Box(BOX_YESNO, "%s", _vm->_textParser[kTBExit_1d]) != 0)
|
||||||
_vm.endGame();
|
_vm->endGame();
|
||||||
else
|
else
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -70,14 +71,14 @@ void Parser_v2d::lineHandler() {
|
||||||
if (gameStatus.gameOverFl)
|
if (gameStatus.gameOverFl)
|
||||||
Utils::gameOverMsg();
|
Utils::gameOverMsg();
|
||||||
else
|
else
|
||||||
// _vm.file().saveOrRestore(true);
|
// _vm->_file->saveOrRestore(true);
|
||||||
warning("STUB: saveOrRestore()");
|
warning("STUB: saveOrRestore()");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!strcmp("restore", _line)) {
|
if (!strcmp("restore", _line)) {
|
||||||
_config.soundFl = false;
|
_config.soundFl = false;
|
||||||
// _vm.file().saveOrRestore(false);
|
// _vm->_file->saveOrRestore(false);
|
||||||
warning("STUB: saveOrRestore()");
|
warning("STUB: saveOrRestore()");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -101,35 +102,35 @@ void Parser_v2d::lineHandler() {
|
||||||
do {
|
do {
|
||||||
noun = findNextNoun(noun); // Find a noun in the line
|
noun = findNextNoun(noun); // Find a noun in the line
|
||||||
// Must try at least once for objects allowing verb-context
|
// Must try at least once for objects allowing verb-context
|
||||||
for (int i = 0; i < _vm._numObj; i++) {
|
for (int i = 0; i < _vm->_numObj; i++) {
|
||||||
obj = &_vm._objects[i];
|
obj = &_vm->_object->_objects[i];
|
||||||
if (isNear(verb, noun, obj, farComment)) {
|
if (isNear(verb, noun, obj, farComment)) {
|
||||||
if (isObjectVerb(verb, obj) // Foreground object
|
if (isObjectVerb(verb, obj) // Foreground object
|
||||||
|| isGenericVerb(verb, obj)) // Common action type
|
|| isGenericVerb(verb, obj)) // Common action type
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((*farComment != '\0') && isBackgroundWord(noun, verb, _vm._backgroundObjects[*_vm._screen_p]))
|
if ((*farComment != '\0') && isBackgroundWord(noun, verb, _vm->_backgroundObjects[*_vm->_screen_p]))
|
||||||
return;
|
return;
|
||||||
} while (noun);
|
} while (noun);
|
||||||
}
|
}
|
||||||
|
|
||||||
noun = findNextNoun(noun);
|
noun = findNextNoun(noun);
|
||||||
if ( !isCatchallVerb(true, noun, verb, _vm._backgroundObjects[*_vm._screen_p])
|
if ( !isCatchallVerb(true, noun, verb, _vm->_backgroundObjects[*_vm->_screen_p])
|
||||||
&& !isCatchallVerb(true, noun, verb, _vm._catchallList)
|
&& !isCatchallVerb(true, noun, verb, _vm->_catchallList)
|
||||||
&& !isCatchallVerb(false, noun, verb, _vm._backgroundObjects[*_vm._screen_p])
|
&& !isCatchallVerb(false, noun, verb, _vm->_backgroundObjects[*_vm->_screen_p])
|
||||||
&& !isCatchallVerb(false, noun, verb, _vm._catchallList)) {
|
&& !isCatchallVerb(false, noun, verb, _vm->_catchallList)) {
|
||||||
if (*farComment != '\0') { // An object matched but not near enough
|
if (*farComment != '\0') { // An object matched but not near enough
|
||||||
Utils::Box(BOX_ANY, "%s", farComment);
|
Utils::Box(BOX_ANY, "%s", farComment);
|
||||||
} else if (_maze.enabledFl && (verb == _vm._arrayVerbs[_vm._look][0])) {
|
} else if (_maze.enabledFl && (verb == _vm->_arrayVerbs[_vm->_look][0])) {
|
||||||
Utils::Box(BOX_ANY, "%s", _vm._textParser[kTBMaze]);
|
Utils::Box(BOX_ANY, "%s", _vm->_textParser[kTBMaze]);
|
||||||
showTakeables();
|
_vm->_object->showTakeables();
|
||||||
} else if (verb && noun) { // A combination I didn't think of
|
} else if (verb && noun) { // A combination I didn't think of
|
||||||
Utils::Box(BOX_ANY, "%s", _vm._textParser[kTBNoUse_2d]);
|
Utils::Box(BOX_ANY, "%s", _vm->_textParser[kTBNoUse_2d]);
|
||||||
} else if (verb || noun) {
|
} else if (verb || noun) {
|
||||||
Utils::Box(BOX_ANY, "%s", _vm._textParser[kTBNoun]);
|
Utils::Box(BOX_ANY, "%s", _vm->_textParser[kTBNoun]);
|
||||||
} else {
|
} else {
|
||||||
Utils::Box(BOX_ANY, "%s", _vm._textParser[kTBEh_2d]);
|
Utils::Box(BOX_ANY, "%s", _vm->_textParser[kTBEh_2d]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,10 +39,11 @@
|
||||||
#include "hugo/schedule.h"
|
#include "hugo/schedule.h"
|
||||||
#include "hugo/util.h"
|
#include "hugo/util.h"
|
||||||
#include "hugo/sound.h"
|
#include "hugo/sound.h"
|
||||||
|
#include "hugo/object.h"
|
||||||
|
|
||||||
namespace Hugo {
|
namespace Hugo {
|
||||||
|
|
||||||
Parser_v3d::Parser_v3d(HugoEngine &vm) : Parser_v1w(vm) {
|
Parser_v3d::Parser_v3d(HugoEngine *vm) : Parser_v1w(vm) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Parser_v3d::~Parser_v3d() {
|
Parser_v3d::~Parser_v3d() {
|
||||||
|
@ -52,11 +53,11 @@ Parser_v3d::~Parser_v3d() {
|
||||||
void Parser_v3d::lineHandler() {
|
void Parser_v3d::lineHandler() {
|
||||||
debugC(1, kDebugParser, "lineHandler()");
|
debugC(1, kDebugParser, "lineHandler()");
|
||||||
|
|
||||||
status_t &gameStatus = _vm.getGameStatus();
|
status_t &gameStatus = _vm->getGameStatus();
|
||||||
|
|
||||||
// Toggle God Mode
|
// Toggle God Mode
|
||||||
if (!strncmp(_line, "PPG", 3)) {
|
if (!strncmp(_line, "PPG", 3)) {
|
||||||
_vm.sound().playSound(!_vm._soundTest, BOTH_CHANNELS, HIGH_PRI);
|
_vm->_sound->playSound(!_vm->_soundTest, BOTH_CHANNELS, HIGH_PRI);
|
||||||
gameStatus.godModeFl ^= 1;
|
gameStatus.godModeFl ^= 1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -71,9 +72,9 @@ void Parser_v3d::lineHandler() {
|
||||||
if (gameStatus.godModeFl) {
|
if (gameStatus.godModeFl) {
|
||||||
// Special code to allow me to go straight to any screen
|
// Special code to allow me to go straight to any screen
|
||||||
if (strstr(_line, "goto")) {
|
if (strstr(_line, "goto")) {
|
||||||
for (int i = 0; i < _vm._numScreens; i++) {
|
for (int i = 0; i < _vm->_numScreens; i++) {
|
||||||
if (!strcmp(&_line[strlen("goto") + 1], _vm._screenNames[i])) {
|
if (!strcmp(&_line[strlen("goto") + 1], _vm->_screenNames[i])) {
|
||||||
_vm.scheduler().newScreen(i);
|
_vm->_scheduler->newScreen(i);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -81,17 +82,17 @@ void Parser_v3d::lineHandler() {
|
||||||
|
|
||||||
// Special code to allow me to get objects from anywhere
|
// Special code to allow me to get objects from anywhere
|
||||||
if (strstr(_line, "fetch all")) {
|
if (strstr(_line, "fetch all")) {
|
||||||
for (int i = 0; i < _vm._numObj; i++) {
|
for (int i = 0; i < _vm->_numObj; i++) {
|
||||||
if (_vm._objects[i].genericCmd & TAKE)
|
if (_vm->_object->_objects[i].genericCmd & TAKE)
|
||||||
takeObject(&_vm._objects[i]);
|
takeObject(&_vm->_object->_objects[i]);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strstr(_line, "fetch")) {
|
if (strstr(_line, "fetch")) {
|
||||||
for (int i = 0; i < _vm._numObj; i++) {
|
for (int i = 0; i < _vm->_numObj; i++) {
|
||||||
if (!strcmp(&_line[strlen("fetch") + 1], _vm._arrayNouns[_vm._objects[i].nounIndex][0])) {
|
if (!strcmp(&_line[strlen("fetch") + 1], _vm->_arrayNouns[_vm->_object->_objects[i].nounIndex][0])) {
|
||||||
takeObject(&_vm._objects[i]);
|
takeObject(&_vm->_object->_objects[i]);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -99,9 +100,9 @@ void Parser_v3d::lineHandler() {
|
||||||
|
|
||||||
// Special code to allow me to goto objects
|
// Special code to allow me to goto objects
|
||||||
if (strstr(_line, "find")) {
|
if (strstr(_line, "find")) {
|
||||||
for (int i = 0; i < _vm._numObj; i++) {
|
for (int i = 0; i < _vm->_numObj; i++) {
|
||||||
if (!strcmp(&_line[strlen("find") + 1], _vm._arrayNouns[_vm._objects[i].nounIndex][0])) {
|
if (!strcmp(&_line[strlen("find") + 1], _vm->_arrayNouns[_vm->_object->_objects[i].nounIndex][0])) {
|
||||||
_vm.scheduler().newScreen(_vm._objects[i].screenIndex);
|
_vm->_scheduler->newScreen(_vm->_object->_objects[i].screenIndex);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -111,8 +112,8 @@ void Parser_v3d::lineHandler() {
|
||||||
// Special meta commands
|
// Special meta commands
|
||||||
// EXIT/QUIT
|
// EXIT/QUIT
|
||||||
if (!strcmp("exit", _line) || strstr(_line, "quit")) {
|
if (!strcmp("exit", _line) || strstr(_line, "quit")) {
|
||||||
if (Utils::Box(BOX_YESNO, "%s", _vm._textParser[kTBExit_1d]) != 0)
|
if (Utils::Box(BOX_YESNO, "%s", _vm->_textParser[kTBExit_1d]) != 0)
|
||||||
_vm.endGame();
|
_vm->endGame();
|
||||||
else
|
else
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -123,14 +124,14 @@ void Parser_v3d::lineHandler() {
|
||||||
if (gameStatus.gameOverFl)
|
if (gameStatus.gameOverFl)
|
||||||
Utils::gameOverMsg();
|
Utils::gameOverMsg();
|
||||||
else
|
else
|
||||||
// _vm.file().saveOrRestore(true);
|
// _vm->_file->saveOrRestore(true);
|
||||||
warning("STUB: saveOrRestore()");
|
warning("STUB: saveOrRestore()");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!strcmp("restore", _line)) {
|
if (!strcmp("restore", _line)) {
|
||||||
_config.soundFl = false;
|
_config.soundFl = false;
|
||||||
// _vm.file().saveOrRestore(false);
|
// _vm->_file->saveOrRestore(false);
|
||||||
warning("STUB: saveOrRestore()");
|
warning("STUB: saveOrRestore()");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -150,9 +151,9 @@ void Parser_v3d::lineHandler() {
|
||||||
char farComment[XBYTES * 5] = ""; // hold 5 line comment if object not nearby
|
char farComment[XBYTES * 5] = ""; // hold 5 line comment if object not nearby
|
||||||
|
|
||||||
// Test for nearby objects referenced explicitly
|
// Test for nearby objects referenced explicitly
|
||||||
for (int i = 0; i < _vm._numObj; i++) {
|
for (int i = 0; i < _vm->_numObj; i++) {
|
||||||
object_t *obj = &_vm._objects[i];
|
object_t *obj = &_vm->_object->_objects[i];
|
||||||
if (isWordPresent(_vm._arrayNouns[obj->nounIndex])) {
|
if (isWordPresent(_vm->_arrayNouns[obj->nounIndex])) {
|
||||||
if (isObjectVerb(obj, farComment) || isGenericVerb(obj, farComment))
|
if (isObjectVerb(obj, farComment) || isGenericVerb(obj, farComment))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -160,8 +161,8 @@ void Parser_v3d::lineHandler() {
|
||||||
|
|
||||||
// Test for nearby objects that only require a verb
|
// Test for nearby objects that only require a verb
|
||||||
// Note comment is unused if not near.
|
// Note comment is unused if not near.
|
||||||
for (int i = 0; i < _vm._numObj; i++) {
|
for (int i = 0; i < _vm->_numObj; i++) {
|
||||||
object_t *obj = &_vm._objects[i];
|
object_t *obj = &_vm->_object->_objects[i];
|
||||||
if (obj->verbOnlyFl) {
|
if (obj->verbOnlyFl) {
|
||||||
char contextComment[XBYTES * 5] = ""; // Unused comment for context objects
|
char contextComment[XBYTES * 5] = ""; // Unused comment for context objects
|
||||||
if (isObjectVerb(obj, contextComment) || isGenericVerb(obj, contextComment))
|
if (isObjectVerb(obj, contextComment) || isGenericVerb(obj, contextComment))
|
||||||
|
@ -170,13 +171,13 @@ 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(_vm._backgroundObjects[*_vm._screen_p]))
|
if (isBackgroundWord(_vm->_backgroundObjects[*_vm->_screen_p]))
|
||||||
return;
|
return;
|
||||||
if (isCatchallVerb(_vm._backgroundObjects[*_vm._screen_p]))
|
if (isCatchallVerb(_vm->_backgroundObjects[*_vm->_screen_p]))
|
||||||
return;
|
return;
|
||||||
if (isBackgroundWord(_vm._catchallList))
|
if (isBackgroundWord(_vm->_catchallList))
|
||||||
return;
|
return;
|
||||||
if (isCatchallVerb(_vm._catchallList))
|
if (isCatchallVerb(_vm->_catchallList))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// If a not-near comment was generated, print it
|
// If a not-near comment was generated, print it
|
||||||
|
@ -190,13 +191,13 @@ void Parser_v3d::lineHandler() {
|
||||||
char *noun = findNoun();
|
char *noun = findNoun();
|
||||||
|
|
||||||
if (verb && noun) { // A combination I didn't think of
|
if (verb && noun) { // A combination I didn't think of
|
||||||
Utils::Box(BOX_ANY, "%s", _vm._textParser[kTBNoPoint]);
|
Utils::Box(BOX_ANY, "%s", _vm->_textParser[kTBNoPoint]);
|
||||||
} else if (noun) {
|
} else if (noun) {
|
||||||
Utils::Box(BOX_ANY, "%s", _vm._textParser[kTBNoun]);
|
Utils::Box(BOX_ANY, "%s", _vm->_textParser[kTBNoun]);
|
||||||
} else if (verb) {
|
} else if (verb) {
|
||||||
Utils::Box(BOX_ANY, "%s", _vm._textParser[kTBVerb]);
|
Utils::Box(BOX_ANY, "%s", _vm->_textParser[kTBVerb]);
|
||||||
} else {
|
} else {
|
||||||
Utils::Box(BOX_ANY, "%s", _vm._textParser[kTBEh]);
|
Utils::Box(BOX_ANY, "%s", _vm->_textParser[kTBEh]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,16 +38,17 @@
|
||||||
#include "hugo/game.h"
|
#include "hugo/game.h"
|
||||||
#include "hugo/route.h"
|
#include "hugo/route.h"
|
||||||
#include "hugo/global.h"
|
#include "hugo/global.h"
|
||||||
|
#include "hugo/object.h"
|
||||||
|
|
||||||
namespace Hugo {
|
namespace Hugo {
|
||||||
Route::Route(HugoEngine &vm) : _vm(vm) {
|
Route::Route(HugoEngine *vm) : _vm(vm) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Face hero in new direction, based on cursor key input by user.
|
// Face hero in new direction, based on cursor key input by user.
|
||||||
void Route::setDirection(uint16 keyCode) {
|
void Route::setDirection(uint16 keyCode) {
|
||||||
debugC(1, kDebugRoute, "setDirection(%d)", keyCode);
|
debugC(1, kDebugRoute, "setDirection(%d)", keyCode);
|
||||||
|
|
||||||
object_t *obj = _vm._hero; // Pointer to hero object
|
object_t *obj = _vm->_hero; // Pointer to hero object
|
||||||
|
|
||||||
// Set first image in sequence
|
// Set first image in sequence
|
||||||
switch (keyCode) {
|
switch (keyCode) {
|
||||||
|
@ -84,9 +85,9 @@ void Route::setWalk(uint16 direction) {
|
||||||
debugC(1, kDebugRoute, "setWalk(%d)", direction);
|
debugC(1, kDebugRoute, "setWalk(%d)", direction);
|
||||||
|
|
||||||
static uint16 oldDirection = 0; // Last direction char
|
static uint16 oldDirection = 0; // Last direction char
|
||||||
object_t *obj = _vm._hero; // Pointer to hero object
|
object_t *obj = _vm->_hero; // Pointer to hero object
|
||||||
|
|
||||||
if (_vm.getGameStatus().storyModeFl || obj->pathType != USER) // Make sure user has control
|
if (_vm->getGameStatus().storyModeFl || obj->pathType != USER) // Make sure user has control
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!obj->vx && !obj->vy)
|
if (!obj->vx && !obj->vy)
|
||||||
|
@ -195,7 +196,7 @@ void Route::segment(int16 x, int16 y) {
|
||||||
if (y <= 0 || y >= YPIX - 1)
|
if (y <= 0 || y >= YPIX - 1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (_vm._hero->x < x1) {
|
if (_vm->_hero->x < x1) {
|
||||||
// Hero x not in segment, search x1..x2
|
// Hero x not in segment, search x1..x2
|
||||||
// Find all segments above current
|
// Find all segments above current
|
||||||
for (x = x1; !(_routeFoundFl | _fullStackFl | _fullSegmentFl) && x <= x2; x++) {
|
for (x = x1; !(_routeFoundFl | _fullStackFl | _fullSegmentFl) && x <= x2; x++) {
|
||||||
|
@ -208,7 +209,7 @@ void Route::segment(int16 x, int16 y) {
|
||||||
if (_boundaryMap[y + 1][x] == 0)
|
if (_boundaryMap[y + 1][x] == 0)
|
||||||
segment(x, y + 1);
|
segment(x, y + 1);
|
||||||
}
|
}
|
||||||
} else if (_vm._hero->x + HERO_MAX_WIDTH > x2) {
|
} else if (_vm->_hero->x + HERO_MAX_WIDTH > x2) {
|
||||||
// Hero x not in segment, search x1..x2
|
// Hero x not in segment, search x1..x2
|
||||||
// Find all segments above current
|
// Find all segments above current
|
||||||
for (x = x2; !(_routeFoundFl | _fullStackFl | _fullSegmentFl) && x >= x1; x--) {
|
for (x = x2; !(_routeFoundFl | _fullStackFl | _fullSegmentFl) && x >= x1; x--) {
|
||||||
|
@ -224,22 +225,22 @@ void Route::segment(int16 x, int16 y) {
|
||||||
} else {
|
} else {
|
||||||
// Organize search around hero x position - this gives
|
// Organize search around hero x position - this gives
|
||||||
// better chance for more direct route.
|
// better chance for more direct route.
|
||||||
for (x = _vm._hero->x; !(_routeFoundFl | _fullStackFl | _fullSegmentFl) && x <= x2; x++) {
|
for (x = _vm->_hero->x; !(_routeFoundFl | _fullStackFl | _fullSegmentFl) && x <= x2; x++) {
|
||||||
if (_boundaryMap[y - 1][x] == 0)
|
if (_boundaryMap[y - 1][x] == 0)
|
||||||
segment(x, y - 1);
|
segment(x, y - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (x = x1; !(_routeFoundFl | _fullStackFl | _fullSegmentFl) && x < _vm._hero->x; x++) {
|
for (x = x1; !(_routeFoundFl | _fullStackFl | _fullSegmentFl) && x < _vm->_hero->x; x++) {
|
||||||
if (_boundaryMap[y - 1][x] == 0)
|
if (_boundaryMap[y - 1][x] == 0)
|
||||||
segment(x, y - 1);
|
segment(x, y - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (x = _vm._hero->x; !(_routeFoundFl | _fullStackFl | _fullSegmentFl) && x <= x2; x++) {
|
for (x = _vm->_hero->x; !(_routeFoundFl | _fullStackFl | _fullSegmentFl) && x <= x2; x++) {
|
||||||
if (_boundaryMap[y + 1][x] == 0)
|
if (_boundaryMap[y + 1][x] == 0)
|
||||||
segment(x, y + 1);
|
segment(x, y + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (x = x1; !(_routeFoundFl | _fullStackFl | _fullSegmentFl) && x < _vm._hero->x; x++) {
|
for (x = x1; !(_routeFoundFl | _fullStackFl | _fullSegmentFl) && x < _vm->_hero->x; x++) {
|
||||||
if (_boundaryMap[y + 1][x] == 0)
|
if (_boundaryMap[y + 1][x] == 0)
|
||||||
segment(x, y + 1);
|
segment(x, y + 1);
|
||||||
}
|
}
|
||||||
|
@ -289,30 +290,30 @@ bool Route::findRoute(int16 cx, int16 cy) {
|
||||||
_destY = cy; // Destination coords
|
_destY = cy; // Destination coords
|
||||||
_destX = cx; // Destination coords
|
_destX = cx; // Destination coords
|
||||||
|
|
||||||
int16 herox1 = _vm._hero->x + _vm._hero->currImagePtr->x1; // Hero baseline
|
int16 herox1 = _vm->_hero->x + _vm->_hero->currImagePtr->x1; // Hero baseline
|
||||||
int16 herox2 = _vm._hero->x + _vm._hero->currImagePtr->x2; // Hero baseline
|
int16 herox2 = _vm->_hero->x + _vm->_hero->currImagePtr->x2; // Hero baseline
|
||||||
int16 heroy = _vm._hero->y + _vm._hero->currImagePtr->y2; // Hero baseline
|
int16 heroy = _vm->_hero->y + _vm->_hero->currImagePtr->y2; // Hero baseline
|
||||||
|
|
||||||
// Store all object baselines into objbound (except hero's = [0])
|
// Store all object baselines into objbound (except hero's = [0])
|
||||||
object_t *obj; // Ptr to object
|
object_t *obj; // Ptr to object
|
||||||
int i;
|
int i;
|
||||||
for (i = 1, obj = &_vm._objects[i]; i < _vm._numObj; i++, obj++) {
|
for (i = 1, obj = &_vm->_object->_objects[i]; i < _vm->_numObj; i++, obj++) {
|
||||||
if ((obj->screenIndex == *_vm._screen_p) && (obj->cycling != INVISIBLE) && (obj->priority == FLOATING))
|
if ((obj->screenIndex == *_vm->_screen_p) && (obj->cycling != INVISIBLE) && (obj->priority == FLOATING))
|
||||||
_vm.storeBoundary(obj->oldx + obj->currImagePtr->x1, obj->oldx + obj->currImagePtr->x2, obj->oldy + obj->currImagePtr->y2);
|
_vm->storeBoundary(obj->oldx + obj->currImagePtr->x1, obj->oldx + obj->currImagePtr->x2, obj->oldy + obj->currImagePtr->y2);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Combine objbound and boundary bitmaps to local byte map
|
// Combine objbound and boundary bitmaps to local byte map
|
||||||
for (int16 y = 0; y < YPIX; y++) {
|
for (int16 y = 0; y < YPIX; y++) {
|
||||||
for (int16 x = 0; x < XBYTES; x++) {
|
for (int16 x = 0; x < XBYTES; x++) {
|
||||||
for (i = 0; i < 8; i++)
|
for (i = 0; i < 8; i++)
|
||||||
_boundaryMap[y][x * 8 + i] = ((_vm.getObjectBoundaryOverlay()[y * XBYTES + x] | _vm.getBoundaryOverlay()[y * XBYTES + x]) & (0x80 >> i)) ? kMapBound : 0;
|
_boundaryMap[y][x * 8 + i] = ((_vm->getObjectBoundaryOverlay()[y * XBYTES + x] | _vm->getBoundaryOverlay()[y * XBYTES + x]) & (0x80 >> i)) ? kMapBound : 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear all object baselines from objbound
|
// Clear all object baselines from objbound
|
||||||
for (i = 0, obj = _vm._objects; i < _vm._numObj; i++, obj++) {
|
for (i = 0, obj = _vm->_object->_objects; i < _vm->_numObj; i++, obj++) {
|
||||||
if ((obj->screenIndex == *_vm._screen_p) && (obj->cycling != INVISIBLE) && (obj->priority == FLOATING))
|
if ((obj->screenIndex == *_vm->_screen_p) && (obj->cycling != INVISIBLE) && (obj->priority == FLOATING))
|
||||||
_vm.clearBoundary(obj->oldx + obj->currImagePtr->x1, obj->oldx + obj->currImagePtr->x2, obj->oldy + obj->currImagePtr->y2);
|
_vm->clearBoundary(obj->oldx + obj->currImagePtr->x1, obj->oldx + obj->currImagePtr->x2, obj->oldy + obj->currImagePtr->y2);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Search from hero to destination
|
// Search from hero to destination
|
||||||
|
@ -389,43 +390,43 @@ 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
|
||||||
|
|
||||||
// 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();
|
status_t &gameStatus = _vm->getGameStatus();
|
||||||
Point *routeNode = &_route[gameStatus.routeIndex];
|
Point *routeNode = &_route[gameStatus.routeIndex];
|
||||||
|
|
||||||
// Arrived at node?
|
// Arrived at node?
|
||||||
if (abs(herox - routeNode->x) < DX + 1 && abs(heroy - routeNode->y) < DY) {
|
if (abs(herox - routeNode->x) < DX + 1 && abs(heroy - routeNode->y) < DY) {
|
||||||
// DX too low
|
// DX too low
|
||||||
// Close enough - position hero exactly
|
// Close enough - position hero exactly
|
||||||
_vm._hero->x = _vm._hero->oldx = routeNode->x - _vm._hero->currImagePtr->x1;
|
_vm->_hero->x = _vm->_hero->oldx = routeNode->x - _vm->_hero->currImagePtr->x1;
|
||||||
_vm._hero->y = _vm._hero->oldy = routeNode->y - _vm._hero->currImagePtr->y2;
|
_vm->_hero->y = _vm->_hero->oldy = routeNode->y - _vm->_hero->currImagePtr->y2;
|
||||||
_vm._hero->vx = _vm._hero->vy = 0;
|
_vm->_hero->vx = _vm->_hero->vy = 0;
|
||||||
_vm._hero->cycling = NOT_CYCLING;
|
_vm->_hero->cycling = NOT_CYCLING;
|
||||||
|
|
||||||
// Arrived at final node?
|
// Arrived at final node?
|
||||||
if (--gameStatus.routeIndex < 0) {
|
if (--gameStatus.routeIndex < 0) {
|
||||||
// See why we walked here
|
// See why we walked here
|
||||||
switch (gameStatus.go_for) {
|
switch (gameStatus.go_for) {
|
||||||
case GO_EXIT: // Walked to an exit, proceed into it
|
case GO_EXIT: // Walked to an exit, proceed into it
|
||||||
setWalk(_vm._hotspots[gameStatus.go_id].direction);
|
setWalk(_vm->_hotspots[gameStatus.go_id].direction);
|
||||||
break;
|
break;
|
||||||
case GO_LOOK: // Look at an object
|
case GO_LOOK: // Look at an object
|
||||||
if (turnedFl) {
|
if (turnedFl) {
|
||||||
_vm.lookObject(&_vm._objects[gameStatus.go_id]);
|
_vm->_object->lookObject(&_vm->_object->_objects[gameStatus.go_id]);
|
||||||
turnedFl = false;
|
turnedFl = false;
|
||||||
} else {
|
} else {
|
||||||
setDirection(_vm._objects[gameStatus.go_id].direction);
|
setDirection(_vm->_object->_objects[gameStatus.go_id].direction);
|
||||||
gameStatus.routeIndex++; // Come round again
|
gameStatus.routeIndex++; // Come round again
|
||||||
turnedFl = true;
|
turnedFl = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case GO_GET: // Get (or use) an object
|
case GO_GET: // Get (or use) an object
|
||||||
if (turnedFl) {
|
if (turnedFl) {
|
||||||
_vm.useObject(gameStatus.go_id);
|
_vm->_object->useObject(gameStatus.go_id);
|
||||||
turnedFl = false;
|
turnedFl = false;
|
||||||
} else {
|
} else {
|
||||||
setDirection(_vm._objects[gameStatus.go_id].direction);
|
setDirection(_vm->_object->_objects[gameStatus.go_id].direction);
|
||||||
gameStatus.routeIndex++; // Come round again
|
gameStatus.routeIndex++; // Come round again
|
||||||
turnedFl = true;
|
turnedFl = true;
|
||||||
}
|
}
|
||||||
|
@ -435,7 +436,7 @@ void Route::processRoute() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (_vm._hero->vx == 0 && _vm._hero->vy == 0) {
|
} else if (_vm->_hero->vx == 0 && _vm->_hero->vy == 0) {
|
||||||
// Set direction of travel if at a node
|
// Set direction of travel if at a node
|
||||||
// Note realignment when changing to (thinner) up/down sprite,
|
// Note realignment when changing to (thinner) up/down sprite,
|
||||||
// otherwise hero could bump into boundaries along route.
|
// otherwise hero could bump into boundaries along route.
|
||||||
|
@ -445,10 +446,10 @@ void Route::processRoute() {
|
||||||
setWalk(Common::KEYCODE_LEFT);
|
setWalk(Common::KEYCODE_LEFT);
|
||||||
} else if (heroy < routeNode->y) {
|
} else if (heroy < routeNode->y) {
|
||||||
setWalk(Common::KEYCODE_DOWN);
|
setWalk(Common::KEYCODE_DOWN);
|
||||||
_vm._hero->x = _vm._hero->oldx = routeNode->x - _vm._hero->currImagePtr->x1;
|
_vm->_hero->x = _vm->_hero->oldx = routeNode->x - _vm->_hero->currImagePtr->x1;
|
||||||
} else if (heroy > routeNode->y) {
|
} else if (heroy > routeNode->y) {
|
||||||
setWalk(Common::KEYCODE_UP);
|
setWalk(Common::KEYCODE_UP);
|
||||||
_vm._hero->x = _vm._hero->oldx = routeNode->x - _vm._hero->currImagePtr->x1;
|
_vm->_hero->x = _vm->_hero->oldx = routeNode->x - _vm->_hero->currImagePtr->x1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -460,10 +461,10 @@ bool Route::startRoute(go_t go_for, int16 id, int16 cx, int16 cy) {
|
||||||
debugC(1, kDebugRoute, "startRoute(%d, %d, %d, %d)", go_for, id, cx, cy);
|
debugC(1, kDebugRoute, "startRoute(%d, %d, %d, %d)", go_for, id, cx, cy);
|
||||||
|
|
||||||
// Don't attempt to walk if user does not have control
|
// Don't attempt to walk if user does not have control
|
||||||
if (_vm._hero->pathType != USER)
|
if (_vm->_hero->pathType != USER)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
status_t &gameStatus = _vm.getGameStatus();
|
status_t &gameStatus = _vm->getGameStatus();
|
||||||
// if inventory showing, make it go away
|
// if inventory showing, make it go away
|
||||||
if (gameStatus.inventoryState != I_OFF)
|
if (gameStatus.inventoryState != I_OFF)
|
||||||
gameStatus.inventoryState = I_UP;
|
gameStatus.inventoryState = I_UP;
|
||||||
|
@ -478,7 +479,7 @@ bool Route::startRoute(go_t go_for, int16 id, int16 cx, int16 cy) {
|
||||||
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
|
gameStatus.routeIndex = _routeListIndex; // Node index
|
||||||
_vm._hero->vx = _vm._hero->vy = 0; // Stop manual motion
|
_vm->_hero->vx = _vm->_hero->vy = 0; // Stop manual motion
|
||||||
}
|
}
|
||||||
|
|
||||||
return foundFl;
|
return foundFl;
|
||||||
|
|
|
@ -53,7 +53,7 @@ struct segment_t { // Search segment
|
||||||
|
|
||||||
class Route {
|
class Route {
|
||||||
public:
|
public:
|
||||||
Route(HugoEngine &vm);
|
Route(HugoEngine *vm);
|
||||||
|
|
||||||
void processRoute();
|
void processRoute();
|
||||||
bool startRoute(go_t go_for, short id, short cx, short cy);
|
bool startRoute(go_t go_for, short id, short cx, short cy);
|
||||||
|
@ -61,7 +61,7 @@ public:
|
||||||
void setWalk(uint16 direction);
|
void setWalk(uint16 direction);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
HugoEngine &_vm;
|
HugoEngine *_vm;
|
||||||
|
|
||||||
byte _boundaryMap[YPIX][XPIX]; // Boundary byte map
|
byte _boundaryMap[YPIX][XPIX]; // Boundary byte map
|
||||||
segment_t _segment[kMaxSeg]; // List of points in fill-path
|
segment_t _segment[kMaxSeg]; // List of points in fill-path
|
||||||
|
|
|
@ -43,12 +43,13 @@
|
||||||
#include "hugo/parser.h"
|
#include "hugo/parser.h"
|
||||||
#include "hugo/util.h"
|
#include "hugo/util.h"
|
||||||
#include "hugo/sound.h"
|
#include "hugo/sound.h"
|
||||||
|
#include "hugo/object.h"
|
||||||
|
|
||||||
namespace Hugo {
|
namespace Hugo {
|
||||||
|
|
||||||
#define SIGN(X) ((X < 0) ? -1 : 1)
|
#define SIGN(X) ((X < 0) ? -1 : 1)
|
||||||
|
|
||||||
Scheduler::Scheduler(HugoEngine &vm) : _vm(vm) {
|
Scheduler::Scheduler(HugoEngine *vm) : _vm(vm) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Scheduler::~Scheduler() {
|
Scheduler::~Scheduler() {
|
||||||
|
@ -169,9 +170,9 @@ void Scheduler::insertActionList(uint16 actIndex) {
|
||||||
// Call Insert_action for each action in the list supplied
|
// Call Insert_action for each action in the list supplied
|
||||||
debugC(1, kDebugSchedule, "insertActionList(%d)", actIndex);
|
debugC(1, kDebugSchedule, "insertActionList(%d)", actIndex);
|
||||||
|
|
||||||
if (_vm._actListArr[actIndex]) {
|
if (_vm->_actListArr[actIndex]) {
|
||||||
for (int i = 0; _vm._actListArr[actIndex][i].a0.actType != ANULL; i++)
|
for (int i = 0; _vm->_actListArr[actIndex][i].a0.actType != ANULL; i++)
|
||||||
insertAction(&_vm._actListArr[actIndex][i]);
|
insertAction(&_vm->_actListArr[actIndex][i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -192,7 +193,7 @@ event_t *Scheduler::doAction(event_t *curEvent) {
|
||||||
// to the next action in the list, except special case of NEW_SCREEN
|
// to the next action in the list, except special case of NEW_SCREEN
|
||||||
debugC(1, kDebugSchedule, "doAction - Event action type : %d", curEvent->action->a0.actType);
|
debugC(1, kDebugSchedule, "doAction - Event action type : %d", curEvent->action->a0.actType);
|
||||||
|
|
||||||
status_t &gameStatus = _vm.getGameStatus();
|
status_t &gameStatus = _vm->getGameStatus();
|
||||||
act *action = curEvent->action;
|
act *action = curEvent->action;
|
||||||
char *response; // User's response string
|
char *response; // User's response string
|
||||||
object_t *obj1;
|
object_t *obj1;
|
||||||
|
@ -208,16 +209,16 @@ event_t *Scheduler::doAction(event_t *curEvent) {
|
||||||
insertActionList(action->a0.actIndex);
|
insertActionList(action->a0.actIndex);
|
||||||
break;
|
break;
|
||||||
case START_OBJ: // act1: Start an object cycling
|
case START_OBJ: // act1: Start an object cycling
|
||||||
_vm._objects[action->a1.objNumb].cycleNumb = action->a1.cycleNumb;
|
_vm->_object->_objects[action->a1.objNumb].cycleNumb = action->a1.cycleNumb;
|
||||||
_vm._objects[action->a1.objNumb].cycling = action->a1.cycle;
|
_vm->_object->_objects[action->a1.objNumb].cycling = action->a1.cycle;
|
||||||
break;
|
break;
|
||||||
case INIT_OBJXY: // act2: Initialise an object
|
case INIT_OBJXY: // act2: Initialise an object
|
||||||
_vm._objects[action->a2.objNumb].x = action->a2.x; // Coordinates
|
_vm->_object->_objects[action->a2.objNumb].x = action->a2.x; // Coordinates
|
||||||
_vm._objects[action->a2.objNumb].y = action->a2.y;
|
_vm->_object->_objects[action->a2.objNumb].y = action->a2.y;
|
||||||
break;
|
break;
|
||||||
case PROMPT: { // act3: Prompt user for key phrase
|
case PROMPT: { // act3: Prompt user for key phrase
|
||||||
// TODO : Add specific code for Hugo 1 DOS, which is handled differently,
|
// TODO : Add specific code for Hugo 1 DOS, which is handled differently,
|
||||||
response = Utils::Box(BOX_PROMPT, "%s", _vm.file().fetchString(action->a3.promptIndex));
|
response = Utils::Box(BOX_PROMPT, "%s", _vm->_file->fetchString(action->a3.promptIndex));
|
||||||
|
|
||||||
warning("STUB: doAction(act3), expecting answer %s", response);
|
warning("STUB: doAction(act3), expecting answer %s", response);
|
||||||
|
|
||||||
|
@ -227,7 +228,7 @@ event_t *Scheduler::doAction(event_t *curEvent) {
|
||||||
char *tmpStr; // General purpose string ptr
|
char *tmpStr; // General purpose string ptr
|
||||||
|
|
||||||
for (found = false, dx = 0; !found && (action->a3.responsePtr[dx] != -1); dx++) {
|
for (found = false, dx = 0; !found && (action->a3.responsePtr[dx] != -1); dx++) {
|
||||||
tmpStr = _vm.file().Fetch_string(action->a3.responsePtr[dx]);
|
tmpStr = _vm->_file->Fetch_string(action->a3.responsePtr[dx]);
|
||||||
if (strstr(Utils::strlwr(response) , tmpStr))
|
if (strstr(Utils::strlwr(response) , tmpStr))
|
||||||
found = true;
|
found = true;
|
||||||
}
|
}
|
||||||
|
@ -243,53 +244,50 @@ event_t *Scheduler::doAction(event_t *curEvent) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case BKGD_COLOR: // act4: Set new background color
|
case BKGD_COLOR: // act4: Set new background color
|
||||||
_vm.screen().setBackgroundColor(action->a4.newBackgroundColor);
|
_vm->_screen->setBackgroundColor(action->a4.newBackgroundColor);
|
||||||
break;
|
break;
|
||||||
case INIT_OBJVXY: // act5: Initialise an object
|
case INIT_OBJVXY: // act5: Initialise an object velocity
|
||||||
_vm._objects[action->a5.objNumb].vx = action->a5.vx; // velocities
|
_vm->_object->setVelocity(action->a5.objNumb, action->a5.vx, action->a5.vy);
|
||||||
_vm._objects[action->a5.objNumb].vy = action->a5.vy;
|
|
||||||
break;
|
break;
|
||||||
case INIT_CARRY: // act6: Initialise an object
|
case INIT_CARRY: // act6: Initialise an object
|
||||||
_vm._objects[action->a6.objNumb].carriedFl = action->a6.carriedFl; // carried status
|
_vm->_object->setCarry(action->a6.objNumb, action->a6.carriedFl); // carried status
|
||||||
break;
|
break;
|
||||||
case INIT_HF_COORD: // act7: Initialise an object to hero's "feet" coords
|
case INIT_HF_COORD: // act7: Initialise an object to hero's "feet" coords
|
||||||
_vm._objects[action->a7.objNumb].x = _vm._hero->x - 1;
|
_vm->_object->_objects[action->a7.objNumb].x = _vm->_hero->x - 1;
|
||||||
_vm._objects[action->a7.objNumb].y = _vm._hero->y + _vm._hero->currImagePtr->y2 - 1;
|
_vm->_object->_objects[action->a7.objNumb].y = _vm->_hero->y + _vm->_hero->currImagePtr->y2 - 1;
|
||||||
_vm._objects[action->a7.objNumb].screenIndex = *_vm._screen_p; // Don't forget screen!
|
_vm->_object->_objects[action->a7.objNumb].screenIndex = *_vm->_screen_p; // Don't forget screen!
|
||||||
break;
|
break;
|
||||||
case NEW_SCREEN: // act8: Start new screen
|
case NEW_SCREEN: // act8: Start new screen
|
||||||
newScreen(action->a8.screenIndex);
|
newScreen(action->a8.screenIndex);
|
||||||
break;
|
break;
|
||||||
case INIT_OBJSTATE: // act9: Initialise an object state
|
case INIT_OBJSTATE: // act9: Initialise an object state
|
||||||
_vm._objects[action->a9.objNumb].state = action->a9.newState;
|
_vm->_object->_objects[action->a9.objNumb].state = action->a9.newState;
|
||||||
break;
|
break;
|
||||||
case INIT_PATH: // act10: Initialise an object path and velocity
|
case INIT_PATH: // act10: Initialise an object path and velocity
|
||||||
_vm._objects[action->a10.objNumb].pathType = (path_t) action->a10.newPathType;
|
_vm->_object->setPath(action->a10.objNumb, (path_t) action->a10.newPathType, action->a10.vxPath, action->a10.vyPath);
|
||||||
_vm._objects[action->a10.objNumb].vxPath = action->a10.vxPath;
|
|
||||||
_vm._objects[action->a10.objNumb].vyPath = action->a10.vyPath;
|
|
||||||
break;
|
break;
|
||||||
case COND_R: // act11: action lists conditional on object state
|
case COND_R: // act11: action lists conditional on object state
|
||||||
if (_vm._objects[action->a11.objNumb].state == action->a11.stateReq)
|
if (_vm->_object->_objects[action->a11.objNumb].state == action->a11.stateReq)
|
||||||
insertActionList(action->a11.actPassIndex);
|
insertActionList(action->a11.actPassIndex);
|
||||||
else
|
else
|
||||||
insertActionList(action->a11.actFailIndex);
|
insertActionList(action->a11.actFailIndex);
|
||||||
break;
|
break;
|
||||||
case TEXT: // act12: Text box (CF WARN)
|
case TEXT: // act12: Text box (CF WARN)
|
||||||
Utils::Box(BOX_ANY, "%s", _vm.file().fetchString(action->a12.stringIndex)); // Fetch string from file
|
Utils::Box(BOX_ANY, "%s", _vm->_file->fetchString(action->a12.stringIndex)); // Fetch string from file
|
||||||
break;
|
break;
|
||||||
case SWAP_IMAGES: // act13: Swap 2 object images
|
case SWAP_IMAGES: // act13: Swap 2 object images
|
||||||
swapImages(action->a13.obj1, action->a13.obj2);
|
_vm->_object->swapImages(action->a13.obj1, action->a13.obj2);
|
||||||
break;
|
break;
|
||||||
case COND_SCR: // act14: Conditional on current screen
|
case COND_SCR: // act14: Conditional on current screen
|
||||||
if (_vm._objects[action->a14.objNumb].screenIndex == action->a14.screenReq)
|
if (_vm->_object->_objects[action->a14.objNumb].screenIndex == action->a14.screenReq)
|
||||||
insertActionList(action->a14.actPassIndex);
|
insertActionList(action->a14.actPassIndex);
|
||||||
else
|
else
|
||||||
insertActionList(action->a14.actFailIndex);
|
insertActionList(action->a14.actFailIndex);
|
||||||
break;
|
break;
|
||||||
case AUTOPILOT: // act15: Home in on a (stationary) object
|
case AUTOPILOT: // act15: Home in on a (stationary) object
|
||||||
// object p1 will home in on object p2
|
// object p1 will home in on object p2
|
||||||
obj1 = &_vm._objects[action->a15.obj1];
|
obj1 = &_vm->_object->_objects[action->a15.obj1];
|
||||||
obj2 = &_vm._objects[action->a15.obj2];
|
obj2 = &_vm->_object->_objects[action->a15.obj2];
|
||||||
obj1->pathType = AUTO;
|
obj1->pathType = AUTO;
|
||||||
dx = obj1->x + obj1->currImagePtr->x1 - obj2->x - obj2->currImagePtr->x1;
|
dx = obj1->x + obj1->currImagePtr->x1 - obj2->x - obj2->currImagePtr->x1;
|
||||||
dy = obj1->y + obj1->currImagePtr->y1 - obj2->y - obj2->currImagePtr->y1;
|
dy = obj1->y + obj1->currImagePtr->y1 - obj2->y - obj2->currImagePtr->y1;
|
||||||
|
@ -310,16 +308,16 @@ event_t *Scheduler::doAction(event_t *curEvent) {
|
||||||
case INIT_OBJ_SEQ: // act16: Set sequence number to use
|
case INIT_OBJ_SEQ: // act16: Set sequence number to use
|
||||||
// Note: Don't set a sequence at time 0 of a new screen, it causes
|
// Note: Don't set a sequence at time 0 of a new screen, it causes
|
||||||
// problems clearing the boundary bits of the object! t>0 is safe
|
// problems clearing the boundary bits of the object! t>0 is safe
|
||||||
_vm._objects[action->a16.objNumb].currImagePtr = _vm._objects[action->a16.objNumb].seqList[action->a16.seqIndex].seqPtr;
|
_vm->_object->_objects[action->a16.objNumb].currImagePtr = _vm->_object->_objects[action->a16.objNumb].seqList[action->a16.seqIndex].seqPtr;
|
||||||
break;
|
break;
|
||||||
case SET_STATE_BITS: // act17: OR mask with curr obj state
|
case SET_STATE_BITS: // act17: OR mask with curr obj state
|
||||||
_vm._objects[action->a17.objNumb].state |= action->a17.stateMask;
|
_vm->_object->_objects[action->a17.objNumb].state |= action->a17.stateMask;
|
||||||
break;
|
break;
|
||||||
case CLEAR_STATE_BITS: // act18: AND ~mask with curr obj state
|
case CLEAR_STATE_BITS: // act18: AND ~mask with curr obj state
|
||||||
_vm._objects[action->a18.objNumb].state &= ~action->a18.stateMask;
|
_vm->_object->_objects[action->a18.objNumb].state &= ~action->a18.stateMask;
|
||||||
break;
|
break;
|
||||||
case TEST_STATE_BITS: // act19: If all bits set, do apass else afail
|
case TEST_STATE_BITS: // act19: If all bits set, do apass else afail
|
||||||
if ((_vm._objects[action->a19.objNumb].state & action->a19.stateMask) == action->a19.stateMask)
|
if ((_vm->_object->_objects[action->a19.objNumb].state & action->a19.stateMask) == action->a19.stateMask)
|
||||||
insertActionList(action->a19.actPassIndex);
|
insertActionList(action->a19.actPassIndex);
|
||||||
else
|
else
|
||||||
insertActionList(action->a19.actFailIndex);
|
insertActionList(action->a19.actFailIndex);
|
||||||
|
@ -340,18 +338,18 @@ event_t *Scheduler::doAction(event_t *curEvent) {
|
||||||
gameStatus.gameOverFl = true;
|
gameStatus.gameOverFl = true;
|
||||||
break;
|
break;
|
||||||
case INIT_HH_COORD: // act22: Initialise an object to hero's actual coords
|
case INIT_HH_COORD: // act22: Initialise an object to hero's actual coords
|
||||||
_vm._objects[action->a22.objNumb].x = _vm._hero->x;
|
_vm->_object->_objects[action->a22.objNumb].x = _vm->_hero->x;
|
||||||
_vm._objects[action->a22.objNumb].y = _vm._hero->y;
|
_vm->_object->_objects[action->a22.objNumb].y = _vm->_hero->y;
|
||||||
_vm._objects[action->a22.objNumb].screenIndex = *_vm._screen_p;// Don't forget screen!
|
_vm->_object->_objects[action->a22.objNumb].screenIndex = *_vm->_screen_p;// Don't forget screen!
|
||||||
break;
|
break;
|
||||||
case EXIT: // act23: Exit game back to DOS
|
case EXIT: // act23: Exit game back to DOS
|
||||||
_vm.endGame();
|
_vm->endGame();
|
||||||
break;
|
break;
|
||||||
case BONUS: // act24: Get bonus score for action
|
case BONUS: // act24: Get bonus score for action
|
||||||
processBonus(action->a24.pointIndex);
|
processBonus(action->a24.pointIndex);
|
||||||
break;
|
break;
|
||||||
case COND_BOX: // act25: Conditional on bounding box
|
case COND_BOX: // act25: Conditional on bounding box
|
||||||
obj1 = &_vm._objects[action->a25.objNumb];
|
obj1 = &_vm->_object->_objects[action->a25.objNumb];
|
||||||
dx = obj1->x + obj1->currImagePtr->x1;
|
dx = obj1->x + obj1->currImagePtr->x1;
|
||||||
dy = obj1->y + obj1->currImagePtr->y2;
|
dy = obj1->y + obj1->currImagePtr->y2;
|
||||||
if ((dx >= action->a25.x1) && (dx <= action->a25.x2) &&
|
if ((dx >= action->a25.x1) && (dx <= action->a25.x2) &&
|
||||||
|
@ -361,19 +359,19 @@ event_t *Scheduler::doAction(event_t *curEvent) {
|
||||||
insertActionList(action->a25.actFailIndex);
|
insertActionList(action->a25.actFailIndex);
|
||||||
break;
|
break;
|
||||||
case SOUND: // act26: Play a sound (or tune)
|
case SOUND: // act26: Play a sound (or tune)
|
||||||
if (action->a26.soundIndex < _vm._tunesNbr)
|
if (action->a26.soundIndex < _vm->_tunesNbr)
|
||||||
_vm.sound().playMusic(action->a26.soundIndex);
|
_vm->_sound->playMusic(action->a26.soundIndex);
|
||||||
else
|
else
|
||||||
_vm.sound().playSound(action->a26.soundIndex, BOTH_CHANNELS, MED_PRI);
|
_vm->_sound->playSound(action->a26.soundIndex, BOTH_CHANNELS, MED_PRI);
|
||||||
break;
|
break;
|
||||||
case ADD_SCORE: // act27: Add object's value to score
|
case ADD_SCORE: // act27: Add object's value to score
|
||||||
_vm.adjustScore(_vm._objects[action->a27.objNumb].objValue);
|
_vm->adjustScore(_vm->_object->_objects[action->a27.objNumb].objValue);
|
||||||
break;
|
break;
|
||||||
case SUB_SCORE: // act28: Subtract object's value from score
|
case SUB_SCORE: // act28: Subtract object's value from score
|
||||||
_vm.adjustScore(-_vm._objects[action->a28.objNumb].objValue);
|
_vm->adjustScore(-_vm->_object->_objects[action->a28.objNumb].objValue);
|
||||||
break;
|
break;
|
||||||
case COND_CARRY: // act29: Conditional on object being carried
|
case COND_CARRY: // act29: Conditional on object being carried
|
||||||
if (_vm._objects[action->a29.objNumb].carriedFl)
|
if (_vm->_object->isCarried(action->a29.objNumb))
|
||||||
insertActionList(action->a29.actPassIndex);
|
insertActionList(action->a29.actPassIndex);
|
||||||
else
|
else
|
||||||
insertActionList(action->a29.actFailIndex);
|
insertActionList(action->a29.actFailIndex);
|
||||||
|
@ -393,31 +391,31 @@ event_t *Scheduler::doAction(event_t *curEvent) {
|
||||||
_maze.enabledFl = false;
|
_maze.enabledFl = false;
|
||||||
break;
|
break;
|
||||||
case INIT_PRIORITY:
|
case INIT_PRIORITY:
|
||||||
_vm._objects[action->a32.objNumb].priority = action->a32.priority;
|
_vm->_object->_objects[action->a32.objNumb].priority = action->a32.priority;
|
||||||
break;
|
break;
|
||||||
case INIT_SCREEN:
|
case INIT_SCREEN:
|
||||||
_vm._objects[action->a33.objNumb].screenIndex = action->a33.screenIndex;
|
_vm->_object->_objects[action->a33.objNumb].screenIndex = action->a33.screenIndex;
|
||||||
break;
|
break;
|
||||||
case AGSCHEDULE: // act34: Schedule a (global) action list
|
case AGSCHEDULE: // act34: Schedule a (global) action list
|
||||||
insertActionList(action->a34.actIndex);
|
insertActionList(action->a34.actIndex);
|
||||||
break;
|
break;
|
||||||
case REMAPPAL: // act35: Remap a palette color
|
case REMAPPAL: // act35: Remap a palette color
|
||||||
_vm.screen().remapPal(action->a35.oldColorIndex, action->a35.newColorIndex);
|
_vm->_screen->remapPal(action->a35.oldColorIndex, action->a35.newColorIndex);
|
||||||
break;
|
break;
|
||||||
case COND_NOUN: // act36: Conditional on noun mentioned
|
case COND_NOUN: // act36: Conditional on noun mentioned
|
||||||
if (_vm.parser().isWordPresent(_vm._arrayNouns[action->a36.nounIndex]))
|
if (_vm->_parser->isWordPresent(_vm->_arrayNouns[action->a36.nounIndex]))
|
||||||
insertActionList(action->a36.actPassIndex);
|
insertActionList(action->a36.actPassIndex);
|
||||||
else
|
else
|
||||||
insertActionList(action->a36.actFailIndex);
|
insertActionList(action->a36.actFailIndex);
|
||||||
break;
|
break;
|
||||||
case SCREEN_STATE: // act37: Set new screen state
|
case SCREEN_STATE: // act37: Set new screen state
|
||||||
_vm._screenStates[action->a37.screenIndex] = action->a37.newState;
|
_vm->_screenStates[action->a37.screenIndex] = action->a37.newState;
|
||||||
break;
|
break;
|
||||||
case INIT_LIPS: // act38: Position lips on object
|
case INIT_LIPS: // act38: Position lips on object
|
||||||
_vm._objects[action->a38.lipsObjNumb].x = _vm._objects[action->a38.objNumb].x + action->a38.dxLips;
|
_vm->_object->_objects[action->a38.lipsObjNumb].x = _vm->_object->_objects[action->a38.objNumb].x + action->a38.dxLips;
|
||||||
_vm._objects[action->a38.lipsObjNumb].y = _vm._objects[action->a38.objNumb].y + action->a38.dyLips;
|
_vm->_object->_objects[action->a38.lipsObjNumb].y = _vm->_object->_objects[action->a38.objNumb].y + action->a38.dyLips;
|
||||||
_vm._objects[action->a38.lipsObjNumb].screenIndex = *_vm._screen_p; // Don't forget screen!
|
_vm->_object->_objects[action->a38.lipsObjNumb].screenIndex = *_vm->_screen_p; // Don't forget screen!
|
||||||
_vm._objects[action->a38.lipsObjNumb].cycling = CYCLE_FORWARD;
|
_vm->_object->_objects[action->a38.lipsObjNumb].cycling = CYCLE_FORWARD;
|
||||||
break;
|
break;
|
||||||
case INIT_STORY_MODE: // act39: Init story_mode flag
|
case INIT_STORY_MODE: // act39: Init story_mode flag
|
||||||
// This is similar to the QUIET path mode, except that it is
|
// This is similar to the QUIET path mode, except that it is
|
||||||
|
@ -426,23 +424,23 @@ event_t *Scheduler::doAction(event_t *curEvent) {
|
||||||
|
|
||||||
// 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)
|
||||||
_vm.endGame();
|
_vm->endGame();
|
||||||
break;
|
break;
|
||||||
case WARN: // act40: Text box (CF TEXT)
|
case WARN: // act40: Text box (CF TEXT)
|
||||||
Utils::Box(BOX_OK, "%s", _vm.file().fetchString(action->a40.stringIndex));
|
Utils::Box(BOX_OK, "%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 (_vm->_points[action->a41.BonusIndex].scoredFl)
|
||||||
insertActionList(action->a41.actPassIndex);
|
insertActionList(action->a41.actPassIndex);
|
||||||
else
|
else
|
||||||
insertActionList(action->a41.actFailIndex);
|
insertActionList(action->a41.actFailIndex);
|
||||||
break;
|
break;
|
||||||
case TEXT_TAKE: // act42: Text box with "take" message
|
case TEXT_TAKE: // act42: Text box with "take" message
|
||||||
Utils::Box(BOX_ANY, TAKE_TEXT, _vm._arrayNouns[_vm._objects[action->a42.objNumb].nounIndex][TAKE_NAME]);
|
Utils::Box(BOX_ANY, TAKE_TEXT, _vm->_arrayNouns[_vm->_object->_objects[action->a42.objNumb].nounIndex][TAKE_NAME]);
|
||||||
break;
|
break;
|
||||||
case YESNO: // act43: Prompt user for Yes or No
|
case YESNO: // act43: Prompt user for Yes or No
|
||||||
warning("doAction(act43) - Yes/No Box");
|
warning("doAction(act43) - Yes/No Box");
|
||||||
if (Utils::Box(BOX_YESNO, "%s", _vm.file().fetchString(action->a43.promptIndex)) != 0)
|
if (Utils::Box(BOX_YESNO, "%s", _vm->_file->fetchString(action->a43.promptIndex)) != 0)
|
||||||
insertActionList(action->a43.actYesIndex);
|
insertActionList(action->a43.actYesIndex);
|
||||||
else
|
else
|
||||||
insertActionList(action->a43.actNoIndex);
|
insertActionList(action->a43.actNoIndex);
|
||||||
|
@ -463,16 +461,16 @@ event_t *Scheduler::doAction(event_t *curEvent) {
|
||||||
gameStatus.jumpExitFl = action->a46.jumpExitFl;
|
gameStatus.jumpExitFl = action->a46.jumpExitFl;
|
||||||
break;
|
break;
|
||||||
case INIT_VIEW: // act47: Init object.viewx, viewy, dir
|
case INIT_VIEW: // act47: Init object.viewx, viewy, dir
|
||||||
_vm._objects[action->a47.objNumb].viewx = action->a47.viewx;
|
_vm->_object->_objects[action->a47.objNumb].viewx = action->a47.viewx;
|
||||||
_vm._objects[action->a47.objNumb].viewy = action->a47.viewy;
|
_vm->_object->_objects[action->a47.objNumb].viewy = action->a47.viewy;
|
||||||
_vm._objects[action->a47.objNumb].direction = action->a47.direction;
|
_vm->_object->_objects[action->a47.objNumb].direction = action->a47.direction;
|
||||||
break;
|
break;
|
||||||
case INIT_OBJ_FRAME: // act48: Set seq,frame number to use
|
case INIT_OBJ_FRAME: // act48: Set seq,frame number to use
|
||||||
// Note: Don't set a sequence at time 0 of a new screen, it causes
|
// Note: Don't set a sequence at time 0 of a new screen, it causes
|
||||||
// problems clearing the boundary bits of the object! t>0 is safe
|
// problems clearing the boundary bits of the object! t>0 is safe
|
||||||
_vm._objects[action->a48.objNumb].currImagePtr = _vm._objects[action->a48.objNumb].seqList[action->a48.seqIndex].seqPtr;
|
_vm->_object->_objects[action->a48.objNumb].currImagePtr = _vm->_object->_objects[action->a48.objNumb].seqList[action->a48.seqIndex].seqPtr;
|
||||||
for (dx = 0; dx < action->a48.frameIndex; dx++)
|
for (dx = 0; dx < action->a48.frameIndex; dx++)
|
||||||
_vm._objects[action->a48.objNumb].currImagePtr = _vm._objects[action->a48.objNumb].currImagePtr->nextSeqPtr;
|
_vm->_object->_objects[action->a48.objNumb].currImagePtr = _vm->_object->_objects[action->a48.objNumb].currImagePtr->nextSeqPtr;
|
||||||
break;
|
break;
|
||||||
case OLD_SONG:
|
case OLD_SONG:
|
||||||
//TODO For Hugo 1 and Hugo2 DOS: The songs were not stored in a DAT file, but directly as
|
//TODO For Hugo 1 and Hugo2 DOS: The songs were not stored in a DAT file, but directly as
|
||||||
|
@ -500,7 +498,7 @@ event_t *Scheduler::doAction(event_t *curEvent) {
|
||||||
void Scheduler::runScheduler() {
|
void Scheduler::runScheduler() {
|
||||||
debugC(6, kDebugSchedule, "runScheduler");
|
debugC(6, kDebugSchedule, "runScheduler");
|
||||||
|
|
||||||
status_t &gameStatus = _vm.getGameStatus();
|
status_t &gameStatus = _vm->getGameStatus();
|
||||||
event_t *curEvent = _headEvent; // The earliest event
|
event_t *curEvent = _headEvent; // The earliest event
|
||||||
|
|
||||||
while (curEvent && curEvent->time <= gameStatus.tick) // While mature events found
|
while (curEvent && curEvent->time <= gameStatus.tick) // While mature events found
|
||||||
|
@ -512,16 +510,16 @@ uint32 Scheduler::getTicks() {
|
||||||
// Return system time in ticks. A tick is 1/TICKS_PER_SEC mS
|
// Return system time in ticks. A tick is 1/TICKS_PER_SEC mS
|
||||||
debugC(3, kDebugSchedule, "getTicks");
|
debugC(3, kDebugSchedule, "getTicks");
|
||||||
|
|
||||||
return _vm.getGameStatus().tick;
|
return _vm->getGameStatus().tick;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Scheduler::processBonus(int bonusIndex) {
|
void Scheduler::processBonus(int bonusIndex) {
|
||||||
// Add indecated bonus to score if not added already
|
// Add indecated bonus to score if not added already
|
||||||
debugC(1, kDebugSchedule, "processBonus(%d)", bonusIndex);
|
debugC(1, kDebugSchedule, "processBonus(%d)", bonusIndex);
|
||||||
|
|
||||||
if (!_vm._points[bonusIndex].scoredFl) {
|
if (!_vm->_points[bonusIndex].scoredFl) {
|
||||||
_vm.adjustScore(_vm._points[bonusIndex].score);
|
_vm->adjustScore(_vm->_points[bonusIndex].score);
|
||||||
_vm._points[bonusIndex].scoredFl = true;
|
_vm->_points[bonusIndex].scoredFl = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -535,11 +533,11 @@ void Scheduler::newScreen(int screenIndex) {
|
||||||
debugC(1, kDebugSchedule, "newScreen(%d)", screenIndex);
|
debugC(1, kDebugSchedule, "newScreen(%d)", screenIndex);
|
||||||
|
|
||||||
// Make sure the background file exists!
|
// Make sure the background file exists!
|
||||||
if (!_vm.isPacked()) {
|
if (!_vm->isPacked()) {
|
||||||
char line[32];
|
char line[32];
|
||||||
if (!_vm.file().fileExists(strcat(strncat(strcpy(line, _vm._picDir), _vm._screenNames[screenIndex], NAME_LEN), BKGEXT)) &&
|
if (!_vm->_file->fileExists(strcat(strncat(strcpy(line, _vm->_picDir), _vm->_screenNames[screenIndex], NAME_LEN), BKGEXT)) &&
|
||||||
!_vm.file().fileExists(strcat(strcpy(line, _vm._screenNames[screenIndex]), ".ART"))) {
|
!_vm->_file->fileExists(strcat(strcpy(line, _vm->_screenNames[screenIndex]), ".ART"))) {
|
||||||
Utils::Box(BOX_ANY, "%s", _vm._textSchedule[kSsNoBackground]);
|
Utils::Box(BOX_ANY, "%s", _vm->_textSchedule[kSsNoBackground]);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -555,16 +553,16 @@ void Scheduler::newScreen(int screenIndex) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. Set the new screen in the hero object and any being carried
|
// 2. Set the new screen in the hero object and any being carried
|
||||||
_vm.setNewScreen(screenIndex);
|
_vm->setNewScreen(screenIndex);
|
||||||
|
|
||||||
// 3. Read in new screen files
|
// 3. Read in new screen files
|
||||||
_vm.readScreenFiles(screenIndex);
|
_vm->readScreenFiles(screenIndex);
|
||||||
|
|
||||||
// 4. Schedule action list for this screen
|
// 4. Schedule action list for this screen
|
||||||
_vm.screenActions(screenIndex);
|
_vm->screenActions(screenIndex);
|
||||||
|
|
||||||
// 5. Initialise prompt line and status line
|
// 5. Initialise prompt line and status line
|
||||||
_vm.screen().initNewScreenDisplay();
|
_vm->_screen->initNewScreenDisplay();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write the event queue to the file with handle f
|
// Write the event queue to the file with handle f
|
||||||
|
@ -642,35 +640,13 @@ void Scheduler::restoreScreen(int screenIndex) {
|
||||||
debugC(1, kDebugSchedule, "restoreScreen(%d)", screenIndex);
|
debugC(1, kDebugSchedule, "restoreScreen(%d)", screenIndex);
|
||||||
|
|
||||||
// 1. Set the new screen in the hero object and any being carried
|
// 1. Set the new screen in the hero object and any being carried
|
||||||
_vm.setNewScreen(screenIndex);
|
_vm->setNewScreen(screenIndex);
|
||||||
|
|
||||||
// 2. Read in new screen files
|
// 2. Read in new screen files
|
||||||
_vm.readScreenFiles(screenIndex);
|
_vm->readScreenFiles(screenIndex);
|
||||||
|
|
||||||
// 3. Initialise prompt line and status line
|
// 3. Initialise prompt line and status line
|
||||||
_vm.screen().initNewScreenDisplay();
|
_vm->_screen->initNewScreenDisplay();
|
||||||
}
|
|
||||||
|
|
||||||
void Scheduler::swapImages(int objNumb1, int objNumb2) {
|
|
||||||
// Swap all the images of one object with another. Set hero_image (we make
|
|
||||||
// the assumption for now that the first obj is always the HERO) to the object
|
|
||||||
// number of the swapped image
|
|
||||||
debugC(1, kDebugSchedule, "swapImages(%d, %d)", objNumb1, objNumb2);
|
|
||||||
|
|
||||||
_vm.file().saveSeq(&_vm._objects[objNumb1]);
|
|
||||||
|
|
||||||
seqList_t tmpSeqList[MAX_SEQUENCES];
|
|
||||||
int seqListSize = sizeof(seqList_t) * MAX_SEQUENCES;
|
|
||||||
|
|
||||||
memcpy(tmpSeqList, _vm._objects[objNumb1].seqList, seqListSize);
|
|
||||||
memcpy(_vm._objects[objNumb1].seqList, _vm._objects[objNumb2].seqList, seqListSize);
|
|
||||||
memcpy(_vm._objects[objNumb2].seqList, tmpSeqList, seqListSize);
|
|
||||||
_vm.file().restoreSeq(&_vm._objects[objNumb1]);
|
|
||||||
_vm._objects[objNumb2].currImagePtr = _vm._objects[objNumb2].seqList[0].seqPtr;
|
|
||||||
_vm._heroImage = (_vm._heroImage == HERO) ? objNumb2 : HERO;
|
|
||||||
|
|
||||||
// Make sure baseline stays constant
|
|
||||||
_vm._objects[objNumb1].y += _vm._objects[objNumb2].currImagePtr->y2 - _vm._objects[objNumb1].currImagePtr->y2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // End of namespace Hugo
|
} // End of namespace Hugo
|
||||||
|
|
|
@ -47,7 +47,7 @@ struct event_t {
|
||||||
|
|
||||||
class Scheduler {
|
class Scheduler {
|
||||||
public:
|
public:
|
||||||
Scheduler(HugoEngine &vm);
|
Scheduler(HugoEngine *vm);
|
||||||
virtual ~Scheduler();
|
virtual ~Scheduler();
|
||||||
|
|
||||||
void initEventQueue();
|
void initEventQueue();
|
||||||
|
@ -61,7 +61,6 @@ public:
|
||||||
void restoreEvents(Common::SeekableReadStream *f);
|
void restoreEvents(Common::SeekableReadStream *f);
|
||||||
void saveEvents(Common::WriteStream *f);
|
void saveEvents(Common::WriteStream *f);
|
||||||
void restoreScreen(int screenIndex);
|
void restoreScreen(int screenIndex);
|
||||||
void swapImages(int objNumb1, int objNumb2);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum seqTextSchedule {
|
enum seqTextSchedule {
|
||||||
|
@ -69,7 +68,7 @@ private:
|
||||||
kSsBadSaveGame = 1
|
kSsBadSaveGame = 1
|
||||||
};
|
};
|
||||||
|
|
||||||
HugoEngine &_vm;
|
HugoEngine *_vm;
|
||||||
|
|
||||||
event_t _events[kMaxEvents]; // Statically declare event structures
|
event_t _events[kMaxEvents]; // Statically declare event structures
|
||||||
|
|
||||||
|
@ -86,7 +85,7 @@ private:
|
||||||
|
|
||||||
class Scheduler_v1d : public Scheduler {
|
class Scheduler_v1d : public Scheduler {
|
||||||
public:
|
public:
|
||||||
Scheduler_v1d(HugoEngine &vm);
|
Scheduler_v1d(HugoEngine *vm);
|
||||||
~Scheduler_v1d();
|
~Scheduler_v1d();
|
||||||
|
|
||||||
const char *getCypher();
|
const char *getCypher();
|
||||||
|
@ -94,7 +93,7 @@ public:
|
||||||
|
|
||||||
class Scheduler_v3d : public Scheduler {
|
class Scheduler_v3d : public Scheduler {
|
||||||
public:
|
public:
|
||||||
Scheduler_v3d(HugoEngine &vm);
|
Scheduler_v3d(HugoEngine *vm);
|
||||||
~Scheduler_v3d();
|
~Scheduler_v3d();
|
||||||
|
|
||||||
const char *getCypher();
|
const char *getCypher();
|
||||||
|
|
|
@ -39,7 +39,7 @@
|
||||||
|
|
||||||
namespace Hugo {
|
namespace Hugo {
|
||||||
|
|
||||||
Scheduler_v1d::Scheduler_v1d(HugoEngine &vm) : Scheduler(vm) {
|
Scheduler_v1d::Scheduler_v1d(HugoEngine *vm) : Scheduler(vm) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Scheduler_v1d::~Scheduler_v1d() {
|
Scheduler_v1d::~Scheduler_v1d() {
|
||||||
|
|
|
@ -39,7 +39,7 @@
|
||||||
|
|
||||||
namespace Hugo {
|
namespace Hugo {
|
||||||
|
|
||||||
Scheduler_v3d::Scheduler_v3d(HugoEngine &vm) : Scheduler(vm) {
|
Scheduler_v3d::Scheduler_v3d(HugoEngine *vm) : Scheduler(vm) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Scheduler_v3d::~Scheduler_v3d() {
|
Scheduler_v3d::~Scheduler_v3d() {
|
||||||
|
|
|
@ -239,7 +239,7 @@ void MidiPlayer::timerCallback(void *p) {
|
||||||
player->updateTimer();
|
player->updateTimer();
|
||||||
}
|
}
|
||||||
|
|
||||||
SoundHandler::SoundHandler(HugoEngine &vm) : _vm(vm) {
|
SoundHandler::SoundHandler(HugoEngine *vm) : _vm(vm) {
|
||||||
MidiDriver::DeviceHandle dev = MidiDriver::detectDevice(MDT_MIDI | MDT_ADLIB | MDT_PREFER_GM);
|
MidiDriver::DeviceHandle dev = MidiDriver::detectDevice(MDT_MIDI | MDT_ADLIB | MDT_PREFER_GM);
|
||||||
MidiDriver *driver = MidiDriver::createMidi(dev);
|
MidiDriver *driver = MidiDriver::createMidi(dev);
|
||||||
|
|
||||||
|
@ -254,7 +254,7 @@ void SoundHandler::setMusicVolume() {
|
||||||
|
|
||||||
void SoundHandler::stopSound() {
|
void SoundHandler::stopSound() {
|
||||||
/* Stop any sound that might be playing */
|
/* Stop any sound that might be playing */
|
||||||
_vm._mixer->stopAll();
|
_vm->_mixer->stopAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SoundHandler::stopMusic() {
|
void SoundHandler::stopMusic() {
|
||||||
|
@ -285,8 +285,8 @@ void SoundHandler::playMusic(int16 tune) {
|
||||||
uint16 size; // Size of sequence data
|
uint16 size; // Size of sequence data
|
||||||
|
|
||||||
if (_config.musicFl) {
|
if (_config.musicFl) {
|
||||||
_vm.getGameStatus().song = tune;
|
_vm->getGameStatus().song = tune;
|
||||||
seqPtr = _vm.file().getSound(tune, &size);
|
seqPtr = _vm->_file->getSound(tune, &size);
|
||||||
playMIDI(seqPtr, size);
|
playMIDI(seqPtr, size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -302,7 +302,7 @@ void SoundHandler::playSound(int16 sound, stereo_t channel, byte priority) {
|
||||||
static byte curPriority = 0; // Priority of currently playing sound
|
static byte curPriority = 0; // Priority of currently playing sound
|
||||||
//
|
//
|
||||||
/* Sound disabled */
|
/* Sound disabled */
|
||||||
if (!_config.soundFl || !_vm._mixer->isReady())
|
if (!_config.soundFl || !_vm->_mixer->isReady())
|
||||||
return;
|
return;
|
||||||
//
|
//
|
||||||
// // See if last wave still playing - if so, check priority
|
// // See if last wave still playing - if so, check priority
|
||||||
|
@ -314,11 +314,11 @@ void SoundHandler::playSound(int16 sound, stereo_t channel, byte priority) {
|
||||||
curPriority = priority;
|
curPriority = priority;
|
||||||
//
|
//
|
||||||
/* Get sound data */
|
/* Get sound data */
|
||||||
if ((sound_p = _vm.file().getSound(sound, &size)) == 0)
|
if ((sound_p = _vm->_file->getSound(sound, &size)) == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Audio::AudioStream *stream = Audio::makeRawStream(sound_p, size, 11025, Audio::FLAG_UNSIGNED);
|
Audio::AudioStream *stream = Audio::makeRawStream(sound_p, size, 11025, Audio::FLAG_UNSIGNED);
|
||||||
_vm._mixer->playStream(Audio::Mixer::kSpeechSoundType, &_soundHandle, stream);
|
_vm->_mixer->playStream(Audio::Mixer::kSpeechSoundType, &_soundHandle, stream);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -41,7 +41,7 @@ class MidiPlayer;
|
||||||
|
|
||||||
class SoundHandler {
|
class SoundHandler {
|
||||||
public:
|
public:
|
||||||
SoundHandler(HugoEngine &vm);
|
SoundHandler(HugoEngine *vm);
|
||||||
|
|
||||||
void toggleMusic();
|
void toggleMusic();
|
||||||
void toggleSound();
|
void toggleSound();
|
||||||
|
@ -51,7 +51,7 @@ public:
|
||||||
void initSound();
|
void initSound();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
HugoEngine &_vm;
|
HugoEngine *_vm;
|
||||||
Audio::SoundHandle _soundHandle;
|
Audio::SoundHandle _soundHandle;
|
||||||
MidiPlayer *_midiPlayer;
|
MidiPlayer *_midiPlayer;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue