From e208bc49e8f8d2baf214b0c5b92467f6fdc28c85 Mon Sep 17 00:00:00 2001 From: Jonas Kulla Date: Sat, 16 Aug 2014 13:50:57 +0200 Subject: [PATCH] Sprite: Implement Y based Z draw ordering (RGSS2) If two sprites have the same Z, their order is decided based on their Y coordinate first, and only then (if equal) by creation time. --- src/scene.cpp | 32 +++++++++++++++++++++++++++----- src/scene.h | 7 ++++++- src/sprite.cpp | 4 +++- src/viewport.cpp | 4 ++-- src/viewport.h | 2 +- 5 files changed, 39 insertions(+), 10 deletions(-) diff --git a/src/scene.cpp b/src/scene.cpp index 55e5232..a9836af 100644 --- a/src/scene.cpp +++ b/src/scene.cpp @@ -105,12 +105,14 @@ void Scene::composite() } -SceneElement::SceneElement(Scene &scene, int z) +SceneElement::SceneElement(Scene &scene, int z, bool isSprite) : link(this), creationStamp(shState->genTimeStamp()), z(z), visible(true), - scene(&scene) + scene(&scene), + spriteY(0), + isSprite(isSprite) { scene.insert(*this); } @@ -120,7 +122,9 @@ SceneElement::SceneElement(Scene &scene, int z, unsigned int cStamp) creationStamp(cStamp), z(z), visible(true), - scene(&scene) + scene(&scene), + spriteY(0), + isSprite(false) { scene.insert(*this); } @@ -167,11 +171,23 @@ void SceneElement::setVisible(bool value) bool SceneElement::operator<(const SceneElement &o) const { + /* Element draw order is decided by their Z value. + * If two Z values are equal, the later created object + * has priority */ + if (z <= o.z) { if (z == o.z) - if (creationStamp > o.creationStamp) - return false; + { +#ifdef RGSS2 + /* RGSS2: If two sprites' Z values collide, + * their Y coordinates decide draw order. Only + * on equal Y does the creation time take effect */ + if (isSprite && o.isSprite && spriteY != o.spriteY) + return (spriteY < o.spriteY); +#endif + return (creationStamp <= o.creationStamp); + } return true; } @@ -179,6 +195,12 @@ bool SceneElement::operator<(const SceneElement &o) const return false; } +void SceneElement::setSpriteY(int value) +{ + spriteY = value; + scene->reinsert(*this); +} + void SceneElement::unlink() { if (scene) diff --git a/src/scene.h b/src/scene.h index a0e23e3..399ec6c 100644 --- a/src/scene.h +++ b/src/scene.h @@ -71,7 +71,7 @@ protected: class SceneElement { public: - SceneElement(Scene &scene, int z = 0); + SceneElement(Scene &scene, int z = 0, bool isSprite = false); SceneElement(Scene &scene, int z, unsigned int cStamp); virtual ~SceneElement(); @@ -108,6 +108,7 @@ protected: * elements with lower priority are drawn earlier */ bool operator<(const SceneElement &o) const; + void setSpriteY(int value); void unlink(); IntruListLink link; @@ -119,6 +120,10 @@ protected: friend class Scene; friend class Viewport; friend struct TilemapPrivate; + +private: + int spriteY; + const bool isSprite; }; #endif // SCENE_H diff --git a/src/sprite.cpp b/src/sprite.cpp index d68a823..9aa99ca 100644 --- a/src/sprite.cpp +++ b/src/sprite.cpp @@ -302,7 +302,7 @@ struct SpritePrivate }; Sprite::Sprite(Viewport *viewport) - : ViewportElement(viewport) + : ViewportElement(viewport, 0, true) { p = new SpritePrivate; onGeometryChange(scene->getGeometry()); @@ -393,6 +393,8 @@ void Sprite::setY(int value) #ifdef RGSS2 p->wave.dirty = true; + + setSpriteY(value); #endif } diff --git a/src/viewport.cpp b/src/viewport.cpp index f0395b2..a579507 100644 --- a/src/viewport.cpp +++ b/src/viewport.cpp @@ -218,8 +218,8 @@ void Viewport::onGeometryChange(const Geometry &geo) } -ViewportElement::ViewportElement(Viewport *viewport, int z) - : SceneElement(viewport ? *viewport : *shState->screen(), z), +ViewportElement::ViewportElement(Viewport *viewport, int z, bool isSprite) + : SceneElement(viewport ? *viewport : *shState->screen(), z, isSprite), m_viewport(viewport) {} diff --git a/src/viewport.h b/src/viewport.h index 6fea1b3..45c8965 100644 --- a/src/viewport.h +++ b/src/viewport.h @@ -65,7 +65,7 @@ private: class ViewportElement : public SceneElement { public: - ViewportElement(Viewport *viewport = 0, int z = 0); + ViewportElement(Viewport *viewport = 0, int z = 0, bool isSprite = false); ViewportElement(Viewport *viewport, int z, unsigned int cStamp); Viewport *getViewport() const;