mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-11 11:45:21 +00:00
DIRECTOR: Refactor Channel to remove overlay position/dimensions
The original logic doesn't hold up to testing. The position/width/height of a sprite can be changed at any time without any extra flags; although the screen needs to be redrawn before you can see any change. The main thing that the sprite puppet flag does is determine if sprites are updated from the score data when the frame changes. Fixes the broken mouse cursor tracking sprite in Chop Suey. Fixes the sprite scaling in the Doc Martens minigame in Virtual Nightclub. Fixes director-tests/D4-unit/T_SPRT01.DIR
This commit is contained in:
parent
7bf8744cf3
commit
2ff3357dac
@ -47,13 +47,10 @@ Channel::Channel(Score *sc, Sprite *sp, int priority) {
|
||||
_sprite = new Sprite(*sp);
|
||||
|
||||
_widget = nullptr;
|
||||
_currentPoint = _sprite ? _sprite->_startPoint : Common::Point(0, 0);
|
||||
_constraint = 0;
|
||||
_mask = nullptr;
|
||||
|
||||
_priority = priority;
|
||||
_width = _sprite ? _sprite->_width : 0;
|
||||
_height = _sprite ? _sprite->_height : 0;
|
||||
|
||||
_movieRate = 0.0;
|
||||
_movieTime = 0;
|
||||
@ -78,13 +75,10 @@ Channel& Channel::operator=(const Channel &channel) {
|
||||
_sprite = channel._sprite ? new Sprite(*channel._sprite) : nullptr;
|
||||
|
||||
_widget = nullptr;
|
||||
_currentPoint = channel._currentPoint;
|
||||
_constraint = channel._constraint;
|
||||
_mask = nullptr;
|
||||
|
||||
_priority = channel._priority;
|
||||
_width = channel._width;
|
||||
_height = channel._height;
|
||||
|
||||
_movieRate = channel._movieRate;
|
||||
_movieTime = channel._movieTime;
|
||||
@ -263,17 +257,16 @@ bool Channel::isDirty(Sprite *nextSprite) {
|
||||
_sprite->_ink != nextSprite->_ink || _sprite->_backColor != nextSprite->_backColor ||
|
||||
_sprite->_foreColor != nextSprite->_foreColor;
|
||||
if (!_sprite->_moveable)
|
||||
isDirtyFlag |= _currentPoint != nextSprite->_startPoint;
|
||||
isDirtyFlag |= _sprite->getPosition() != nextSprite->getPosition();
|
||||
if (isStretched() && !hasTextCastMember(_sprite))
|
||||
isDirtyFlag |= _width != nextSprite->_width || _height != nextSprite->_height;
|
||||
isDirtyFlag |= _sprite->_width != nextSprite->_width || _sprite->_height != nextSprite->_height;
|
||||
}
|
||||
|
||||
return isDirtyFlag;
|
||||
}
|
||||
|
||||
bool Channel::isStretched() {
|
||||
return _sprite->_stretch || (_sprite->_puppet &&
|
||||
(_sprite->_width != _width || _sprite->_height != _height));
|
||||
return _sprite->_stretch;
|
||||
}
|
||||
|
||||
bool Channel::isEmpty() {
|
||||
@ -388,54 +381,12 @@ bool Channel::isVideoDirectToStage() {
|
||||
return ((DigitalVideoCastMember *)_sprite->_cast)->_directToStage;
|
||||
}
|
||||
|
||||
bool Channel::isBboxDeterminedByChannel() {
|
||||
bool isShape = _sprite->_cast && _sprite->_cast->_type == kCastShape;
|
||||
// Use the dimensions and position in the Channel:
|
||||
// - if the sprite is of a shape, or
|
||||
// - if the sprite has the puppet flag enabled
|
||||
// Otherwise, use the Sprite dimensions and position (i.e. taken from the
|
||||
// frame data in the Score).
|
||||
return (isShape || _sprite->_puppet || _sprite->_moveable);
|
||||
}
|
||||
|
||||
Common::Rect Channel::getBbox(bool unstretched) {
|
||||
// Setting unstretched to true always returns the Sprite dimensions.
|
||||
bool useOverride = isBboxDeterminedByChannel() && !unstretched;
|
||||
|
||||
Common::Rect result(
|
||||
useOverride ? _width : _sprite->_width,
|
||||
useOverride ? _height : _sprite->_height
|
||||
);
|
||||
// If this is a cast member, use the cast member's getBbox function
|
||||
// so we start with a rect containing the correct registration offset.
|
||||
if (_sprite->_cast)
|
||||
result = _sprite->_cast->getBbox(result.width(), result.height());
|
||||
|
||||
// The origin of the rect should be at the registration offset,
|
||||
// e.g. for bitmap sprites this defaults to the centre.
|
||||
// Now we move the rect to the correct spot.
|
||||
Common::Point startPos = getPosition(unstretched);
|
||||
result.translate(startPos.x, startPos.y);
|
||||
return result;
|
||||
}
|
||||
|
||||
Common::Point Channel::getPosition(bool unstretched) {
|
||||
bool useOverride = isBboxDeterminedByChannel() && !unstretched;
|
||||
|
||||
return Common::Point(
|
||||
useOverride ? _currentPoint.x : _sprite->_startPoint.x,
|
||||
useOverride ? _currentPoint.y : _sprite->_startPoint.y
|
||||
);
|
||||
}
|
||||
|
||||
void Channel::setCast(CastMemberID memberID) {
|
||||
// release previous widget
|
||||
if (_sprite->_cast)
|
||||
_sprite->_cast->releaseWidget();
|
||||
|
||||
_sprite->setCast(memberID);
|
||||
_width = _sprite->_width;
|
||||
_height = _sprite->_height;
|
||||
replaceWidget();
|
||||
|
||||
// Based on Director in a Nutshell, page 15
|
||||
@ -515,6 +466,21 @@ void Channel::setClean(Sprite *nextSprite, bool partial) {
|
||||
_dirty = false;
|
||||
}
|
||||
|
||||
void Channel::setStretch(bool enabled) {
|
||||
if (!enabled) {
|
||||
// when the stretch flag is manually disabled,
|
||||
// revert whatever dimensions the sprite has to
|
||||
// the default in the cast
|
||||
g_director->getCurrentWindow()->addDirtyRect(getBbox());
|
||||
_dirty = true;
|
||||
|
||||
Common::Rect bbox = _sprite->_cast->getBbox();
|
||||
_sprite->setWidth(bbox.width());
|
||||
_sprite->setHeight(bbox.height());
|
||||
}
|
||||
_sprite->_stretch = enabled;
|
||||
}
|
||||
|
||||
// this is used to for setting and updating text castmember
|
||||
// e.g. set editable, update dims for auto expanding
|
||||
void Channel::updateTextCast() {
|
||||
@ -530,8 +496,6 @@ void Channel::updateTextCast() {
|
||||
if (!textWidget->getFixDims() && (_sprite->_width != _widget->_dims.width() || _sprite->_height != _widget->_dims.height())) {
|
||||
_sprite->_width = _widget->_dims.width();
|
||||
_sprite->_height = _widget->_dims.height();
|
||||
_width = _sprite->_width;
|
||||
_height = _sprite->_height;
|
||||
g_director->getCurrentWindow()->addDirtyRect(_widget->_dims);
|
||||
}
|
||||
}
|
||||
@ -582,7 +546,6 @@ void Channel::replaceSprite(Sprite *nextSprite) {
|
||||
if (!nextSprite)
|
||||
return;
|
||||
|
||||
bool newSprite = (_sprite->_spriteType == kInactiveSprite && nextSprite->_spriteType != kInactiveSprite);
|
||||
bool widgetKeeped = _sprite->_cast && _widget;
|
||||
|
||||
// if there's a video in the old sprite that's different, stop it before we continue
|
||||
@ -597,7 +560,6 @@ void Channel::replaceSprite(Sprite *nextSprite) {
|
||||
if (_sprite->_cast && !canKeepWidget(_sprite, nextSprite)) {
|
||||
widgetKeeped = false;
|
||||
_sprite->_cast->releaseWidget();
|
||||
newSprite = true;
|
||||
}
|
||||
|
||||
// If the cast member is the same, persist the editable flag
|
||||
@ -606,8 +568,8 @@ void Channel::replaceSprite(Sprite *nextSprite) {
|
||||
editable = _sprite->_editable;
|
||||
}
|
||||
|
||||
int width = _width;
|
||||
int height = _height;
|
||||
int width = _sprite->_width;
|
||||
int height = _sprite->_height;
|
||||
bool immediate = _sprite->_immediate;
|
||||
|
||||
*_sprite = *nextSprite;
|
||||
@ -624,46 +586,6 @@ void Channel::replaceSprite(Sprite *nextSprite) {
|
||||
_sprite->_width = width;
|
||||
_sprite->_height = height;
|
||||
}
|
||||
|
||||
// Sprites marked moveable are constrained to the same bounding box until
|
||||
// the moveable is disabled
|
||||
if (!_sprite->_moveable || newSprite)
|
||||
_currentPoint = _sprite->_startPoint;
|
||||
|
||||
_width = _sprite->_width;
|
||||
_height = _sprite->_height;
|
||||
}
|
||||
|
||||
void Channel::setWidth(int w) {
|
||||
_width = MAX<int>(w, 0);
|
||||
|
||||
// Based on Director in a Nutshell, page 15
|
||||
_sprite->setAutoPuppet(kAPWidth, true);
|
||||
}
|
||||
|
||||
void Channel::setHeight(int h) {
|
||||
_height = MAX<int>(h, 0);
|
||||
|
||||
// Based on Director in a Nutshell, page 15
|
||||
_sprite->setAutoPuppet(kAPHeight, true);
|
||||
}
|
||||
|
||||
void Channel::setBbox(int l, int t, int r, int b) {
|
||||
_width = r - l;
|
||||
_height = b - t;
|
||||
|
||||
Common::Rect source(_width, _height);
|
||||
if (_sprite->_cast) {
|
||||
source = _sprite->_cast->getBbox(_width, _height);
|
||||
}
|
||||
_currentPoint.x = (int16)(l - source.left);
|
||||
_currentPoint.y = (int16)(t - source.top);
|
||||
|
||||
if (_width <= 0 || _height <= 0)
|
||||
_width = _height = 0;
|
||||
|
||||
// Based on Director in a Nutshell, page 15
|
||||
_sprite->setAutoPuppet(kAPBbox, true);
|
||||
}
|
||||
|
||||
void Channel::setPosition(int x, int y, bool force) {
|
||||
@ -673,18 +595,7 @@ void Channel::setPosition(int x, int y, bool force) {
|
||||
newPos.x = MIN(constraintBbox.right, MAX(constraintBbox.left, newPos.x));
|
||||
newPos.y = MIN(constraintBbox.bottom, MAX(constraintBbox.top, newPos.y));
|
||||
}
|
||||
_currentPoint = newPos;
|
||||
// Very occasionally, setPosition should override the
|
||||
// sprite copy of the position.
|
||||
// This is necessary for cases where aspects of the sprite
|
||||
// are modified by the score, except for the position
|
||||
// (e.g. dragging the animated parts in Face Kit)
|
||||
if (force) {
|
||||
_sprite->_startPoint = newPos;
|
||||
}
|
||||
|
||||
// Based on Director in a Nutshell, page 15
|
||||
_sprite->setAutoPuppet(kAPLoc, true);
|
||||
_sprite->setPosition(newPos.x, newPos.y);
|
||||
}
|
||||
|
||||
// here is the place for deciding whether the widget can be keep or not
|
||||
@ -743,8 +654,6 @@ void Channel::replaceWidget(CastMemberID previousCastId, bool force) {
|
||||
|
||||
_sprite->_width = _widget->_dims.width();
|
||||
_sprite->_height = _widget->_dims.height();
|
||||
_width = _sprite->_width;
|
||||
_height = _sprite->_height;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -23,6 +23,7 @@
|
||||
#define DIRECTOR_CHANNEL_H
|
||||
|
||||
#include "director/cursor.h"
|
||||
#include "director/sprite.h"
|
||||
|
||||
namespace Graphics {
|
||||
struct Surface;
|
||||
@ -46,10 +47,11 @@ public:
|
||||
DirectorPlotData getPlotData();
|
||||
const Graphics::Surface *getMask(bool forceMatte = false);
|
||||
|
||||
bool isBboxDeterminedByChannel();
|
||||
Common::Point getPosition(bool unstretched = false);
|
||||
inline int getWidth() { return _sprite->_width; };
|
||||
inline int getHeight() { return _sprite->_height; };
|
||||
inline Common::Point getPosition() { return _sprite->getPosition(); };
|
||||
// Return the area of screen to be used for drawing content.
|
||||
Common::Rect getBbox(bool unstretched = false);
|
||||
inline Common::Rect getBbox(bool unstretched = false) { return _sprite->getBbox(unstretched); };
|
||||
|
||||
bool isStretched();
|
||||
bool isDirty(Sprite *nextSprite = nullptr);
|
||||
@ -61,12 +63,13 @@ public:
|
||||
bool isActiveVideo();
|
||||
bool isVideoDirectToStage();
|
||||
|
||||
void setWidth(int w);
|
||||
void setHeight(int h);
|
||||
void setBbox(int l, int t, int r, int b);
|
||||
inline void setWidth(int w) { _sprite->setWidth(w); replaceWidget(); _dirty = true; };
|
||||
inline void setHeight(int h) { _sprite->setHeight(h); replaceWidget(); _dirty = true; };
|
||||
inline void setBbox(int l, int t, int r, int b) { _sprite->setBbox(l, t, r, b); replaceWidget(); _dirty = true; };
|
||||
void setPosition(int x, int y, bool force = false);
|
||||
void setCast(CastMemberID memberID);
|
||||
void setClean(Sprite *nextSprite, bool partial = false);
|
||||
void setStretch(bool enabled);
|
||||
bool getEditable();
|
||||
void setEditable(bool editable);
|
||||
void replaceSprite(Sprite *nextSprite);
|
||||
@ -104,17 +107,6 @@ public:
|
||||
|
||||
int _priority;
|
||||
|
||||
// These fields are used for tracking overrides for the position, width and height of
|
||||
// the channel, as available in Lingo.
|
||||
// Basically, if the sprite -isn't- in puppet mode, Lingo will allow you to set
|
||||
// these values to whatever, but the sprite on the screen will still be the position and
|
||||
// dimensions from the score frame.
|
||||
// If you set puppet mode, the sprite on the screen will use these values instead.
|
||||
// If you set puppet mode, change things, then disable puppet mode, it will revert to the score.
|
||||
Common::Point _currentPoint;
|
||||
int _width;
|
||||
int _height;
|
||||
|
||||
// Used in digital movie sprites
|
||||
double _movieRate;
|
||||
int _movieTime;
|
||||
|
@ -1053,6 +1053,7 @@ static void showChannels() {
|
||||
ImGui::TableNextColumn();
|
||||
|
||||
if (sprite._castId.member) {
|
||||
Common::Point position = channel.getPosition();
|
||||
ImGui::Text("%s", sprite._castId.asString().c_str());
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Checkbox("", &channel._visible);
|
||||
@ -1067,7 +1068,7 @@ static void showChannels() {
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%d", sprite._thickness);
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%dx%d@%d,%d", channel._width, channel._height, channel._currentPoint.x, channel._currentPoint.y);
|
||||
ImGui::Text("%dx%d@%d,%d", channel.getWidth(), channel.getHeight(), position.x, position.y);
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%d (%s)", sprite._spriteType, spriteType2str(sprite._spriteType));
|
||||
ImGui::TableNextColumn();
|
||||
|
@ -153,7 +153,7 @@ void Movie::resolveScriptEvent(LingoEvent &event) {
|
||||
_mouseDownWasInButton = true;
|
||||
|
||||
if (_score->_channels[spriteId]->_sprite->_moveable) {
|
||||
_draggingSpriteOffset = _score->_channels[spriteId]->_currentPoint - event.mousePos;
|
||||
_draggingSpriteOffset = _score->_channels[spriteId]->getPosition() - event.mousePos;
|
||||
_currentDraggedChannel = _score->_channels[spriteId];
|
||||
}
|
||||
|
||||
|
@ -1331,7 +1331,7 @@ Datum Lingo::getTheSprite(Datum &id1, int field) {
|
||||
d = (int)g_director->transformColor(sprite->_foreColor);
|
||||
break;
|
||||
case kTheHeight:
|
||||
d = channel->_height;
|
||||
d = channel->getHeight();
|
||||
break;
|
||||
case kTheImmediate:
|
||||
d = sprite->_immediate;
|
||||
@ -1346,16 +1346,19 @@ Datum Lingo::getTheSprite(Datum &id1, int field) {
|
||||
d = sprite->_thickness & 0x3;
|
||||
break;
|
||||
case kTheLoc:
|
||||
d.type = POINT;
|
||||
d.u.farr = new FArray;
|
||||
d.u.farr->arr.push_back(channel->_currentPoint.x);
|
||||
d.u.farr->arr.push_back(channel->_currentPoint.y);
|
||||
{
|
||||
Common::Point position = channel->getPosition();
|
||||
d.type = POINT;
|
||||
d.u.farr = new FArray;
|
||||
d.u.farr->arr.push_back(position.x);
|
||||
d.u.farr->arr.push_back(position.y);
|
||||
}
|
||||
break;
|
||||
case kTheLocH:
|
||||
d = channel->_currentPoint.x;
|
||||
d = channel->getPosition().x;
|
||||
break;
|
||||
case kTheLocV:
|
||||
d = channel->_currentPoint.y;
|
||||
d = channel->getPosition().y;
|
||||
break;
|
||||
case kTheMoveableSprite:
|
||||
d = sprite->_moveable;
|
||||
@ -1376,12 +1379,15 @@ Datum Lingo::getTheSprite(Datum &id1, int field) {
|
||||
break;
|
||||
case kTheRect:
|
||||
// let compiler to optimize this
|
||||
d.type = RECT;
|
||||
d.u.farr = new FArray;
|
||||
d.u.farr->arr.push_back(channel->getBbox().left);
|
||||
d.u.farr->arr.push_back(channel->getBbox().top);
|
||||
d.u.farr->arr.push_back(channel->getBbox().right);
|
||||
d.u.farr->arr.push_back(channel->getBbox().bottom);
|
||||
{
|
||||
Common::Rect bbox = channel->getBbox();
|
||||
d.type = RECT;
|
||||
d.u.farr = new FArray;
|
||||
d.u.farr->arr.push_back(bbox.left);
|
||||
d.u.farr->arr.push_back(bbox.top);
|
||||
d.u.farr->arr.push_back(bbox.right);
|
||||
d.u.farr->arr.push_back(bbox.bottom);
|
||||
}
|
||||
break;
|
||||
case kTheRight:
|
||||
d = channel->getBbox().right;
|
||||
@ -1419,7 +1425,7 @@ Datum Lingo::getTheSprite(Datum &id1, int field) {
|
||||
d = sprite->_volume;
|
||||
break;
|
||||
case kTheWidth:
|
||||
d = channel->_width;
|
||||
d = channel->getWidth();
|
||||
break;
|
||||
default:
|
||||
warning("Lingo::getTheSprite(): Unprocessed getting field \"%s\" of sprite", field2str(field));
|
||||
@ -1549,7 +1555,7 @@ void Lingo::setTheSprite(Datum &id1, int field, Datum &d) {
|
||||
}
|
||||
break;
|
||||
case kTheHeight:
|
||||
if (d.asInt() != channel->_height) {
|
||||
if (d.asInt() != channel->getHeight()) {
|
||||
g_director->getCurrentWindow()->addDirtyRect(channel->getBbox());
|
||||
channel->setHeight(d.asInt());
|
||||
channel->_dirty = true;
|
||||
@ -1579,21 +1585,21 @@ void Lingo::setTheSprite(Datum &id1, int field, Datum &d) {
|
||||
}
|
||||
break;
|
||||
case kTheLoc:
|
||||
if (channel->_currentPoint.x != d.asPoint().x || channel->_currentPoint.y != d.asPoint().y) {
|
||||
if (channel->getPosition() != d.asPoint()) {
|
||||
movie->getWindow()->addDirtyRect(channel->getBbox());
|
||||
channel->_dirty = true;
|
||||
}
|
||||
channel->setPosition(d.asPoint().x, d.asPoint().y);
|
||||
break;
|
||||
case kTheLocH:
|
||||
if (d.asInt() != channel->_currentPoint.x) {
|
||||
if (d.asInt() != channel->getPosition().x) {
|
||||
// adding the dirtyRect only when the trails is false. Other changes which will add dirtyRect may also apply this patch
|
||||
// this is for fixing the bug in jman-win. Currently, i've only patched the LocH, LocV and castNum since those are the only ones used in jman
|
||||
if (!channel->_sprite->_trails) {
|
||||
movie->getWindow()->addDirtyRect(channel->getBbox());
|
||||
channel->_dirty = true;
|
||||
}
|
||||
channel->setPosition(d.asInt(), channel->_currentPoint.y);
|
||||
channel->setPosition(d.asInt(), channel->getPosition().y);
|
||||
}
|
||||
|
||||
// Based on Director in a Nutshell, page 15
|
||||
@ -1601,12 +1607,12 @@ void Lingo::setTheSprite(Datum &id1, int field, Datum &d) {
|
||||
|
||||
break;
|
||||
case kTheLocV:
|
||||
if (d.asInt() != channel->_currentPoint.y) {
|
||||
if (d.asInt() != channel->getPosition().y) {
|
||||
if (!channel->_sprite->_trails) {
|
||||
movie->getWindow()->addDirtyRect(channel->getBbox());
|
||||
channel->_dirty = true;
|
||||
}
|
||||
channel->setPosition(channel->_currentPoint.x, d.asInt());
|
||||
channel->setPosition(channel->getPosition().x, d.asInt());
|
||||
}
|
||||
|
||||
// Based on Director in a Nutshell, page 15
|
||||
@ -1676,15 +1682,7 @@ void Lingo::setTheSprite(Datum &id1, int field, Datum &d) {
|
||||
warning("Setting stopTime for non-digital video");
|
||||
break;
|
||||
case kTheStretch:
|
||||
if ((d.asInt() != 0) != sprite->_stretch) {
|
||||
g_director->getCurrentWindow()->addDirtyRect(channel->getBbox());
|
||||
|
||||
sprite->_stretch = (d.asInt() != 0);
|
||||
channel->_dirty = true;
|
||||
|
||||
channel->_width = sprite->_width;
|
||||
channel->_height = sprite->_height;
|
||||
}
|
||||
channel->setStretch(d.asInt() != 0);
|
||||
break;
|
||||
case kTheTrails:
|
||||
sprite->_trails = (d.asInt() ? true : false);
|
||||
@ -1707,7 +1705,7 @@ void Lingo::setTheSprite(Datum &id1, int field, Datum &d) {
|
||||
sprite->_volume = d.asInt();
|
||||
break;
|
||||
case kTheWidth:
|
||||
if (d.asInt() != channel->_width) {
|
||||
if (d.asInt() != channel->getWidth()) {
|
||||
g_director->getCurrentWindow()->addDirtyRect(channel->getBbox());
|
||||
channel->setWidth(d.asInt());
|
||||
channel->_dirty = true;
|
||||
|
@ -1855,11 +1855,12 @@ Common::String Score::formatChannelInfo() {
|
||||
for (int i = 0; i < frame._numChannels; i++) {
|
||||
Channel &channel = *_channels[i + 1];
|
||||
Sprite &sprite = *channel._sprite;
|
||||
Common::Point position = channel.getPosition();
|
||||
if (sprite._castId.member) {
|
||||
result += Common::String::format("CH: %-3d castId: %s, visible: %d, [inkData: 0x%02x [ink: %d, trails: %d, stretch: %d, line: %d], %dx%d@%d,%d type: %d (%s) fg: %d bg: %d], script: %s, colorcode: 0x%x, blendAmount: 0x%x, unk3: 0x%x, constraint: %d, puppet: %d, moveable: %d, movieRate: %f, movieTime: %d (%f)\n",
|
||||
i + 1, sprite._castId.asString().c_str(), channel._visible, sprite._inkData,
|
||||
sprite._ink, sprite._trails, sprite._stretch, sprite._thickness, channel._width, channel._height,
|
||||
channel._currentPoint.x, channel._currentPoint.y,
|
||||
sprite._ink, sprite._trails, sprite._stretch, sprite._thickness,
|
||||
channel.getWidth(), channel.getHeight(), position.x, position.y,
|
||||
sprite._spriteType, spriteType2str(sprite._spriteType), sprite._foreColor, sprite._backColor,
|
||||
sprite._scriptId.asString().c_str(), sprite._colorcode, sprite._blendAmount, sprite._unk3,
|
||||
channel._constraint, sprite._puppet, sprite._moveable, channel._movieRate, channel._movieTime, (float)(channel._movieTime/60.0f));
|
||||
|
@ -407,6 +407,65 @@ bool Sprite::getAutoPuppet(AutoPuppetProperty property) {
|
||||
return (_autoPuppet & (1 << property)) != 0;
|
||||
}
|
||||
|
||||
void Sprite::setWidth(int w) {
|
||||
_width = MAX<int>(w, 0);
|
||||
|
||||
// Based on Director in a Nutshell, page 15
|
||||
setAutoPuppet(kAPWidth, true);
|
||||
}
|
||||
|
||||
void Sprite::setHeight(int h) {
|
||||
_height = MAX<int>(h, 0);
|
||||
|
||||
// Based on Director in a Nutshell, page 15
|
||||
setAutoPuppet(kAPHeight, true);
|
||||
}
|
||||
|
||||
Common::Rect Sprite::getBbox(bool unstretched) {
|
||||
Common::Rect result(_width, _height);
|
||||
// If this is a cast member, use the cast member's getBbox function
|
||||
// so we start with a rect containing the correct registration offset.
|
||||
if (_cast)
|
||||
result = _cast->getBbox(_width, _height);
|
||||
|
||||
// The origin of the rect should be at the registration offset,
|
||||
// e.g. for bitmap sprites this defaults to the centre.
|
||||
// Now we move the rect to the correct spot.
|
||||
Common::Point startPos = _startPoint;
|
||||
result.translate(startPos.x, startPos.y);
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
void Sprite::setBbox(int l, int t, int r, int b) {
|
||||
_width = r - l;
|
||||
_height = b - t;
|
||||
|
||||
Common::Rect source(_width, _height);
|
||||
if (_cast) {
|
||||
source = _cast->getBbox(_width, _height);
|
||||
}
|
||||
_startPoint.x = (int16)(l - source.left);
|
||||
_startPoint.y = (int16)(t - source.top);
|
||||
|
||||
if (_width <= 0 || _height <= 0)
|
||||
_width = _height = 0;
|
||||
|
||||
// Based on Director in a Nutshell, page 15
|
||||
setAutoPuppet(kAPBbox, true);
|
||||
}
|
||||
|
||||
Common::Point Sprite::getPosition() {
|
||||
return _startPoint;
|
||||
}
|
||||
|
||||
void Sprite::setPosition(int x, int y) {
|
||||
_startPoint = Common::Point(x, y);
|
||||
|
||||
// Based on Director in a Nutshell, page 15
|
||||
setAutoPuppet(kAPLoc, true);
|
||||
}
|
||||
|
||||
bool Sprite::checkSpriteType() {
|
||||
// check whether the sprite type match the cast type
|
||||
// if it doesn't match, then we treat it as transparent
|
||||
|
@ -83,6 +83,17 @@ public:
|
||||
void setAutoPuppet(AutoPuppetProperty property, bool value);
|
||||
bool getAutoPuppet(AutoPuppetProperty property);
|
||||
|
||||
inline int getWidth() { return _width; }
|
||||
void setWidth(int w);
|
||||
inline int getHeight() { return _height; }
|
||||
void setHeight(int h);
|
||||
|
||||
Common::Rect getBbox(bool unstretched);
|
||||
void setBbox(int l, int t, int r, int b);
|
||||
|
||||
Common::Point getPosition();
|
||||
void setPosition(int x, int y);
|
||||
|
||||
Frame *_frame;
|
||||
Score *_score;
|
||||
Movie *_movie;
|
||||
|
Loading…
Reference in New Issue
Block a user