diff options
Diffstat (limited to 'engines/hugo/parser_v1w.cpp')
-rw-r--r-- | engines/hugo/parser_v1w.cpp | 311 |
1 files changed, 69 insertions, 242 deletions
diff --git a/engines/hugo/parser_v1w.cpp b/engines/hugo/parser_v1w.cpp index 236d24b61b..2de173712e 100644 --- a/engines/hugo/parser_v1w.cpp +++ b/engines/hugo/parser_v1w.cpp @@ -38,264 +38,91 @@ #include "hugo/parser.h" #include "hugo/file.h" #include "hugo/schedule.h" +#include "hugo/route.h" +#include "hugo/display.h" #include "hugo/util.h" #include "hugo/sound.h" #include "hugo/object.h" namespace Hugo { -Parser_v1w::Parser_v1w(HugoEngine *vm) : Parser(vm) { +Parser_v1w::Parser_v1w(HugoEngine *vm) : Parser_v3d(vm) { } Parser_v1w::~Parser_v1w() { } -/** -* Test whether command line contains a verb allowed by this object. -* If it does, and the object is near and passes the tests in the command -* list then carry out the actions in the action list and return TRUE -*/ -bool Parser_v1w::isObjectVerb(object_t *obj, char *comment) { - debugC(1, kDebugParser, "isObjectVerb(object_t *obj, %s)", comment); - - // First, find matching verb in cmd list - uint16 cmdIndex = obj->cmdIndex; // ptr to list of commands - if (cmdIndex == 0) // No commands for this obj - return false; - - int i; - 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? - break; - } - - if (_vm->_cmdList[cmdIndex][i].verbIndex == 0) // No verbs used. - return false; - - // Verb match found. Check if object is Near - char *verb = *_vm->_arrayVerbs[_vm->_cmdList[cmdIndex][i].verbIndex]; - if (!isNear(obj, verb, comment)) - return false; - - // Check all required objects are being carried - cmd *cmnd = &_vm->_cmdList[cmdIndex][i]; // ptr to struct cmd - if (cmnd->reqIndex) { // At least 1 thing in list - uint16 *reqs = _vm->_arrayReqs[cmnd->reqIndex]; // ptr to list of required objects - for (i = 0; reqs[i]; i++) { // for each obj - if (!_vm->_object->isCarrying(reqs[i])) { - Utils::Box(BOX_ANY, "%s", _vm->_textData[cmnd->textDataNoCarryIndex]); - return true; - } - } - } - - // Required objects are present, now check state is correct - if ((obj->state != cmnd->reqState) && (cmnd->reqState != DONT_CARE)) { - Utils::Box(BOX_ANY, "%s", _vm->_textData[cmnd->textDataWrongIndex]); - return true; - } - - // 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 - obj->state = cmnd->newState; - Utils::Box(BOX_ANY, "%s", _vm->_textData[cmnd->textDataDoneIndex]); - _vm->_scheduler->insertActionList(cmnd->actIndex); +void Parser_v1w::keyHandler(uint16 nChar, uint16 nFlags) { + debugC(1, kDebugParser, "keyHandler(%d, %d)", nChar, nFlags); - // 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])) - isGenericVerb(obj, comment); - return true; -} - -/** -* Test whether command line contains one of the generic actions -*/ -bool Parser_v1w::isGenericVerb(object_t *obj, char *comment) { - debugC(1, kDebugParser, "isGenericVerb(object_t *obj, %s)", comment); - - if (!obj->genericCmd) - return false; - - // Following is equivalent to switch, but couldn't do one - if (isWordPresent(_vm->_arrayVerbs[_vm->_look]) && isNear(obj, _vm->_arrayVerbs[_vm->_look][0], comment)) { - // Test state-dependent look before general look - if ((obj->genericCmd & LOOK_S) == LOOK_S) { - Utils::Box(BOX_ANY, "%s", _vm->_textData[obj->stateDataIndex[obj->state]]); - } else { - if ((LOOK & obj->genericCmd) == LOOK) { - if (_vm->_textData[obj->dataIndex]) - Utils::Box(BOX_ANY, "%s", _vm->_textData[obj->dataIndex]); - else - return false; - } else { - Utils::Box(BOX_ANY, "%s", _vm->_textParser[kTBUnusual]); - } + status_t &gameStatus = _vm->getGameStatus(); + bool repeatedFl = (nFlags & 0x4000); // TRUE if key is a repeat + +// Process key down event - called from OnKeyDown() + switch (nChar) { // Set various toggle states + case Common::KEYCODE_ESCAPE: // Escape key, may want to QUIT + if (gameStatus.inventoryState == I_ACTIVE) // Remove inventory, if displayed + gameStatus.inventoryState = I_UP; + gameStatus.inventoryObjId = -1; // Deselect any dragged icon + break; + case Common::KEYCODE_END: + case Common::KEYCODE_HOME: + case Common::KEYCODE_LEFT: + case Common::KEYCODE_RIGHT: + case Common::KEYCODE_UP: + case Common::KEYCODE_DOWN: + if (!repeatedFl) { + gameStatus.routeIndex = -1; // Stop any automatic route + _vm->_route->setWalk(nChar); // Direction of hero travel } - } else if (isWordPresent(_vm->_arrayVerbs[_vm->_take]) && isNear(obj, _vm->_arrayVerbs[_vm->_take][0], comment)) { - if (obj->carriedFl) - Utils::Box(BOX_ANY, "%s", _vm->_textParser[kTBHave]); - else if ((TAKE & obj->genericCmd) == TAKE) - takeObject(obj); - else if (obj->cmdIndex != 0) // No comment if possible commands - return false; - else if (!obj->verbOnlyFl && (TAKE & obj->genericCmd) == TAKE) // Make sure not taking object in context! - Utils::Box(BOX_ANY, "%s", _vm->_textParser[kTBNoUse]); - else - return false; - } else if (isWordPresent(_vm->_arrayVerbs[_vm->_drop])) { - if (!obj->carriedFl && ((DROP & obj->genericCmd) == DROP)) - Utils::Box(BOX_ANY, "%s", _vm->_textParser[kTBDontHave]); - else if (obj->carriedFl && ((DROP & obj->genericCmd) == DROP)) - dropObject(obj); - else if (obj->cmdIndex == 0) - Utils::Box(BOX_ANY, "%s", _vm->_textParser[kTBNeed]); + break; + case Common::KEYCODE_F1: // User Help (DOS) + if (_checkDoubleF1Fl) + _vm->_file->instructions(); else - return false; - } else { // It was not a generic cmd - return false; - } - - return true; -} - -/** -* Test whether hero is close to object. Return TRUE or FALSE -* If object not near, return suitable comment; may be another object close -* If radius is -1, treat radius as infinity -* Verb is included to determine correct comment if not near -*/ -bool Parser_v1w::isNear(object_t *obj, char *verb, char *comment) { - debugC(1, kDebugParser, "isNear(object_t *obj, %s, %s)", verb, comment); - - if (obj->carriedFl) // Object is being carried - return true; - - if (obj->screenIndex != *_vm->_screen_p) { - // Not in same screen - if (obj->objValue) - strcpy(comment, _vm->_textParser[kCmtAny1]); - else - strcpy(comment, _vm->_textParser[kCmtAny2]); - return false; - } - - if (obj->cycling == INVISIBLE) { - if (obj->seqNumb) { - // There is an image - strcpy(comment, _vm->_textParser[kCmtAny3]); - return false; - } else { - // No image, assume visible - if ((obj->radius < 0) || - ((abs(obj->x - _vm->_hero->x) <= obj->radius) && - (abs(obj->y - _vm->_hero->y - _vm->_hero->currImagePtr->y2) <= obj->radius))) { - return true; - } else { - // User is not close enough - if (obj->objValue && (verb != _vm->_arrayVerbs[_vm->_take][0])) - strcpy(comment, _vm->_textParser[kCmtAny1]); - else - strcpy(comment, _vm->_textParser[kCmtClose]); - return false; + _vm->_screen->userHelp(); + _checkDoubleF1Fl = !_checkDoubleF1Fl; + break; + case Common::KEYCODE_F2: // Toggle sound + _vm->_sound->toggleSound(); + _vm->_sound->toggleMusic(); + break; + case Common::KEYCODE_F3: // Repeat last line + gameStatus.recallFl = true; + break; + case Common::KEYCODE_F4: // Save game + if (gameStatus.viewState == V_PLAY) + _vm->_file->saveGame(-1, Common::String()); + break; + case Common::KEYCODE_F5: // Restore game + _vm->_file->restoreGame(-1); + _vm->_scheduler->restoreScreen(*_vm->_screen_p); + gameStatus.viewState = V_PLAY; + break; + case Common::KEYCODE_F6: // Inventory + gameStatus.inventoryState = I_DOWN; + gameStatus.viewState = V_INVENT; + break; + case Common::KEYCODE_F8: // Turbo mode + _config.turboFl = !_config.turboFl; + break; + case Common::KEYCODE_F9: // Boss button + warning("STUB: F9 (DOS) - BossKey"); + break; + default: // Any other key + if (!gameStatus.storyModeFl) { // Keyboard disabled + // Add printable keys to ring buffer + uint16 bnext = _putIndex + 1; + if (bnext >= sizeof(_ringBuffer)) + bnext = 0; + if (bnext != _getIndex) { + _ringBuffer[_putIndex] = nChar; + _putIndex = bnext; } } + break; } - - if ((obj->radius < 0) || - ((abs(obj->x - _vm->_hero->x) <= obj->radius) && - (abs(obj->y + obj->currImagePtr->y2 - _vm->_hero->y - _vm->_hero->currImagePtr->y2) <= obj->radius))) { - return true; - } else { - // User is not close enough - if (obj->objValue && (verb != _vm->_arrayVerbs[_vm->_take][0])) - strcpy(comment, _vm->_textParser[kCmtAny1]); - else - strcpy(comment, _vm->_textParser[kCmtClose]); - return false; - } - return true; -} - -/** -* Do all things necessary to carry an object -*/ -void Parser_v1w::takeObject(object_t *obj) { - debugC(1, kDebugParser, "takeObject(object_t *obj)"); - - obj->carriedFl = true; - if (obj->seqNumb) { // Don't change if no image to display - obj->cycling = INVISIBLE; - } - _vm->adjustScore(obj->objValue); - - if (obj->seqNumb > 0) // If object has an image, force walk to dropped - obj->viewx = -1; // (possibly moved) object next time taken! - Utils::Box(BOX_ANY, TAKE_TEXT, _vm->_arrayNouns[obj->nounIndex][TAKE_NAME]); -} - -/** -* Do all necessary things to drop an object -*/ -void Parser_v1w::dropObject(object_t *obj) { - debugC(1, kDebugParser, "dropObject(object_t *obj)"); - - obj->carriedFl = false; - obj->screenIndex = *_vm->_screen_p; - if ((obj->seqNumb > 1) || (obj->seqList[0].imageNbr > 1)) - obj->cycling = CYCLE_FORWARD; - else - obj->cycling = NOT_CYCLING; - obj->x = _vm->_hero->x - 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; - _vm->adjustScore(-obj->objValue); - Utils::Box(BOX_ANY, "%s", _vm->_textParser[kTBOk]); -} - -/** -* Search for matching verbs in background command list. -* Noun is not required. Return TRUE if match found -* Note that if the background command list has match set TRUE then do not -* print text if there are any recognizable nouns in the command line -*/ -bool Parser_v1w::isCatchallVerb(objectList_t obj) { - debugC(1, kDebugParser, "isCatchallVerb(object_list_t obj)"); - - for (int i = 0; obj[i].verbIndex != 0; i++) { - if (isWordPresent(_vm->_arrayVerbs[obj[i].verbIndex]) && obj[i].nounIndex == 0 && - (!obj[i].matchFl || !findNoun()) && - ((obj[i].roomState == DONT_CARE) || - (obj[i].roomState == _vm->_screenStates[*_vm->_screen_p]))) { - Utils::Box(BOX_ANY, "%s", _vm->_file->fetchString(obj[i].commentIndex)); - _vm->_scheduler->processBonus(obj[i].bonusIndex); - - // If this is LOOK (without a noun), show any takeable objects - if (*(_vm->_arrayVerbs[obj[i].verbIndex]) == _vm->_arrayVerbs[_vm->_look][0]) - _vm->_object->showTakeables(); - - return true; - } - } - return false; -} - -/** -* Search for matching verb/noun pairs in background command list -* Print text for possible background object. Return TRUE if match found -*/ -bool Parser_v1w::isBackgroundWord(objectList_t obj) { - debugC(1, kDebugParser, "isBackgroundWord(object_list_t obj)"); - - for (int i = 0; obj[i].verbIndex != 0; i++) { - if (isWordPresent(_vm->_arrayVerbs[obj[i].verbIndex]) && - isWordPresent(_vm->_arrayNouns[obj[i].nounIndex]) && - ((obj[i].roomState == DONT_CARE) || - (obj[i].roomState == _vm->_screenStates[*_vm->_screen_p]))) { - Utils::Box(BOX_ANY, "%s", _vm->_file->fetchString(obj[i].commentIndex)); - _vm->_scheduler->processBonus(obj[i].bonusIndex); - return true; - } - } - return false; + if (_checkDoubleF1Fl && (nChar != Common::KEYCODE_F1)) + _checkDoubleF1Fl = false; } /** |