diff options
Diffstat (limited to 'engines/avalanche')
-rw-r--r-- | engines/avalanche/animation.cpp | 16 | ||||
-rw-r--r-- | engines/avalanche/animation.h | 2 | ||||
-rw-r--r-- | engines/avalanche/avalanche.cpp | 16 | ||||
-rw-r--r-- | engines/avalanche/avalanche.h | 6 | ||||
-rw-r--r-- | engines/avalanche/avalot.cpp | 34 | ||||
-rw-r--r-- | engines/avalanche/avalot.h | 2 | ||||
-rw-r--r-- | engines/avalanche/background.cpp | 2 | ||||
-rw-r--r-- | engines/avalanche/configure.engine | 3 | ||||
-rw-r--r-- | engines/avalanche/console.cpp | 1 | ||||
-rw-r--r-- | engines/avalanche/detection.cpp | 2 | ||||
-rw-r--r-- | engines/avalanche/dialogs.cpp | 57 | ||||
-rw-r--r-- | engines/avalanche/enums.h | 5 | ||||
-rw-r--r-- | engines/avalanche/graphics.cpp | 23 | ||||
-rw-r--r-- | engines/avalanche/menu.cpp | 6 | ||||
-rw-r--r-- | engines/avalanche/module.mk | 3 | ||||
-rw-r--r-- | engines/avalanche/nim.cpp | 177 | ||||
-rw-r--r-- | engines/avalanche/nim.h | 76 | ||||
-rw-r--r-- | engines/avalanche/parser.cpp | 177 | ||||
-rw-r--r-- | engines/avalanche/parser.h | 36 | ||||
-rw-r--r-- | engines/avalanche/timer.cpp | 36 |
20 files changed, 461 insertions, 219 deletions
diff --git a/engines/avalanche/animation.cpp b/engines/avalanche/animation.cpp index 927de07236..cef4088722 100644 --- a/engines/avalanche/animation.cpp +++ b/engines/avalanche/animation.cpp @@ -248,7 +248,7 @@ void AnimationType::walk() { break; case kMagicUnfinished: { bounce(); - Common::String tmpStr = Common::String::format("%c%cSorry.%cThis place is not available yet!", + Common::String tmpStr = Common::String::format("%c%cSorry.%cThis place is not available yet!", kControlBell, kControlCenter, kControlRoman); _anim->_vm->_dialogs->displayText(tmpStr); } @@ -792,7 +792,7 @@ void Animation::callSpecial(uint16 which) { _vm->_magics[11]._data = 5; _vm->_magics[3]._operation = kMagicBounce; // Now works as planned! stopWalking(); - _vm->_dialogs->displayScrollChain('q', 26); + _vm->_dialogs->displayScrollChain('Q', 26); _vm->_userMovesAvvy = true; break; case 3: // _vm->special 3: Room 71: triggers dart. @@ -824,12 +824,12 @@ void Animation::callSpecial(uint16 which) { if (_vm->_friarWillTieYouUp) { // _vm->special 5: Room 42: touched tree, and get tied up. _vm->_magics[4]._operation = kMagicBounce; // Boundary effect is now working again. - _vm->_dialogs->displayScrollChain('q', 35); + _vm->_dialogs->displayScrollChain('Q', 35); _sprites[0]->remove(); AnimationType *spr1 = _sprites[1]; _vm->_background->draw(-1, -1, 1); - _vm->_dialogs->displayScrollChain('q', 36); + _vm->_dialogs->displayScrollChain('Q', 36); _vm->_tiedUp = true; _vm->_friarWillTieYouUp = false; spr1->walkTo(2); @@ -862,7 +862,7 @@ void Animation::callSpecial(uint16 which) { case 8: // _vm->special 8: leave du Lustie's room. if (_vm->_geidaFollows && !_vm->_lustieIsAsleep) { AnimationType *spr1 = _sprites[1]; - _vm->_dialogs->displayScrollChain('q', 63); + _vm->_dialogs->displayScrollChain('Q', 63); spr1->turn(kDirDown); spr1->stopWalk(); spr1->_callEachStepFl = false; // Geida @@ -885,9 +885,9 @@ void Animation::callSpecial(uint16 which) { if ((_vm->_catacombX == 4) && (_vm->_catacombY == 1)) { // Into Geida's room. if (_vm->_objects[kObjectKey - 1]) - _vm->_dialogs->displayScrollChain('q', 62); + _vm->_dialogs->displayScrollChain('Q', 62); else { - _vm->_dialogs->displayScrollChain('q', 61); + _vm->_dialogs->displayScrollChain('Q', 61); return; } } @@ -1247,7 +1247,7 @@ void Animation::animLink() { if (_mustExclaim) { _mustExclaim = false; - _vm->_dialogs->displayScrollChain('x', _sayWhat); + _vm->_dialogs->displayScrollChain('X', _sayWhat); } } diff --git a/engines/avalanche/animation.h b/engines/avalanche/animation.h index 3223615985..cda5f05bd0 100644 --- a/engines/avalanche/animation.h +++ b/engines/avalanche/animation.h @@ -157,7 +157,7 @@ private: void followAvalotY(byte tripnum); void backAndForth(byte tripnum); void faceAvvy(byte tripnum); - + // Movements for Homing NPCs: Spludwick and Geida. void spin(Direction dir, byte &tripnum); void takeAStep(byte &tripnum); diff --git a/engines/avalanche/avalanche.cpp b/engines/avalanche/avalanche.cpp index 8b3efe4081..2bb927646e 100644 --- a/engines/avalanche/avalanche.cpp +++ b/engines/avalanche/avalanche.cpp @@ -42,7 +42,7 @@ AvalancheEngine::AvalancheEngine(OSystem *syst, const AvalancheGameDescription * _system->getTimeAndDate(time); _rnd->setSeed(time.tm_sec + time.tm_min + time.tm_hour); _showDebugLines = false; - + _clock = nullptr; _graphics = nullptr; _parser = nullptr; @@ -55,6 +55,7 @@ AvalancheEngine::AvalancheEngine(OSystem *syst, const AvalancheGameDescription * _menu = nullptr; _closing = nullptr; _sound = nullptr; + _nim = nullptr; _platform = gd->desc.platform; initVariables(); @@ -77,6 +78,7 @@ AvalancheEngine::~AvalancheEngine() { delete _menu; delete _closing; delete _sound; + delete _nim; for (int i = 0; i < 31; i++) { for (int j = 0; j < 2; j++) { @@ -182,6 +184,7 @@ Common::ErrorCode AvalancheEngine::initialize() { _menu = new Menu(this); _closing = new Closing(this); _sound = new SoundHandler(this); + _nim = new Nim(this); _graphics->init(); _dialogs->init(); @@ -210,6 +213,7 @@ const char *AvalancheEngine::getCopyrightString() const { void AvalancheEngine::synchronize(Common::Serializer &sz) { _animation->synchronize(sz); _parser->synchronize(sz); + _nim->synchronize(sz); _sequence->synchronize(sz); _background->synchronize(sz); @@ -349,7 +353,7 @@ void AvalancheEngine::synchronize(Common::Serializer &sz) { sz.syncAsByte(_timer->_times[i]._action); sz.syncAsByte(_timer->_times[i]._reason); } - + } bool AvalancheEngine::canSaveGameStateCurrently() { // TODO: Refine these!!! @@ -417,7 +421,7 @@ bool AvalancheEngine::loadGame(const int16 slot) { // Check version. We can't restore from obsolete versions. byte saveVersion = f->readByte(); - if (saveVersion != kSavegameVersion) { + if (saveVersion > kSavegameVersion) { warning("Savegame of incompatible version!"); delete f; return false; @@ -466,9 +470,9 @@ bool AvalancheEngine::loadGame(const int16 slot) { _animation->animLink(); _background->update(); - Common::String tmpStr = Common::String::format("%cLoaded: %c%s.ASG%c%c%c%s%c%csaved on %s.", - kControlItalic, kControlRoman, description.c_str(), kControlCenter, kControlNewLine, - kControlNewLine, _roomnName.c_str(), kControlNewLine, kControlNewLine, + Common::String tmpStr = Common::String::format("%cLoaded: %c%s.ASG%c%c%c%s%c%csaved on %s.", + kControlItalic, kControlRoman, description.c_str(), kControlCenter, kControlNewLine, + kControlNewLine, _roomnName.c_str(), kControlNewLine, kControlNewLine, expandDate(t.tm_mday, t.tm_mon, t.tm_year).c_str()); _dialogs->displayText(tmpStr); diff --git a/engines/avalanche/avalanche.h b/engines/avalanche/avalanche.h index fdbc4c7a15..87eb3c2158 100644 --- a/engines/avalanche/avalanche.h +++ b/engines/avalanche/avalanche.h @@ -41,6 +41,7 @@ #include "avalanche/menu.h" #include "avalanche/closing.h" #include "avalanche/sound.h" +#include "avalanche/nim.h" #include "common/serializer.h" @@ -59,7 +60,7 @@ struct AvalancheGameDescription { ADGameDescription desc; }; -static const int kSavegameVersion = 1; +static const int kSavegameVersion = 2; enum Pitch { kPitchInvalid, @@ -84,6 +85,7 @@ public: Menu *_menu; Closing *_closing; SoundHandler *_sound; + Nim *_nim; OSystem *_system; @@ -289,7 +291,7 @@ public: void newGame(); // This sets up the DNA for a completely new game. bool getFlag(char x); bool decreaseMoney(uint16 amount); // Called pennycheck in the original. - + Common::String getName(People whose); Common::String getItem(byte which); // Called get_better in the original. Common::String f5Does(); // This procedure determines what f5 does. diff --git a/engines/avalanche/avalot.cpp b/engines/avalanche/avalot.cpp index 08096d85c0..ec3f81e55d 100644 --- a/engines/avalanche/avalot.cpp +++ b/engines/avalanche/avalot.cpp @@ -143,7 +143,7 @@ void Clock::update() { if ((_hour == 0) && (_oldHour != 0) && (_oldHour != 17717)) { Common::String tmpStr = Common::String::format("Good morning!%c%cYes, it's just past " \ - "midnight. Are you having an all-night Avvy session? Glad you like the game that much!", + "midnight. Are you having an all-night Avvy session? Glad you like the game that much!", kControlNewLine, kControlNewLine); _vm->_dialogs->displayText(tmpStr); } @@ -184,7 +184,7 @@ void Clock::chime() { // Mute - skip the sound generation if ((_oldHour == 17717) || (!_vm->_soundFx)) return; - + byte hour = _hour % 12; if (hour == 0) hour = 12; @@ -194,12 +194,11 @@ void Clock::chime() { for (int i = 1; i <= hour; i++) { for (int j = 1; j <= 3; j++) _vm->_sound->playNote((i % 3) * 64 + 140 - j * 30, 50 - j * 12); - if (i != hour) + if (i != hour) _vm->_system->delayMillis(100); } } - void AvalancheEngine::handleKeyDown(Common::Event &event) { _sound->click(); @@ -301,7 +300,7 @@ void AvalancheEngine::setup() { fxToggle(); thinkAbout(kObjectMoney, kThing); - _dialogs->displayScrollChain('q', 83); // Info on the game, etc. + _dialogs->displayScrollChain('Q', 83); // Info on the game, etc. } } @@ -576,7 +575,6 @@ void AvalancheEngine::exitRoom(byte x) { _lastRoomNotMap = _room; } - /** * Only when entering a NEW town! Not returning to the last one, * but choosing another from the map. @@ -811,12 +809,12 @@ void AvalancheEngine::enterRoom(Room roomId, byte ped) { _graphics->zoomOut(_peds[ped - 1]._x, _peds[ped - 1]._y); if ((_objects[kObjectWine - 1]) && (_wineState != 3)) { - _dialogs->displayScrollChain('q', 9); // Don't want to waste the wine! + _dialogs->displayScrollChain('Q', 9); // Don't want to waste the wine! _objects[kObjectWine - 1] = false; refreshObjectList(); } - _dialogs->displayScrollChain('q', 69); + _dialogs->displayScrollChain('Q', 69); break; case kRoomCatacombs: @@ -999,7 +997,7 @@ void AvalancheEngine::enterRoom(Room roomId, byte ped) { case kRoomDucks: _npcFacing = 1; // Duck. - break; + break; default: break; @@ -1064,7 +1062,7 @@ void AvalancheEngine::drawScore() { _scoreToDisplay[i] = numbers[i]; } -void AvalancheEngine::incScore(byte num) { +void AvalancheEngine::incScore(byte num) { for (int i = 1; i <= num; i++) { _dnascore++; @@ -1311,9 +1309,9 @@ void AvalancheEngine::fadeOut() { void AvalancheEngine::fadeIn() { if (_holdTheDawn || !_fxHidden) return; - + _fxHidden = false; - + byte pal[3]; for (int i = 15; i >= 0; i--) { for (int j = 0; j < 16; j++) { @@ -1341,7 +1339,6 @@ void AvalancheEngine::drawDirection() { // It's data is loaded in load_digits(). CursorMan.showMouse(true); } - void AvalancheEngine::gameOver() { _userMovesAvvy = false; @@ -1380,7 +1377,7 @@ uint16 AvalancheEngine::bearing(byte whichPed) { if (avvy->_x == curPed->_x) return 0; - + int16 deltaX = avvy->_x - curPed->_x; int16 deltaY = avvy->_y - curPed->_y; uint16 result = (uint16)(atan((float)(deltaY / deltaX)) * 180 / M_PI); @@ -1391,7 +1388,7 @@ uint16 AvalancheEngine::bearing(byte whichPed) { } } -/** +/** * @remarks Originally called 'sprite_run' */ void AvalancheEngine::spriteRun() { @@ -1484,6 +1481,7 @@ void AvalancheEngine::resetVariables() { _startTime = getTimeInSeconds(); _parser->resetVariables(); + _nim->resetVariables(); _animation->resetVariables(); _sequence->resetVariables(); _background->resetVariables(); @@ -1566,7 +1564,7 @@ Common::String AvalancheEngine::getName(People whose) { static const char lads[17][20] = { "Avalot", "Spludwick", "Crapulus", "Dr. Duck", "Malagauche", "Friar Tuck", "Robin Hood", "Cwytalot", "du Lustie", "the Duke of Cardiff", - "Dogfood", "A trader", "Ibythneth", "Ayles", "Port", + "Dogfood", "A trader", "Ibythneth", "Ayles", "Port", "Spurge", "Jacques" }; @@ -1748,10 +1746,10 @@ void AvalancheEngine::openDoor(Room whither, byte ped, byte magicnum) { } void AvalancheEngine::setRoom(People persId, Room roomId) { - _whereIs[persId - kPeopleAvalot] = roomId; + _whereIs[persId - kPeopleAvalot] = roomId; } Room AvalancheEngine::getRoom(People persId) { - return _whereIs[persId - kPeopleAvalot]; + return _whereIs[persId - kPeopleAvalot]; } } // End of namespace Avalanche diff --git a/engines/avalanche/avalot.h b/engines/avalanche/avalot.h index ab78f5c385..f50ad28bc4 100644 --- a/engines/avalanche/avalot.h +++ b/engines/avalanche/avalot.h @@ -40,7 +40,7 @@ public: Clock(AvalancheEngine *vm); void update(); - + private: static const int kCenterX = 510; static const int kCenterY = 183; diff --git a/engines/avalanche/background.cpp b/engines/avalanche/background.cpp index 523b7a6826..5d168a20af 100644 --- a/engines/avalanche/background.cpp +++ b/engines/avalanche/background.cpp @@ -251,7 +251,7 @@ void Background::update() { if (_nextBell < 5) _nextBell = 12; _nextBell--; - // CHECKME: 2 is a guess. No length in the original? + // CHECKME: 2 is a guess. No length in the original? _vm->_sound->playNote(_vm->kNotes[_nextBell], 2); break; case 2: diff --git a/engines/avalanche/configure.engine b/engines/avalanche/configure.engine new file mode 100644 index 0000000000..28d6a558db --- /dev/null +++ b/engines/avalanche/configure.engine @@ -0,0 +1,3 @@ +# This file is included from the main "configure" script +# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps] +add_engine avalanche "Lord Avalot d'Argent" no diff --git a/engines/avalanche/console.cpp b/engines/avalanche/console.cpp index 656cc1907c..e4b52116e4 100644 --- a/engines/avalanche/console.cpp +++ b/engines/avalanche/console.cpp @@ -50,5 +50,4 @@ bool AvalancheConsole::Cmd_MagicLines(int argc, const char **argv) { return false; } - } // End of namespace Avalanche diff --git a/engines/avalanche/detection.cpp b/engines/avalanche/detection.cpp index 048b0fe148..5f4f03a78b 100644 --- a/engines/avalanche/detection.cpp +++ b/engines/avalanche/detection.cpp @@ -129,7 +129,7 @@ SaveStateList AvalancheMetaEngine::listSaves(const char *target) const { // Check version. byte saveVersion = file->readByte(); - if (saveVersion != kSavegameVersion) { + if (saveVersion > kSavegameVersion) { warning("Savegame of incompatible version!"); delete file; continue; diff --git a/engines/avalanche/dialogs.cpp b/engines/avalanche/dialogs.cpp index 4b6cacf569..271c0b8288 100644 --- a/engines/avalanche/dialogs.cpp +++ b/engines/avalanche/dialogs.cpp @@ -190,7 +190,6 @@ void Dialogs::scrollModeNormal() { break; } while (!((mrelease > 0) || (buttona1()) || (buttonb1()))); - if (mrelease == 0) { inkey(); if (aboutscroll) { @@ -375,7 +374,7 @@ void Dialogs::scrollModeMusic() { else store(kPitchHigher, played); } - + if (theyMatch(played)) { setReadyLight(0); _vm->_timer->addTimer(8, Timer::kProcJacquesWakesUp, Timer::kReasonJacquesWakingUp); @@ -502,7 +501,7 @@ void Dialogs::drawScroll(DialogFunctionType modeFunc) { _underScroll = (my + 3) * 2; // Multiplying because of the doubled screen height. ringBell(); - + _vm->_dropsOk = false; dodgem(); @@ -510,7 +509,7 @@ void Dialogs::drawScroll(DialogFunctionType modeFunc) { unDodgem(); _vm->_dropsOk = true; - + resetScrollDriver(); } @@ -597,7 +596,7 @@ Common::String Dialogs::displayMoney() { else result = Common::String::format("%d/%d", _vm->_money / 12, _vm->_money % 12); } else { // L, s & d - result = Common::String::format("\x9C%d.%d.%d", _vm->_money / 240, (_vm->_money / 12) % 20, + result = Common::String::format("\x9C%d.%d.%d", _vm->_money / 240, (_vm->_money / 12) % 20, _vm->_money % 12); } if (_vm->_money > 12) { @@ -636,7 +635,7 @@ void Dialogs::solidify(byte n) { /** * @remarks Originally called 'calldriver' - * Display text by calling the dialog driver. It unifies the function of the original + * Display text by calling the dialog driver. It unifies the function of the original * 'calldriver' and 'display' by using Common::String instead of a private buffer. */ void Dialogs::displayText(Common::String text) { @@ -717,7 +716,7 @@ void Dialogs::displayText(Common::String text) { PedType *quasiPed = &_vm->_peds[kQuasipeds[_param - 10]._whichPed]; _talkX = quasiPed->_x; _talkY = quasiPed->_y; // Position. - + _vm->_graphics->setDialogColor(kQuasipeds[_param - 10]._backgroundColor, kQuasipeds[_param - 10]._textColor); } else { _vm->errorLed(); // Not valid. @@ -732,7 +731,7 @@ void Dialogs::displayText(Common::String text) { return; break; - // CHECME: The whole kControlNegative block seems completely unused, as the only use (the easter egg check) is a false positive + // CHECME: The whole kControlNegative block seems completely unused, as the only use (the easter egg check) is a false positive case kControlNegative: switch (_param) { case 1: @@ -763,7 +762,7 @@ void Dialogs::displayText(Common::String text) { case 10: switch (_vm->_boxContent) { case 0: // Sixpence. - displayScrollChain('q', 37); // You find the sixpence. + displayScrollChain('Q', 37); // You find the sixpence. _vm->_money += 6; _vm->_boxContent = _vm->_parser->kNothing; _vm->incScore(2); @@ -777,7 +776,7 @@ void Dialogs::displayText(Common::String text) { break; case 11: for (int j = 0; j < kObjectNum; j++) { - if (_vm->_objects[j]) + if (_vm->_objects[j]) displayText(_vm->getItem(j) + ", " + kControlToBuffer); } break; @@ -830,7 +829,7 @@ int16 Dialogs::getTalkPosX() { bool Dialogs::displayQuestion(Common::String question) { displayText(question + kControlNewLine + kControlQuestion); - + if (_scReturn && (_vm->_rnd->getRandomNumber(1) == 0)) { // Half-and-half chance. Common::String tmpStr = Common::String::format("...Positive about that?%cI%c%c%c", kControlRegister, kControlIcon, kControlNewLine, kControlQuestion); displayText(tmpStr); // Be annoying! @@ -874,7 +873,7 @@ void Dialogs::loadFont() { * @remarks Originally called 'musical_scroll' */ void Dialogs::displayMusicalScroll() { - Common::String tmpStr = Common::String::format("To play the harp...%c%cUse these keys:%c%cQ W E R T Y U I O P [ ]%c%cOr press Enter to stop playing.%c", + Common::String tmpStr = Common::String::format("To play the harp...%c%cUse these keys:%c%cQ W E R T Y U I O P [ ]%c%cOr press Enter to stop playing.%c", kControlNewLine, kControlNewLine, kControlNewLine, kControlInsertSpaces, kControlNewLine, kControlNewLine, kControlToBuffer); displayText(tmpStr); @@ -906,7 +905,7 @@ void Dialogs::displayScrollChain(char block, byte point, bool report, bool bubbl bool error = false; - indexfile.seek((toupper(block) - 65) * 2); + indexfile.seek((toupper(block) - 'A') * 2); uint16 idx_offset = indexfile.readUint16LE(); if (idx_offset == 0) error = true; @@ -953,7 +952,7 @@ void Dialogs::displayScrollChain(char block, byte point, bool report, bool bubbl */ void Dialogs::speak(byte who, byte subject) { if (subject == 0) { // No subject. - displayScrollChain('s', who, false, true); + displayScrollChain('S', who, false, true); return; } @@ -1007,7 +1006,7 @@ void Dialogs::talkTo(byte whom) { switch (whom) { case kPeopleSpludwick: if ((_vm->_lustieIsAsleep) & (!_vm->_objects[kObjectPotion - 1])) { - displayScrollChain('q', 68); + displayScrollChain('Q', 68); _vm->_objects[kObjectPotion - 1] = true; _vm->refreshObjectList(); _vm->incScore(3); @@ -1019,64 +1018,64 @@ void Dialogs::talkTo(byte whom) { case 1: // Fallthrough is intended. case 2: { Common::String objStr = _vm->getItem(AvalancheEngine::kSpludwicksOrder[_vm->_givenToSpludwick]); - Common::String tmpStr = Common::String::format("Can you get me %s, please?%c2%c", + Common::String tmpStr = Common::String::format("Can you get me %s, please?%c2%c", objStr.c_str(), kControlRegister, kControlSpeechBubble); displayText(tmpStr); } return; case 3: - displayScrollChain('q', 30); // Need any help with the game? + displayScrollChain('Q', 30); // Need any help with the game? return; } } else { - displayScrollChain('q', 42); // Haven't talked to Crapulus. Go and talk to him. + displayScrollChain('Q', 42); // Haven't talked to Crapulus. Go and talk to him. return; } break; case kPeopleIbythneth: if (_vm->_givenBadgeToIby) { - displayScrollChain('q', 33); // Thanks a lot! + displayScrollChain('Q', 33); // Thanks a lot! return; // And leave the proc. } break; // Or... just continue, 'cos he hasn't got it. case kPeopleDogfood: if (_vm->_wonNim) { // We've won the game. - displayScrollChain('q', 6); // "I'm Not Playing!" + displayScrollChain('Q', 6); // "I'm Not Playing!" return; // Zap back. } else _vm->_askedDogfoodAboutNim = true; break; case kPeopleAyles: if (!_vm->_aylesIsAwake) { - displayScrollChain('q', 43); // He's fast asleep! + displayScrollChain('Q', 43); // He's fast asleep! return; } else if (!_vm->_givenPenToAyles) { - displayScrollChain('q', 44); // Can you get me a pen, Avvy? + displayScrollChain('Q', 44); // Can you get me a pen, Avvy? return; } break; case kPeopleJacques: - displayScrollChain('q', 43); + displayScrollChain('Q', 43); return; case kPeopleGeida: if (_vm->_givenPotionToGeida) _vm->_geidaFollows = true; else { - displayScrollChain('u', 17); + displayScrollChain('U', 17); return; } break; case kPeopleSpurge: if (!_vm->_sittingInPub) { - displayScrollChain('q', 71); // Try going over and sitting down. + displayScrollChain('Q', 71); // Try going over and sitting down. return; } else { if (_vm->_spurgeTalkCount < 5) _vm->_spurgeTalkCount++; if (_vm->_spurgeTalkCount > 1) { // no. 1 falls through - displayScrollChain('q', 70 + _vm->_spurgeTalkCount); + displayScrollChain('Q', 70 + _vm->_spurgeTalkCount); return; } } @@ -1084,7 +1083,7 @@ void Dialogs::talkTo(byte whom) { } // On a subject. Is there any reason to block it? } else if ((whom == kPeopleAyles) && (!_vm->_aylesIsAwake)) { - displayScrollChain('q', 43); // He's fast asleep! + displayScrollChain('Q', 43); // He's fast asleep! return; } @@ -1109,12 +1108,12 @@ void Dialogs::talkTo(byte whom) { speak(whom, _vm->_subjectNum); if (!_noError) - displayScrollChain('n', whom); // File not found! + displayScrollChain('N', whom); // File not found! if ((_vm->_subjectNum == 0) && ((whom + 149) == kPeopleCrapulus)) { // Crapulus: get the badge - first time only _vm->_objects[kObjectBadge - 1] = true; _vm->refreshObjectList(); - displayScrollChain('q', 1); // Circular from Cardiff. + displayScrollChain('Q', 1); // Circular from Cardiff. _vm->_talkedToCrapulus = true; _vm->setRoom(kPeopleCrapulus, kRoomDummy); // Crapulus walks off. diff --git a/engines/avalanche/enums.h b/engines/avalanche/enums.h index 604c62de84..2b5db67609 100644 --- a/engines/avalanche/enums.h +++ b/engines/avalanche/enums.h @@ -81,12 +81,12 @@ enum VerbCode { kVerbCodeRestart = 31, kVerbCodeEat = 32, kVerbCodeListen = 33, kVerbCodeBuy = 34, kVerbCodeAttack = 35, kVerbCodePasswd = 36, kVerbCodeDir = 37, kVerbCodeDie = 38, kVerbCodeScore = 39, kVerbCodePut = 40, kVerbCodeKiss = 41, kVerbCodeClimb = 42, kVerbCodeJump = 43, kVerbCodeHiscores = 44, kVerbCodeWake = 45, - kVerbCodeHello = 46, kVerbCodeThanks = 47, + kVerbCodeHello = 46, kVerbCodeThanks = 47, kVerbCodeSmartAlec = 249, kVerbCodeExpletive = 253, kVerbCodePardon = 254 }; enum MouseCursor { - kCurUpArrow = 0, kCurScrewDriver = 1, kCurRightArrow = 2, kCurFletch = 3, kCurWait = 4, kCurHand = 5, + kCurUpArrow = 0, kCurScrewDriver = 1, kCurRightArrow = 2, kCurFletch = 3, kCurWait = 4, kCurHand = 5, kCurCrosshair = 6, kCurIBeam = 7 }; @@ -127,7 +127,6 @@ static const int16 kScreenHeight = 200; static const int16 kWalk = 3; static const int16 kRun = 5; - } // End of namespace Avalanche #endif // AVALANCHE_ENUMS_H diff --git a/engines/avalanche/graphics.cpp b/engines/avalanche/graphics.cpp index d7c32cb1fc..841512847f 100644 --- a/engines/avalanche/graphics.cpp +++ b/engines/avalanche/graphics.cpp @@ -36,15 +36,15 @@ namespace Avalanche { const byte GraphicManager::kEgaPaletteIndex[16] = {0, 1, 2, 3, 4, 5, 20, 7, 56, 57, 58, 59, 60, 61, 62, 63}; const MouseHotspotType GraphicManager::kMouseHotSpots[9] = { - {8,0}, // 0 - up-arrow - {0,0}, // 1 - screwdriver + {8,0}, // 0 - up-arrow + {0,0}, // 1 - screwdriver {15,6}, // 2 - right-arrow - {0,0}, // 3 - fletch - {8,7}, // 4 - hourglass - {4,0}, // 5 - TTHand - {8,5}, // 6 - Mark's crosshairs - {8,7}, // 7 - I-beam - {0,0} // 8 - question mark + {0,0}, // 3 - fletch + {8,7}, // 4 - hourglass + {4,0}, // 5 - TTHand + {8,5}, // 6 - Mark's crosshairs + {8,7}, // 7 - I-beam + {0,0} // 8 - question mark }; GraphicManager::GraphicManager(AvalancheEngine *vm) { @@ -127,7 +127,6 @@ void GraphicManager::loadMouse(byte which) { cursor.create(16, 32, Graphics::PixelFormat::createFormatCLUT8()); cursor.fillRect(Common::Rect(0, 0, 16, 32), 255); - // The AND mask. f.seek(kMouseSize * 2 * which + 134); @@ -573,7 +572,7 @@ void GraphicManager::drawPicture(Graphics::Surface &target, const Graphics::Surf if (destX + maxX > target.w) maxX = target.w - destX; - + if (destY + maxY > target.h) maxY = target.h - destY; @@ -624,7 +623,7 @@ void GraphicManager::drawSign(Common::String fn, int16 xl, int16 yl, int16 y) { } } } - + drawPicture(_scrolls, sign, kScreenWidth / 2 - width / 2, y); file.close(); @@ -669,7 +668,7 @@ void GraphicManager::prepareBubble(int xc, int xw, int my, Common::Point points[ drawTriangle(points, _talkBackgroundColor); } -/** +/** * Set the background of the text to the desired color. */ void GraphicManager::wipeChar(int x, int y, Color color) { diff --git a/engines/avalanche/menu.cpp b/engines/avalanche/menu.cpp index 7c37b79bc8..c3fa709ee4 100644 --- a/engines/avalanche/menu.cpp +++ b/engines/avalanche/menu.cpp @@ -64,7 +64,7 @@ void HeadType::highlight() { // Force reload and redraw of cursor. _menu->_vm->_currentMouse = 177; - + } bool HeadType::parseAltTrigger(char key) { @@ -141,8 +141,8 @@ void MenuItem::display() { void MenuItem::wipe() { CursorMan.showMouse(false); - _menu->drawMenuText(_menu->_menuBar._menuItems[_menu->_activeMenuItem._activeNum]._xpos, 1, - _menu->_menuBar._menuItems[_menu->_activeMenuItem._activeNum]._trigger, + _menu->drawMenuText(_menu->_menuBar._menuItems[_menu->_activeMenuItem._activeNum]._xpos, 1, + _menu->_menuBar._menuItems[_menu->_activeMenuItem._activeNum]._trigger, _menu->_menuBar._menuItems[_menu->_activeMenuItem._activeNum]._title, true, false); _activeNow = false; diff --git a/engines/avalanche/module.mk b/engines/avalanche/module.mk index 9c1205df02..0f66bb8213 100644 --- a/engines/avalanche/module.mk +++ b/engines/avalanche/module.mk @@ -15,7 +15,8 @@ MODULE_OBJS = \ dialogs.o \ sequence.o \ sound.o \ - timer.o + timer.o \ + nim.o # This module can be built as a plugin ifeq ($(ENABLE_AVALANCHE), DYNAMIC_PLUGIN) diff --git a/engines/avalanche/nim.cpp b/engines/avalanche/nim.cpp new file mode 100644 index 0000000000..a2572f1fa5 --- /dev/null +++ b/engines/avalanche/nim.cpp @@ -0,0 +1,177 @@ +/* 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. + * + */ + +/* + * This code is based on the original source code of Lord Avalot d'Argent version 1.3. + * Copyright (c) 1994-1995 Mike, Mark and Thomas Thurman. + */ + +#include "avalanche/avalanche.h" +#include "avalanche/nim.h" + +namespace Avalanche { + +const char * const Nim::kNames[2] = {"Avalot", "Dogfood"}; + +Nim::Nim(AvalancheEngine *vm) { + _vm = vm; + + _playedNim = 0; +} + +void Nim::resetVariables() { + _playedNim = 0; +} + +void Nim::synchronize(Common::Serializer &sz) { + if (sz.isLoading() && sz.getVersion() < 2) + return; + + sz.syncAsByte(_playedNim); +} + +void Nim::playNim() { + if (_vm->_wonNim) { // Already won the game. + _vm->_dialogs->displayScrollChain('Q', 6); + return; + } + + if (!_vm->_askedDogfoodAboutNim) { + _vm->_dialogs->displayScrollChain('Q', 84); + return; + } + + _vm->_dialogs->displayScrollChain('Q', 3); + _playedNim++; + _vm->fadeOut(); + + _vm->_graphics->saveScreen(); + + CursorMan.showMouse(false); + setup(); + board(); + CursorMan.showMouse(true); + + do { + startMove(); + if (_dogfoodsTurn) + dogFood(); + else + takeSome(); + _stones[_row] -= _number; + showChanges(); + } while (_stonesLeft != 0); + + endOfGame(); // Winning sequence is A1, B3, B1, C1, C1, btw. + + _vm->fadeOut(); + CursorMan.showMouse(false); + + _vm->_graphics->restoreScreen(); + _vm->_graphics->removeBackup(); + + CursorMan.showMouse(true); + _vm->fadeIn(); + + if (_dogfoodsTurn) { + // Dogfood won - as usual. + if (_playedNim == 1) // Your first game. + _vm->_dialogs->displayScrollChain('Q', 4); // Goody! Play me again? + else + _vm->_dialogs->displayScrollChain('Q', 5); // Oh, look at that! I've won again! + _vm->decreaseMoney(4); // And you've just lost 4d! + } else { + // You won - strange! + _vm->_dialogs->displayScrollChain('Q', 7); + _vm->_objects[kObjectLute - 1] = true; + _vm->refreshObjectList(); + _vm->_wonNim = true; + _vm->_background->draw(-1, -1, 0); // Show the settle with no lute on it. + + // 7 points for winning! + _vm->incScore(7); + } + + if (_playedNim == 1) { + // 3 points for playing your 1st game. + _vm->incScore(3); + } +} + +void Nim::chalk(int x,int y, Common::String z) { + warning("STUB: Nim::chalk()"); +} + +void Nim::setup() { + warning("STUB: Nim::setup()"); +} + +void Nim::plotStone(byte x,byte y) { + warning("STUB: Nim::plotStone()"); +} + +void Nim::board() { + warning("STUB: Nim::board()"); +} + +void Nim::startMove() { + warning("STUB: Nim::startMove()"); +} + +void Nim::showChanges() { + warning("STUB: Nim::showChanges()"); +} + +void Nim::blip() { + warning("STUB: Nim::blip()"); +} + +void Nim::checkMouse() { + warning("STUB: Nim::checkMouse()"); +} + +void Nim::less() { + warning("STUB: Nim::less()"); +} + +void Nim::takeSome() { + warning("STUB: Nim::takeSome()"); +} + +void Nim::endOfGame() { + warning("STUB: Nim::endOfGame()"); +} + +void Nim::dogFood() { + warning("STUB: Nim::dogFood()"); +} + +bool Nim::find(byte x) { + warning("STUB: Nim::find()"); + return true; +} + +void Nim::findAp(byte start,byte stepsize) { + warning("STUB: Nim::findAp()"); +} + +} // End of namespace Avalanche diff --git a/engines/avalanche/nim.h b/engines/avalanche/nim.h new file mode 100644 index 0000000000..a76afcfe22 --- /dev/null +++ b/engines/avalanche/nim.h @@ -0,0 +1,76 @@ +/* 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. + * + */ + +/* + * This code is based on the original source code of Lord Avalot d'Argent version 1.3. + * Copyright (c) 1994-1995 Mike, Mark and Thomas Thurman. + */ + +#ifndef AVALANCHE_NIM_H +#define AVALANCHE_NIM_H + +namespace Avalanche { + +class Nim { +public: + Nim(AvalancheEngine *vm); + void resetVariables(); + void synchronize(Common::Serializer &sz); + void playNim(); + +private: + AvalancheEngine *_vm; + + static const char * const kNames[2]; + + byte _old[3]; + byte _stones[3]; + byte _stonePic[4][23][7]; // Picture of Nimstone. + byte _turns; + bool _dogfoodsTurn; + byte _stonesLeft; + bool _clicked; + byte _row; + byte _number; + bool _squeak; + int8 _mNum, _mRow; + byte _playedNim; // How many times you've played Nim. + + void chalk(int x,int y, Common::String z); + void setup(); + void plotStone(byte x,byte y); + void board(); + void startMove(); + void showChanges(); + void blip(); + void checkMouse(); + void less(); + void takeSome(); + void endOfGame(); + void dogFood(); + bool find(byte x); + void findAp(byte start,byte stepsize); +}; + +} // End of namespace Avalanche + +#endif // AVALANCHE_NIM_H diff --git a/engines/avalanche/parser.cpp b/engines/avalanche/parser.cpp index 6090dc967a..811e71ee1d 100644 --- a/engines/avalanche/parser.cpp +++ b/engines/avalanche/parser.cpp @@ -27,6 +27,7 @@ #include "avalanche/avalanche.h" #include "avalanche/parser.h" +#include "avalanche/nim.h" #include "gui/saveload.h" @@ -50,7 +51,7 @@ Parser::Parser(AvalancheEngine *vm) { _thing2 = 0; _sworeNum = 0; _alcoholLevel = 0; - _playedNim = 0; + _boughtOnion = false; } @@ -521,10 +522,17 @@ void Parser::cursorOff() { _cursorState = false; } +/** + * Asks the parsekey proc in Dropdown if it knows it. + */ void Parser::tryDropdown() { - warning("STUB: Parser::tryDropdown()"); // TODO: Implement at the same time with Dropdown's keyboard handling. + // TODO: Implement at the same time with Dropdown's keyboard handling. + warning("STUB: Parser::tryDropdown()"); } +/** + * Returns the index of the first appearance of crit in src. + */ int16 Parser::getPos(const Common::String &crit, const Common::String &src) { if (src.contains(crit)) return strstr(src.c_str(),crit.c_str()) - src.c_str(); @@ -624,6 +632,9 @@ void Parser::cheatParse(Common::String codes) { warning("STUB: Parser::cheatParse()"); } +/** + * Strips punctuation from word. + */ void Parser::stripPunctuation(Common::String &word) { const char punct[] = "~`!@#$%^&*()_+-={}[]:\"|;'\\,./<>?"; @@ -732,7 +743,7 @@ void Parser::storeInterrogation(byte interrogation) { if (!_vm->_spareEvening.empty()) _vm->_spareEvening.clear(); _vm->_spareEvening = _inputText; - _vm->_dialogs->displayScrollChain('z', 5); // His closing statement... + _vm->_dialogs->displayScrollChain('Z', 5); // His closing statement... _vm->_animation->_sprites[1]->walkTo(3); // The end of the drawbridge _vm->_animation->_sprites[1]->_vanishIfStill = true; // Then go away! _vm->_magics[1]._operation = kMagicNothing; @@ -748,8 +759,6 @@ void Parser::storeInterrogation(byte interrogation) { _vm->_timer->cardiffSurvey(); } - - void Parser::parse() { // First parsing - word identification if (!_thats.empty()) @@ -762,7 +771,6 @@ void Parser::parse() { _person = kPeoplePardon; clearWords(); - // A cheat mode attempt. if (_inputText[0] == '.') { cheatParse(_inputText); @@ -925,7 +933,7 @@ void Parser::parse() { _polite = true; } - if ((!unkString.empty()) && (_verb != kVerbCodeExam) && (_verb != kVerbCodeTalk) && + if ((!unkString.empty()) && (_verb != kVerbCodeExam) && (_verb != kVerbCodeTalk) && (_verb != kVerbCodeSave) && (_verb != kVerbCodeLoad) && (_verb != kVerbCodeDir)) { Common::String tmpStr = Common::String::format("Sorry, but I have no idea what \"%s\" means. Can you rephrase it?", unkString.c_str()); _vm->_dialogs->displayText(tmpStr); @@ -947,6 +955,9 @@ void Parser::parse() { } } +/** + * Examine a standard object-thing + */ void Parser::examineObject() { if (_thing != _vm->_thinks) _vm->thinkAbout(_thing, AvalancheEngine::kThing); @@ -956,29 +967,29 @@ void Parser::examineObject() { switch (_vm->_wineState) { case 1: // Normal examine wine scroll - _vm->_dialogs->displayScrollChain('t', 1); + _vm->_dialogs->displayScrollChain('T', 1); break; case 2: // Bad wine - _vm->_dialogs->displayScrollChain('d', 6); + _vm->_dialogs->displayScrollChain('D', 6); break; case 3: // Vinegar - _vm->_dialogs->displayScrollChain('d', 7); + _vm->_dialogs->displayScrollChain('D', 7); break; } break; case kObjectOnion: if (_vm->_rottenOnion) // Yucky onion - _vm->_dialogs->displayScrollChain('q', 21); + _vm->_dialogs->displayScrollChain('Q', 21); else // Normal onion - _vm->_dialogs->displayScrollChain('t', 18); + _vm->_dialogs->displayScrollChain('T', 18); break; default: // Ordinarily - _vm->_dialogs->displayScrollChain('t', _thing); + _vm->_dialogs->displayScrollChain('T', _thing); } } @@ -1011,7 +1022,7 @@ void Parser::exampers() { // He's asleep. _vm->_dialogs->displayScrollChain('Q', 65); else - _vm->_dialogs->displayScrollChain('p', newPerson); + _vm->_dialogs->displayScrollChain('P', newPerson); if ((_person == kPeopleAyles) && !_vm->_aylesIsAwake) _vm->_dialogs->displayScrollChain('Q', 13); @@ -1140,7 +1151,7 @@ void Parser::swallow() { case 2: case 3: // You can't drink it! - _vm->_dialogs->displayScrollChain('d', 8); + _vm->_dialogs->displayScrollChain('D', 8); break; } break; @@ -1177,6 +1188,9 @@ void Parser::swallow() { } } +/** + * this lists the other people in the room. + */ void Parser::peopleInRoom() { // First compute the number of people in the room. byte numPeople = 0; @@ -1214,42 +1228,45 @@ void Parser::peopleInRoom() { _vm->_dialogs->displayText(tmpStr + " here."); } +/** + * This is called when you say "look". + */ void Parser::lookAround() { _vm->_dialogs->displayText(*_vm->_also[0][1]); switch (_vm->_room) { case kRoomSpludwicks: if (_vm->_avariciusTalk > 0) - _vm->_dialogs->displayScrollChain('q', 23); + _vm->_dialogs->displayScrollChain('Q', 23); else peopleInRoom(); break; case kRoomRobins: if (_vm->_tiedUp) - _vm->_dialogs->displayScrollChain('q', 38); + _vm->_dialogs->displayScrollChain('Q', 38); if (_vm->_mushroomGrowing) - _vm->_dialogs->displayScrollChain('q', 55); + _vm->_dialogs->displayScrollChain('Q', 55); break; case kRoomInsideCardiffCastle: if (!_vm->_takenPen) - _vm->_dialogs->displayScrollChain('q', 49); + _vm->_dialogs->displayScrollChain('Q', 49); break; case kRoomLustiesRoom: if (_vm->_lustieIsAsleep) - _vm->_dialogs->displayScrollChain('q', 65); + _vm->_dialogs->displayScrollChain('Q', 65); break; case kRoomCatacombs: switch (_vm->_catacombY * 256 + _vm->_catacombX) { case 258 : // Inside art gallery. - _vm->_dialogs->displayScrollChain('q', 80); + _vm->_dialogs->displayScrollChain('Q', 80); break; case 514 : // Outside ditto. - _vm->_dialogs->displayScrollChain('q', 81); + _vm->_dialogs->displayScrollChain('Q', 81); break; case 260 : // Outside Geida's room. - _vm->_dialogs->displayScrollChain('q', 82); + _vm->_dialogs->displayScrollChain('Q', 82); break; } break; @@ -1272,7 +1289,7 @@ void Parser::openDoor() { break; case kRoomSpludwicks: if (_thing == 61) { - _vm->_dialogs->displayScrollChain('q', 85); + _vm->_dialogs->displayScrollChain('Q', 85); return; } break; @@ -1290,7 +1307,7 @@ void Parser::openDoor() { switch (portal->_operation) { case kMagicExclaim: _vm->_animation->_sprites[0]->bounce(); - _vm->_dialogs->displayScrollChain('x', portal->_data); + _vm->_dialogs->displayScrollChain('X', portal->_data); break; case kMagicTransport: _vm->flipRoom((Room)((portal->_data) >> 8), portal->_data & 0x0F); @@ -1318,6 +1335,9 @@ void Parser::openDoor() { _vm->_dialogs->displayText("Door? What door?"); } +/** + * Called when you call kVerbCodeput. + */ void Parser::putProc() { if (!isHolding()) return; @@ -1346,7 +1366,7 @@ void Parser::putProc() { // Put onion into vinegar! Yes! _vm->_onionInVinegar = true; _vm->incScore(7); - _vm->_dialogs->displayScrollChain('u', 9); + _vm->_dialogs->displayScrollChain('U', 9); } } } else @@ -1424,6 +1444,7 @@ void Parser::goToCauldron() { /** * Check is it's possible to give something to Spludwick + * The result of this function is whether or not he says "Hey, thanks!". * @remarks Originally called 'give2spludwick' */ bool Parser::giveToSpludwick() { @@ -1436,10 +1457,10 @@ bool Parser::giveToSpludwick() { case kObjectOnion: _vm->_objects[kObjectOnion - 1] = false; if (_vm->_rottenOnion) - _vm->_dialogs->displayScrollChain('q', 22); + _vm->_dialogs->displayScrollChain('Q', 22); else { _vm->_givenToSpludwick++; - _vm->_dialogs->displayScrollChain('q', 20); + _vm->_dialogs->displayScrollChain('Q', 20); goToCauldron(); _vm->incScore(3); } @@ -1449,13 +1470,13 @@ bool Parser::giveToSpludwick() { _vm->_objects[kObjectInk - 1] = false; _vm->refreshObjectList(); _vm->_givenToSpludwick++; - _vm->_dialogs->displayScrollChain('q', 24); + _vm->_dialogs->displayScrollChain('Q', 24); goToCauldron(); _vm->incScore(3); break; case kObjectMushroom: _vm->_objects[kObjectMushroom - 1] = false; - _vm->_dialogs->displayScrollChain('q', 25); + _vm->_dialogs->displayScrollChain('Q', 25); _vm->incScore(5); _vm->_givenToSpludwick++; goToCauldron(); @@ -1503,6 +1524,9 @@ void Parser::already() { _vm->_dialogs->displayText("You're already standing!"); } +/** + * Called when you ask Avvy to stand. + */ void Parser::standUp() { switch (_vm->_room) { case kRoomYours: @@ -1510,9 +1534,9 @@ void Parser::standUp() { if (_vm->_avvyIsAwake && _vm->_avvyInBed) { // But he's in bed. if (_vm->_teetotal) { - _vm->_dialogs->displayScrollChain('d', 12); + _vm->_dialogs->displayScrollChain('D', 12); _vm->_graphics->setBackgroundColor(kColorBlack); - _vm->_dialogs->displayScrollChain('d', 14); + _vm->_dialogs->displayScrollChain('D', 14); } _vm->_animation->_sprites[0]->_visible = true; _vm->_userMovesAvvy = true; @@ -1567,7 +1591,7 @@ void Parser::getProc(char thing) { _vm->_dialogs->displayText(tmpStr); } } else - _vm->_dialogs->displayScrollChain('q', 57); + _vm->_dialogs->displayScrollChain('Q', 57); break; case kRoomInsideCardiffCastle: switch (thing) { @@ -1588,15 +1612,15 @@ void Parser::getProc(char thing) { _vm->_dialogs->displayText("Taken."); } } else if (_vm->_standingOnDais) - _vm->_dialogs->displayScrollChain('q', 53); + _vm->_dialogs->displayScrollChain('Q', 53); else - _vm->_dialogs->displayScrollChain('q', 51); + _vm->_dialogs->displayScrollChain('Q', 51); break; case kObjectBolt: - _vm->_dialogs->displayScrollChain('q', 52); + _vm->_dialogs->displayScrollChain('Q', 52); break; default: - _vm->_dialogs->displayScrollChain('q', 57); + _vm->_dialogs->displayScrollChain('Q', 57); } break; case kRoomRobins: @@ -1609,10 +1633,10 @@ void Parser::getProc(char thing) { _vm->refreshObjectList(); _vm->incScore(3); } else - _vm->_dialogs->displayScrollChain('q', 57); + _vm->_dialogs->displayScrollChain('Q', 57); break; default: - _vm->_dialogs->displayScrollChain('q', 57); + _vm->_dialogs->displayScrollChain('Q', 57); } } @@ -1629,7 +1653,7 @@ void Parser::giveGeidaTheLute() { _vm->_objects[kObjectLute - 1] = false; _vm->refreshObjectList(); // She plays it. - _vm->_dialogs->displayScrollChain('q', 64); + _vm->_dialogs->displayScrollChain('Q', 64); _vm->_timer->addTimer(1, Timer::kProcGiveLuteToGeida, Timer::kReasonGeidaSings); //_vm->_enid->backToBootstrap(4); TODO: Replace it with proper ScummVM-friendly function(s)! Do not remove until then! @@ -1643,7 +1667,7 @@ void Parser::playHarp() { } void Parser::winSequence() { - _vm->_dialogs->displayScrollChain('q', 78); + _vm->_dialogs->displayScrollChain('Q', 78); _vm->_sequence->startWinSeq(); _vm->_timer->addTimer(30, Timer::kProcWinning, Timer::kReasonWinning); } @@ -1668,7 +1692,6 @@ void Parser::doThat() { // "Slip" object _thing -= 49; - if ((_verb != kVerbCodeLoad) && (_verb != kVerbCodeSave) && (_verb != kVerbCodeQuit) && (_verb != kVerbCodeInfo) && (_verb != kVerbCodeHelp) && (_verb != kVerbCodeLarrypass) && (_verb != kVerbCodePhaon) && (_verb != kVerbCodeBoss) && (_verb != kVerbCodeCheat) && (_verb != kVerbCodeRestart) && (_verb != kVerbCodeDir) && (_verb != kVerbCodeScore) && (_verb != kVerbCodeHiscores) && (_verb != kVerbCodeSmartAlec)) { @@ -1690,7 +1713,7 @@ void Parser::doThat() { case kVerbCodeOpen: openDoor(); break; - case kVerbCodePause: { + case kVerbCodePause: { // Note that the original game doesn't care about the "O.K." box neither, it accepts // clicks from everywhere on the screen to continue. Just like my code. Common::String tmpStr = Common::String::format("Game paused.%c%c%cPress Enter, Esc, or click the mouse on the `O.K.\" " \ @@ -1782,7 +1805,7 @@ void Parser::doThat() { break; case kPeopleIbythneth: if (_thing == kObjectBadge) { - _vm->_dialogs->displayScrollChain('q', 32); // Thanks! Wow! + _vm->_dialogs->displayScrollChain('Q', 32); // Thanks! Wow! _vm->incScore(3); _vm->_objects[kObjectBadge - 1] = false; _vm->_objects[kObjectHabit - 1] = true; @@ -1796,7 +1819,7 @@ void Parser::doThat() { if (_vm->_aylesIsAwake) { if (_thing == kObjectPen) { _vm->_objects[kObjectPen - 1] = false; - _vm->_dialogs->displayScrollChain('q', 54); + _vm->_dialogs->displayScrollChain('Q', 54); _vm->_objects[kObjectInk - 1] = true; _vm->_givenPenToAyles = true; _vm->refreshObjectList(); @@ -1811,7 +1834,7 @@ void Parser::doThat() { case kObjectPotion: _vm->_objects[kObjectPotion - 1] = false; // She drinks it. - _vm->_dialogs->displayScrollChain('u', 16); + _vm->_dialogs->displayScrollChain('U', 16); _vm->incScore(2); _vm->_givenPotionToGeida = true; _vm->refreshObjectList(); @@ -1830,7 +1853,7 @@ void Parser::doThat() { winSequence(); else // That Geida woman! - _vm->_dialogs->displayScrollChain('q', 77); + _vm->_dialogs->displayScrollChain('Q', 77); break; default: _vm->_dialogs->sayThanks(_thing - 1); @@ -1860,7 +1883,7 @@ void Parser::doThat() { if (savegameId < 0) // dialog aborted, nothing to load return; - + _vm->loadGame(savegameId); } break; @@ -1964,45 +1987,7 @@ void Parser::doThat() { // They just typed "play"... switch (_vm->_room) { case kRoomArgentPub: - // ...in the pub, => play Nim. - warning("STUB: Parser::doThat() - case kVerbCodeplay - play_nim()"); - // play_nim(); - - // The following parts are copied from play_nim(). - // The player automatically wins the game everytime he wins, until I implement the mini-game. - if (_vm->_wonNim) { // Already won the game. - _vm->_dialogs->displayScrollChain('Q', 6); - return; - } - - if (!_vm->_askedDogfoodAboutNim) { - _vm->_dialogs->displayScrollChain('q', 84); - return; - } - - _vm->_dialogs->displayScrollChain('Q', 3); - _playedNim++; - - // You won - strange! - - // You won! Give us a lute! - _vm->_dialogs->displayScrollChain('Q', 7); - _vm->_objects[kObjectLute - 1] = true; - _vm->refreshObjectList(); - _vm->_wonNim = true; - // Show the settle with no lute on it. - _vm->_background->draw(-1, -1, 0); - // 7 points for winning! - _vm->incScore(7); - - if (_playedNim == 1) - // 3 points for playing your 1st game. - _vm->incScore(3); - - // A warning to the player that there should have been a mini-game. TODO: Remove it later!!! - _vm->_dialogs->displayText(Common::String("P.S.: There should have been the mini-game called \"Nim\", " \ - "but I haven't implemented it yet: you win and get the lute automatically.") - + kControlNewLine + kControlNewLine + "Peter (uruk)"); + _vm->_nim->playNim(); // ...in the pub, => play Nim. break; case kRoomMusicRoom: playHarp(); @@ -2081,13 +2066,13 @@ void Parser::doThat() { break; case kVerbCodeMagic: if (_vm->_avariciusTalk > 0) - _vm->_dialogs->displayScrollChain('q', 19); + _vm->_dialogs->displayScrollChain('Q', 19); else { if ((_vm->_room == kRoomSpludwicks) & (_vm->_animation->inField(1))) { // Avaricius appears! - _vm->_dialogs->displayScrollChain('q', 17); + _vm->_dialogs->displayScrollChain('Q', 17); if (_vm->getRoom(kPeopleSpludwick) == kRoomSpludwicks) - _vm->_dialogs->displayScrollChain('q', 18); + _vm->_dialogs->displayScrollChain('Q', 18); else { Avalanche::AnimationType *spr = _vm->_animation->_sprites[1]; // Avaricius @@ -2241,7 +2226,7 @@ void Parser::doThat() { case kRoomNottsPub: // Can't sell to southerners. - _vm->_dialogs->displayScrollChain('n', 15); + _vm->_dialogs->displayScrollChain('N', 15); break; default: // Can't buy that. @@ -2317,7 +2302,7 @@ void Parser::doThat() { break; case kVerbCodeScore: { Common::String tmpStr = Common::String::format("Your score is %d,%c%cout of a possible 128.%c%c " \ - "This gives you a rank of %s.%c%c%s", _vm->_dnascore, kControlCenter, kControlNewLine, kControlNewLine, + "This gives you a rank of %s.%c%c%s", _vm->_dnascore, kControlCenter, kControlNewLine, kControlNewLine, kControlNewLine, rank().c_str(), kControlNewLine, kControlNewLine, totalTime().c_str()); _vm->_dialogs->displayText(tmpStr); } @@ -2378,7 +2363,7 @@ void Parser::doThat() { // Picture of Avvy, awake in bed. _vm->_background->draw(-1, -1, 2); if (_vm->_teetotal) - _vm->_dialogs->displayScrollChain('d', 13); + _vm->_dialogs->displayScrollChain('D', 13); } else _vm->_dialogs->displayText("You're already awake, Avvy!"); break; @@ -2479,7 +2464,6 @@ void Parser::resetVariables() { _wearing = kNothing; _sworeNum = 0; _alcoholLevel = 0; - _playedNim = 0; _boughtOnion = false; } @@ -2487,7 +2471,10 @@ void Parser::synchronize(Common::Serializer &sz) { sz.syncAsByte(_wearing); sz.syncAsByte(_sworeNum); sz.syncAsByte(_alcoholLevel); - sz.syncAsByte(_playedNim); + if (sz.isLoading() && sz.getVersion() < 2) { + int dummy; + sz.syncAsByte(dummy); + } sz.syncAsByte(_boughtOnion); } diff --git a/engines/avalanche/parser.h b/engines/avalanche/parser.h index bdb5ab9bc1..20066329e5 100644 --- a/engines/avalanche/parser.h +++ b/engines/avalanche/parser.h @@ -34,17 +34,16 @@ #include "common/str.h" #include "common/serializer.h" - namespace Avalanche { class AvalancheEngine; class Parser { public: - static const byte kPardon = 254; // Didn't understand / wasn't given. static const int16 kParserWordsNum = 277; // How many words does the parser know? + static const int16 kFirstPassword = 88; // words[kFirstPassword] should equal "TIROS". + static const byte kPardon = 254; // Didn't understand / wasn't given. static const byte kNothing = 250; - static const byte kMoved = 0; // This word was moved. (Usually because it was the subject of conversation.) - static const int16 kFirstPassword = 88; // words[kFirstPassword] should equal "TIROS". + static const byte kMoved = 0; // This word was moved. (Usually because it was the subject of conversation.) struct VocabEntry { byte _number; @@ -63,9 +62,9 @@ public: byte _thing; People _person; bool _polite; - Common::String _inputText; // Original name: current + Common::String _inputText; Common::String _inputTextBackup; - byte _inputTextPos; // Original name: curpos + byte _inputTextPos; bool _quote; bool _cursorState; bool _weirdWord; @@ -87,8 +86,8 @@ public: void plotText(); void cursorOn(); void cursorOff(); - void tryDropdown(); // This asks the parsekey proc in Dropdown if it knows it. - int16 getPos(const Common::String &crit, const Common::String &src); // Returns the index of the first appearance of crit in src. + void tryDropdown(); + int16 getPos(const Common::String &crit, const Common::String &src); void doVerb(VerbCode id); void resetVariables(); @@ -107,10 +106,9 @@ private: Common::String _thats; byte _thing2; - byte _sworeNum; // number of times you've sworn + byte _sworeNum; // number of times you've sworn byte _alcoholLevel; // Your blood alcohol level. - byte _playedNim; // How many times you've played Nim. - bool _boughtOnion; // Have you bought an onion yet? + bool _boughtOnion; // Have you bought an onion yet? byte wordNum(Common::String word); void replace(Common::String oldChars, byte newChar); @@ -120,14 +118,14 @@ private: void clearWords(); void cheatParse(Common::String codes); - void stripPunctuation(Common::String &word); // Strips punctuation from word. - void displayWhat(byte target, bool animate, bool &ambiguous); // << It's an adjective! + void stripPunctuation(Common::String &word); + void displayWhat(byte target, bool animate, bool &ambiguous); bool doPronouns(); void properNouns(); - void lookAround(); // This is called when you say "look". + void lookAround(); void openDoor(); void storeInterrogation(byte interrogation); - void examineObject(); // Examine a standard object-thing + void examineObject(); bool isPersonHere(); void exampers(); bool isHolding(); @@ -135,14 +133,14 @@ private: void examine(); void inventory(); void swallow(); - void peopleInRoom(); // This lists the other people in the room. - void putProc(); // Called when you call kVerbCodeput. + void peopleInRoom(); + void putProc(); void notInOrder(); void goToCauldron(); - bool giveToSpludwick(); // The result of this fn is whether or not he says "Hey, thanks!". + bool giveToSpludwick(); void cardiffClimbing(); void already(); - void standUp(); // Called when you ask Avvy to stand. + void standUp(); void getProc(char thing); void giveGeidaTheLute(); void playHarp(); diff --git a/engines/avalanche/timer.cpp b/engines/avalanche/timer.cpp index 8a4aa1c055..40f2af529a 100644 --- a/engines/avalanche/timer.cpp +++ b/engines/avalanche/timer.cpp @@ -201,7 +201,7 @@ void Timer::updateTimer() { } } } - + _vm->_roomCycles++; // Cycles since you've been in this room. } @@ -224,7 +224,7 @@ void Timer::openDrawbridge() { } void Timer::avariciusTalks() { - _vm->_dialogs->displayScrollChain('q', _vm->_avariciusTalk); + _vm->_dialogs->displayScrollChain('Q', _vm->_avariciusTalk); _vm->_avariciusTalk++; if (_vm->_avariciusTalk < 17) @@ -267,25 +267,25 @@ void Timer::stairs() { void Timer::cardiffSurvey() { if (_vm->_cardiffQuestionNum == 0) { _vm->_cardiffQuestionNum++; - _vm->_dialogs->displayScrollChain('q', 27); + _vm->_dialogs->displayScrollChain('Q', 27); } - _vm->_dialogs->displayScrollChain('z', _vm->_cardiffQuestionNum); + _vm->_dialogs->displayScrollChain('Z', _vm->_cardiffQuestionNum); _vm->_interrogation = _vm->_cardiffQuestionNum; addTimer(182, kProcCardiffSurvey, kReasonCardiffsurvey); } void Timer::cardiffReturn() { - _vm->_dialogs->displayScrollChain('q', 28); + _vm->_dialogs->displayScrollChain('Q', 28); cardiffSurvey(); // Add end of question. } void Timer::cwytalotInHerts() { - _vm->_dialogs->displayScrollChain('q', 29); + _vm->_dialogs->displayScrollChain('Q', 29); } void Timer::getTiedUp() { - _vm->_dialogs->displayScrollChain('q', 34); // ...Trouble! + _vm->_dialogs->displayScrollChain('Q', 34); // ...Trouble! _vm->_userMovesAvvy = false; _vm->_beenTiedUp = true; _vm->_animation->stopWalking(); @@ -312,18 +312,18 @@ void Timer::hangAround() { avvy->init(7, true); // Robin Hood _vm->setRoom(kPeopleRobinHood, kRoomRobins); _vm->_animation->appearPed(0, 1); - _vm->_dialogs->displayScrollChain('q', 39); + _vm->_dialogs->displayScrollChain('Q', 39); avvy->walkTo(6); addTimer(55, kProcHangAround2, kReasonHangingAround); } void Timer::hangAround2() { - _vm->_dialogs->displayScrollChain('q', 40); + _vm->_dialogs->displayScrollChain('Q', 40); AnimationType *spr = _vm->_animation->_sprites[1]; spr->_vanishIfStill = false; spr->walkTo(3); _vm->setRoom(kPeopleFriarTuck, kRoomRobins); - _vm->_dialogs->displayScrollChain('q', 41); + _vm->_dialogs->displayScrollChain('Q', 41); _vm->_animation->_sprites[0]->remove(); spr->remove(); // Get rid of Robin Hood and Friar Tuck. @@ -367,7 +367,7 @@ void Timer::afterTheShootemup() { warning("STUB: Timer::after_the_shootemup()"); - _vm->_dialogs->displayScrollChain('q', 70); + _vm->_dialogs->displayScrollChain('Q', 70); } void Timer::jacquesWakesUp() { @@ -423,7 +423,7 @@ void Timer::naughtyDuke() { // This is when the Duke comes in and takes your mon void Timer::naughtyDuke2() { AnimationType *spr = _vm->_animation->_sprites[1]; - _vm->_dialogs->displayScrollChain('q', 48); // "Ha ha, it worked again!" + _vm->_dialogs->displayScrollChain('Q', 48); // "Ha ha, it worked again!" spr->walkTo(0); // Walk to the door. spr->_vanishIfStill = true; // Then go away! @@ -476,14 +476,14 @@ void Timer::jump() { _vm->_arrowInTheDoor = false; // You've got it. _vm->_objects[kObjectBolt - 1] = true; _vm->refreshObjectList(); - _vm->_dialogs->displayScrollChain('q', 50); + _vm->_dialogs->displayScrollChain('Q', 50); _vm->incScore(3); } } } void Timer::crapulusSaysSpludOut() { - _vm->_dialogs->displayScrollChain('q', 56); + _vm->_dialogs->displayScrollChain('Q', 56); _vm->_crapulusWillTell = false; } @@ -578,7 +578,7 @@ void Timer::robinHoodAndGeida() { } void Timer::robinHoodAndGeidaTalk() { - _vm->_dialogs->displayScrollChain('q', 66); + _vm->_dialogs->displayScrollChain('Q', 66); AnimationType *avvy = _vm->_animation->_sprites[0]; AnimationType *spr = _vm->_animation->_sprites[1]; @@ -597,7 +597,7 @@ void Timer::avalotReturns() { spr->remove(); avvy->init(0, true); _vm->_animation->appearPed(0, 0); - _vm->_dialogs->displayScrollChain('q', 67); + _vm->_dialogs->displayScrollChain('Q', 67); _vm->_userMovesAvvy = true; } @@ -628,12 +628,12 @@ void Timer::arkataShouts() { if (_vm->_teetotal) return; - _vm->_dialogs->displayScrollChain('q', 76); + _vm->_dialogs->displayScrollChain('Q', 76); addTimer(160, kProcArkataShouts, kReasonArkataShouts); } void Timer::winning() { - _vm->_dialogs->displayScrollChain('q', 79); + _vm->_dialogs->displayScrollChain('Q', 79); _vm->_pingo->winningPic(); warning("STUB: Timer::winning()"); |