[Scummvm-git-logs] scummvm master -> e9779c0c367c9be415520b2c1e022ec265bd1ff6
fracturehill
noreply at scummvm.org
Thu Jul 13 11:33:53 UTC 2023
This automated email contains information about 4 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
9162c5357c NANCY: Add detection entries
eda2ee947c NANCY: Fix use-then-lose items
1bfb6f8d98 NANCY: Ignore invalid hotspots
e9779c0c36 NANCY: Implement SoundEqualizerPuzzle
Commit: 9162c5357c55dad2bf3125c4d1775c137d98a918
https://github.com/scummvm/scummvm/commit/9162c5357c55dad2bf3125c4d1775c137d98a918
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2023-07-13T14:32:46+03:00
Commit Message:
NANCY: Add detection entries
Added detection entries for nancy3 and nancy4's Steam
releases, as well as an unknown variant of nancy5.
Changed paths:
engines/nancy/detection.cpp
diff --git a/engines/nancy/detection.cpp b/engines/nancy/detection.cpp
index f2f9a8e160c..9e366da4129 100644
--- a/engines/nancy/detection.cpp
+++ b/engines/nancy/detection.cpp
@@ -144,7 +144,18 @@ static const Nancy::NancyGameDescription gameDescriptions[] = {
AD_ENTRY1s("ciftree.dat", "ee5f8832226567c3610556497c451b09", 16256355),
Common::EN_ANY,
Common::kPlatformWindows,
- ADGF_UNSTABLE | ADGF_DROPPLATFORM | ADGF_DROPPLATFORM,
+ ADGF_UNSTABLE | ADGF_DROPPLATFORM,
+ GUIO0()
+ },
+ Nancy::kGameTypeNancy3
+ },
+ { // Steam version
+ {
+ "nancy3", nullptr,
+ AD_ENTRY1s("ciftree.dat", "6b379f9d8edfb2d439062122e08f785c", 16161115),
+ Common::EN_ANY,
+ Common::kPlatformWindows,
+ ADGF_UNSTABLE | ADGF_DROPPLATFORM,
GUIO0()
},
Nancy::kGameTypeNancy3
@@ -171,7 +182,7 @@ static const Nancy::NancyGameDescription gameDescriptions[] = {
AD_ENTRY1s("ciftree.dat", "6b379f9d8edfb2d439062122e08f785c", 16161148),
Common::RU_RUS,
Common::kPlatformWindows,
- ADGF_UNSTABLE | ADGF_DROPPLATFORM | ADGF_DROPPLATFORM,
+ ADGF_UNSTABLE | ADGF_DROPPLATFORM,
GUIO0()
},
Nancy::kGameTypeNancy3
@@ -203,6 +214,28 @@ static const Nancy::NancyGameDescription gameDescriptions[] = {
},
Nancy::kGameTypeNancy4
},
+ { // MD5 by fracturehill
+ {
+ "nancy4", nullptr,
+ AD_ENTRY1s("ciftree.dat", "8645fad8c3fb8c0ee13e7a0a75902782", 9714463),
+ Common::RU_RUS,
+ Common::kPlatformWindows,
+ ADGF_UNSTABLE | ADGF_DROPPLATFORM,
+ GUIO0()
+ },
+ Nancy::kGameTypeNancy4
+ },
+ { // Steam version
+ {
+ "nancy4", nullptr,
+ AD_ENTRY1s("ciftree.dat", "3ad55cd8f9a3b010a19de44ff4ce7edf", 8786300),
+ Common::EN_ANY,
+ Common::kPlatformWindows,
+ ADGF_UNSTABLE | ADGF_DROPPLATFORM,
+ GUIO0()
+ },
+ Nancy::kGameTypeNancy4
+ },
{ // MD5 by waltervn
{
"nancy4", nullptr,
@@ -219,17 +252,6 @@ static const Nancy::NancyGameDescription gameDescriptions[] = {
},
Nancy::kGameTypeNancy4
},
- { // MD5 by fracturehill
- {
- "nancy4", nullptr,
- AD_ENTRY1s("ciftree.dat", "8645fad8c3fb8c0ee13e7a0a75902782", 9714463),
- Common::RU_RUS,
- Common::kPlatformWindows,
- ADGF_UNSTABLE | ADGF_DROPPLATFORM,
- GUIO0()
- },
- Nancy::kGameTypeNancy4
- },
{ // MD5 by fracturehill
{
"nancy4", nullptr,
@@ -290,6 +312,22 @@ static const Nancy::NancyGameDescription gameDescriptions[] = {
},
Nancy::kGameTypeNancy5
},
+ { // MD5 by fracturehill
+ {
+ "nancy5", nullptr,
+ {
+ { "data1.hdr", 0, "0db3fb5bc002eb875eebb872969a22ca", 278505 },
+ { "data1.cab", 0, "b5d2d218ded5683b5ca2eafcdc1ed76e", 1720654 },
+ { "data2.cab", 0, "d379a879fb23b3013f78537927ac6cfe", 548761463 },
+ AD_LISTEND
+ },
+ Common::EN_ANY,
+ Common::kPlatformWindows,
+ ADGF_UNSTABLE | ADGF_DROPPLATFORM | Nancy::GF_COMPRESSED,
+ GUIO0()
+ },
+ Nancy::kGameTypeNancy5
+ },
{ // MD5 by Strangerke
{
"nancy6", nullptr,
Commit: eda2ee947c167dd3f58944824417992e40440f82
https://github.com/scummvm/scummvm/commit/eda2ee947c167dd3f58944824417992e40440f82
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2023-07-13T14:32:46+03:00
Commit Message:
NANCY: Fix use-then-lose items
Items marked as single-use are now correctly removed from
the inventory. Also extended the get_inventory console
command to show if an item is single-use or not.
Changed paths:
engines/nancy/action/actionmanager.cpp
engines/nancy/console.cpp
diff --git a/engines/nancy/action/actionmanager.cpp b/engines/nancy/action/actionmanager.cpp
index 4d43bb65310..add96cb7ab6 100644
--- a/engines/nancy/action/actionmanager.cpp
+++ b/engines/nancy/action/actionmanager.cpp
@@ -74,6 +74,8 @@ void ActionManager::handleInput(NancyInput &input) {
NancySceneState.setHeldItem(-1);
}
+
+ rec->_cursorDependency = nullptr;
}
}
@@ -371,13 +373,8 @@ void ActionManager::processDependency(DependencyRecord &dep, ActionRecord &recor
}
}
- if (isSatisfied) {
- dep.satisfied = true;
- record._cursorDependency = nullptr;
- } else {
- dep.satisfied = false;
- record._cursorDependency = &dep;
- }
+ dep.satisfied = isSatisfied;
+ record._cursorDependency = &dep;
}
break;
diff --git a/engines/nancy/console.cpp b/engines/nancy/console.cpp
index 7fdd00fddfe..5e846292a45 100644
--- a/engines/nancy/console.cpp
+++ b/engines/nancy/console.cpp
@@ -669,9 +669,10 @@ bool NancyConsole::Cmd_getInventory(int argc, const char **argv) {
if (argc == 1) {
for (uint i = 0; i < numItems; ++i) {
- debugPrintf("\nItem %u, %s, %s",
+ debugPrintf("\nItem %u, %s, %s, %s",
i,
g_nancy->_inventoryData->itemDescriptions[i].name.c_str(),
+ g_nancy->_inventoryData->itemDescriptions[i].keepItem == 0 ? "UseThenLose" : "KeepAlways",
NancySceneState.hasItem(i) == g_nancy->_true ? "true" : "false");
}
} else {
@@ -681,9 +682,10 @@ bool NancyConsole::Cmd_getInventory(int argc, const char **argv) {
debugPrintf("\nInvalid flag %s", argv[i]);
continue;
}
- debugPrintf("\nItem %u, %s, %s",
+ debugPrintf("\nItem %u, %s, %s, %s",
flagID,
g_nancy->_inventoryData->itemDescriptions[flagID].name.c_str(),
+ g_nancy->_inventoryData->itemDescriptions[i].keepItem == 0 ? "UseThenLose" : "KeepAlways",
NancySceneState.hasItem(i) == g_nancy->_true ? "true" : "false");
}
Commit: 1bfb6f8d98f02d9250c398d47f84ee1eb3c8168e
https://github.com/scummvm/scummvm/commit/1bfb6f8d98f02d9250c398d47f84ee1eb3c8168e
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2023-07-13T14:32:46+03:00
Commit Message:
NANCY: Ignore invalid hotspots
Added a check for action record hotspot validity. This
fixes a broken frame in nancy2 scene 1600.
Changed paths:
engines/nancy/action/actionmanager.cpp
diff --git a/engines/nancy/action/actionmanager.cpp b/engines/nancy/action/actionmanager.cpp
index add96cb7ab6..da78c3f6198 100644
--- a/engines/nancy/action/actionmanager.cpp
+++ b/engines/nancy/action/actionmanager.cpp
@@ -41,7 +41,10 @@ void ActionManager::handleInput(NancyInput &input) {
rec->handleInput(input);
}
- if (rec->_isActive && rec->_hasHotspot && NancySceneState.getViewport().convertViewportToScreen(rec->_hotspot).contains(input.mousePos)) {
+ if ( rec->_isActive &&
+ rec->_hasHotspot &&
+ rec->_hotspot.isValidRect() && // Needed for nancy2 scene 1600
+ NancySceneState.getViewport().convertViewportToScreen(rec->_hotspot).contains(input.mousePos)) {
g_nancy->_cursorManager->setCursorType(rec->getHoverCursor());
if (input.input & NancyInput::kLeftMouseButtonUp) {
Commit: e9779c0c367c9be415520b2c1e022ec265bd1ff6
https://github.com/scummvm/scummvm/commit/e9779c0c367c9be415520b2c1e022ec265bd1ff6
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2023-07-13T14:32:46+03:00
Commit Message:
NANCY: Implement SoundEqualizerPuzzle
Implemented the SoundEqualizerPuzzle, used for nancy2's
mixing console sequence. Also extended the SoundManager
to accommodate the need to change volume and playback
rate while a sound is playing.
Changed paths:
A engines/nancy/action/soundequalizerpuzzle.cpp
A engines/nancy/action/soundequalizerpuzzle.h
engines/nancy/action/arfactory.cpp
engines/nancy/module.mk
engines/nancy/puzzledata.cpp
engines/nancy/puzzledata.h
engines/nancy/sound.cpp
engines/nancy/sound.h
engines/nancy/ui/scrollbar.cpp
engines/nancy/ui/scrollbar.h
diff --git a/engines/nancy/action/arfactory.cpp b/engines/nancy/action/arfactory.cpp
index 50a726d6ef3..d94d809c34f 100644
--- a/engines/nancy/action/arfactory.cpp
+++ b/engines/nancy/action/arfactory.cpp
@@ -35,6 +35,7 @@
#include "engines/nancy/action/riddlepuzzle.h"
#include "engines/nancy/action/overridelockpuzzle.h"
#include "engines/nancy/action/bombpuzzle.h"
+#include "engines/nancy/action/soundequalizerpuzzle.h"
#include "engines/nancy/state/scene.h"
@@ -152,6 +153,8 @@ ActionRecord *ActionManager::createActionRecord(uint16 type) {
return new StopSound(); // StopAndUnloadSound, but we always unload
case 160:
return new HintSystem();
+ case 200:
+ return new SoundEqualizerPuzzle();
case 201:
return new TowerPuzzle();
case 202:
diff --git a/engines/nancy/action/soundequalizerpuzzle.cpp b/engines/nancy/action/soundequalizerpuzzle.cpp
new file mode 100644
index 00000000000..0dbf8ba918d
--- /dev/null
+++ b/engines/nancy/action/soundequalizerpuzzle.cpp
@@ -0,0 +1,304 @@
+/* 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 3 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, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include "engines/nancy/action/soundequalizerpuzzle.h"
+#include "engines/nancy/state/scene.h"
+#include "engines/nancy/ui/scrollbar.h"
+
+#include "engines/nancy/util.h"
+#include "engines/nancy/nancy.h"
+#include "engines/nancy/graphics.h"
+#include "engines/nancy/resource.h"
+#include "engines/nancy/input.h"
+#include "engines/nancy/sound.h"
+#include "engines/nancy/puzzledata.h"
+
+namespace Nancy {
+namespace Action {
+
+class ViewportScrollbar : public UI::Scrollbar {
+public:
+ ViewportScrollbar(uint16 zOrder, const Common::Rect &srcBounds, Graphics::ManagedSurface &srcSurf, const Common::Point &topPosition, uint16 scrollDistance, bool isVertical = true) :
+ Scrollbar(zOrder, srcBounds, srcSurf, topPosition, scrollDistance, isVertical) {}
+ virtual ~ViewportScrollbar() = default;
+
+ bool handleInput(NancyInput &input) {
+ if (_screenPosition.contains(input.mousePos)) {
+ input.input &= (~NancyInput::kRightMouseButtonUp);
+
+ Scrollbar::handleInput(input);
+
+ g_nancy->_cursorManager->setCursorType(CursorManager::kHotspot);
+ return true;
+ }
+
+ return false;
+ }
+};
+
+SoundEqualizerPuzzle::~SoundEqualizerPuzzle() {
+ for (auto *scrollbar : _sliders) {
+ delete scrollbar;
+ }
+}
+
+void SoundEqualizerPuzzle::init() {
+ Common::Rect screenBounds = NancySceneState.getViewport().getBounds();
+ _drawSurface.create(screenBounds.width(), screenBounds.height(), g_nancy->_graphicsManager->getInputPixelFormat());
+ _drawSurface.clear(g_nancy->_graphicsManager->getTransColor());
+ setTransparent(true);
+ setVisible(true);
+ moveTo(screenBounds);
+
+ g_nancy->_resource->loadImage(_imageName, _image);
+ _image.setTransparentColor(_drawSurface.getTransparentColor());
+
+ Common::Rect vpPos = g_nancy->_viewportData->screenPosition;
+
+ if (_puzzleState->sliderValues[0] == 255) {
+ for (uint i = 0; i < 6; ++i) {
+ _puzzleState->sliderValues[i] = _sliderInitialPositions[i];
+ }
+ }
+
+ _sliders.resize(6);
+ for (uint i = 0; i < 6; ++i) {
+ Common::Point screenDest(_sliderX[i], _sliderYMax[i] - (_sliderSrc.height() / 2));
+ screenDest.x += vpPos.left;
+ screenDest.y += vpPos.top;
+ _sliders[i] = new ViewportScrollbar( 8,
+ _sliderSrc,
+ _image,
+ screenDest,
+ _sliderYMin[i] - _sliderYMax[i]);
+ _sliders[i]->init();
+ _sliders[i]->setPosition((float)(100 - _puzzleState->sliderValues[i]) / 100);
+ }
+}
+
+void SoundEqualizerPuzzle::registerGraphics() {
+ for (auto *scrollbar : _sliders) {
+ scrollbar->registerGraphics();
+ }
+
+ RenderActionRecord::registerGraphics();
+}
+
+void SoundEqualizerPuzzle::readData(Common::SeekableReadStream &stream) {
+ _puzzleState = (SoundEqualizerPuzzleData *)NancySceneState.getPuzzleData(SoundEqualizerPuzzleData::getTag());
+ assert(_puzzleState);
+
+ uint16 difficulty = NancySceneState.getDifficulty();
+ readFilename(stream, _imageName);
+
+ readRect(stream, _buttonSrc);
+ readRect(stream, _buttonDest);
+ readRect(stream, _sliderSrc);
+
+ _sliderX.resize(6);
+ _sliderYMin.resize(6);
+ _sliderYMax.resize(6);
+ for (uint i = 0; i < 6; ++i) {
+ _sliderX[i] = stream.readUint16LE();
+ _sliderYMin[i] = stream.readUint16LE();
+ _sliderYMax[i] = stream.readUint16LE();
+ }
+
+ readRect(stream, _lightSrc);
+
+ _lightDests.resize(6);
+ for (uint i = 0; i < 6; ++i) {
+ readRectArray(stream, _lightDests[i], 10);
+ }
+
+ _sliderInitialPositions.resize(6);
+ for (uint i = 0; i < 3; ++i) {
+ // Only read the data for the current difficulty and skip over the rest
+ if (i == difficulty) {
+ for (uint j = 0; j < 6; ++j) {
+ _sliderInitialPositions[j] = stream.readUint16LE();
+ }
+ } else {
+ stream.skip(12);
+ }
+ }
+
+ _sounds.resize(3);
+ for (uint i = 0; i < 3; ++i) {
+ _sounds[i].readNormal(stream);
+ }
+
+ _minVolume.resize(3);
+ _maxVolume.resize(3);
+ _minRate.resize(3);
+ _maxRate.resize(3);
+
+ for (uint i = 0; i < 3; ++i) {
+ // Only read the data for the current difficulty and skip over the rest
+ if (i == difficulty) {
+ for (uint j = 0; j < 3; ++j) {
+ _minVolume[j] = stream.readUint16LE();
+ _maxVolume[j] = stream.readUint16LE();
+ _minRate[j] = stream.readUint32LE();
+ _maxRate[j] = stream.readUint32LE();
+ }
+ } else {
+ stream.skip(12 * 3);
+ }
+ }
+
+ _solveChannelID = stream.readUint16LE();
+
+ for (uint i = 0; i < 3; ++i) {
+ // Only read the data for the current difficulty and skip over the rest
+ if (i == difficulty) {
+ _solveMinVolume = stream.readUint16LE();
+ _solveMaxVolume = stream.readUint16LE();
+ _solveMinRate = stream.readUint32LE();
+ _solveMaxRate = stream.readUint32LE();
+ } else {
+ stream.skip(12);
+ }
+ }
+
+ _exitScene.readData(stream);
+ stream.skip(2);
+ _exitSound.readNormal(stream);
+
+ _solveFlag.label = stream.readSint16LE();
+ _solveFlag.flag = stream.readByte();
+}
+
+void SoundEqualizerPuzzle::execute() {
+ switch(_state) {
+ case kBegin:
+ init();
+ registerGraphics();
+
+ for (uint i = 0; i < 3; ++i) {
+ g_nancy->_sound->loadSound(_sounds[i]);
+ g_nancy->_sound->playSound(_sounds[i]);
+ }
+
+ for (uint i = 0; i < 6; ++i) {
+ updateSlider(i);
+ }
+
+ _state = kRun;
+ break;
+ case kRun:
+ break;
+ case kActionTrigger:
+ if (g_nancy->_sound->isSoundPlaying(_exitSound)) {
+ return;
+ }
+
+ for (uint i = 0; i < 3; ++i) {
+ g_nancy->_sound->stopSound(_sounds[i]);
+ }
+
+ NancySceneState.changeScene(_exitScene);
+ finishExecution();
+ }
+}
+
+void SoundEqualizerPuzzle::handleInput(NancyInput &input) {
+ if (_state == kActionTrigger) {
+ g_nancy->_cursorManager->setCursorType(CursorManager::kHotspot);
+ return;
+ } else if (_state == kBegin) {
+ return;
+ }
+
+ if (NancySceneState.getViewport().convertViewportToScreen(_buttonDest).contains(input.mousePos)) {
+ g_nancy->_cursorManager->setCursorType(CursorManager::kHotspot);
+
+ if (input.input & NancyInput::kLeftMouseButtonUp) {
+ // Exit button pressed
+ _drawSurface.blitFrom(_image, _buttonSrc, _buttonDest);
+ _needsRedraw = true;
+
+ g_nancy->_sound->loadSound(_exitSound);
+ g_nancy->_sound->playSound(_exitSound);
+
+ _state = kActionTrigger;
+ return;
+ }
+ } else {
+ for (uint i = 0; i < 6; ++i) {
+ if (_sliders[i]->handleInput(input)) {
+ updateSlider(i);
+ break;
+ }
+ }
+ }
+}
+
+void SoundEqualizerPuzzle::updateSlider(uint sliderID) {
+ float sliderVal = 1 - _sliders[sliderID]->getPos();
+ _puzzleState->sliderValues[sliderID] = sliderVal * 100;
+
+ if (sliderID < 3) {
+ // First three sliders change pitch, except when the slider
+ // controls the "solve" sound; in that case it does nothing
+ if (sliderID != _solveChannelID) {
+ g_nancy->_sound->setRate(_sounds[sliderID],
+ _minRate[sliderID] + (_maxRate[sliderID] - _minRate[sliderID]) * sliderVal);
+ }
+ } else {
+ // Other three sliders change volume;
+ // "solve" sound slider behaves as an on/off switch
+ if (sliderID - 3 != _solveChannelID) {
+ g_nancy->_sound->setVolume(_sounds[sliderID - 3],
+ _minVolume[sliderID - 3] + (_maxVolume[sliderID - 3] - _minVolume[sliderID - 3]) * sliderVal);
+ } else {
+ if (sliderVal * 100 >= _solveMinVolume && sliderVal * 100 <= _solveMaxVolume) {
+ g_nancy->_sound->setVolume(_sounds[sliderID - 3], _maxVolume[sliderID - 3]);
+
+ // Since the rate for the "solve" sound never actualy changes,
+ // we only need the volume to be correct.
+ NancySceneState.setEventFlag(_solveFlag);
+ } else {
+ g_nancy->_sound->setVolume(_sounds[sliderID - 3], _minVolume[sliderID - 3]);
+ }
+ }
+ }
+
+ uint numLights = sliderVal * 10;
+
+ if (numLights < 10) {
+ Common::Rect clear = _lightDests[sliderID][numLights];
+ clear.extend(_lightDests[sliderID][9]);
+
+ _drawSurface.fillRect(clear, _drawSurface.getTransparentColor());
+
+ _needsRedraw = true;
+ }
+
+ for (uint i = 0; i < numLights; ++i) {
+ _drawSurface.blitFrom(_image, _lightSrc, _lightDests[sliderID][i]);
+
+ _needsRedraw = true;
+ }
+}
+
+} // End of namespace Action
+} // End of namespace Nancy
diff --git a/engines/nancy/action/soundequalizerpuzzle.h b/engines/nancy/action/soundequalizerpuzzle.h
new file mode 100644
index 00000000000..bff08a2254f
--- /dev/null
+++ b/engines/nancy/action/soundequalizerpuzzle.h
@@ -0,0 +1,99 @@
+/* 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 3 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, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef NANCY_ACTION_SOUNDEQUALIZERPUZZLE_H
+#define NANCY_ACTION_SOUNDEQUALIZERPUZZLE_H
+
+#include "engines/nancy/action/actionrecord.h"
+
+namespace UI {
+class Scrollbar;
+}
+
+namespace Nancy {
+
+struct SoundEqualizerPuzzleData;
+
+namespace Action {
+
+class ViewportScrollbar;
+
+class SoundEqualizerPuzzle: public RenderActionRecord {
+public:
+ SoundEqualizerPuzzle() : RenderActionRecord(7) {}
+ virtual ~SoundEqualizerPuzzle();
+
+ void init() override;
+ void registerGraphics() override;
+
+ void readData(Common::SeekableReadStream &stream) override;
+ void execute() override;
+ void handleInput(NancyInput &input) override;
+
+ Common::String _imageName;
+
+ Common::Rect _buttonSrc;
+ Common::Rect _buttonDest;
+ Common::Rect _sliderSrc;
+
+ Common::Array<uint16> _sliderX;
+ Common::Array<uint16> _sliderYMin;
+ Common::Array<uint16> _sliderYMax;
+
+ Common::Rect _lightSrc;
+ Common::Array<Common::Array<Common::Rect>> _lightDests;
+
+ Common::Array<uint16> _sliderInitialPositions;
+
+ Common::Array<SoundDescription> _sounds;
+
+ Common::Array<uint16> _minVolume;
+ Common::Array<uint16> _maxVolume;
+ Common::Array<uint16> _minRate;
+ Common::Array<uint16> _maxRate;
+
+ uint16 _solveChannelID;
+ uint16 _solveMinVolume;
+ uint16 _solveMaxVolume;
+ uint16 _solveMinRate;
+ uint16 _solveMaxRate;
+
+ SceneChangeDescription _exitScene;
+ SoundDescription _exitSound;
+
+ FlagDescription _solveFlag;
+
+ Graphics::ManagedSurface _image;
+ Common::Array<ViewportScrollbar *> _sliders;
+
+ SoundEqualizerPuzzleData *_puzzleState = nullptr;
+
+protected:
+ Common::String getRecordTypeName() const override { return "SoundEqualizerPuzzle"; }
+ bool isViewportRelative() const override { return true; }
+
+ void updateSlider(uint sliderID);
+};
+
+} // End of namespace Action
+} // End of namespace Nancy
+
+#endif // NANCY_ACTION_SOUNDEQUALIZERPUZZLE_H
diff --git a/engines/nancy/module.mk b/engines/nancy/module.mk
index 075bfd37c4b..d06009945d4 100644
--- a/engines/nancy/module.mk
+++ b/engines/nancy/module.mk
@@ -18,6 +18,7 @@ MODULE_OBJS = \
action/secondarymovie.o \
action/secondaryvideo.o \
action/sliderpuzzle.o \
+ action/soundequalizerpuzzle.o \
action/towerpuzzle.o \
action/telephone.o \
ui/fullscreenimage.o \
diff --git a/engines/nancy/puzzledata.cpp b/engines/nancy/puzzledata.cpp
index 5515e88f5da..9b0baa117e7 100644
--- a/engines/nancy/puzzledata.cpp
+++ b/engines/nancy/puzzledata.cpp
@@ -96,6 +96,14 @@ void RiddlePuzzleData::synchronize(Common::Serializer &ser) {
ser.syncArray(solvedRiddleIDs.data(), numRiddles, Common::Serializer::Byte);
}
+SoundEqualizerPuzzleData::SoundEqualizerPuzzleData() {
+ sliderValues.resize(6, 255);
+}
+
+void SoundEqualizerPuzzleData::synchronize(Common::Serializer &ser) {
+ ser.syncArray(sliderValues.data(), 6, Common::Serializer::Byte);
+}
+
PuzzleData *makePuzzleData(const uint32 tag) {
switch(tag) {
case SliderPuzzleData::getTag():
@@ -106,6 +114,8 @@ PuzzleData *makePuzzleData(const uint32 tag) {
return new TowerPuzzleData();
case RiddlePuzzleData::getTag():
return new RiddlePuzzleData();
+ case SoundEqualizerPuzzleData::getTag():
+ return new SoundEqualizerPuzzleData();
default:
return nullptr;
}
diff --git a/engines/nancy/puzzledata.h b/engines/nancy/puzzledata.h
index bf9c90f4a07..abed79cf1d3 100644
--- a/engines/nancy/puzzledata.h
+++ b/engines/nancy/puzzledata.h
@@ -78,6 +78,15 @@ struct RiddlePuzzleData : public PuzzleData {
int8 incorrectRiddleID;
};
+struct SoundEqualizerPuzzleData : public PuzzleData {
+ SoundEqualizerPuzzleData();
+
+ static constexpr uint32 getTag() { return MKTAG('S', 'E', 'Q', 'L'); }
+ virtual void synchronize(Common::Serializer &ser);
+
+ Common::Array<byte> sliderValues;
+};
+
PuzzleData *makePuzzleData(const uint32 tag);
} // End of namespace Nancy
diff --git a/engines/nancy/sound.cpp b/engines/nancy/sound.cpp
index 6dd1b011fa0..65cdc5199f6 100644
--- a/engines/nancy/sound.cpp
+++ b/engines/nancy/sound.cpp
@@ -486,6 +486,30 @@ void SoundManager::calculatePanForAllSounds() {
}
}
+void SoundManager::setVolume(uint16 channelID, uint16 volume) {
+ _mixer->setChannelVolume(_channels[channelID].handle, volume);
+}
+
+void SoundManager::setVolume(const SoundDescription &description, uint16 volume) {
+ setVolume(description.channelID, volume);
+}
+
+void SoundManager::setVolume(const Common::String &chunkName, uint16 volume) {
+ setVolume(_commonSounds[chunkName], volume);
+}
+
+void SoundManager::setRate(uint16 channelID, uint32 rate) {
+ _mixer->setChannelRate(_channels[channelID].handle, rate);
+}
+
+void SoundManager::setRate(const SoundDescription &description, uint32 rate) {
+ setRate(description.channelID, rate);
+}
+
+void SoundManager::setRate(const Common::String &chunkName, uint32 rate) {
+ setRate(_commonSounds[chunkName], rate);
+}
+
void SoundManager::stopAndUnloadSpecificSounds() {
if (g_nancy->getGameType() == kGameTypeVampire && Nancy::State::Map::hasInstance()) {
// Don't stop the map sound in certain scenes
diff --git a/engines/nancy/sound.h b/engines/nancy/sound.h
index 6277217c468..d5da394260c 100644
--- a/engines/nancy/sound.h
+++ b/engines/nancy/sound.h
@@ -71,6 +71,14 @@ public:
void calculatePan(const SoundDescription &description);
void calculatePanForAllSounds();
+ void setVolume(uint16 channelID, uint16 volume);
+ void setVolume(const SoundDescription &description, uint16 volume);
+ void setVolume(const Common::String &chunkName, uint16 volume);
+
+ void setRate(uint16 channelID, uint32 rate);
+ void setRate(const SoundDescription &description, uint32 rate);
+ void setRate(const Common::String &chunkName, uint32 rate);
+
// Used when changing scenes
void stopAndUnloadSpecificSounds();
diff --git a/engines/nancy/ui/scrollbar.cpp b/engines/nancy/ui/scrollbar.cpp
index b12b6e3ceab..0a79e0d7c1e 100644
--- a/engines/nancy/ui/scrollbar.cpp
+++ b/engines/nancy/ui/scrollbar.cpp
@@ -30,12 +30,15 @@ namespace Nancy {
namespace UI {
Scrollbar::Scrollbar(uint16 zOrder, const Common::Rect &srcBounds, const Common::Point &topPosition, uint16 scrollDistance, bool isVertical) :
+ Scrollbar(zOrder, srcBounds, g_nancy->_graphicsManager->_object0, topPosition, scrollDistance, isVertical) {}
+
+Scrollbar::Scrollbar(uint16 zOrder, const Common::Rect &srcBounds, Graphics::ManagedSurface &srcSurf, const Common::Point &topPosition, uint16 scrollDistance, bool isVertical) :
RenderObject(zOrder),
_isVertical(isVertical),
_isClicked(false),
_currentPosition(0),
_maxDist(scrollDistance) {
- _drawSurface.create(g_nancy->_graphicsManager->_object0, srcBounds);
+ _drawSurface.create(srcSurf, srcBounds);
_startPosition = topPosition;
_startPosition.x -= srcBounds.width() / 2;
@@ -92,6 +95,11 @@ void Scrollbar::handleInput(NancyInput &input) {
}
}
+void Scrollbar::setPosition(float pos) {
+ _currentPosition = pos;
+ moveTo(Common::Point(_screenPosition.left, _startPosition.y + (_maxDist * pos)));
+}
+
void Scrollbar::calculatePosition() {
uint16 scroll = _isVertical ? _screenPosition.top - _startPosition.y : _screenPosition.left - _startPosition.x;
diff --git a/engines/nancy/ui/scrollbar.h b/engines/nancy/ui/scrollbar.h
index 9129c6d38f6..b85f6938aac 100644
--- a/engines/nancy/ui/scrollbar.h
+++ b/engines/nancy/ui/scrollbar.h
@@ -33,6 +33,7 @@ namespace UI {
class Scrollbar : public RenderObject {
public:
Scrollbar(uint16 zOrder, const Common::Rect &srcBounds, const Common::Point &topPosition, uint16 scrollDistance, bool isVertical = true);
+ Scrollbar(uint16 zOrder, const Common::Rect &srcBounds, Graphics::ManagedSurface &srcSurf, const Common::Point &topPosition, uint16 scrollDistance, bool isVertical = true);
virtual ~Scrollbar() = default;
void init() override;
@@ -42,6 +43,7 @@ public:
void resetPosition();
float getPos() const { return _currentPosition; }
+ void setPosition(float pos);
void calculatePosition();
Common::Point _startPosition;
More information about the Scummvm-git-logs
mailing list