[Scummvm-git-logs] scummvm master -> 82d41b17cdeaacca045ce57665976ec89de09489
fracturehill
noreply at scummvm.org
Thu Apr 13 18:24:13 UTC 2023
This automated email contains information about 9 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
d2d65ffb28 NANCY: Make arfactory.cpp more readable
203d4fa5dc NANCY: Implement Overlay action record
e76e3c3f1f NANCY: Correctly load INV chunk in nancy2
9b1c62e489 NANCY: Add stub for SpecialEffect action record
2888248e7e NANCY: Add workaround for broken Overlay
50a08027ab NANCY: Implement ClosedCaptioning dependency
0befb73ecb NANCY: Implement TextBoxWrite action record
4e734c4778 NANCY: Correct viewport panning
82d41b17cd NANCY: Show virtual keyboard during password puzzle
Commit: d2d65ffb2831d78ad9d69c9f369a5180bef7b2bf
https://github.com/scummvm/scummvm/commit/d2d65ffb2831d78ad9d69c9f369a5180bef7b2bf
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2023-04-13T21:20:35+03:00
Commit Message:
NANCY: Make arfactory.cpp more readable
Replaced the hexadecimal ActionRecord typeIDs and replaced
them with the ones found inside gameflow.h. Also updated
the scan_ar_type console command to match.
Changed paths:
engines/nancy/action/arfactory.cpp
engines/nancy/console.cpp
diff --git a/engines/nancy/action/arfactory.cpp b/engines/nancy/action/arfactory.cpp
index d99e77c5578..a49bae4a118 100644
--- a/engines/nancy/action/arfactory.cpp
+++ b/engines/nancy/action/arfactory.cpp
@@ -37,102 +37,101 @@ namespace Nancy {
namespace Action {
ActionRecord *ActionManager::createActionRecord(uint16 type) {
- type -= 0xA;
switch (type) {
- case 0x00:
+ case 10:
return new Hot1FrSceneChange();
- case 0x01:
+ case 11:
return new HotMultiframeSceneChange();
- case 0x02:
+ case 12:
return new SceneChange();
- case 0x03:
+ case 13:
return new HotMultiframeMultisceneChange();
- case 0x04:
+ case 14:
return new Hot1FrExitSceneChange();
- case 0x0A:
+ case 20:
return new PaletteThisScene();
- case 0x0B:
+ case 21:
return new PaletteNextScene();
- case 0x1E:
+ case 40:
return new LightningOn();
- case 0x28:
+ case 50:
return new PlayPrimaryVideoChan0();
- case 0x29:
+ case 51:
return new PlaySecondaryVideo(0);
- case 0x2A:
+ case 52:
return new PlaySecondaryVideo(1);
- case 0x2B:
+ case 53:
return new PlaySecondaryMovie();
- case 0x2C:
+ case 54:
return new PlayStaticBitmapAnimation(false); // PlayStaticBitmapAnimation
- case 0x2D:
+ case 55:
return new PlayStaticBitmapAnimation(true); // PlayIntStaticBitmapAnimation
- case 0x32:
+ case 60:
return new MapCall();
- case 0x33:
+ case 61:
return new MapCallHot1Fr();
- case 0x34:
+ case 62:
return new MapCallHotMultiframe();
- case 0x41:
+ case 75:
return new TextBoxWrite();
- case 0x42:
+ case 76:
return new TextBoxClear();
- case 0x5A:
+ case 100:
return new BumpPlayerClock();
- case 0x5B:
+ case 101:
return new SaveContinueGame();
- case 0x5C:
+ case 102:
return new TurnOffMainRendering();
- case 0x5D:
+ case 103:
return new TurnOnMainRendering();
- case 0x5E:
+ case 104:
return new ResetAndStartTimer();
- case 0x5F:
+ case 105:
return new StopTimer();
- case 0x60:
+ case 106:
return new EventFlagsMultiHS();
- case 0x61:
+ case 107:
return new EventFlags();
- case 0x62:
+ case 108:
return new OrderingPuzzle();
- case 0x63:
+ case 109:
return new LoseGame();
- case 0x64:
+ case 110:
return new PushScene();
- case 0x65:
+ case 111:
return new PopScene();
- case 0x66:
+ case 112:
return new WinGame();
- case 0x67:
+ case 113:
return new DifficultyLevel();
- case 0x68:
+ case 114:
return new RotatingLockPuzzle();
- case 0x69:
+ case 115:
return new LeverPuzzle();
- case 0x6A:
+ case 116:
return new Telephone();
- case 0x6B:
+ case 117:
return new SliderPuzzle();
- case 0x6C:
+ case 118:
return new PasswordPuzzle();
- case 0x6E:
+ case 120:
return new AddInventoryNoHS();
- case 0x6F:
+ case 121:
return new RemoveInventoryNoHS();
- case 0x70:
+ case 122:
return new ShowInventoryItem();
- case 0x8C:
+ case 150:
return new PlayDigiSoundAndDie();
- case 0x8D:
+ case 151:
return new PlayDigiSoundAndDie();
- case 0x8E:
+ case 152:
return new PlaySoundPanFrameAnchorAndDie();
- case 0x8F:
+ case 153:
return new PlaySoundMultiHS();
- case 0x96:
+ case 160:
return new HintSystem();
default:
- error("Action Record type %i is invalid!", type+0xA);
+ error("Action Record type %i is invalid!", type);
return nullptr;
}
}
diff --git a/engines/nancy/console.cpp b/engines/nancy/console.cpp
index 4ac9477cb81..b6829ee100b 100644
--- a/engines/nancy/console.cpp
+++ b/engines/nancy/console.cpp
@@ -546,7 +546,7 @@ bool NancyConsole::Cmd_scanForActionRecordType(int argc, const char **argv) {
return true;
}
- byte typeID = atoi(argv[1]) + 10;
+ byte typeID = atoi(argv[1]);
Common::Array<Common::String> list;
g_nancy->_resource->list((argc == 2 ? "ciftree" : argv[2]), list, ResourceManager::kResTypeScript);
Commit: 203d4fa5dc2f0db65d2f11d3d71d799c30ea431b
https://github.com/scummvm/scummvm/commit/203d4fa5dc2f0db65d2f11d3d71d799c30ea431b
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2023-04-13T21:20:35+03:00
Commit Message:
NANCY: Implement Overlay action record
Implemented the Overlay action record, which is the
upgraded version of PlayIntStaticBitmapAnim that appears
from nancy 2 and onward.
Changed paths:
A engines/nancy/action/overlay.cpp
A engines/nancy/action/overlay.h
R engines/nancy/action/staticbitmapanim.cpp
R engines/nancy/action/staticbitmapanim.h
engines/nancy/action/arfactory.cpp
engines/nancy/commontypes.cpp
engines/nancy/module.mk
diff --git a/engines/nancy/action/arfactory.cpp b/engines/nancy/action/arfactory.cpp
index a49bae4a118..31e7a8a9f79 100644
--- a/engines/nancy/action/arfactory.cpp
+++ b/engines/nancy/action/arfactory.cpp
@@ -23,7 +23,7 @@
#include "engines/nancy/action/primaryvideo.h"
#include "engines/nancy/action/secondaryvideo.h"
#include "engines/nancy/action/secondarymovie.h"
-#include "engines/nancy/action/staticbitmapanim.h"
+#include "engines/nancy/action/overlay.h"
#include "engines/nancy/action/orderingpuzzle.h"
#include "engines/nancy/action/rotatinglockpuzzle.h"
#include "engines/nancy/action/telephone.h"
@@ -63,9 +63,9 @@ ActionRecord *ActionManager::createActionRecord(uint16 type) {
case 53:
return new PlaySecondaryMovie();
case 54:
- return new PlayStaticBitmapAnimation(false); // PlayStaticBitmapAnimation
+ return new Overlay(false); // PlayStaticBitmapAnimation
case 55:
- return new PlayStaticBitmapAnimation(true); // PlayIntStaticBitmapAnimation
+ return new Overlay(true); // PlayIntStaticBitmapAnimation
case 60:
return new MapCall();
case 61:
diff --git a/engines/nancy/action/staticbitmapanim.cpp b/engines/nancy/action/overlay.cpp
similarity index 54%
rename from engines/nancy/action/staticbitmapanim.cpp
rename to engines/nancy/action/overlay.cpp
index 2a1f0f4cd2a..19247e3f08a 100644
--- a/engines/nancy/action/staticbitmapanim.cpp
+++ b/engines/nancy/action/overlay.cpp
@@ -24,65 +24,77 @@
#include "engines/nancy/resource.h"
#include "engines/nancy/util.h"
-#include "engines/nancy/action/staticbitmapanim.h"
+#include "engines/nancy/action/overlay.h"
#include "engines/nancy/state/scene.h"
+#include "common/serializer.h"
+
namespace Nancy {
namespace Action {
-void PlayStaticBitmapAnimation::init() {
+void Overlay::init() {
g_nancy->_resource->loadImage(_imageName, _fullSurface);
- setFrame(0);
+ setFrame(_firstFrame);
RenderObject::init();
}
-void PlayStaticBitmapAnimation::readData(Common::SeekableReadStream &stream) {
- readFilename(stream, _imageName);
-
- stream.skip(0x2);
- _transparency = stream.readUint16LE();
- _animationSceneChange = stream.readUint16LE();
- _playDirection = stream.readUint16LE();
- _loop = stream.readUint16LE();
- _firstFrame = stream.readUint16LE();
- _loopFirstFrame = stream.readUint16LE();
- _loopLastFrame = stream.readUint16LE();
+void Overlay::readData(Common::SeekableReadStream &stream) {
+ Common::Serializer ser(&stream, nullptr);
+ ser.setVersion(g_nancy->getGameType());
+
+ uint16 numSrcRects;
+
+ readFilename(ser, _imageName);
+ ser.skip(2);
+ ser.syncAsUint16LE(_transparency);
+ ser.syncAsUint16LE(_hasSceneChange);
+
+ ser.syncAsUint16LE(_enableHotspot, kGameTypeNancy2);
+ ser.syncAsUint16LE(_z, kGameTypeNancy2);
+ ser.syncAsUint16LE(_overlayType, kGameTypeNancy2);
+ ser.syncAsUint16LE(numSrcRects, kGameTypeNancy2);
+
+ ser.syncAsUint16LE(_playDirection);
+ ser.syncAsUint16LE(_loop);
+ ser.syncAsUint16LE(_firstFrame);
+ ser.syncAsUint16LE(_loopFirstFrame);
+ ser.syncAsUint16LE(_loopLastFrame);
_frameTime = Common::Rational(1000, stream.readUint16LE()).toInt();
- _z = stream.readUint16LE();
+ ser.syncAsUint16LE(_z, kGameTypeNancy1, kGameTypeNancy1);
- if (_isInterruptible) {
- _interruptCondition.label = stream.readSint16LE();
- _interruptCondition.flag = stream.readUint16LE();
- } else {
- _interruptCondition.label = kEvNoEvent;
- _interruptCondition.flag = kEvNotOccurred;
+ if (ser.getVersion() > kGameTypeNancy1) {
+ _isInterruptible = true;
}
+ if (_isInterruptible) {
+ ser.syncAsSint16LE(_interruptCondition.label);
+ ser.syncAsUint16LE(_interruptCondition.flag);
+ } else {
+ _interruptCondition.label = kEvNoEvent;
+ _interruptCondition.flag = kEvNotOccurred;
+ }
+
_sceneChange.readData(stream);
- _triggerFlags.readData(stream);
+ _flagsOnTrigger.readData(stream);
_sound.read(stream, SoundDescription::kNormal);
uint numViewportFrames = stream.readUint16LE();
- _srcRects.reserve(_loopLastFrame - _firstFrame);
- for (uint i = _firstFrame; i <= _loopLastFrame; ++i) {
- _srcRects.push_back(Common::Rect());
- readRect(stream, _srcRects[i]);
+ if (_overlayType == kPlayOverlayAnimated) {
+ numSrcRects = _loopLastFrame - _firstFrame + 1;
}
- _bitmaps.reserve(numViewportFrames);
- for (uint i = 0; i < numViewportFrames; ++i) {
- _bitmaps.push_back(BitmapDescription());
- BitmapDescription &rects = _bitmaps.back();
- rects.frameID = stream.readUint16LE();
- readRect(stream, rects.src);
- readRect(stream, rects.dest);
+ readRectArray(ser, _srcRects, numSrcRects);
+
+ _bitmaps.resize(numViewportFrames);
+ for (auto &bm : _bitmaps) {
+ bm.readData(stream);
}
}
-void PlayStaticBitmapAnimation::execute() {
+void Overlay::execute() {
uint32 _currentFrameTime = g_nancy->getTotalPlayTime();
switch (_state) {
case kBegin:
@@ -94,11 +106,11 @@ void PlayStaticBitmapAnimation::execute() {
// fall through
case kRun: {
// Check the timer to see if we need to draw the next animation frame
- if (_nextFrameTime <= _currentFrameTime) {
+ if (_overlayType == kPlayOverlayAnimated && _nextFrameTime <= _currentFrameTime) {
// World's worst if statement
if (NancySceneState.getEventFlag(_interruptCondition) ||
- ( (((_currentFrame == _loopLastFrame) && (_playDirection == kPlayAnimationForward) && (_loop == kPlayAnimationOnce)) ||
- ((_currentFrame == _loopFirstFrame) && (_playDirection == kPlayAnimationReverse) && (_loop == kPlayAnimationOnce))) &&
+ ( (((_currentFrame == _loopLastFrame) && (_playDirection == kPlayOverlayForward) && (_loop == kPlayOverlayOnce)) ||
+ ((_currentFrame == _loopFirstFrame) && (_playDirection == kPlayOverlayReverse) && (_loop == kPlayOverlayOnce))) &&
!g_nancy->_sound->isSoundPlaying(_sound)) ) {
_state = kActionTrigger;
@@ -117,26 +129,30 @@ void PlayStaticBitmapAnimation::execute() {
if (_currentViewportFrame != newFrame) {
_currentViewportFrame = newFrame;
+ setVisible(false);
+
for (uint i = 0; i < _bitmaps.size(); ++i) {
if (_currentViewportFrame == _bitmaps[i].frameID) {
- _screenPosition = _bitmaps[i].dest;
+ moveTo(_bitmaps[i].dest);
+ setVisible(true);
break;
}
}
}
_nextFrameTime = _currentFrameTime + _frameTime;
- setFrame(_currentFrame);
- if (_playDirection == kPlayAnimationReverse) {
- --_currentFrame;
- _currentFrame = _currentFrame < _loopFirstFrame ? _loopLastFrame : _currentFrame;
- return;
+ uint16 nextFrame = _currentFrame;
+
+ if (_playDirection == kPlayOverlayReverse) {
+ --nextFrame;
+ nextFrame = nextFrame < _loopFirstFrame ? _loopLastFrame : nextFrame;
} else {
- ++_currentFrame;
- _currentFrame = _currentFrame > _loopLastFrame ? _loopFirstFrame : _currentFrame;
- return;
+ ++nextFrame;
+ nextFrame = nextFrame > _loopLastFrame ? _loopFirstFrame : nextFrame;
}
+
+ setFrame(nextFrame);
}
} else {
// Check if we've moved the viewport
@@ -145,9 +161,24 @@ void PlayStaticBitmapAnimation::execute() {
if (_currentViewportFrame != newFrame) {
_currentViewportFrame = newFrame;
+ setVisible(false);
+ _hasHotspot = false;
+
for (uint i = 0; i < _bitmaps.size(); ++i) {
if (_currentViewportFrame == _bitmaps[i].frameID) {
- _screenPosition = _bitmaps[i].dest;
+ moveTo(_bitmaps[i].dest);
+ setVisible(true);
+
+ // In static mode every "animation" frame corresponds to a viewport frame
+ if (_overlayType == kPlayOverlayStatic) {
+ setFrame(i);
+
+ if (_enableHotspot) {
+ _hotspot = _screenPosition;
+ _hasHotspot = true;
+ }
+ }
+
break;
}
}
@@ -157,8 +188,8 @@ void PlayStaticBitmapAnimation::execute() {
break;
}
case kActionTrigger:
- _triggerFlags.execute();
- if (_animationSceneChange == kPlayAnimationSceneChange) {
+ _flagsOnTrigger.execute();
+ if (_hasSceneChange == kPlayOverlaySceneChange) {
NancySceneState.changeScene(_sceneChange);
finishExecution();
}
@@ -166,17 +197,29 @@ void PlayStaticBitmapAnimation::execute() {
}
}
-void PlayStaticBitmapAnimation::onPause(bool pause) {
+void Overlay::onPause(bool pause) {
if (!pause) {
registerGraphics();
}
}
-void PlayStaticBitmapAnimation::setFrame(uint frame) {
+Common::String Overlay::getRecordTypeName() const {
+ if (g_nancy->getGameType() <= kGameTypeNancy1) {
+ if (_isInterruptible) {
+ return "PlayIntStaticBitmapAnimation";
+ } else {
+ return "PlayStaticBitmapAnimation";
+ }
+ } else {
+ return "Overlay";
+ }
+}
+
+void Overlay::setFrame(uint frame) {
_currentFrame = frame;
_drawSurface.create(_fullSurface, _srcRects[frame]);
- setTransparent(_transparency == kPlayAnimationPlain);
+ setTransparent(_transparency == kPlayOverlayPlain);
_needsRedraw = true;
}
diff --git a/engines/nancy/action/staticbitmapanim.h b/engines/nancy/action/overlay.h
similarity index 50%
rename from engines/nancy/action/staticbitmapanim.h
rename to engines/nancy/action/overlay.h
index 41a88acaadd..cb66adad9eb 100644
--- a/engines/nancy/action/staticbitmapanim.h
+++ b/engines/nancy/action/overlay.h
@@ -19,8 +19,8 @@
*
*/
-#ifndef NANCY_ACTION_STATICBITMAPANIM_H
-#define NANCY_ACTION_STATICBITMAPANIM_H
+#ifndef NANCY_ACTION_OVERLAY_H
+#define NANCY_ACTION_OVERLAY_H
#include "engines/nancy/renderobject.h"
@@ -29,26 +29,35 @@
namespace Nancy {
namespace Action {
-// ActionRecord subclass describing a short "flipbook" animation from a single bitmap
-// Also supports sound and getting interrupted by an event flag.
-// This class covers both the PlayStaticBitmapAnimation and PlayIntStaticBitmapAnimation
-// action record types, whose functionality is nearly identical
-class PlayStaticBitmapAnimation : public ActionRecord, public RenderObject {
+// ActionRecord describing an overlay on top of the viewport.
+// That overlay can be either a short animation, or a static bitmap
+// that changes depending on the current viewport frame.
+// This class covers three different ActionRecord types:
+// - PlayStaticBitmapAnimation: nancy1 only, does not support static mode
+// - PlayIntStaticBitmapAnimation: nancy1 only, same as above but supports being interrupted by an event flag
+// - Overlay: nancy2 and above, supports static mode
+class Overlay : public ActionRecord, public RenderObject {
public:
- static const byte kPlayAnimationPlain = 1;
- static const byte kPlayAnimationTransparent = 2;
+ static const byte kPlayOverlayPlain = 1;
+ static const byte kPlayOverlayTransparent = 2;
- static const byte kPlayAnimationSceneChange = 1;
- static const byte kPlayAnimationNoSceneChange = 2;
+ static const byte kPlayOverlaySceneChange = 1;
+ static const byte kPlayOverlayNoSceneChange = 2;
- static const byte kPlayAnimationOnce = 1;
- static const byte kPlayAnimationLoop = 2;
+ static const byte kPlayOverlayStatic = 1;
+ static const byte kPlayOverlayAnimated = 2;
- static const byte kPlayAnimationForward = 1;
- static const byte kPlayAnimationReverse = 2;
+ static const byte kPlayOverlayOnce = 1;
+ static const byte kPlayOverlayLoop = 2;
- PlayStaticBitmapAnimation(bool interruptible) : RenderObject(7), _isInterruptible(interruptible) {}
- virtual ~PlayStaticBitmapAnimation() { _fullSurface.free(); }
+ static const byte kPlayOverlayForward = 1;
+ static const byte kPlayOverlayReverse = 2;
+
+ static const byte kPlayOverlayWithHotspot = 1;
+ static const byte kPlayOverlayNoHotspot = 2;
+
+ Overlay(bool interruptible) : RenderObject(7), _isInterruptible(interruptible) {}
+ virtual ~Overlay() { _fullSurface.free(); }
void init() override;
@@ -58,17 +67,19 @@ public:
Common::String _imageName;
- uint16 _transparency = kPlayAnimationPlain; // 0xC
- uint16 _animationSceneChange = kPlayAnimationSceneChange; // 0xE
- uint16 _playDirection = kPlayAnimationForward; // 0x10
- uint16 _loop = kPlayAnimationOnce; // 0x12
- uint16 _firstFrame = 0; // 0x14
- uint16 _loopFirstFrame = 0; // 0x16
- uint16 _loopLastFrame = 0; // 0x18
+ uint16 _transparency = kPlayOverlayPlain;
+ uint16 _hasSceneChange = kPlayOverlaySceneChange;
+ uint16 _enableHotspot = kPlayOverlayNoHotspot;
+ uint16 _overlayType = kPlayOverlayAnimated;
+ uint16 _playDirection = kPlayOverlayForward;
+ uint16 _loop = kPlayOverlayOnce;
+ uint16 _firstFrame = 0;
+ uint16 _loopFirstFrame = 0;
+ uint16 _loopLastFrame = 0;
Time _frameTime;
- FlagDescription _interruptCondition; // 0x1E
+ FlagDescription _interruptCondition;
SceneChangeDescription _sceneChange;
- MultiEventFlagDescription _triggerFlags; // 0x2A
+ MultiEventFlagDescription _flagsOnTrigger; // 0x2A
Nancy::SoundDescription _sound; // 0x52
@@ -84,7 +95,7 @@ public:
bool _isInterruptible;
protected:
- Common::String getRecordTypeName() const override { return _isInterruptible ? "PlayIntStaticBitmapAnimation" : "PlayStaticBitmapAnimation"; }
+ Common::String getRecordTypeName() const override;
bool isViewportRelative() const override { return true; }
void setFrame(uint frame);
@@ -95,4 +106,4 @@ protected:
} // End of namespace Action
} // End of namespace Nancy
-#endif // NANCY_ACTION_STATICBITMAPANIM_H
+#endif // NANCY_ACTION_OVERLAY_H
diff --git a/engines/nancy/commontypes.cpp b/engines/nancy/commontypes.cpp
index 1d5473d4672..9d492d2b77d 100644
--- a/engines/nancy/commontypes.cpp
+++ b/engines/nancy/commontypes.cpp
@@ -21,6 +21,7 @@
#include "engines/nancy/commontypes.h"
#include "engines/nancy/util.h"
+#include "engines/nancy/nancy.h"
#include "engines/nancy/state/scene.h"
@@ -43,7 +44,12 @@ void HotspotDescription::readData(Common::SeekableReadStream &stream) {
}
void BitmapDescription::readData(Common::SeekableReadStream &stream) {
- frameID = stream.readUint16LE();
+ if (g_nancy->getGameType() <= kGameTypeNancy1) {
+ frameID = stream.readUint16LE();
+ } else {
+ frameID = stream.readUint32LE();
+ }
+
readRect(stream, src);
readRect(stream, dest);
}
diff --git a/engines/nancy/module.mk b/engines/nancy/module.mk
index 1d062e9081f..83034d57663 100644
--- a/engines/nancy/module.mk
+++ b/engines/nancy/module.mk
@@ -13,7 +13,7 @@ MODULE_OBJS = \
action/secondarymovie.o \
action/secondaryvideo.o \
action/sliderpuzzle.o \
- action/staticbitmapanim.o \
+ action/overlay.o \
action/telephone.o \
ui/fullscreenimage.o \
ui/animatedbutton.o \
Commit: e76e3c3f1f1ff6b706d1a28701c65c62e5f1de5a
https://github.com/scummvm/scummvm/commit/e76e3c3f1f1ff6b706d1a28701c65c62e5f1de5a
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2023-04-13T21:20:35+03:00
Commit Message:
NANCY: Correctly load INV chunk in nancy2
Added code to load the new data found in the INV chunk.,
Changed paths:
engines/nancy/enginedata.cpp
engines/nancy/enginedata.h
diff --git a/engines/nancy/enginedata.cpp b/engines/nancy/enginedata.cpp
index 1c1f6d75d93..82df0bc6a25 100644
--- a/engines/nancy/enginedata.cpp
+++ b/engines/nancy/enginedata.cpp
@@ -116,24 +116,66 @@ INV::INV(Common::SeekableReadStream *chunkStream) {
readFilename(s, inventoryBoxIconsImageName);
readFilename(s, inventoryCursorsImageName);
- s.skip(0x4); // inventory box icons surface w/h
- s.skip(0x4); // inventory cursors surface w/h
+ s.skip(0x4, kGameTypeVampire, kGameTypeNancy1); // inventory box icons surface w/h
+ s.skip(0x4, kGameTypeVampire, kGameTypeNancy1); // inventory cursors surface w/h
s.skip(0x10); // unknown rect, same size as a hotspot
- byte itemName[20];
- uint itemNameLength = g_nancy->getGameType() == kGameTypeVampire ? 15 : 20;
+ byte textBuf[60];
+
+ if (s.getVersion() >= kGameTypeNancy2) {
+ cantSound.read(*chunkStream, SoundDescription::kNormal);
+ s.syncBytes(textBuf, 60);
+ textBuf[59] = '\0';
+ cantText = (char *)textBuf;
+ }
+
+ uint itemNameLength;
+ switch (s.getVersion()) {
+ case kGameTypeVampire :
+ itemNameLength = 15;
+ break;
+ case kGameTypeNancy1 :
+ itemNameLength = 20;
+ break;
+ case kGameTypeNancy2 :
+ // fall through
+ default:
+ itemNameLength = 48;
+ break;
+ }
uint16 numItems = g_nancy->getStaticData().numItems;
itemDescriptions.resize(numItems);
for (uint i = 0; i < numItems; ++i) {
ItemDescription &item = itemDescriptions[i];
- s.syncBytes(itemName, itemNameLength);
- itemName[itemNameLength - 1] = '\0';
- item.name = (char *)itemName;
+ s.syncBytes(textBuf, itemNameLength);
+ textBuf[itemNameLength - 1] = '\0';
+ item.name = (char *)textBuf;
+
s.syncAsUint16LE(item.keepItem);
readRect(s, item.sourceRect);
+ readRect(s, item.highlightedSourceRect, kGameTypeNancy2);
+
+ if (s.getVersion() == kGameTypeNancy2) {
+ s.syncBytes(textBuf, 60);
+ textBuf[59] = '\0';
+ item.specificCantText = (char *)textBuf;
+
+ s.syncBytes(textBuf, 60);
+ textBuf[59] = '\0';
+ item.generalCantText = (char *)textBuf;
+
+ item.specificCantSound.read(*chunkStream, SoundDescription::kNormal);
+ item.generalCantSound.read(*chunkStream, SoundDescription::kNormal);
+ } else if (s.getVersion() >= kGameTypeNancy3) {
+ s.syncBytes(textBuf, 60);
+ textBuf[59] = '\0';
+ item.specificCantText = (char *)textBuf;
+
+ item.specificCantSound.read(*chunkStream, SoundDescription::kNormal);
+ }
}
delete chunkStream;
diff --git a/engines/nancy/enginedata.h b/engines/nancy/enginedata.h
index 5227adb8513..3d195bee912 100644
--- a/engines/nancy/enginedata.h
+++ b/engines/nancy/enginedata.h
@@ -69,6 +69,12 @@ struct INV {
Common::String name;
byte keepItem;
Common::Rect sourceRect;
+ Common::Rect highlightedSourceRect;
+
+ Common::String specificCantText;
+ Common::String generalCantText;
+ SoundDescription specificCantSound;
+ SoundDescription generalCantSound;
};
INV(Common::SeekableReadStream *chunkStream);
@@ -87,6 +93,9 @@ struct INV {
Common::String inventoryBoxIconsImageName;
Common::String inventoryCursorsImageName;
+ SoundDescription cantSound;
+ Common::String cantText;
+
Common::Array<ItemDescription> itemDescriptions;
};
Commit: 9b1c62e4892e74c881d8154be305a324e8538333
https://github.com/scummvm/scummvm/commit/9b1c62e4892e74c881d8154be305a324e8538333
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2023-04-13T21:20:35+03:00
Commit Message:
NANCY: Add stub for SpecialEffect action record
Changed paths:
engines/nancy/action/arfactory.cpp
engines/nancy/action/recordtypes.cpp
engines/nancy/action/recordtypes.h
diff --git a/engines/nancy/action/arfactory.cpp b/engines/nancy/action/arfactory.cpp
index 31e7a8a9f79..7f52edcbf22 100644
--- a/engines/nancy/action/arfactory.cpp
+++ b/engines/nancy/action/arfactory.cpp
@@ -33,6 +33,8 @@
#include "engines/nancy/state/scene.h"
+#include "engines/nancy/nancy.h"
+
namespace Nancy {
namespace Action {
@@ -53,7 +55,12 @@ ActionRecord *ActionManager::createActionRecord(uint16 type) {
case 21:
return new PaletteNextScene();
case 40:
- return new LightningOn();
+ if (g_nancy->getGameType() < kGameTypeNancy2) {
+ // Only used in TVD
+ return new LightningOn();
+ } else {
+ return new SpecialEffect();
+ }
case 50:
return new PlayPrimaryVideoChan0();
case 51:
diff --git a/engines/nancy/action/recordtypes.cpp b/engines/nancy/action/recordtypes.cpp
index a004477b1ce..e6509a35c55 100644
--- a/engines/nancy/action/recordtypes.cpp
+++ b/engines/nancy/action/recordtypes.cpp
@@ -206,6 +206,10 @@ void LightningOn::readData(Common::SeekableReadStream &stream) {
stream.skip(4);
}
+void SpecialEffect::readData(Common::SeekableReadStream &stream) {
+ stream.skip(5);
+}
+
void LightningOn::execute() {
NancySceneState.beginLightning(_distance, _pulseTime, _rgbPercent);
_isDone = true;
diff --git a/engines/nancy/action/recordtypes.h b/engines/nancy/action/recordtypes.h
index 5d371711015..f60f22e7700 100644
--- a/engines/nancy/action/recordtypes.h
+++ b/engines/nancy/action/recordtypes.h
@@ -130,6 +130,14 @@ protected:
Common::String getRecordTypeName() const override { return "LightningOn"; }
};
+class SpecialEffect : public Unimplemented {
+public:
+ void readData(Common::SeekableReadStream &stream) override;
+
+protected:
+ Common::String getRecordTypeName() const override { return "SpecialEffect"; }
+};
+
class MapCall : public ActionRecord {
public:
void readData(Common::SeekableReadStream &stream) override;
Commit: 2888248e7ed868582814ee798aacfaf630b879e5
https://github.com/scummvm/scummvm/commit/2888248e7ed868582814ee798aacfaf630b879e5
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2023-04-13T21:20:36+03:00
Commit Message:
NANCY: Add workaround for broken Overlay
Changed paths:
engines/nancy/action/overlay.cpp
diff --git a/engines/nancy/action/overlay.cpp b/engines/nancy/action/overlay.cpp
index 19247e3f08a..5ff6dfad94b 100644
--- a/engines/nancy/action/overlay.cpp
+++ b/engines/nancy/action/overlay.cpp
@@ -217,7 +217,17 @@ Common::String Overlay::getRecordTypeName() const {
void Overlay::setFrame(uint frame) {
_currentFrame = frame;
- _drawSurface.create(_fullSurface, _srcRects[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
+ Common::Rect srcRect = _srcRects[frame];
+ if (!srcRect.isValidRect()) {
+ srcRect.setWidth(_srcRects[0].width());
+ srcRect.setHeight(_srcRects[0].height());
+ }
+
+ _drawSurface.create(_fullSurface, srcRect);
setTransparent(_transparency == kPlayOverlayPlain);
Commit: 50a08027aba5729884ff95c4832ce1ce3d15a139
https://github.com/scummvm/scummvm/commit/50a08027aba5729884ff95c4832ce1ce3d15a139
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2023-04-13T21:20:36+03:00
Commit Message:
NANCY: Implement ClosedCaptioning dependency
Implemented the ClosedCaptioning action record
dependency type introduced in nancy2.
Changed paths:
engines/nancy/action/actionmanager.cpp
engines/nancy/action/actionrecord.h
diff --git a/engines/nancy/action/actionmanager.cpp b/engines/nancy/action/actionmanager.cpp
index 90952714467..a2346cfd270 100644
--- a/engines/nancy/action/actionmanager.cpp
+++ b/engines/nancy/action/actionmanager.cpp
@@ -20,6 +20,7 @@
*/
#include "common/serializer.h"
+#include "common/config-manager.h"
#include "engines/nancy/nancy.h"
#include "engines/nancy/input.h"
@@ -29,7 +30,6 @@
#include "engines/nancy/action/actionrecord.h"
#include "engines/nancy/state/scene.h"
-
namespace Nancy {
namespace Action {
@@ -309,6 +309,17 @@ void ActionManager::processActionRecords() {
dep.satisfied = true;
}
+ break;
+ case DependencyType::kClosedCaptioning:
+ if (ConfMan.getBool("subtitles")) {
+ if (dep.condition == 2) {
+ dep.satisfied = true;
+ }
+ } else {
+ if (dep.condition == 1) {
+ dep.satisfied = true;
+ }
+ }
break;
default:
warning("Unimplemented Dependency type %i", (int)dep.type);
diff --git a/engines/nancy/action/actionrecord.h b/engines/nancy/action/actionrecord.h
index bbca62d2b87..327eff5153a 100644
--- a/engines/nancy/action/actionrecord.h
+++ b/engines/nancy/action/actionrecord.h
@@ -55,7 +55,7 @@ enum struct DependencyType : byte {
kTimerLessThanDependencyTime = 13,
kTimerGreaterThanDependencyTime = 14,
kDifficultyLevel = 15,
- kClosedCaptioning = 16, // Not implemented
+ kClosedCaptioning = 16,
kSound = 17, // Not implemented
kOpenParentheses = 18, // Not implemented
kCloseParentheses = 19 // Not implemented
Commit: 0befb73ecbe1959e943000daa6095c291466ba2b
https://github.com/scummvm/scummvm/commit/0befb73ecbe1959e943000daa6095c291466ba2b
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2023-04-13T21:20:36+03:00
Commit Message:
NANCY: Implement TextBoxWrite action record
Changed paths:
engines/nancy/action/recordtypes.cpp
engines/nancy/action/recordtypes.h
diff --git a/engines/nancy/action/recordtypes.cpp b/engines/nancy/action/recordtypes.cpp
index e6509a35c55..40824c4da96 100644
--- a/engines/nancy/action/recordtypes.cpp
+++ b/engines/nancy/action/recordtypes.cpp
@@ -277,11 +277,31 @@ void MapCallHotMultiframe::execute() {
void TextBoxWrite::readData(Common::SeekableReadStream &stream) {
uint16 size = stream.readUint16LE();
- stream.skip(size);
if (size > 10000) {
error("Action Record atTextboxWrite has too many text box chars: %d", size);
}
+
+ char *buf = new char[size];
+ stream.read(buf, size);
+ buf[size - 1] = '\0';
+ _text = buf;
+
+ delete[] buf;
+}
+
+TextBoxWrite::~TextBoxWrite() {
+ NancySceneState.setShouldClearTextbox(true);
+ NancySceneState.getTextbox().setVisible(false);
+}
+
+void TextBoxWrite::execute() {
+ auto &tb = NancySceneState.getTextbox();
+ tb.clear();
+ tb.addTextLine(_text);
+ tb.setVisible(true);
+ NancySceneState.setShouldClearTextbox(false);
+ finishExecution();
}
void TextBoxClear::readData(Common::SeekableReadStream &stream) {
diff --git a/engines/nancy/action/recordtypes.h b/engines/nancy/action/recordtypes.h
index f60f22e7700..9a217a848fe 100644
--- a/engines/nancy/action/recordtypes.h
+++ b/engines/nancy/action/recordtypes.h
@@ -171,9 +171,14 @@ protected:
Common::String getRecordTypeName() const override { return "MapCallHotMultiframe"; }
};
-class TextBoxWrite : public Unimplemented {
+class TextBoxWrite : public ActionRecord {
public:
+ virtual ~TextBoxWrite();
+
void readData(Common::SeekableReadStream &stream) override;
+ void execute() override;
+
+ Common::String _text;
protected:
Common::String getRecordTypeName() const override { return "TextBoxWrite"; }
Commit: 4e734c4778dfd3104b89ed3ad7d26f1ea102b990
https://github.com/scummvm/scummvm/commit/4e734c4778dfd3104b89ed3ad7d26f1ea102b990
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2023-04-13T21:20:37+03:00
Commit Message:
NANCY: Correct viewport panning
Fixed an issue where the viewport would wrap around once
even when set to kPanLeftRight mode.
Changed paths:
engines/nancy/ui/viewport.cpp
diff --git a/engines/nancy/ui/viewport.cpp b/engines/nancy/ui/viewport.cpp
index 7dcbf55fa14..83f3d03e48c 100644
--- a/engines/nancy/ui/viewport.cpp
+++ b/engines/nancy/ui/viewport.cpp
@@ -186,6 +186,8 @@ void Viewport::loadVideo(const Common::String &filename, uint frameNr, uint vert
_videoFormat = format;
enableEdges(kUp | kDown | kLeft | kRight);
+
+ _panningType = panningType;
setFrame(frameNr);
setVerticalScroll(verticalScroll);
@@ -197,7 +199,6 @@ void Viewport::loadVideo(const Common::String &filename, uint frameNr, uint vert
_movementLastFrame = 0;
_nextMovementTime = 0;
- _panningType = panningType;
}
void Viewport::setFrame(uint frameNr) {
Commit: 82d41b17cdeaacca045ce57665976ec89de09489
https://github.com/scummvm/scummvm/commit/82d41b17cdeaacca045ce57665976ec89de09489
Author: Kaloyan Chehlarski (strahy at outlook.com)
Date: 2023-04-13T21:20:37+03:00
Commit Message:
NANCY: Show virtual keyboard during password puzzle
Changed paths:
engines/nancy/action/passwordpuzzle.cpp
diff --git a/engines/nancy/action/passwordpuzzle.cpp b/engines/nancy/action/passwordpuzzle.cpp
index ba131d67048..f85faf01257 100644
--- a/engines/nancy/action/passwordpuzzle.cpp
+++ b/engines/nancy/action/passwordpuzzle.cpp
@@ -77,6 +77,7 @@ void PasswordPuzzle::execute() {
case kBegin:
init();
registerGraphics();
+ g_system->setFeatureState(OSystem::kFeatureVirtualKeyboard, true);
_nextBlinkTime = g_nancy->getTotalPlayTime() + _cursorBlinkTime;
_state = kRun;
// fall through
@@ -156,6 +157,8 @@ void PasswordPuzzle::execute() {
NancySceneState.setEventFlag(_flagOnSolve.label);
break;
}
+
+ g_system->setFeatureState(OSystem::kFeatureVirtualKeyboard, false);
finishExecution();
}
More information about the Scummvm-git-logs
mailing list