From 7a9514567f44f5a717fcfb1994431e54e06ea148 Mon Sep 17 00:00:00 2001 From: Filippos Karapetis Date: Mon, 16 Mar 2015 01:41:08 +0200 Subject: MADS: Handle a game bug in scene 604, which prevents game completion --- engines/mads/nebular/nebular_scenes6.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'engines/mads') diff --git a/engines/mads/nebular/nebular_scenes6.cpp b/engines/mads/nebular/nebular_scenes6.cpp index 046782b772..d94fb17fd4 100644 --- a/engines/mads/nebular/nebular_scenes6.cpp +++ b/engines/mads/nebular/nebular_scenes6.cpp @@ -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); -- cgit v1.2.3 From 4009305070f3f8a1a718526b3e00fc9902a9d87e Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Wed, 18 Mar 2015 20:29:50 -0400 Subject: MADS: Hook up ScummVM volume control --- engines/mads/mads.cpp | 7 +++++++ engines/mads/nebular/sound_nebular.cpp | 37 +++++++++++++++++++++------------- engines/mads/nebular/sound_nebular.h | 8 +++++++- engines/mads/sound.cpp | 15 ++++++++++++-- engines/mads/sound.h | 6 ++++++ 5 files changed, 56 insertions(+), 17 deletions(-) (limited to 'engines/mads') diff --git a/engines/mads/mads.cpp b/engines/mads/mads.cpp index 59d600fbfb..374e373035 100644 --- a/engines/mads/mads.cpp +++ b/engines/mads/mads.cpp @@ -126,6 +126,13 @@ void MADSEngine::loadOptions() { 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() { diff --git a/engines/mads/nebular/sound_nebular.cpp b/engines/mads/nebular/sound_nebular.cpp index 6412654fd6..9716e6d522 100644 --- a/engines/mads/nebular/sound_nebular.cpp +++ b/engines/mads/nebular/sound_nebular.cpp @@ -44,6 +44,7 @@ AdlibChannel::AdlibChannel() { _field4 = 0; _sampleIndex = 0; _volume = 0; + _volumeOffset = 0; _field7 = 0; _field8 = 0; _field9 = 0; @@ -61,7 +62,6 @@ AdlibChannel::AdlibChannel() { _field19 = 0; _soundData = nullptr; _field1D = 0; - _field1E = 0; _field1F = 0; _field20 = 0; @@ -97,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; @@ -104,7 +105,7 @@ void AdlibChannel::load(byte *pData) { _field1F = 0; _field2 = _field3 = 0; _volume = _field7 = 0; - _field1D = _field1E = 0; + _field1D = 0; _fieldE = 0; _field9 = 0; _fieldB = 0; @@ -117,7 +118,7 @@ void AdlibChannel::load(byte *pData) { void AdlibChannel::check(byte *nullPtr) { if (_activeCount && _fieldE) { - if (!_field1E) { + if (!_volumeOffset) { _pSrc = nullPtr; _fieldE = 0; } else { @@ -166,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; @@ -540,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; @@ -615,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; } @@ -659,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; @@ -668,7 +670,7 @@ void ASound::pollActiveChannel() { newVal = 63; } - chan->_field1E = newVal; + chan->_volumeOffset = newVal; updateFlag = true; } } @@ -755,7 +757,8 @@ static const int outputChannels[] = { 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 @@ -857,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; @@ -1014,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 cfacb211a4..d2fc552eec 100644 --- a/engines/mads/nebular/sound_nebular.h +++ b/engines/mads/nebular/sound_nebular.h @@ -70,7 +70,7 @@ public: int _field19; byte *_soundData; int _field1D; - int _field1E; + int _volumeOffset; int _field1F; // TODO: Only used by asound.003. Figure out usage @@ -146,6 +146,7 @@ class ASound : public Audio::AudioStream { private: Common::List _dataCache; uint16 _randomSeed; + int _masterVolume; /** * Does the initial Adlib initialisation @@ -382,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/sound.cpp b/engines/mads/sound.cpp index 1baa169c55..4036ee8112 100644 --- a/engines/mads/sound.cpp +++ b/engines/mads/sound.cpp @@ -36,6 +36,7 @@ SoundManager::SoundManager(MADSEngine *vm, Audio::Mixer *mixer) { _pollSoundEnabled = false; _soundPollFlag = false; _newSoundsPaused = false; + _masterVolume = 255; _opl = OPL::Config::create(); _opl->init(11025); @@ -97,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() { @@ -141,6 +145,13 @@ 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) diff --git a/engines/mads/sound.h b/engines/mads/sound.h index 72bb21a812..5884323474 100644 --- a/engines/mads/sound.h +++ b/engines/mads/sound.h @@ -43,6 +43,7 @@ private: bool _soundPollFlag; bool _newSoundsPaused; Common::Queue _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 -- cgit v1.2.3 From fb0f95172a0395cc6d86f26fea5de2c6a780999a Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 29 Mar 2015 16:21:49 -0400 Subject: MADS: Don't hide sprites bewteen resources in an animation sequence --- engines/mads/menu_views.cpp | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'engines/mads') diff --git a/engines/mads/menu_views.cpp b/engines/mads/menu_views.cpp index 5a0c7ee92e..319f5b0f87 100644 --- a/engines/mads/menu_views.cpp +++ b/engines/mads/menu_views.cpp @@ -544,6 +544,7 @@ void AnimationView::doFrame() { scriptDone(); } else { scene._frameStartTime = 0; + scene._spriteSlots.clear(); loadNextResource(); } } else if (_currentAnimation->getCurrentFrame() == 1) { @@ -559,6 +560,10 @@ void AnimationView::doFrame() { ++scene._frameStartTime; _currentAnimation->update(); _redrawFlag = true; + + if (_currentAnimation->freeFlag()) + // We don't want the sprites removed after the last animation frame + scene._spriteSlots.clear(); } } -- cgit v1.2.3 From 478fae2a6ea6d1c896cd9d5454b170889fc8447a Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 29 Mar 2015 22:12:27 -0400 Subject: MADS: Set testing flags for Rex Nebular --- engines/mads/detection_tables.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'engines/mads') diff --git a/engines/mads/detection_tables.h b/engines/mads/detection_tables.h index 0a8e98bb31..faf73996ac 100644 --- a/engines/mads/detection_tables.h +++ b/engines/mads/detection_tables.h @@ -55,7 +55,7 @@ static const MADSGameDescription gameDescriptions[] = { }, Common::EN_ANY, Common::kPlatformDOS, - ADGF_NO_FLAGS, + ADGF_TESTING, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EASY_MOUSE, GAMEOPTION_ANIMATED_INVENTORY, GAMEOPTION_ANIMATED_INTERFACE, GAMEOPTION_NAUGHTY_MODE) }, GType_RexNebular, @@ -73,7 +73,7 @@ static const MADSGameDescription gameDescriptions[] = { }, Common::EN_ANY, Common::kPlatformDOS, - ADGF_NO_FLAGS, + ADGF_TESTING, GUIO5(GUIO_NOSPEECH, GAMEOPTION_EASY_MOUSE, GAMEOPTION_ANIMATED_INVENTORY, GAMEOPTION_ANIMATED_INTERFACE, GAMEOPTION_NAUGHTY_MODE) }, GType_RexNebular, -- cgit v1.2.3 From a44ab1facc9c1ed8bc1f1ff38876c65f2624a406 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 4 Apr 2015 21:08:15 -0500 Subject: MADS: Fix incorrect depth handling after picking up rebreather --- engines/mads/nebular/nebular_scenes1.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'engines/mads') diff --git a/engines/mads/nebular/nebular_scenes1.cpp b/engines/mads/nebular/nebular_scenes1.cpp index 0c5888b6ec..047dc1f498 100644 --- a/engines/mads/nebular/nebular_scenes1.cpp +++ b/engines/mads/nebular/nebular_scenes1.cpp @@ -1462,7 +1462,6 @@ void Scene103::actions() { } 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.startPingPongCycle(_globals._spriteIndexes[12], false, 3, 2); _scene->_sequences.setMsgLayout(_globals._sequenceIndexes[12]); _scene->_sequences.addSubEntry(_globals._sequenceIndexes[12], SEQUENCE_TRIGGER_SPRITE, 6, 1); -- cgit v1.2.3 From 355fa444caadfc951ba289bf23fc275f949bf36e Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 4 Apr 2015 21:40:21 -0500 Subject: MADS: Fix throwing burger in the different difficulty modes --- engines/mads/nebular/nebular_scenes1.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'engines/mads') diff --git a/engines/mads/nebular/nebular_scenes1.cpp b/engines/mads/nebular/nebular_scenes1.cpp index 047dc1f498..0a62e375d7 100644 --- a/engines/mads/nebular/nebular_scenes1.cpp +++ b/engines/mads/nebular/nebular_scenes1.cpp @@ -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; } -- cgit v1.2.3 From ae61f8ba04aca3cbd84c4dd27f9302744246f109 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 4 Apr 2015 22:03:06 -0500 Subject: MADS: Fix wait cursor when leaving crashed ship for the first time --- engines/mads/events.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'engines/mads') diff --git a/engines/mads/events.cpp b/engines/mads/events.cpp index 767f998d81..52569af375 100644 --- a/engines/mads/events.cpp +++ b/engines/mads/events.cpp @@ -84,8 +84,8 @@ void EventsManager::waitCursor() { CursorType cursorId = (CursorType)MIN(_cursorSprites->getCount(), (int)CURSOR_WAIT); _newCursorId = cursorId; if (_cursorId != _newCursorId) { - changeCursor(); _cursorId = _newCursorId; + changeCursor(); } } -- cgit v1.2.3 From d6945864ea450cdaa20e5120771e3c497e5515ee Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 4 Apr 2015 22:39:56 -0500 Subject: MADS: Keep Rex's speech on-screen longer when exitting crashed ship --- engines/mads/messages.cpp | 8 +++++--- engines/mads/nebular/nebular_scenes1.cpp | 4 ++-- 2 files changed, 7 insertions(+), 5 deletions(-) (limited to 'engines/mads') diff --git a/engines/mads/messages.cpp b/engines/mads/messages.cpp index 4b105630d6..304c79aa46 100644 --- a/engines/mads/messages.cpp +++ b/engines/mads/messages.cpp @@ -91,7 +91,7 @@ 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._frameTimer = scene._frameStartTime; rec._trigger = endTrigger; rec._abortMode = _vm->_game->_triggerSetupMode; @@ -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/nebular/nebular_scenes1.cpp b/engines/mads/nebular/nebular_scenes1.cpp index 0a62e375d7..bcc4fb43d5 100644 --- a/engines/mads/nebular/nebular_scenes1.cpp +++ b/engines/mads/nebular/nebular_scenes1.cpp @@ -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; } } -- cgit v1.2.3 From cb91e1518a3ba88e378d4e90cbe0d8e99ba4e639 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 4 Apr 2015 22:59:43 -0500 Subject: MADS: Have Rex swim to correct spot when throwing burger or fish --- engines/mads/nebular/nebular_scenes1.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'engines/mads') diff --git a/engines/mads/nebular/nebular_scenes1.cpp b/engines/mads/nebular/nebular_scenes1.cpp index bcc4fb43d5..c9eda08859 100644 --- a/engines/mads/nebular/nebular_scenes1.cpp +++ b/engines/mads/nebular/nebular_scenes1.cpp @@ -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); -- cgit v1.2.3 From d9168c8fae304c0984b59d142dfc66e04b9fab36 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sun, 5 Apr 2015 15:28:10 -0500 Subject: MADS: Fix placement of blowgun in easy mode --- engines/mads/game.cpp | 2 -- 1 file changed, 2 deletions(-) (limited to 'engines/mads') diff --git a/engines/mads/game.cpp b/engines/mads/game.cpp index b601a12c82..72d7988c05 100644 --- a/engines/mads/game.cpp +++ b/engines/mads/game.cpp @@ -115,8 +115,6 @@ void Game::run() { _statusFlag = true; while (!_vm->shouldQuit()) { - initializeGlobals(); - if (_loadGameSlot == -1) { startGame(); } -- cgit v1.2.3 From 661542b8c62a618f5d4b8265c8f9fb4d7e58a3a7 Mon Sep 17 00:00:00 2001 From: Filippos Karapetis Date: Mon, 6 Apr 2015 03:12:15 +0300 Subject: MADS: Implement copy protection screen for Rex --- engines/mads/nebular/dialogs_nebular.cpp | 44 +++++++++++++++++++---- engines/mads/nebular/dialogs_nebular.h | 3 ++ engines/mads/nebular/game_nebular.cpp | 62 +++++++++++++++++--------------- engines/mads/nebular/nebular_scenes8.cpp | 2 +- 4 files changed, 74 insertions(+), 37 deletions(-) (limited to 'engines/mads') diff --git a/engines/mads/nebular/dialogs_nebular.cpp b/engines/mads/nebular/dialogs_nebular.cpp index 4ba5366a60..9388aa2aa5 100644 --- a/engines/mads/nebular/dialogs_nebular.cpp +++ b/engines/mads/nebular/dialogs_nebular.cpp @@ -417,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"); @@ -428,17 +428,47 @@ 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; + 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(); + + while (!_vm->shouldQuit()) { + while (!_vm->_events->isKeyPressed()) { + _vm->_events->delay(1); + } + + 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(); + + _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(); + delete origInput; } +bool CopyProtectionDialog::isCorrectAnswer() { + return _hogEntry._word == _textInput; +} + + bool CopyProtectionDialog::getHogAnusEntry(HOGANUS &entry) { File f; f.open("*HOGANUS.DAT"); diff --git a/engines/mads/nebular/dialogs_nebular.h b/engines/mads/nebular/dialogs_nebular.h index 5dbe4da6f0..0f086f6ec1 100644 --- a/engines/mads/nebular/dialogs_nebular.h +++ b/engines/mads/nebular/dialogs_nebular.h @@ -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 { diff --git a/engines/mads/nebular/game_nebular.cpp b/engines/mads/nebular/game_nebular.cpp index cde998e66a..ec7c6678e8 100644 --- a/engines/mads/nebular/game_nebular.cpp +++ b/engines/mads/nebular/game_nebular.cpp @@ -45,19 +45,25 @@ 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) { + dlg = new CopyProtectionDialog(_vm, true); + dlg->show(); + correctAnswer = dlg->isCorrectAnswer(); + delete dlg; + } + + return correctAnswer ? PROTECTION_SUCCEED : PROTECTION_FAIL; } void GameNebular::startGame() { @@ -91,26 +97,6 @@ void GameNebular::startGame() { checkShowDialog(); _winStatus = 0; - /* - // 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: - // User escaped out of copy protection dialog - _vm->quitGame(); - return; - default: - // Copy protection check succeeded - break; - } - */ - _sectionNumber = 1; initSection(_sectionNumber); _vm->_events->setCursor(CURSOR_ARROW); @@ -128,6 +114,24 @@ void GameNebular::startGame() { _scene._nextSceneId = 101; initializeGlobals(); + + // Check copy protection + ProtectionResult protectionResult = checkCopyProtection(); + + switch (protectionResult) { + case PROTECTION_FAIL: + // Copy protection failed + _scene._nextSceneId = 804; + _globals[kCopyProtectFailed] = true; + return; + case PROTECTION_ESCAPE: + // User escaped out of copy protection dialog + _vm->quitGame(); + return; + default: + // Copy protection check succeeded + break; + } } void GameNebular::initializeGlobals() { diff --git a/engines/mads/nebular/nebular_scenes8.cpp b/engines/mads/nebular/nebular_scenes8.cpp index 8ce559b82b..5f8417cee1 100644 --- a/engines/mads/nebular/nebular_scenes8.cpp +++ b/engines/mads/nebular/nebular_scenes8.cpp @@ -957,7 +957,7 @@ void Scene804::step() { _globals[kInSpace] = false; _globals[kBeamIsUp] = true; - assert(!_globals[kCopyProtectFailed]); + //assert(!_globals[kCopyProtectFailed]); _game._winStatus = 4; return; } -- cgit v1.2.3 From f3251b5bb65bbd4ecee7a0700e1f876987cc7644 Mon Sep 17 00:00:00 2001 From: Torbjörn Andersson Date: Mon, 6 Apr 2015 08:29:46 +0200 Subject: MADS: Allow quitting in Rex's copy protection dialog --- engines/mads/nebular/dialogs_nebular.cpp | 5 ++++- engines/mads/nebular/game_nebular.cpp | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) (limited to 'engines/mads') diff --git a/engines/mads/nebular/dialogs_nebular.cpp b/engines/mads/nebular/dialogs_nebular.cpp index 9388aa2aa5..731e7e960d 100644 --- a/engines/mads/nebular/dialogs_nebular.cpp +++ b/engines/mads/nebular/dialogs_nebular.cpp @@ -439,10 +439,13 @@ void CopyProtectionDialog::show() { _vm->_screen.updateScreen(); while (!_vm->shouldQuit()) { - while (!_vm->_events->isKeyPressed()) { + 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) diff --git a/engines/mads/nebular/game_nebular.cpp b/engines/mads/nebular/game_nebular.cpp index ec7c6678e8..c96f1c6df9 100644 --- a/engines/mads/nebular/game_nebular.cpp +++ b/engines/mads/nebular/game_nebular.cpp @@ -56,7 +56,7 @@ ProtectionResult GameNebular::checkCopyProtection() { correctAnswer = dlg->isCorrectAnswer(); delete dlg; - if (!correctAnswer) { + if (!correctAnswer && !_vm->shouldQuit()) { dlg = new CopyProtectionDialog(_vm, true); dlg->show(); correctAnswer = dlg->isCorrectAnswer(); -- cgit v1.2.3 From c8ac76b22bfd676bb72a850a141730022d6d476c Mon Sep 17 00:00:00 2001 From: Torbjörn Andersson Date: Mon, 6 Apr 2015 10:42:16 +0200 Subject: MADS: Show first character of the Rex Nebular copy protection word --- engines/mads/nebular/dialogs_nebular.cpp | 35 +++++++++++++++++++------------- 1 file changed, 21 insertions(+), 14 deletions(-) (limited to 'engines/mads') diff --git a/engines/mads/nebular/dialogs_nebular.cpp b/engines/mads/nebular/dialogs_nebular.cpp index 731e7e960d..10715797ed 100644 --- a/engines/mads/nebular/dialogs_nebular.cpp +++ b/engines/mads/nebular/dialogs_nebular.cpp @@ -438,24 +438,31 @@ void CopyProtectionDialog::show() { _vm->_screen.copyRectToScreen(inputArea); _vm->_screen.updateScreen(); + bool firstTime = true; + while (!_vm->shouldQuit()) { - while (!_vm->shouldQuit() && !_vm->_events->isKeyPressed()) { - _vm->_events->delay(1); - } + if (!firstTime) { + while (!_vm->shouldQuit() && !_vm->_events->isKeyPressed()) { + _vm->_events->delay(1); + } - if (_vm->shouldQuit()) - break; + 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; + 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(); + _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, -- cgit v1.2.3 From 07c7f5e31a1f1952ebe583a138352e13e45e0c66 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Tue, 7 Apr 2015 20:09:00 -0500 Subject: MADS: Fix crash leaving scene after shooting monkey --- engines/mads/sprites.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'engines/mads') diff --git a/engines/mads/sprites.cpp b/engines/mads/sprites.cpp index 67d5e20fe5..bc36b5575a 100644 --- a/engines/mads/sprites.cpp +++ b/engines/mads/sprites.cpp @@ -399,7 +399,7 @@ void SpriteSets::remove(int idx) { if (idx == SPRITE_SLOTS_MAX_SIZE) { delete _uiSprites; _uiSprites = nullptr; - } else if (idx >= 0) { + } else if (idx >= 0 && idx < (int)size()) { delete (*this)[idx]; if (idx < ((int)size() - 1)) { -- cgit v1.2.3 From 47afe424c194d5d4fd1797948b53f999473fe922 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Wed, 8 Apr 2015 21:28:24 -0500 Subject: MADS: Don't show protection dialog when exiting directly from main menu --- engines/mads/nebular/game_nebular.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'engines/mads') diff --git a/engines/mads/nebular/game_nebular.cpp b/engines/mads/nebular/game_nebular.cpp index c96f1c6df9..e9a3d0b716 100644 --- a/engines/mads/nebular/game_nebular.cpp +++ b/engines/mads/nebular/game_nebular.cpp @@ -107,6 +107,9 @@ void GameNebular::startGame() { _vm->_dialogs->showDialog(); } while (!_vm->shouldQuit() && _vm->_dialogs->_pendingDialog != DIALOG_NONE); + if (_vm->shouldQuit()) + return; + _priorSectionNumber = 0; _priorSectionNumber = -1; _scene._priorSceneId = 0; -- cgit v1.2.3 From ec999f1cb74dff8c42c69898bb6cbc3823b169dd Mon Sep 17 00:00:00 2001 From: Filippos Karapetis Date: Thu, 9 Apr 2015 13:44:39 +0300 Subject: MADS: Plug some memory leaks Surfaces should be freed (to free their inner allocated surface buffers) before being deleted --- engines/mads/game.cpp | 1 + engines/mads/nebular/dialogs_nebular.cpp | 4 +++- engines/mads/scene_data.cpp | 2 ++ engines/mads/sprites.cpp | 4 +++- engines/mads/user_interface.cpp | 1 + 5 files changed, 10 insertions(+), 2 deletions(-) (limited to 'engines/mads') diff --git a/engines/mads/game.cpp b/engines/mads/game.cpp index 72d7988c05..3d1c194612 100644 --- a/engines/mads/game.cpp +++ b/engines/mads/game.cpp @@ -100,6 +100,7 @@ Game::~Game() { } delete _saveFile; + _surface->free(); delete _surface; delete _sectionHandler; } diff --git a/engines/mads/nebular/dialogs_nebular.cpp b/engines/mads/nebular/dialogs_nebular.cpp index 10715797ed..5b9942db07 100644 --- a/engines/mads/nebular/dialogs_nebular.cpp +++ b/engines/mads/nebular/dialogs_nebular.cpp @@ -430,7 +430,7 @@ void CopyProtectionDialog::show() { draw(); Common::KeyState curKey; - Common::Rect inputArea(110, 165, 210, 175); + 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)); @@ -471,6 +471,7 @@ void CopyProtectionDialog::show() { _vm->_screen.updateScreen(); } + origInput->free(); delete origInput; } @@ -592,6 +593,7 @@ void PictureDialog::save() { void PictureDialog::restore() { if (_savedSurface) { _savedSurface->copyTo(&_vm->_screen); + _savedSurface->free(); delete _savedSurface; _savedSurface = nullptr; diff --git a/engines/mads/scene_data.cpp b/engines/mads/scene_data.cpp index d0e96be1d7..e594406447 100644 --- a/engines/mads/scene_data.cpp +++ b/engines/mads/scene_data.cpp @@ -451,6 +451,8 @@ void SceneInfo::loadMadsV2Background(int sceneId, const Common::String &resName, fab.decompress(compressedTileData, compressedTileDataSize, (byte*)newTile->getPixels(), tileWidth * tileHeight); tileSet.push_back(TileSetList::value_type(newTile)); + newTile->free(); + delete newTile; delete[] compressedTileData; } diff --git a/engines/mads/sprites.cpp b/engines/mads/sprites.cpp index bc36b5575a..f15d6456d3 100644 --- a/engines/mads/sprites.cpp +++ b/engines/mads/sprites.cpp @@ -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; + } } } } diff --git a/engines/mads/user_interface.cpp b/engines/mads/user_interface.cpp index 93a555d9c7..1e5a1d80d2 100644 --- a/engines/mads/user_interface.cpp +++ b/engines/mads/user_interface.cpp @@ -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, -- cgit v1.2.3 From ec03857d7dd7614675b41cfc412be20b733b469a Mon Sep 17 00:00:00 2001 From: Filippos Karapetis Date: Thu, 9 Apr 2015 14:08:48 +0300 Subject: MADS: Fix a regression in V2 games --- engines/mads/scene_data.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'engines/mads') diff --git a/engines/mads/scene_data.cpp b/engines/mads/scene_data.cpp index e594406447..e48bcd8c6f 100644 --- a/engines/mads/scene_data.cpp +++ b/engines/mads/scene_data.cpp @@ -451,8 +451,6 @@ void SceneInfo::loadMadsV2Background(int sceneId, const Common::String &resName, fab.decompress(compressedTileData, compressedTileDataSize, (byte*)newTile->getPixels(), tileWidth * tileHeight); tileSet.push_back(TileSetList::value_type(newTile)); - newTile->free(); - delete newTile; delete[] compressedTileData; } @@ -471,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(); -- cgit v1.2.3 From dd63cef93efce72b300c99a6a8b9415a111c2b82 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Sat, 11 Apr 2015 15:38:31 -0500 Subject: MADS: Fix memory leak in Dialog class --- engines/mads/dialogs.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'engines/mads') diff --git a/engines/mads/dialogs.cpp b/engines/mads/dialogs.cpp index 158d9693ad..7f0b02bc65 100644 --- a/engines/mads/dialogs.cpp +++ b/engines/mads/dialogs.cpp @@ -43,6 +43,7 @@ Dialog::Dialog(MADSEngine *vm) } Dialog::~Dialog() { + delete _savedSurface; } void Dialog::save() { -- cgit v1.2.3