[Scummvm-git-logs] scummvm master -> 6d32f570f5f7820698d330225910e73db2491453

moralrecordings code at moral.net.au
Sun Nov 7 04:05:46 UTC 2021


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:
af69978b58 DIRECTOR: Add Total Distortion demo
6d32f570f5 DIRECTOR: Rework film loops to render as channels


Commit: af69978b5837fc96eb8fb9c52107f08b58537a67
    https://github.com/scummvm/scummvm/commit/af69978b5837fc96eb8fb9c52107f08b58537a67
Author: Scott Percival (code at moral.net.au)
Date: 2021-11-07T12:05:29+08:00

Commit Message:
DIRECTOR: Add Total Distortion demo

Changed paths:
    engines/director/detection_tables.h


diff --git a/engines/director/detection_tables.h b/engines/director/detection_tables.h
index eeb8e7896c..88335a0418 100644
--- a/engines/director/detection_tables.h
+++ b/engines/director/detection_tables.h
@@ -3394,6 +3394,7 @@ static const DirectorGameDescription gameDescriptions[] = {
 	// Mac executable name is TD MAC/PPC
 	MACGAME1("totaldistortion", "", "TD MACPPC", "17efee018a660458fae80de4364021ac", 486074, 404),
 	WINGAME1("totaldistortion", "", "TOTAL_DN.EXE", "461b407c321e80487ae4882056310f9f", 700747, 404),
+	WINGAME1("totaldistortion", "Demo", "TD_DEMO.EXE", "3ae9cfa4b020861b41f3bab9b28f3f5a", 696855, 404),
 
 	MACGAME1("toyota95", "", "Toyota 95", "01be45e7241194dad07938e7059b88e3", 486985, 404),
 


Commit: 6d32f570f5f7820698d330225910e73db2491453
    https://github.com/scummvm/scummvm/commit/6d32f570f5f7820698d330225910e73db2491453
Author: Scott Percival (code at moral.net.au)
Date: 2021-11-07T12:05:29+08:00

Commit Message:
DIRECTOR: Rework film loops to render as channels

The engine treats film loops as N full channels getting rendered to the
screen in the space of one. As such, it's impossible to pre-blit together
the content, as any blitter mode can be used for each of the items.

Changed paths:
    engines/director/castmember.cpp
    engines/director/castmember.h
    engines/director/channel.cpp
    engines/director/channel.h
    engines/director/frame.cpp
    engines/director/window.cpp


diff --git a/engines/director/castmember.cpp b/engines/director/castmember.cpp
index 68f23a74d7..40af6e9cac 100644
--- a/engines/director/castmember.cpp
+++ b/engines/director/castmember.cpp
@@ -570,21 +570,20 @@ bool FilmLoopCastMember::isModified() {
 	if (_frames.size())
 		return true;
 
-	if (_bbox.width() && _bbox.height())
+	if (_initialRect.width() && _initialRect.height())
 		return true;
 
 	return false;
 }
 
-Graphics::MacWidget *FilmLoopCastMember::createWidget(Common::Rect &bbox, Channel *channel, SpriteType spriteType) {
-	Common::Rect widgetRect(bbox.width() ? bbox.width() : _bbox.width(), bbox.height() ? bbox.height() : _bbox.height());
-	channel->_width = widgetRect.width();
-	channel->_height = widgetRect.height();
-	Graphics::MacWidget *widget = new Graphics::MacWidget(g_director->getCurrentWindow(), bbox.left, bbox.top, widgetRect.width(), widgetRect.height(), g_director->_wm, false);
+Common::Array<Channel> *FilmLoopCastMember::getSubChannels(Common::Rect &bbox, Channel *channel) {
+	Common::Rect widgetRect(bbox.width() ? bbox.width() : _initialRect.width(), bbox.height() ? bbox.height() : _initialRect.height());
+
+	_subchannels.clear();
 
 	if (channel->_filmLoopFrame >= _frames.size()) {
 		warning("Film loop frame %d requested, only %d available", channel->_filmLoopFrame, _frames.size());
-		return widget;
+		return &_subchannels;
 	}
 
 	// get the list of sprite IDs for this frame
@@ -594,45 +593,33 @@ Graphics::MacWidget *FilmLoopCastMember::createWidget(Common::Rect &bbox, Channe
 	}
 	Common::sort(spriteIds.begin(), spriteIds.end());
 
-	// render the sprites in order onto the widget surface
+	// copy the sprites in order to the list
 	for (Common::Array<int>::iterator iter = spriteIds.begin(); iter != spriteIds.end(); ++iter) {
 		Sprite src = _frames[channel->_filmLoopFrame].sprites[*iter];
 		if (!src._cast)
 			continue;
 		// translate sprite relative to the global bounding box
-		int16 relX = (src._startPoint.x - _bbox.left) * widgetRect.width() / _bbox.width();
-		int16 relY = (src._startPoint.y - _bbox.top) * widgetRect.height() / _bbox.height();
-		int16 width = src._width * widgetRect.width() / _bbox.width();
-		int16 height = src._height * widgetRect.height() / _bbox.height();
-		Common::Rect relBbox(relX, relY, relX + width, relY + height);
-
-		Graphics::MacWidget *srcWidget = src._cast->createWidget(relBbox, channel, spriteType);
-		DirectorPlotData pd(g_director->_wm, src._spriteType, src._ink, src._blend, src.getBackColor(), src.getForeColor());
-		pd.colorWhite = pd._wm->_colorWhite;
-		pd.colorBlack = pd._wm->_colorBlack;
-		pd.dst = widget->getSurface();
-		pd.destRect = relBbox;
-
-		pd.srf = srcWidget ? srcWidget->getSurface() : nullptr;
-		if (!pd.srf && src._spriteType != kBitmapSprite) {
-			// Shapes come colourized from macDrawPixel
-			pd.ms = src.getShape();
-			pd.applyColor = false;
-			pd.inkBlitShape(relBbox);
-		} else {
-			pd.setApplyColor();
-			// TODO: Support masks
-			pd.inkBlitStretchSurface(relBbox, nullptr);
-		}
-		if (srcWidget)
-			delete srcWidget;
+		int16 relX = (src._startPoint.x - _initialRect.left) * widgetRect.width() / _initialRect.width();
+		int16 relY = (src._startPoint.y - _initialRect.top) * widgetRect.height() / _initialRect.height();
+		int16 absX = relX + bbox.left;
+		int16 absY = relY + bbox.top;
+		int16 width = src._width * widgetRect.width() / _initialRect.width();
+		int16 height = src._height * widgetRect.height() / _initialRect.height();
+
+		Channel chan(&src);
+		chan._currentPoint = Common::Point(absX, absY);
+		chan._width = width;
+		chan._height = height;
+		chan.addRegistrationOffset(chan._currentPoint, true);
+
+		_subchannels.push_back(chan);
+		_subchannels[_subchannels.size() - 1].replaceWidget();
 	}
-
-	return widget;
+	return &_subchannels;
 }
 
 void FilmLoopCastMember::loadFilmLoopData(Common::SeekableReadStreamEndian &stream) {
-	_bbox = Common::Rect();
+	_initialRect = Common::Rect();
 	_frames.clear();
 
 	uint32 size = stream.readUint32BE();
@@ -678,6 +665,8 @@ void FilmLoopCastMember::loadFilmLoopData(Common::SeekableReadStreamEndian &stre
 			if (debugChannelSet(8, kDebugLoading)) {
 				stream.hexdump(msgWidth);
 			}
+			sprite._puppet = 1;
+			sprite._stretch = 1;
 
 			int fieldPosition = channelOffset;
 			int finishPosition = channelOffset + msgWidth;
@@ -744,10 +733,10 @@ void FilmLoopCastMember::loadFilmLoopData(Common::SeekableReadStreamEndian &stre
 			);
 			newFrame.sprites.setVal(channel, sprite);
 			if (!((spriteBbox.width() == 0) && (spriteBbox.height() == 0))) {
-				if ((_bbox.width() == 0) && (_bbox.height() == 0)) {
-					_bbox = spriteBbox;
+				if ((_initialRect.width() == 0) && (_initialRect.height() == 0)) {
+					_initialRect = spriteBbox;
 				} else {
-					_bbox.extend(spriteBbox);
+					_initialRect.extend(spriteBbox);
 				}
 			}
 		}
@@ -764,7 +753,7 @@ void FilmLoopCastMember::loadFilmLoopData(Common::SeekableReadStreamEndian &stre
 		_frames.push_back(newFrame);
 
 	}
-	debugC(5, kDebugLoading, "Full bounding box: %d %d %d %d", _bbox.left, _bbox.top, _bbox.width(), _bbox.height());
+	debugC(5, kDebugLoading, "Full bounding box: %d %d %d %d", _initialRect.left, _initialRect.top, _initialRect.width(), _initialRect.height());
 
 }
 
diff --git a/engines/director/castmember.h b/engines/director/castmember.h
index 84067b7411..26eb28812b 100644
--- a/engines/director/castmember.h
+++ b/engines/director/castmember.h
@@ -202,7 +202,9 @@ public:
 	~FilmLoopCastMember();
 
 	virtual bool isModified() override;
-	virtual Graphics::MacWidget *createWidget(Common::Rect &bbox, Channel *channel, SpriteType spriteType) override;
+	//virtual Graphics::MacWidget *createWidget(Common::Rect &bbox, Channel *channel, SpriteType spriteType) override;
+
+	Common::Array<Channel> *getSubChannels(Common::Rect &bbox, Channel *channel);
 
 	void loadFilmLoopData(Common::SeekableReadStreamEndian &stream);
 
@@ -211,8 +213,8 @@ public:
 	bool _crop;
 	bool _center;
 
-	Common::Rect _bbox;
 	Common::Array<FilmLoopFrame> _frames;
+	Common::Array<Channel> _subchannels;
 };
 
 class SoundCastMember : public CastMember {
diff --git a/engines/director/channel.cpp b/engines/director/channel.cpp
index 079e9abdf2..18ac1f33fb 100644
--- a/engines/director/channel.cpp
+++ b/engines/director/channel.cpp
@@ -43,14 +43,14 @@ Channel::Channel(Sprite *sp, int priority) {
 		_sprite = new Sprite(*sp);
 
 	_widget = nullptr;
-	_currentPoint = sp->_startPoint;
+	_currentPoint = _sprite ? _sprite->_startPoint : Common::Point(0, 0);
 	_delta = Common::Point(0, 0);
 	_constraint = 0;
 	_mask = nullptr;
 
 	_priority = priority;
-	_width = _sprite->_width;
-	_height = _sprite->_height;
+	_width = _sprite ? _sprite->_width : 0;
+	_height = _sprite ? _sprite->_height : 0;
 
 	_movieRate = 0.0;
 	_movieTime = 0;
@@ -65,10 +65,44 @@ Channel::Channel(Sprite *sp, int priority) {
 	_sprite->updateEditable();
 }
 
+Channel::Channel(const Channel &channel) {
+	*this = channel;
+}
+
+Channel& Channel::operator=(const Channel &channel) {
+	_sprite = channel._sprite ? new Sprite(*channel._sprite) : nullptr;
+
+	_widget = nullptr;
+	_currentPoint = channel._currentPoint;
+	_delta = channel._delta;
+	_constraint = channel._constraint;
+	_mask = nullptr;
+
+	_priority = channel._priority;
+	_width = channel._width;
+	_height = channel._height;
+
+	_movieRate = channel._movieRate;
+	_movieTime = channel._movieTime;
+	_startTime = channel._startTime;
+	_stopTime = channel._stopTime;
+
+	_filmLoopFrame = channel._filmLoopFrame;
+
+	_visible = channel._visible;
+	_dirty = channel._dirty;
+
+	return *this;
+}
+
+
 Channel::~Channel() {
-	delete _widget;
-	delete _mask;
-	delete _sprite;
+	if (_widget)
+		delete _widget;
+	if (_mask)
+		delete _mask;
+	if (_sprite)
+		delete _sprite;
 }
 
 DirectorPlotData Channel::getPlotData() {
@@ -603,6 +637,7 @@ void Channel::addRegistrationOffset(Common::Point &pos, bool subtract) {
 			pos += point;
 	} break;
 	case kCastDigitalVideo:
+	case kCastFilmLoop:
 		pos -= Common::Point(_sprite->_cast->_initialRect.width() >> 1, _sprite->_cast->_initialRect.height() >> 1);
 		break;
 	default:
@@ -709,4 +744,20 @@ Common::Point Channel::getPosition() {
 	return res;
 }
 
+bool Channel::hasSubChannels() {
+	if ((_sprite->_cast) && (_sprite->_cast->_type == kCastFilmLoop)) {
+		return true;
+	}
+	return false;
+}
+
+Common::Array<Channel> *Channel::getSubChannels() {
+	if ((!_sprite->_cast) || (_sprite->_cast->_type != kCastFilmLoop)) {
+		warning("Channel doesn't have any sub-channels");
+		return nullptr;
+	}
+	Common::Rect bbox = getBbox();
+	return ((FilmLoopCastMember *)_sprite->_cast)->getSubChannels(bbox, this);
+}
+
 } // End of namespace Director
diff --git a/engines/director/channel.h b/engines/director/channel.h
index 2167ec3480..627bc56fe4 100644
--- a/engines/director/channel.h
+++ b/engines/director/channel.h
@@ -39,6 +39,8 @@ class Cursor;
 class Channel {
 public:
 	Channel(Sprite *sp, int priority = 0);
+	Channel(const Channel &channel);
+	Channel& operator=(const Channel &channel);
 	~Channel();
 
 	DirectorPlotData getPlotData();
@@ -81,6 +83,12 @@ public:
 
 	void updateVideoTime();
 
+	// used for film loops
+	bool hasSubChannels();
+	Common::Array<Channel> *getSubChannels();
+
+	void addRegistrationOffset(Common::Point &pos, bool subtract = false);
+
 public:
 	Sprite *_sprite;
 	Cursor _cursor;
@@ -110,7 +118,6 @@ private:
 	Graphics::ManagedSurface *getSurface();
 	Common::Point getPosition();
 
-	void addRegistrationOffset(Common::Point &pos, bool subtract = false);
 };
 
 } // End of namespace Director
diff --git a/engines/director/frame.cpp b/engines/director/frame.cpp
index 703bf6a7b2..e2e941b62e 100644
--- a/engines/director/frame.cpp
+++ b/engines/director/frame.cpp
@@ -367,7 +367,7 @@ void Frame::readChannels(Common::ReadStreamEndian *stream, uint16 version) {
 		sprite._moveable = ((sprite._colorcode & 0x80) == 0x80);
 
 		if (sprite._castId.member) {
-			debugC(4, kDebugLoading, "CH: %-3d castId: %s [flags:%04x [ink: %x trails: %d line: %d], %dx%d@%d,%d type: %d fg: %d bg: %d] script: %s, flags2: %x, unk2: %x, unk3: %x",
+			debugC(4, kDebugLoading, "CH: %-3d castId: %s [inkData:%02x [ink: %x trails: %d line: %d], %dx%d@%d,%d type: %d fg: %d bg: %d] script: %s, flags2: %x, unk2: %x, unk3: %x",
 				i + 1, sprite._castId.asString().c_str(), sprite._inkData,
 				sprite._ink, sprite._trails, sprite._thickness, sprite._width, sprite._height,
 				sprite._startPoint.x, sprite._startPoint.y,
diff --git a/engines/director/window.cpp b/engines/director/window.cpp
index 3e50e30ada..94aca1590a 100644
--- a/engines/director/window.cpp
+++ b/engines/director/window.cpp
@@ -161,9 +161,16 @@ bool Window::render(bool forceRedraw, Graphics::ManagedSurface *blitTo) {
 				}
 
 				if ((*j)->_visible) {
-					inkBlitFrom(*j, r, blitTo);
-					if ((*j) == hiliteChannel)
-						invertChannel(hiliteChannel, r);
+					if ((*j)->hasSubChannels()) {
+						Common::Array<Channel> *list = (*j)->getSubChannels();
+						for (Common::Array<Channel>::iterator k = list->begin(); k != list->end(); k++) {
+							inkBlitFrom(&(*k), r, blitTo);
+						}
+					} else {
+						inkBlitFrom(*j, r, blitTo);
+						if ((*j) == hiliteChannel)
+							invertChannel(hiliteChannel, r);
+					}
 				}
 			}
 		}




More information about the Scummvm-git-logs mailing list