aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
Diffstat (limited to 'engines')
-rw-r--r--engines/draci/animation.cpp101
-rw-r--r--engines/draci/animation.h9
-rw-r--r--engines/draci/script.cpp4
-rw-r--r--engines/draci/sprite.cpp48
-rw-r--r--engines/draci/sprite.h28
5 files changed, 64 insertions, 126 deletions
diff --git a/engines/draci/animation.cpp b/engines/draci/animation.cpp
index e3f87feb8b..cae4897329 100644
--- a/engines/draci/animation.cpp
+++ b/engines/draci/animation.cpp
@@ -33,10 +33,7 @@ Animation::Animation(DraciEngine *vm, int index) : _vm(vm) {
_id = kUnused;
_index = index;
_z = 0;
- _relX = 0;
- _relY = 0;
- _scaleX = 1.0;
- _scaleY = 1.0;
+ _displacement = kNoDisplacement;
_playing = false;
_looping = false;
_paused = false;
@@ -59,8 +56,8 @@ void Animation::setRelative(int relx, int rely) {
if (_frames.size() > 0)
markDirtyRect(_vm->_screen->getSurface());
- _relX = relx;
- _relY = rely;
+ _displacement.relX = relx;
+ _displacement.relY = rely;
}
void Animation::setLooping(bool looping) {
@@ -72,14 +69,7 @@ void Animation::setLooping(bool looping) {
void Animation::markDirtyRect(Surface *surface) const {
// Fetch the current frame's rectangle
Drawable *frame = _frames[_currentFrame];
- Common::Rect frameRect = frame->getRect();
-
- // Translate rectangle to compensate for relative coordinates
- frameRect.translate(_relX, _relY);
-
- // Take animation scaling into account
- frameRect.setWidth((int) (frameRect.width() * _scaleX));
- frameRect.setHeight((int) (frameRect.height() * _scaleY));
+ Common::Rect frameRect = frame->getRect(_displacement);
// Mark the rectangle dirty on the surface
surface->markDirtyRect(frameRect);
@@ -135,42 +125,13 @@ void Animation::drawFrame(Surface *surface) {
if (_frames.size() == 0 || !_playing)
return;
- Drawable *frame = _frames[_currentFrame];
+ const Drawable *frame = _frames[_currentFrame];
if (_id == kOverlayImage) {
frame->draw(surface, false);
} else {
-
- int x = frame->getX();
- int y = frame->getY();
-
- // Take account relative coordinates
- int newX = x + _relX;
- int newY = y + _relY;
-
- // Translate the frame to those relative coordinates
- frame->setX(newX);
- frame->setY(newY);
-
- // Save scaled width and height
- int scaledWidth = frame->getScaledWidth();
- int scaledHeight = frame->getScaledHeight();
-
- // Take into account per-animation scaling and adjust the current frames dimensions
- if (_scaleX != 1.0 || _scaleY != 1.0)
- frame->setScaled(
- (int) (scaledWidth * _scaleX),
- (int) (scaledHeight * _scaleY));
-
// Draw frame
- frame->drawScaled(surface, false);
-
- // Revert back to old coordinates
- frame->setX(x);
- frame->setY(y);
-
- // Revert back to old dimensions
- frame->setScaled(scaledWidth, scaledHeight);
+ frame->drawReScaled(surface, false, _displacement);
}
}
@@ -191,11 +152,11 @@ uint Animation::getZ() const {
}
int Animation::getRelativeX() const {
- return _relX;
+ return _displacement.relX;
}
int Animation::getRelativeY() const {
- return _relY;
+ return _displacement.relY;
}
bool Animation::isPlaying() const {
@@ -223,16 +184,16 @@ void Animation::setScaleFactors(double scaleX, double scaleY) {
markDirtyRect(_vm->_screen->getSurface());
- _scaleX = scaleX;
- _scaleY = scaleY;
+ _displacement.extraScaleX = scaleX;
+ _displacement.extraScaleY = scaleY;
}
double Animation::getScaleX() const {
- return _scaleX;
+ return _displacement.extraScaleX;
}
double Animation::getScaleY() const {
- return _scaleY;
+ return _displacement.extraScaleY;
}
void Animation::addFrame(Drawable *frame) {
@@ -574,9 +535,9 @@ void AnimationManager::deleteAfterIndex(int index) {
_lastIndex = index;
}
-int AnimationManager::getTopAnimationID(int x, int y) {
+int AnimationManager::getTopAnimationID(int x, int y) const {
- Common::List<Animation *>::iterator it;
+ Common::List<Animation *>::const_iterator it;
// The default return value if no animations were found on these coordinates (not even overlays)
// i.e. the black background shows through so treat it as an overlay
@@ -594,53 +555,25 @@ int AnimationManager::getTopAnimationID(int x, int y) {
continue;
}
- Drawable *frame = anim->getFrame();
+ const Drawable *frame = anim->getFrame();
if (frame == NULL) {
continue;
}
- int oldX = frame->getX();
- int oldY = frame->getY();
-
- // Take account relative coordinates
- int newX = oldX + anim->getRelativeX();
- int newY = oldY + anim->getRelativeY();
-
- // Translate the frame to those relative coordinates
- frame->setX(newX);
- frame->setY(newY);
-
- // Save scaled width and height
- int scaledWidth = frame->getScaledWidth();
- int scaledHeight = frame->getScaledHeight();
-
- // Take into account per-animation scaling and adjust the current frames dimensions
- if (anim->getScaleX() != 1.0 || anim->getScaleY() != 1.0)
- frame->setScaled(
- (int) (scaledWidth * anim->getScaleX()),
- (int) (scaledHeight * anim->getScaleY()));
-
- if (frame->getRect().contains(x, y)) {
+ if (frame->getRect(anim->getDisplacement()).contains(x, y)) {
if (frame->getType() == kDrawableText) {
retval = anim->getID();
} else if (frame->getType() == kDrawableSprite &&
- reinterpret_cast<Sprite *>(frame)->getPixel(x, y) != transparent) {
+ reinterpret_cast<const Sprite *>(frame)->getPixel(x, y, anim->getDisplacement()) != transparent) {
retval = anim->getID();
}
}
- // Revert back to old coordinates
- frame->setX(oldX);
- frame->setY(oldY);
-
- // Revert back to old dimensions
- frame->setScaled(scaledWidth, scaledHeight);
-
// Found an animation
if (retval != kOverlayImage)
break;
diff --git a/engines/draci/animation.h b/engines/draci/animation.h
index 2358775d8d..24ee5368c1 100644
--- a/engines/draci/animation.h
+++ b/engines/draci/animation.h
@@ -92,6 +92,7 @@ public:
void setRelative(int relx, int rely);
int getRelativeX() const;
int getRelativeY() const;
+ const Displacement &getDisplacement() const { return _displacement; }
int getIndex() const;
void setIndex(int index);
@@ -128,11 +129,7 @@ private:
uint _currentFrame;
uint _z;
- int _relX;
- int _relY;
-
- double _scaleX;
- double _scaleY;
+ Displacement _displacement;
uint _tick;
bool _playing;
@@ -176,7 +173,7 @@ public:
int getLastIndex() const;
void deleteAfterIndex(int index);
- int getTopAnimationID(int x, int y);
+ int getTopAnimationID(int x, int y) const;
private:
void sortAnimations();
diff --git a/engines/draci/script.cpp b/engines/draci/script.cpp
index 3622f2d028..8a256f4fcc 100644
--- a/engines/draci/script.cpp
+++ b/engines/draci/script.cpp
@@ -676,7 +676,7 @@ void Script::talk(Common::Queue<int> &params) {
const Person *person = _vm->_game->getPerson(personID);
// Set the string and text colour
- surface->markDirtyRect(speechFrame->getRect(true));
+ surface->markDirtyRect(speechFrame->getRect());
speechFrame->setText(Common::String((const char *)f->_data+1, f->_length-1));
speechFrame->setColour(person->_fontColour);
@@ -712,7 +712,7 @@ void Script::talk(Common::Queue<int> &params) {
_vm->_game->loop();
// Delete the text
- _vm->_screen->getSurface()->markDirtyRect(speechFrame->getRect(true));
+ _vm->_screen->getSurface()->markDirtyRect(speechFrame->getRect());
speechFrame->setText("");
// Revert to "normal" loop status
diff --git a/engines/draci/sprite.cpp b/engines/draci/sprite.cpp
index 2028f7ab4b..1e3e749e1e 100644
--- a/engines/draci/sprite.cpp
+++ b/engines/draci/sprite.cpp
@@ -33,6 +33,8 @@
namespace Draci {
+const Displacement kNoDisplacement = { 0, 0, 1.0, 1.0 };
+
/**
* @brief Transforms an image from column-wise to row-wise
* @param img pointer to the buffer containing the image data
@@ -129,19 +131,19 @@ void Sprite::setMirrorOff() {
}
-int Sprite::getPixel(int x, int y) const {
+int Sprite::getPixel(int x, int y, const Displacement &displacement) const {
- Common::Rect rect = getRect();
+ Common::Rect rect = getRect(displacement);
int dy = y - rect.top;
int dx = x - rect.left;
// Calculate scaling factors
- double scaleX = double(_scaledWidth) / _width;
- double scaleY = double(_scaledHeight) / _height;
+ double scaleX = double(rect.width()) / _width;
+ double scaleY = double(rect.height()) / _height;
- int sy = scummvm_lround(dy * scaleY);
- int sx = scummvm_lround(dx * scaleX);
+ int sy = scummvm_lround(dy / scaleY);
+ int sx = scummvm_lround(dx / scaleX);
if (_mirror)
return _data[sy * _width + (_width - sx)];
@@ -150,10 +152,15 @@ int Sprite::getPixel(int x, int y) const {
}
-void Sprite::drawScaled(Surface *surface, bool markDirty) const {
+void Sprite::drawReScaled(Surface *surface, bool markDirty, const Displacement &displacement) const {
Common::Rect sourceRect(0, 0, _width, _height);
- Common::Rect destRect(_x, _y, _x + _scaledWidth, _y + _scaledHeight);
+ Common::Rect destRect(getRect(displacement));
+
+ // Calculate scaling factors
+ double scaleX = double(destRect.width()) / _width;
+ double scaleY = double(destRect.height()) / _height;
+
Common::Rect surfaceRect(0, 0, surface->w, surface->h);
Common::Rect clippedDestRect(destRect);
@@ -184,10 +191,6 @@ void Sprite::drawScaled(Surface *surface, bool markDirty) const {
int *rowIndices = new int[rows];
int *columnIndices = new int[columns];
- // Calculate scaling factors
- double scaleX = double(_scaledWidth) / _width;
- double scaleY = double(_scaledHeight) / _height;
-
// Precalculate pixel indexes
for (int i = 0; i < rows; ++i) {
rowIndices[i] = scummvm_lround(i / scaleY);
@@ -241,10 +244,10 @@ void Sprite::drawScaled(Surface *surface, bool markDirty) const {
* Draws the sprite to a Draci::Surface and marks its rectangle on the surface as dirty.
* It is safe to call it for sprites that would overflow the surface.
*/
-void Sprite::draw(Surface *surface, bool markDirty) const {
+void Sprite::draw(Surface *surface, bool markDirty, int relX, int relY) const {
Common::Rect sourceRect(0, 0, _width, _height);
- Common::Rect destRect(_x, _y, _x + _width, _y + _height);
+ Common::Rect destRect(_x + relX, _y + relY, _x + relX + _width, _y + relY + _height);
Common::Rect surfaceRect(0, 0, surface->w, surface->h);
Common::Rect clippedDestRect(destRect);
@@ -295,11 +298,10 @@ void Sprite::draw(Surface *surface, bool markDirty) const {
}
-Common::Rect Sprite::getRect(bool scaled) const {
- if (scaled)
- return Common::Rect(_x, _y, _x + _scaledWidth, _y + _scaledHeight);
- else
- return Common::Rect(_x, _y, _x + _width, _y + _height);
+Common::Rect Sprite::getRect(const Displacement &displacement) const {
+ return Common::Rect(_x + displacement.relX, _y + displacement.relY,
+ _x + displacement.relX + (int) (_scaledWidth * displacement.extraScaleX),
+ _y + displacement.relY + (int) (_scaledHeight * displacement.extraScaleY));
}
Text::Text(const Common::String &str, const Font *font, byte fontColour,
@@ -356,13 +358,13 @@ uint Text::getLength() const {
return _length;
}
-void Text::draw(Surface *surface, bool markDirty) const {
- _font->drawString(surface, _text, _x, _y, _colour, _spacing);
+void Text::draw(Surface *surface, bool markDirty, int relX, int relY) const {
+ _font->drawString(surface, _text, _x + relX, _y + relY, _colour, _spacing);
}
// TODO: Handle scaled parameter properly by implementing Text scaling
-Common::Rect Text::getRect(bool scaled) const {
- return Common::Rect(_x, _y, _x + _width, _y + _height);
+Common::Rect Text::getRect(const Displacement &displacement) const {
+ return Common::Rect(_x + displacement.relX, _y + displacement.relY, _x + displacement.relX + _width, _y + displacement.relY + _height);
}
void Text::setFont(const Font *font) {
diff --git a/engines/draci/sprite.h b/engines/draci/sprite.h
index 0488043c7e..ce2d516437 100644
--- a/engines/draci/sprite.h
+++ b/engines/draci/sprite.h
@@ -33,11 +33,17 @@ namespace Draci {
enum DrawableType { kDrawableText, kDrawableSprite };
+struct Displacement {
+ int relX, relY;
+ double extraScaleX, extraScaleY;
+};
+extern const Displacement kNoDisplacement;
+
class Drawable {
public:
- virtual void draw(Surface *surface, bool markDirty = true) const = 0;
- virtual void drawScaled(Surface *surface, bool markDirty = true) const = 0;
+ virtual void draw(Surface *surface, bool markDirty, int relX=0, int relY=0) const = 0;
+ virtual void drawReScaled(Surface *surface, bool markDirty, const Displacement &displacement = kNoDisplacement) const = 0;
virtual ~Drawable() {};
@@ -61,7 +67,7 @@ public:
void setDelay(int delay) { _delay = delay; }
int getDelay() const { return _delay; }
- virtual Common::Rect getRect(bool scaled = true) const = 0;
+ virtual Common::Rect getRect(const Displacement &displacement = kNoDisplacement) const = 0;
virtual DrawableType getType() const = 0;
@@ -100,16 +106,16 @@ public:
~Sprite();
- void draw(Surface *surface, bool markDirty = true) const;
- void drawScaled(Surface *surface, bool markDirty = true) const;
+ void draw(Surface *surface, bool markDirty, int relX=0, int relY=0) const;
+ void drawReScaled(Surface *surface, bool markDirty, const Displacement &displacement = kNoDisplacement) const;
void setMirrorOn();
void setMirrorOff();
- Common::Rect getRect(bool scaled = true) const;
+ Common::Rect getRect(const Displacement &displacement = kNoDisplacement) const;
const byte *getBuffer() const { return _data; }
- int getPixel(int x, int y) const;
+ int getPixel(int x, int y, const Displacement &displacement = kNoDisplacement) const;
DrawableType getType() const { return kDrawableSprite; }
@@ -132,13 +138,13 @@ public:
uint getLength() const;
- void draw(Surface *surface, bool markDirty = true) const;
+ void draw(Surface *surface, bool markDirty, int relX=0, int relY=0) const;
- // TODO: drawScaled just calls draw so Text can be accessed through a Drawable pointer.
+ // TODO: drawReScaled just calls draw so Text can be accessed through a Drawable pointer.
// Handle scaling text sometimes (not essential).
- void drawScaled(Surface *surface, bool markDirty = true) const { draw(surface, markDirty); }
- Common::Rect getRect(bool) const;
+ void drawReScaled(Surface *surface, bool markDirty, const Displacement &displacement = kNoDisplacement) const { draw(surface, markDirty, displacement.relX, displacement.relY); }
+ Common::Rect getRect(const Displacement &displacement = kNoDisplacement) const;
DrawableType getType() const { return kDrawableText; }