DIRECTOR: Refactor FilmLoopCastMember to use Sprite

This commit is contained in:
Scott Percival 2021-10-06 23:52:49 +08:00
parent 0ecdd9b26f
commit 0efc7139a9
4 changed files with 113 additions and 47 deletions

View File

@ -30,6 +30,7 @@
#include "director/cursor.h"
#include "director/channel.h"
#include "director/movie.h"
#include "director/sprite.h"
#include "director/sound.h"
#include "director/window.h"
#include "director/stxt.h"
@ -603,63 +604,93 @@ void FilmLoopCastMember::loadFilmLoopData(Common::SeekableReadStreamEndian &stre
int channel = (order / channelSize) - 1;
int channelOffset = order % channelSize;
uint16 spriteCastId = 0;
int16 x = 0;
int16 y = 0;
uint16 width = 0;
uint16 height = 0;
Sprite sprite(nullptr);
if (newFrame.sprites.contains(channel)) {
FilmLoopSprite s = newFrame.sprites.getVal(channel);
spriteCastId = s.castId;
x = s.bbox.left;
y = s.bbox.top;
width = s.bbox.width();
height = s.bbox.height();
sprite = newFrame.sprites.getVal(channel);
}
debugC(8, kDebugLoading, "Message: msgWidth %d, channel %d, channelOffset %d", msgWidth, channel, channelOffset);
if (debugChannelSet(8, kDebugLoading)) {
stream.hexdump(msgWidth);
}
for (int i = channelOffset; i < channelOffset + msgWidth; i += 2) {
switch (i) {
case 6:
spriteCastId = stream.readUint16BE();
int fieldPosition = channelOffset;
int finishPosition = channelOffset + msgWidth;
while (fieldPosition < finishPosition) {
switch (fieldPosition) {
case kSpritePositionUnk1:
stream.readByte();
fieldPosition++;
break;
case 8:
y = stream.readSint16BE();
case kSpritePositionEnabled:
sprite._enabled = stream.readByte() != 0;
fieldPosition++;
break;
case 10:
x = stream.readSint16BE();
case kSpritePositionUnk2:
stream.readUint16BE();
fieldPosition += 2;
break;
case 12:
height = stream.readUint16BE();
case kSpritePositionFlags:
sprite._thickness = stream.readByte();
sprite._inkData = stream.readByte();
sprite._ink = static_cast<InkType>(sprite._inkData & 0x3f);
if (sprite._inkData & 0x40)
sprite._trails = 1;
else
sprite._trails = 0;
fieldPosition += 2;
break;
case 14:
width = stream.readUint16BE();
case kSpritePositionCastId:
sprite._castId = CastMemberID(stream.readUint16(), 0);
fieldPosition += 2;
break;
case kSpritePositionY:
sprite._startPoint.y = stream.readUint16();
fieldPosition += 2;
break;
case kSpritePositionX:
sprite._startPoint.x = stream.readUint16();
fieldPosition += 2;
break;
case kSpritePositionWidth:
sprite._width = stream.readUint16();
fieldPosition += 2;
break;
case kSpritePositionHeight:
sprite._height = stream.readUint16();
fieldPosition += 2;
break;
default:
stream.readUint16BE();
fieldPosition += 2;
break;
}
}
frameSize -= msgWidth;
Common::Rect spriteBbox(x, y, x + width, y + height);
newFrame.sprites.setVal(channel, FilmLoopSprite(spriteCastId, spriteBbox));
if (!_bbox.isValidRect()) {
_bbox = spriteBbox;
} else {
_bbox.extend(spriteBbox);
Common::Rect spriteBbox(
sprite._startPoint.x,
sprite._startPoint.y,
sprite._startPoint.x + sprite._width,
sprite._startPoint.y + sprite._height
);
newFrame.sprites.setVal(channel, sprite);
if (!((spriteBbox.width() == 0) && (spriteBbox.height() == 0))) {
if ((_bbox.width() == 0) && (_bbox.height() == 0)) {
_bbox = spriteBbox;
} else {
_bbox.extend(spriteBbox);
}
}
}
if (debugChannelSet(5, kDebugLoading)) {
for (Common::HashMap<int, FilmLoopSprite>::iterator s = newFrame.sprites.begin(); s != newFrame.sprites.end(); ++s) {
debugC(5, kDebugLoading, "FilmLoopSprite: channel %d, castId %d, bbox %d %d %d %d", s->_key,
s->_value.castId, s->_value.bbox.left, s->_value.bbox.top,
s->_value.bbox.width(), s->_value.bbox.height());
for (Common::HashMap<int, Sprite>::iterator s = newFrame.sprites.begin(); s != newFrame.sprites.end(); ++s) {
debugC(5, kDebugLoading, "Sprite: channel %d, castId %s, bbox %d %d %d %d", s->_key,
s->_value._castId.asString().c_str(), s->_value._startPoint.x, s->_value._startPoint.y,
s->_value._width, s->_value._height);
}
}
@ -667,6 +698,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());
}

View File

@ -26,6 +26,7 @@
#include "graphics/font.h"
#include "director/archive.h"
#include "director/sprite.h"
#include "director/stxt.h"
#include "director/lingo/lingo-object.h"
@ -58,6 +59,7 @@ class AudioDecoder;
struct CastMemberInfo;
class Channel;
struct Resource;
class Sprite;
class Stxt;
class CastMember : public Object<CastMember> {
@ -190,16 +192,8 @@ public:
};
struct FilmLoopSprite {
uint16 castId;
Common::Rect bbox;
FilmLoopSprite() { castId = 0; }
FilmLoopSprite(uint16 castId1, Common::Rect &bbox1) { castId = castId1; bbox = bbox1; }
};
struct FilmLoopFrame {
Common::HashMap<int, FilmLoopSprite> sprites;
Common::HashMap<int, Sprite> sprites;
};
class FilmLoopCastMember : public CastMember {

View File

@ -35,8 +35,8 @@ namespace Director {
Sprite::Sprite(Frame *frame) {
_frame = frame;
_score = _frame->getScore();
_movie = _score->getMovie();
_score = _frame ? _frame->getScore() : nullptr;
_movie = _score ? _score->getMovie() : nullptr;
_scriptId = CastMemberID(0, 0);
_colorcode = 0;
@ -71,6 +71,45 @@ Sprite::Sprite(Frame *frame) {
_stretch = 0;
}
Sprite::Sprite(const Sprite &sprite) {
_frame = sprite._frame;
_score = sprite._score;
_movie = sprite._movie;
_scriptId = sprite._scriptId;
_colorcode = sprite._colorcode;
_blendAmount = sprite._blendAmount;
_unk3 = sprite._unk3;
_enabled = sprite._enabled;
_castId = sprite._castId;
_pattern = sprite._pattern;
_spriteType = sprite._spriteType;
_inkData = sprite._inkData;
_ink = sprite._ink;
_trails = sprite._trails;
_matte = sprite._matte;
_cast = sprite._cast;
_thickness = sprite._thickness;
_startPoint = sprite._startPoint;
_width = sprite._width;
_height = sprite._height;
_moveable = sprite._moveable;
_editable = sprite._editable;
_puppet = sprite._puppet;
_immediate = sprite._immediate;
_backColor = sprite._backColor;
_foreColor = sprite._foreColor;
_blend = sprite._blend;
_volume = sprite._volume;
_stretch = sprite._stretch;
}
Sprite::~Sprite() {
delete _matte;
}

View File

@ -32,8 +32,8 @@ class TextCastMember;
enum SpritePosition {
kSpritePositionUnk1 = 0,
kSpritePositionEnabled,
kSpritePositionUnk2,
kSpritePositionEnabled = 1,
kSpritePositionUnk2 = 2,
kSpritePositionFlags = 4,
kSpritePositionCastId = 6,
kSpritePositionY = 8,
@ -59,7 +59,8 @@ enum MainChannelsPosition {
class Sprite {
public:
Sprite(Frame *frame);
Sprite(Frame *frame = nullptr);
Sprite(const Sprite &sprite);
~Sprite();
Frame *getFrame() const { return _frame; }