[Scummvm-git-logs] scummvm master -> d3c7c3cbc830d5b8ba287c67f17d25f52d287bb1
moralrecordings
code at moral.net.au
Sat May 23 13:34:39 UTC 2020
This automated email contains information about 3 new commits which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .
Summary:
14d5b982d5 DIRECTOR: LINGO: Buffer events when calling b_updateStage
7be0816f3f DIRECTOR: Move sprite bounding box calculation into class method
d3c7c3cbc8 DIRECTOR: Simplify dirty sprite check
Commit: 14d5b982d5ac9bd6a9dfc1c13982a2947da4ec61
https://github.com/scummvm/scummvm/commit/14d5b982d5ac9bd6a9dfc1c13982a2947da4ec61
Author: Scott Percival (code at moral.net.au)
Date: 2020-05-23T21:33:50+08:00
Commit Message:
DIRECTOR: LINGO: Buffer events when calling b_updateStage
Changed paths:
engines/director/lingo/lingo-builtins.cpp
diff --git a/engines/director/lingo/lingo-builtins.cpp b/engines/director/lingo/lingo-builtins.cpp
index 2d7944e04c..e72924e119 100644
--- a/engines/director/lingo/lingo-builtins.cpp
+++ b/engines/director/lingo/lingo-builtins.cpp
@@ -1817,8 +1817,8 @@ void LB::b_updateStage(int nargs) {
return;
}
- score->renderFrame( score->getCurrentFrame(), false, true);
- processQuitEvent();
+ score->renderFrame(score->getCurrentFrame(), false, true);
+ g_director->processEvents(true);
if (debugChannelSet(-1, kDebugFewFramesOnly))
score->_framesRan++;
Commit: 7be0816f3fc7d5d98c84650c35c9821c14d2b35d
https://github.com/scummvm/scummvm/commit/7be0816f3fc7d5d98c84650c35c9821c14d2b35d
Author: Scott Percival (code at moral.net.au)
Date: 2020-05-23T21:33:51+08:00
Commit Message:
DIRECTOR: Move sprite bounding box calculation into class method
Changed paths:
engines/director/score.cpp
engines/director/sprite.cpp
engines/director/sprite.h
diff --git a/engines/director/score.cpp b/engines/director/score.cpp
index 632d8d80bd..7eb3a2f362 100644
--- a/engines/director/score.cpp
+++ b/engines/director/score.cpp
@@ -773,122 +773,7 @@ void Score::setSpriteBboxes() {
for (uint16 i = 0; i < _frames.size(); i++) {
for (uint16 j = 0; j < _frames[i]->_sprites.size(); j++) {
Sprite *sp = _frames[i]->_sprites[j];
-
- if (sp->_castId == 0)
- continue;
-
- CastType castType = sp->_castType;
-
- switch (castType) {
- case kCastShape:
- sp->_startBbox = Common::Rect(sp->_currentPoint.x,
- sp->_currentPoint.y,
- sp->_currentPoint.x + sp->_width,
- sp->_currentPoint.y + sp->_height);
- break;
- case kCastRTE:
- case kCastText: {
- TextCast *textCast = (TextCast*)sp->_cast;
- int x = sp->_currentPoint.x; // +rectLeft;
- int y = sp->_currentPoint.y; // +rectTop;
- int height = textCast->_initialRect.height(); //_sprites[spriteId]->_height;
- int width;
- Common::Rect *textRect = NULL;
-
- if (_vm->getVersion() >= 4) {
- // where does textRect come from?
- if (textRect == NULL) {
- width = textCast->_initialRect.right;
- } else {
- width = textRect->width();
- }
- } else {
- width = textCast->_initialRect.width(); //_sprites[spriteId]->_width;
- }
-
- sp->_startBbox = Common::Rect(x, y, x + width, y + height);
- break;
- }
- case kCastButton: {
- uint16 castId = sp->_castId;
-
- // This may not be a button cast. It could be a textcast with the
- // channel forcing it to be a checkbox or radio button!
- ButtonCast *button = (ButtonCast *)_vm->getCurrentScore()->_loadedCast->getVal(castId);
-
- // Sometimes, at least in the D3 Workshop Examples, these buttons are
- // just TextCast. If they are, then we just want to use the spriteType
- // as the button type. If they are full-bown Cast members, then use the
- // actual cast member type.
- int buttonType = sp->_spriteType;
- if (buttonType == kCastMemberSprite) {
- switch (button->_buttonType) {
- case kTypeCheckBox:
- buttonType = kCheckboxSprite;
- break;
- case kTypeButton:
- buttonType = kButtonSprite;
- break;
- case kTypeRadio:
- buttonType = kRadioButtonSprite;
- break;
- }
- }
-
- uint32 rectLeft = button->_initialRect.left;
- uint32 rectTop = button->_initialRect.top;
-
- int x = sp->_currentPoint.x;
- int y = sp->_currentPoint.y;
-
- if (_vm->getVersion() > 3) {
- x += rectLeft;
- y += rectTop;
- }
-
- int height = button->_initialRect.height();
- int width = button->_initialRect.width() + 3;
-
- switch (buttonType) {
- case kCheckboxSprite:
- // Magic numbers: checkbox square need to move left about 5px from
- // text and 12px side size (D4)
- sp->_startBbox = Common::Rect(x, y + 2, x + 12, y + 14);
- break;
- case kButtonSprite:
- sp->_startBbox = Common::Rect(x, y, x + width, y + height + 3);
- break;
- case kRadioButtonSprite:
- sp->_startBbox = Common::Rect(x, y + 2, x + 12, y + 14);
- break;
- default:
- warning("Score::setSpriteBboxes: Unknown buttonType");
- }
- break;
- }
- case kCastBitmap: {
- BitmapCast *bc = (BitmapCast *)sp->_cast;
-
- int32 regX = bc->_regX;
- int32 regY = bc->_regY;
- int32 rectLeft = bc->_initialRect.left;
- int32 rectTop = bc->_initialRect.top;
-
- int x = sp->_currentPoint.x - regX + rectLeft;
- int y = sp->_currentPoint.y - regY + rectTop;
- int height = sp->_height;
- int width = _vm->getVersion() > 4 ? bc->_initialRect.width() : sp->_width;
-
- // If one of the dimensions is invalid, invalidate whole thing
- if (width == 0 || height == 0)
- width = height = 0;
-
- sp->_startBbox = Common::Rect(x, y, x + width, y + height);
- break;
- }
- default:
- warning("Score::setSpriteBboxes(): Unhandled cast type: %d, frame %d, channel %d", castType, i, j);
- }
+ sp->_startBbox = sp->getBbox();
sp->_currentBbox = sp->_startBbox;
sp->_dirtyBbox = sp->_startBbox;
}
@@ -1848,6 +1733,10 @@ void Score::renderFrame(uint16 frameId, bool forceUpdate, bool updateStageOnly)
else
nextSprite = currentFrame->_sprites[i];
+ // A sprite needs to be updated if one of the following happens:
+ // - The dimensions/bounding box of the sprite has changed (_dirty flag set)
+ // - The cast member ID of the sprite has changed (_dirty flag set)
+ // - The sprite slot from the current frame is different (cast member ID or bounding box) from the cached sprite slot
bool needsUpdate = (currentSprite->_currentBbox != nextSprite->_currentBbox || currentSprite->_currentBbox != currentSprite->_dirtyBbox);
if (needsUpdate || forceUpdate)
diff --git a/engines/director/sprite.cpp b/engines/director/sprite.cpp
index 0f8b203f1e..2605d56b5f 100644
--- a/engines/director/sprite.cpp
+++ b/engines/director/sprite.cpp
@@ -45,6 +45,7 @@ Sprite::Sprite() {
_cast = nullptr;
_thickness = 0;
+ _dirty = false;
_width = 0;
_height = 0;
_constraint = 0;
@@ -167,6 +168,125 @@ void Sprite::setCast(uint16 castId) {
_castType = member->_type;
}
}
+ _dirty = true;
+}
+
+Common::Rect Sprite::getBbox() {
+ Common::Rect result;
+ if (_castId == 0) {
+ warning("Sprite::getBbox(): attempted to get bbox for null cast member");
+ return result;
+ }
+
+ switch (_castType) {
+ case kCastShape:
+ result = Common::Rect(_currentPoint.x,
+ _currentPoint.y,
+ _currentPoint.x + _width,
+ _currentPoint.y + _height);
+ break;
+ case kCastRTE:
+ case kCastText: {
+ TextCast *textCast = (TextCast*)_cast;
+ int x = _currentPoint.x; // +rectLeft;
+ int y = _currentPoint.y; // +rectTop;
+ int height = textCast->_initialRect.height(); //_sprites[spriteId]->_height;
+ int width;
+ Common::Rect *textRect = NULL;
+
+ if (g_director->getVersion() >= 4) {
+ // where does textRect come from?
+ if (textRect == NULL) {
+ width = textCast->_initialRect.right;
+ } else {
+ width = textRect->width();
+ }
+ } else {
+ width = textCast->_initialRect.width(); //_sprites[spriteId]->_width;
+ }
+
+ result = Common::Rect(x, y, x + width, y + height);
+ break;
+ }
+ case kCastButton: {
+ // This may not be a button cast. It could be a textcast with the
+ // channel forcing it to be a checkbox or radio button!
+ ButtonCast *button = (ButtonCast *)_cast;
+
+ // Sometimes, at least in the D3 Workshop Examples, these buttons are
+ // just TextCast. If they are, then we just want to use the spriteType
+ // as the button type. If they are full-bown Cast members, then use the
+ // actual cast member type.
+ int buttonType = _spriteType;
+ if (buttonType == kCastMemberSprite) {
+ switch (button->_buttonType) {
+ case kTypeCheckBox:
+ buttonType = kCheckboxSprite;
+ break;
+ case kTypeButton:
+ buttonType = kButtonSprite;
+ break;
+ case kTypeRadio:
+ buttonType = kRadioButtonSprite;
+ break;
+ }
+ }
+
+ uint32 rectLeft = button->_initialRect.left;
+ uint32 rectTop = button->_initialRect.top;
+
+ int x = _currentPoint.x;
+ int y = _currentPoint.y;
+
+ if (g_director->getVersion() > 3) {
+ x += rectLeft;
+ y += rectTop;
+ }
+
+ int height = button->_initialRect.height();
+ int width = button->_initialRect.width() + 3;
+
+ switch (buttonType) {
+ case kCheckboxSprite:
+ // Magic numbers: checkbox square need to move left about 5px from
+ // text and 12px side size (D4)
+ _startBbox = Common::Rect(x, y + 2, x + 12, y + 14);
+ break;
+ case kButtonSprite:
+ _startBbox = Common::Rect(x, y, x + width, y + height + 3);
+ break;
+ case kRadioButtonSprite:
+ _startBbox = Common::Rect(x, y + 2, x + 12, y + 14);
+ break;
+ default:
+ warning("Score::getBbox(): Unknown buttonType");
+ }
+ break;
+ }
+ case kCastBitmap: {
+ BitmapCast *bc = (BitmapCast *)_cast;
+
+ int32 regX = bc->_regX;
+ int32 regY = bc->_regY;
+ int32 rectLeft = bc->_initialRect.left;
+ int32 rectTop = bc->_initialRect.top;
+
+ int x = _currentPoint.x - regX + rectLeft;
+ int y = _currentPoint.y - regY + rectTop;
+ int height = _height;
+ int width = g_director->getVersion() > 4 ? bc->_initialRect.width() : _width;
+
+ // If one of the dimensions is invalid, invalidate whole thing
+ if (width == 0 || height == 0)
+ width = height = 0;
+
+ result = Common::Rect(x, y, x + width, y + height);
+ break;
+ }
+ default:
+ warning("Sprite::getBbox(): Unhandled cast type: %d", _castType);
+ }
+ return result;
}
diff --git a/engines/director/sprite.h b/engines/director/sprite.h
index 7a70feb7c4..f342e4a3d0 100644
--- a/engines/director/sprite.h
+++ b/engines/director/sprite.h
@@ -67,6 +67,8 @@ public:
void setCast(uint16 castid);
+ Common::Rect getBbox();
+
uint16 _scriptId;
uint16 _scriptCastIndex;
byte _colorcode; // x40 editable, 0x80 moveable
@@ -85,6 +87,7 @@ public:
Cast *_cast;
byte _thickness;
+ bool _dirty;
Common::Point _startPoint;
Common::Point _currentPoint;
Common::Rect _startBbox;
Commit: d3c7c3cbc830d5b8ba287c67f17d25f52d287bb1
https://github.com/scummvm/scummvm/commit/d3c7c3cbc830d5b8ba287c67f17d25f52d287bb1
Author: Scott Percival (code at moral.net.au)
Date: 2020-05-23T21:33:51+08:00
Commit Message:
DIRECTOR: Simplify dirty sprite check
Changed paths:
engines/director/events.cpp
engines/director/lingo/lingo-the.cpp
engines/director/score.cpp
engines/director/sprite.h
diff --git a/engines/director/events.cpp b/engines/director/events.cpp
index 6af7ef8ed4..836df726b6 100644
--- a/engines/director/events.cpp
+++ b/engines/director/events.cpp
@@ -87,7 +87,7 @@ void DirectorEngine::processEvents(bool bufferLingoEvents) {
Common::Point delta = pos - _draggingSpritePos;
draggedSprite->_currentPoint.x += delta.x;
draggedSprite->_currentPoint.y += delta.y;
- draggedSprite->_dirtyBbox.translate(delta.x, delta.y);
+ draggedSprite->_dirty = true;
_draggingSpritePos = pos;
} else {
releaseDraggedSprite();
diff --git a/engines/director/lingo/lingo-the.cpp b/engines/director/lingo/lingo-the.cpp
index 8e1d4008ec..18323bc9b6 100644
--- a/engines/director/lingo/lingo-the.cpp
+++ b/engines/director/lingo/lingo-the.cpp
@@ -717,7 +717,6 @@ void Lingo::setTheSprite(Datum &id1, int field, Datum &d) {
sprite->_moveable = d.asInt();
if (!d.u.i) {
sprite->_currentPoint = sprite->_startPoint;
- sprite->_dirtyBbox = sprite->_startBbox;
}
break;
case kTheMovieRate:
@@ -733,7 +732,6 @@ void Lingo::setTheSprite(Datum &id1, int field, Datum &d) {
sprite->_puppet = d.asInt();
if (!d.u.i) {
sprite->_currentPoint = sprite->_startPoint;
- sprite->_dirtyBbox = sprite->_startBbox;
}
break;
case kTheStartTime:
@@ -764,6 +762,7 @@ void Lingo::setTheSprite(Datum &id1, int field, Datum &d) {
default:
warning("Lingo::setTheSprite(): Unprocessed setting field \"%s\" of sprite", field2str(field));
}
+ sprite->_dirty = true;
}
Datum Lingo::getTheCast(Datum &id1, int field) {
diff --git a/engines/director/score.cpp b/engines/director/score.cpp
index 7eb3a2f362..f5d663b8e5 100644
--- a/engines/director/score.cpp
+++ b/engines/director/score.cpp
@@ -770,12 +770,12 @@ void Score::setSpriteCasts() {
}
void Score::setSpriteBboxes() {
+ // Initialise the sprite cache for all the initial bounding boxes
for (uint16 i = 0; i < _frames.size(); i++) {
for (uint16 j = 0; j < _frames[i]->_sprites.size(); j++) {
Sprite *sp = _frames[i]->_sprites[j];
sp->_startBbox = sp->getBbox();
sp->_currentBbox = sp->_startBbox;
- sp->_dirtyBbox = sp->_startBbox;
}
}
}
@@ -1737,7 +1737,8 @@ void Score::renderFrame(uint16 frameId, bool forceUpdate, bool updateStageOnly)
// - The dimensions/bounding box of the sprite has changed (_dirty flag set)
// - The cast member ID of the sprite has changed (_dirty flag set)
// - The sprite slot from the current frame is different (cast member ID or bounding box) from the cached sprite slot
- bool needsUpdate = (currentSprite->_currentBbox != nextSprite->_currentBbox || currentSprite->_currentBbox != currentSprite->_dirtyBbox);
+ // (maybe we have to compare all the sprite attributes, not just these two?)
+ bool needsUpdate = currentSprite->_dirty || currentSprite->_castId != nextSprite->_castId || currentSprite->_currentBbox != nextSprite->_currentBbox;
if (needsUpdate || forceUpdate)
unrenderSprite(i);
@@ -1776,7 +1777,8 @@ void Score::unrenderSprite(uint16 spriteId) {
_surface->fillRect(currentSprite->_currentBbox, _stageColor);
}
- currentSprite->_currentBbox = currentSprite->_dirtyBbox;
+ currentSprite->_currentBbox = currentSprite->getBbox();
+ currentSprite->_dirty = false;
}
void Score::renderSprite(uint16 id) {
diff --git a/engines/director/sprite.h b/engines/director/sprite.h
index f342e4a3d0..c0f11922d9 100644
--- a/engines/director/sprite.h
+++ b/engines/director/sprite.h
@@ -92,7 +92,6 @@ public:
Common::Point _currentPoint;
Common::Rect _startBbox;
Common::Rect _currentBbox;
- Common::Rect _dirtyBbox;
uint16 _width;
uint16 _height;
// TODO: default constraint = 0, if turned on, sprite is constrainted to the bounding rect
More information about the Scummvm-git-logs
mailing list