[Scummvm-git-logs] scummvm master -> ee174389de8052c4f75fe5077b0b28a5b118f05b
fracturehill
noreply at scummvm.org
Thu Apr 20 15:01:57 UTC 2023
This automated email contains information about 2 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
9d18181318 NANCY: Implement SpecialEffect
ee174389de NANCY: Overlay fixes
Commit: 9d18181318728fa54969696fce5c6729bd0d70b8
https://github.com/scummvm/scummvm/commit/9d18181318728fa54969696fce5c6729bd0d70b8
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2023-04-20T18:00:23+03:00
Commit Message:
NANCY: Implement SpecialEffect
Implemented the SpecialEffect action record, which
handles crossfading between scenes and fades to black.
Changed paths:
A engines/nancy/misc/specialeffect.cpp
A engines/nancy/misc/specialeffect.h
engines/nancy/action/recordtypes.cpp
engines/nancy/action/recordtypes.h
engines/nancy/enginedata.cpp
engines/nancy/enginedata.h
engines/nancy/graphics.cpp
engines/nancy/graphics.h
engines/nancy/misc/lightning.cpp
engines/nancy/misc/lightning.h
engines/nancy/module.mk
engines/nancy/nancy.cpp
engines/nancy/nancy.h
engines/nancy/state/scene.cpp
engines/nancy/state/scene.h
diff --git a/engines/nancy/action/recordtypes.cpp b/engines/nancy/action/recordtypes.cpp
index ed31513e4a4..375ec74599e 100644
--- a/engines/nancy/action/recordtypes.cpp
+++ b/engines/nancy/action/recordtypes.cpp
@@ -207,7 +207,14 @@ void LightningOn::readData(Common::SeekableReadStream &stream) {
}
void SpecialEffect::readData(Common::SeekableReadStream &stream) {
- stream.skip(5);
+ _type = stream.readByte();
+ _fadeToBlackTime = stream.readUint16LE();
+ _frameTime = stream.readUint16LE();
+}
+
+void SpecialEffect::execute() {
+ NancySceneState.specialEffect(_type, _fadeToBlackTime, _frameTime);
+ _isDone = true;
}
void LightningOn::execute() {
diff --git a/engines/nancy/action/recordtypes.h b/engines/nancy/action/recordtypes.h
index db659fc37e8..1949f229ac5 100644
--- a/engines/nancy/action/recordtypes.h
+++ b/engines/nancy/action/recordtypes.h
@@ -128,9 +128,14 @@ protected:
Common::String getRecordTypeName() const override { return "LightningOn"; }
};
-class SpecialEffect : public Unimplemented {
+class SpecialEffect : public ActionRecord {
public:
void readData(Common::SeekableReadStream &stream) override;
+ void execute() override;
+
+ byte _type = 1;
+ uint16 _fadeToBlackTime = 0;
+ uint16 _frameTime = 0;
protected:
Common::String getRecordTypeName() const override { return "SpecialEffect"; }
diff --git a/engines/nancy/enginedata.cpp b/engines/nancy/enginedata.cpp
index f5c4f3880b2..b7a3cd9fcbd 100644
--- a/engines/nancy/enginedata.cpp
+++ b/engines/nancy/enginedata.cpp
@@ -413,6 +413,16 @@ CLOK::CLOK(Common::SeekableReadStream *chunkStream) {
delete chunkStream;
}
+SPEC::SPEC(Common::SeekableReadStream *chunkStream) {
+ assert(chunkStream);
+
+ chunkStream->seek(0);
+
+ fadeToBlackNumFrames = chunkStream->readByte();
+ fadeToBlackFrameTime = chunkStream->readUint16LE();
+ crossDissolveNumFrames = chunkStream->readUint16LE();
+}
+
ImageChunk::ImageChunk(Common::SeekableReadStream *chunkStream) {
assert(chunkStream);
diff --git a/engines/nancy/enginedata.h b/engines/nancy/enginedata.h
index 1394ee1836c..fd50bd14469 100644
--- a/engines/nancy/enginedata.h
+++ b/engines/nancy/enginedata.h
@@ -208,6 +208,14 @@ struct CLOK {
uint16 frameTime;
};
+struct SPEC {
+ SPEC(Common::SeekableReadStream *chunkStream);
+
+ byte fadeToBlackNumFrames;
+ uint16 fadeToBlackFrameTime;
+ byte crossDissolveNumFrames;
+};
+
struct ImageChunk {
ImageChunk() : width(0), height(0) {}
ImageChunk(Common::SeekableReadStream *chunkStream);
diff --git a/engines/nancy/graphics.cpp b/engines/nancy/graphics.cpp
index 3753ae1e9d2..a7dc274a2ff 100644
--- a/engines/nancy/graphics.cpp
+++ b/engines/nancy/graphics.cpp
@@ -48,7 +48,7 @@ void GraphicsManager::init() {
g_nancy->_resource->loadImage(g_nancy->_imageChunks["OB0"].imageName, _object0);
}
-void GraphicsManager::draw() {
+void GraphicsManager::draw(bool updateScreen) {
if (_isSuppressed) {
_isSuppressed = false;
return;
@@ -109,7 +109,9 @@ void GraphicsManager::draw() {
}
// Draw the screen
- _screen.update();
+ if (updateScreen) {
+ _screen.update();
+ }
}
void GraphicsManager::loadFonts(Common::SeekableReadStream *chunkStream) {
@@ -319,6 +321,12 @@ void GraphicsManager::rotateBlit(const Graphics::ManagedSurface &src, Graphics::
}
}
+void GraphicsManager::crossDissolve(const Graphics::ManagedSurface &from, const Graphics::ManagedSurface &to, byte alpha, Graphics::ManagedSurface &inResult) {
+ assert(from.getBounds() == to.getBounds() && to.getBounds() == inResult.getBounds());
+ inResult.blitFrom(from, Common::Point());
+ inResult.transBlitFrom(to, -1, false, 0, alpha);
+}
+
void GraphicsManager::debugDrawToScreen(const Graphics::ManagedSurface &surf) {
_screen.blitFrom(surf, Common::Point());
_screen.update();
@@ -356,6 +364,13 @@ void GraphicsManager::grabViewportObjects(Common::Array<RenderObject *> &inArray
}
}
+void GraphicsManager::screenshotViewport(Graphics::ManagedSurface &inSurf) {
+ draw(false);
+ inSurf.free();
+ inSurf.create(g_nancy->_viewportData->bounds.width(), g_nancy->_viewportData->bounds.height(), _screenPixelFormat);
+ inSurf.blitFrom(_screen, g_nancy->_viewportData->screenPosition, g_nancy->_viewportData->bounds);
+}
+
// Draw a given screen-space rectangle to the screen
void GraphicsManager::blitToScreen(const RenderObject &src, Common::Rect screenRect) {
_screen.blitFrom(src._drawSurface, src._drawSurface.getBounds().findIntersectingRect(src.convertToLocal(screenRect)), screenRect);
diff --git a/engines/nancy/graphics.h b/engines/nancy/graphics.h
index 713174bbed8..a5fc0caa5b5 100644
--- a/engines/nancy/graphics.h
+++ b/engines/nancy/graphics.h
@@ -37,7 +37,7 @@ public:
GraphicsManager();
void init();
- void draw();
+ void draw(bool updateScreen = true);
void loadFonts(Common::SeekableReadStream *chunkStream);
@@ -56,12 +56,14 @@ public:
uint getTransColor();
void grabViewportObjects(Common::Array<RenderObject *> &inArray);
+ void screenshotViewport(Graphics::ManagedSurface &inSurf);
static void loadSurfacePalette(Graphics::ManagedSurface &inSurf, const Common::String paletteFilename, uint paletteStart = 0, uint paletteSize = 256);
static void copyToManaged(const Graphics::Surface &src, Graphics::ManagedSurface &dst, bool verticalFlip = false, bool doubleSize = false);
static void copyToManaged(void *src, Graphics::ManagedSurface &dst, uint srcW, uint srcH, const Graphics::PixelFormat &format, bool verticalFlip = false, bool doubleSize = false);
static void rotateBlit(const Graphics::ManagedSurface &src, Graphics::ManagedSurface &dest, byte rotation);
+ static void crossDissolve(const Graphics::ManagedSurface &from, const Graphics::ManagedSurface &to, byte alpha, Graphics::ManagedSurface &inResult);
// Debug
void debugDrawToScreen(const Graphics::ManagedSurface &surf);
diff --git a/engines/nancy/misc/lightning.cpp b/engines/nancy/misc/lightning.cpp
index 5e916a96377..6ba0d9af2e9 100644
--- a/engines/nancy/misc/lightning.cpp
+++ b/engines/nancy/misc/lightning.cpp
@@ -189,5 +189,5 @@ void Lightning::handleThunder() {
}
}
-} // End of namespace Action
} // End of namespace Misc
+} // End of namespace Nancy
diff --git a/engines/nancy/misc/lightning.h b/engines/nancy/misc/lightning.h
index c30fe5fe506..fd0cbbc5e52 100644
--- a/engines/nancy/misc/lightning.h
+++ b/engines/nancy/misc/lightning.h
@@ -19,15 +19,12 @@
*
*/
-#ifndef NANCY_ACTION_LIGHTNING_H
-#define NANCY_ACTION_LIGHTNING_H
+#ifndef NANCY_MISC_LIGHTNING_H
+#define NANCY_MISC_LIGHTNING_H
#include "engines/nancy/commontypes.h"
namespace Nancy {
-
-class RenderObject;
-
namespace Misc {
// Special class that handles The Vampire Diaries' lightning screen effect.
@@ -73,4 +70,4 @@ private:
} // End of namespace Misc
} // End of namespace Nancy
-#endif // NANCY_ACTION_LIGHTNING_H
+#endif // NANCY_MISC_LIGHTNING_H
diff --git a/engines/nancy/misc/specialeffect.cpp b/engines/nancy/misc/specialeffect.cpp
new file mode 100644
index 00000000000..b2d9e6deb70
--- /dev/null
+++ b/engines/nancy/misc/specialeffect.cpp
@@ -0,0 +1,89 @@
+/* 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/nancy.h"
+#include "engines/nancy/graphics.h"
+
+#include "engines/nancy/misc/specialeffect.h"
+
+namespace Nancy {
+namespace Misc {
+
+void SpecialEffect::init() {
+ _specialEffectData = g_nancy->_specialEffectData;
+ assert(_specialEffectData);
+
+ _numFrames = _type == kSceneChangeFadeOutToBlack ? _specialEffectData->fadeToBlackNumFrames : _specialEffectData->crossDissolveNumFrames;
+ _frameTime = _type == kSceneChangeFadeOutToBlack ? _specialEffectData->fadeToBlackFrameTime : _frameTime;
+
+ _drawSurface.create(g_nancy->_viewportData->bounds.width(), g_nancy->_viewportData->bounds.height(), g_nancy->_graphicsManager->getScreenPixelFormat());
+ moveTo(g_nancy->_viewportData->screenPosition);
+ setTransparent(false);
+
+ RenderObject::init();
+}
+
+void SpecialEffect::updateGraphics() {
+ if (g_nancy->getTotalPlayTime() > _nextFrameTime && _currentFrame < _numFrames) {
+ ++_currentFrame;
+ _nextFrameTime += _frameTime;
+
+ GraphicsManager::crossDissolve(_fadeFrom, _fadeTo, 255 * _currentFrame / _numFrames, _drawSurface);
+ setVisible(true);
+ }
+}
+
+void SpecialEffect::onSceneChange() {
+ g_nancy->_graphicsManager->screenshotViewport(_fadeFrom);
+ _drawSurface.rawBlitFrom(_fadeFrom, _fadeFrom.getBounds(), Common::Point());
+}
+
+void SpecialEffect::afterSceneChange() {
+ if (_type == kSceneChangeFadeCrossDissolve) {
+ g_nancy->_graphicsManager->screenshotViewport(_fadeTo);
+ } else {
+ _fadeTo.create(_drawSurface.w, _drawSurface.h, _drawSurface.format);
+ _fadeTo.clear();
+ }
+
+ // Workaround for the way ManagedSurface handles transparency. Both pure black
+ // and pure white appear in scenes with SpecialEffects, and those happen to be
+ // the two default values transBlitFrom uses for transColor. By doing this
+ // transColor gets set to the one color guaranteed to not appear in any scene,
+ // and transparency works correctly
+ _fadeTo.setTransparentColor(g_nancy->_graphicsManager->getTransColor());
+
+ registerGraphics();
+ _nextFrameTime = g_nancy->getTotalPlayTime() + _frameTime;
+ _fadeToBlackEndTime = g_nancy->getTotalPlayTime() + _fadeToBlackTime;
+ _initialized = true;
+}
+
+bool SpecialEffect::isDone() const {
+ if (_type == kSceneChangeFadeCrossDissolve) {
+ return _currentFrame >= _numFrames;
+ } else {
+ return g_nancy->getTotalPlayTime() > _fadeToBlackEndTime;
+ }
+}
+
+} // End of namespace Misc
+} // End of namespace Nancy
diff --git a/engines/nancy/misc/specialeffect.h b/engines/nancy/misc/specialeffect.h
new file mode 100644
index 00000000000..33b03340bc7
--- /dev/null
+++ b/engines/nancy/misc/specialeffect.h
@@ -0,0 +1,76 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 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_MISC_SPECIALEFFECT_H
+#define NANCY_MISC_SPECIALEFFECT_H
+
+#include "engines/nancy/time.h"
+#include "engines/nancy/renderobject.h"
+
+namespace Nancy {
+
+struct SPEC;
+
+namespace Misc {
+
+class SpecialEffect : public RenderObject {
+public:
+ static const byte kSceneChangeFadeOutToBlack = 1;
+ static const byte kSceneChangeFadeCrossDissolve = 1;
+
+ SpecialEffect(byte type, uint16 fadeToBlackTime, uint16 frameTime) :
+ RenderObject(16),
+ _type(type),
+ _fadeToBlackTime(fadeToBlackTime),
+ _frameTime(frameTime) {}
+ virtual ~SpecialEffect() {}
+
+ void init() override;
+ void updateGraphics() override;
+
+ void onSceneChange();
+ void afterSceneChange();
+
+ bool isDone() const;
+ bool isInitialized() const { return _initialized; }
+
+protected:
+ bool _initialized = false;
+
+ Time _nextFrameTime;
+ Time _fadeToBlackEndTime;
+
+ Graphics::ManagedSurface _fadeFrom;
+ Graphics::ManagedSurface _fadeTo;
+
+ byte _type = 1;
+ uint16 _fadeToBlackTime = 0;
+ uint16 _frameTime = 0;
+
+ uint _currentFrame = 0;
+ uint _numFrames = 0;
+ SPEC *_specialEffectData = nullptr;
+};
+
+} // End of namespace Misc
+} // End of namespace Nancy
+
+#endif // NANCY_MISC_SPECIALEFFECT_H
diff --git a/engines/nancy/module.mk b/engines/nancy/module.mk
index 90f7a8dbad8..18bde304e50 100644
--- a/engines/nancy/module.mk
+++ b/engines/nancy/module.mk
@@ -35,6 +35,7 @@ MODULE_OBJS = \
state/map.o \
state/scene.o \
misc/lightning.o \
+ misc/specialeffect.o \
commontypes.o \
console.o \
cursor.o \
diff --git a/engines/nancy/nancy.cpp b/engines/nancy/nancy.cpp
index b32e64ac3c0..dabc048bc80 100644
--- a/engines/nancy/nancy.cpp
+++ b/engines/nancy/nancy.cpp
@@ -78,6 +78,7 @@ NancyEngine::NancyEngine(OSystem *syst, const NancyGameDescription *gd) :
_hintData = nullptr;
_sliderPuzzleData = nullptr;
_clockData = nullptr;
+ _specialEffectData = nullptr;
}
NancyEngine::~NancyEngine() {
@@ -98,6 +99,7 @@ NancyEngine::~NancyEngine() {
delete _hintData;
delete _sliderPuzzleData;
delete _clockData;
+ delete _specialEffectData;
}
NancyEngine *NancyEngine::create(GameType type, OSystem *syst, const NancyGameDescription *gd) {
@@ -393,6 +395,11 @@ void NancyEngine::bootGameEngine() {
_clockData = new CLOK(chunkStream);
}
+ chunkStream = boot->getChunkStream("SPEC");
+ if (chunkStream) {
+ _specialEffectData = new SPEC(chunkStream);
+ }
+
_sound->loadCommonSounds(boot);
delete boot;
diff --git a/engines/nancy/nancy.h b/engines/nancy/nancy.h
index 4f9631406ed..35c6ca20671 100644
--- a/engines/nancy/nancy.h
+++ b/engines/nancy/nancy.h
@@ -121,6 +121,7 @@ public:
HINT *_hintData;
SPUZ *_sliderPuzzleData;
CLOK *_clockData;
+ SPEC *_specialEffectData;
Common::HashMap<Common::String, ImageChunk> _imageChunks;
diff --git a/engines/nancy/state/scene.cpp b/engines/nancy/state/scene.cpp
index a7484339cc4..a4b18b2e806 100644
--- a/engines/nancy/state/scene.cpp
+++ b/engines/nancy/state/scene.cpp
@@ -38,6 +38,7 @@
#include "engines/nancy/ui/clock.h"
#include "engines/nancy/misc/lightning.h"
+#include "engines/nancy/misc/specialeffect.h"
namespace Common {
DECLARE_SINGLETON(Nancy::State::Scene);
@@ -114,6 +115,7 @@ Scene::Scene() :
_difficulty(0),
_activeConversation(nullptr),
_lightning(nullptr),
+ _specialEffect(nullptr),
_sliderPuzzleState(nullptr),
_rippedLetterPuzzleState(nullptr),
_towerPuzzleState(nullptr),
@@ -127,6 +129,7 @@ Scene::~Scene() {
delete _inventoryBoxOrnaments;
delete _clock;
delete _lightning;
+ delete _specialEffect;
delete _sliderPuzzleState;
delete _rippedLetterPuzzleState;
delete _towerPuzzleState;
@@ -213,6 +216,10 @@ void Scene::changeScene(uint16 id, uint16 frame, uint16 verticalOffset, byte con
_sceneState.nextScene.paletteID = paletteID;
}
+ if (_specialEffect) {
+ _specialEffect->onSceneChange();
+ }
+
_state = kLoad;
}
@@ -641,6 +648,15 @@ void Scene::beginLightning(int16 distance, uint16 pulseTime, int16 rgbPercent) {
}
}
+void Scene::specialEffect(byte type, uint16 fadeToBlackTime, uint16 frameTime) {
+ if (_specialEffect) {
+ delete _specialEffect;
+ }
+
+ _specialEffect = new Misc::SpecialEffect(type, fadeToBlackTime, frameTime);
+ _specialEffect->init();
+}
+
void Scene::load() {
clearSceneData();
@@ -713,6 +729,10 @@ void Scene::load() {
_timers.sceneTime = 0;
+ if (_specialEffect) {
+ _specialEffect->afterSceneChange();
+ }
+
_state = kStartSound;
}
@@ -723,6 +743,16 @@ void Scene::run() {
return;
}
+ if (_specialEffect && _specialEffect->isInitialized()) {
+ if (_specialEffect->isDone()) {
+ delete _specialEffect;
+ _specialEffect = nullptr;
+ g_nancy->_graphicsManager->redrawAll();
+ }
+
+ return;
+ }
+
Time currentPlayTime = g_nancy->getTotalPlayTime();
Time deltaTime = currentPlayTime - _timers.lastTotalTime;
diff --git a/engines/nancy/state/scene.h b/engines/nancy/state/scene.h
index c0ff18eb5bf..171675414ee 100644
--- a/engines/nancy/state/scene.h
+++ b/engines/nancy/state/scene.h
@@ -52,6 +52,7 @@ class ConversationSound;
namespace Misc {
class Lightning;
+class SpecialEffect;
}
namespace UI {
@@ -185,6 +186,9 @@ public:
// The Vampire Diaries only;
void beginLightning(int16 distance, uint16 pulseTime, int16 rgbPercent);
+ // Used from nancy2 onwards
+ void specialEffect(byte type, uint16 fadeToBlackTime, uint16 frameTime);
+
// Game-specific data that needs to be saved/loaded
SliderPuzzleState *_sliderPuzzleState;
RippedLetterPuzzleState *_rippedLetterPuzzleState;
@@ -268,6 +272,7 @@ private:
NancyState::NancyState _gameStateRequested;
Misc::Lightning *_lightning;
+ Misc::SpecialEffect *_specialEffect;
Common::Rect _mapHotspot;
Commit: ee174389de8052c4f75fe5077b0b28a5b118f05b
https://github.com/scummvm/scummvm/commit/ee174389de8052c4f75fe5077b0b28a5b118f05b
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2023-04-20T18:00:23+03:00
Commit Message:
NANCY: Overlay fixes
Overlays are now correctly set to transparent when needed.
Added a workaround for a broken scene in nancy2.
Changed paths:
engines/nancy/action/overlay.cpp
diff --git a/engines/nancy/action/overlay.cpp b/engines/nancy/action/overlay.cpp
index 36d02074002..01b45423474 100644
--- a/engines/nancy/action/overlay.cpp
+++ b/engines/nancy/action/overlay.cpp
@@ -221,18 +221,19 @@ Common::String Overlay::getRecordTypeName() const {
void Overlay::setFrame(uint frame) {
_currentFrame = frame;
- // Workaround for the fireplace in nancy2 scene 2491,
- // where one of the rects is invalid. Assumes all
- // rects in a single animation have the same dimensions
+ // Workaround for:
+ // - the fireplace in nancy2 scene 2491, where one of the rects is invalid.
+ // - the ball thing in nancy2 scene 1562, where one of the rects is twice as tall as it should be
+ // Assumes all rects in a single animation have the same dimensions
Common::Rect srcRect = _srcRects[frame];
- if (!srcRect.isValidRect()) {
+ if (!srcRect.isValidRect() || srcRect.height() > _srcRects[0].height()) {
srcRect.setWidth(_srcRects[0].width());
srcRect.setHeight(_srcRects[0].height());
}
_drawSurface.create(_fullSurface, srcRect);
- setTransparent(_transparency == kPlayOverlayPlain);
+ setTransparent(_transparency == kPlayOverlayTransparent);
_needsRedraw = true;
}
More information about the Scummvm-git-logs
mailing list