diff options
author | Paul Gilbert | 2015-05-31 14:45:10 -0400 |
---|---|---|
committer | Paul Gilbert | 2015-05-31 14:45:10 -0400 |
commit | e5296ebf8dd09f603499b1894a33865ec71bb28f (patch) | |
tree | d7de032efd54dfdb3159cbc778a0c9ce8cd8aa91 /engines/mads | |
parent | 673537bad93f0b440172a0cc263ebf19cc95ffc0 (diff) | |
parent | 141ff4d08dc24b6bb17098bd71801e2a58e6a38f (diff) | |
download | scummvm-rg350-e5296ebf8dd09f603499b1894a33865ec71bb28f.tar.gz scummvm-rg350-e5296ebf8dd09f603499b1894a33865ec71bb28f.tar.bz2 scummvm-rg350-e5296ebf8dd09f603499b1894a33865ec71bb28f.zip |
Merge branch 'master' into phantom
Diffstat (limited to 'engines/mads')
98 files changed, 1878 insertions, 1052 deletions
diff --git a/engines/mads/action.cpp b/engines/mads/action.cpp index 199ae39000..f1c562675f 100644 --- a/engines/mads/action.cpp +++ b/engines/mads/action.cpp @@ -8,12 +8,12 @@ * 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. @@ -567,9 +567,8 @@ void MADSAction::leftClick() { switch (userInterface._category) { case CAT_COMMAND: if (_selectedRow >= 0) { - if (_verbType == VERB_ONLY) { + if (_verbType == VERB_ONLY) _selectedAction = -1; - } else { _recentCommand = _selectedRow; _recentCommandSource = _commandSource; diff --git a/engines/mads/action.h b/engines/mads/action.h index cfd5a3be3f..3ea10cd964 100644 --- a/engines/mads/action.h +++ b/engines/mads/action.h @@ -8,12 +8,12 @@ * 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. diff --git a/engines/mads/animation.cpp b/engines/mads/animation.cpp index 9f0e0adb6d..e4f44fc308 100644 --- a/engines/mads/animation.cpp +++ b/engines/mads/animation.cpp @@ -8,12 +8,12 @@ * 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. @@ -41,7 +41,7 @@ void AAHeader::load(Common::SeekableReadStream *f) { _spritesIndex = f->readUint16LE(); _scrollPosition.x = f->readSint16LE(); _scrollPosition.y = f->readSint16LE(); - _scrollTicks = f->readUint32LE(); + _scrollTicks = f->readUint32LE() & 0xffff; f->skip(6); char buffer[FILENAME_SIZE]; @@ -340,9 +340,6 @@ void Animation::startAnimation(int endTrigger) { _unkIndex = -1; //SpriteAsset *asset = _scene->_sprites[_spriteListIndexes[_header._spritesIndex]]; - // TODO: Weird stuff with _unkList. Seems like it's treated as pointers - // here, but in processText, it's used as POINTs? - loadFrame(1); } @@ -439,10 +436,8 @@ void Animation::update() { if (_vm->_game->_scene._frameStartTime < _nextFrameTimer) return; - for (uint idx = 0; idx < scene._spriteSlots.size(); ++idx) { - if (scene._spriteSlots[idx]._seqIndex >= 0x80) - scene._spriteSlots[idx]._flags = IMG_ERASE; - } + // Erase any active sprites + eraseSprites(); // Validate the current frame if (_currentFrame >= (int)_miscEntries.size()) { @@ -601,12 +596,19 @@ void Animation::setCurrentFrame(int frameNumber) { _currentFrame = frameNumber; _oldFrameEntry = 0; _freeFlag = false; - - _nextScrollTimer = _nextFrameTimer = _vm->_game->_scene._frameStartTime; } void Animation::setNextFrameTimer(int frameNumber) { _nextFrameTimer = frameNumber; } +void Animation::eraseSprites() { + Scene &scene = _vm->_game->_scene; + + for (uint idx = 0; idx < scene._spriteSlots.size(); ++idx) { + if (scene._spriteSlots[idx]._seqIndex >= 0x80) + scene._spriteSlots[idx]._flags = IMG_ERASE; + } +} + } // End of namespace MADS diff --git a/engines/mads/animation.h b/engines/mads/animation.h index 8b85a5370d..46ef85c5eb 100644 --- a/engines/mads/animation.h +++ b/engines/mads/animation.h @@ -8,12 +8,12 @@ * 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. @@ -219,6 +219,11 @@ public: */ void update(); + /** + * Erases any sprites from the previous animation frame + */ + void eraseSprites(); + void setNextFrameTimer(int frameNumber); int getNextFrameTimer() const { return _nextFrameTimer; } void setCurrentFrame(int frameNumber); diff --git a/engines/mads/assets.cpp b/engines/mads/assets.cpp index a2d495f311..1d4634e383 100644 --- a/engines/mads/assets.cpp +++ b/engines/mads/assets.cpp @@ -8,12 +8,12 @@ * 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. diff --git a/engines/mads/assets.h b/engines/mads/assets.h index 155590f9bd..8a0dc2cd44 100644 --- a/engines/mads/assets.h +++ b/engines/mads/assets.h @@ -8,12 +8,12 @@ * 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. diff --git a/engines/mads/audio.cpp b/engines/mads/audio.cpp index 1c61e13957..8f33f22243 100644 --- a/engines/mads/audio.cpp +++ b/engines/mads/audio.cpp @@ -8,12 +8,12 @@ * 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. @@ -37,6 +37,7 @@ AudioPlayer::AudioPlayer(Audio::Mixer *mixer, uint32 gameID) : _mixer(mixer), _g AudioPlayer::~AudioPlayer() { _dsrEntries.clear(); + _filename = ""; } bool AudioPlayer::isPlaying() const { @@ -65,25 +66,27 @@ void AudioPlayer::setDefaultSoundGroup() { } void AudioPlayer::setSoundGroup(const Common::String &filename) { - _dsrEntries.clear(); - - _filename = filename; - _dsrFile.open(filename); - - // Read header - uint16 entryCount = _dsrFile.readUint16LE(); - - for (uint16 i = 0; i < entryCount; i++) { - DSREntry newEntry; - newEntry.frequency = _dsrFile.readUint16LE(); - newEntry.channels = _dsrFile.readUint32LE(); - newEntry.compSize = _dsrFile.readUint32LE(); - newEntry.uncompSize = _dsrFile.readUint32LE(); - newEntry.offset = _dsrFile.readUint32LE(); - _dsrEntries.push_back(newEntry); + if (_filename != filename) { + _dsrEntries.clear(); + + _filename = filename; + _dsrFile.open(filename); + + // Read header + uint16 entryCount = _dsrFile.readUint16LE(); + + for (uint16 i = 0; i < entryCount; i++) { + DSREntry newEntry; + newEntry.frequency = _dsrFile.readUint16LE(); + newEntry.channels = _dsrFile.readUint32LE(); + newEntry.compSize = _dsrFile.readUint32LE(); + newEntry.uncompSize = _dsrFile.readUint32LE(); + newEntry.offset = _dsrFile.readUint32LE(); + _dsrEntries.push_back(newEntry); + } + + _dsrFile.close(); } - - _dsrFile.close(); } void AudioPlayer::playSound(int soundIndex, bool loop) { @@ -126,4 +129,8 @@ void AudioPlayer::playSound(int soundIndex, bool loop) { */ } +void AudioPlayer::stop() { + _mixer->stopHandle(_handle); +} + } // End of namespace M4 diff --git a/engines/mads/audio.h b/engines/mads/audio.h index 21f4bed59a..5c3cd5e682 100644 --- a/engines/mads/audio.h +++ b/engines/mads/audio.h @@ -8,12 +8,12 @@ * 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. @@ -46,6 +46,7 @@ public: void setSoundGroup(const Common::String &filename); void setDefaultSoundGroup(); void playSound(int soundIndex, bool loop = false); + void stop(); void setVolume(int volume); bool isPlaying() const; diff --git a/engines/mads/compression.cpp b/engines/mads/compression.cpp index 79cd1786de..1f6f1ee202 100644 --- a/engines/mads/compression.cpp +++ b/engines/mads/compression.cpp @@ -8,12 +8,12 @@ * 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. diff --git a/engines/mads/compression.h b/engines/mads/compression.h index f7381e4af3..b560ed33c1 100644 --- a/engines/mads/compression.h +++ b/engines/mads/compression.h @@ -8,12 +8,12 @@ * 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. diff --git a/engines/mads/debugger.cpp b/engines/mads/debugger.cpp index 99251f9fbb..a6a4d3edbc 100644 --- a/engines/mads/debugger.cpp +++ b/engines/mads/debugger.cpp @@ -8,12 +8,12 @@ * 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 + * 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. diff --git a/engines/mads/debugger.h b/engines/mads/debugger.h index c8fee5f5b2..70b2cadc65 100644 --- a/engines/mads/debugger.h +++ b/engines/mads/debugger.h @@ -8,12 +8,12 @@ * 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 + * 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. diff --git a/engines/mads/detection.cpp b/engines/mads/detection.cpp index 971acde024..57f4776e82 100644 --- a/engines/mads/detection.cpp +++ b/engines/mads/detection.cpp @@ -8,12 +8,12 @@ * 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. @@ -29,6 +29,7 @@ #include "common/memstream.h" #include "engines/advancedDetector.h" #include "common/system.h" +#include "common/translation.h" #include "graphics/colormasks.h" #include "graphics/surface.h" #include "mads/events.h" @@ -75,11 +76,71 @@ static const PlainGameDescriptor MADSGames[] = { {0, 0} }; +#define GAMEOPTION_EASY_MOUSE GUIO_GAMEOPTIONS1 +#define GAMEOPTION_ANIMATED_INVENTORY GUIO_GAMEOPTIONS2 +#define GAMEOPTION_ANIMATED_INTERFACE GUIO_GAMEOPTIONS3 +#define GAMEOPTION_NAUGHTY_MODE GUIO_GAMEOPTIONS4 +//#define GAMEOPTION_GRAPHICS_DITHERING GUIO_GAMEOPTIONS5 + #include "mads/detection_tables.h" +static const ADExtraGuiOptionsMap optionsList[] = { + { + GAMEOPTION_EASY_MOUSE, + { + _s("Easy mouse interface"), + _s("Shows object names when hovering the mouse over them"), + "EasyMouse", + true + } + }, + + { + GAMEOPTION_ANIMATED_INVENTORY, + { + _s("Animated inventory items"), + _s("Animated inventory items"), + "InvObjectsAnimated", + true + } + }, + + { + GAMEOPTION_ANIMATED_INTERFACE, + { + _s("Animated game interface"), + _s("Animated game interface"), + "TextWindowAnimated", + true + } + }, + + { + GAMEOPTION_NAUGHTY_MODE, + { + _s("Naughty game mode"), + _s("Naughty game mode"), + "NaughtyMode", + true + } + }, + + /*{ + GAMEOPTION_GRAPHICS_DITHERING, + { + _s("Graphics dithering"), + _s("Graphics dithering"), + "GraphicsDithering", + true + } + },*/ + + AD_EXTRA_GUI_OPTIONS_TERMINATOR +}; + class MADSMetaEngine : public AdvancedMetaEngine { public: - MADSMetaEngine() : AdvancedMetaEngine(MADS::gameDescriptions, sizeof(MADS::MADSGameDescription), MADSGames) { + MADSMetaEngine() : AdvancedMetaEngine(MADS::gameDescriptions, sizeof(MADS::MADSGameDescription), MADSGames, optionsList) { _maxScanDepth = 3; } diff --git a/engines/mads/detection_tables.h b/engines/mads/detection_tables.h index e68ae380d0..56df09577c 100644 --- a/engines/mads/detection_tables.h +++ b/engines/mads/detection_tables.h @@ -8,12 +8,12 @@ * 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. @@ -37,7 +37,7 @@ static const MADSGameDescription gameDescriptions[] = { Common::EN_ANY, Common::kPlatformDOS, ADGF_NO_FLAGS, - GUIO1(GUIO_NONE) + GUIO5(GUIO_NOSPEECH, GAMEOPTION_EASY_MOUSE, GAMEOPTION_ANIMATED_INVENTORY, GAMEOPTION_ANIMATED_INTERFACE, GAMEOPTION_NAUGHTY_MODE) }, GType_RexNebular, 0 @@ -55,8 +55,8 @@ static const MADSGameDescription gameDescriptions[] = { }, Common::EN_ANY, Common::kPlatformDOS, - ADGF_NO_FLAGS, - GUIO1(GUIO_NONE) + ADGF_TESTING, + GUIO5(GUIO_NOSPEECH, GAMEOPTION_EASY_MOUSE, GAMEOPTION_ANIMATED_INVENTORY, GAMEOPTION_ANIMATED_INTERFACE, GAMEOPTION_NAUGHTY_MODE) }, GType_RexNebular, 0 @@ -73,8 +73,8 @@ static const MADSGameDescription gameDescriptions[] = { }, Common::EN_ANY, Common::kPlatformDOS, - ADGF_NO_FLAGS, - GUIO1(GUIO_NONE) + ADGF_TESTING, + GUIO5(GUIO_NOSPEECH, GAMEOPTION_EASY_MOUSE, GAMEOPTION_ANIMATED_INVENTORY, GAMEOPTION_ANIMATED_INTERFACE, GAMEOPTION_NAUGHTY_MODE) }, GType_RexNebular, 0 @@ -92,7 +92,7 @@ static const MADSGameDescription gameDescriptions[] = { Common::EN_ANY, Common::kPlatformDOS, ADGF_NO_FLAGS, - GUIO1(GUIO_NONE) + GUIO1(GAMEOPTION_EASY_MOUSE) }, GType_Phantom, 0 @@ -110,7 +110,7 @@ static const MADSGameDescription gameDescriptions[] = { Common::EN_ANY, Common::kPlatformDOS, ADGF_NO_FLAGS, - GUIO1(GUIO_NONE) + GUIO1(GAMEOPTION_EASY_MOUSE) }, GType_Dragonsphere, 0 diff --git a/engines/mads/dialogs.cpp b/engines/mads/dialogs.cpp index 5ea8fb115c..d9b27ce926 100644 --- a/engines/mads/dialogs.cpp +++ b/engines/mads/dialogs.cpp @@ -8,12 +8,12 @@ * 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. @@ -43,6 +43,7 @@ Dialog::Dialog(MADSEngine *vm) } Dialog::~Dialog() { + delete _savedSurface; } void Dialog::save() { @@ -430,6 +431,7 @@ void FullScreenDialog::display() { if (_screenId > 0) { SceneInfo *sceneInfo = SceneInfo::init(_vm); sceneInfo->load(_screenId, 0, "", 0, scene._depthSurface, scene._backgroundSurface); + delete sceneInfo; } scene._priorSceneId = priorSceneId; @@ -449,7 +451,7 @@ void FullScreenDialog::display() { } // Set Fx state and palette entries - game._fx = _vm->_screenFade == SCREEN_FADE_SMOOTH ? kTransitionFadeIn : kCenterVertTransition; + game._fx = _vm->_screenFade == SCREEN_FADE_SMOOTH ? kTransitionFadeIn : kNullPaletteCopy; game._trigger = 0; // Clear the screen and draw the upper and lower horizontal lines @@ -457,6 +459,7 @@ void FullScreenDialog::display() { _vm->_palette->setLowRange(); _vm->_screen.hLine(0, 20, MADS_SCREEN_WIDTH, 2); _vm->_screen.hLine(0, 179, MADS_SCREEN_WIDTH, 2); + _vm->_screen.resetClipBounds(); _vm->_screen.copyRectToScreen(Common::Rect(0, 0, MADS_SCREEN_WIDTH, MADS_SCREEN_HEIGHT)); // Restrict the screen to the area between the two lines diff --git a/engines/mads/dialogs.h b/engines/mads/dialogs.h index 317c7bd792..efd2871d89 100644 --- a/engines/mads/dialogs.h +++ b/engines/mads/dialogs.h @@ -8,12 +8,12 @@ * 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. diff --git a/engines/mads/dragonsphere/dragonsphere_scenes.cpp b/engines/mads/dragonsphere/dragonsphere_scenes.cpp index dbf1759d4b..6f5a28bff9 100644 --- a/engines/mads/dragonsphere/dragonsphere_scenes.cpp +++ b/engines/mads/dragonsphere/dragonsphere_scenes.cpp @@ -8,12 +8,12 @@ * 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. diff --git a/engines/mads/dragonsphere/dragonsphere_scenes.h b/engines/mads/dragonsphere/dragonsphere_scenes.h index a6c778eca7..173cc667ce 100644 --- a/engines/mads/dragonsphere/dragonsphere_scenes.h +++ b/engines/mads/dragonsphere/dragonsphere_scenes.h @@ -8,12 +8,12 @@ * 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. diff --git a/engines/mads/dragonsphere/game_dragonsphere.cpp b/engines/mads/dragonsphere/game_dragonsphere.cpp index 3836adb6d2..b07eab9daa 100644 --- a/engines/mads/dragonsphere/game_dragonsphere.cpp +++ b/engines/mads/dragonsphere/game_dragonsphere.cpp @@ -8,12 +8,12 @@ * 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. diff --git a/engines/mads/dragonsphere/game_dragonsphere.h b/engines/mads/dragonsphere/game_dragonsphere.h index 7869dc87b4..b57f8833c6 100644 --- a/engines/mads/dragonsphere/game_dragonsphere.h +++ b/engines/mads/dragonsphere/game_dragonsphere.h @@ -8,12 +8,12 @@ * 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. diff --git a/engines/mads/events.cpp b/engines/mads/events.cpp index de4dc3c070..7ba9098935 100644 --- a/engines/mads/events.cpp +++ b/engines/mads/events.cpp @@ -8,12 +8,12 @@ * 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. @@ -41,10 +41,9 @@ EventsManager::EventsManager(MADSEngine *vm) { _mouseReleased = false; _mouseButtons = 0; _mouseStatus = 0; - _vD2 = 0; + _strokeGoing = 0; _mouseStatusCopy = 0; _mouseMoved = false; - _vD8 = 0; _rightMousePressed = false; _eventTarget = nullptr; } @@ -85,8 +84,8 @@ void EventsManager::waitCursor() { CursorType cursorId = (CursorType)MIN(_cursorSprites->getCount(), (int)CURSOR_WAIT); _newCursorId = cursorId; if (_cursorId != _newCursorId) { - changeCursor(); _cursorId = _newCursorId; + changeCursor(); } } @@ -158,11 +157,17 @@ void EventsManager::pollEvents() { _vm->_debugger->attach(); _vm->_debugger->onFrame(); } else { - _pendingKeys.push(event); + _pendingKeys.push(event.kbd); } return; case Common::EVENT_KEYUP: return; + case Common::EVENT_WHEELUP: + _pendingKeys.push(Common::KeyState(Common::KEYCODE_PAGEUP)); + return; + case Common::EVENT_WHEELDOWN: + _pendingKeys.push(Common::KeyState(Common::KEYCODE_PAGEDOWN)); + return; case Common::EVENT_LBUTTONDOWN: case Common::EVENT_RBUTTONDOWN: _mouseClicked = true; @@ -261,7 +266,7 @@ void EventsManager::waitForNextFrame() { void EventsManager::initVars() { _mousePos = Common::Point(-1, -1); _mouseStatusCopy = _mouseStatus; - _vD2 = _vD8 = 0; + _strokeGoing = 0; } } // End of namespace MADS diff --git a/engines/mads/events.h b/engines/mads/events.h index 54df337efd..1a2579cae0 100644 --- a/engines/mads/events.h +++ b/engines/mads/events.h @@ -8,12 +8,12 @@ * 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. @@ -67,11 +67,10 @@ public: byte _mouseButtons; bool _rightMousePressed; int _mouseStatus; - int _vD2; + int _strokeGoing; int _mouseStatusCopy; bool _mouseMoved; - int _vD8; - Common::Stack<Common::Event> _pendingKeys; + Common::Stack<Common::KeyState> _pendingKeys; public: /** * Constructor @@ -169,6 +168,8 @@ public: * Returns true if there's any pending keys to be processed */ bool isKeyPressed() const { return !_pendingKeys.empty(); } + + Common::KeyState getKey() { return _pendingKeys.pop(); } }; } // End of namespace MADS diff --git a/engines/mads/font.cpp b/engines/mads/font.cpp index f7c1c52703..3e6d23fe6f 100644 --- a/engines/mads/font.cpp +++ b/engines/mads/font.cpp @@ -8,12 +8,12 @@ * 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. diff --git a/engines/mads/font.h b/engines/mads/font.h index 47df647637..486cadcfff 100644 --- a/engines/mads/font.h +++ b/engines/mads/font.h @@ -8,12 +8,12 @@ * 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. diff --git a/engines/mads/game.cpp b/engines/mads/game.cpp index b544eff2db..91f6cd5630 100644 --- a/engines/mads/game.cpp +++ b/engines/mads/game.cpp @@ -8,12 +8,12 @@ * 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. @@ -100,13 +100,12 @@ Game::~Game() { } delete _saveFile; + _surface->free(); delete _surface; delete _sectionHandler; } void Game::run() { - initializeGlobals(); - // If requested, load a savegame instead of showing the intro if (ConfMan.hasKey("save_slot")) { int saveSlot = ConfMan.getInt("save_slot"); @@ -116,15 +115,17 @@ void Game::run() { _statusFlag = true; - if (_loadGameSlot == -1) { - startGame(); - } + while (!_vm->shouldQuit()) { + if (_loadGameSlot == -1) { + startGame(); + } - // Get the initial starting time for the first scene - _scene._frameStartTime = _vm->_events->getFrameCounter(); + // Get the initial starting time for the first scene + _scene._frameStartTime = _vm->_events->getFrameCounter(); - if (!_vm->shouldQuit()) - gameLoop(); + if (!_vm->shouldQuit()) + gameLoop(); + } } void Game::splitQuote(const Common::String &source, Common::String &line1, Common::String &line2) { @@ -140,7 +141,7 @@ void Game::splitQuote(const Common::String &source, Common::String &line1, Commo } void Game::gameLoop() { - while (!_vm->shouldQuit() && _statusFlag) { + while (!_vm->shouldQuit() && _statusFlag && !_winStatus) { if (_loadGameSlot != -1) { loadGame(_loadGameSlot); _loadGameSlot = -1; @@ -158,7 +159,7 @@ void Game::gameLoop() { sectionLoop(); _player.releasePlayerSprites(); - assert(_scene._sprites._assetCount == 0); + assert(_scene._sprites.size() == 0); _vm->_palette->unlock(); _vm->_events->waitCursor(); @@ -168,7 +169,8 @@ void Game::gameLoop() { } void Game::sectionLoop() { - while (!_vm->shouldQuit() && _statusFlag && (_sectionNumber == _currentSectionNumber)) { + while (!_vm->shouldQuit() && _statusFlag && !_winStatus && + (_sectionNumber == _currentSectionNumber)) { _kernelMode = KERNEL_ROOM_PRELOAD; _player._spritesChanged = true; _quoteEmergency = false; @@ -240,7 +242,7 @@ void Game::sectionLoop() { _fx = kTransitionFadeOutIn; break; case SCREEN_FADE_FAST: - _fx = kCenterVertTransition; + _fx = kNullPaletteCopy; break; default: _fx = kTransitionNone; @@ -324,7 +326,7 @@ void Game::initSection(int sectionNumber) { _vm->_palette->resetGamePalette(18, 10); _vm->_palette->setLowRange(); - if (_scene._layer == LAYER_GUI) + if (_scene._mode == SCREENMODE_VGA) _vm->_palette->setPalette(_vm->_palette->_mainPalette, 0, 4); _vm->_events->loadCursors("*CURSOR.SS"); @@ -403,12 +405,12 @@ Common::StringArray Game::getMessage(uint32 id) { static const char *const DEBUG_STRING = "WIDEPIPE"; -void Game::handleKeypress(const Common::Event &event) { - if (event.kbd.flags & Common::KBD_CTRL) { +void Game::handleKeypress(const Common::KeyState &kbd) { + if (kbd.flags & Common::KBD_CTRL) { if (_widepipeCtr == 8) { // Implement original game cheating keys here someday } else { - if (event.kbd.keycode == (Common::KEYCODE_a + + if (kbd.keycode == (Common::KEYCODE_a + (DEBUG_STRING[_widepipeCtr] - 'a'))) { if (++_widepipeCtr == 8) { MessageDialog *dlg = new MessageDialog(_vm, 2, @@ -420,7 +422,8 @@ void Game::handleKeypress(const Common::Event &event) { } } - switch (event.kbd.keycode) { + Scene &scene = _vm->_game->_scene; + switch (kbd.keycode) { case Common::KEYCODE_F1: _vm->_dialogs->_pendingDialog = DIALOG_GAME_MENU; break; @@ -430,11 +433,19 @@ void Game::handleKeypress(const Common::Event &event) { case Common::KEYCODE_F7: _vm->_dialogs->_pendingDialog = DIALOG_RESTORE; break; + case Common::KEYCODE_PAGEUP: + scene._userInterface._scrollbarStrokeType = SCROLLBAR_UP; + scene._userInterface.changeScrollBar(); + break; + case Common::KEYCODE_PAGEDOWN: + scene._userInterface._scrollbarStrokeType = SCROLLBAR_DOWN; + scene._userInterface.changeScrollBar(); + break; + + default: break; } - - warning("TODO: handleKeypress - %d", (int)event.kbd.keycode); } void Game::synchronize(Common::Serializer &s, bool phase1) { @@ -558,7 +569,7 @@ void Game::writeSavegameHeader(Common::OutSaveFile *out, MADSSavegameHeader &hea if (!_saveThumb) createThumbnail(); Graphics::saveThumbnail(*out, *_saveThumb); - + _saveThumb->free(); delete _saveThumb; _saveThumb = nullptr; diff --git a/engines/mads/game.h b/engines/mads/game.h index 1a61fc8ac8..95b54b0d1a 100644 --- a/engines/mads/game.h +++ b/engines/mads/game.h @@ -8,12 +8,12 @@ * 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. @@ -195,6 +195,9 @@ public: */ virtual void synchronize(Common::Serializer &s, bool phase1); + virtual void setNaughtyMode(bool naughtyMode) {} + virtual bool getNaughtyMode() const { return true; } + // DEPRECATED: ScummVM re-implementation keeps all the quotes loaded, so the methods below are stubs void clearQuotes() {} void loadQuoteRange(int startNum, int endNum) {} @@ -204,7 +207,7 @@ public: /** * Handle a keyboard event */ - void handleKeypress(const Common::Event &event); + void handleKeypress(const Common::KeyState &kbd); /** * Starts a savegame loading. diff --git a/engines/mads/game_data.cpp b/engines/mads/game_data.cpp index 70e9e6c30b..6421d057e8 100644 --- a/engines/mads/game_data.cpp +++ b/engines/mads/game_data.cpp @@ -8,12 +8,12 @@ * 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. diff --git a/engines/mads/game_data.h b/engines/mads/game_data.h index 65a9ae1553..e9bf45d8a5 100644 --- a/engines/mads/game_data.h +++ b/engines/mads/game_data.h @@ -8,12 +8,12 @@ * 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. diff --git a/engines/mads/globals.cpp b/engines/mads/globals.cpp index 1d088992ea..e4a681d551 100644 --- a/engines/mads/globals.cpp +++ b/engines/mads/globals.cpp @@ -8,12 +8,12 @@ * 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. diff --git a/engines/mads/globals.h b/engines/mads/globals.h index a6c9b628dd..27553a2b06 100644 --- a/engines/mads/globals.h +++ b/engines/mads/globals.h @@ -8,12 +8,12 @@ * 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. diff --git a/engines/mads/hotspots.cpp b/engines/mads/hotspots.cpp index d75d7ae13e..bd28645504 100644 --- a/engines/mads/hotspots.cpp +++ b/engines/mads/hotspots.cpp @@ -8,12 +8,12 @@ * 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 + * 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. @@ -137,7 +137,7 @@ void DynamicHotspots::refresh() { switch (scrObjects._inputMode) { case kInputBuildingSentences: case kInputLimitedSentences: - scrObjects.add(dh._bounds, _vm->_game->_scene._layer, CAT_12, dh._descId); + scrObjects.add(dh._bounds, _vm->_game->_scene._mode, CAT_12, dh._descId); scrObjects._forceRescan = true; break; default: diff --git a/engines/mads/hotspots.h b/engines/mads/hotspots.h index f9334eace8..902275bb21 100644 --- a/engines/mads/hotspots.h +++ b/engines/mads/hotspots.h @@ -8,12 +8,12 @@ * 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 + * 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. diff --git a/engines/mads/inventory.cpp b/engines/mads/inventory.cpp index ca05575ec5..fe1d24baea 100644 --- a/engines/mads/inventory.cpp +++ b/engines/mads/inventory.cpp @@ -8,12 +8,12 @@ * 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. diff --git a/engines/mads/inventory.h b/engines/mads/inventory.h index cf82de59f1..2897f950e4 100644 --- a/engines/mads/inventory.h +++ b/engines/mads/inventory.h @@ -8,12 +8,12 @@ * 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. diff --git a/engines/mads/mads.cpp b/engines/mads/mads.cpp index 52a0b40561..8c7b6b1ce3 100644 --- a/engines/mads/mads.cpp +++ b/engines/mads/mads.cpp @@ -8,12 +8,12 @@ * 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. @@ -38,12 +38,13 @@ namespace MADS { MADSEngine::MADSEngine(OSystem *syst, const MADSGameDescription *gameDesc) : _gameDescription(gameDesc), Engine(syst), _randomSource("MADS") { - // Initialize fields + // Initialize game/engine options _easyMouse = true; _invObjectsAnimated = true; _textWindowStill = false; _screenFade = SCREEN_FADE_SMOOTH; _musicFlag = true; + _soundFlag = true; _dithering = false; _debugger = nullptr; @@ -95,9 +96,63 @@ void MADSEngine::initialize() { _audio = new AudioPlayer(_mixer, getGameID()); _game = Game::init(this); + loadOptions(); + _screen.empty(); } +void MADSEngine::loadOptions() { + if (ConfMan.hasKey("EasyMouse")) + _easyMouse = ConfMan.getBool("EasyMouse"); + + if (ConfMan.hasKey("mute") && ConfMan.getBool("mute")) { + _soundFlag = false; + _musicFlag = false; + } else { + _soundFlag = !ConfMan.hasKey("sfx_mute") || !ConfMan.getBool("sfx_mute"); + _musicFlag = !ConfMan.hasGameDomain("music_mute") || !ConfMan.getBool("music_mute"); + } + + if (ConfMan.hasKey("ScreenFade")) + _screenFade = (ScreenFade)ConfMan.getInt("ScreenFade"); + //if (ConfMan.hasKey("GraphicsDithering")) + // _dithering = ConfMan.getBool("GraphicsDithering"); + + if (getGameID() == GType_RexNebular) { + if (ConfMan.hasKey("InvObjectsAnimated")) + _invObjectsAnimated = ConfMan.getBool("InvObjectsAnimated"); + if (ConfMan.hasKey("TextWindowStill")) + _textWindowStill = !ConfMan.getBool("TextWindowAnimated"); + if (ConfMan.hasKey("NaughtyMode")) + _game->setNaughtyMode(ConfMan.getBool("NaughtyMode")); + } + + // Note: MADS is weird in that sfx and music are handled by the same driver, + // and the game scripts themselves check for music being enabled before playing + // a "music" sound. Which means we can independantly mute music in ScummVM, but + // otherwise all sound, music and sfx, is controlled by the SFX volume slider. + int soundVolume = MIN(255, ConfMan.getInt("sfx_volume")); + _sound->setVolume(soundVolume); +} + +void MADSEngine::saveOptions() { + ConfMan.setBool("EasyMouse", _easyMouse); + ConfMan.setInt("ScreenFade", (int)_screenFade); + //ConfMan.setBool("GraphicsDithering", _dithering); + + ConfMan.setBool("mute", !_soundFlag && !_musicFlag); + ConfMan.setBool("sfx_mute", !_soundFlag && _musicFlag); + ConfMan.setBool("music_mute", _soundFlag && !_musicFlag); + + if (getGameID() == GType_RexNebular) { + ConfMan.setBool("InvObjectsAnimated", _invObjectsAnimated); + ConfMan.setBool("TextWindowAnimated", !_textWindowStill); + ConfMan.setBool("NaughtyMode", _game->getNaughtyMode()); + } + + ConfMan.flushToDisk(); +} + Common::Error MADSEngine::run() { initGraphics(MADS_SCREEN_WIDTH, MADS_SCREEN_HEIGHT, false); initialize(); @@ -134,6 +189,12 @@ bool MADSEngine::canSaveGameStateCurrently() { && _events->_cursorId != CURSOR_WAIT; } +void MADSEngine::syncSoundSettings() { + Engine::syncSoundSettings(); + + loadOptions(); +} + /** * Support method that generates a savegame name * @param slot Slot number diff --git a/engines/mads/mads.h b/engines/mads/mads.h index 9a8f2152a1..901035320a 100644 --- a/engines/mads/mads.h +++ b/engines/mads/mads.h @@ -8,12 +8,12 @@ * 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. @@ -84,6 +84,8 @@ private: * Handles basic initialisation */ void initialize(); + + void loadOptions(); protected: // Engine APIs virtual Common::Error run(); @@ -104,6 +106,7 @@ public: bool _textWindowStill; ScreenFade _screenFade; bool _musicFlag; + bool _soundFlag; bool _dithering; public: MADSEngine(OSystem *syst, const MADSGameDescription *gameDesc); @@ -145,6 +148,13 @@ public: * Handles saving the game via the GMM */ virtual Common::Error saveGameState(int slot, const Common::String &desc); + + /** + * Handles updating sound settings after they're changed in the GMM dialog + */ + virtual void syncSoundSettings(); + + void saveOptions(); }; } // End of namespace MADS diff --git a/engines/mads/menu_views.cpp b/engines/mads/menu_views.cpp index 6acf6cdf9f..10d5a2179a 100644 --- a/engines/mads/menu_views.cpp +++ b/engines/mads/menu_views.cpp @@ -1,24 +1,24 @@ /* 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. - * - */ +* +* 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. +* +*/ #include "common/scummsys.h" #include "mads/game.h" @@ -37,7 +37,7 @@ MenuView::MenuView(MADSEngine *vm) : FullScreenDialog(vm) { } void MenuView::show() { - Scene &scene = _vm->_game->_scene; + Scene &scene = _vm->_game->_scene; EventsManager &events = *_vm->_events; _vm->_screenFade = SCREEN_FADE_FAST; @@ -80,6 +80,15 @@ bool MenuView::onEvent(Common::Event &event) { return false; } +Common::String MenuView::getResourceName() { + Common::String s(_filename); + s.toLowercase(); + while (s.contains('.')) + s.deleteLastChar(); + + return s; +} + /*------------------------------------------------------------------------*/ char TextView::_resourceName[100]; @@ -112,12 +121,17 @@ TextView::TextView(MADSEngine *vm) : MenuView(vm) { } TextView::~TextView() { + // Turn off palette cycling as well as any playing sound + Scene &scene = _vm->_game->_scene; + scene._cyclingActive = false; + _vm->_sound->stop(); } void TextView::load() { Common::String scriptName(_resourceName); scriptName += ".txr"; + _filename = scriptName; if (!_script.open(scriptName)) error("Could not open resource %s", _resourceName); @@ -181,7 +195,7 @@ void TextView::processCommand() { paramP = commandStr + 10; resetPalette(); int screenId = getParameter(¶mP); - + SceneInfo *sceneInfo = SceneInfo::init(_vm); sceneInfo->load(screenId, 0, "", 0, scene._depthSurface, scene._backgroundSurface); scene._spriteSlots.fullRefresh(); @@ -216,7 +230,7 @@ void TextView::processCommand() { int soundId = getParameter(¶mP); _vm->_sound->command(soundId); - } else if (!strncmp(commandStr, "COLOR", 5) && ((commandStr[5] == '0') || + } else if (!strncmp(commandStr, "COLOR", 5) && ((commandStr[5] == '0') || (commandStr[5] == '1'))) { // Set the text colors int index = commandStr[5] - '0'; @@ -240,7 +254,8 @@ void TextView::processCommand() { sceneInfo->_width = MADS_SCREEN_WIDTH; sceneInfo->_height = MADS_SCENE_HEIGHT; _spareScreens[spareIndex].setSize(MADS_SCREEN_WIDTH, MADS_SCENE_HEIGHT); - sceneInfo->loadMadsV1Background(screenId, "", SCENEFLAG_TRANSLATE, + + sceneInfo->loadMadsV1Background(screenId, "", SCENEFLAG_TRANSLATE, _spareScreens[spareIndex]); delete sceneInfo; @@ -395,7 +410,7 @@ void TextView::doFrame() { Common::copy(srcP, srcP + MADS_SCREEN_WIDTH, destP); } - Common::copy(linesTemp, linesTemp + _pan.y * MADS_SCREEN_WIDTH, + Common::copy(linesTemp, linesTemp + _pan.y * MADS_SCREEN_WIDTH, (byte *)scene._backgroundSurface.getPixels()); delete[] linesTemp; } @@ -412,10 +427,10 @@ void TextView::doFrame() { scene._textDisplay.expire(tl._textDisplayIndex); tl._pos.y--; - if (tl._pos.y < 0) { + if (tl._pos.y + _font->getHeight() < 0) { _textLines.remove_at(i); } else { - tl._textDisplayIndex = scene._textDisplay.add(tl._pos.x, tl._pos.y, + tl._textDisplayIndex = scene._textDisplay.add(tl._pos.x, tl._pos.y, 0x605, -1, tl._line, _font); } } @@ -470,11 +485,19 @@ AnimationView::AnimationView(MADSEngine *vm) : MenuView(vm) { _animFrameNumber = 0; _nextCyclingActive = false; _sceneInfo = SceneInfo::init(_vm); + _scrollFrameCtr = 0; load(); } AnimationView::~AnimationView() { + // Turn off palette cycling as well as any playing sound + Scene &scene = _vm->_game->_scene; + scene._cyclingActive = false; + _vm->_sound->stop(); + _vm->_audio->stop(); + + // Delete data delete _currentAnimation; delete _sceneInfo; } @@ -484,6 +507,7 @@ void AnimationView::load() { if (!resName.hasSuffix(".")) resName += ".res"; + _filename = resName; if (!_script.open(resName)) error("Could not open resource %s", resName.c_str()); @@ -505,7 +529,7 @@ void AnimationView::display() { bool AnimationView::onEvent(Common::Event &event) { // Wait for the Escape key or a mouse press if (((event.type == Common::EVENT_KEYDOWN) && (event.kbd.keycode == Common::KEYCODE_ESCAPE)) || - (event.type == Common::EVENT_RBUTTONUP)) { + (event.type == Common::EVENT_LBUTTONUP)) { scriptDone(); return true; } @@ -515,22 +539,32 @@ bool AnimationView::onEvent(Common::Event &event) { void AnimationView::doFrame() { Scene &scene = _vm->_game->_scene; - + if (_resourceIndex == -1 || _currentAnimation->freeFlag()) { if (++_resourceIndex == (int)_resources.size()) { scriptDone(); } else { scene._frameStartTime = 0; + scene._spriteSlots.clear(); loadNextResource(); } } else if (_currentAnimation->getCurrentFrame() == 1) { scene._cyclingActive = _nextCyclingActive; } + if (_currentAnimation && (++_scrollFrameCtr >= _currentAnimation->_header._scrollTicks)) { + _scrollFrameCtr = 0; + scroll(); + } + if (_currentAnimation) { ++scene._frameStartTime; _currentAnimation->update(); _redrawFlag = true; + + if (_currentAnimation->freeFlag()) + // We don't want the sprites removed after the last animation frame + scene._spriteSlots.clear(); } } @@ -543,7 +577,7 @@ void AnimationView::loadNextResource() { if (resEntry._bgFlag) palette.resetGamePalette(1, 8); - palette._mainPalette[253 * 3] = palette._mainPalette[253 * 3 + 1] + palette._mainPalette[253 * 3] = palette._mainPalette[253 * 3 + 1] = palette._mainPalette[253 * 3 + 2] = 0xb4; palette.setPalette(&palette._mainPalette[253 * 3], 253, 1); @@ -565,7 +599,7 @@ void AnimationView::loadNextResource() { delete _currentAnimation; _currentAnimation = Animation::init(_vm, &scene); int flags = ANIMFLAG_ANIMVIEW | (resEntry._bgFlag ? ANIMFLAG_LOAD_BACKGROUND : 0); - _currentAnimation->load(scene._backgroundSurface, scene._depthSurface, + _currentAnimation->load(scene._backgroundSurface, scene._depthSurface, resEntry._resourceName, flags, &paletteCycles, _sceneInfo); // Signal for a screen refresh @@ -614,6 +648,21 @@ void AnimationView::loadNextResource() { scene.initPaletteAnimation(paletteCycles, _nextCyclingActive && !_vm->_game->_fx); } +void AnimationView::scroll() { + Scene &scene = _vm->_game->_scene; + Common::Point pt = _currentAnimation->_header._scrollPosition; + + if (pt.x != 0) { + scene._backgroundSurface.scrollX(pt.x); + scene._spriteSlots.fullRefresh(); + } + + if (pt.y != 0) { + scene._backgroundSurface.scrollY(pt.y); + scene._spriteSlots.fullRefresh(); + } +} + void AnimationView::scriptDone() { _breakFlag = true; _vm->_dialogs->_pendingDialog = DIALOG_MAIN_MENU; @@ -634,7 +683,11 @@ void AnimationView::processLines() { if (c != '\r' && c != '\0') _currentLine += c; } - + + // Check for comment line + if (_currentLine.hasPrefix("#")) + continue; + // Process the line while (!_currentLine.empty()) { if (_currentLine.hasPrefix("-")) { @@ -650,7 +703,7 @@ void AnimationView::processLines() { } // Add resource into list along with any set state information - _resources.push_back(ResourceEntry(resName, _sfx, _soundFlag, + _resources.push_back(ResourceEntry(resName, _sfx, _soundFlag, _bgLoadFlag, _showWhiteBars)); // Fx resets between resource entries @@ -731,7 +784,7 @@ int AnimationView::getParameter() { while (!_currentLine.empty()) { char c = _currentLine[0]; - + if (c >= '0' && c <= '9') { _currentLine.deleteChar(0); result = result * 10 + (c - '0'); diff --git a/engines/mads/menu_views.h b/engines/mads/menu_views.h index 6faa665bff..c203248ad9 100644 --- a/engines/mads/menu_views.h +++ b/engines/mads/menu_views.h @@ -8,12 +8,20 @@ * 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. +<<<<<<< HEAD +======= + * +>>>>>>> master * 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. +<<<<<<< HEAD +======= + * +>>>>>>> master * 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. @@ -36,6 +44,7 @@ class MenuView: public FullScreenDialog { protected: bool _breakFlag; bool _redrawFlag; + Common::String _filename; virtual void doFrame() = 0; @@ -51,6 +60,8 @@ public: virtual ~MenuView() {} virtual void show(); + + Common::String getResourceName(); }; struct TextLine { @@ -107,11 +118,6 @@ private: int getParameter(const char **paramP); /** - * Called when the script is finished - */ - void scriptDone(); - - /** * Reset the game palette */ void resetPalette(); @@ -119,6 +125,11 @@ protected: virtual void display(); virtual void doFrame(); + + /** + * Called when the script is finished + */ + virtual void scriptDone(); public: /** * Queue the given text resource for display @@ -193,6 +204,8 @@ private: int scanResourceIndex(const Common::String &resourceName); + uint _scrollFrameCtr; +private: void load(); void processLines(); @@ -201,15 +214,17 @@ private: int getParameter(); - void scriptDone(); - void loadNextResource(); + + void scroll(); protected: virtual void display(); virtual void doFrame(); virtual bool onEvent(Common::Event &event); + + virtual void scriptDone(); public: /** * Queue the given text resource for display diff --git a/engines/mads/messages.cpp b/engines/mads/messages.cpp index e83b69d210..d88806150d 100644 --- a/engines/mads/messages.cpp +++ b/engines/mads/messages.cpp @@ -8,12 +8,12 @@ * 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. @@ -69,7 +69,7 @@ void KernelMessages::clear() { } int KernelMessages::add(const Common::Point &pt, uint fontColor, uint8 flags, - uint8 abortTimers, uint32 timeout, const Common::String &msg) { + int endTrigger, uint32 timeout, const Common::String &msg) { Scene &scene = _vm->_game->_scene; // Find a free slot @@ -77,7 +77,7 @@ int KernelMessages::add(const Common::Point &pt, uint fontColor, uint8 flags, while ((idx < _entries.size()) && ((_entries[idx]._flags & KMSG_ACTIVE) != 0)) ++idx; if (idx == _entries.size()) { - if (abortTimers == 0) + if (endTrigger == 0) return -1; error("KernelMessages overflow"); @@ -91,8 +91,8 @@ int KernelMessages::add(const Common::Point &pt, uint fontColor, uint8 flags, rec._position = pt; rec._textDisplayIndex = -1; rec._timeout = timeout; - rec._frameTimer = _vm->_game->_priorFrameTimer; - rec._trigger = abortTimers; + rec._frameTimer = scene._frameStartTime; + rec._trigger = endTrigger; rec._abortMode = _vm->_game->_triggerSetupMode; rec._actionDetails = scene._action._activeAction; @@ -104,10 +104,10 @@ int KernelMessages::add(const Common::Point &pt, uint fontColor, uint8 flags, return idx; } -int KernelMessages::addQuote(int quoteId, int abortTimers, uint32 timeout) { +int KernelMessages::addQuote(int quoteId, int endTrigger, uint32 timeout) { Common::String quoteStr = _vm->_game->getQuote(quoteId); return add(Common::Point(), 0x1110, KMSG_PLAYER_TIMEOUT | KMSG_CENTER_ALIGN, - abortTimers, timeout, quoteStr); + endTrigger, timeout, quoteStr); } void KernelMessages::scrollMessage(int msgIndex, int numTicks, bool quoted) { @@ -162,8 +162,10 @@ void KernelMessages::update() { uint32 currentTimer = _vm->_game->_scene._frameStartTime; for (uint i = 0; i < _entries.size() && !_vm->_game->_trigger; ++i) { - KernelMessage &msg = _entries[i]; + if (_vm->_game->_trigger) + break; + KernelMessage &msg = _entries[i]; if (((msg._flags & KMSG_ACTIVE) != 0) && (currentTimer >= msg._frameTimer)) processText(i); } @@ -172,7 +174,7 @@ void KernelMessages::update() { void KernelMessages::processText(int msgIndex) { Scene &scene = _vm->_game->_scene; KernelMessage &msg = _entries[msgIndex]; - uint32 currentTimer = _vm->_game->_priorFrameTimer; + uint32 currentTimer = scene._frameStartTime; bool flag = false; if ((msg._flags & KMSG_EXPIRE) != 0) { diff --git a/engines/mads/messages.h b/engines/mads/messages.h index a7411d98d1..764477a7fc 100644 --- a/engines/mads/messages.h +++ b/engines/mads/messages.h @@ -8,12 +8,12 @@ * 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. @@ -99,9 +99,9 @@ public: ~KernelMessages(); void clear(); - int add(const Common::Point &pt, uint fontColor, uint8 flags, uint8 abortTimers, + int add(const Common::Point &pt, uint fontColor, uint8 flags, int endTrigger, uint32 timeout, const Common::String &msg); - int addQuote(int quoteId, int abortTimers, uint32 timeout); + int addQuote(int quoteId, int endTrigger, uint32 timeout); void scrollMessage(int msgIndex, int numTicks, bool quoted); void setSeqIndex(int msgIndex, int seqIndex); void remove(int msgIndex); diff --git a/engines/mads/msurface.cpp b/engines/mads/msurface.cpp index 0cb4530a84..f768624278 100644 --- a/engines/mads/msurface.cpp +++ b/engines/mads/msurface.cpp @@ -8,12 +8,12 @@ * 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. @@ -87,7 +87,6 @@ void MSurface::drawSprite(const Common::Point &pt, SpriteInfo &info, const Commo // rectangle is always 0, 0 assert(clipRect.top == 0 && clipRect.left == 0); - // TODO: Put err* and scaled* into SpriteInfo int errX = info.hotX * info.scaleX % 100; int errY = info.hotY * info.scaleY % 100; int scaledWidth = scaleValue(info.width, info.scaleX, errX); @@ -160,7 +159,6 @@ void MSurface::drawSprite(const Common::Point &pt, SpriteInfo &info, const Commo if (status == kStatusDraw && clipY == 0) { // Draw previously scaled line - // TODO Implement different drawing types (depth, shadow etc.) byte *tempDst = dst; for (int lineX = 0; lineX < scaledWidth; lineX++) { byte pixel = scaledLineBuf[lineX]; @@ -186,8 +184,6 @@ void MSurface::drawSprite(const Common::Point &pt, SpriteInfo &info, const Commo } dst += pitch; heightAmt--; - // TODO depth etc. - //depthAddress += Destination -> Width; errY += 100; if (errY >= 0) @@ -312,6 +308,9 @@ void MSurface::copyFrom(MSurface *src, const Common::Point &destPos, int depth, if (!copyRect.isValidRect()) return; + if (flipped) + copyRect.moveTo(0, copyRect.top); + byte *data = src->getData(); byte *srcPtr = data + (src->getWidth() * copyRect.top + copyRect.left); byte *destPtr = (byte *)pixels + (destY * pitch) + destX; @@ -401,14 +400,16 @@ void MSurface::copyFrom(MSurface *src, const Common::Point &destPos, int depth, const byte *srcP = srcPixelsP; byte *destP = destPixelsP; - for (int xp = 0, sprX = 0; xp < frameWidth; ++xp, ++srcP) { - if (xp < spriteLeft) - // Not yet reached start of display area - continue; - if (!lineDist[sprX++]) + for (int xp = 0, sprX = -1; xp < frameWidth; ++xp, ++srcP) { + if (!lineDist[xp]) // Not a display pixel continue; + ++sprX; + if (sprX < spriteLeft || sprX >= spriteRight) + // Skip pixel if it's not in horizontal display portion + continue; + // Get depth of current output pixel in depth surface Common::Point pt((destP - (byte *)this->pixels) % this->pitch, (destP - (byte *)this->pixels) / this->pitch); @@ -489,7 +490,6 @@ void MSurface::scrollY(int yAmount) { delete[] tempData; } - void MSurface::translate(Common::Array<RGB6> &palette) { for (int y = 0; y < this->h; ++y) { byte *pDest = getBasePtr(0, y); @@ -525,6 +525,20 @@ MSurface *MSurface::flipHorizontal() const { return dest; } +void MSurface::copyRectTranslate(MSurface &srcSurface, const byte *paletteMap, + const Common::Point &destPos, const Common::Rect &srcRect) { + // Loop through the lines + for (int yCtr = 0; yCtr < srcRect.height(); ++yCtr) { + const byte *srcP = srcSurface.getBasePtr(srcRect.left, srcRect.top + yCtr); + byte *destP = getBasePtr(destPos.x, destPos.y + yCtr); + + // Copy the line over + for (int xCtr = 0; xCtr < srcRect.width(); ++xCtr, ++srcP, ++destP) { + *destP = paletteMap[*srcP]; + } + } +} + /*------------------------------------------------------------------------*/ int DepthSurface::getDepth(const Common::Point &pt) { diff --git a/engines/mads/msurface.h b/engines/mads/msurface.h index ebfb1f437a..80891afb83 100644 --- a/engines/mads/msurface.h +++ b/engines/mads/msurface.h @@ -8,12 +8,12 @@ * 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. @@ -220,11 +220,16 @@ public: * Create a new surface which is a flipped horizontal copy of the current one */ MSurface *flipHorizontal() const; + + /** + * Copy an area from one surface to another, translating it using a palette + * map as it's done + */ + void copyRectTranslate(MSurface &srcSurface, const byte *paletteMap, + const Common::Point &destPos, const Common::Rect &srcRect); }; class DepthSurface : public MSurface { -private: - MADSEngine *_vm; public: /** * Depth style @@ -234,7 +239,7 @@ public: /** * Constructor */ - DepthSurface(MADSEngine *vm) : _vm(vm), _depthStyle(0) {} + DepthSurface() : _depthStyle(0) {} /** * Returns the depth at a given position diff --git a/engines/mads/nebular/dialogs_nebular.cpp b/engines/mads/nebular/dialogs_nebular.cpp index 86244bd3bb..960a2cc2f4 100644 --- a/engines/mads/nebular/dialogs_nebular.cpp +++ b/engines/mads/nebular/dialogs_nebular.cpp @@ -8,12 +8,12 @@ * 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. @@ -91,6 +91,8 @@ bool DialogsNebular::show(int messageId, int objectId) { dialog->incNumLines(); } } else if (commandCheck("ASK", valStr, commandText)) { + if (!dialog) + error("DialogsNebular::show - Uninitialized dialog"); dialog->addInput(); } else if (commandCheck("VERB", valStr, commandText)) { dialogText += getVocab(action._activeAction._verbId); @@ -114,12 +116,18 @@ bool DialogsNebular::show(int messageId, int objectId) { } else if (commandCheck("WIDTH", valStr, commandText)) { _dialogWidth = atoi(valStr.c_str()); } else if (commandCheck("BAR", valStr, commandText)) { + if (!dialog) + error("DialogsNebular::show - Uninitialized dialog"); dialog->addBarLine(); } else if (commandCheck("UNDER", valStr, commandText)) { underlineFlag = true; } else if (commandCheck("DOWN", valStr, commandText)) { + if (!dialog) + error("DialogsNebular::show - Uninitialized dialog"); dialog->downPixelLine(); } else if (commandCheck("TAB", valStr, commandText)) { + if (!dialog) + error("DialogsNebular::show - Uninitialized dialog"); int xp = atoi(valStr.c_str()); dialog->setLineXp(xp); } @@ -164,6 +172,9 @@ bool DialogsNebular::show(int messageId, int objectId) { if (!centerFlag) dialog->incNumLines(); + if (!dialog) + error("DialogsNebular::show - Uninitialized dialog"); + // Show the dialog _vm->_events->setCursor(CURSOR_ARROW); dialog->show(); @@ -314,13 +325,13 @@ void DialogsNebular::showDialog() { break; } case DIALOG_TEXTVIEW: { - TextView *dlg = new TextView(_vm); + TextView *dlg = new RexTextView(_vm); dlg->show(); delete dlg; - break; + return; } case DIALOG_ANIMVIEW: { - AnimationView *dlg = new AnimationView(_vm); + AnimationView *dlg = new RexAnimationView(_vm); dlg->show(); delete dlg; break; @@ -333,7 +344,7 @@ void DialogsNebular::showDialog() { void DialogsNebular::showScummVMSaveDialog() { Nebular::GameNebular &game = *(Nebular::GameNebular *)_vm->_game; - Scene *scene = &(game._scene); + Scene &scene = game._scene; GUI::SaveLoadChooser *dialog = new GUI::SaveLoadChooser(_("Save game:"), _("Save"), true); int slot = dialog->runModalWithCurrentTarget(); @@ -345,24 +356,31 @@ void DialogsNebular::showScummVMSaveDialog() { desc = dialog->createDefaultSaveDescription(slot); } - scene->_spriteSlots.reset(); - scene->loadScene(scene->_currentSceneId, game._aaName, true); - scene->_userInterface.noInventoryAnim(); + scene._spriteSlots.reset(); + scene.loadScene(scene._currentSceneId, game._aaName, true); + scene._userInterface.noInventoryAnim(); game._scene.drawElements(kTransitionFadeIn, false); game.saveGame(slot, desc); } + + // Flag for scene loading that we're returning from a dialog + scene._currentSceneId = RETURNING_FROM_DIALOG; } void DialogsNebular::showScummVMRestoreDialog() { Nebular::GameNebular &game = *(Nebular::GameNebular *)_vm->_game; GUI::SaveLoadChooser *dialog = new GUI::SaveLoadChooser(_("Restore game:"), _("Restore"), false); + Scene &scene = game._scene; int slot = dialog->runModalWithCurrentTarget(); if (slot >= 0) { game._loadGameSlot = slot; - game._scene._currentSceneId = -1; + game._scene._currentSceneId = RETURNING_FROM_LOADING; game._currentSectionNumber = -1; + } else { + // Flag for scene loading that we're returning from a dialog + scene._currentSceneId = RETURNING_FROM_DIALOG; } } @@ -376,8 +394,7 @@ TextDialog(vm, FONT_INTERFACE, Common::Point(-1, -1), 32) { addLine("ANSWER INCORRECT!", true); wordWrap("\n"); addLine("(But we'll give you another chance!)"); - } - else { + } else { addLine("REX NEBULAR version 8.43", true); wordWrap("\n"); addLine("(Copy Protection, for your convenience)"); @@ -400,7 +417,7 @@ TextDialog(vm, FONT_INTERFACE, Common::Point(-1, -1), 32) { _hogEntry._pageNum, _hogEntry._lineNum, _hogEntry._wordNum); wordWrap(line); - wordWrap("and type it on the line below (we',27h,'ve even given you"); + wordWrap("and type it on the line below (we've even given you"); wordWrap("first letter as a hint). As soon as you do that, we can get"); wordWrap("right into this really COOL adventure game!\n"); wordWrap("\n"); @@ -411,17 +428,58 @@ TextDialog(vm, FONT_INTERFACE, Common::Point(-1, -1), 32) { void CopyProtectionDialog::show() { draw(); - _vm->_events->showCursor(); - // TODO: Replace with text input - while (!_vm->shouldQuit() && !_vm->_events->isKeyPressed() && - !_vm->_events->_mouseClicked) { - _vm->_events->delay(1); + Common::KeyState curKey; + const Common::Rect inputArea(110, 165, 210, 175); + MSurface *origInput = new MSurface(inputArea.width(), inputArea.height()); + _vm->_screen.frameRect(inputArea, TEXTDIALOG_BLACK); + _vm->_screen.copyTo(origInput, inputArea, Common::Point(0, 0)); + _font->setColors(TEXTDIALOG_FE, TEXTDIALOG_FE, TEXTDIALOG_FE, TEXTDIALOG_FE); + _vm->_screen.copyRectToScreen(inputArea); + _vm->_screen.updateScreen(); + + bool firstTime = true; + + while (!_vm->shouldQuit()) { + if (!firstTime) { + while (!_vm->shouldQuit() && !_vm->_events->isKeyPressed()) { + _vm->_events->delay(1); + } + + if (_vm->shouldQuit()) + break; + + curKey = _vm->_events->getKey(); + + if (curKey.keycode == Common::KEYCODE_RETURN || curKey.keycode == Common::KEYCODE_KP_ENTER) + break; + else if (curKey.keycode == Common::KEYCODE_BACKSPACE) + _textInput.deleteLastChar(); + else if (_textInput.size() < 14) + _textInput += curKey.ascii; + + _vm->_events->_pendingKeys.clear(); + } else { + firstTime = false; + _textInput = _hogEntry._word[0]; + } + + _vm->_screen.copyFrom(origInput, Common::Rect(0, 0, inputArea.width(), inputArea.height()), Common::Point(inputArea.left, inputArea.top)); + _font->writeString(&_vm->_screen, _textInput, + Common::Point(inputArea.left + 2, inputArea.top + 1), 1); + _vm->_screen.copyRectToScreen(inputArea); + _vm->_screen.updateScreen(); } - _vm->_events->_pendingKeys.clear(); + origInput->free(); + delete origInput; +} + +bool CopyProtectionDialog::isCorrectAnswer() { + return _hogEntry._word == _textInput; } + bool CopyProtectionDialog::getHogAnusEntry(HOGANUS &entry) { File f; f.open("*HOGANUS.DAT"); @@ -535,6 +593,7 @@ void PictureDialog::save() { void PictureDialog::restore() { if (_savedSurface) { _savedSurface->copyTo(&_vm->_screen); + _savedSurface->free(); delete _savedSurface; _savedSurface = nullptr; @@ -594,14 +653,20 @@ GameDialog::GameDialog(MADSEngine *vm) : FullScreenDialog(vm) { _vm->_events->waitCursor(); scene.clearVocab(); scene._dynamicHotspots.clear(); + // Clear scene sprites and objects + scene._spriteSlots.reset(); + _vm->_game->_screenObjects.clear(); _vm->_dialogs->_defaultPosition = Common::Point(-1, -1); _menuSpritesIndex = 0; } void GameDialog::display() { + Palette &palette = *_vm->_palette; + palette.initPalette(); + palette.resetGamePalette(18, 10); + FullScreenDialog::display(); - Palette &palette = *_vm->_palette; palette.setEntry(10, 0, 63, 0); palette.setEntry(11, 0, 45, 0); palette.setEntry(12, 63, 63, 0); @@ -621,6 +686,7 @@ void GameDialog::display() { GameDialog::~GameDialog() { _vm->_screen.resetClipBounds(); + _vm->_game->_scene._currentSceneId = RETURNING_FROM_DIALOG; } void GameDialog::clearLines() { @@ -640,14 +706,14 @@ void GameDialog::setClickableLines() { int maxHeight = _lines[idx]._font->getHeight(); screenObjects.add(Common::Rect(pt.x, pt.y, pt.x + strWidth, pt.y + maxHeight - 1), - LAYER_GUI, CAT_COMMAND, idx); + SCREENMODE_VGA, CAT_COMMAND, idx); } } if (_vm->_dialogs->_pendingDialog == DIALOG_SAVE || _vm->_dialogs->_pendingDialog == DIALOG_RESTORE) { - screenObjects.add(Common::Rect(293, 26, 312, 75), LAYER_GUI, CAT_INV_LIST, 50); - screenObjects.add(Common::Rect(293, 78, 312, 127), LAYER_GUI, CAT_INV_LIST, 51); + screenObjects.add(Common::Rect(293, 26, 312, 75), SCREENMODE_VGA, CAT_INV_LIST, 50); + screenObjects.add(Common::Rect(293, 78, 312, 127), SCREENMODE_VGA, CAT_INV_LIST, 51); } } @@ -791,7 +857,7 @@ void GameDialog::show() { Scene &scene = _vm->_game->_scene; - while (_selectedLine < 1 && !_vm->shouldQuit()) { + while (_selectedLine == -1 && !_vm->shouldQuit()) { handleEvents(); if (_redrawFlag) { if (!_tempLine) @@ -818,11 +884,21 @@ void GameDialog::handleEvents() { _lines[i]._state = DLGSTATE_UNSELECTED; // Process pending events - _vm->_events->pollEvents(); + events.pollEvents(); + + if (events.isKeyPressed()) { + switch (events.getKey().keycode) { + case Common::KEYCODE_ESCAPE: + _selectedLine = 0; + break; + default: + break; + } + } // Scan for objects in the dialog Common::Point mousePos = events.currentPos() - Common::Point(0, DIALOG_TOP); - int objIndex = screenObjects.scan(mousePos, LAYER_GUI); + int objIndex = screenObjects.scan(mousePos, SCREENMODE_VGA); if (_movedFlag) { int yp = mousePos.y; @@ -905,7 +981,7 @@ void GameDialog::refreshText() { } if (!skipFlag) { - _lines[i]._textDisplayIndex = scene._textDisplay.add(_lines[i]._pos.x, _lines[i]._pos.y, + _lines[i]._textDisplayIndex = scene._textDisplay.add(_lines[i]._pos.x, _lines[i]._pos.y, fontColor, _lines[i]._widthAdjust, _lines[i]._msg, _lines[i]._font); } } @@ -997,12 +1073,13 @@ void GameMenuDialog::show() { _vm->_dialogs->_pendingDialog = DIALOG_OPTIONS; _vm->_dialogs->showDialog(); break; + case 5: + _vm->quitGame(); + break; case 4: + default: // Resume game break; - case 5: - default: - _vm->quitGame(); } } @@ -1015,12 +1092,11 @@ OptionsDialog::OptionsDialog(MADSEngine *vm) : GameDialog(vm) { int OptionsDialog::getOptionQuote(int option) { Nebular::GameNebular &game = *(Nebular::GameNebular *)_vm->_game; - // TODO: Hook the rest of the options to the current config switch (option) { case 17: // Music - return 24; // 24: ON, 25: OFF + return _vm->_musicFlag ? 24 : 25; // 24: ON, 25: OFF case 18: // Sound - return 26; // 26: ON, 27: OFF + return _vm->_soundFlag ? 26 : 27; // 26: ON, 27: OFF case 19: // Interface return !_vm->_easyMouse ? 28 : 29; // 28: Standard, 29: Easy case 20: // Inventory @@ -1061,16 +1137,25 @@ void OptionsDialog::display() { void OptionsDialog::show() { Nebular::GameNebular &game = *(Nebular::GameNebular *)_vm->_game; + + // Previous options, restored when cancel is selected + bool prevMusicFlag = _vm->_musicFlag; + bool prevEasyMouse = _vm->_easyMouse; + bool prevInvObjectsAnimated = _vm->_invObjectsAnimated; + bool prevTextWindowStill = _vm->_textWindowStill; + ScreenFade prevScreenFade = _vm->_screenFade; + StoryMode prevStoryMode = game._storyMode; + do { - _selectedLine = 0; + _selectedLine = -1; GameDialog::show(); switch (_selectedLine) { case 1: // Music - warning("STUB: Music toggle"); + _vm->_musicFlag = _vm->_soundFlag = !_vm->_musicFlag; break; case 2: // Sound - warning("STUB: Sound toggle"); + _vm->_musicFlag = _vm->_soundFlag = !_vm->_musicFlag; break; case 3: // Interface _vm->_easyMouse = !_vm->_easyMouse; @@ -1099,19 +1184,22 @@ void OptionsDialog::show() { // Reload menu _lineIndex = -1; clearLines(); + _vm->_game->_screenObjects.clear(); + _vm->_game->_scene._spriteSlots.reset(); setLines(); - setClickableLines(); - } while (_selectedLine <= 7); - - switch (_selectedLine) { - case 8: // Done - // TODO: Copy from temporary config - break; - case 9: // Cancel - // TODO: Ignore all changes to temporary config - break; - default: - break; + } while (!_vm->shouldQuit() && _selectedLine != 0 && _selectedLine <= 7); + + if (_selectedLine == 8) { + // OK button, save settings + _vm->saveOptions(); + } else if (_selectedLine == 9) { + // Cancel button, revert all options from the saved ones + _vm->_musicFlag = _vm->_soundFlag = prevMusicFlag; + _vm->_easyMouse = prevEasyMouse; + _vm->_invObjectsAnimated = prevInvObjectsAnimated; + _vm->_textWindowStill = prevTextWindowStill; + _vm->_screenFade = prevScreenFade; + game._storyMode = prevStoryMode; } } diff --git a/engines/mads/nebular/dialogs_nebular.h b/engines/mads/nebular/dialogs_nebular.h index d00cd87ead..4935ee4b8c 100644 --- a/engines/mads/nebular/dialogs_nebular.h +++ b/engines/mads/nebular/dialogs_nebular.h @@ -8,12 +8,12 @@ * 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. @@ -69,6 +69,7 @@ struct HOGANUS { class CopyProtectionDialog : public TextDialog { private: HOGANUS _hogEntry; + Common::String _textInput; /** * Get a random copy protection entry from the HOGANUS resource @@ -84,6 +85,8 @@ public: * Show the dialog */ virtual void show(); + + bool isCorrectAnswer(); }; class PictureDialog : public TextDialog { @@ -116,7 +119,7 @@ class GameDialog: public FullScreenDialog { Common::String _msg; Font *_font; int _widthAdjust; - + DialogLine(); DialogLine(const Common::String &s); }; @@ -130,7 +133,7 @@ protected: int _menuSpritesIndex; int _lineIndex; int _textLineCount; - + /** * Display the dialog */ diff --git a/engines/mads/nebular/game_nebular.cpp b/engines/mads/nebular/game_nebular.cpp index 902f42507a..e8e0a4f42c 100644 --- a/engines/mads/nebular/game_nebular.cpp +++ b/engines/mads/nebular/game_nebular.cpp @@ -8,12 +8,12 @@ * 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. @@ -27,6 +27,7 @@ #include "mads/game.h" #include "mads/screen.h" #include "mads/msurface.h" +#include "mads/menu_views.h" #include "mads/nebular/game_nebular.h" #include "mads/nebular/dialogs_nebular.h" #include "mads/nebular/globals_nebular.h" @@ -44,30 +45,86 @@ GameNebular::GameNebular(MADSEngine *vm) } ProtectionResult GameNebular::checkCopyProtection() { - /* - // DEBUG: Flag copy protection failure - _globals[kCopyProtectFailed] = -1; + //if (!ConfMan.getBool("copy_protection")) + // return PROTECTION_SUCCEED; - if (!ConfMan.getBool("copy_protection")) - return true; + CopyProtectionDialog *dlg; + bool correctAnswer; - * DEBUG: Disabled for now - CopyProtectionDialog *dlg = new CopyProtectionDialog(_vm, false); + dlg = new CopyProtectionDialog(_vm, false); dlg->show(); + correctAnswer = dlg->isCorrectAnswer(); delete dlg; - */ - return PROTECTION_SUCCEED; + + if (!correctAnswer && !_vm->shouldQuit()) { + dlg = new CopyProtectionDialog(_vm, true); + dlg->show(); + correctAnswer = dlg->isCorrectAnswer(); + delete dlg; + } + + return correctAnswer ? PROTECTION_SUCCEED : PROTECTION_FAIL; } void GameNebular::startGame() { - /* + // First handle any ending credits from a just finished game session. + // Note that, with the exception of the decompression ending, which doesn't + // use animations, the remaining animations will automatically launch their + // own text view credits when the animation is completed + switch (_winStatus) { + case 1: + // No shields failure ending + AnimationView::execute(_vm, "rexend1"); + break; + case 2: + // Shields, but no targetting failure ending + AnimationView::execute(_vm, "rexend2"); + break; + case 3: + // Completed game successfully, so activate quotes item on the main menu + ConfMan.setBool("ShowQuotes", true); + ConfMan.flushToDisk(); + + AnimationView::execute(_vm, "rexend3"); + break; + case 4: + // Decompression ending + TextView::execute(_vm, "ending4"); + break; + } + + do { + checkShowDialog(); + _winStatus = 0; + + _sectionNumber = 1; + initSection(_sectionNumber); + _vm->_events->setCursor(CURSOR_ARROW); + _statusFlag = true; + + // Show the main menu + _vm->_dialogs->_pendingDialog = DIALOG_MAIN_MENU; + _vm->_dialogs->showDialog(); + } while (!_vm->shouldQuit() && _vm->_dialogs->_pendingDialog != DIALOG_NONE); + + if (_vm->shouldQuit()) + return; + + _priorSectionNumber = 0; + _priorSectionNumber = -1; + _scene._priorSceneId = 0; + _scene._currentSceneId = -1; + _scene._nextSceneId = 101; + + initializeGlobals(); + // Check copy protection ProtectionResult protectionResult = checkCopyProtection(); + switch (protectionResult) { case PROTECTION_FAIL: // Copy protection failed _scene._nextSceneId = 804; - initializeGlobals(); _globals[kCopyProtectFailed] = true; return; case PROTECTION_ESCAPE: @@ -78,23 +135,6 @@ void GameNebular::startGame() { // Copy protection check succeeded break; } - */ - - initSection(_sectionNumber); - _statusFlag = true; - - // Show the main menu - _vm->_dialogs->_pendingDialog = DIALOG_MAIN_MENU; - _vm->_dialogs->showDialog(); - _vm->_dialogs->_pendingDialog = DIALOG_NONE; - - _priorSectionNumber = 0; - _priorSectionNumber = -1; - _scene._priorSceneId = 0; - _scene._currentSceneId = -1; - _scene._nextSceneId = 101; - - initializeGlobals(); } void GameNebular::initializeGlobals() { @@ -244,10 +284,12 @@ void GameNebular::initializeGlobals() { // Final setup based on selected difficulty level switch (_difficulty) { case DIFFICULTY_HARD: - _objects.setRoom(OBJ_PLANT_STALK, NOWHERE); - _objects.setRoom(OBJ_PENLIGHT, NOWHERE); + _objects.setRoom(OBJ_BLOWGUN, NOWHERE); + _objects.setRoom(OBJ_NOTE, NOWHERE); - _globals[kLeavesStatus] = LEAVES_ON_TRAP; + _globals[kLeavesStatus] = LEAVES_ON_GROUND; + _globals[kDurafailRecharged] = 0; + _globals[kPenlightCellStatus] = FIRST_TIME_UNCHARGED_DURAFAIL; break; case DIFFICULTY_MEDIUM: @@ -259,12 +301,10 @@ void GameNebular::initializeGlobals() { break; case DIFFICULTY_EASY: - _objects.setRoom(OBJ_BLOWGUN, NOWHERE); - _objects.setRoom(OBJ_NOTE, NOWHERE); + _objects.setRoom(OBJ_PLANT_STALK, NOWHERE); + _objects.setRoom(OBJ_PENLIGHT, NOWHERE); - _globals[kLeavesStatus] = LEAVES_ON_GROUND; - _globals[kPenlightCellStatus] = FIRST_TIME_UNCHARGED_DURAFAIL; - _globals[kDurafailRecharged] = 0; + _globals[kLeavesStatus] = LEAVES_ON_TRAP; break; } @@ -309,7 +349,9 @@ void GameNebular::setSectionHandler() { } void GameNebular::checkShowDialog() { - if (_vm->_dialogs->_pendingDialog && _player._stepEnabled && !_globals[kCopyProtectFailed]) { + // Loop for showing dialogs, if any need to be shown + if (_vm->_dialogs->_pendingDialog && (_player._stepEnabled || _winStatus) + && !_globals[kCopyProtectFailed]) { _player.releasePlayerSprites(); // Make a thumbnail in case it's needed for making a savegame @@ -428,7 +470,7 @@ void GameNebular::doObjectAction() { dialogs.show(464); } else if (action.isAction(VERB_REFLECT)) { dialogs.show(466); - } else if (action.isAction(VERB_GAZE_INTO, NOUN_REARVIEW_MIRROR)) { + } else if (action.isAction(VERB_GAZE_INTO, NOUN_REARVIEW_MIRROR)) { dialogs.show(467); } else if (action.isAction(VERB_EAT, NOUN_CHICKEN_BOMB)) { dialogs.show(469); @@ -599,7 +641,7 @@ void GameNebular::doObjectAction() { _objects.addToInventory(OBJ_DURAFAIL_CELLS); if (_difficulty == DIFFICULTY_HARD) { dialogs.showItem(OBJ_DURAFAIL_CELLS, 416); - } + } _globals[kHandsetCellStatus] = 0; break; case 3: @@ -784,7 +826,7 @@ void GameNebular::step() { (_player._facing == _player._turnToFacing)) { if (_scene._frameStartTime >= *((uint32 *)&_globals[kWalkerTiming])) { if (!_player._stopWalkerIndex) { - int randomVal = _vm->getRandomNumber(29999);; + int randomVal = _vm->getRandomNumber(29999); if (_globals[kSexOfRex] == REX_MALE) { switch (_player._facing) { case FACING_SOUTHWEST: diff --git a/engines/mads/nebular/game_nebular.h b/engines/mads/nebular/game_nebular.h index da607d47ee..3cf7aefc18 100644 --- a/engines/mads/nebular/game_nebular.h +++ b/engines/mads/nebular/game_nebular.h @@ -8,12 +8,12 @@ * 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. @@ -131,20 +131,21 @@ public: virtual void step(); virtual void synchronize(Common::Serializer &s, bool phase1); -}; + virtual void setNaughtyMode(bool naughtyMode) { _storyMode = naughtyMode ? STORYMODE_NAUGHTY : STORYMODE_NICE; } + virtual bool getNaughtyMode() const { return _storyMode == STORYMODE_NAUGHTY; } +}; +// Section handlers aren't needed in ScummVM implementation class Section1Handler : public SectionHandler { public: Section1Handler(MADSEngine *vm) : SectionHandler(vm) {} - // TODO: Properly implement handler methods virtual void preLoadSection() {} virtual void sectionPtr2() {} virtual void postLoadSection() {} }; -// TODO: Properly implement handler classes typedef Section1Handler Section2Handler; typedef Section1Handler Section3Handler; typedef Section1Handler Section4Handler; diff --git a/engines/mads/nebular/globals_nebular.cpp b/engines/mads/nebular/globals_nebular.cpp index 9f8b8a7888..c44506e546 100644 --- a/engines/mads/nebular/globals_nebular.cpp +++ b/engines/mads/nebular/globals_nebular.cpp @@ -8,12 +8,12 @@ * 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. diff --git a/engines/mads/nebular/globals_nebular.h b/engines/mads/nebular/globals_nebular.h index bd1c6d84b0..7c7069892e 100644 --- a/engines/mads/nebular/globals_nebular.h +++ b/engines/mads/nebular/globals_nebular.h @@ -8,12 +8,12 @@ * 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. @@ -148,9 +148,9 @@ enum GlobalId { /* Section #6 Variables */ kConvHermit1 = 130, - kconvHermit2 = 131, + kConvHermit2 = 131, kHasTalkedToHermit = 132, - kExecuted_1_11 = 133, + kHermitWantsBatteries = 133, kHandsetCellStatus = 134, kBeenInVideoStore = 135, kDurafailRecharged = 136, diff --git a/engines/mads/nebular/menu_nebular.cpp b/engines/mads/nebular/menu_nebular.cpp index 717e3f6cf9..6fe17f3beb 100644 --- a/engines/mads/nebular/menu_nebular.cpp +++ b/engines/mads/nebular/menu_nebular.cpp @@ -8,12 +8,12 @@ * 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. @@ -21,6 +21,7 @@ */ #include "common/scummsys.h" +#include "common/config-manager.h" #include "mads/game.h" #include "mads/mads.h" #include "mads/menu_views.h" @@ -47,7 +48,7 @@ MainMenu::MainMenu(MADSEngine *vm): MenuView(vm) { _highlightedIndex = -1; _selectedIndex = -1; _buttonDown = false; - + for (int i = 0; i < 7; ++i) _menuItems[i] = nullptr; } @@ -62,6 +63,10 @@ MainMenu::~MainMenu() { scene._spriteSlots.reset(); } +bool MainMenu::shouldShowQuotes() { + return ConfMan.hasKey("ShowQuotes") && ConfMan.getBool("ShowQuotes"); +} + void MainMenu::display() { MenuView::display(); Scene &scene = _vm->_game->_scene; @@ -80,8 +85,8 @@ void MainMenu::display() { Common::Point pt(frame0->_offset.x - (frame0->w / 2), frame0->_offset.y - frame0->h); screenObjects.add( - Common::Rect(pt.x, pt.y + DIALOG_TOP, pt.x + frame0->w, - pt.y + frame0->h + DIALOG_TOP), LAYER_GUI, CAT_COMMAND, i); + Common::Rect(pt.x, pt.y + DIALOG_TOP, pt.x + frame0->w, + pt.y + frame0->h + DIALOG_TOP), SCREENMODE_VGA, CAT_COMMAND, i); } // Set the cursor for when it's shown @@ -101,6 +106,9 @@ void MainMenu::doFrame() { handleAction((MADSGameAction)_selectedIndex); } else { for (_menuItemIndex = 0; _menuItemIndex < 6; ++_menuItemIndex) { + if (_menuItemIndex == 4 && !shouldShowQuotes()) + continue; + if (_menuItemIndex != _selectedIndex) { addSpriteSlot(); } @@ -118,8 +126,11 @@ void MainMenu::doFrame() { // If the user has chosen to skip the animation, show the full menu immediately if (_skipFlag && _menuItemIndex >= 0) { - // Quickly loop through all the menu items to display each's final frame + // Quickly loop through all the menu items to display each's final frame for (; _menuItemIndex < 6; ++_menuItemIndex) { + if (_menuItemIndex == 4 && !shouldShowQuotes()) + continue; + // Draw the final frame of the menuitem _frameIndex = 0; addSpriteSlot(); @@ -129,9 +140,12 @@ void MainMenu::doFrame() { } else { if ((_menuItemIndex == -1) || (_frameIndex == 0)) { if (++_menuItemIndex == 6) { + // Reached end of display animation _vm->_events->showCursor(); return; + } else if (_menuItemIndex == 4 && !shouldShowQuotes()) { + ++_menuItemIndex; } _frameIndex = _menuItems[_menuItemIndex]->getCount() - 1; @@ -147,7 +161,7 @@ void MainMenu::doFrame() { void MainMenu::addSpriteSlot() { Scene &scene = _vm->_game->_scene; SpriteSlots &spriteSlots = scene._spriteSlots; - + int seqIndex = (_menuItemIndex < 6) ? _menuItemIndex : _frameIndex; spriteSlots.deleteTimer(seqIndex); @@ -241,7 +255,7 @@ bool MainMenu::onEvent(Common::Event &event) { } return true; - case Common::EVENT_MOUSEMOVE: + case Common::EVENT_MOUSEMOVE: if (_buttonDown) { int menuIndex = getHighlightedItem(event.mouse); if (menuIndex != _highlightedIndex) { @@ -273,12 +287,12 @@ bool MainMenu::onEvent(Common::Event &event) { default: break; } - + return false; } int MainMenu::getHighlightedItem(const Common::Point &pt) { - return _vm->_game->_screenObjects.scan(pt, LAYER_GUI) - 1; + return _vm->_game->_screenObjects.scan(pt, SCREENMODE_VGA) - 1; } void MainMenu::unhighlightItem() { @@ -303,7 +317,7 @@ void MainMenu::handleAction(MADSGameAction action) { break; case RESUME_GAME: - // The original resumed the most recently saved game. Instead, + // The original resumed the most recently saved game. Instead, // just show the load game scren _vm->_dialogs->_pendingDialog = DIALOG_RESTORE; return; @@ -340,7 +354,7 @@ void AdvertView::show() { uint32 expiryTime = g_system->getMillis() + 10 * 1000; _vm->_palette->resetGamePalette(4, 8); - + // Load the advert background onto the screen SceneInfo *sceneInfo = SceneInfo::init(_vm); sceneInfo->load(screenId, 0, Common::String(), 0, _vm->_game->_scene._depthSurface, @@ -375,6 +389,21 @@ bool AdvertView::onEvent(Common::Event &event) { return false; } +/*------------------------------------------------------------------------*/ + +void RexAnimationView::scriptDone() { + AnimationView::scriptDone(); + + Common::String s = getResourceName(); + if (s == "rexend1") { + TextView::execute(_vm, "ending1"); + } else if (s == "rexend2") { + TextView::execute(_vm, "ending2"); + } else if (s == "rexend3") { + TextView::execute(_vm, "credits"); + } +} + } // End of namespace Nebular } // End of namespace MADS diff --git a/engines/mads/nebular/menu_nebular.h b/engines/mads/nebular/menu_nebular.h index 29777a7a7c..35af0bb34f 100644 --- a/engines/mads/nebular/menu_nebular.h +++ b/engines/mads/nebular/menu_nebular.h @@ -8,12 +8,12 @@ * 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. @@ -80,6 +80,8 @@ private: * Add a sprite slot for the current menuitem frame */ void addSpriteSlot(); + + bool shouldShowQuotes(); protected: /** * Display the menu @@ -128,6 +130,18 @@ public: void show(); }; +class RexAnimationView : public AnimationView { +protected: + virtual void scriptDone(); +public: + RexAnimationView(MADSEngine *vm) : AnimationView(vm) {} +}; + +class RexTextView : public TextView { +public: + RexTextView(MADSEngine *vm) : TextView(vm) {} +}; + } // End of namespace Nebular } // End of namespace MADS diff --git a/engines/mads/nebular/nebular_scenes.cpp b/engines/mads/nebular/nebular_scenes.cpp index b5e2491624..eb6f7a5610 100644 --- a/engines/mads/nebular/nebular_scenes.cpp +++ b/engines/mads/nebular/nebular_scenes.cpp @@ -8,12 +8,12 @@ * 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. @@ -432,7 +432,7 @@ void SceneTeleporter::teleporterHandleKey() { case 0: { _game._player._stepEnabled = false; Common::Point msgPos = teleporterComputeLocation(); - _handSequenceId = _scene->_sequences.startReverseCycle(_handSpriteId, false, 4, 2, 0, 0); + _handSequenceId = _scene->_sequences.startPingPongCycle(_handSpriteId, false, 4, 2, 0, 0); _scene->_sequences.setPosition(_handSequenceId, msgPos); _scene->_sequences.setDepth(_handSequenceId, 2); _scene->_sequences.addSubEntry(_handSequenceId, SEQUENCE_TRIGGER_LOOP, 0, 1); @@ -451,7 +451,10 @@ void SceneTeleporter::teleporterHandleKey() { _curCode *= 10; _curCode += _buttonTyped; _digitCount++; - _msgText = Common::String::format("%d", _curCode); + + Common::String format = "%01d"; + format.setChar('0' + _digitCount, 2); + _msgText = Common::String::format(format.c_str(), _curCode); if (_digitCount < 4) _msgText += "_"; @@ -535,7 +538,7 @@ void SceneTeleporter::teleporterEnter() { _curMessageId = -1; _msgText = "_"; - if (_scene->_priorSceneId == -2) + if (_scene->_priorSceneId == RETURNING_FROM_DIALOG) _scene->_priorSceneId = _globals[kTeleporterDestination]; if (_scene->_priorSceneId < 101) diff --git a/engines/mads/nebular/nebular_scenes.h b/engines/mads/nebular/nebular_scenes.h index cf33b21aad..58a6d1c98f 100644 --- a/engines/mads/nebular/nebular_scenes.h +++ b/engines/mads/nebular/nebular_scenes.h @@ -8,12 +8,12 @@ * 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. @@ -106,6 +106,7 @@ enum Verb { VERB_WALK_UP = 0x227, VERB_WALK_INTO = 0x242, VERB_EXIT = 0x298, + VERB_WALK_BEHIND = 0x2A2, VERB_WALK_ONTO = 0x2B5, VERB_RETURN_TO = 0x2D5, VERB_CLIMB_INTO = 0x2F7, @@ -216,9 +217,9 @@ enum Noun { NOUN_CLEARING_TO_EAST = 0x4B, NOUN_CLEARING_TO_SOUTH = 0x4C, NOUN_CLIFF_FACE = 0x4D, - NOUN_CLIMB_DOWN = 0x4E, - NOUN_CLIMB_THROUGH = 0x4F, - NOUN_CLIMB_UP = 0x50, + //NOUN_CLIMB_DOWN = 0x4E, + //NOUN_CLIMB_THROUGH = 0x4F, + //NOUN_CLIMB_UP = 0x50, NOUN_CLOCK = 0x51, NOUN_CLOSET = 0x52, NOUN_CLOTHESLINE = 0x53, @@ -397,7 +398,7 @@ enum Noun { NOUN_PALM_TREE = 0x100, NOUN_PASSAGE_WAY_TO_SOUTH = 0x101, NOUN_PASSION_PUSS = 0x102, - NOUN_PEER_THROUGH = 0x103, + //NOUN_PEER_THROUGH = 0x103, NOUN_PENCIL = 0x104, NOUN_PENDULOUS_CRAG = 0x105, NOUN_PENLIGHT = 0x106, @@ -812,7 +813,7 @@ enum Noun { NOUN_COUNTER = 0x29F, NOUN_SENSOR = 0x2A0, NOUN_SOFTWARE_INFORMATION = 0x2A1, - NOUN_WALK_BEHIND = 0x2A2, + //NOUN_WALK_BEHIND = 0x2A2, NOUN_BARGAINS = 0x2A3, NOUN_SCAN_LIGHT = 0x2A4, NOUN_OLD_SOFTWARE_STAND = 0x2A5, @@ -831,7 +832,7 @@ enum Noun { //NOUN_GAWK_AT = 0x2B2, NOUN_CORRIDOR_TO_SOUTH = 0x2B3, NOUN_CORRIDOR_TO_NORTH = 0x2B4, - NOUN_WALK_ONTO = 0x2B5, + //NOUN_WALK_ONTO = 0x2B5, NOUN_ROCK_WALL = 0x2B6, NOUN_WOMAN = 0x2B7, NOUN_WOMEN = 0x2B8, @@ -897,7 +898,7 @@ enum Noun { NOUN_YOUR_STUFF = 0x2F4, NOUN_OTHER_STUFF = 0x2F5, NOUN_LAMP = 0x2F6, - NOUN_CLIMB_INTO = 0x2F7, + //NOUN_CLIMB_INTO = 0x2F7, NOUN_LIGHT_BULB = 0x2F8, //NOUN_STEP_INTO = 0x2F9, NOUN_ROOM = 0x2FA, @@ -924,7 +925,6 @@ enum Noun { NOUN_WHISKEY = 0x30F, NOUN_ALCOHOL = 0x310, NOUN_RIM = 0x311, - //NOUN_WALK_ALONG = 0x312, NOUN_SUBMERGED_CITY = 0x313, NOUN_GOVERNORS_HOUSE = 0x314, NOUN_RIM_TOWARDS_EAST = 0x315, @@ -1057,7 +1057,7 @@ enum Noun { NOUN_PAD_TO_EAST = 0x394, NOUN_PAD_TO_WEST = 0x395, NOUN_TOWER = 0x396, - NOUN_LOOK_OUT = 0x397, + //NOUN_LOOK_OUT = 0x397, NOUN_SERVICE_PANEL = 0x398, NOUN_CRACK = 0x399, NOUN_THROTTLE = 0x39A, diff --git a/engines/mads/nebular/nebular_scenes1.cpp b/engines/mads/nebular/nebular_scenes1.cpp index ab072c1d3c..fd97f71727 100644 --- a/engines/mads/nebular/nebular_scenes1.cpp +++ b/engines/mads/nebular/nebular_scenes1.cpp @@ -8,12 +8,12 @@ * 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 + * 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. @@ -134,7 +134,7 @@ void Scene101::sayDang() { switch (_game._trigger) { case 0: _scene->_sequences.remove(_globals._sequenceIndexes[11]); - _globals._sequenceIndexes[11] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[11], false, 3, 6, 0, 0); + _globals._sequenceIndexes[11] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[11], false, 3, 6, 0, 0); _scene->_sequences.setAnimRange(_globals._sequenceIndexes[11], 17, 21); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[11], SEQUENCE_TRIGGER_EXPIRE, 0, 72); _vm->_sound->command(17); @@ -188,13 +188,13 @@ void Scene101::enter() { _scene->_hotspots.activate(NOUN_SHIELD_MODULATOR, false); _panelOpened = false; - if (_scene->_priorSceneId != -1) + if (_scene->_priorSceneId != RETURNING_FROM_LOADING) _globals[kNeedToStandUp] = false; - if (_scene->_priorSceneId != -2) + if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) _game._player._playerPos = Common::Point(100, 152); - if ((_scene->_priorSceneId == 112) || ((_scene->_priorSceneId == -2) && _sittingFl )) { + if ((_scene->_priorSceneId == 112) || ((_scene->_priorSceneId == RETURNING_FROM_DIALOG) && _sittingFl )) { _game._player._visible = false; _sittingFl = true; _game._player._playerPos = Common::Point(161, 123); @@ -696,7 +696,7 @@ void Scene102::enter() { _globals._spriteIndexes[11] = _scene->_sprites.addSprites("*RXMRC_8"); _globals._spriteIndexes[13] = _scene->_sprites.addSprites(formAnimName('x', 0)); - _globals._sequenceIndexes[1] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[1], false, 8, 0, 0, 0); + _globals._sequenceIndexes[1] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[1], false, 8, 0, 0, 0); _globals._sequenceIndexes[2] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[2], false, 170, 0, 1, 6); _globals._sequenceIndexes[3] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[3], false, 11, 0, 2, 3); _globals._sequenceIndexes[4] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[4], false, 4, 0, 1, 0); @@ -721,7 +721,7 @@ void Scene102::enter() { _scene->_sequences.addSubEntry(_globals._sequenceIndexes[6], SEQUENCE_TRIGGER_EXPIRE, 0, 70); } else if (_scene->_priorSceneId == 103) _game._player._playerPos = Common::Point(47, 152); - else if (_scene->_priorSceneId != -2) { + else if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) { _game._player._facing = FACING_NORTHWEST; _game._player._playerPos = Common::Point(32, 129); } @@ -906,7 +906,7 @@ void Scene102::actions() { _fridgeFirstOpenFl = false; int quoteId = _vm->getRandomNumber(59, 63); Common::String curQuote = _game.getQuote(quoteId); - int width = _vm->_font->getWidth(curQuote, -1); + int width = _scene->_kernelMessages._talkFont->getWidth(curQuote, -1); _scene->_kernelMessages.reset(); _game._triggerSetupMode = SEQUENCE_TRIGGER_DAEMON; _scene->_kernelMessages.add(Common::Point(210, 60), 0x1110, 0, 73, 120, curQuote); @@ -1201,7 +1201,7 @@ void Scene102::actions() { if (_action.isAction(VERB_TAKE, NOUN_BINOCULARS) && _game._objects.isInRoom(OBJ_BINOCULARS)) { switch (_game._trigger) { case 0: - _globals._sequenceIndexes[11] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[11], false, 3, 1, 0, 0); + _globals._sequenceIndexes[11] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[11], false, 3, 1, 0, 0); _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[11]); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[11], SEQUENCE_TRIGGER_EXPIRE, 0, 1); _game._player._visible = false; @@ -1342,7 +1342,7 @@ void Scene103::enter() { _scene->_hotspots.activate(362, false); } - if (_scene->_priorSceneId != -2) + if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) _game._player._playerPos = Common::Point(237, 74); if (_scene->_priorSceneId == 102) { @@ -1433,7 +1433,7 @@ void Scene103::actions() { switch (_vm->_game->_trigger) { case 0: _scene->changeVariant(1); - _globals._sequenceIndexes[13] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[13], false, 3, 2); + _globals._sequenceIndexes[13] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[13], false, 3, 2); _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[13]); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[13], SEQUENCE_TRIGGER_SPRITE, 7, 1); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[13], SEQUENCE_TRIGGER_EXPIRE, 0, 2); @@ -1453,17 +1453,16 @@ void Scene103::actions() { _scene->_hotspots.activate(371, false); _vm->_game->_player._visible = true; _vm->_game->_player._stepEnabled = true; - _vm->_dialogs->showItem(OBJ_REBREATHER, 805); + _vm->_dialogs->showItem(OBJ_TIMER_MODULE, 805); break; default: break; } - } else if (_action.isAction(VERB_TAKE, 289, 0) && _game._objects.isInRoom(OBJ_REBREATHER)) { + } else if (_action.isAction(VERB_TAKE, NOUN_REBREATHER, 0) && _game._objects.isInRoom(OBJ_REBREATHER)) { switch (_vm->_game->_trigger) { case 0: - _scene->changeVariant(1); - _globals._sequenceIndexes[12] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[12], false, 3, 2); + _globals._sequenceIndexes[12] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[12], false, 3, 2); _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[12]); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[12], SEQUENCE_TRIGGER_SPRITE, 6, 1); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[12], SEQUENCE_TRIGGER_EXPIRE, 0, 2); @@ -1621,10 +1620,11 @@ void Scene104::setup() { void Scene104::enter() { _globals._spriteIndexes[1] = _scene->_sprites.addSprites(formAnimName('h', -1)); _globals._sequenceIndexes[1] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[1], false, 14, 0, 0, 1); + _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 8); if (_scene->_priorSceneId == 105) _game._player._playerPos = Common::Point(302, 107); - else if (_scene->_priorSceneId != -2) + else if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) _game._player._playerPos = Common::Point(160, 134); _loseFl = false; @@ -1846,7 +1846,7 @@ void Scene105::enter() { if (_scene->_priorSceneId == 104) _game._player._playerPos = Common::Point(13, 97); - else if (_scene->_priorSceneId != -2) + else if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) _game._player._playerPos = Common::Point(116, 147); _game.loadQuoteSet(0x4A, 0x4B, 0x4C, 0x35, 0x34, 0); @@ -2009,7 +2009,7 @@ void Scene106::enter() { } _globals._spriteIndexes[2] = _scene->_sprites.addSprites(formAnimName('G', -1)); - _globals._sequenceIndexes[2] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[2], false, 21, 0, 0, 0); + _globals._sequenceIndexes[2] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[2], false, 21, 0, 0, 0); _globals._spriteIndexes[4] = _scene->_sprites.addSprites(formAnimName('I', -1)); _globals._sequenceIndexes[4] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[4], false, 6, 0, 32, 47); @@ -2020,7 +2020,7 @@ void Scene106::enter() { _game._player._stepEnabled = false; _game._player._facing = FACING_EAST; _game._player._playerPos = Common::Point(106, 69); - } else if (_scene->_priorSceneId != -2) { + } else if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) { if (_scene->_priorSceneId == 107) { _game._player._playerPos = Common::Point(319, 84); _game._player._facing = _game._player._prepareWalkFacing = FACING_WEST; @@ -2112,9 +2112,9 @@ void Scene106::step() { } if (msgId >= 0) { - int nextAbortVal = _game._trigger + 1; + int nextTrigger = _game._trigger + 1; _scene->_kernelMessages.add(Common::Point(15, _positionY), 0x1110, 0, 0, 360, _game.getQuote(msgId)); - _scene->_sequences.addTimer(150, nextAbortVal); + _scene->_sequences.addTimer(150, nextTrigger); _positionY += 14; } } @@ -2239,7 +2239,7 @@ void Scene107::enter() { _game._player._playerPos = Common::Point(132, 47); else if (_scene->_priorSceneId == 106) _game._player._playerPos = Common::Point(20, 91); - else if (_scene->_priorSceneId != -2) + else if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) _game._player._playerPos = Common::Point(223, 151); if (((_scene->_priorSceneId == 105) || (_scene->_priorSceneId == 106)) && (_vm->getRandomNumber(1, 3) == 1)) { @@ -2351,7 +2351,7 @@ void Scene108::enter() { if (_scene->_priorSceneId == 107) _game._player._playerPos = Common::Point(138, 58); - else if (_scene->_priorSceneId != -2) + else if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) _game._player._playerPos = Common::Point(305, 98); _game.loadQuoteSet(0x4A, 0x4B, 0x4C, 0x35, 0x34, 0); @@ -2458,7 +2458,7 @@ void Scene109::enter() { if (_scene->_priorSceneId == 110) { _game._player._playerPos = Common::Point(248, 38); _globals[kHoovicSated] = 2; - } else if (_scene->_priorSceneId != -2) { + } else if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) { _game._player._playerPos = Common::Point(20, 68); _game._player._facing = FACING_EAST; } @@ -2502,7 +2502,7 @@ void Scene109::enter() { _globals._spriteIndexes[10] = _scene->_sprites.addSprites(Resources::formatName(105, 'F', 1, EXT_SS, "")); _globals._spriteIndexes[9] = _scene->_sprites.addSprites(formAnimName('H', 1)); - _globals._sequenceIndexes[10] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[10], true, 4, 0, 0, 0); + _globals._sequenceIndexes[10] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[10], true, 4, 0, 0, 0); _scene->_sequences.setDepth(_globals._sequenceIndexes[10], 5); _scene->_sequences.setPosition(_globals._sequenceIndexes[10], Common::Point(126, 39)); _scene->_sequences.setMotion(_globals._sequenceIndexes[10], 0, 200, 0); @@ -2589,8 +2589,8 @@ void Scene109::preActions() { _game._player._walkOffScreenSceneId = 108; if ((_action.isAction(VERB_THROW) || _action.isAction(VERB_GIVE) || _action.isAction(VERB_PUT)) - && (_action.isObject(NOUN_SMALL_HOLE) || _action.isObject(NOUN_TUNNEL)) - && (_action.isObject(NOUN_DEAD_FISH) || _action.isObject(NOUN_STUFFED_FISH) || _action.isObject(NOUN_BURGER))) { + && (_action.isTarget(NOUN_SMALL_HOLE) || _action.isTarget(NOUN_TUNNEL)) + && (_action.isObject(NOUN_DEAD_FISH) || _action.isObject(NOUN_STUFFED_FISH) || _action.isObject(NOUN_BURGER))) { int idx = _game._objects.getIdFromDesc(_action._activeAction._objectNameId); if ((idx >= 0) && _game._objects.isInInventory(idx)) { _game._player._prepareWalkPos = Common::Point(106, 38); @@ -2637,7 +2637,7 @@ void Scene109::actions() { break; case OBJ_BURGER: - _hoovicDifficultFl = (_game._difficulty == DIFFICULTY_EASY); + _hoovicDifficultFl = (_game._difficulty == DIFFICULTY_HARD); _globals._spriteIndexes[8] = _scene->_sprites.addSprites(formAnimName('H', (_hoovicDifficultFl ? 3 : 1))); break; } @@ -2675,7 +2675,7 @@ void Scene109::actions() { case 2: if (_hoovicDifficultFl) - _globals._sequenceIndexes[8] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[8], false, 4, 2, 0, 0); + _globals._sequenceIndexes[8] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[8], false, 4, 2, 0, 0); else _globals._sequenceIndexes[8] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[8], false, 4, 1, 0, 0); @@ -2864,7 +2864,7 @@ void Scene110::enter() { _scene->_dynamicHotspots.setPosition(idx, Common::Point(-1, 0), FACING_NONE); idx = _scene->_dynamicHotspots.add(91, 348, _globals._sequenceIndexes[3], Common::Rect(0, 0, 0, 0)); _scene->_dynamicHotspots.setPosition(idx, Common::Point(-1, 0), FACING_NONE); - } else if (_scene->_priorSceneId != -2) { + } else if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) { _game._player._playerPos = Common::Point(194, 23); _game._player._facing = FACING_SOUTH; _game._player._visible = false; @@ -3007,7 +3007,7 @@ void Scene111::enter() { _launched2Fl = false; _stampedFl = false; - if ((_scene->_priorSceneId < 201) && (_scene->_priorSceneId != -2)) { + if ((_scene->_priorSceneId < 201) && (_scene->_priorSceneId != RETURNING_FROM_DIALOG)) { _game._player._stepEnabled = false; _game._player._visible = false; _scene->loadAnimation(Resources::formatName(111, 'A', 0, EXT_AA, ""), 70); @@ -3018,7 +3018,7 @@ void Scene111::enter() { _launched2Fl = true; _vm->_sound->command(36); - } else if (_scene->_priorSceneId != -2) { + } else if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) { _game._player._playerPos = Common::Point(300, 130); _game._player._facing = FACING_WEST; } diff --git a/engines/mads/nebular/nebular_scenes1.h b/engines/mads/nebular/nebular_scenes1.h index 1afa7fccc1..d8c9059846 100644 --- a/engines/mads/nebular/nebular_scenes1.h +++ b/engines/mads/nebular/nebular_scenes1.h @@ -8,12 +8,12 @@ * 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. diff --git a/engines/mads/nebular/nebular_scenes2.cpp b/engines/mads/nebular/nebular_scenes2.cpp index 94e30aa4f2..1cbd6f56ef 100644 --- a/engines/mads/nebular/nebular_scenes2.cpp +++ b/engines/mads/nebular/nebular_scenes2.cpp @@ -8,12 +8,12 @@ * 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 + * 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. @@ -152,7 +152,7 @@ void Scene201::enter() { int idx = _scene->_dynamicHotspots.add(NOUN_BIRDS, 209, _globals._sequenceIndexes[4], Common::Rect(0, 0, 0, 0)); _scene->_dynamicHotspots.setPosition(idx, Common::Point(186, 81), FACING_NORTH); - if ((_scene->_priorSceneId == 202) || (_scene->_priorSceneId == -1)) { + if ((_scene->_priorSceneId == 202) || (_scene->_priorSceneId == RETURNING_FROM_LOADING)) { _game._player._playerPos = Common::Point(165, 152); } else { _game._player._playerPos = Common::Point(223, 149); @@ -165,16 +165,16 @@ void Scene201::enter() { int sepChar = (_globals[kSexOfRex] == SEX_MALE) ? 't' : 'u'; // Guess values. What is the default value used by the compiler? int suffixNum = -1; - int abortTimers = -1; + int endTrigger = -1; switch(_globals[kTeleporterCommand]) { case 1: suffixNum = 3; - abortTimers = 76; + endTrigger = 76; _globals[kTeleporterUnderstood] = true; break; case 2: suffixNum = 1; - abortTimers = 77; + endTrigger = 77; break; case 3: _game._player._visible = true; @@ -183,12 +183,12 @@ void Scene201::enter() { break; case 4: suffixNum = 2; - abortTimers = 78; + endTrigger = 78; break; } _globals[kTeleporterCommand] = 0; if (suffixNum >= 0) - _scene->loadAnimation(formAnimName(sepChar, suffixNum), abortTimers); + _scene->loadAnimation(formAnimName(sepChar, suffixNum), endTrigger); } if ((_scene->_priorSceneId == 202) && (_globals[kMeteorologistStatus] == METEOROLOGIST_PRESENT) && !_scene->_roomChanged) { @@ -430,7 +430,7 @@ void Scene202::enter() { if (_scene->_priorSceneId == 201) { _game._player._playerPos = Common::Point(190, 91); _game._player._facing = FACING_SOUTH; - } else if (_scene->_priorSceneId != -2) { + } else if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) { _game._player._playerPos = Common::Point(178, 152); _game._player._facing = FACING_NORTH; } @@ -446,7 +446,7 @@ void Scene202::enter() { _game.loadQuoteSet(0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x62, 0x63, 0x64, 0x65, 0x66, 0x61, 0); _activeMsgFl = false; - if (_scene->_priorSceneId == -2) { + if (_scene->_priorSceneId == RETURNING_FROM_DIALOG) { if (_waitingMeteoFl) { _globals._sequenceIndexes[9] = _scene->_sequences.startCycle(_globals._spriteIndexes[9], false, 1); _game._player._visible = false; @@ -556,7 +556,7 @@ void Scene202::step() { case 90: _vm->_sound->command(41); _scene->_sequences.remove(_globals._sequenceIndexes[10]); - _globals._sequenceIndexes[9] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[9], true, 6, 1, 0, 0); + _globals._sequenceIndexes[9] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[9], true, 6, 1, 0, 0); _scene->_sequences.setPosition(_globals._sequenceIndexes[9], Common::Point(247, 82)); _scene->_sequences.setDepth(_globals._sequenceIndexes[9], 1); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[9], SEQUENCE_TRIGGER_EXPIRE, 0, 91); @@ -811,7 +811,7 @@ void Scene202::actions() { } else { _game._player._stepEnabled = false; _game._player._visible = false; - _globals._sequenceIndexes[7] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[7], false, 3, 2, 0, 0); + _globals._sequenceIndexes[7] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[7], false, 3, 2, 0, 0); _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[7]); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[7], SEQUENCE_TRIGGER_SPRITE, 6, 1); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[7], SEQUENCE_TRIGGER_EXPIRE, 0, 2); @@ -1044,7 +1044,7 @@ void Scene203::enter() { } else if (_scene->_priorSceneId == 209) { _game._player._playerPos = Common::Point(308, 117); _game._player._facing = FACING_WEST; - } else if (_scene->_priorSceneId != -2) { + } else if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) { _game._player._playerPos = Common::Point(155, 152); _game._player._facing = FACING_NORTH; } @@ -1152,8 +1152,9 @@ void Scene205::setup() { } Scene205::Scene205(MADSEngine *vm) : Scene2xx(vm) { - _lastFishTime = 0; - _chickenTime = 0; + _lastFishTime = _scene->_frameStartTime; + _chickenTime = _scene->_frameStartTime; + _beingKicked = false; _kernelMessage = -1; } @@ -1161,8 +1162,6 @@ Scene205::Scene205(MADSEngine *vm) : Scene2xx(vm) { void Scene205::synchronize(Common::Serializer &s) { Scene2xx::synchronize(s); - s.syncAsUint32LE(_lastFishTime); - s.syncAsUint32LE(_chickenTime); s.syncAsByte(_beingKicked); s.syncAsSint16LE(_kernelMessage); } @@ -1191,7 +1190,6 @@ void Scene205::enter() { _scene->_sequences.setDepth(_globals._sequenceIndexes[5], 11); if (!_game._visitedScenes._sceneRevisited) { - _lastFishTime = _scene->_frameStartTime; _globals._sequenceIndexes[6] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[6], false, 7, 1, 0, 0); idx = _scene->_dynamicHotspots.add(269, 13, _globals._sequenceIndexes[6], Common::Rect(0, 0, 0, 0)); _scene->_dynamicHotspots.setPosition(idx, Common::Point(49, 86), FACING_NORTH); @@ -1224,7 +1222,7 @@ void Scene205::enter() { Common::Rect(195, 99, 264, 134), 13, 2, 0xFDFC, 60, 108, 108, 109, 109, 110, 110, 111, 108, 0); - if (_scene->_priorSceneId != -2) + if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) _game._player._playerPos = Common::Point(99, 152); if (_globals[kSexOfRex] != SEX_MALE) { @@ -1448,8 +1446,9 @@ Scene207::Scene207(MADSEngine *vm) : Scene2xx(vm) { _eyeFl = false; _spiderHotspotId = -1; _vultureHotspotId = -1; - _spiderTime = 0; - _vultureTime = 0; + + _spiderTime = _game._player._priorTimer; + _vultureTime = _game._player._priorTimer; } void Scene207::synchronize(Common::Serializer &s) { @@ -1461,8 +1460,6 @@ void Scene207::synchronize(Common::Serializer &s) { s.syncAsSint32LE(_spiderHotspotId); s.syncAsSint32LE(_vultureHotspotId); - s.syncAsSint32LE(_spiderTime); - s.syncAsSint32LE(_vultureTime); } void Scene207::setup() { @@ -1500,8 +1497,7 @@ void Scene207::enter() { _spiderFl = (var2 & 1); if (_vultureFl) { - _globals._sequenceIndexes[1] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[1], false, 30, 0, 0, 400); - _vultureTime = _game._player._priorTimer; + _globals._sequenceIndexes[1] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[1], false, 30, 0, 0, 400); _vultureHotspotId = _scene->_dynamicHotspots.add(389, 13, _globals._sequenceIndexes[1], Common::Rect(0, 0, 0, 0)); _scene->_dynamicHotspots.setPosition(_vultureHotspotId, Common::Point(254, 94), FACING_WEST); } @@ -1509,7 +1505,6 @@ void Scene207::enter() { if (_spiderFl) { _globals._sequenceIndexes[4] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[4], false, 7, 1, 0, 0); _scene->_sequences.setAnimRange(_globals._sequenceIndexes[4], -1, -1); - _spiderTime = _game._player._priorTimer; _spiderHotspotId = _scene->_dynamicHotspots.add(333, 13, _globals._sequenceIndexes[4], Common::Rect(0, 0, 0, 0)); _scene->_dynamicHotspots.setPosition(_spiderHotspotId, Common::Point(59, 132), FACING_SOUTH); } @@ -1521,7 +1516,7 @@ void Scene207::enter() { } else if (_scene->_priorSceneId == 214) { _game._player._playerPos = Common::Point(164, 117); _game._player._facing = FACING_SOUTH; - } else if (_scene->_priorSceneId != -2) { + } else if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) { _game._player._playerPos = Common::Point(305, 131); } @@ -1549,11 +1544,17 @@ void Scene207::moveSpider() { } void Scene207::step() { - if (!_vultureFl) - moveVulture(); + Player &player = _game._player; + + if (_vultureFl) { + if (((int32)player._priorTimer - _vultureTime) > 1700) + moveVulture(); + } - if (_spiderFl) - moveSpider(); + if (_spiderFl) { + if (((int32)player._priorTimer - _spiderTime) > 800) + moveSpider(); + } if (_game._trigger == 70) { _globals._sequenceIndexes[6] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[6], false, 10, 0, 0, 0); @@ -1685,18 +1686,18 @@ void Scene208::updateTrap() { } switch (_globals[kLeavesStatus]) { - case 0: { + case LEAVES_ON_GROUND: { _globals._sequenceIndexes[2] = _scene->_sequences.startCycle(_globals._spriteIndexes[2], false, 1); _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 15); int idx = _scene->_dynamicHotspots.add(NOUN_PILE_OF_LEAVES, VERB_WALKTO, _globals._sequenceIndexes[2], Common::Rect(0, 0, 0, 0)); _scene->_dynamicHotspots.setPosition(idx, Common::Point(60, 152), FACING_NORTH); } break; - case 2: { + case LEAVES_ON_TRAP: { _scene->_sequences.setDepth(_globals._sequenceIndexes[3], 15); _globals._sequenceIndexes[3] = _scene->_sequences.startCycle(_globals._spriteIndexes[3], false, 1); _scene->_hotspots.activate(NOUN_DEEP_PIT, false); - int idx = _scene->_dynamicHotspots.add(NOUN_LEAF_COVERED_PIT, VERB_WALKTO, _globals._sequenceIndexes[2], Common::Rect(0, 0, 0, 0)); + int idx = _scene->_dynamicHotspots.add(NOUN_LEAF_COVERED_PIT, VERB_WALKTO, _globals._sequenceIndexes[3], Common::Rect(0, 0, 0, 0)); _scene->_dynamicHotspots.setPosition(idx, Common::Point(100, 146), FACING_NORTH); _scene->_dynamicHotspots[idx]._articleNumber = PREP_ON; } @@ -1727,7 +1728,7 @@ void Scene208::enter() { } else if (_scene->_priorSceneId == 209) { _game._player._playerPos = Common::Point(307, 123); _game._player._facing = FACING_WEST; - } else if (_scene->_priorSceneId != -2) { + } else if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) { _game._player._playerPos = Common::Point(162, 149); _game._player._facing = FACING_NORTH; } @@ -1745,7 +1746,8 @@ void Scene208::enter() { } void Scene208::step() { - if (_boundingFl && (_rhotundaTime <= _scene->_activeAnimation->getCurrentFrame())) { + if (_boundingFl && _scene->_activeAnimation && + (_rhotundaTime <= _scene->_activeAnimation->getCurrentFrame())) { _rhotundaTime = _scene->_activeAnimation->getCurrentFrame(); if (_rhotundaTime == 125) @@ -1794,7 +1796,6 @@ void Scene208::preActions() { } void Scene208::subAction(int mode) { - switch (_game._trigger) { case 0: { _game._player._stepEnabled = false; @@ -1802,21 +1803,21 @@ void Scene208::subAction(int mode) { _globals._sequenceIndexes[5] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[5], false, 6, 1, 0, 0); _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[5]); - int abortVal; + int endTrigger; if ((mode == 1) || (mode == 2)) - abortVal = 1; + endTrigger = 1; else - abortVal = 2; + endTrigger = 2; - _scene->_sequences.addSubEntry(_globals._sequenceIndexes[5], SEQUENCE_TRIGGER_EXPIRE, 0, abortVal); + _scene->_sequences.addSubEntry(_globals._sequenceIndexes[5], SEQUENCE_TRIGGER_EXPIRE, 0, endTrigger); } break; case 1: { - int oldVal = _globals._sequenceIndexes[5]; - _globals._sequenceIndexes[5] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[6], false, 12, 3, 0, 0); + int oldSeq = _globals._sequenceIndexes[5]; + _globals._sequenceIndexes[5] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[5], false, 12, 3, 0, 0); _scene->_sequences.setAnimRange(_globals._sequenceIndexes[5], 3, 4); _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[5]); - _scene->_sequences.updateTimeout(_globals._sequenceIndexes[5], oldVal); + _scene->_sequences.updateTimeout(_globals._sequenceIndexes[5], oldSeq); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[5], SEQUENCE_TRIGGER_EXPIRE, 0, 2); _vm->_sound->command(20); } @@ -2157,7 +2158,7 @@ void Scene209::handleLookRight() { switch (_game._trigger) { case 151: _scene->_sequences.remove(_globals._sequenceIndexes[3]); - _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 8, 2, 0, 0); + _globals._sequenceIndexes[3] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[3], false, 8, 2, 0, 0); _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 8, 14); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 152); break; @@ -2224,7 +2225,7 @@ void Scene209::handleGetBinoculars() { case 162: { int oldIdx = _globals._sequenceIndexes[3]; - _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 8, 6, 0, 0); + _globals._sequenceIndexes[3] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[3], false, 8, 6, 0, 0); _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 23, 25); _scene->_sequences.updateTimeout(_globals._sequenceIndexes[3], oldIdx); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 163); @@ -2233,7 +2234,7 @@ void Scene209::handleGetBinoculars() { case 163: { int oldIdx = _globals._sequenceIndexes[3]; - _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 8, 0, 0, 0); + _globals._sequenceIndexes[3] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[3], false, 8, 0, 0, 0); _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 23, 24); _scene->_sequences.updateTimeout(_globals._sequenceIndexes[3], oldIdx); _scene->_sequences.addTimer(8, 164); @@ -2257,7 +2258,7 @@ void Scene209::handleBinocularBlink() { case 167: { int oldIdx = _globals._sequenceIndexes[3]; _scene->_sequences.remove(_globals._sequenceIndexes[3]); - _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 8, 2, 0, 0); + _globals._sequenceIndexes[3] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[3], false, 8, 2, 0, 0); _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 23, 25); _scene->_sequences.updateTimeout(_globals._sequenceIndexes[3], oldIdx); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 168); @@ -2266,7 +2267,7 @@ void Scene209::handleBinocularBlink() { case 168: { int oldIdx = _globals._sequenceIndexes[3]; - _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 8, 0, 0, 0); + _globals._sequenceIndexes[3] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[3], false, 8, 0, 0, 0); _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 23, 24); _scene->_sequences.updateTimeout(_globals._sequenceIndexes[3], oldIdx); _scene->_sequences.addTimer(30, 169); @@ -2286,7 +2287,7 @@ void Scene209::handleBinocularScan() { case 171: { int oldIdx = _globals._sequenceIndexes[3]; _scene->_sequences.remove(_globals._sequenceIndexes[3]); - _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 12, 2, 0, 0); + _globals._sequenceIndexes[3] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[3], false, 12, 2, 0, 0); _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 43, 45); _scene->_sequences.updateTimeout(_globals._sequenceIndexes[3], oldIdx); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 172); @@ -2298,10 +2299,10 @@ void Scene209::handleBinocularScan() { int randAction = _vm->getRandomNumber(1,2); switch (randAction) { case 1: - _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 12, 2, 0, 0); + _globals._sequenceIndexes[3] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[3], false, 12, 2, 0, 0); break; case 2: - _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 12, 4, 0, 0); + _globals._sequenceIndexes[3] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[3], false, 12, 4, 0, 0); break; } _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 23, 25); @@ -2312,7 +2313,7 @@ void Scene209::handleBinocularScan() { case 173: { int oldIdx = _globals._sequenceIndexes[3]; - _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 12, 2, 0, 0); + _globals._sequenceIndexes[3] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[3], false, 12, 2, 0, 0); _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 26, 30); _scene->_sequences.updateTimeout(_globals._sequenceIndexes[3], oldIdx); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 174); @@ -2321,7 +2322,7 @@ void Scene209::handleBinocularScan() { case 174: { int oldIdx = _globals._sequenceIndexes[3]; - _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 12, 0, 0, 0); + _globals._sequenceIndexes[3] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[3], false, 12, 0, 0, 0); _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 23, 24); _scene->_sequences.updateTimeout(_globals._sequenceIndexes[3], oldIdx); _scene->_sequences.addTimer(60, 175); @@ -2407,7 +2408,7 @@ void Scene209::handleTongue() { case 185: { _vm->_sound->command(18); int oldIdx = _globals._sequenceIndexes[3]; - _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 6, 20, 0, 0); + _globals._sequenceIndexes[3] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[3], false, 6, 20, 0, 0); _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 38, 39); _scene->_sequences.updateTimeout(_globals._sequenceIndexes[3], oldIdx); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 186); @@ -2527,7 +2528,7 @@ void Scene209::handleMonkeyEating() { case 200: { int oldIdx = _globals._sequenceIndexes[4]; - _globals._sequenceIndexes[4] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[4], false, 10, 10, 0, 0); + _globals._sequenceIndexes[4] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[4], false, 10, 10, 0, 0); _scene->_sequences.setAnimRange(_globals._sequenceIndexes[4], 15, 16); _scene->_sequences.updateTimeout(_globals._sequenceIndexes[4], oldIdx); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[4], SEQUENCE_TRIGGER_EXPIRE, 0, 201); @@ -2556,14 +2557,14 @@ void Scene209::handleMonkeyEating() { case 204: _scene->_sequences.remove(_globals._sequenceIndexes[4]); - _globals._sequenceIndexes[4] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[4], false, 10, 8, 0, 0); + _globals._sequenceIndexes[4] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[4], false, 10, 8, 0, 0); _scene->_sequences.setAnimRange(_globals._sequenceIndexes[4], 18, 19); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[4], SEQUENCE_TRIGGER_EXPIRE, 0, 205); break; case 205: { int oldIdx = _globals._sequenceIndexes[4]; - _globals._sequenceIndexes[4] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[4], false, 10, 8, 0, 0); + _globals._sequenceIndexes[4] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[4], false, 10, 8, 0, 0); _scene->_sequences.setAnimRange(_globals._sequenceIndexes[4], 20, 21); _scene->_sequences.updateTimeout(_globals._sequenceIndexes[4], oldIdx); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[4], SEQUENCE_TRIGGER_EXPIRE, 0, 206); @@ -2588,7 +2589,7 @@ void Scene209::handleMonkeyEating() { _scene->_kernelMessages.setQuoted(msgIndex, 4, true); int oldIdx = _globals._sequenceIndexes[4]; - _globals._sequenceIndexes[4] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[4], false, 15, 4, 0, 0); + _globals._sequenceIndexes[4] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[4], false, 15, 4, 0, 0); _scene->_sequences.setAnimRange(_globals._sequenceIndexes[4], 26, 27); _scene->_sequences.updateTimeout(_globals._sequenceIndexes[4], oldIdx); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[4], SEQUENCE_TRIGGER_EXPIRE, 0, 208); @@ -2598,7 +2599,7 @@ void Scene209::handleMonkeyEating() { case 208: { _scene->_kernelMessages.add(Common::Point(180, 39), 0xFDFC, 0, 0, 90, _game.getQuote(131)); int oldIdx = _globals._sequenceIndexes[4]; - _globals._sequenceIndexes[4] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[4], false, 10, 4, 0, 0); + _globals._sequenceIndexes[4] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[4], false, 10, 4, 0, 0); _scene->_sequences.setAnimRange(_globals._sequenceIndexes[4], 28, 29); _scene->_sequences.updateTimeout(_globals._sequenceIndexes[4], oldIdx); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[4], SEQUENCE_TRIGGER_EXPIRE, 0, 209); @@ -2837,6 +2838,7 @@ void Scene209::enter() { _globals._spriteIndexes[5] = _scene->_sprites.addSprites(formAnimName('m', 3)); _globals._spriteIndexes[6] = _scene->_sprites.addSprites(formAnimName('m', 6)); _globals._spriteIndexes[7] = _scene->_sprites.addSprites(formAnimName('m', 8)); + _globals._spriteIndexes[11] = _scene->_sprites.addSprites("*RXMBD_2"); _game.loadQuoteSet(0x82, 0x83, 0x84, 0x9C, 0x97, 0x95, 0x99, 0x9E, 0x98, 0x9B, 0xA0, 0x96, 0x9F, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x91, 0x92, 0x93, 0x94, 0x89, 0x85, 0x8A, 0x86, 0x87, 0x88, 0); @@ -2854,7 +2856,7 @@ void Scene209::enter() { if (_scene->_priorSceneId == 208) { _game._player._playerPos = Common::Point(11, 121); _game._player._facing = FACING_EAST; - } else if (_scene->_priorSceneId != -2) { + } else if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) { _game._player._playerPos = Common::Point(28, 121); _game._player._facing = FACING_SOUTH; } @@ -3438,10 +3440,9 @@ void Scene209::actions() { if (_action.isAction(VERB_TAKE, NOUN_PLANT_STALK) && (_game._trigger || _game._objects.isInRoom(OBJ_PLANT_STALK))) { switch (_game._trigger) { case 0: - _globals._spriteIndexes[11] = _scene->_sprites.addSprites("*RXMBD_2"); _game._player._stepEnabled = false; _game._player._visible = false; - _globals._sequenceIndexes[11] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[11], false, 3, 2, 0, 0); + _globals._sequenceIndexes[11] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[11], false, 3, 2, 0, 0); _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[11]); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[11], SEQUENCE_TRIGGER_SPRITE, 4, 1); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[11], SEQUENCE_TRIGGER_EXPIRE, 0, 2); @@ -3460,7 +3461,6 @@ void Scene209::actions() { break; case 3: - _scene->_sprites.remove(_globals._spriteIndexes[11]); break; } _action._inProgress = false; @@ -3473,7 +3473,7 @@ void Scene209::actions() { _globals._spriteIndexes[10] = _scene->_sprites.addSprites("*RXMBD_8"); _game._player._stepEnabled = false; _game._player._visible = false; - _globals._sequenceIndexes[10] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[10], false, 3, 2, 0, 0); + _globals._sequenceIndexes[10] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[10], false, 3, 2, 0, 0); _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[10]); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[10], SEQUENCE_TRIGGER_SPRITE, 4, 1); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[10], SEQUENCE_TRIGGER_EXPIRE, 0, 2); @@ -4173,7 +4173,7 @@ void Scene210::enter() { _game._player._playerPos = Common::Point(168, 128); _game._player._facing = FACING_SOUTH; _globals[kCurtainOpen] = true; - } else if (_scene->_priorSceneId != -2) + } else if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) _game._player._playerPos = Common::Point(308, 132); if (!_globals[kCurtainOpen]) { @@ -4210,7 +4210,7 @@ void Scene210::enter() { _twinkleAnimationType = 0; _twinklesCurrentFrame = 0; - if (_scene->_priorSceneId != -2) { + if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) { _shouldMoveHead = false; _shouldFaceRex = false; _shouldTalk = false; @@ -4647,7 +4647,7 @@ void Scene211::enter() { _game._player._visible = false; _scene->loadAnimation(formAnimName('A', -1), 100); _scene->_activeAnimation->setCurrentFrame(169); - } else if (_scene->_priorSceneId != -2) { + } else if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) { _game._player._playerPos = Common::Point(310, 31); _game._player._facing = FACING_SOUTHWEST; } @@ -4905,7 +4905,7 @@ void Scene212::enter() { if (_scene->_priorSceneId == 208) { _game._player._playerPos = Common::Point(195, 85); _game._player._facing = FACING_SOUTH; - } else if (_scene->_priorSceneId != -2) { + } else if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) { _game._player._playerPos = Common::Point(67, 117); _game._player._facing = FACING_NORTHEAST; } @@ -5061,7 +5061,7 @@ void Scene214::enter() { _scene->_hotspots.activate(NOUN_BLOWGUN, false); } - if (_scene->_priorSceneId != -2) + if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) _game._player._playerPos = Common::Point(191, 152); sceneEntrySound(); @@ -5257,7 +5257,7 @@ void Scene215::enter() { _game._player._stepEnabled = false; _globals._sequenceIndexes[3] = _scene->_sequences.startCycle(_globals._spriteIndexes[3], false, 1); _scene->_sequences.addTimer(120, 70); - } else if (_scene->_priorSceneId != -2) { + } else if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) { _game._player._playerPos = Common::Point(204, 152); _game._player._facing = FACING_NORTH; } @@ -5290,7 +5290,7 @@ void Scene215::actions() { if (_globals[kSexOfRex] == REX_MALE) { _game._player._visible = false; _game._player._stepEnabled = false; - _globals._sequenceIndexes[2] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[2], false, 6, 2, 0, 0); + _globals._sequenceIndexes[2] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[2], false, 6, 2, 0, 0); _scene->_sequences.setAnimRange(_globals._sequenceIndexes[2], 1, 4); _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[2]); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_LOOP, 0, 1); diff --git a/engines/mads/nebular/nebular_scenes2.h b/engines/mads/nebular/nebular_scenes2.h index c860db9470..0ea4702eea 100644 --- a/engines/mads/nebular/nebular_scenes2.h +++ b/engines/mads/nebular/nebular_scenes2.h @@ -8,12 +8,12 @@ * 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. diff --git a/engines/mads/nebular/nebular_scenes3.cpp b/engines/mads/nebular/nebular_scenes3.cpp index bcedf95a27..5a6edbf995 100644 --- a/engines/mads/nebular/nebular_scenes3.cpp +++ b/engines/mads/nebular/nebular_scenes3.cpp @@ -8,12 +8,12 @@ * 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 + * 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. @@ -370,7 +370,7 @@ void Scene304::enter() { _globals._spriteIndexes[2] = _scene->_sprites.addSprites(formAnimName('a', 1)); _globals._spriteIndexes[3] = _scene->_sprites.addSprites(formAnimName('b', 0)); - _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 150, 0, 3, 0); + _globals._sequenceIndexes[3] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[3], false, 150, 0, 3, 0); _scene->_sequences.setDepth(_globals._sequenceIndexes[3], 2); _vm->_palette->setEntry(252, 45, 63, 45); _vm->_palette->setEntry(253, 20, 45, 20); @@ -521,11 +521,11 @@ void Scene307::setup() { setPlayerSpritesPrefix(); setAAName(); _scene->addActiveVocab(NOUN_AIR_VENT); - _scene->addActiveVocab(NOUN_CLIMB_INTO); + _scene->addActiveVocab(VERB_CLIMB_INTO); } void Scene307::handleRexDialog(int quote) { - Common::String curQuote = _game.getQuote(_action._activeAction._verbId); + Common::String curQuote = _game.getQuote(quote); if (_vm->_font->getWidth(curQuote, _scene->_textSpacing) > 200) { Common::String subQuote1; _game.splitQuote(curQuote, subQuote1, _subQuote2); @@ -769,7 +769,7 @@ void Scene307::enter() { _dialog2.write(0x11E, true); - if (_scene->_priorSceneId == -2) { + if (_scene->_priorSceneId == RETURNING_FROM_DIALOG) { if (_grateOpenedFl) _vm->_sound->command(10); else @@ -953,7 +953,7 @@ void Scene307::actions() { case 2: { int oldIdx = _globals._sequenceIndexes[5]; - _globals._sequenceIndexes[5] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[5], false, 12, 6, 0, 0); + _globals._sequenceIndexes[5] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[5], false, 12, 6, 0, 0); _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[5]); _scene->_sequences.setAnimRange(_globals._sequenceIndexes[5], 2, 3); _scene->_sequences.updateTimeout(_globals._sequenceIndexes[5], oldIdx); @@ -992,7 +992,7 @@ void Scene307::actions() { _scene->_sequences.remove(_globals._sequenceIndexes[5]); _grateOpenedFl = true; _scene->_hotspots.activate(17, false); - int idx = _scene->_dynamicHotspots.add(17, NOUN_CLIMB_INTO, -1, Common::Rect(117, 67, 117 + 19, 67 + 13)); + int idx = _scene->_dynamicHotspots.add(17, VERB_CLIMB_INTO, -1, Common::Rect(117, 67, 117 + 19, 67 + 13)); int hotspotId = _scene->_dynamicHotspots.setPosition(idx, Common::Point(129, 104), FACING_NORTH); _scene->_dynamicHotspots.setCursor(hotspotId, CURSOR_GO_UP); _game._objects.removeFromInventory(OBJ_SCALPEL, NOWHERE); @@ -1245,7 +1245,7 @@ void Scene308::step() { switch (_game._trigger) { case 70: { _scene->_sequences.remove(_globals._sequenceIndexes[3]); - _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 18, 9, 0, 0); + _globals._sequenceIndexes[3] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[3], false, 18, 9, 0, 0); _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 2, 3); _scene->_sequences.setDepth(_globals._sequenceIndexes[3], 9); _scene->_kernelMessages.reset(); @@ -1266,7 +1266,7 @@ void Scene308::step() { case 72: _scene->_sequences.remove(_globals._sequenceIndexes[3]); - _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 20, 5, 0, 0); + _globals._sequenceIndexes[3] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[3], false, 20, 5, 0, 0); _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 3, 4); _scene->_sequences.setDepth(_globals._sequenceIndexes[3], 9); _scene->_kernelMessages.reset(); @@ -1284,7 +1284,7 @@ void Scene308::step() { case 74: { _scene->_sequences.remove(_globals._sequenceIndexes[3]); - _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 20, 8, 0, 0); + _globals._sequenceIndexes[3] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[3], false, 20, 8, 0, 0); _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 6, 7); _scene->_sequences.setDepth(_globals._sequenceIndexes[3], 9); _scene->_kernelMessages.reset(); @@ -1306,7 +1306,7 @@ void Scene308::step() { case 76: { int seqIdx = _globals._sequenceIndexes[3]; - _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 26, 0, 0, 0); + _globals._sequenceIndexes[3] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[3], false, 26, 0, 0, 0); _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 2, 3); _scene->_sequences.setDepth(_globals._sequenceIndexes[3], 9); _scene->_kernelMessages.reset(); @@ -1441,7 +1441,7 @@ void Scene309::step() { case 70: { int idx = _scene->_dynamicHotspots.add(689, 690, _globals._sequenceIndexes[3], Common::Rect(0, 0, 0, 0)); _scene->_dynamicHotspots.setPosition(idx, Common::Point(142, 146), FACING_NORTHEAST); - _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 7, 4, 0, 0); + _globals._sequenceIndexes[3] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[3], false, 7, 4, 0, 0); _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 2, 3); _scene->_sequences.setDepth(_globals._sequenceIndexes[3], 11); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 71); @@ -1462,7 +1462,7 @@ void Scene309::step() { case 72: { int _oldIdx = _globals._sequenceIndexes[3]; - _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 7, 8, 0, 0); + _globals._sequenceIndexes[3] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[3], false, 7, 8, 0, 0); _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 8, 11); _scene->_sequences.setDepth(_globals._sequenceIndexes[3], 11); _scene->_sequences.updateTimeout(_globals._sequenceIndexes[3], _oldIdx); @@ -1484,7 +1484,7 @@ void Scene309::step() { case 74: { int _oldIdx = _globals._sequenceIndexes[3]; - _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 7, 6, 0, 0); + _globals._sequenceIndexes[3] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[3], false, 7, 6, 0, 0); _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 21, 23); _scene->_sequences.setDepth(_globals._sequenceIndexes[3], 11); _scene->_sequences.updateTimeout(_globals._sequenceIndexes[3], _oldIdx); @@ -1494,7 +1494,7 @@ void Scene309::step() { case 75: { int _oldIdx = _globals._sequenceIndexes[3]; - _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 12, 6, 0, 0); + _globals._sequenceIndexes[3] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[3], false, 12, 6, 0, 0); _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 24, 25); _scene->_sequences.updateTimeout(_globals._sequenceIndexes[3], _oldIdx); _scene->_sequences.setDepth(_globals._sequenceIndexes[3], 11); @@ -1513,7 +1513,7 @@ void Scene309::step() { break; case 77: { - _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 90, 0, 0, 0); + _globals._sequenceIndexes[3] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[3], false, 90, 0, 0, 0); _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 29, 30); _scene->_sequences.setDepth(_globals._sequenceIndexes[3], 11); int idx = _scene->_kernelMessages.add(Common::Point(15, 46), 0xFDFC, 0, 0, 120, _game.getQuote(247)); @@ -1618,7 +1618,7 @@ void Scene311::enter() { else if (_scene->_priorSceneId == 320) { _game._player._playerPos = Common::Point(129, 113); _game._player._facing = FACING_SOUTH; - } else if (_scene->_priorSceneId != -2) { + } else if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) { _game._player._visible = false; _game._player._stepEnabled = false; _scene->loadAnimation(formAnimName('a', -1), 70); @@ -1749,7 +1749,7 @@ void Scene311::actions() { else if (_checkGuardFl) { _checkGuardFl = false; _scene->_kernelMessages.reset(); - _scene->_kernelMessages.addQuote(0xFA, 120, 0); + _scene->_kernelMessages.addQuote(250, 0, 240); } else if (_action.isAction(VERB_SIT_AT, NOUN_DESK)) _scene->_nextSceneId = 320; else if (_action.isAction(VERB_CLIMB_INTO, NOUN_AIR_VENT)) { @@ -1896,7 +1896,7 @@ void Scene313::enter() { } else if (_scene->_priorSceneId == 388) { _game._player._playerPos = Common::Point(199, 70); _game._player._facing = FACING_WEST; - } else if (_scene->_priorSceneId != -2) { + } else if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) { _game._player._playerPos = Common::Point(234, 70); _game._player._facing = FACING_WEST; } @@ -1965,7 +1965,7 @@ void Scene316::handleRexInGrate() { case 1: _scene->_sequences.setDone(_globals._sequenceIndexes[4]); - _globals._sequenceIndexes[4] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[4], false, 12, 3, 0, 0); + _globals._sequenceIndexes[4] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[4], false, 12, 3, 0, 0); _scene->_sequences.setAnimRange(_globals._sequenceIndexes[4], 2, 3); _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[4]); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[4], SEQUENCE_TRIGGER_EXPIRE, 0, 2); @@ -2085,7 +2085,7 @@ void Scene316::handleRoxInGrate() { case 1: _scene->_sequences.setDone(_globals._sequenceIndexes[5]); - _globals._sequenceIndexes[5] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[5], false, 17, 3, 0, 0); + _globals._sequenceIndexes[5] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[5], false, 17, 3, 0, 0); _scene->_sequences.setAnimRange(_globals._sequenceIndexes[5], 2, 3); _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[5]); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[5], SEQUENCE_TRIGGER_EXPIRE, 0, 2); @@ -2215,7 +2215,7 @@ void Scene316::enter() { _globals._sequenceIndexes[1] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[spriteIdx], false, 6, 1, 0, 0); _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 2); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[1], SEQUENCE_TRIGGER_EXPIRE, 0, 60); - } else if (_scene->_priorSceneId != -2) + } else if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) _game._player._playerPos = Common::Point(291, 126); sceneEntrySound(); @@ -2523,7 +2523,7 @@ void Scene318::handleDialog() { case 0x19C: case 0x19D: _scene->_sequences.remove(_globals._sequenceIndexes[2]); - _globals._sequenceIndexes[2] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[2], false, 8, 1, 0, 0); + _globals._sequenceIndexes[2] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[2], false, 8, 1, 0, 0); _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 1); _scene->_sequences.setPosition(_globals._sequenceIndexes[2], Common::Point(142, 121)); _scene->_sequences.setAnimRange(_globals._sequenceIndexes[2], 6, 8); @@ -2581,6 +2581,12 @@ void Scene318::handleInternDialog(int quoteId, int quoteNum, uint32 timeout) { _scene->_kernelMessages.reset(); _internTalkingFl = true; + // WORKAROUND: In case the player launches multiple talk selections with the + // intern before previous ones have finished, take care of removing any + int seqIndex; + while ((seqIndex = _scene->_sequences.findByTrigger(63)) != -1) + _scene->_sequences.remove(seqIndex); + for (int i = 0; i < quoteNum; i++) { _game._triggerSetupMode = SEQUENCE_TRIGGER_DAEMON; _scene->_sequences.addTimer(180, 63); @@ -2611,7 +2617,7 @@ void Scene318::enter() { if (_scene->_priorSceneId == 357) _game._player._playerPos = Common::Point(15, 110); - else if (_scene->_priorSceneId != -2) + else if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) _game._player._playerPos = Common::Point(214, 152); _dialog1.setup(0x47, 0x191, 0x192, 0x193, 0x194, 0x195, 0x196, 0x197, 0x198, 0x199, 0x19A, 0x19B, 0x19C, 0x19D, 0); @@ -2632,7 +2638,7 @@ void Scene318::enter() { _lastFrame = 0; _scene->_hotspots.activate(NOUN_INTERN, false); - if (_scene->_priorSceneId != -2) { + if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) { _dialogFl = false; _internWalkingFl = false; _counter= 0; @@ -2649,7 +2655,8 @@ void Scene318::enter() { 0x1C8, 0x1C9, 0x1CA, 0x1CB, 0x1CC, 0x1CD, 0x1CE, 0x1CF, 0x1D0, 0x1D1, 0x1D2, 0x1D3, 0x190, 0x19D, 0); - if ((_scene->_priorSceneId== -2) || (((_scene->_priorSceneId == 318) || (_scene->_priorSceneId == -1)) && (!_globals[kAfterHavoc]))) { + if ((_scene->_priorSceneId == RETURNING_FROM_DIALOG) || (((_scene->_priorSceneId == 318) || + (_scene->_priorSceneId == RETURNING_FROM_LOADING)) && (!_globals[kAfterHavoc]))) { if (!_globals[kAfterHavoc]) { _game._player._visible = false; _globals._spriteIndexes[2] = _scene->_sprites.addSprites(formAnimName('g', -1)); @@ -2883,7 +2890,7 @@ void Scene318::actions() { case 0: _game._player._stepEnabled = false; _scene->_sequences.remove(_globals._sequenceIndexes[2]); - _globals._sequenceIndexes[2] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[2], false, 8, 2, 0, 80); + _globals._sequenceIndexes[2] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[2], false, 8, 2, 0, 80); _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 1); _scene->_sequences.setPosition(_globals._sequenceIndexes[2], Common::Point(142, 121)); _scene->_sequences.setAnimRange(_globals._sequenceIndexes[2], 2, 5); @@ -3113,7 +3120,7 @@ void Scene319::enter() { _dialog2.setup(0x44, 0x171, 0x172, 0x173, 0x174, 0x175, 0x176, 0); _dialog3.setup(0x45, 0x17D, 0x17E, 0x17F, 0x180, 0x181, 0x182, 0x183, 0); - if (_scene->_priorSceneId != -2) { + if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) { _dialog1.set(0x165, 0x166, 0x167, 0x168, 0); _dialog2.set(0x171, 0x172, 0x173, 0x174, 0); _dialog3.set(0x17D, 0x17E, 0x17F, 0x180, 0); @@ -3136,7 +3143,7 @@ void Scene319::enter() { _scene->loadAnimation(formAnimName('b', 0)); - if (_scene->_priorSceneId != -2) { + if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) { _animMode = 1; _nextAction1 = 2; _nextAction2 = 2; @@ -3306,7 +3313,7 @@ void Scene319::step() { switch (_game._trigger) { case 70: - case 71: + case 71: { _animMode = 1; _nextAction1 = _nextAction2; _animFrame = 0; @@ -3329,7 +3336,14 @@ void Scene319::step() { _scene->_sequences.updateTimeout(_globals._sequenceIndexes[i], oldIdx); } _scene->_sequences.addSubEntry(_globals._sequenceIndexes[0], SEQUENCE_TRIGGER_EXPIRE, 0, 74); + + // WORKAROUND: This fixes the game sometimes going into an endless waiting + // loop even after the doctor has finished hitting Rex. Note sure if it's due + // to a bug in room script or in the engine, but this at least fixes it + int seqIndex = _scene->_sequences.findByTrigger(2); + _scene->_sequences[seqIndex]._doneFlag = false; break; + } case 72: _vm->_palette->setColorFlags(0xFF, 0, 0); @@ -3588,7 +3602,7 @@ void Scene320::setLeftView(int view) { _scene->_sequences.remove(_globals._sequenceIndexes[0]); if (view != 10) { - _globals._sequenceIndexes[0] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[view], false, 6, 0, 0, 18); + _globals._sequenceIndexes[0] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[view], false, 6, 0, 0, 18); _scene->_sequences.setDepth(_globals._sequenceIndexes[0], 0); if (!_blinkFl) _scene->_sequences.setAnimRange(_globals._sequenceIndexes[0], 2, 2); @@ -3752,7 +3766,7 @@ void Scene320::actions() { case 0: _game._player._stepEnabled = false; handleButtons(); - _globals._sequenceIndexes[18] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[18], _flippedFl, 4, 2, 0, 0); + _globals._sequenceIndexes[18] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[18], _flippedFl, 4, 2, 0, 0); _scene->_sequences.setScale(_globals._sequenceIndexes[18], 60); _scene->_sequences.setPosition(_globals._sequenceIndexes[18], Common::Point(_posX, 170)); _scene->_sequences.setDepth(_globals._sequenceIndexes[18], 0); @@ -3825,7 +3839,7 @@ void Scene320::actions() { else if (_action.isAction(VERB_LOOK, NOUN_DOUGHNUT)) _vm->_dialogs->show(32006); else if (_action.isAction(VERB_LOOK, NOUN_MAGAZINE)) - _vm->_dialogs->show(32006); + _vm->_dialogs->show(32007); else if (_action.isAction(VERB_LOOK, NOUN_PAPER_FOOTBALL)) _vm->_dialogs->show(32008); else if (_action.isAction(VERB_LOOK, NOUN_NEWSPAPER)) @@ -3975,7 +3989,7 @@ void Scene351::enter() { if (_scene->_priorSceneId == 352) _game._player._playerPos = Common::Point(148, 152); - else if (_scene->_priorSceneId != -2) { + else if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) { _game._player._playerPos = Common::Point(207, 81); _game._player._facing = FACING_NORTH; } @@ -4053,12 +4067,12 @@ void Scene351::actions() { _game._player._stepEnabled = false; _game._player._visible = false; if (_globals[kSexOfRex] == REX_FEMALE) { - _globals._sequenceIndexes[2] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[2], false, 5, 2, 0, 0); + _globals._sequenceIndexes[2] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[2], false, 5, 2, 0, 0); _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[2]); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_SPRITE, 5, 1); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 2); } else { - _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 5, 2, 0, 0); + _globals._sequenceIndexes[3] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[3], false, 5, 2, 0, 0); _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[3]); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_SPRITE, 6, 1); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 2); @@ -4152,7 +4166,7 @@ void Scene352::setup() { void Scene352::putArmDown(bool corridorExit, bool doorwayExit) { switch (_game._trigger) { case 0: - _scene->_kernelMessages.add(Common::Point(0, 0), 0x1110, 34, 0, 60, _game.getQuote(0xFF)); + _scene->_kernelMessages.add(Common::Point(0, 0), 0x1110, 34, 0, 120, _game.getQuote(0xFF)); _scene->_sequences.addTimer(48, 1); break; @@ -4160,12 +4174,12 @@ void Scene352::putArmDown(bool corridorExit, bool doorwayExit) { _game._player._stepEnabled = false; _game._player._visible = false; if (_globals[kSexOfRex] == REX_FEMALE) { - _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 5, 2, 0, 0); + _globals._sequenceIndexes[3] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[3], false, 5, 2, 0, 0); _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[3]); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_SPRITE, 5, 2); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 3); } else { - _globals._sequenceIndexes[4] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[4], false, 5, 2, 0, 0); + _globals._sequenceIndexes[4] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[4], false, 5, 2, 0, 0); _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[4]); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[4], SEQUENCE_TRIGGER_SPRITE, 6, 2); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[4], SEQUENCE_TRIGGER_EXPIRE, 0, 3); @@ -4197,7 +4211,6 @@ void Scene352::putArmDown(bool corridorExit, bool doorwayExit) { case 4: _game._player.walk(Common::Point(116, 107), FACING_NORTH); - _game._player._stepEnabled = true; _mustPutArmDownFl = false; _scene->_sequences.addTimer(180, 5); _leaveRoomFl = true; @@ -4261,7 +4274,7 @@ void Scene352::enter() { _vaultOpenFl = false; - if (_scene->_priorSceneId != -2) { + if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) { _mustPutArmDownFl = false; if (!_game._visitedScenes._sceneRevisited) _globals[kHaveYourStuff] = false; @@ -4276,7 +4289,7 @@ void Scene352::enter() { if (_scene->_priorSceneId == 353) _game._player._playerPos = Common::Point(171, 155); - else if (_scene->_priorSceneId != -2) + else if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) _game._player._playerPos = Common::Point(116, 107); sceneEntrySound(); @@ -4305,7 +4318,7 @@ void Scene352::preActions() { _game._player._stepEnabled = false; _scene->_sequences.remove(_commonSequenceIdx); _vm->_sound->command(20); - _commonSequenceIdx = _scene->_sequences.startReverseCycle(_commonSpriteIndex, false, 6, 1, 0, 0); + _commonSequenceIdx = _scene->_sequences.addReverseSpriteCycle(_commonSpriteIndex, false, 6, 1, 0, 0); _scene->_sequences.addSubEntry(_commonSequenceIdx, SEQUENCE_TRIGGER_EXPIRE, 0, 1); _scene->_sequences.setDepth(_commonSequenceIdx, 15); } @@ -4364,7 +4377,7 @@ void Scene352::actions() { case 1: { _vm->_sound->command(21); - _globals._sequenceIndexes[12] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[12], false, 7, 2, 20, 0); + _globals._sequenceIndexes[12] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[12], false, 7, 2, 20, 0); _scene->_sequences.setDepth(_globals._sequenceIndexes[12], FACING_NORTH); int oldIdx = _commonSequenceIdx; _commonSequenceIdx = _scene->_sequences.startCycle(_commonSpriteIndex, false, -2); @@ -4376,7 +4389,7 @@ void Scene352::actions() { case 2: _vm->_sound->command(22); _scene->_sequences.remove(_commonSequenceIdx); - _commonSequenceIdx = _scene->_sequences.startReverseCycle(_commonSpriteIndex, false, 8, 1, 0, 0); + _commonSequenceIdx = _scene->_sequences.startPingPongCycle(_commonSpriteIndex, false, 8, 1, 0, 0); _scene->_sequences.setAnimRange(_commonSequenceIdx, 1, 3); _scene->_sequences.addSubEntry(_commonSequenceIdx, SEQUENCE_TRIGGER_EXPIRE, 0, 3); break; @@ -4431,12 +4444,12 @@ void Scene352::actions() { _game._player._stepEnabled = false; _game._player._visible = false; if (_globals[kSexOfRex] == REX_FEMALE) { - _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 5, 2, 0, 0); + _globals._sequenceIndexes[3] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[3], false, 5, 2, 0, 0); _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[3]); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_SPRITE, 5, 1); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 2); } else { - _globals._sequenceIndexes[4] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[4], false, 5, 2, 0, 0); + _globals._sequenceIndexes[4] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[4], false, 5, 2, 0, 0); _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[4]); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[4], SEQUENCE_TRIGGER_SPRITE, 6, 1); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[4], SEQUENCE_TRIGGER_EXPIRE, 0, 2); @@ -4478,7 +4491,7 @@ void Scene352::actions() { case 1: { _vm->_sound->command(21); - _globals._sequenceIndexes[12] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[12], false, 7, 2, 20, 0); + _globals._sequenceIndexes[12] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[12], false, 7, 2, 20, 0); _scene->_sequences.setDepth(_globals._sequenceIndexes[12], 8); int oldIdx = _commonSequenceIdx; _commonSequenceIdx = _scene->_sequences.startCycle(_commonSpriteIndex, false, -2); @@ -4490,7 +4503,7 @@ void Scene352::actions() { case 2: _vm->_sound->command(23); _scene->_sequences.remove(_commonSequenceIdx); - _commonSequenceIdx = _scene->_sequences.startReverseCycle(_commonSpriteIndex, false, 8, 1, 0, 0); + _commonSequenceIdx = _scene->_sequences.addReverseSpriteCycle(_commonSpriteIndex, false, 8, 1, 0, 0); _scene->_sequences.setAnimRange(_commonSequenceIdx, 1, 4); _scene->_sequences.addSubEntry(_commonSequenceIdx, SEQUENCE_TRIGGER_EXPIRE, 0, 3); break; @@ -4545,13 +4558,13 @@ void Scene352::actions() { _game._player._stepEnabled = false; _game._player._visible = false; if (_globals[kSexOfRex] == REX_MALE) { - _globals._sequenceIndexes[14] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[14], false, 8, 1, 0, 0); + _globals._sequenceIndexes[14] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[14], false, 8, 1, 0, 0); _scene->_sequences.setAnimRange(_globals._sequenceIndexes[14], 1, 2); _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[14]); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[14], SEQUENCE_TRIGGER_SPRITE, 2, 1); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[14], SEQUENCE_TRIGGER_EXPIRE, 0, 2); } else { - _globals._sequenceIndexes[15] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[15], false, 8, 1, 0, 0); + _globals._sequenceIndexes[15] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[15], false, 8, 1, 0, 0); _scene->_sequences.setAnimRange(_globals._sequenceIndexes[15], 1, 2); _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[15]); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[15], SEQUENCE_TRIGGER_SPRITE, 2, 1); @@ -4592,12 +4605,12 @@ void Scene352::actions() { _game._player._stepEnabled = false; _game._player._visible = false; if (_globals[kSexOfRex] == REX_MALE) { - _globals._sequenceIndexes[6] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[6], true, 6, 2, 0, 0); + _globals._sequenceIndexes[6] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[6], true, 6, 2, 0, 0); _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[6]); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[6], SEQUENCE_TRIGGER_SPRITE, 6, 1); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[6], SEQUENCE_TRIGGER_EXPIRE, 0, 2); } else { - _globals._sequenceIndexes[7] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[7], true, 6, 2, 0, 0); + _globals._sequenceIndexes[7] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[7], true, 6, 2, 0, 0); _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[7]); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[7], SEQUENCE_TRIGGER_SPRITE, 6, 1); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[7], SEQUENCE_TRIGGER_EXPIRE, 0, 2); @@ -4745,7 +4758,7 @@ void Scene354::enter() { _game._player._facing = FACING_NORTH; } else if (_scene->_priorSceneId == 316) _game._player._playerPos = Common::Point(71, 107); - else if (_scene->_priorSceneId != -2) + else if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) _game._player._playerPos = Common::Point(167, 57); sceneEntrySound(); @@ -4812,7 +4825,7 @@ void Scene357::enter() { _game._player._playerPos = Common::Point(298, 142); else if (_scene->_priorSceneId == 313) _game._player._playerPos = Common::Point(127, 101); - else if (_scene->_priorSceneId != -2) + else if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) _game._player._playerPos = Common::Point(15, 148); sceneEntrySound(); @@ -4876,7 +4889,7 @@ void Scene358::enter() { if (_scene->_priorSceneId == 357) _game._player._playerPos = Common::Point(305, 142); - else if (_scene->_priorSceneId != -2) + else if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) _game._player._playerPos = Common::Point(12, 141); sceneEntrySound(); @@ -4952,7 +4965,7 @@ void Scene359::enter() { if (_scene->_priorSceneId == 358) _game._player._playerPos = Common::Point(301, 141); - else if (_scene->_priorSceneId != -2) + else if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) _game._player._playerPos = Common::Point(15, 148); sceneEntrySound(); @@ -4980,12 +4993,12 @@ void Scene359::actions() { _game._player._visible = false; _vm->_dialogs->show(35920); if (_globals[kSexOfRex] == REX_MALE) { - _globals._sequenceIndexes[2] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[2], false, 4, 2, 0, 0); + _globals._sequenceIndexes[2] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[2], false, 4, 2, 0, 0); _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[2]); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_SPRITE, 6, 1); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 2); } else { - _globals._sequenceIndexes[4] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[4], true, 7, 2, 0, 0); + _globals._sequenceIndexes[4] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[4], true, 7, 2, 0, 0); _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[4]); _scene->_sequences.setPosition(_globals._sequenceIndexes[4], Common::Point(106, 110)); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[4], SEQUENCE_TRIGGER_SPRITE, 6, 1); @@ -5075,7 +5088,7 @@ void Scene360::enter() { if (_scene->_priorSceneId == 359) _game._player._playerPos = Common::Point(304, 143); - else if (_scene->_priorSceneId != -2) + else if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) _game._player._playerPos = Common::Point(13, 141); sceneEntrySound(); @@ -5341,7 +5354,7 @@ void Scene361::enter() { else if (_scene->_priorSceneId == 320) { _game._player._playerPos = Common::Point(129, 113); _game._player._facing = FACING_SOUTH; - } else if (_scene->_priorSceneId != -2) + } else if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) _game._player._playerPos = Common::Point(13, 145); _game.loadQuoteSet(0xFB, 0xFC, 0); @@ -5466,7 +5479,7 @@ void Scene361::actions() { _vm->_dialogs->show(36119); else if (_action.isAction(VERB_SIT_AT, NOUN_DESK)) { _scene->_kernelMessages.reset(); - _scene->_kernelMessages.addQuote(0xFC, 120, 0); + _scene->_kernelMessages.addQuote(252, 0, 120); } else if (_action.isAction(VERB_CLIMB_INTO, NOUN_AIR_VENT)) { if (_globals[kSexOfRex] == REX_FEMALE) handleRoxAction(); diff --git a/engines/mads/nebular/nebular_scenes3.h b/engines/mads/nebular/nebular_scenes3.h index 9efd38e9a4..cf925b3867 100644 --- a/engines/mads/nebular/nebular_scenes3.h +++ b/engines/mads/nebular/nebular_scenes3.h @@ -8,12 +8,12 @@ * 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. diff --git a/engines/mads/nebular/nebular_scenes4.cpp b/engines/mads/nebular/nebular_scenes4.cpp index 56f6fb4466..c981f6a6e4 100644 --- a/engines/mads/nebular/nebular_scenes4.cpp +++ b/engines/mads/nebular/nebular_scenes4.cpp @@ -8,12 +8,12 @@ * 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 + * 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. @@ -113,7 +113,7 @@ void Scene401::setup() { } void Scene401::enter() { - if (_scene->_priorSceneId != -2) + if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) _northFl = false; _timer = 0; @@ -125,7 +125,7 @@ void Scene401::enter() { _game._player._playerPos = Common::Point(149, 90); _game._player._facing = FACING_SOUTH; _northFl = true; - } else if (_scene->_priorSceneId != -2) { + } else if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) { _game._player._playerPos = Common::Point(142, 131); _game._player._facing = FACING_NORTH; } @@ -718,7 +718,7 @@ void Scene402::enter() { _roxOnStool = false; _bartenderDialogNode = 1; _conversationFl = false; - } else if (_scene->_priorSceneId != -2) { + } else if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) { _game._player._playerPos = Common::Point(160, 150); _game._player._facing = FACING_NORTH; _game._objects.addToInventory(OBJ_CREDIT_CHIP); @@ -962,7 +962,7 @@ void Scene402::step() { } if (!_bartenderTalking) { - _globals._sequenceIndexes[10] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[10], false, 7, 0, 0, 0); + _globals._sequenceIndexes[10] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[10], false, 7, 0, 0, 0); _scene->_sequences.setAnimRange(_globals._sequenceIndexes[10], 3, 4); _scene->_sequences.setDepth(_globals._sequenceIndexes[10], 8); int idx = _scene->_dynamicHotspots.add(NOUN_BARTENDER, VERB_WALKTO, _globals._sequenceIndexes[10], Common::Rect(0, 0, 0, 0)); @@ -1514,7 +1514,7 @@ void Scene402::step() { break; case 3: - _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 12, 2, 0, 0); + _globals._sequenceIndexes[3] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[3], false, 12, 2, 0, 0); _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 4, 5); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 32); _rightWomanMoving = true; @@ -1697,7 +1697,7 @@ void Scene402::step() { _scene->_kernelMessages.add(Common::Point(171, 47), 0xFBFA, 0, 0, 130, _game.getQuote(0x200)); _scene->_sequences.addTimer(150, 63); _scene->_sequences.remove(_globals._sequenceIndexes[13]); - _globals._sequenceIndexes[13] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[13], false, 30, 4, 0, 0); + _globals._sequenceIndexes[13] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[13], false, 30, 4, 0, 0); _scene->_sequences.setAnimRange(_globals._sequenceIndexes[13], 10, 11); _scene->_sequences.setDepth(_globals._sequenceIndexes[13], 8); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[13], SEQUENCE_TRIGGER_EXPIRE, 0, 62); @@ -1769,7 +1769,7 @@ void Scene402::step() { case 69: { int seqIdx = _globals._sequenceIndexes[13]; - _globals._sequenceIndexes[13] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[13], false, 25, 4, 0, 0); + _globals._sequenceIndexes[13] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[13], false, 25, 4, 0, 0); _scene->_sequences.setAnimRange(_globals._sequenceIndexes[13], 10, 11); _scene->_sequences.setDepth(_globals._sequenceIndexes[13], 8); _scene->_sequences.updateTimeout(_globals._sequenceIndexes[13], seqIdx); @@ -1783,7 +1783,7 @@ void Scene402::step() { break; case 70: - _globals._sequenceIndexes[13] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[13], false, 25, 4, 0, 0); + _globals._sequenceIndexes[13] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[13], false, 25, 4, 0, 0); _scene->_sequences.setAnimRange(_globals._sequenceIndexes[13], 10, 12); _scene->_sequences.setDepth(_globals._sequenceIndexes[13], 8); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[13], SEQUENCE_TRIGGER_EXPIRE, 0, 72); @@ -1840,7 +1840,7 @@ void Scene402::step() { _cutSceneReady = false; _helgaReady = false; _scene->_sequences.remove(_globals._sequenceIndexes[13]); - _globals._sequenceIndexes[13] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[13], false, 15, 2, 0, 0); + _globals._sequenceIndexes[13] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[13], false, 15, 2, 0, 0); _scene->_sequences.setAnimRange(_globals._sequenceIndexes[13], 11, 13); _scene->_sequences.setDepth(_globals._sequenceIndexes[13], 8); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[13], SEQUENCE_TRIGGER_EXPIRE, 0, 26); @@ -1860,7 +1860,7 @@ void Scene402::step() { _cutSceneReady = false; _helgaReady = false; _scene->_sequences.remove(_globals._sequenceIndexes[13]); - _globals._sequenceIndexes[13] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[13], false, 15, 2, 0, 0); + _globals._sequenceIndexes[13] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[13], false, 15, 2, 0, 0); _scene->_sequences.setAnimRange(_globals._sequenceIndexes[13], 14, 15); _scene->_sequences.setDepth(_globals._sequenceIndexes[13], 8); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[13], SEQUENCE_TRIGGER_EXPIRE, 0, 26); @@ -2069,7 +2069,7 @@ void Scene402::actions() { if (_game._trigger == 0) { _game._player._stepEnabled = false; _game._player._visible = false; - _globals._sequenceIndexes[21] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[21], false, 7, 2, 0, 0); + _globals._sequenceIndexes[21] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[21], false, 7, 2, 0, 0); _scene->_sequences.setAnimRange(_globals._sequenceIndexes[21], 1, 2); _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[21]); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[21], SEQUENCE_TRIGGER_SPRITE, 2, 165); @@ -2202,7 +2202,7 @@ void Scene402::actions() { _game._triggerSetupMode = SEQUENCE_TRIGGER_DAEMON; _game._player._stepEnabled = false; _game._player._visible = false; - _globals._sequenceIndexes[22] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[22], false, 7, 2, 0, 0); + _globals._sequenceIndexes[22] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[22], false, 7, 2, 0, 0); _scene->_sequences.setAnimRange(_globals._sequenceIndexes[22], 1, 2); _scene->_sequences.setPosition(_globals._sequenceIndexes[22], Common::Point(_game._player._playerPos.x, _game._player._playerPos.y + 1)); _scene->_sequences.setDepth(_globals._sequenceIndexes[22], 5); @@ -2411,7 +2411,7 @@ void Scene405::enter() { } else if (_scene->_priorSceneId == 413) { _game._player._playerPos = Common::Point(284, 109); _game._player._facing = FACING_SOUTH; - } else if (_scene->_priorSceneId != -2) { + } else if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) { _game._player._playerPos = Common::Point(23, 123); _game._player._facing = FACING_EAST; } @@ -2445,7 +2445,7 @@ void Scene405::step() { if (_game._trigger == 70) { _game._player._priorTimer = _scene->_frameStartTime + _game._player._ticksAmount ; _game._player._visible = true; - _globals._sequenceIndexes[1] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[1], false, 6, 1, 0, 0); + _globals._sequenceIndexes[1] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[1], false, 6, 1, 0, 0); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[1], SEQUENCE_TRIGGER_EXPIRE, 0, 71); _vm->_sound->command(19); } @@ -2495,7 +2495,7 @@ void Scene405::actions() { _game._player._stepEnabled = false; _game._player._visible = false; _game._triggerSetupMode = SEQUENCE_TRIGGER_DAEMON; - _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 7, 2, 0, 0); + _globals._sequenceIndexes[3] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[3], false, 7, 2, 0, 0); _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 1, 2); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 75); Common::Point msgPos = Common::Point(_game._player._playerPos.x, _game._player._playerPos.y + 1); @@ -2505,7 +2505,7 @@ void Scene405::actions() { _game._triggerSetupMode = SEQUENCE_TRIGGER_DAEMON; _game._player._stepEnabled = false; _game._player._visible = false; - _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 7, 2, 0, 0); + _globals._sequenceIndexes[3] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[3], false, 7, 2, 0, 0); _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 1, 2); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 70); _scene->_sequences.setPosition(_globals._sequenceIndexes[3], _game._player._playerPos); @@ -2514,7 +2514,7 @@ void Scene405::actions() { _game._triggerSetupMode = SEQUENCE_TRIGGER_DAEMON; _game._player._stepEnabled = false; _game._player._visible = false; - _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 7, 2, 0, 0); + _globals._sequenceIndexes[3] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[3], false, 7, 2, 0, 0); _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 1, 2); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 80); _scene->_sequences.setPosition(_globals._sequenceIndexes[3], _game._player._playerPos); @@ -2587,7 +2587,7 @@ void Scene406::enter() { } else if (_scene->_priorSceneId == 411) { _game._player._playerPos = Common::Point(153, 108); _game._player._facing = FACING_SOUTH; - } else if (_scene->_priorSceneId != -2) { + } else if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) { _game._player._playerPos = Common::Point(15, 129); _game._player._facing = FACING_EAST; } @@ -2609,7 +2609,7 @@ void Scene406::enter() { else { _game._player._stepEnabled = false; _game._triggerSetupMode = SEQUENCE_TRIGGER_DAEMON; - _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 3, 1, 0, 0); + _globals._sequenceIndexes[3] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[3], false, 3, 1, 0, 0); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 90); _vm->_sound->command(19); } @@ -2647,7 +2647,7 @@ void Scene406::step() { if (_game._trigger == 70) { _game._player._priorTimer = _scene->_frameStartTime + _game._player._ticksAmount; _game._player._visible = true; - _globals._sequenceIndexes[1] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[1], false, 4, 1, 0, 0); + _globals._sequenceIndexes[1] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[1], false, 4, 1, 0, 0); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[1], SEQUENCE_TRIGGER_EXPIRE, 0, 71); _vm->_sound->command(19); } @@ -2703,7 +2703,7 @@ void Scene406::actions() { _game._player._stepEnabled = false; _game._player._visible = false; _game._triggerSetupMode = SEQUENCE_TRIGGER_DAEMON; - _globals._sequenceIndexes[2] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[2], false, 7, 2, 0, 0); + _globals._sequenceIndexes[2] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[2], false, 7, 2, 0, 0); _scene->_sequences.setAnimRange(_globals._sequenceIndexes[2], 1, 2); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 75); Common::Point msgPos = Common::Point(_game._player._playerPos.x, _game._player._playerPos.y + 1); @@ -2713,7 +2713,7 @@ void Scene406::actions() { _game._triggerSetupMode = SEQUENCE_TRIGGER_DAEMON; _game._player._stepEnabled = false; _game._player._visible = false; - _globals._sequenceIndexes[2] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[2], false, 7, 2, 0, 0); + _globals._sequenceIndexes[2] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[2], false, 7, 2, 0, 0); _scene->_sequences.setAnimRange(_globals._sequenceIndexes[2], 1, 2); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 70); Common::Point msgPos = Common::Point(_game._player._playerPos.x, _game._player._playerPos.y + 1); @@ -2723,7 +2723,7 @@ void Scene406::actions() { _game._triggerSetupMode = SEQUENCE_TRIGGER_DAEMON; _game._player._stepEnabled = false; _game._player._visible = false; - _globals._sequenceIndexes[2] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[2], false, 7, 2, 0, 0); + _globals._sequenceIndexes[2] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[2], false, 7, 2, 0, 0); _scene->_sequences.setAnimRange(_globals._sequenceIndexes[2], 1, 2); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 110); _scene->_sequences.setPosition(_globals._sequenceIndexes[2], _game._player._playerPos); @@ -2791,14 +2791,14 @@ void Scene407::setup() { } void Scene407::enter() { - if (_scene->_priorSceneId != -2) + if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) _fromNorth = false; if (_scene->_priorSceneId == 318) { _game._player._playerPos = Common::Point(172, 92); _game._player._facing = FACING_SOUTH; _fromNorth = true; - } else if (_scene->_priorSceneId != -2) { + } else if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) { _game._player._playerPos = Common::Point(172, 132); _game._player._facing = FACING_NORTH; } @@ -2934,7 +2934,7 @@ void Scene408::actions() { _vm->_sound->command(57); _game._player._stepEnabled = false; _game._player._visible = false; - _globals._sequenceIndexes[1] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[1], true, 7, 2, 0, 0); + _globals._sequenceIndexes[1] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[1], true, 7, 2, 0, 0); _scene->_sequences.setAnimRange(_globals._sequenceIndexes[1], 1, 2); _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[1]); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[1], SEQUENCE_TRIGGER_SPRITE, 2, 1); @@ -3118,7 +3118,7 @@ void Scene410::enter() { else _scene->_hotspots.activate(NOUN_CHARGE_CASES, false); - if (_scene->_priorSceneId != -2) { + if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) { _game._player._playerPos = Common::Point(155, 150); _game._player._facing = FACING_NORTH; } @@ -3182,7 +3182,7 @@ void Scene410::actions() { _vm->_sound->command(57); _game._player._stepEnabled = false; _game._player._visible = false; - _globals._sequenceIndexes[2] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[2], false, 7, 2, 0, 0); + _globals._sequenceIndexes[2] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[2], false, 7, 2, 0, 0); _scene->_sequences.setAnimRange(_globals._sequenceIndexes[2], 1, 3); _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[2]); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_SPRITE, 3, 1); @@ -3646,7 +3646,7 @@ void Scene411::enter() { _scene->_dynamicHotspots.setPosition(idx, Common::Point(220, 121), FACING_NORTHEAST); } - if (_scene->_priorSceneId != -2) { + if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) { _game._player._playerPos = Common::Point(60, 146); _game._player._facing = FACING_NORTHEAST; } @@ -3842,7 +3842,7 @@ void Scene411::actions() { _vm->_sound->command(57); _game._player._stepEnabled = false; _game._player._visible = false; - _globals._sequenceIndexes[8] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[8], false, 7, 2, 0, 0); + _globals._sequenceIndexes[8] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[8], false, 7, 2, 0, 0); _scene->_sequences.setAnimRange(_globals._sequenceIndexes[8], 1, 2); _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[8]); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[8], SEQUENCE_TRIGGER_SPRITE, 2, 1); @@ -3879,7 +3879,7 @@ void Scene411::actions() { _vm->_sound->command(57); _game._player._stepEnabled = false; _game._player._visible = false; - _globals._sequenceIndexes[8] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[8], false, 7, 2, 0, 0); + _globals._sequenceIndexes[8] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[8], false, 7, 2, 0, 0); _scene->_sequences.setAnimRange(_globals._sequenceIndexes[8], 1, 2); _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[8]); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[8], SEQUENCE_TRIGGER_SPRITE, 2, 1); @@ -4058,7 +4058,7 @@ void Scene413::enter() { _game._player._playerPos = Common::Point(142, 146); _game._player._facing = FACING_NORTH; _game._player._visible = true; - } else if (_scene->_priorSceneId != -2) { + } else if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) { if (_globals[kSexOfRex] == REX_MALE) { _scene->loadAnimation(Resources::formatName(413, 'd', 1, EXT_AA, ""), 78); _vm->_sound->command(30); @@ -4078,7 +4078,7 @@ void Scene413::enter() { case 1: _vm->_sound->command(30); _game._player._visible = false; - _globals._sequenceIndexes[1] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[1], false, 7, 1, 0, 0); + _globals._sequenceIndexes[1] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[1], false, 7, 1, 0, 0); _scene->_sequences.setAnimRange(_globals._sequenceIndexes[1], 1, 19); _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 8); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[1], SEQUENCE_TRIGGER_EXPIRE, 0, 76); diff --git a/engines/mads/nebular/nebular_scenes4.h b/engines/mads/nebular/nebular_scenes4.h index fbd5ce81f0..de11bd4129 100644 --- a/engines/mads/nebular/nebular_scenes4.h +++ b/engines/mads/nebular/nebular_scenes4.h @@ -8,12 +8,12 @@ * 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. diff --git a/engines/mads/nebular/nebular_scenes5.cpp b/engines/mads/nebular/nebular_scenes5.cpp index 66d8294fc6..95eb429193 100644 --- a/engines/mads/nebular/nebular_scenes5.cpp +++ b/engines/mads/nebular/nebular_scenes5.cpp @@ -8,12 +8,12 @@ * 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 + * 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. @@ -132,7 +132,7 @@ void Scene501::handleSlotActions() { frameIndex = 2; } - _mainSequenceId = _scene->_sequences.startReverseCycle(_mainSpriteId, false, numTicks, 1, 0, 0); + _mainSequenceId = _scene->_sequences.startPingPongCycle(_mainSpriteId, false, numTicks, 1, 0, 0); _scene->_sequences.setAnimRange(_mainSequenceId, 1, frameIndex); _scene->_sequences.setMsgLayout(_mainSequenceId); _vm->_sound->command(10); @@ -199,7 +199,7 @@ void Scene501::enter() { _game._player._playerPos = Common::Point(317, 102); _game._player._facing = FACING_SOUTHWEST; _scene->_sequences.addTimer(15, 80); - } else if (_scene->_priorSceneId != -2) + } else if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) _game._player._playerPos = Common::Point(299, 131); if (_scene->_roomChanged) { @@ -238,7 +238,7 @@ void Scene501::step() { break; case 82: - _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 9, 1, 0, 0); + _globals._sequenceIndexes[3] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[3], false, 9, 1, 0, 0); _scene->_sequences.setDepth(_globals._sequenceIndexes[3], 7); _vm->_sound->command(12); _doorHotspotid = _scene->_dynamicHotspots.add(NOUN_DOOR, VERB_WALK_THROUGH, _globals._sequenceIndexes[3], Common::Rect(0, 0, 0, 0)); @@ -273,7 +273,7 @@ void Scene501::step() { case 72: _scene->_sequences.remove(_globals._sequenceIndexes[2]); - _globals._sequenceIndexes[2] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[2], false, 6, 1, 0, 0); + _globals._sequenceIndexes[2] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[2], false, 6, 1, 0, 0); _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 4); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 73); break; @@ -415,7 +415,7 @@ void Scene501::actions() { case 7: { _vm->_sound->command(12); int syncIdx = _globals._sequenceIndexes[3]; - _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 9, 1, 0, 0); + _globals._sequenceIndexes[3] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[3], false, 9, 1, 0, 0); _scene->_sequences.setDepth(_globals._sequenceIndexes[3], 7); _scene->_sequences.updateTimeout(_globals._sequenceIndexes[3], syncIdx); _vm->_sound->command(12); @@ -563,7 +563,7 @@ void Scene503::enter() { _scene->_dynamicHotspots.setPosition(_detonatorHotspotId, Common::Point(254, 135), FACING_SOUTH); } - if (_scene->_priorSceneId != -2) { + if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) { _game._player._playerPos = Common::Point(191, 152); _game._player._facing = FACING_NORTHWEST; } @@ -581,13 +581,13 @@ void Scene503::actions() { _game._player._stepEnabled = false; _game._player._visible = false; if (_globals[kSexOfRex] == REX_MALE) { - _globals._sequenceIndexes[2] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[2], false, 8, 1, 0, 0); + _globals._sequenceIndexes[2] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[2], false, 8, 1, 0, 0); _scene->_sequences.setAnimRange(_globals._sequenceIndexes[2], 1, 3); _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[2]); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_SPRITE, 3, 1); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 2); } else { - _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], true, 8, 1, 0, 0); + _globals._sequenceIndexes[3] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[3], true, 8, 1, 0, 0); _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 1, 4); _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[3]); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_SPRITE, 4, 1); @@ -709,7 +709,7 @@ void Scene504::enter() { _globals._spriteIndexes[3] = _scene->_sprites.addSprites(formAnimName('a', 3)); _carAnimationMode = 1; _scene->loadAnimation(formAnimName('A', -1)); - if ((_scene->_priorSceneId != -2) && (_scene->_priorSceneId != 505)) + if ((_scene->_priorSceneId != RETURNING_FROM_DIALOG) && (_scene->_priorSceneId != 505)) _globals[kHoverCarLocation] = _scene->_priorSceneId; _globals._sequenceIndexes[7] = _scene->_sequences.startCycle(_globals._spriteIndexes[7], false, 1); @@ -800,7 +800,7 @@ void Scene504::actions() { case 1: { int syncIdx = _globals._sequenceIndexes[3]; - _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 6, 1, 0, 0); + _globals._sequenceIndexes[3] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[3], false, 6, 1, 0, 0); _scene->_sequences.setDepth(_globals._sequenceIndexes[3], 13); _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 1, 6); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 2); @@ -912,8 +912,8 @@ void Scene505::enter() { _globals._spriteIndexes[11] = _scene->_sprites.addSprites(formAnimName('t', -1)); _globals._spriteIndexes[12] = _scene->_sprites.addSprites(formAnimName('e', -1)); - if (_scene->_priorSceneId != -2) - _globals._sequenceIndexes[12] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[12], false, 6, 1, 0, 0); + if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) + _globals._sequenceIndexes[12] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[12], false, 6, 1, 0, 0); _globals._sequenceIndexes[13] = _scene->_sequences.addSpriteCycle(_globals._spriteIndexes[13], false, 6, 1, 120, 0); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[13], SEQUENCE_TRIGGER_EXPIRE, 0, 60); @@ -934,7 +934,7 @@ void Scene505::enter() { for (int i = 0; i < 9; i++) { if (_globals[kHoverCarLocation] == _carLocations[i]) { _homeSelectedId = i; - if (_scene->_priorSceneId != -2) + if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) _selectedId = i; } } @@ -996,7 +996,7 @@ void Scene505::step() { _scene->_sequences.remove(_globals._sequenceIndexes[1]); _scene->_sequences.remove(_globals._sequenceIndexes[0]); _scene->_sequences.remove(_globals._sequenceIndexes[13]); - _globals._sequenceIndexes[13] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[13], false, 6, 1, 0, 0); + _globals._sequenceIndexes[13] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[13], false, 6, 1, 0, 0); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[13], SEQUENCE_TRIGGER_EXPIRE, 0, 63); _vm->_sound->command(18); } @@ -1222,7 +1222,7 @@ void Scene506::enter() { _game._player._facing = FACING_SOUTHEAST; _scene->_sequences.addTimer(60, 80); _game._player._stepEnabled = false; - } else if (_scene->_priorSceneId != -2) { + } else if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) { _game._player._playerPos = Common::Point(138, 116); _game._player._facing = FACING_NORTHEAST; _game._player._visible = false; @@ -1260,7 +1260,7 @@ void Scene506::step() { case 71: _scene->_sequences.remove(_globals._sequenceIndexes[3]); - _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 6, 1, 0, 0); + _globals._sequenceIndexes[3] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[3], false, 6, 1, 0, 0); _scene->_sequences.setDepth(_globals._sequenceIndexes[3], 5); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 72); break; @@ -1317,7 +1317,7 @@ void Scene506::handleDoorSequences() { case 82: _scene->_sequences.remove(_doorSequenceIdx); - _doorSequenceIdx = _scene->_sequences.startReverseCycle(_doorSpriteIdx, false, 7, 1, 0, 0); + _doorSequenceIdx = _scene->_sequences.addReverseSpriteCycle(_doorSpriteIdx, false, 7, 1, 0, 0); _scene->_sequences.setDepth(_doorSequenceIdx, _doorDepth); if (_actionFl) _scene->_sequences.addSubEntry(_doorSequenceIdx, SEQUENCE_TRIGGER_EXPIRE, 0, 84); @@ -1471,7 +1471,7 @@ void Scene507::enter() { _scene->_dynamicHotspots.setPosition(_penlightHotspotId, Common::Point(233, 152), FACING_SOUTHEAST); } - if (_scene->_priorSceneId != -2) { + if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) { _game._player._playerPos = Common::Point(121, 147); _game._player._facing = FACING_NORTH; } @@ -1487,7 +1487,7 @@ void Scene507::actions() { case 0: _game._player._stepEnabled = false; _game._player._visible = false; - _globals._sequenceIndexes[2] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[2], false, 6, 1, 0, 0); + _globals._sequenceIndexes[2] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[2], false, 6, 1, 0, 0); _scene->_sequences.setAnimRange(_globals._sequenceIndexes[2], 1, 5); _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[2]); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_SPRITE, 5, 1); @@ -1547,7 +1547,9 @@ void Scene507::actions() { _vm->_dialogs->show(50724); else if (_action.isAction(VERB_LOOK, NOUN_WINDOW)) _vm->_dialogs->show(50725); - else if (_action.isAction(VERB_LOOK, NOUN_COUNTER)) { + else if (_action.isAction(VERB_WALK_BEHIND, NOUN_COUNTER)) { + // WORKAROUND: Empty handling to prevent default "can't do that" dialogs showing + } else if (_action.isAction(VERB_LOOK, NOUN_COUNTER)) { if (_game._objects.isInRoom(OBJ_PENLIGHT)) _vm->_dialogs->show(50728); else @@ -1613,7 +1615,7 @@ void Scene508::enter() { _scene->_sequences.setDepth(_globals._sequenceIndexes[4], 11); int idx = _scene->_dynamicHotspots.add(NOUN_LASER_BEAM, VERB_WALKTO, _globals._sequenceIndexes[4], Common::Rect(0, 0, 0, 0)); _scene->_dynamicHotspots.setPosition(idx, Common::Point(57, 116), FACING_NORTHEAST); - _globals._sequenceIndexes[2] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[2], false, 15, 0, 0, 0); + _globals._sequenceIndexes[2] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[2], false, 15, 0, 0, 0); _scene->_sequences.setAnimRange(_globals._sequenceIndexes[2], 6, 8); _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 6); if (_globals[kLaserHoleIsThere]) { @@ -1628,7 +1630,7 @@ void Scene508::enter() { if (_scene->_priorSceneId == 515) { _game._player._playerPos = Common::Point(57, 116); _game._player._facing = FACING_NORTHEAST; - } else if (_scene->_priorSceneId != -2) { + } else if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) { _game._player._playerPos = Common::Point(289, 139); _game._player._facing = FACING_WEST; } @@ -1659,7 +1661,7 @@ void Scene508::handlePedestral() { case 0: _game._player._stepEnabled = false; _game._player._visible = false; - _globals._sequenceIndexes[6] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[6], false, 9, 1, 0, 0); + _globals._sequenceIndexes[6] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[6], false, 9, 1, 0, 0); _scene->_sequences.setAnimRange(_globals._sequenceIndexes[6], 1, 4); _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[6]); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[6], SEQUENCE_TRIGGER_SPRITE, 4, 1); @@ -1732,7 +1734,7 @@ void Scene508::actions() { break; case 4: - _globals._sequenceIndexes[2] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[2], false, 15, 0, 0, 0); + _globals._sequenceIndexes[2] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[2], false, 15, 0, 0, 0); _scene->_sequences.setAnimRange(_globals._sequenceIndexes[2], 6, 8); _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 6); break; @@ -1866,7 +1868,7 @@ void Scene511::enter() { _globals._spriteIndexes[1] = _scene->_sprites.addSprites(formAnimName('c', 0)); _globals._spriteIndexes[4] = _scene->_sprites.addSprites("*RXCD_6"); - if (_scene->_priorSceneId != -2) + if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) _handingLine = false; if (_globals[kBoatRaised]) { @@ -1921,7 +1923,7 @@ void Scene511::enter() { if (_scene->_priorSceneId == 512) { _game._player._playerPos = Common::Point(60, 112); _game._player._facing = FACING_SOUTHEAST; - } else if (_scene->_priorSceneId != -2) { + } else if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) { _game._player._playerPos = Common::Point(55, 152); _game._player._facing = FACING_NORTHWEST; _game._player._visible = false; @@ -2024,7 +2026,7 @@ void Scene511::actions() { case 0: _game._player._stepEnabled = false; _scene->_sequences.remove(_globals._sequenceIndexes[1]); - _globals._sequenceIndexes[1] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[1], false, 6, 1, 0, 0); + _globals._sequenceIndexes[1] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[1], false, 6, 1, 0, 0); _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 1); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[1], SEQUENCE_TRIGGER_EXPIRE, 0, 1); break; @@ -2064,6 +2066,7 @@ void Scene511::actions() { if (_game._trigger == 0) { _game._player._stepEnabled = false; _game._player._visible = false; + _game._player.update(); _lineAnimationMode = 1; _lineAnimationPosition = 1; _lineMoving = true; @@ -2086,7 +2089,8 @@ void Scene511::actions() { } else { _vm->_dialogs->show(51130); } - } else if (_action.isAction(VERB_TIE, NOUN_FISHING_LINE, NOUN_BOAT) || _action.isAction(VERB_ATTACH, NOUN_FISHING_LINE, NOUN_BOAT)) { + } else if (_action.isAction(VERB_TIE, NOUN_FISHING_LINE, NOUN_BOAT) || + _action.isAction(VERB_ATTACH, NOUN_FISHING_LINE, NOUN_BOAT)) { if (_globals[kBoatRaised]) _vm->_dialogs->show(51131); else if (_globals[kLineStatus] == 1) @@ -2104,7 +2108,6 @@ void Scene511::actions() { _scene->_sequences.addTimer(1, 1); else { _game._player._visible = true; - _game._player._priorTimer = _scene->_frameStartTime - _game._player._ticksAmount; _globals._sequenceIndexes[7] = _scene->_sequences.startCycle(_globals._spriteIndexes[7], false, -2); _scene->_sequences.setDepth(_globals._sequenceIndexes[7], 4); int idx = _scene->_dynamicHotspots.add(NOUN_FISHING_LINE, VERB_WALKTO, _globals._sequenceIndexes[7], Common::Rect(0, 0, 0, 0)); @@ -2114,6 +2117,10 @@ void Scene511::actions() { _lineMoving = true; _globals[kLineStatus] = 3; _game._player._stepEnabled = true; + + if (_scene->_activeAnimation) + _scene->_activeAnimation->eraseSprites(); + _game._player.update(); } } } @@ -2240,7 +2247,7 @@ void Scene512::enter() { } else _scene->_hotspots.activate(NOUN_PADLOCK_KEY, false); - if (_scene->_priorSceneId != -2) { + if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) { _game._player._playerPos = Common::Point(144, 152); _game._player._facing = FACING_NORTHEAST; } @@ -2257,7 +2264,7 @@ void Scene512::actions() { case 0: _game._player._stepEnabled = false; _game._player._visible = false; - _globals._sequenceIndexes[2] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[2], false, 8, 1, 0, 0); + _globals._sequenceIndexes[2] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[2], false, 8, 1, 0, 0); _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[2]); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_SPRITE, 5, 1); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 2); @@ -2293,7 +2300,7 @@ void Scene512::actions() { case 1: _game._player._visible = false; - _globals._sequenceIndexes[8] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[8], false, 9, 1, 0, 0); + _globals._sequenceIndexes[8] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[8], false, 9, 1, 0, 0); _scene->_sequences.setAnimRange(_globals._sequenceIndexes[8], 1, 3); _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[8]); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[8], SEQUENCE_TRIGGER_EXPIRE, 0, 2); @@ -2326,7 +2333,7 @@ void Scene512::actions() { break; case 5: - _globals._sequenceIndexes[5] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[5], false, 14, 0, 0, 0); + _globals._sequenceIndexes[5] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[5], false, 14, 0, 0, 0); _scene->_sequences.setDepth(_globals._sequenceIndexes[5], 3); _scene->_hotspots.activate(NOUN_PADLOCK_KEY, true); _scene->_sequences.addTimer(60, 6); @@ -2347,7 +2354,7 @@ void Scene512::actions() { case 0: _game._player._stepEnabled = false; _game._player._visible = false; - _globals._sequenceIndexes[2] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[2], false, 10, 1, 0, 0); + _globals._sequenceIndexes[2] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[2], false, 10, 1, 0, 0); _scene->_sequences.setAnimRange(_globals._sequenceIndexes[2], 1, 2); _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[2]); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 1); @@ -2358,12 +2365,12 @@ void Scene512::actions() { _game._player._visible = true; if (!_game._objects.isInRoom(OBJ_PADLOCK_KEY) || _game._difficulty == DIFFICULTY_EASY) { _scene->_sequences.remove(_globals._sequenceIndexes[3]); - _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 12, 1, 0, 0); + _globals._sequenceIndexes[3] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[3], false, 12, 1, 0, 0); _scene->_sequences.setDepth(_globals._sequenceIndexes[3], 3); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 2); } else { _scene->_sequences.remove(_globals._sequenceIndexes[5]); - _globals._sequenceIndexes[4] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[4], false, 12, 1, 0, 0); + _globals._sequenceIndexes[4] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[4], false, 12, 1, 0, 0); _scene->_sequences.setDepth(_globals._sequenceIndexes[4], 3); _scene->_hotspots.activate(NOUN_PADLOCK_KEY, false); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[4], SEQUENCE_TRIGGER_EXPIRE, 0, 2); @@ -2391,7 +2398,7 @@ void Scene512::actions() { else endVal = 2; - _globals._sequenceIndexes[2] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[2], false, 10, 1, 0, 0); + _globals._sequenceIndexes[2] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[2], false, 10, 1, 0, 0); _scene->_sequences.setAnimRange(_globals._sequenceIndexes[2], 1, endVal); _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[2]); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_SPRITE, endVal, 1); @@ -2427,7 +2434,8 @@ void Scene512::actions() { _vm->_dialogs->show(51225); else if (_action.isAction(VERB_LOOK, NOUN_PADLOCK_KEY) && _game._objects.isInRoom(OBJ_PADLOCK_KEY)) _vm->_dialogs->show(51215); - else if (_action.isAction(VERB_LOOK, NOUN_FISHING_ROD) && (_scene->_activeAnimation->getCurrentFrame() == 4)) + else if (_action.isAction(VERB_LOOK, NOUN_FISHING_ROD) && (!_scene->_activeAnimation || + _scene->_activeAnimation->getCurrentFrame() == 4)) _vm->_dialogs->show(51216); else if (_action.isAction(VERB_LOOK, NOUN_SHIPS_WHEEL)) _vm->_dialogs->show(51218); @@ -2460,7 +2468,9 @@ void Scene512::actions() { _vm->_dialogs->show(51233); else if (_action.isAction(VERB_LOOK, NOUN_LAMP)) _vm->_dialogs->show(51234); - else if (_action.isAction(VERB_LOOK, NOUN_COUNTER)) + else if (_action.isAction(VERB_WALK_BEHIND, NOUN_COUNTER)) { + // WORKAROUND: Empty handling to prevent default "can't do that" dialogs showing + } else if (_action.isAction(VERB_LOOK, NOUN_COUNTER)) _vm->_dialogs->show(51235); else if (_action.isAction(VERB_LOOK, NOUN_ICE_CHESTS)) _vm->_dialogs->show(51237); @@ -2505,7 +2515,7 @@ void Scene513::enter() { _game._player._facing = FACING_WEST; _game._player._stepEnabled = false; _scene->_sequences.addTimer(15, 80); - } else if (_scene->_priorSceneId != -2) { + } else if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) { _game._player._playerPos = Common::Point(63, 149); _game._player._facing = FACING_NORTHEAST; _game._player._visible = false; @@ -2529,7 +2539,7 @@ void Scene513::step() { case 80: _game._player._stepEnabled = false; _scene->_sequences.remove(_globals._sequenceIndexes[2]); - _globals._sequenceIndexes[2] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[2], false, 7, 1, 0, 0); + _globals._sequenceIndexes[2] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[2], false, 7, 1, 0, 0); _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 2); _vm->_sound->command(24); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 81); @@ -2588,7 +2598,7 @@ void Scene513::actions() { case 0: _game._player._stepEnabled = false; _scene->_sequences.remove(_globals._sequenceIndexes[1]); - _globals._sequenceIndexes[1] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[1], false, 6, 1, 0, 0); + _globals._sequenceIndexes[1] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[1], false, 6, 1, 0, 0); _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 1); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[1], SEQUENCE_TRIGGER_EXPIRE, 0, 1); break; @@ -2626,7 +2636,7 @@ void Scene513::actions() { case 0: _game._player._stepEnabled = false; _game._player._visible = false; - _globals._sequenceIndexes[4] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[4], false, 7, 1, 0, 0); + _globals._sequenceIndexes[4] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[4], false, 7, 1, 0, 0); _scene->_sequences.setAnimRange(_globals._sequenceIndexes[4], 1, 2); _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[4]); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[4], SEQUENCE_TRIGGER_EXPIRE, 0, 1); @@ -2636,7 +2646,7 @@ void Scene513::actions() { _scene->_sequences.updateTimeout(-1, _globals._sequenceIndexes[4]); _game._player._visible = true; _scene->_sequences.remove(_globals._sequenceIndexes[2]); - _globals._sequenceIndexes[2] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[2], false, 7, 1, 0, 0); + _globals._sequenceIndexes[2] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[2], false, 7, 1, 0, 0); _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 2); _vm->_sound->command(24); _scene->_kernelMessages.reset(); @@ -2739,7 +2749,7 @@ void Scene551::enter() { if (_scene->_priorSceneId == 501) _game._player._playerPos = Common::Point(18, 130); - else if (_scene->_priorSceneId != -2) { + else if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) { _game._player._playerPos = Common::Point(124, 119); _game._player._facing = FACING_NORTH; } diff --git a/engines/mads/nebular/nebular_scenes5.h b/engines/mads/nebular/nebular_scenes5.h index 2face26508..f314ae8513 100644 --- a/engines/mads/nebular/nebular_scenes5.h +++ b/engines/mads/nebular/nebular_scenes5.h @@ -8,12 +8,12 @@ * 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. diff --git a/engines/mads/nebular/nebular_scenes6.cpp b/engines/mads/nebular/nebular_scenes6.cpp index 13ee1a3dc1..d97e37ea0b 100644 --- a/engines/mads/nebular/nebular_scenes6.cpp +++ b/engines/mads/nebular/nebular_scenes6.cpp @@ -8,12 +8,12 @@ * 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 + * 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. @@ -112,7 +112,7 @@ void Scene601::enter() { _globals._sequenceIndexes[2] = _scene->_sequences.startCycle(_globals._spriteIndexes[2], false, -2); _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 3); _scene->loadAnimation(formAnimName('R', 1), 70); - } else if (_scene->_priorSceneId != -2) { + } else if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) { _game._player._playerPos = Common::Point(229, 129); _game._player._facing = FACING_SOUTHWEST; } @@ -130,7 +130,7 @@ void Scene601::step() { case 71: _scene->_sequences.remove(_globals._sequenceIndexes[2]); - _globals._sequenceIndexes[2] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[2], false, 6, 1, 0, 0); + _globals._sequenceIndexes[2] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[2], false, 6, 1, 0, 0); _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 3); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 72); break; @@ -293,7 +293,7 @@ void Scene602::enter() { if (_scene->_priorSceneId == 603) { _game._player._playerPos = Common::Point(228, 126); _game._player._facing = FACING_WEST; - } else if (_scene->_priorSceneId != -2) { + } else if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) { _game._player._playerPos = Common::Point(50, 127); _game._player._facing = FACING_EAST; } @@ -313,7 +313,7 @@ void Scene602::handleSafeActions() { case 0: _game._player._stepEnabled = false; _game._player._visible = false; - _globals._sequenceIndexes[5] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[5], true, 12, 1, 0, 0); + _globals._sequenceIndexes[5] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[5], true, 12, 1, 0, 0); _scene->_sequences.setAnimRange(_globals._sequenceIndexes[5], 1, 3); _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[5]); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[5], SEQUENCE_TRIGGER_SPRITE, 3, 1); @@ -348,7 +348,7 @@ void Scene602::handleSafeActions() { else _lastSpriteIdx = _globals._spriteIndexes[3]; - _lastSequenceIdx = _scene->_sequences.startReverseCycle(_lastSpriteIdx, false, 12, 1, 0, 0); + _lastSequenceIdx = _scene->_sequences.startPingPongCycle(_lastSpriteIdx, false, 12, 1, 0, 0); _scene->_sequences.setDepth(_lastSequenceIdx, 14); if (_game._objects[OBJ_DOOR_KEY]._roomNumber == _scene->_currentSceneId) _scene->_hotspots.activate(NOUN_DOOR_KEY, false); @@ -460,7 +460,7 @@ void Scene602::actions() { case 0: _game._player._stepEnabled = false; _game._player._visible = false; - _globals._sequenceIndexes[5] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[5], true, 8, 1, 0, 0); + _globals._sequenceIndexes[5] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[5], true, 8, 1, 0, 0); _scene->_sequences.setAnimRange(_globals._sequenceIndexes[5], 1, 3); _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[5]); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[5], SEQUENCE_TRIGGER_SPRITE, 3, 1); @@ -585,7 +585,7 @@ void Scene603::enter() { _scene->_dynamicHotspots.setPosition(_noteHotspotId, Common::Point(242, 118), FACING_NORTHEAST); } - if (_scene->_priorSceneId != -2) + if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) _game._player._playerPos = Common::Point(113, 134); sceneEntrySound(); @@ -600,7 +600,7 @@ void Scene603::actions() { case 0: _game._player._stepEnabled = false; _game._player._visible = false; - _globals._sequenceIndexes[4] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[4], false, 8, 1, 0, 0); + _globals._sequenceIndexes[4] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[4], false, 8, 1, 0, 0); _scene->_sequences.setAnimRange(_globals._sequenceIndexes[4], 1, 5); _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[4]); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[4], SEQUENCE_TRIGGER_SPRITE, 5, 1); @@ -750,7 +750,7 @@ void Scene604::enter() { _vm->_palette->setEntry(253, 45, 24, 17); _animationActiveFl = false; - if (_scene->_priorSceneId != -2) { + if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) { _game._player._playerPos = Common::Point(72, 149); _game._player._facing = FACING_NORTHEAST; _game._player._visible = false; @@ -858,7 +858,7 @@ void Scene604::handleBombActions() { case 0: _game._player._stepEnabled = false; _game._player._visible = false; - _globals._sequenceIndexes[5] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[5], false, 9, 1, 0, 0); + _globals._sequenceIndexes[5] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[5], false, 9, 1, 0, 0); _scene->_sequences.setAnimRange(_globals._sequenceIndexes[5], 1, 3); _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[5]); if (_bombMode == 1) @@ -908,7 +908,7 @@ void Scene604::actions() { case 0: _game._player._stepEnabled = false; _scene->_sequences.remove(_globals._sequenceIndexes[2]); - _globals._sequenceIndexes[2] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[2], false, 6, 1, 0, 0); + _globals._sequenceIndexes[2] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[2], false, 6, 1, 0, 0); _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 1); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 1); break; @@ -948,8 +948,14 @@ void Scene604::actions() { _bombMode = 1; if ((_game._difficulty == DIFFICULTY_HARD) || _globals[kWarnedFloodCity]) handleBombActions(); - else if ((_game._objects.isInInventory(OBJ_POLYCEMENT) && _game._objects.isInInventory(OBJ_CHICKEN)) - && ((_globals[kLineStatus] == LINE_TIED) || ((_game._difficulty == DIFFICULTY_EASY) && (!_globals[kBoatRaised])))) + else if ( + (_game._objects.isInInventory(OBJ_POLYCEMENT) && (_game._objects.isInInventory(OBJ_CHICKEN) || _game._objects.isInInventory(OBJ_CHICKEN_BOMB))) + && (_globals[kLineStatus] == LINE_TIED || (_game._difficulty == DIFFICULTY_EASY && !_globals[kBoatRaised])) + ) + // The original can get in an impossible state at this point, if the player has + // combined the chicken with the bomb before placing the timer bomb on the ledge. + // Therefore, we also allow the player to place the bomb if the chicken bomb is + // in the inventory. handleBombActions(); else if (_game._difficulty == DIFFICULTY_EASY) _vm->_dialogs->show(60424); @@ -1003,12 +1009,12 @@ void Scene605::enter() { _globals._spriteIndexes[5] = _scene->_sprites.addSprites(formAnimName('n', -1)); _globals._spriteIndexes[6] = _scene->_sprites.addSprites(formAnimName('f', -1)); - _globals._sequenceIndexes[1] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[1], false, 15, 0, 0, 0); - _globals._sequenceIndexes[2] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[2], false, 17, 0, 0, 0); - _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 14, 0, 0, 0); - _globals._sequenceIndexes[4] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[4], false, 13, 0, 0, 0); - _globals._sequenceIndexes[5] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[5], false, 17, 0, 0, 0); - _globals._sequenceIndexes[6] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[6], false, 18, 0, 0, 0); + _globals._sequenceIndexes[1] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[1], false, 15, 0, 0, 0); + _globals._sequenceIndexes[2] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[2], false, 17, 0, 0, 0); + _globals._sequenceIndexes[3] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[3], false, 14, 0, 0, 0); + _globals._sequenceIndexes[4] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[4], false, 13, 0, 0, 0); + _globals._sequenceIndexes[5] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[5], false, 17, 0, 0, 0); + _globals._sequenceIndexes[6] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[6], false, 18, 0, 0, 0); _game._player._visible = false; _game._player._stepEnabled = false; @@ -1106,7 +1112,7 @@ void Scene607::enter() { if (_scene->_priorSceneId == 608) { _game._player._playerPos = Common::Point(297, 50); _game._player._facing = FACING_SOUTHEAST; - } else if (_scene->_priorSceneId != -2) { + } else if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) { _game._player._playerPos = Common::Point(40, 104); _game._player._facing = FACING_SOUTHEAST; _game._player._visible = false; @@ -1164,7 +1170,7 @@ void Scene607::step() { && !_dogBarking && (_vm->getRandomNumber(1, 50) == 10)) { _dogBarking = true; _scene->_sequences.remove(_globals._sequenceIndexes[1]); - _globals._sequenceIndexes[1] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[1], false, 5, 8, 0, 0); + _globals._sequenceIndexes[1] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[1], false, 5, 8, 0, 0); _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 6); _scene->_kernelMessages.reset(); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[1], SEQUENCE_TRIGGER_SPRITE, 2, 100); @@ -1250,7 +1256,7 @@ void Scene607::step() { case 61: { int syncIdx = _globals._sequenceIndexes[4]; - _globals._sequenceIndexes[4] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[4], false, 15, 3, 0, 0); + _globals._sequenceIndexes[4] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[4], false, 15, 3, 0, 0); _scene->_sequences.setAnimRange(_globals._sequenceIndexes[4], 46, -2); _scene->_sequences.setDepth(_globals._sequenceIndexes[4], 1); _scene->_sequences.updateTimeout(_globals._sequenceIndexes[4], syncIdx); @@ -1397,7 +1403,7 @@ void Scene607::actions() { case 0: _game._player._stepEnabled = false; _scene->_sequences.remove(_globals._sequenceIndexes[2]); - _globals._sequenceIndexes[2] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[2], false, 6, 1, 0, 0); + _globals._sequenceIndexes[2] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[2], false, 6, 1, 0, 0); _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 4); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 1); break; @@ -1778,7 +1784,7 @@ void Scene608::enter() { _vm->_palette->setEntry(252, 63, 44, 30); _vm->_palette->setEntry(253, 63, 20, 22); - if (_scene->_priorSceneId != -2) { + if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) { _game._player._playerPos = Common::Point(46, 132); _game._player._facing = FACING_EAST; if (_game._difficulty == DIFFICULTY_HARD) { @@ -1791,7 +1797,7 @@ void Scene608::enter() { if (!_dogUnderCar) resetDogVariables(); else { - _globals._sequenceIndexes[10] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[10], false, 9, 0, 0, 0); + _globals._sequenceIndexes[10] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[10], false, 9, 0, 0, 0); _scene->_sequences.setAnimRange(_globals._sequenceIndexes[10], 10, 11); _scene->_sequences.setDepth(_globals._sequenceIndexes[10], 6); } @@ -1833,7 +1839,7 @@ void Scene608::step() { if (_vm->getRandomNumber(1, 50) == 10) { _dogBarkingFl = true; _scene->_sequences.remove(_globals._sequenceIndexes[5]); - _globals._sequenceIndexes[5] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[5], false, 5, 8, 0, 0); + _globals._sequenceIndexes[5] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[5], false, 5, 8, 0, 0); _scene->_sequences.setDepth(_globals._sequenceIndexes[5], 4); int idx = _scene->_dynamicHotspots.add(NOUN_OBNOXIOUS_DOG, VERB_WALKTO, _globals._sequenceIndexes[5], Common::Rect(0, 0, 0, 0)); _scene->_dynamicHotspots.setPosition(idx, Common::Point(194, 142), FACING_EAST); @@ -1958,7 +1964,7 @@ void Scene608::step() { _game._player._visible = true; _game._player._priorTimer = _scene->_activeAnimation->getNextFrameTimer() - _game._player._ticksAmount; } else if (_carFrame == 41) { - _globals._sequenceIndexes[10] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[10], false, 9, 0, 0, 0); + _globals._sequenceIndexes[10] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[10], false, 9, 0, 0, 0); _scene->_sequences.setAnimRange(_globals._sequenceIndexes[10], 10, 11); _scene->_sequences.setDepth(_globals._sequenceIndexes[10], 6); _dogUnderCar = true; @@ -2148,7 +2154,7 @@ void Scene608::step() { case 82: { int syncIdx = _globals._sequenceIndexes[9]; - _globals._sequenceIndexes[9] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[9], false, 15, 5, 0, 0); + _globals._sequenceIndexes[9] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[9], false, 15, 5, 0, 0); _scene->_sequences.setAnimRange(_globals._sequenceIndexes[9], 39, 40); _scene->_sequences.setDepth(_globals._sequenceIndexes[9], 5); _scene->_sequences.updateTimeout(_globals._sequenceIndexes[9], syncIdx); @@ -2219,7 +2225,7 @@ void Scene608::actions() { if ((_globals[kCarStatus] == CAR_UP) || (_globals[kCarStatus] == CAR_SQUASHES_DOG) || (_globals[kCarStatus] == CAR_SQUASHES_DOG_AGAIN)) { _game._player._stepEnabled = false; _game._player._visible = false; - _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], true, 6, 2, 0, 0); + _globals._sequenceIndexes[3] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[3], true, 6, 2, 0, 0); _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 1, 2); _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[3]); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 1); @@ -2293,7 +2299,7 @@ void Scene608::actions() { if ((_globals[kCarStatus] == CAR_DOWN) || (_globals[kCarStatus] == CAR_DOWN_ON_SQUASHED_DOG)) { _game._player._stepEnabled = false; _game._player._visible = false; - _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], true, 6, 2, 0, 0); + _globals._sequenceIndexes[3] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[3], true, 6, 2, 0, 0); _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 1, 3); _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[3]); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 1); @@ -2379,7 +2385,7 @@ void Scene608::actions() { case 0: _game._player._stepEnabled = false; _game._player._visible = false; - _globals._sequenceIndexes[2] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[2], true, 6, 2, 0, 0); + _globals._sequenceIndexes[2] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[2], true, 6, 2, 0, 0); _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[2]); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_SPRITE, 4, 1); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 2); @@ -2407,7 +2413,7 @@ void Scene608::actions() { case 0: _game._player._stepEnabled = false; _game._player._visible = false; - _globals._sequenceIndexes[2] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[2], true, 6, 2, 0, 0); + _globals._sequenceIndexes[2] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[2], true, 6, 2, 0, 0); _scene->_sequences.setAnimRange(_globals._sequenceIndexes[2], 1, 2); _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[2]); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_SPRITE, 2, 1); @@ -2535,7 +2541,7 @@ void Scene609::enter() { _game._player._facing = FACING_EAST; _scene->_sequences.addTimer(60, 60); _game._player._stepEnabled = false; - } else if (_scene->_priorSceneId != -2) { + } else if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) { _game._player._playerPos = Common::Point(86, 136); _game._player._facing = FACING_NORTHEAST; _game._player._visible = false; @@ -2574,7 +2580,7 @@ void Scene609::step() { case 62: _scene->_sequences.remove( _globals._sequenceIndexes[2]); - _globals._sequenceIndexes[2] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[2], false, 7, 1, 0, 0); + _globals._sequenceIndexes[2] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[2], false, 7, 1, 0, 0); _scene->_hotspots.activate(NOUN_VIDEO_STORE_DOOR, true); _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 9); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 63); @@ -2582,7 +2588,7 @@ void Scene609::step() { case 63: if (!_globals[kHasTalkedToHermit] && (_game._difficulty != DIFFICULTY_HARD)) { - _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 26, 2, 0, 0); + _globals._sequenceIndexes[3] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[3], false, 26, 2, 0, 0); _scene->_sequences.setDepth(_globals._sequenceIndexes[3], 7); _scene->_sequences.setPosition(_globals._sequenceIndexes[3], Common::Point(287, 73)); _scene->_sequences.setScale(_globals._sequenceIndexes[3], 47); @@ -2605,7 +2611,7 @@ void Scene609::step() { case 71: if (!_globals[kHasTalkedToHermit]) { - _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 26, 2, 0, 0); + _globals._sequenceIndexes[3] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[3], false, 26, 2, 0, 0); _scene->_sequences.setDepth(_globals._sequenceIndexes[3], 7); _scene->_sequences.setPosition(_globals._sequenceIndexes[3], Common::Point(287, 73)); _scene->_sequences.setScale(_globals._sequenceIndexes[3], 47); @@ -2648,7 +2654,7 @@ void Scene609::enterStore() { case 2: _game._player._visible = false; - _globals._sequenceIndexes[5] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[5], true, 11, 2, 0, 0); + _globals._sequenceIndexes[5] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[5], true, 11, 2, 0, 0); _scene->_sequences.setAnimRange(_globals._sequenceIndexes[5], 1, 2); _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[5]); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[5], SEQUENCE_TRIGGER_EXPIRE, 0, 3); @@ -2690,7 +2696,7 @@ void Scene609::enterStore() { case 7: _scene->_sequences.remove(_globals._sequenceIndexes[2]); - _globals._sequenceIndexes[2] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[2], false, 7, 1, 0, 0); + _globals._sequenceIndexes[2] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[2], false, 7, 1, 0, 0); _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 9); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 8); break; @@ -2766,7 +2772,7 @@ void Scene609::actions() { case 0: _game._player._stepEnabled = false; _scene->_sequences.remove(_globals._sequenceIndexes[1]); - _globals._sequenceIndexes[1] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[1], false, 6, 1, 0, 0); + _globals._sequenceIndexes[1] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[1], false, 6, 1, 0, 0); _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 5); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[1], SEQUENCE_TRIGGER_EXPIRE, 0, 1); break; @@ -2884,7 +2890,7 @@ void Scene610::enter() { if (_scene->_roomChanged && _game._difficulty != DIFFICULTY_EASY) _game._objects.addToInventory(OBJ_PENLIGHT); - if (_scene->_priorSceneId != -2) { + if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) { _game._player._playerPos = Common::Point(175, 152); _game._player._facing = FACING_NORTHWEST; } @@ -2922,7 +2928,7 @@ void Scene610::actions() { case 0: _game._player._stepEnabled = false; _game._player._visible = false; - _globals._sequenceIndexes[2] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[2], true, 8, 1, 0, 0); + _globals._sequenceIndexes[2] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[2], true, 8, 1, 0, 0); _scene->_sequences.setAnimRange(_globals._sequenceIndexes[2], 1, 2); _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[2]); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_SPRITE, 2, 1); @@ -2952,7 +2958,7 @@ void Scene610::actions() { case 0: _game._player._stepEnabled = false; _game._player._visible = false; - _globals._sequenceIndexes[2] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[2], true, 8, 1, 0, 0); + _globals._sequenceIndexes[2] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[2], true, 8, 1, 0, 0); _scene->_sequences.setAnimRange(_globals._sequenceIndexes[2], 1, 2); _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[2]); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_SPRITE, 2, 1); @@ -3155,7 +3161,7 @@ bool Scene611::check2ChargedBatteries() { } bool Scene611::check4ChargedBatteries() { - if (_game._objects.isInInventory(OBJ_DURAFAIL_CELLS) && _game._objects.isInInventory(OBJ_PHONE_CELLS) + if (_game._objects.isInInventory(OBJ_DURAFAIL_CELLS) && _game._objects.isInInventory(OBJ_PHONE_CELLS) && _globals[kDurafailRecharged]) return true; @@ -3253,6 +3259,8 @@ void Scene611::handleSubDialog1() { handleTalking(500); displayHermitQuestions(17); _dialog1.write(0x290, false); + _dialog1.write(0x28e, false); + if (!_dialog1.read(0x28F)) _dialog1.write(0x291, true); @@ -3271,8 +3279,9 @@ void Scene611::handleSubDialog1() { if ((_game._objects.isInInventory(OBJ_DURAFAIL_CELLS)) || (_game._objects.isInInventory(OBJ_PHONE_CELLS))) _dialog1.write(0x294, true); - if (!_game._objects.isInInventory(OBJ_DURAFAIL_CELLS) && !_game._objects.isInInventory(OBJ_PHONE_CELLS)) - _globals[kExecuted_1_11] = true; + // WORKAROUND: Fix bug in the original where the option to give Hermit batteries + // would be given before the player even has any batteries + _globals[kHermitWantsBatteries] = true; setDialogNode(1); break; @@ -3826,29 +3835,29 @@ void Scene611::displayHermitQuestions(int question) { Common::String curQuote = _game.getQuote(0x2D3); int width = _vm->_font->getWidth(curQuote, _scene->_textSpacing); int quotePosX = _defaultDialogPos.x - (width / 2); - _scene->_kernelMessages.add(Common::Point(quotePosX, _defaultDialogPos.y + 3), 0xFDFC, 0, 0, 9999999, curQuote); + _scene->_kernelMessages.add(Common::Point(quotePosX, _defaultDialogPos.y + 3), 0xFDFC, 0, 0, 800, curQuote); curQuote = _game.getQuote(0x2D4); width = _vm->_font->getWidth(curQuote, _scene->_textSpacing); quotePosX = _defaultDialogPos.x - (width / 2); - _scene->_kernelMessages.add(Common::Point(quotePosX, _defaultDialogPos.y + 17), 0xFDFC, 0, 0, 9999999, curQuote); + _scene->_kernelMessages.add(Common::Point(quotePosX, _defaultDialogPos.y + 17), 0xFDFC, 0, 0, 800, curQuote); curQuote = _game.getQuote(0x2D5); width = _vm->_font->getWidth(curQuote, _scene->_textSpacing); quotePosX = _defaultDialogPos.x - (width / 2); - _scene->_kernelMessages.add(Common::Point(quotePosX, _defaultDialogPos.y + 31), 0xFDFC, 0, 0, 9999999, curQuote); + _scene->_kernelMessages.add(Common::Point(quotePosX, _defaultDialogPos.y + 31), 0xFDFC, 0, 0, 800, curQuote); curQuote = _game.getQuote(0x2D6); width = _vm->_font->getWidth(curQuote, _scene->_textSpacing); quotePosX = _defaultDialogPos.x - (width / 2); - _scene->_kernelMessages.add(Common::Point(quotePosX, _defaultDialogPos.y + 45), 0xFDFC, 0, 0, 9999999, curQuote); + _scene->_kernelMessages.add(Common::Point(quotePosX, _defaultDialogPos.y + 45), 0xFDFC, 0, 0, 800, curQuote); curQuote = _game.getQuote(0x2D7); width = _vm->_font->getWidth(curQuote, _scene->_textSpacing); quotePosX = _defaultDialogPos.x - (width / 2); - _scene->_kernelMessages.add(Common::Point(quotePosX, _defaultDialogPos.y + 59), 0xFDFC, 0, 0, 9999999, curQuote); - } - break; + _scene->_kernelMessages.add(Common::Point(quotePosX, _defaultDialogPos.y + 59), 0xFDFC, 0, 0, 800, curQuote); + } + break; case 22: { Common::String curQuote = _game.getQuote(0x2D8); @@ -3921,14 +3930,14 @@ void Scene611::enter() { 0x2D9, 0x2DA, 0x2DB, 0x2DC, 0x2DD, 0x2DE, 0x2DF, 0x2E0, 0x2E1, 0x2E2, 0x2E3, 0x2E4, 0x2E5, 0x2E6, 0x323, 0x324, 0); - _dialog1.setup(0x82, 0x287, 0x288, 0x289, 0x28A, 0x28B, 0x28C, 0x28D, 0x28E, 0x28F, 0x290, + _dialog1.setup(kConvHermit1, 0x287, 0x288, 0x289, 0x28A, 0x28B, 0x28C, 0x28D, 0x28E, 0x28F, 0x290, 0x291, 0x292, 0x293, 0x294, 0x295, 0x296, 0); - _dialog2.setup(0x83, 0x29C, 0x29D, 0x29E, 0x29F, 0); + _dialog2.setup(kConvHermit2, 0x29C, 0x29D, 0x29E, 0x29F, 0); if (!_game._visitedScenes._sceneRevisited) { - _dialog1.set(0x82, 0x287, 0x288, 0x296, 0); - _dialog2.set(0x83, 0x29F, 0); + _dialog1.set(kConvHermit1, 0x287, 0x288, 0x296, 0); + _dialog2.set(kConvHermit2, 0x29F, 0); } _vm->_palette->setEntry(252, 51, 51, 47); @@ -3945,7 +3954,7 @@ void Scene611::enter() { _alreadyTalkingFl = false; _startTradingFl = false; - if (_scene->_priorSceneId != -2) { + if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) { _game._player._playerPos = Common::Point(22, 132); _game._player._facing = FACING_EAST; _duringDialogFl = false; @@ -3964,11 +3973,10 @@ void Scene611::enter() { _scene->_hotspots.activate(NOUN_HERMIT, false); } - // CHECKME: The last line of the block looks extremely useless - if (_globals[kExecuted_1_11]) { - _dialog1.write(0x294, true); - _dialog1.write(0x292, false); - _globals[kExecuted_1_11] = true; + // WORKAROUND: Fix original adding 'give batteries' option even if you don't have them + if (_globals[kHermitWantsBatteries]) { + if ((_game._objects.isInInventory(OBJ_DURAFAIL_CELLS)) || (_game._objects.isInInventory(OBJ_PHONE_CELLS))) + _dialog1.write(0x294, true); } if (_duringDialogFl) { @@ -4012,7 +4020,7 @@ void Scene611::step() { _scene->_sequences.addSubEntry(_globals._sequenceIndexes[1], SEQUENCE_TRIGGER_EXPIRE, 0, 81); } else if (_game._trigger == 81) { int syncId = _globals._sequenceIndexes[1]; - _globals._sequenceIndexes[1] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[1], false, 20, 0, 0, 0); + _globals._sequenceIndexes[1] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[1], false, 20, 0, 0, 0); int idx = _scene->_dynamicHotspots.add(NOUN_RAT, VERB_WALKTO, _globals._sequenceIndexes[1], Common::Rect(0, 0, 0, 0)); _ratHotspotId = _scene->_dynamicHotspots.setPosition(idx, Common::Point(272, 154), FACING_SOUTHEAST); _scene->_sequences.setAnimRange(_globals._sequenceIndexes[1], 9, 10); @@ -4040,7 +4048,7 @@ void Scene611::step() { break; case 6: - _globals._sequenceIndexes[2] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[2], false, 12, 3, 0, 0); + _globals._sequenceIndexes[2] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[2], false, 12, 3, 0, 0); _scene->_sequences.setAnimRange(_globals._sequenceIndexes[2], 2, 4); _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 1); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 71); @@ -4260,7 +4268,7 @@ void Scene611::step() { if (_hermitMode == 6) { if ((_scene->_activeAnimation->getCurrentFrame() == 9) && _check1Fl) { _scene->_sequences.remove(_globals._sequenceIndexes[3]); - _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 7, 1, 0, 0); + _globals._sequenceIndexes[3] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[3], false, 7, 1, 0, 0); _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 1, 2); _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[3]); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 112); @@ -4300,7 +4308,7 @@ void Scene611::step() { _resetBatterieText = true; int syncIdx = _globals._sequenceIndexes[3]; _nextFrame = 10; - _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 7, 1, 0, 0); + _globals._sequenceIndexes[3] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[3], false, 7, 1, 0, 0); _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 1, 2); _scene->_sequences.updateTimeout(_globals._sequenceIndexes[3], syncIdx); _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[3]); @@ -4488,7 +4496,7 @@ void Scene612::handleWinchMovement() { case 0: _game._player._stepEnabled = false; _game._player._visible = false; - _globals._sequenceIndexes[4] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[4], false, 10, 1, 0, 0); + _globals._sequenceIndexes[4] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[4], false, 10, 1, 0, 0); _scene->_sequences.setAnimRange(_globals._sequenceIndexes[4], 1, 5); _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[4]); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[4], SEQUENCE_TRIGGER_SPRITE, 5, 1); @@ -4506,7 +4514,7 @@ void Scene612::handleWinchMovement() { _globals[kBoatRaised] = false; } else { _scene->_sequences.remove(_globals._sequenceIndexes[2]); - _globals._sequenceIndexes[2] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[2], false, 17, 9, 0, 0); + _globals._sequenceIndexes[2] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[2], false, 17, 9, 0, 0); _vm->_sound->command(18); } _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 1); @@ -4558,7 +4566,7 @@ void Scene612::enter() { _globals._sequenceIndexes[2] = _scene->_sequences.startCycle(_globals._spriteIndexes[2], false, _cycleIndex); _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 1); - if (_scene->_priorSceneId != -2) { + if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) { _game._player._playerPos = Common::Point(280, 75); _game._player._facing = FACING_SOUTHWEST; _game._player._visible = false; @@ -4608,7 +4616,7 @@ void Scene612::actions() { case 0: _game._player._stepEnabled = false; _scene->_sequences.remove(_globals._sequenceIndexes[1]); - _globals._sequenceIndexes[1] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[1], false, 6, 1, 0, 0); + _globals._sequenceIndexes[1] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[1], false, 6, 1, 0, 0); _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 2); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[1], SEQUENCE_TRIGGER_EXPIRE, 0, 1); break; diff --git a/engines/mads/nebular/nebular_scenes6.h b/engines/mads/nebular/nebular_scenes6.h index c5cac56626..4fc4a2e8ae 100644 --- a/engines/mads/nebular/nebular_scenes6.h +++ b/engines/mads/nebular/nebular_scenes6.h @@ -8,12 +8,12 @@ * 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 + * 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. diff --git a/engines/mads/nebular/nebular_scenes7.cpp b/engines/mads/nebular/nebular_scenes7.cpp index 930bb7c250..c2a249e5f8 100644 --- a/engines/mads/nebular/nebular_scenes7.cpp +++ b/engines/mads/nebular/nebular_scenes7.cpp @@ -8,12 +8,12 @@ * 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 + * 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. @@ -148,17 +148,20 @@ void Scene701::enter() { switch (boatStatus) { case BOAT_TIED_FLOATING: - _globals._sequenceIndexes[4] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[4], false, 20, 0, 0, 0); + _globals._sequenceIndexes[4] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[4], false, 20, 0, 0, 0); _scene->_sequences.setDepth(_globals._sequenceIndexes[4], 10); break; case BOAT_ADRIFT: - _globals._sequenceIndexes[6] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[6], false, 20, 0, 0, 0); + _globals._sequenceIndexes[6] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[6], false, 20, 0, 0, 0); _scene->_sequences.setDepth(_globals._sequenceIndexes[6], 10); break; - case BOAT_TIED: + case BOAT_TIED: { _globals._sequenceIndexes[2] = _scene->_sequences.startCycle(_globals._spriteIndexes[2], false, -1); _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 9); + int idx = _scene->_dynamicHotspots.add(837, 759, _globals._sequenceIndexes[2], Common::Rect()); + _scene->_dynamicHotspots.setPosition(idx, Common::Point(231, 127), FACING_NORTH); break; + } case BOAT_GONE: _scene->_hotspots.activate(NOUN_BOAT, false); break; @@ -191,7 +194,7 @@ void Scene701::enter() { _game._player._stepEnabled = false; _scene->loadAnimation(formAnimName('B', 1), 80); _vm->_sound->command(28); - } else if (_scene->_priorSceneId != -2 && _scene->_priorSceneId != 620) { + } else if (_scene->_priorSceneId != RETURNING_FROM_DIALOG && _scene->_priorSceneId != 620) { _game._player._playerPos = Common::Point(22, 131); _game._player._facing = FACING_EAST; _game._player._stepEnabled = false; @@ -206,7 +209,7 @@ void Scene701::step() { switch(_game._trigger) { case 60: _scene->_sequences.remove(_globals._sequenceIndexes[5]); - _globals._sequenceIndexes[5] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[5], false, 6, 1, 0, 0); + _globals._sequenceIndexes[5] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[5], false, 6, 1, 0, 0); _scene->_sequences.setPosition(_globals._sequenceIndexes[5], Common::Point(155, 129)); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[5], SEQUENCE_TRIGGER_EXPIRE, 0, 61); break; @@ -276,10 +279,8 @@ void Scene701::preActions() { } void Scene701::actions() { - if (_action.isAction(VERB_WALK_ALONG, NOUN_PLATFORM)) - return; - - if (_action.isAction(VERB_LOOK, NOUN_BINOCULARS, NOUN_BUILDING) && _game._objects[OBJ_VASE]._roomNumber == 706) { + if (_action.isAction(VERB_WALK_ALONG, NOUN_PLATFORM)) { + } else if (_action.isAction(VERB_LOOK, NOUN_BINOCULARS, NOUN_BUILDING) && _game._objects[OBJ_VASE]._roomNumber == 706) { switch (_game._trigger) { case 0: _game._player._stepEnabled = false; @@ -326,7 +327,7 @@ void Scene701::actions() { case 3: _vm->_sound->command(17); - _globals._sequenceIndexes[1] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[1], false, 5, 1, 0, 0); + _globals._sequenceIndexes[1] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[1], false, 5, 1, 0, 0); _scene->_sequences.setPosition(_globals._sequenceIndexes[1], Common::Point(48, 136)); _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 10); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[1], SEQUENCE_TRIGGER_EXPIRE, 0, 4); @@ -415,7 +416,7 @@ void Scene701::actions() { _vm->_dialogs->show(70111); } else if (_action.isAction(VERB_LOOK, NOUN_SUBMERGED_CITY)) _vm->_dialogs->show(70112); - else if (_action.isAction(VERB_LOOK, 0)) + else if (_action.isAction(VERB_LOOK, NOUN_ELEVATOR)) _vm->_dialogs->show(70113); else if (_action.isAction(VERB_LOOK, NOUN_PLATFORM)) _vm->_dialogs->show(70114); @@ -460,7 +461,7 @@ void Scene702::enter() { if (_scene->_priorSceneId == 701) { _game._player._playerPos = Common::Point(13, 145); _game._player._facing = FACING_EAST; - } else if (_scene->_priorSceneId != -2 && _scene->_priorSceneId != 620) { + } else if (_scene->_priorSceneId != RETURNING_FROM_DIALOG && _scene->_priorSceneId != 620) { _game._player._playerPos = Common::Point(289, 138); _game._player.walk(Common::Point(262, 148), FACING_WEST); _game._player._facing = FACING_WEST; @@ -502,7 +503,7 @@ void Scene702::actions() { case 0: _game._player._stepEnabled = false; _game._player._visible = false; - _globals._sequenceIndexes[12] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[12], false, 5, 2, 0, 0); + _globals._sequenceIndexes[12] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[12], false, 5, 2, 0, 0); _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[12]); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[12], SEQUENCE_TRIGGER_SPRITE, 4, 1); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[12], SEQUENCE_TRIGGER_EXPIRE, 0, 2); @@ -694,7 +695,7 @@ void Scene703::enter() { _monsterMode = 0; _scene->loadAnimation(formAnimName('A', -1)); _scene->_activeAnimation->setCurrentFrame(34); - } else if (_scene->_priorSceneId != -2) { + } else if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) { _game._player._stepEnabled = false; _boatDir = 1; if (_globals[kMonsterAlive]) { @@ -1218,7 +1219,7 @@ void Scene704::handleFillBottle(int quote) { void Scene704::enter() { if (_game._objects[OBJ_BOTTLE]._roomNumber == _scene->_currentSceneId) { _globals._spriteIndexes[1] = _scene->_sprites.addSprites(formAnimName('b', 0)); - _globals._sequenceIndexes[1] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[1], false, 6, 0, 0, 0); + _globals._sequenceIndexes[1] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[1], false, 6, 0, 0, 0); _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 1); if (_scene->_priorSceneId == 705) { _scene->_sequences.setPosition(_globals._sequenceIndexes[1], Common::Point(123, 125)); @@ -1241,7 +1242,7 @@ void Scene704::enter() { _boatDirection = 2; _scene->loadAnimation(formAnimName('A', -1)); _scene->_activeAnimation->setCurrentFrame(36); - } else if (_scene->_priorSceneId != -2) { + } else if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) { _game._player._stepEnabled = false; _boatDirection = 1; _scene->loadAnimation(formAnimName('A', -1)); @@ -1567,7 +1568,7 @@ void Scene705::enter() { _globals._sequenceIndexes[3] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[3], false, 9, 1, 0, 0); _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 1, 4); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 71); - } else if (_scene->_priorSceneId != -2) { + } else if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) { _game._player._stepEnabled = false; _scene->_sequences.addTimer(1, 80); _vm->_sound->command(28); @@ -1585,7 +1586,7 @@ void Scene705::enter() { void Scene705::step() { switch (_game._trigger) { case 70: - _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 9, 1, 0, 0); + _globals._sequenceIndexes[3] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[3], false, 9, 1, 0, 0); _scene->_sequences.setAnimRange(_globals._sequenceIndexes[3], 1, 4); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 71); break; @@ -1798,7 +1799,7 @@ void Scene706::handleTakeVase() { case 0: _game._player._stepEnabled = false; _game._player._visible = false; - _globals._sequenceIndexes[3] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[3], false, 4, 2, 0, 0); + _globals._sequenceIndexes[3] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[3], false, 4, 2, 0, 0); _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[3]); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_SPRITE, 7, 1); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[3], SEQUENCE_TRIGGER_EXPIRE, 0, 2); @@ -1854,7 +1855,7 @@ void Scene706::enter() { if (_scene->_priorSceneId == 707) { _game._player._playerPos = Common::Point(277, 103); _game._player._facing = FACING_SOUTHWEST; - } else if (_scene->_priorSceneId != -2) { + } else if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) { _game._player._playerPos = Common::Point(167, 152); _game._player._facing = FACING_NORTH; } @@ -2087,7 +2088,7 @@ void Scene710::enter() { if (_game._objects[OBJ_VASE]._roomNumber == 706) { _globals._spriteIndexes[1] = _scene->_sprites.addSprites(formAnimName('g', -1)); - _globals._sequenceIndexes[1] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[1], false, 6, 0, 0, 0); + _globals._sequenceIndexes[1] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[1], false, 6, 0, 0, 0); } _game._player._visible = false; @@ -2213,7 +2214,7 @@ void Scene751::enter() { _globals._sequenceIndexes[4] = _scene->_sequences.startCycle(_globals._spriteIndexes[4], false, -2); _scene->_sequences.setPosition(_globals._sequenceIndexes[4], Common::Point(155, 129)); _scene->_sequences.addTimer(15, 70); - } else if (_scene->_priorSceneId != -2) { + } else if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) { _game._player._playerPos = Common::Point(22, 131); _game._player._facing = FACING_EAST; _game._player._stepEnabled = false; @@ -2248,7 +2249,7 @@ void Scene751::step() { switch (_game._trigger) { case 70: _scene->_sequences.remove(_globals._sequenceIndexes[4]); - _globals._sequenceIndexes[4] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[4], false, 6, 1, 0, 0); + _globals._sequenceIndexes[4] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[4], false, 6, 1, 0, 0); _scene->_sequences.setPosition(_globals._sequenceIndexes[4], Common::Point(155, 129)); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[4], SEQUENCE_TRIGGER_EXPIRE, 0, 71); break; @@ -2287,7 +2288,7 @@ void Scene751::step() { case 62: _vm->_sound->command(17); - _globals._sequenceIndexes[1] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[1], false, 5, 1, 0, 0); + _globals._sequenceIndexes[1] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[1], false, 5, 1, 0, 0); _scene->_sequences.setPosition(_globals._sequenceIndexes[1], Common::Point(48, 136)); _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 10); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[1], SEQUENCE_TRIGGER_EXPIRE, 0, 63); @@ -2329,7 +2330,7 @@ void Scene751::preActions() { _game._player._readyToWalk = false; _game._player._stepEnabled = false; _scene->_sequences.remove(_globals._sequenceIndexes[2]); - _globals._sequenceIndexes[2] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[2], false, 11, 1, 0, 0); + _globals._sequenceIndexes[2] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[2], false, 11, 1, 0, 0); _scene->_sequences.setAnimRange(_globals._sequenceIndexes[2], -1, 7); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 1); break; @@ -2398,7 +2399,7 @@ void Scene751::actions() { case 3: _vm->_sound->command(17); - _globals._sequenceIndexes[1] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[1], false, 5, 1, 0, 0); + _globals._sequenceIndexes[1] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[1], false, 5, 1, 0, 0); _scene->_sequences.setPosition(_globals._sequenceIndexes[1], Common::Point(48, 136)); _scene->_sequences.setDepth(_globals._sequenceIndexes[1], 10); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[1], SEQUENCE_TRIGGER_EXPIRE, 0, 4); @@ -2527,7 +2528,7 @@ void Scene752::enter() { if (_scene->_priorSceneId == 751) { _game._player._playerPos = Common::Point(13, 145); _game._player._facing = FACING_EAST; - } else if (_scene->_priorSceneId != -2) { + } else if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) { _game._player._playerPos = Common::Point(289, 138); _game._player.walk(Common::Point(262, 148), FACING_WEST); _game._player._facing = FACING_WEST; @@ -2597,7 +2598,7 @@ void Scene752::actions() { case 0: _game._player._stepEnabled = false; _game._player._visible = false; - _globals._sequenceIndexes[12] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[12], false, 5, 2, 0, 0); + _globals._sequenceIndexes[12] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[12], false, 5, 2, 0, 0); _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[12]); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[12], SEQUENCE_TRIGGER_SPRITE, 4, 1); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[12], SEQUENCE_TRIGGER_EXPIRE, 0, 2); @@ -2616,13 +2617,13 @@ void Scene752::actions() { default: break; } - } else if (_action.isAction(VERB_TAKE, NOUN_BONES) && (_action._savedFields._mainObjectSource == CAT_HOTSPOT) && + } else if (_action.isAction(VERB_TAKE, NOUN_BONES) && (_action._savedFields._mainObjectSource == CAT_HOTSPOT) && (!_game._objects.isInInventory(OBJ_BONES) || _game._trigger)) { switch (_game._trigger) { case 0: _game._player._stepEnabled = false; _game._player._visible = false; - _globals._sequenceIndexes[12] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[12], false, 5, 2, 0, 0); + _globals._sequenceIndexes[12] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[12], false, 5, 2, 0, 0); _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[12]); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[12], SEQUENCE_TRIGGER_SPRITE, 4, 1); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[12], SEQUENCE_TRIGGER_EXPIRE, 0, 2); diff --git a/engines/mads/nebular/nebular_scenes7.h b/engines/mads/nebular/nebular_scenes7.h index dfb3c0f16e..b5aeba818c 100644 --- a/engines/mads/nebular/nebular_scenes7.h +++ b/engines/mads/nebular/nebular_scenes7.h @@ -8,12 +8,12 @@ * 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. diff --git a/engines/mads/nebular/nebular_scenes8.cpp b/engines/mads/nebular/nebular_scenes8.cpp index 14f36756de..a904569624 100644 --- a/engines/mads/nebular/nebular_scenes8.cpp +++ b/engines/mads/nebular/nebular_scenes8.cpp @@ -8,12 +8,12 @@ * 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 + * 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. @@ -121,7 +121,7 @@ void Scene801::enter() { _game._player._playerPos = Common::Point(307, 111); _game._player.walk(Common::Point(270, 118), FACING_WEST); _game._player._visible = true; - } else if ((_scene->_priorSceneId != -2) && !_globals[kTeleporterCommand]) { + } else if ((_scene->_priorSceneId != RETURNING_FROM_DIALOG) && !_globals[kTeleporterCommand]) { _game._player._playerPos = Common::Point(8, 117); _game._player.walk(Common::Point(41, 115), FACING_EAST); _game._player._visible = true; @@ -145,10 +145,10 @@ void Scene801::enter() { case 2: _game._player._playerPos = Common::Point(8, 117); _globals[kTeleporterUnderstood] = true; - _globals._sequenceIndexes[1] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[1], false, 8, 1, 0, 0); + _globals._sequenceIndexes[1] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[1], false, 8, 1, 0, 0); _scene->_sequences.setAnimRange(_globals._sequenceIndexes[1], 1, 13); _game._triggerSetupMode = SEQUENCE_TRIGGER_DAEMON; - _scene->_sequences.addSubEntry(_globals._sequenceIndexes[1], SEQUENCE_TRIGGER_EXPIRE, 0, 8090); + _scene->_sequences.addSubEntry(_globals._sequenceIndexes[1], SEQUENCE_TRIGGER_EXPIRE, 0, 80); _vm->_sound->command(30); break; @@ -283,7 +283,7 @@ void Scene801::actions() { _globals[kBetweenRooms] = true; _game._triggerSetupMode = SEQUENCE_TRIGGER_DAEMON; _scene->_sequences.remove(_globals._sequenceIndexes[2]); - _globals._sequenceIndexes[2] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[2], false, 4, 1, 0, 0); + _globals._sequenceIndexes[2] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[2], false, 4, 1, 0, 0); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 90); _scene->_sequences.setAnimRange(_globals._sequenceIndexes[2], 1, 5); _scene->_sequences.setDepth(_globals._sequenceIndexes[2], 13); @@ -346,7 +346,7 @@ void Scene802::enter() { _game._player._playerPos = Common::Point(303, 119); _game._player._facing = FACING_WEST; - } else if (_scene->_priorSceneId != -2) { + } else if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) { _game._player._playerPos = Common::Point(15, 129); _game._player._facing = FACING_EAST; } @@ -419,7 +419,7 @@ void Scene802::actions() { case 0: _game._player._stepEnabled = false; _game._player._visible = false; - _globals._sequenceIndexes[2] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[2], true, 7, 2, 0, 0); + _globals._sequenceIndexes[2] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[2], true, 7, 2, 0, 0); _scene->_sequences.setAnimRange(_globals._sequenceIndexes[2], 1, 2); _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[2]); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_SPRITE, 2, 1); @@ -451,7 +451,7 @@ void Scene802::actions() { case 0: _game._player._stepEnabled = false; _game._player._visible = false; - _globals._sequenceIndexes[5] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[5], true, 7, 2, 0, 0); + _globals._sequenceIndexes[5] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[5], true, 7, 2, 0, 0); _scene->_sequences.setAnimRange(_globals._sequenceIndexes[5], 1, 4); _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[5]); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[5], SEQUENCE_TRIGGER_SPRITE, 4, 1); @@ -557,7 +557,7 @@ void Scene803::enter() { if (!_globals[kFromCockpit]) { if (!_globals[kReturnFromCut]) { - if (_scene->_priorSceneId != -2) { + if (_scene->_priorSceneId != RETURNING_FROM_DIALOG) { _game._player._playerPos = Common::Point(15, 130); _game._player._facing = FACING_EAST; } @@ -692,7 +692,7 @@ void Scene803::step() { if (_game._trigger == 90) { int syncIdx = _globals._sequenceIndexes[4]; - _globals._sequenceIndexes[4] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[4], false, 15, 0, 0, 0); + _globals._sequenceIndexes[4] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[4], false, 15, 0, 0, 0); _scene->_sequences.updateTimeout(_globals._sequenceIndexes[4], syncIdx); _scene->_sequences.setAnimRange(_globals._sequenceIndexes[4], 4, 9); if (_globals[kHoppyDead]) @@ -719,14 +719,14 @@ void Scene803::step() { else _game._winStatus = 3; - _vm->quitGame(); + return; } } if (_game._trigger == 150) { _scene->_sequences.remove(_globals._sequenceIndexes[6]); _vm->_sound->command(18); - _globals._sequenceIndexes[6] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[6], false, 8, 1, 0, 0); + _globals._sequenceIndexes[6] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[6], false, 8, 1, 0, 0); _scene->_sequences.setAnimRange(_globals._sequenceIndexes[6], 1, 19); _scene->_sequences.setDepth(_globals._sequenceIndexes[6], 4); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[6], SEQUENCE_TRIGGER_EXPIRE, 0, 151); @@ -778,7 +778,7 @@ void Scene803::actions() { case 162: _scene->_sequences.remove(_globals._sequenceIndexes[9]); - _globals._sequenceIndexes[9] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[9], true, 6, 1, 0, 0); + _globals._sequenceIndexes[9] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[9], true, 6, 1, 0, 0); _scene->_sequences.setAnimRange(_globals._sequenceIndexes[9], 1, 4); _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[9]); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[9], SEQUENCE_TRIGGER_EXPIRE, 0, 163); @@ -899,15 +899,17 @@ void Scene804::enter() { _scene->_sequences.addTimer(60, 100); } else { _globals._sequenceIndexes[6] = _scene->_sequences.startCycle(_globals._spriteIndexes[6], false, 1); - _globals._sequenceIndexes[7] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[7], false, 4, 0, 0, 0); + _globals._sequenceIndexes[7] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[7], false, 4, 0, 0, 0); _scene->_sequences.addTimer(160, 70); _game._player._stepEnabled = false; } } else { - if (_globals[kBeamIsUp] == 0) + if (_globals[kBeamIsUp]) { _globals._sequenceIndexes[8] = _scene->_sequences.startCycle(_globals._spriteIndexes[8], false, 1); + _scene->_sequences.setDepth(_globals._sequenceIndexes[8], 7); + } - if (_globals[kWindowFixed] == 0) + if (_globals[kWindowFixed]) _globals._sequenceIndexes[4] = _scene->_sequences.startCycle(_globals._spriteIndexes[4], false, 1); _globals._sequenceIndexes[1] = _scene->_sequences.startCycle(_globals._spriteIndexes[1], false, 1); @@ -955,9 +957,9 @@ void Scene804::step() { _globals[kInSpace] = false; _globals[kBeamIsUp] = true; - assert(!_globals[kCopyProtectFailed]); + //assert(!_globals[kCopyProtectFailed]); _game._winStatus = 4; - _vm->quitGame(); + return; } break; @@ -969,7 +971,7 @@ void Scene804::step() { assert(!_globals[kCopyProtectFailed]); _game._winStatus = 4; - _vm->quitGame(); + return; } } @@ -1098,7 +1100,7 @@ void Scene804::actions() { _action.isAction(VERB_OPEN, NOUN_SERVICE_PANEL)) { _scene->_nextSceneId = 805; } else if ((_action.isAction(VERB_ACTIVATE, NOUN_REMOTE)) && _globals[kTopButtonPushed]) { - if (!_globals[kInSpace]) { + if (!_globals[kInSpace]) { // Top button pressed on panel in hanger control if (!_globals[kBeamIsUp]) { _globals[kFromCockpit] = true; @@ -1129,8 +1131,7 @@ void Scene804::actions() { } else { _messWithThrottle = true; } - } - else if (_action.isAction(VERB_APPLY, NOUN_POLYCEMENT, NOUN_CRACK) || + } else if (_action.isAction(VERB_APPLY, NOUN_POLYCEMENT, NOUN_CRACK) || _action.isAction(VERB_PUT, NOUN_POLYCEMENT, NOUN_CRACK)) { if (!_globals[kWindowFixed]) { _resetFrame = 2; @@ -1219,6 +1220,8 @@ void Scene805::enter() { } void Scene805::step() { + UserInterface &userInterface = _vm->_game->_scene._userInterface; + if (_game._trigger == 70) { _scene->_hotspots.activate(OBJ_SHIELD_MODULATOR, false); _globals._sequenceIndexes[1] = _scene->_sequences.startCycle(_globals._spriteIndexes[1], false, 25); @@ -1226,6 +1229,7 @@ void Scene805::step() { _scene->_dynamicHotspots.setPosition(idx, Common::Point(0, 0), FACING_DUMMY); _globals[kShieldModInstalled] = true; _game._objects.setRoom(OBJ_SHIELD_MODULATOR, NOWHERE); + userInterface._selectedInvIndex = -1; _game._player._stepEnabled = true; _vm->_sound->command(24); } @@ -1237,6 +1241,7 @@ void Scene805::step() { _scene->_dynamicHotspots.setPosition(idx, Common::Point(0, 0), FACING_DUMMY); _globals[kTargetModInstalled] = true; _game._objects.setRoom(OBJ_TARGET_MODULE, NOWHERE); + userInterface._selectedInvIndex = -1; _game._player._stepEnabled = true; _vm->_sound->command(24); } @@ -1278,14 +1283,14 @@ void Scene805::actions() { } else if (_action.isAction(VERB_REMOVE, NOUN_SHIELD_MODULATOR) && _globals[kShieldModInstalled]) { _scene->_sequences.remove(_globals._sequenceIndexes[1]); _game._triggerSetupMode = SEQUENCE_TRIGGER_DAEMON; - _globals._sequenceIndexes[1] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[1], false, 7, 1, 0, 0); + _globals._sequenceIndexes[1] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[1], false, 7, 1, 0, 0); _scene->_sequences.setAnimRange(_globals._sequenceIndexes[1], -1, -2); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[1], SEQUENCE_TRIGGER_EXPIRE, 0, 71); _game._player._stepEnabled = false; } else if (_action.isAction(VERB_REMOVE, NOUN_TARGET_MODULE) && _globals[kTargetModInstalled]) { _scene->_sequences.remove(_globals._sequenceIndexes[2]); _game._triggerSetupMode = SEQUENCE_TRIGGER_DAEMON; - _globals._sequenceIndexes[2] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[2], false, 7, 1, 0, 0); + _globals._sequenceIndexes[2] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[2], false, 7, 1, 0, 0); _scene->_sequences.setAnimRange(_globals._sequenceIndexes[2], -1, -2); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[2], SEQUENCE_TRIGGER_EXPIRE, 0, 81); _game._player._stepEnabled = false; @@ -1434,7 +1439,7 @@ void Scene808::actions() { _vm->_sound->command(20); _vm->_sound->command(25); } - _globals._sequenceIndexes[4] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[4], false, 4, 1, 0, 0); + _globals._sequenceIndexes[4] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[4], false, 4, 1, 0, 0); _scene->_sequences.setPosition(_globals._sequenceIndexes[4], Common::Point(248, 211)); _scene->_sequences.setDepth(_globals._sequenceIndexes[4], 2); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[4], SEQUENCE_TRIGGER_EXPIRE, 0, 71); @@ -1469,7 +1474,7 @@ void Scene808::actions() { _vm->_sound->command(20); } _globals[kTopButtonPushed] = false; - _globals._sequenceIndexes[4] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[4], false, 4, 1, 0, 0); + _globals._sequenceIndexes[4] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[4], false, 4, 1, 0, 0); _scene->_sequences.setPosition(_globals._sequenceIndexes[4], Common::Point(248, 186)); _scene->_sequences.setDepth(_globals._sequenceIndexes[4], 2); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[4], SEQUENCE_TRIGGER_EXPIRE, 0, 91); @@ -1500,7 +1505,7 @@ void Scene808::actions() { _vm->_sound->command(20); } _globals[kTopButtonPushed] = true; - _globals._sequenceIndexes[4] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[4], false, 4, 1, 0, 0); + _globals._sequenceIndexes[4] = _scene->_sequences.addReverseSpriteCycle(_globals._spriteIndexes[4], false, 4, 1, 0, 0); _scene->_sequences.setPosition(_globals._sequenceIndexes[4], Common::Point(248, 163)); _scene->_sequences.setDepth(_globals._sequenceIndexes[4], 2); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[4], SEQUENCE_TRIGGER_EXPIRE, 0, 81); @@ -1517,7 +1522,7 @@ void Scene808::actions() { switch (_game._trigger) { case 0: _game._player._stepEnabled = false; - _globals._sequenceIndexes[4] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[4], false, 4, 2, 0, 0); + _globals._sequenceIndexes[4] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[4], false, 4, 2, 0, 0); _scene->_sequences.setPosition(_globals._sequenceIndexes[4], Common::Point(168, 211)); _scene->_sequences.setDepth(_globals._sequenceIndexes[4], 2); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[4], SEQUENCE_TRIGGER_EXPIRE, 0, 70); @@ -1534,7 +1539,7 @@ void Scene808::actions() { switch (_game._trigger) { case 0: _game._player._stepEnabled = false; - _globals._sequenceIndexes[4] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[4], false, 4, 2, 0, 0); + _globals._sequenceIndexes[4] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[4], false, 4, 2, 0, 0); _scene->_sequences.setPosition(_globals._sequenceIndexes[4], Common::Point(172, 163)); _scene->_sequences.setDepth(_globals._sequenceIndexes[4], 2); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[4], SEQUENCE_TRIGGER_EXPIRE, 0, 80); @@ -1551,7 +1556,7 @@ void Scene808::actions() { switch (_game._trigger) { case 0: _game._player._stepEnabled = false; - _globals._sequenceIndexes[4] = _scene->_sequences.startReverseCycle(_globals._spriteIndexes[4], false, 4, 2, 0, 0); + _globals._sequenceIndexes[4] = _scene->_sequences.startPingPongCycle(_globals._spriteIndexes[4], false, 4, 2, 0, 0); _scene->_sequences.setPosition(_globals._sequenceIndexes[4], Common::Point(172, 186)); _scene->_sequences.setDepth(_globals._sequenceIndexes[4], 2); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[4], SEQUENCE_TRIGGER_EXPIRE, 0, 90); @@ -1601,7 +1606,8 @@ void Scene810::enter() { } void Scene810::step() { - if ((_scene->_activeAnimation->getCurrentFrame() == 200) && _moveAllowed) { + if (_scene->_activeAnimation && (_scene->_activeAnimation->getCurrentFrame() == 200) + && _moveAllowed) { _scene->_sequences.addTimer(100, 70); _moveAllowed = false; } diff --git a/engines/mads/nebular/nebular_scenes8.h b/engines/mads/nebular/nebular_scenes8.h index 7f2c34a843..439815f05c 100644 --- a/engines/mads/nebular/nebular_scenes8.h +++ b/engines/mads/nebular/nebular_scenes8.h @@ -8,12 +8,12 @@ * 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. diff --git a/engines/mads/nebular/sound_nebular.cpp b/engines/mads/nebular/sound_nebular.cpp index c540eb4382..240c18f6dc 100644 --- a/engines/mads/nebular/sound_nebular.cpp +++ b/engines/mads/nebular/sound_nebular.cpp @@ -8,12 +8,12 @@ * 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. @@ -24,6 +24,7 @@ #include "audio/decoders/raw.h" #include "common/algorithm.h" #include "common/debug.h" +#include "common/md5.h" #include "common/memstream.h" #include "mads/sound.h" #include "mads/nebular/sound_nebular.h" @@ -35,6 +36,7 @@ namespace Nebular { bool AdlibChannel::_channelsEnabled; AdlibChannel::AdlibChannel() { + _owner = nullptr; _activeCount = 0; _field1 = 0; _field2 = 0; @@ -42,6 +44,7 @@ AdlibChannel::AdlibChannel() { _field4 = 0; _sampleIndex = 0; _volume = 0; + _volumeOffset = 0; _field7 = 0; _field8 = 0; _field9 = 0; @@ -54,11 +57,11 @@ AdlibChannel::AdlibChannel() { _pSrc = nullptr; _ptr3 = nullptr; _ptr4 = nullptr; + _ptrEnd = nullptr; _field17 = 0; _field19 = 0; _soundData = nullptr; _field1D = 0; - _field1E = 0; _field1F = 0; _field20 = 0; @@ -94,6 +97,7 @@ void AdlibChannel::setPtr2(byte *pData) { void AdlibChannel::load(byte *pData) { _ptr1 = _pSrc = _ptr3 = pData; _ptr4 = _soundData = pData; + _volumeOffset = 0; _fieldA = 0xFF; _activeCount = 1; _fieldD = 64; @@ -101,17 +105,20 @@ void AdlibChannel::load(byte *pData) { _field1F = 0; _field2 = _field3 = 0; _volume = _field7 = 0; - _field1D = _field1E = 0; + _field1D = 0; _fieldE = 0; _field9 = 0; _fieldB = 0; _field17 = 0; _field19 = 0; + + CachedDataEntry &cacheEntry = _owner->getCachedData(pData); + _ptrEnd = cacheEntry._dataEnd; } void AdlibChannel::check(byte *nullPtr) { if (_activeCount && _fieldE) { - if (!_field1E) { + if (!_volumeOffset) { _pSrc = nullPtr; _fieldE = 0; } else { @@ -160,6 +167,7 @@ ASound::ASound(Audio::Mixer *mixer, FM_OPL *opl, const Common::String &filename, _samplePtr = nullptr; _frameCounter = 0; _isDisabled = false; + _masterVolume = 255; _v1 = 0; _v2 = 0; _activeChannelNumber = 0; @@ -191,6 +199,9 @@ ASound::ASound(Audio::Mixer *mixer, FM_OPL *opl, const Common::String &filename, _channelData[i]._freqBase = 0; _channelData[i]._field6 = 0; } + + for (int i = 0; i < ADLIB_CHANNEL_COUNT; ++i) + _channels[i]._owner = this; AdlibChannel::_channelsEnabled = false; @@ -218,6 +229,32 @@ ASound::~ASound() { _mixer->stopHandle(_soundHandle); } +void ASound::validate() { + Common::File f; + static const char *const MD5[] = { + "205398468de2c8873b7d4d73d5be8ddc", + "f9b2d944a2fb782b1af5c0ad592306d3", + "7431f8dad77d6ddfc24e6f3c0c4ac7df", + "eb1f3f5a4673d3e73d8ac1818c957cf4", + "f936dd853073fa44f3daac512e91c476", + "3dc139d3e02437a6d9b732072407c366", + "af0edab2934947982e9a405476702e03", + "8cbc25570b50ba41c9b5361cad4fbedc", + "a31e4783e098f633cbb6689adb41dd4f" + }; + + for (int i = 1; i <= 9; ++i) { + Common::String filename = Common::String::format("ASOUND.00%d", i); + if (!f.open(filename)) + error("Could not process - %s", filename.c_str()); + Common::String md5str = Common::computeStreamMD5AsString(f, 8192); + f.close(); + + if (md5str != MD5[i - 1]) + error("Invalid sound file - %s", filename.c_str()); + } +} + void ASound::adlibInit() { write(4, 0x60); write(4, 0x80); @@ -256,6 +293,17 @@ void ASound::noise() { } } +CachedDataEntry &ASound::getCachedData(byte *pData) { + Common::List<CachedDataEntry>::iterator i; + for (i = _dataCache.begin(); i != _dataCache.end(); ++i) { + CachedDataEntry &e = *i; + if (e._data == pData) + return e; + } + + error("Could not find previously loaded data"); +} + void ASound::write(int reg, int val) { _queue.push(RegisterValue(reg, val)); } @@ -304,6 +352,7 @@ byte *ASound::loadData(int offset, int size) { CachedDataEntry rec; rec._offset = offset; rec._data = new byte[size]; + rec._dataEnd = rec._data + size - 1; _soundFile.seek(_dataOffset + offset); _soundFile.read(rec._data, size); _dataCache.push_back(rec); @@ -422,6 +471,10 @@ void ASound::pollActiveChannel() { warning("pollActiveChannel(): No data found for sound channel"); break; } + if (pSrc > chan->_ptrEnd) { + warning("Read beyond end of loaded sound data"); + } + if (!(*pSrc & 0x80) || (*pSrc <= 0xF0)) { if (updateFlag) updateActiveChannel(); @@ -489,7 +542,7 @@ void ASound::pollActiveChannel() { chan->_field1 = 0; chan->_field2 = chan->_field3 = 0; chan->_volume = chan->_field7 = 0; - chan->_field1D = chan->_field1E = 0; + chan->_field1D = chan->_volumeOffset = 0; chan->_field8 = 0; chan->_field9 = 0; chan->_fieldB = 0; @@ -543,7 +596,7 @@ void ASound::pollActiveChannel() { break; case 8: - chan->_field1D = *++pSrc; + chan->_field1D = (int8)*++pSrc; chan->_pSrc += 2; break; @@ -564,7 +617,7 @@ void ASound::pollActiveChannel() { if (chan->_fieldE) { chan->_pSrc += 2; } else { - chan->_field1E = *pSrc >> 1; + chan->_volumeOffset = *pSrc >> 1; updateFlag = true; chan->_pSrc += 2; } @@ -608,7 +661,7 @@ void ASound::pollActiveChannel() { if (!--chan->_field9) { chan->_field9 = chan->_fieldA; if (chan->_field2) { - int8 newVal = (int8)chan->_field2 + (int8)chan->_field1E; + int8 newVal = (int8)chan->_field2 + (int8)chan->_volumeOffset; if (newVal < 0) { chan->_field9 = 0; newVal = 0; @@ -617,7 +670,7 @@ void ASound::pollActiveChannel() { newVal = 63; } - chan->_field1E = newVal; + chan->_volumeOffset = newVal; updateFlag = true; } } @@ -682,8 +735,8 @@ void ASound::updateChannelState() { resultCheck(); } else { int reg = 0xA0 + _activeChannelNumber; - int vTimes = (_activeChannelPtr->_field4 + _activeChannelPtr->_field1F) / 12; - int vOffset = (_activeChannelPtr->_field4 + _activeChannelPtr->_field1F) % 12; + int vTimes = (byte)(_activeChannelPtr->_field4 + _activeChannelPtr->_field1F) / 12; + int vOffset = (byte)(_activeChannelPtr->_field4 + _activeChannelPtr->_field1F) % 12; int val = _vList1[vOffset] + _activeChannelPtr->_field1D; write2(8, reg, val & 0xFF); @@ -700,32 +753,18 @@ static const int outputIndexes[] = { static const int outputChannels[] = { 0, 1, 2, 3, 4, 5, 8, 9, 10, 11, 12, 13, 16, 17, 18, 19, 20, 21, 0 }; -static const int volumeList[] = { - 0x3F, 0x3F, 0x36, 0x31, 0x2D, 0x2A, 0x28, 0x26, 0x24, 0x22, 0x21, 0x20, 0x1F, 0x1E, 0x1D, 0x1C, - 0x1B, 0x1A, 0x19, 0x19, 0x18, 0x17, 0x17, 0x16, 0x16, 0x15, 0x15, 0x14, 0x14, 0x13, 0x12, 0x12, - 0x11, 0x11, 0x10, 0x10, 0x0F, 0x0F, 0x0E, 0x0E, 0x0D, 0x0D, 0x0C, 0x0C, 0x0B, 0x0B, 0x0A, 0x0A, - 0x0A, 0x09, 0x09, 0x09, 0x09, 0x09, 0x08, 0x08, 0x08, 0x08, 0x08, 0x07, 0x07, 0x07, 0x07, 0x07, - 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x04, - 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, - 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -}; void ASound::updateActiveChannel() { int reg = 0x40 + outputChannels[outputIndexes[_activeChannelNumber * 2 + 1]]; int portVal = _ports[reg] & 0xFFC0; - int newVolume = CLIP(_activeChannelPtr->_volume + _activeChannelPtr->_field1E, 0, 63); + int newVolume = CLIP(_activeChannelPtr->_volume + _activeChannelPtr->_volumeOffset, 0, 63); + newVolume = newVolume * _masterVolume / 255; // Note: Original had a whole block not seeming to be used, since the initialisation // sets a variable to 5660h, and doesn't change it, so the branch is never taken - int val = CLIP(newVolume - volumeList[_activeChannelPtr->_fieldD], 0, 63); - val = (63 - val) | portVal; + portVal |= 63 - newVolume; - int val2 = CLIP(newVolume - volumeList[-(_activeChannelPtr->_fieldD - 127)], 0, 63); - val2 = (63 - val2) | portVal; - write2(0, reg, val); - write2(2, reg, val2); + write2(8, reg, portVal); } void ASound::loadSample(int sampleIndex) { @@ -821,6 +860,12 @@ int ASound::readBuffer(int16 *buffer, const int numSamples) { return numSamples; } +void ASound::setVolume(int volume) { + _masterVolume = volume; + if (!volume) + command0(); +} + int ASound::command0() { bool isDisabled = _isDisabled; _isDisabled = true; @@ -978,22 +1023,22 @@ int ASound1::command10() { int ASound1::command11() { command111213(); - _channels[0]._field1E = 0; - _channels[1]._field1E = 0; + _channels[0]._volumeOffset = 0; + _channels[1]._volumeOffset = 0; return 0; } int ASound1::command12() { command111213(); - _channels[0]._field1E = 40; - _channels[1]._field1E = 0; + _channels[0]._volumeOffset = 40; + _channels[1]._volumeOffset = 0; return 0; } int ASound1::command13() { command111213(); - _channels[0]._field1E = 40; - _channels[1]._field1E = 50; + _channels[0]._volumeOffset = 40; + _channels[1]._volumeOffset = 50; return 0; } diff --git a/engines/mads/nebular/sound_nebular.h b/engines/mads/nebular/sound_nebular.h index abb6516030..9bc1a49458 100644 --- a/engines/mads/nebular/sound_nebular.h +++ b/engines/mads/nebular/sound_nebular.h @@ -8,12 +8,12 @@ * 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. @@ -37,11 +37,15 @@ class SoundManager; namespace Nebular { +class ASound; + /** * Represents the data for a channel on the Adlib */ class AdlibChannel { public: + ASound *_owner; + int _activeCount; int _field1; int _field2; @@ -61,11 +65,12 @@ public: byte *_pSrc; byte *_ptr3; byte *_ptr4; + byte *_ptrEnd; int _field17; int _field19; byte *_soundData; int _field1D; - int _field1E; + int _volumeOffset; int _field1F; // TODO: Only used by asound.003. Figure out usage @@ -128,17 +133,20 @@ struct RegisterValue { #define ADLIB_CHANNEL_MIDWAY 5 #define CALLBACKS_PER_SECOND 60 +struct CachedDataEntry { + int _offset; + byte *_data; + byte *_dataEnd; +}; + /** * Base class for the sound player resource files */ class ASound : public Audio::AudioStream { private: - struct CachedDataEntry { - int _offset; - byte *_data; - }; Common::List<CachedDataEntry> _dataCache; uint16 _randomSeed; + int _masterVolume; /** * Does the initial Adlib initialisation @@ -318,6 +326,11 @@ public: virtual ~ASound(); /** + * Validates the Adlib sound files + */ + static void validate(); + + /** * Execute a player command. Most commands represent sounds to play, but some * low number commands also provide control operations. * @param commandId Player ommand to execute. @@ -345,6 +358,11 @@ public: */ int getFrameCounter() { return _frameCounter; } + /** + * Return the cached data block record for previously loaded sound data + */ + CachedDataEntry &getCachedData(byte *pData); + // AudioStream interface /** * Main buffer read @@ -365,6 +383,11 @@ public: * Return sample rate */ virtual int getRate() const { return 11025; } + + /** + * Set the volume + */ + void setVolume(int volume); }; class ASound1 : public ASound { diff --git a/engines/mads/palette.cpp b/engines/mads/palette.cpp index 1787b3c298..7651fe8e65 100644 --- a/engines/mads/palette.cpp +++ b/engines/mads/palette.cpp @@ -8,12 +8,12 @@ * 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. @@ -178,31 +178,29 @@ int PaletteUsage::process(Common::Array<RGB6> &palette, uint flags) { } if (!changed && !noUsageFlag) { - int var2 = (palette[palIndex]._flags & 0x20) || - (((flags & 0x2000) || (palette[palIndex]._flags & 0x4000)) && + int bestHash = (palette[palIndex]._flags & 0x20) || + (((flags & 0x2000) || (palette[palIndex]._flags & 0x40)) && ((flags & 0x1000) || (palCount == 0))) ? 0x7fff : 1; int var36 = (palette[palIndex]._flags & 0x80) ? 0 : 2; for (int idx = palLow; idx < palIdx; ++idx) { uint32 v = _vm->_palette->_palFlags[idx]; if ((v & var3A) && !(v & var36)) { - int var10; - - if (var2 > 1) { - var10 = rgbFactor(&_vm->_palette->_mainPalette[idx * 3], palette[palIndex]); - } - else if (_vm->_palette->_mainPalette[idx * 3] != palette[palIndex].r || + int hash; + if (bestHash > 1) { + hash = rgbFactor(&_vm->_palette->_mainPalette[idx * 3], palette[palIndex]); + } else if (_vm->_palette->_mainPalette[idx * 3] != palette[palIndex].r || _vm->_palette->_mainPalette[idx * 3 + 1] != palette[palIndex].g || _vm->_palette->_mainPalette[idx * 3 + 2] != palette[palIndex].b) { - var10 = 1; + hash = 1; } else { - var10 = 0; + hash = 0; } - if (var2 > var10) { + if (bestHash > hash) { changed = true; newPalIndex = idx; - var2 = var10; + bestHash = hash; } } } @@ -233,7 +231,7 @@ int PaletteUsage::process(Common::Array<RGB6> &palette, uint flags) { // CHECKME: When pressing on F1 in the first screen, newPalIndex is set to 0xFF at this point // which is a valid value for the index. Maybe a better check would be "< 256" ? //assert(newPalIndex != -1); - + int var52 = (noUsageFlag && palette[palIndex]._u2) ? 2 : 0; _vm->_palette->_palFlags[newPalIndex] |= var52 | rgbMask; @@ -342,7 +340,7 @@ int PaletteUsage::checkRGB(const byte *rgb, int palStart, bool flag, int *palInd if ((!(*flagsP & 1) || flag) && !(*flagsP & 2)) { if (!memcmp(palP, rgb, 3)) { *flagsP |= mask; - + if (palIndex) *palIndex = result; match = true; @@ -430,6 +428,14 @@ void Fader::grabPalette(byte *colors, uint start, uint num) { g_system->getPaletteManager()->grabPalette(colors, start, num); } +void Fader::getFullPalette(byte palette[PALETTE_SIZE]) { + grabPalette(&palette[0], 0, PALETTE_COUNT); +} + +void Fader::setFullPalette(byte palette[PALETTE_SIZE]) { + setPalette(&palette[0], 0, PALETTE_COUNT); +} + void Fader::fadeOut(byte palette[PALETTE_SIZE], byte *paletteMap, int baseColor, int numColors, int baseGrey, int numGreys, int tickDelay, int steps) { @@ -491,7 +497,7 @@ void Fader::fadeIn(byte palette[PALETTE_SIZE], byte destPalette[PALETTE_SIZE], int baseColor, int numColors, int baseGrey, int numGreys, int tickDelay, int steps) { GreyEntry map[PALETTE_COUNT]; - byte tempPal[PALETTE_SIZE];; + byte tempPal[PALETTE_SIZE]; int8 signs[PALETTE_COUNT][3]; byte palIndex[PALETTE_COUNT][3]; int intensity; @@ -505,16 +511,12 @@ void Fader::fadeIn(byte palette[PALETTE_SIZE], byte destPalette[PALETTE_SIZE], for (int colorCtr = 0; colorCtr < 3; ++colorCtr) { if (_colorFlags[colorCtr]) { int shiftSign = _colorValues[colorCtr]; - if (shiftSign >= 0) { + if (shiftSign >= 0) intensity = map[index]._intensity << shiftSign; - } - else { + else intensity = map[index]._intensity >> abs(shiftSign); - } - } - else { + } else intensity = _colorValues[colorCtr]; - } int diff = _rgb64Map[destPalette[palCtr * 3 + colorCtr]] - intensity; palIndex[palCtr][colorCtr] = (byte)ABS(diff); @@ -891,4 +893,30 @@ void Palette::refreshSceneColors() { setPalette(_mainPalette + (val * 3), val, 256 - val); } +int Palette::closestColor(const byte *matchColor, const byte *refPalette, + int paletteInc, int count) { + int bestColor = 0; + int bestDistance = 0x7fff; + + for (int idx = 0; idx < count; ++idx) { + // Figure out figure for 'distance' between two colors + int distance = 0; + for (int rgbIdx = 0; rgbIdx < RGB_SIZE; ++rgbIdx) { + int diff = refPalette[rgbIdx] - matchColor[rgbIdx]; + distance += diff * diff; + } + + // If the given color is a closer match to our color, store the index + if (distance <= bestDistance) { + bestDistance = distance; + bestColor = idx; + } + + refPalette += paletteInc; + } + + return bestColor; +} + + } // End of namespace MADS diff --git a/engines/mads/palette.h b/engines/mads/palette.h index 27d25f266b..6c98947384 100644 --- a/engines/mads/palette.h +++ b/engines/mads/palette.h @@ -8,12 +8,12 @@ * 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. @@ -36,6 +36,7 @@ class MADSEngine; #define PALETTE_RESERVED_HIGH_COUNT 10 #define PALETTE_COUNT 256 +#define RGB_SIZE 3 #define PALETTE_SIZE (256 * 3) /** @@ -212,16 +213,12 @@ public: /** * Gets the entire palette at once */ - void getFullPalette(byte palette[PALETTE_SIZE]) { - grabPalette(&palette[0], 0, PALETTE_COUNT); - } + void getFullPalette(byte palette[PALETTE_SIZE]); /** * Sets the entire palette at once */ - void setFullPalette(byte palette[PALETTE_SIZE]) { - setPalette(&palette[0], 0, PALETTE_COUNT); - } + void setFullPalette(byte palette[PALETTE_SIZE]); /** * Calculates a merge/hash for a given palette entry @@ -318,6 +315,9 @@ public: void unlock(); void refreshSceneColors(); + + static int closestColor(const byte *matchColor, const byte *refPalette, + int paletteInc, int count); }; } // End of namespace MADS diff --git a/engines/mads/phantom/game_phantom.cpp b/engines/mads/phantom/game_phantom.cpp index 2384b94dec..959a726edf 100644 --- a/engines/mads/phantom/game_phantom.cpp +++ b/engines/mads/phantom/game_phantom.cpp @@ -8,12 +8,12 @@ * 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. diff --git a/engines/mads/phantom/game_phantom.h b/engines/mads/phantom/game_phantom.h index 654ec86ba3..44b2321f42 100644 --- a/engines/mads/phantom/game_phantom.h +++ b/engines/mads/phantom/game_phantom.h @@ -8,12 +8,12 @@ * 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. diff --git a/engines/mads/phantom/phantom_scenes.cpp b/engines/mads/phantom/phantom_scenes.cpp index c8faa35fcb..57c2bb2c9b 100644 --- a/engines/mads/phantom/phantom_scenes.cpp +++ b/engines/mads/phantom/phantom_scenes.cpp @@ -8,12 +8,12 @@ * 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. diff --git a/engines/mads/phantom/phantom_scenes.h b/engines/mads/phantom/phantom_scenes.h index 0d7bc253dd..55218f219a 100644 --- a/engines/mads/phantom/phantom_scenes.h +++ b/engines/mads/phantom/phantom_scenes.h @@ -8,12 +8,12 @@ * 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. diff --git a/engines/mads/player.cpp b/engines/mads/player.cpp index bde313af8d..bb747f4b52 100644 --- a/engines/mads/player.cpp +++ b/engines/mads/player.cpp @@ -8,12 +8,12 @@ * 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. @@ -235,12 +235,18 @@ void Player::selectSeries() { void Player::updateFrame() { // WORKAROUND: Prevent character info being referenced when not present - if ((_spritesStart + _spritesIdx) < 0 || !_spriteSetsPresent[_spritesStart + _spritesIdx]) + int idx = _spritesStart + _spritesIdx; + if (idx < 0 || (idx < PLAYER_SPRITES_FILE_COUNT && !_spriteSetsPresent[idx])) return; Scene &scene = _vm->_game->_scene; - SpriteAsset &spriteSet = *scene._sprites[_spritesStart + _spritesIdx]; - assert(spriteSet._charInfo); + assert(scene._sprites[idx] != nullptr); + SpriteAsset &spriteSet = *scene._sprites[idx]; + + // WORKAROUND: Certain cutscenes set up player sprites that don't have any + // character info. In such cases, simply ignore player updates + if (!spriteSet._charInfo) + return; if (!spriteSet._charInfo->_numEntries) { _frameNumber = 1; @@ -509,12 +515,12 @@ void Player::idle() { return; } - if ((_spritesStart + _spritesIdx) < 0 || !_spriteSetsPresent[_spritesStart + _spritesIdx]) + int idx = _spritesStart + _spritesIdx; + if (idx < 0 || (idx < PLAYER_SPRITES_FILE_COUNT && !_spriteSetsPresent[idx])) return; - SpriteAsset &spriteSet = *scene._sprites[_spritesStart + _spritesIdx]; - assert(spriteSet._charInfo); - if (spriteSet._charInfo->_numEntries == 0) + SpriteAsset &spriteSet = *scene._sprites[idx]; + if (spriteSet._charInfo == nullptr || spriteSet._charInfo->_numEntries == 0) // No entries, so exit immediately return; @@ -528,11 +534,11 @@ void Player::idle() { _frameNumber += direction; _forceRefresh = true; - if (spriteSet._charInfo->_stopFrames[frameIndex] < _frameNumber) { + if (_frameNumber > spriteSet._charInfo->_stopFrames[frameIndex]) { _trigger = _upcomingTrigger; updateFrame(); } - if (spriteSet._charInfo->_startFrames[frameIndex] < _frameNumber) { + if (_frameNumber < spriteSet._charInfo->_startFrames[frameIndex]) { _trigger = _upcomingTrigger; updateFrame(); } @@ -658,7 +664,7 @@ void Player::startMovement() { _deltaDistance = (majorChange == 0) ? 0 : _totalDistance / majorChange; if (_playerPos.x > _targetPos.x) - _pixelAccum = MAX(_posChange.x, _posChange.y); + _pixelAccum = MIN(_posChange.x, _posChange.y); else _pixelAccum = 0; @@ -703,7 +709,7 @@ void Player::releasePlayerSprites() { _spritesLoaded = false; _spritesChanged = true; - if (scene._sprites._assetCount > 0) { + if (scene._sprites.size() > 0) { warning("Player::releasePlayerSprites(): leftover sprites remain, clearing list"); scene._sprites.clear(); } @@ -779,14 +785,14 @@ void Player::removePlayerSprites() { int heroSpriteId = _spritesStart; for (int i = 0; i < 8; i++) { if (_spriteSetsPresent[i]) { - scene._sprites.remove(heroSpriteId++); + delete scene._sprites[heroSpriteId]; + scene._sprites[heroSpriteId] = nullptr; _spriteSetsPresent[i] = false; + ++heroSpriteId; } } - if (scene._activeAnimation != nullptr) - scene._activeAnimation->resetSpriteSetsCount(); - + scene._spriteSlots.clear(); scene._spriteSlots.fullRefresh(); _visible = false; } diff --git a/engines/mads/player.h b/engines/mads/player.h index 671ac9d16e..e5765a9bca 100644 --- a/engines/mads/player.h +++ b/engines/mads/player.h @@ -8,12 +8,12 @@ * 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. diff --git a/engines/mads/rails.cpp b/engines/mads/rails.cpp index 322e6e7cb3..9b2ec71de6 100644 --- a/engines/mads/rails.cpp +++ b/engines/mads/rails.cpp @@ -8,12 +8,12 @@ * 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. diff --git a/engines/mads/rails.h b/engines/mads/rails.h index e6cab08f85..c95f5c47a6 100644 --- a/engines/mads/rails.h +++ b/engines/mads/rails.h @@ -8,12 +8,12 @@ * 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. diff --git a/engines/mads/resources.cpp b/engines/mads/resources.cpp index 1fb75e6ba2..d5352fb205 100644 --- a/engines/mads/resources.cpp +++ b/engines/mads/resources.cpp @@ -8,12 +8,12 @@ * 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. diff --git a/engines/mads/resources.h b/engines/mads/resources.h index 8d9ab1e39f..95ea17d3c4 100644 --- a/engines/mads/resources.h +++ b/engines/mads/resources.h @@ -8,12 +8,12 @@ * 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. diff --git a/engines/mads/scene.cpp b/engines/mads/scene.cpp index e8ba988771..ee5f1a5440 100644 --- a/engines/mads/scene.cpp +++ b/engines/mads/scene.cpp @@ -8,12 +8,12 @@ * 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. @@ -31,7 +31,7 @@ namespace MADS { Scene::Scene(MADSEngine *vm) - : _vm(vm), _action(_vm), _depthSurface(vm), + : _vm(vm), _action(_vm), _depthSurface(), _dirtyAreas(_vm), _dynamicHotspots(vm), _hotspots(vm), _kernelMessages(vm), _sequences(vm), _sprites(vm), _spriteSlots(vm), _textDisplay(vm), _userInterface(vm) { @@ -52,7 +52,7 @@ Scene::Scene(MADSEngine *vm) _activeAnimation = nullptr; _textSpacing = -1; _frameStartTime = 0; - _layer = LAYER_GUI; + _mode = SCREENMODE_VGA; _lookFlag = false; _bandsRange = 0; _scaleRange = 0; @@ -182,7 +182,7 @@ void Scene::loadScene(int sceneId, const Common::String &prefix, bool palFlag) { flags |= ANIMFLAG_LOAD_BACKGROUND_ONLY; _animationData = Animation::init(_vm, this); - DepthSurface depthSurface(_vm); + DepthSurface depthSurface; _animationData->load(_userInterface, depthSurface, prefix, flags, nullptr, nullptr); _vm->_palette->_paletteUsage.load(&_scenePaletteUsage); @@ -360,6 +360,9 @@ void Scene::loop() { if (_vm->_dialogs->_pendingDialog != DIALOG_NONE && !_vm->_game->_trigger && _vm->_game->_player._stepEnabled) _reloadSceneFlag = true; + + if (_vm->_game->_winStatus) + break; } } @@ -587,12 +590,14 @@ void Scene::doSceneStep() { } void Scene::checkKeyboard() { - if (_vm->_events->isKeyPressed()) { - Common::Event evt = _vm->_events->_pendingKeys.pop(); + EventsManager &events = *_vm->_events; + + if (events.isKeyPressed()) { + Common::KeyState evt = events.getKey(); _vm->_game->handleKeypress(evt); } - if ((_vm->_events->_mouseStatus & 3) == 3 && _vm->_game->_player._stepEnabled) { + if ((events._mouseStatus & 3) == 3 && _vm->_game->_player._stepEnabled) { _reloadSceneFlag = true; _vm->_dialogs->_pendingDialog = DIALOG_GAME_MENU; _action.clear(); @@ -606,7 +611,7 @@ void Scene::loadAnimation(const Common::String &resName, int trigger) { if (_activeAnimation) freeAnimation(); - DepthSurface depthSurface(_vm); + DepthSurface depthSurface; UserInterface interfaceSurface(_vm); _activeAnimation = Animation::init(_vm, this); @@ -659,6 +664,7 @@ void Scene::freeCurrentScene() { } _vm->_palette->_paletteUsage.load(nullptr); + _cyclingActive = false; _hotspots.clear(); _backgroundSurface.free(); _depthSurface.free(); diff --git a/engines/mads/scene.h b/engines/mads/scene.h index 9fd99ad8e5..c0784c3812 100644 --- a/engines/mads/scene.h +++ b/engines/mads/scene.h @@ -8,12 +8,12 @@ * 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. @@ -40,6 +40,8 @@ namespace MADS { +enum { RETURNING_FROM_DIALOG = -2, RETURNING_FROM_LOADING = -1 }; + class Scene { private: /** @@ -121,7 +123,7 @@ public: bool _reloadSceneFlag; Common::Point _posAdjust; uint32 _frameStartTime; - Layer _layer; + ScreenMode _mode; bool _lookFlag; Common::Point _customDest; Common::Array<PaletteUsage::UsageEntry> _paletteUsageF; diff --git a/engines/mads/scene_data.cpp b/engines/mads/scene_data.cpp index b0a5aa35c6..e48bcd8c6f 100644 --- a/engines/mads/scene_data.cpp +++ b/engines/mads/scene_data.cpp @@ -86,7 +86,8 @@ void ARTHeader::load(Common::SeekableReadStream *f, bool isV2) { void SceneInfo::SpriteInfo::load(Common::SeekableReadStream *f) { f->skip(3); _spriteSetIndex = f->readByte(); - f->skip(2); + _frameNumber = f->readSByte(); + f->skip(1); _position.x = f->readSint16LE(); _position.y = f->readSint16LE(); _depth = f->readByte(); @@ -263,9 +264,9 @@ void SceneInfo::load(int sceneId, int variant, const Common::String &resName, SpriteAsset *asset = spriteSets[si._spriteSetIndex]; assert(asset && _depthStyle != 2); - MSprite *spr = asset->getFrame(asset->getCount() - 1); - bgSurface.copyFrom(spr, si._position, si._depth, &depthSurface, - si._scale, spr->getTransparencyIndex()); + MSprite *spr = asset->getFrame(si._frameNumber); + bgSurface.copyFrom(spr, si._position, si._depth, &depthSurface, + si._scale, false, spr->getTransparencyIndex()); } // Free the sprite sets @@ -468,6 +469,7 @@ void SceneInfo::loadMadsV2Background(int sceneId, const Common::String &resName, for (int i = 0; i < tileIndex; i++) ++tile; ((*tile).get())->copyTo(&bgSurface, Common::Point(x * tileWidth, y * tileHeight)); + ((*tile).get())->free(); } } tileSet.clear(); diff --git a/engines/mads/scene_data.h b/engines/mads/scene_data.h index 41e094b8f5..41a08f74eb 100644 --- a/engines/mads/scene_data.h +++ b/engines/mads/scene_data.h @@ -144,6 +144,7 @@ class SceneInfo { public: int _spriteSetIndex; Common::Point _position; + int _frameNumber; int _depth; int _scale; diff --git a/engines/mads/screen.cpp b/engines/mads/screen.cpp index c9a0863d85..3c27001ae0 100644 --- a/engines/mads/screen.cpp +++ b/engines/mads/screen.cpp @@ -8,12 +8,12 @@ * 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. @@ -244,7 +244,7 @@ void DirtyAreas::reset() { ScreenObject::ScreenObject() { _category = CAT_NONE; _descId = 0; - _layer = 0; + _mode = 0; _active = false; } @@ -265,17 +265,17 @@ ScreenObjects::ScreenObjects(MADSEngine *vm) : _vm(vm) { _baseTime = 0; } -void ScreenObjects::add(const Common::Rect &bounds, Layer layer, ScrCategory category, int descId) { - //assert(size() < 100); - +ScreenObject *ScreenObjects::add(const Common::Rect &bounds, ScreenMode mode, ScrCategory category, int descId) { ScreenObject so; so._bounds = bounds; so._category = category; so._descId = descId; - so._layer = layer; + so._mode = mode; so._active = true; push_back(so); + + return &(*this)[size()]; } void ScreenObjects::check(bool scanFlag) { @@ -288,7 +288,7 @@ void ScreenObjects::check(bool scanFlag) { if ((_vm->_events->_mouseMoved || userInterface._scrollbarActive || _v8332A || _forceRescan) && scanFlag) { _category = CAT_NONE; - _selectedObject = scanBackwards(_vm->_events->currentPos(), LAYER_GUI); + _selectedObject = scanBackwards(_vm->_events->currentPos(), SCREENMODE_VGA); if (_selectedObject > 0) { ScreenObject &scrObject = (*this)[_selectedObject]; _category = (ScrCategory)(scrObject._category & 7); @@ -308,10 +308,10 @@ void ScreenObjects::check(bool scanFlag) { } //_released = _vm->_events->_mouseReleased; - if (_vm->_events->_vD2 || (_vm->_easyMouse && !_vm->_events->_mouseStatusCopy)) + if (_vm->_events->_mouseButtons || (_vm->_easyMouse && !_vm->_events->_mouseStatusCopy)) scene._userInterface._category = _category; - if (!_vm->_events->_mouseButtons || _vm->_easyMouse) { + if (_vm->_events->_mouseButtons || _vm->_easyMouse) { if (userInterface._category >= CAT_COMMAND && userInterface._category <= CAT_TALK_ENTRY) { elementHighlighted(); } @@ -365,7 +365,7 @@ void ScreenObjects::check(bool scanFlag) { int ScreenObjects::scan(const Common::Point &pt, int layer) { for (uint i = 1; i <= size(); ++i) { ScreenObject &sObj = (*this)[i]; - if (sObj._active && sObj._bounds.contains(pt) && sObj._layer == layer) + if (sObj._active && sObj._bounds.contains(pt) && sObj._mode == layer) return i; } @@ -376,7 +376,7 @@ int ScreenObjects::scan(const Common::Point &pt, int layer) { int ScreenObjects::scanBackwards(const Common::Point &pt, int layer) { for (int i = (int)size(); i >= 1; --i) { ScreenObject &sObj = (*this)[i]; - if (sObj._active && sObj._bounds.contains(pt) && sObj._layer == layer) + if (sObj._active && sObj._bounds.contains(pt) && sObj._mode == layer) return i; } @@ -526,7 +526,7 @@ void ScreenObjects::elementHighlighted() { action._pickedWord = newIndex; if (_category == CAT_INV_LIST || _category == CAT_INV_ANIM) { - if (action._interAwaiting == 1 && newIndex >= 0 && _released && + if (action._interAwaiting == AWAITING_COMMAND && newIndex >= 0 && _released && (!_vm->_events->_mouseReleased || !_vm->_easyMouse)) newIndex = -1; } @@ -540,7 +540,7 @@ void ScreenObjects::elementHighlighted() { } void ScreenObjects::setActive(ScrCategory category, int descId, bool active) { - for (uint idx = 1; idx < size(); ++idx) { + for (uint idx = 1; idx <= size(); ++idx) { ScreenObject &sObj = (*this)[idx]; if (sObj._category == category && sObj._descId == descId) sObj._active = active; @@ -571,7 +571,7 @@ void ScreenSurface::init() { } ScreenSurface::~ScreenSurface() { - delete[] _surfacePixels; + ::free(_surfacePixels); } void ScreenSurface::copyRectToScreen(const Common::Rect &bounds) { @@ -609,9 +609,10 @@ void ScreenSurface::updateScreen() { void ScreenSurface::transition(ScreenTransition transitionType, bool surfaceFlag) { Palette &pal = *_vm->_palette; + Scene &scene = _vm->_game->_scene; byte palData[PALETTE_SIZE]; - switch (transitionType) { + switch (transitionType) { case kTransitionFadeIn: case kTransitionFadeOutIn: Common::fill(&pal._colorValues[0], &pal._colorValues[3], 0); @@ -641,8 +642,9 @@ void ScreenSurface::transition(ScreenTransition transitionType, bool surfaceFlag case kTransitionPanLeftToRight: case kTransitionPanRightToLeft: - warning("TODO: pan transition"); - transition(kTransitionFadeIn, surfaceFlag); + panTransition(scene._backgroundSurface, pal._mainPalette, + transitionType - kTransitionPanLeftToRight, + Common::Point(0, 0), scene._posAdjust, THROUGH_BLACK2, true, 1); break; case kTransitionCircleIn1: @@ -653,8 +655,10 @@ void ScreenSurface::transition(ScreenTransition transitionType, bool surfaceFlag transition(kTransitionFadeIn, surfaceFlag); break; - case kCenterVertTransition: - warning("TODO: center vert transition"); + case kNullPaletteCopy: + // Original temporarily set the palette to black, copied the scene to the + // screen, and then restored the palette. We can give a similiar effect + // by doing a standard quick palette fade in transition(kTransitionFadeIn, surfaceFlag); break; @@ -674,5 +678,143 @@ void ScreenSurface::resetClipBounds() { setClipBounds(Common::Rect(0, 0, MADS_SCREEN_WIDTH, MADS_SCREEN_HEIGHT)); } +void ScreenSurface::panTransition(MSurface &newScreen, byte *palData, int entrySide, + const Common::Point &srcPos, const Common::Point &destPos, + ThroughBlack throughBlack, bool setPalette, int numTicks) { + EventsManager &events = *_vm->_events; + Palette &palette = *_vm->_palette; + Common::Point size; + int y1, y2; + int startX = 0; + int deltaX; + int xAt; + int loopStart; +// uint32 baseTicks, currentTicks; + byte paletteMap[256]; + + size.x = MIN(newScreen.w, (uint16)MADS_SCREEN_WIDTH); + size.y = newScreen.h; + if (newScreen.h >= MADS_SCREEN_HEIGHT) + size.y = MADS_SCENE_HEIGHT; + + // Set starting position and direction delta for the transition + if (entrySide == 1) + // Right to left + startX = size.x - 1; + deltaX = startX ? -1 : 1; + + if (setPalette & !throughBlack) + palette.setFullPalette(palData); + + // TODO: Original uses a different frequency ticks counter. Need to + // confirm frequency and see whether we need to implement it, or + // if the current frame ticks can substitute for it +// baseTicks = events.getFrameCounter(); + + y1 = 0; + y2 = size.y - 1; +// sizeY = y2 - y1 + 1; + + if (throughBlack == THROUGH_BLACK2) + swapForeground(palData, &paletteMap[0]); + + loopStart = throughBlack == THROUGH_BLACK1 ? 0 : 1; + for (int loop = loopStart; loop < 2; ++loop) { + xAt = startX; + for (int xCtr = 0; xCtr < size.x; ++xCtr, xAt += deltaX) { + if (!loop) { + fillRect(Common::Rect(xAt + destPos.x, y1 + destPos.y, + xAt + destPos.x + 1, y2 + destPos.y), 0); + } else if (throughBlack == THROUGH_BLACK2) { + copyRectTranslate(newScreen, paletteMap, + Common::Point(xAt, destPos.y), + Common::Rect(srcPos.x + xAt, srcPos.y, + srcPos.x + xAt + 1, srcPos.y + size.y)); + } else { + newScreen.copyRectToSurface(*this, xAt, destPos.y, + Common::Rect(srcPos.x + xAt, srcPos.y, + srcPos.x + xAt + 1, srcPos.y + size.y)); + } + + copyRectToScreen(Common::Rect(xAt, destPos.y, xAt + 1, destPos.y + size.y)); + + // Slight delay + events.pollEvents(); + g_system->delayMillis(1); + } + + if ((setPalette && !loop) || throughBlack == THROUGH_BLACK2) + palette.setFullPalette(palData); + } + + if (throughBlack == THROUGH_BLACK2) { + Common::Rect r(srcPos.x, srcPos.y, srcPos.x + size.x, srcPos.y + size.y); + copyRectToSurface(newScreen, destPos.x, destPos.y, r); + copyRectToScreen(r); + } +} + +/** + * Translates the current screen from the old palette to the new palette + */ +void ScreenSurface::swapForeground(byte newPalette[PALETTE_SIZE], byte *paletteMap) { + Palette &palette = *_vm->_palette; + byte oldPalette[PALETTE_SIZE]; + byte oldMap[PALETTE_COUNT]; + + palette.getFullPalette(oldPalette); + swapPalette(oldPalette, oldMap, true); + swapPalette(newPalette, paletteMap, false); + + // Transfer translated foreground colors. Since foregrounds are interleaved + // with background, we only copy over each alternate RGB tuplet + const byte *srcP = &newPalette[RGB_SIZE]; + byte *destP = &oldPalette[RGB_SIZE]; + while (destP < &oldPalette[PALETTE_SIZE]) { + Common::copy(srcP, srcP + RGB_SIZE, destP); + srcP += 2 * RGB_SIZE; + destP += 2 * RGB_SIZE; + } + + Common::Rect oldClip = _clipBounds; + resetClipBounds(); + + copyRectTranslate(*this, oldMap, Common::Point(0, 0), + Common::Rect(0, 0, MADS_SCREEN_WIDTH, MADS_SCREEN_HEIGHT)); + palette.setFullPalette(oldPalette); + + setClipBounds(oldClip); +} + +/** + * Translates a given palette into a mapping table. + * Palettes consist of 128 RGB entries for the foreground and background + * respectively, with the two interleaved together. So the start + */ +void ScreenSurface::swapPalette(const byte *palData, byte swapTable[PALETTE_COUNT], + bool foreground) { + int start = foreground ? 1 : 0; + const byte *dynamicList = &palData[start * RGB_SIZE]; + int staticStart = 1 - start; + const byte *staticList = &palData[staticStart * RGB_SIZE]; + const int PALETTE_START = 1; + const int PALETTE_END = 252; + + // Set initial index values + for (int idx = 0; idx < PALETTE_COUNT; ++idx) + swapTable[idx] = idx; + + // Handle the 128 palette entries for the foreground or background + for (int idx = 0; idx < (PALETTE_COUNT / 2); ++idx) { + if (start >= PALETTE_START && start <= PALETTE_END) { + swapTable[start] = Palette::closestColor(dynamicList, staticList, + 2 * RGB_SIZE, PALETTE_COUNT / 2) * 2 + staticStart; + } + + dynamicList += 2 * RGB_SIZE; + start += 2; + } +} + } // End of namespace MADS diff --git a/engines/mads/screen.h b/engines/mads/screen.h index 9d01ca82e3..d910e88633 100644 --- a/engines/mads/screen.h +++ b/engines/mads/screen.h @@ -8,12 +8,12 @@ * 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. @@ -33,8 +33,8 @@ namespace MADS { #define MADS_SCREEN_WIDTH 320 #define MADS_SCREEN_HEIGHT 200 -enum Layer { - LAYER_GUI = 19 +enum ScreenMode { + SCREENMODE_VGA = 19 }; enum ScreenTransition { @@ -47,7 +47,7 @@ enum ScreenTransition { kTransitionCircleIn3, kTransitionCircleIn4, kVertTransition1, kVertTransition2, kVertTransition3, kVertTransition4, kVertTransition5, kVertTransition6, - kVertTransition7, kCenterVertTransition + kVertTransition7, kNullPaletteCopy }; enum InputMode { @@ -56,6 +56,11 @@ enum InputMode { kInputLimitedSentences = 2 // Use only scene hotspots }; +enum ThroughBlack { + THROUGH_BLACK1 = 1, + THROUGH_BLACK2 = 2 +}; + class SpriteSlot; class TextDisplay; class UISlot; @@ -130,7 +135,7 @@ public: Common::Rect _bounds; ScrCategory _category; int _descId; - int _layer; + int _mode; ScreenObject(); }; @@ -162,7 +167,7 @@ public: /** * Add a new item to the list */ - void add(const Common::Rect &bounds, Layer layer, ScrCategory category, int descId); + ScreenObject *add(const Common::Rect &bounds, ScreenMode mode, ScrCategory category, int descId); /** * Check objects on the screen @@ -207,6 +212,14 @@ private: uint16 _random; byte *_surfacePixels; Common::Rect _clipBounds; + + void panTransition(MSurface &newScreen, byte *palData, int entrySide, + const Common::Point &srcPos, const Common::Point &destPos, + ThroughBlack throughBlack, bool setPalette, int numTicks); + + void swapForeground(byte newPalette[PALETTE_SIZE], byte *paletteMap); + + void swapPalette(const byte palData[PALETTE_SIZE], byte swapTable[PALETTE_COUNT], bool foreground); public: int _shakeCountdown; public: diff --git a/engines/mads/sequence.cpp b/engines/mads/sequence.cpp index 07b1451718..e5bf1631c2 100644 --- a/engines/mads/sequence.cpp +++ b/engines/mads/sequence.cpp @@ -8,12 +8,12 @@ * 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. @@ -95,8 +95,8 @@ bool SequenceList::addSubEntry(int index, SequenceTrigger mode, int frameIndex, } int SequenceList::add(int spriteListIndex, bool flipped, int frameIndex, int triggerCountdown, int delayTicks, int extraTicks, int numTicks, - int msgX, int msgY, bool nonFixed, int scale, int depth, int frameInc, SpriteAnimType animType, int numSprites, - int frameStart) { + int msgX, int msgY, bool nonFixed, int scale, int depth, int frameInc, SpriteAnimType animType, int numSprites, + int frameStart) { Scene &scene = _vm->_game->_scene; // Find a free slot @@ -144,7 +144,7 @@ int SequenceList::add(int spriteListIndex, bool flipped, int frameIndex, int tri return seqIndex; } -int SequenceList::addTimer(int timeout, int abortVal) { +int SequenceList::addTimer(int timeout, int endTrigger) { Scene &scene = _vm->_game->_scene; uint seqIndex; for (seqIndex = 0; seqIndex < _entries.size(); ++seqIndex) { @@ -164,7 +164,7 @@ int SequenceList::addTimer(int timeout, int abortVal) { se._entries._count = 0; se._triggerMode = _vm->_game->_triggerSetupMode; se._actionNouns = _vm->_game->_scene._action._activeAction; - addSubEntry(seqIndex, SEQUENCE_TRIGGER_EXPIRE, 0, abortVal); + addSubEntry(seqIndex, SEQUENCE_TRIGGER_EXPIRE, 0, endTrigger); return seqIndex; } @@ -181,6 +181,19 @@ void SequenceList::remove(int seqIndex) { scene._spriteSlots.deleteTimer(seqIndex); } +int SequenceList::findByTrigger(int trigger) { + for (uint idx = 0; idx < _entries.size(); ++idx) { + if (_entries[idx]._active) { + for (int subIdx = 0; subIdx < _entries[idx]._entries._count; ++subIdx) { + if (_entries[idx]._entries._trigger[subIdx] == trigger) + return idx; + } + } + } + + return -1; +} + void SequenceList::setSpriteSlot(int seqIndex, SpriteSlot &spriteSlot) { Scene &scene = _vm->_game->_scene; SequenceEntry &timerEntry = _entries[seqIndex]; @@ -466,28 +479,28 @@ int SequenceList::startCycle(int srcSpriteIndex, bool flipped, int cycleIndex) { return result; } -int SequenceList::startReverseCycle(int srcSpriteIndex, bool flipped, int numTicks, +int SequenceList::startPingPongCycle(int srcSpriteIndex, bool flipped, int numTicks, int triggerCountdown, int timeoutTicks, int extraTicks) { SpriteAsset *sprites = _vm->_game->_scene._sprites[srcSpriteIndex]; MSprite *frame = sprites->getFrame(0); int depth = _vm->_game->_scene._depthSurface.getDepth(Common::Point( frame->_offset.x + frame->w / 2, frame->_offset.y + frame->h / 2)); - return add(srcSpriteIndex, flipped, sprites->getCount(), triggerCountdown, timeoutTicks, - extraTicks, numTicks, 0, 0, true, 100, depth - 1, -1, ANIMTYPE_REVERSIBLE, 0, 0); + return add(srcSpriteIndex, flipped, 1, triggerCountdown, timeoutTicks, + extraTicks, numTicks, 0, 0, true, 100, depth - 1, 1, ANIMTYPE_PING_PONG, 0, 0); } -void SequenceList::updateTimeout(int spriteIdx, int seqIndex) { +void SequenceList::updateTimeout(int srcSeqIndex, int destSeqIndex) { Player &player = _vm->_game->_player; int timeout; - if (spriteIdx >= 0) - timeout = _entries[spriteIdx]._timeout; + if (srcSeqIndex >= 0) + timeout = _entries[srcSeqIndex]._timeout; else timeout = player._priorTimer + player._ticksAmount; - if (seqIndex >= 0) - _entries[seqIndex]._timeout = timeout; + if (destSeqIndex >= 0) + _entries[destSeqIndex]._timeout = timeout; else player._priorTimer = timeout - player._ticksAmount; @@ -526,8 +539,7 @@ void SequenceList::setMotion(int seqIndex, int flags, int deltaX, int deltaY) { if (deltaY > 0) { se._posSign.y = 1; - } - else if (deltaY < 0) { + } else if (deltaY < 0) { se._posSign.y = -1; } else { se._posSign.y = 0; diff --git a/engines/mads/sequence.h b/engines/mads/sequence.h index ee587ff02d..c3a277c5a5 100644 --- a/engines/mads/sequence.h +++ b/engines/mads/sequence.h @@ -8,12 +8,12 @@ * 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. @@ -38,7 +38,7 @@ enum SequenceTrigger { SEQUENCE_TRIGGER_SPRITE = 2 // Trigger when sequence reaches specific sprite }; -enum SpriteAnimType { ANIMTYPE_NONE = 0, ANIMTYPE_CYCLED = 1, ANIMTYPE_REVERSIBLE = 2 }; +enum SpriteAnimType { ANIMTYPE_NONE = 0, ANIMTYPE_CYCLED = 1, ANIMTYPE_PING_PONG = 2 }; #define SEQUENCE_ENTRY_SUBSET_MAX 5 @@ -101,8 +101,9 @@ public: int extraTicks, int numTicks, int msgX, int msgY, bool nonFixed, int scale, int depth, int frameInc, SpriteAnimType animType, int numSprites, int frameStart); - int addTimer(int timeout, int abortVal); + int addTimer(int timeout, int endTrigger); void remove(int seqIndex); + int findByTrigger(int trigger); void setSpriteSlot(int seqIndex, SpriteSlot &spriteSlot); bool loadSprites(int seqIndex); void tick(); @@ -117,9 +118,9 @@ public: int triggerCountdown = 0, int timeoutTicks = 0, int extraTicks = 0); int startCycle(int srcSpriteIdx, bool flipped, int cycleIndex); - int startReverseCycle(int srcSpriteIndex, bool flipped, int numTicks, + int startPingPongCycle(int srcSpriteIndex, bool flipped, int numTicks, int triggerCountdown = 0, int timeoutTicks = 0, int extraTicks = 0); - void updateTimeout(int spriteIdx, int seqIndex); + void updateTimeout(int destSeqIndex, int srcSeqIndex); void setScale(int spriteIdx, int scale); void setMsgLayout(int seqIndex); void setDone(int seqIndex); diff --git a/engines/mads/sound.cpp b/engines/mads/sound.cpp index d0aa770a4d..7b9388eee3 100644 --- a/engines/mads/sound.cpp +++ b/engines/mads/sound.cpp @@ -8,12 +8,12 @@ * 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. @@ -36,9 +36,19 @@ SoundManager::SoundManager(MADSEngine *vm, Audio::Mixer *mixer) { _pollSoundEnabled = false; _soundPollFlag = false; _newSoundsPaused = false; + _masterVolume = 255; _opl = OPL::Config::create(); _opl->init(11025); + + // Validate sound files + switch (_vm->getGameID()) { + case GType_RexNebular: + Nebular::ASound::validate(); + break; + default: + break; + } } SoundManager::~SoundManager() { @@ -53,6 +63,9 @@ SoundManager::~SoundManager() { void SoundManager::init(int sectionNumber) { assert(sectionNumber > 0 && sectionNumber < 10); + if (_driver != nullptr) + delete _driver; + switch (_vm->getGameID()) { case GType_RexNebular: switch (sectionNumber) { @@ -85,15 +98,18 @@ void SoundManager::init(int sectionNumber) { break; default: _driver = nullptr; - break; + return; } break; default: warning("SoundManager: Unknown game"); _driver = nullptr; - break; + return; } + + // Set volume for newly loaded driver + _driver->setVolume(_masterVolume); } void SoundManager::closeDriver() { @@ -129,12 +145,22 @@ void SoundManager::startQueuedCommands() { } } +void SoundManager::setVolume(int volume) { + _masterVolume = volume; + + if (_driver) + _driver->setVolume(volume); +} + void SoundManager::command(int commandId, int param) { if (_newSoundsPaused) { if (_queuedCommands.size() < 8) _queuedCommands.push(commandId); } else if (_driver) { - _driver->command(commandId, param); + // Note: I don't know any way to identify music commands versus sfx + // commands, so if sfx is mute, then so is music + if (_vm->_soundFlag) + _driver->command(commandId, param); } } diff --git a/engines/mads/sound.h b/engines/mads/sound.h index 72bb21a812..16128f8284 100644 --- a/engines/mads/sound.h +++ b/engines/mads/sound.h @@ -8,12 +8,12 @@ * 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. @@ -43,6 +43,7 @@ private: bool _soundPollFlag; bool _newSoundsPaused; Common::Queue<int> _queuedCommands; + int _masterVolume; public: SoundManager(MADSEngine *vm, Audio::Mixer *mixer); ~SoundManager(); @@ -78,6 +79,11 @@ public: */ void startQueuedCommands(); + /** + * Set the master volume + */ + void setVolume(int volume); + //@{ /** * Executes a command on the sound driver diff --git a/engines/mads/sprites.cpp b/engines/mads/sprites.cpp index 6cb55aaeee..0a1c0b710d 100644 --- a/engines/mads/sprites.cpp +++ b/engines/mads/sprites.cpp @@ -8,12 +8,12 @@ * 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. @@ -347,8 +347,10 @@ void SpriteSlots::drawSprites(MSurface *s) { spr->copyTo(s, Common::Point(xp, yp), sprite->getTransparencyIndex()); // Free sprite if it was a flipped one - if (flipped) + if (flipped) { + spr->free(); delete spr; + } } } } @@ -368,22 +370,18 @@ SpriteSets::~SpriteSets() { } int SpriteSets::add(SpriteAsset *asset, int idx) { - if (idx) - idx = idx + 49; - else - idx = size(); - - if (idx >= (int)size()) - resize(idx + 1); + if (idx) { + assert(idx == 1); + delete _uiSprites; + _uiSprites = asset; - if ((*this)[idx]) { - delete (*this)[idx]; + return SPRITE_SLOTS_MAX_SIZE; } else { - ++_assetCount; - } + assert(size() < SPRITE_SLOTS_MAX_SIZE); + push_back(asset); - (*this)[idx] = asset; - return idx; + return (int)size() - 1; + } } int SpriteSets::addSprites(const Common::String &resName, int flags) { @@ -393,25 +391,32 @@ int SpriteSets::addSprites(const Common::String &resName, int flags) { void SpriteSets::clear() { for (uint i = 0; i < size(); ++i) delete (*this)[i]; - - _assetCount = 0; Common::Array<SpriteAsset *>::clear(); + + delete _uiSprites; + _uiSprites = nullptr; } void SpriteSets::remove(int idx) { - if (idx >= 0) { + if (idx == SPRITE_SLOTS_MAX_SIZE) { + delete _uiSprites; + _uiSprites = nullptr; + } else if (idx >= 0 && idx < (int)size()) { + delete (*this)[idx]; + if (idx < ((int)size() - 1)) { - delete (*this)[idx]; (*this)[idx] = nullptr; } else { - while (size() > 0 && (*this)[size() - 1] == nullptr) { + do { remove_at(size() - 1); - } + } while (size() > 0 && (*this)[size() - 1] == nullptr); } - - if (_assetCount > 0) - --_assetCount; } } +SpriteAsset *&SpriteSets::operator[](int idx) { + return (idx == SPRITE_SLOTS_MAX_SIZE) ? _uiSprites : + Common::Array<SpriteAsset *>::operator[](idx); +} + } // End of namespace MADS diff --git a/engines/mads/sprites.h b/engines/mads/sprites.h index 6ea3c9e52e..3db922c40b 100644 --- a/engines/mads/sprites.h +++ b/engines/mads/sprites.h @@ -8,12 +8,12 @@ * 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. @@ -202,12 +202,12 @@ class SpriteSets : public Common::Array<SpriteAsset *> { private: MADSEngine *_vm; public: - int _assetCount; - + SpriteAsset *_uiSprites; +public: /** * Constructor */ - SpriteSets(MADSEngine *vm) : _vm(vm), _assetCount(0) {} + SpriteSets(MADSEngine *vm) : _vm(vm), _uiSprites(nullptr) {} /** * Destructor @@ -233,6 +233,8 @@ public: * Remove an asset from the list */ void remove(int idx); + + SpriteAsset *&operator[](int idx); }; } // End of namespace MADS diff --git a/engines/mads/staticres.cpp b/engines/mads/staticres.cpp index 189e5f72e7..b659d9a27c 100644 --- a/engines/mads/staticres.cpp +++ b/engines/mads/staticres.cpp @@ -8,12 +8,12 @@ * 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. diff --git a/engines/mads/staticres.h b/engines/mads/staticres.h index 560fd12e67..b805729327 100644 --- a/engines/mads/staticres.h +++ b/engines/mads/staticres.h @@ -8,12 +8,12 @@ * 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. diff --git a/engines/mads/user_interface.cpp b/engines/mads/user_interface.cpp index 1f8d5037bc..62fd036c03 100644 --- a/engines/mads/user_interface.cpp +++ b/engines/mads/user_interface.cpp @@ -8,12 +8,12 @@ * 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. @@ -164,6 +164,7 @@ void UISlots::draw(bool updateFlag, bool delFlag) { MSurface *spr = sprite->flipHorizontal(); userInterface.mergeFrom(spr, spr->getBounds(), slot._position, sprite->getTransparencyIndex()); + spr->free(); delete spr; } else { userInterface.mergeFrom(sprite, sprite->getBounds(), slot._position, @@ -410,13 +411,21 @@ void UserInterface::setup(InputMode inputMode) { } void UserInterface::drawTextElements() { - if (_vm->_game->_screenObjects._inputMode) { - drawConversationList(); - } else { + switch (_vm->_game->_screenObjects._inputMode) { + case kInputBuildingSentences: // Draw the actions drawActions(); drawInventoryList(); drawItemVocabList(); + break; + + case kInputConversation: + drawConversationList(); + break; + + case kInputLimitedSentences: + default: + break; } } @@ -495,7 +504,6 @@ void UserInterface::drawScroller() { void UserInterface::updateInventoryScroller() { ScreenObjects &screenObjects = _vm->_game->_screenObjects; - Common::Array<int> &inventoryList = _vm->_game->_objects._inventoryList; if (screenObjects._inputMode != kInputBuildingSentences) return; @@ -515,48 +523,11 @@ void UserInterface::updateInventoryScroller() { uint32 timeInc = _scrollbarQuickly ? 100 : 380; if (_vm->_events->_mouseStatus && (_scrollbarMilliTime + timeInc) <= currentMilli) { - _scrollbarQuickly = _vm->_events->_vD2 < 1; + _scrollbarQuickly = _vm->_events->_strokeGoing < 1; _scrollbarMilliTime = currentMilli; - switch (_scrollbarStrokeType) { - case SCROLLBAR_UP: - // Scroll up - if (_inventoryTopIndex > 0 && inventoryList.size() > 0) { - --_inventoryTopIndex; - _inventoryChanged = true; - } - break; - - case SCROLLBAR_DOWN: - // Scroll down - if (_inventoryTopIndex < ((int)inventoryList.size() - 1) && inventoryList.size() > 1) { - ++_inventoryTopIndex; - _inventoryChanged = true; - } - break; - - case SCROLLBAR_ELEVATOR: { - // Inventory slider - int newIndex = CLIP((int)_vm->_events->currentPos().y - 170, 0, 17) - * inventoryList.size() / 10; - if (newIndex >= (int)inventoryList.size()) - newIndex = inventoryList.size() - 1; - - if (inventoryList.size() > 0) { - _inventoryChanged = newIndex != _inventoryTopIndex; - _inventoryTopIndex = newIndex; - } - break; - } - - default: - break; - } - - if (_inventoryChanged) { - int dummy; - updateSelection(CAT_INV_LIST, 0, &dummy); - } + // Change the scrollbar and visible inventory list + changeScrollBar(); } } } @@ -569,6 +540,54 @@ void UserInterface::updateInventoryScroller() { _scrollbarOldElevator = _scrollbarElevator; } +void UserInterface::changeScrollBar() { + Common::Array<int> &inventoryList = _vm->_game->_objects._inventoryList; + ScreenObjects &screenObjects = _vm->_game->_screenObjects; + + if (screenObjects._inputMode != kInputBuildingSentences) + return; + + switch (_scrollbarStrokeType) { + case SCROLLBAR_UP: + // Scroll up + if (_inventoryTopIndex > 0 && inventoryList.size() > 0) { + --_inventoryTopIndex; + _inventoryChanged = true; + } + break; + + case SCROLLBAR_DOWN: + // Scroll down + if (_inventoryTopIndex < ((int)inventoryList.size() - 1) && inventoryList.size() > 1) { + ++_inventoryTopIndex; + _inventoryChanged = true; + } + break; + + case SCROLLBAR_ELEVATOR: { + // Inventory slider + int newIndex = CLIP((int)_vm->_events->currentPos().y - 170, 0, 17) + * inventoryList.size() / 10; + if (newIndex >= (int)inventoryList.size()) + newIndex = inventoryList.size() - 1; + + if (inventoryList.size() > 0) { + _inventoryChanged = newIndex != _inventoryTopIndex; + _inventoryTopIndex = newIndex; + } + break; + } + + default: + break; + } + + if (_inventoryChanged) { + int dummy; + updateSelection(CAT_INV_LIST, 0, &dummy); + } +} + void UserInterface::scrollbarChanged() { Common::Rect r(73, 4, 73 + 9, 4 + 38); _uiSlots.add(r); @@ -673,7 +692,7 @@ void UserInterface::loadElements() { getBounds(CAT_INV_SCROLLER, idx, bounds); moveRect(bounds); - _vm->_game->_screenObjects.add(bounds, LAYER_GUI, CAT_INV_SCROLLER, idx); + _vm->_game->_screenObjects.add(bounds, SCREENMODE_VGA, CAT_INV_SCROLLER, idx); } // Set up actions @@ -682,7 +701,7 @@ void UserInterface::loadElements() { getBounds(CAT_COMMAND, idx, bounds); moveRect(bounds); - _vm->_game->_screenObjects.add(bounds, LAYER_GUI, CAT_COMMAND, idx); + _vm->_game->_screenObjects.add(bounds, SCREENMODE_VGA, CAT_COMMAND, idx); } // Set up inventory list @@ -691,7 +710,7 @@ void UserInterface::loadElements() { getBounds(CAT_INV_LIST, _inventoryTopIndex + idx, bounds); moveRect(bounds); - _vm->_game->_screenObjects.add(bounds, LAYER_GUI, CAT_INV_LIST, idx); + _vm->_game->_screenObjects.add(bounds, SCREENMODE_VGA, CAT_INV_LIST, idx); } // Set up the inventory vocab list @@ -700,12 +719,12 @@ void UserInterface::loadElements() { getBounds(CAT_INV_VOCAB, idx, bounds); moveRect(bounds); - _vm->_game->_screenObjects.add(bounds, LAYER_GUI, CAT_INV_VOCAB, idx); + _vm->_game->_screenObjects.add(bounds, SCREENMODE_VGA, CAT_INV_VOCAB, idx); } // Set up the inventory item picture _categoryIndexes[CAT_INV_ANIM - 1] = _vm->_game->_screenObjects.size() + 1; - _vm->_game->_screenObjects.add(Common::Rect(160, 159, 231, 194), LAYER_GUI, + _vm->_game->_screenObjects.add(Common::Rect(160, 159, 231, 194), SCREENMODE_VGA, CAT_INV_ANIM, 0); } @@ -714,7 +733,9 @@ void UserInterface::loadElements() { _categoryIndexes[CAT_HOTSPOT - 1] = _vm->_game->_screenObjects.size() + 1; for (int hotspotIdx = scene._hotspots.size() - 1; hotspotIdx >= 0; --hotspotIdx) { Hotspot &hs = scene._hotspots[hotspotIdx]; - _vm->_game->_screenObjects.add(hs._bounds, LAYER_GUI, CAT_HOTSPOT, hotspotIdx); + ScreenObject *so = _vm->_game->_screenObjects.add(hs._bounds, SCREENMODE_VGA, + CAT_HOTSPOT, hotspotIdx); + so->_active = hs._active; } } @@ -725,7 +746,7 @@ void UserInterface::loadElements() { getBounds(CAT_TALK_ENTRY, idx, bounds); moveRect(bounds); - _vm->_game->_screenObjects.add(bounds, LAYER_GUI, CAT_TALK_ENTRY, idx); + _vm->_game->_screenObjects.add(bounds, SCREENMODE_VGA, CAT_TALK_ENTRY, idx); } } @@ -833,23 +854,24 @@ void UserInterface::emptyConversationList() { } void UserInterface::addConversationMessage(int vocabId, const Common::String &msg) { - assert(_talkStrings.size() < 5); - - _talkStrings.push_back(msg); - _talkIds.push_back(vocabId); + // Only allow a maximum of 5 talk entries to be displayed + if (_talkStrings.size() < 5) { + _talkStrings.push_back(msg); + _talkIds.push_back(vocabId); + } } void UserInterface::loadInventoryAnim(int objectId) { Scene &scene = _vm->_game->_scene; noInventoryAnim(); - if (_vm->_invObjectsAnimated) { - Common::String resName = Common::String::format("*OB%.3dI", objectId); - SpriteAsset *asset = new SpriteAsset(_vm, resName, ASSET_SPINNING_OBJECT); - _invSpritesIndex = scene._sprites.add(asset, 1); - if (_invSpritesIndex >= 0) { - _invFrameNumber = 1; - } + // WORKAROUND: Even in still mode, we now load the animation frames for the + // object, so we can show the first frame as a 'still' + Common::String resName = Common::String::format("*OB%.3dI", objectId); + SpriteAsset *asset = new SpriteAsset(_vm, resName, ASSET_SPINNING_OBJECT); + _invSpritesIndex = scene._sprites.add(asset, 1); + if (_invSpritesIndex >= 0) { + _invFrameNumber = 1; } } @@ -881,10 +903,13 @@ void UserInterface::inventoryAnim() { _invSpritesIndex < 0) return; - // Move to the next frame number in the sequence, resetting if at the end - SpriteAsset *asset = scene._sprites[_invSpritesIndex]; - if (++_invFrameNumber > asset->getCount()) - _invFrameNumber = 1; + // WORKAROUND: Fix still inventory display, which was broken in the original + if (_vm->_invObjectsAnimated) { + // Move to the next frame number in the sequence, resetting if at the end + SpriteAsset *asset = scene._sprites[_invSpritesIndex]; + if (++_invFrameNumber > asset->getCount()) + _invFrameNumber = 1; + } // Loop through the slots list for inventory animation entry for (uint i = 0; i < _uiSlots.size(); ++i) { diff --git a/engines/mads/user_interface.h b/engines/mads/user_interface.h index 89044c9bf1..1366aa2c32 100644 --- a/engines/mads/user_interface.h +++ b/engines/mads/user_interface.h @@ -8,12 +8,12 @@ * 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. @@ -140,7 +140,6 @@ private: bool _scrollFlag; int _noSegmentsActive; int _someSegmentsActive; - ScrollbarActive _scrollbarStrokeType; /** * Loads the elements of the user interface @@ -216,6 +215,7 @@ public: bool _scrollbarQuickly; uint32 _scrollbarMilliTime; int _scrollbarElevator, _scrollbarOldElevator; + ScrollbarActive _scrollbarStrokeType; public: /** * Constructor @@ -275,6 +275,11 @@ public: void updateSelection(ScrCategory category, int newIndex, int *idx); + /** + * Updates the current top visible item of the scrollbar + */ + void changeScrollBar(); + void scrollerChanged(); void scrollInventory(); |