Replicate RMVX/VXA's broken sprite Z sorting implementation
Fixes Window_NameBox visual appearance in Skyborn. Also nuke the second SceneElement constructor that has been obsolete since the Tilemap mapViewport rewrite.
This commit is contained in:
parent
1a98760b31
commit
d8bb6aa2fc
|
@ -105,26 +105,13 @@ void Scene::composite()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SceneElement::SceneElement(Scene &scene, int z, bool isSprite)
|
SceneElement::SceneElement(Scene &scene, int z, int spriteY)
|
||||||
: link(this),
|
: link(this),
|
||||||
creationStamp(shState->genTimeStamp()),
|
creationStamp(shState->genTimeStamp()),
|
||||||
z(z),
|
z(z),
|
||||||
visible(true),
|
visible(true),
|
||||||
scene(&scene),
|
scene(&scene),
|
||||||
spriteY(0),
|
spriteY(spriteY)
|
||||||
isSprite(isSprite)
|
|
||||||
{
|
|
||||||
scene.insert(*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
SceneElement::SceneElement(Scene &scene, int z, unsigned int cStamp)
|
|
||||||
: link(this),
|
|
||||||
creationStamp(cStamp),
|
|
||||||
z(z),
|
|
||||||
visible(true),
|
|
||||||
scene(&scene),
|
|
||||||
spriteY(0),
|
|
||||||
isSprite(false)
|
|
||||||
{
|
{
|
||||||
scene.insert(*this);
|
scene.insert(*this);
|
||||||
}
|
}
|
||||||
|
@ -184,11 +171,11 @@ bool SceneElement::operator<(const SceneElement &o) const
|
||||||
/* RGSS2: If two sprites' Z values collide,
|
/* RGSS2: If two sprites' Z values collide,
|
||||||
* their Y coordinates decide draw order. Only
|
* their Y coordinates decide draw order. Only
|
||||||
* on equal Y does the creation time take effect */
|
* on equal Y does the creation time take effect */
|
||||||
if (isSprite && o.isSprite && spriteY != o.spriteY)
|
if (spriteY != o.spriteY)
|
||||||
return (spriteY < o.spriteY);
|
return (spriteY < o.spriteY);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (creationStamp <= o.creationStamp);
|
return (creationStamp < o.creationStamp);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
14
src/scene.h
14
src/scene.h
|
@ -71,8 +71,7 @@ protected:
|
||||||
class SceneElement
|
class SceneElement
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SceneElement(Scene &scene, int z = 0, bool isSprite = false);
|
SceneElement(Scene &scene, int z = 0, int spriteY = 0);
|
||||||
SceneElement(Scene &scene, int z, unsigned int cStamp);
|
|
||||||
virtual ~SceneElement();
|
virtual ~SceneElement();
|
||||||
|
|
||||||
void setScene(Scene &scene);
|
void setScene(Scene &scene);
|
||||||
|
@ -122,8 +121,17 @@ protected:
|
||||||
friend struct TilemapPrivate;
|
friend struct TilemapPrivate;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
/* RGSS2 introduced an enhanced type of Z ordering: sprites with
|
||||||
|
* the same Z are first ordered by their Y value (higher Y = closer
|
||||||
|
* to player) and then by creation time. However, the Enterbrain devs
|
||||||
|
* botched their implementation, and now every other scene element
|
||||||
|
* subclass is sorted as if it was a sprite with a fixed Y of 0.
|
||||||
|
* In RGSS3, they tried to fix this for the Window class, badly. It
|
||||||
|
* now behaves as if it was a sprite with fixed Y of infinity. This
|
||||||
|
* means that sprites created _after_ a window with the same Z will
|
||||||
|
* still always be displayed below said window. */
|
||||||
int spriteY;
|
int spriteY;
|
||||||
const bool isSprite;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // SCENE_H
|
#endif // SCENE_H
|
||||||
|
|
|
@ -290,7 +290,7 @@ struct SpritePrivate
|
||||||
};
|
};
|
||||||
|
|
||||||
Sprite::Sprite(Viewport *viewport)
|
Sprite::Sprite(Viewport *viewport)
|
||||||
: ViewportElement(viewport, 0, true)
|
: ViewportElement(viewport)
|
||||||
{
|
{
|
||||||
p = new SpritePrivate;
|
p = new SpritePrivate;
|
||||||
onGeometryChange(scene->getGeometry());
|
onGeometryChange(scene->getGeometry());
|
||||||
|
|
|
@ -313,14 +313,6 @@ struct TilemapPrivate
|
||||||
size_t activeLayers;
|
size_t activeLayers;
|
||||||
Scene::Geometry sceneGeo;
|
Scene::Geometry sceneGeo;
|
||||||
Vec2i sceneOffset;
|
Vec2i sceneOffset;
|
||||||
|
|
||||||
/* The ground and zlayer elements' creationStamp
|
|
||||||
* should be aquired once (at Tilemap construction)
|
|
||||||
* instead of regenerated everytime the elements are
|
|
||||||
* (re)created. ZLayers can share one stamp because
|
|
||||||
* their z always differs anway */
|
|
||||||
unsigned int groundStamp;
|
|
||||||
unsigned int zlayerStamp;
|
|
||||||
} elem;
|
} elem;
|
||||||
|
|
||||||
/* Affected by: autotiles, tileset */
|
/* Affected by: autotiles, tileset */
|
||||||
|
@ -398,9 +390,6 @@ struct TilemapPrivate
|
||||||
flash.quadCount = 0;
|
flash.quadCount = 0;
|
||||||
flash.alphaIdx = 0;
|
flash.alphaIdx = 0;
|
||||||
|
|
||||||
elem.groundStamp = shState->genTimeStamp();
|
|
||||||
elem.zlayerStamp = shState->genTimeStamp();
|
|
||||||
|
|
||||||
elem.ground = new GroundLayer(this, viewport);
|
elem.ground = new GroundLayer(this, viewport);
|
||||||
|
|
||||||
for (size_t i = 0; i < zlayersMax; ++i)
|
for (size_t i = 0; i < zlayersMax; ++i)
|
||||||
|
@ -1077,7 +1066,7 @@ struct TilemapPrivate
|
||||||
};
|
};
|
||||||
|
|
||||||
GroundLayer::GroundLayer(TilemapPrivate *p, Viewport *viewport)
|
GroundLayer::GroundLayer(TilemapPrivate *p, Viewport *viewport)
|
||||||
: ViewportElement(viewport, 0, p->elem.groundStamp),
|
: ViewportElement(viewport, 0),
|
||||||
vboCount(0),
|
vboCount(0),
|
||||||
p(p)
|
p(p)
|
||||||
{
|
{
|
||||||
|
@ -1139,7 +1128,7 @@ void GroundLayer::onGeometryChange(const Scene::Geometry &geo)
|
||||||
}
|
}
|
||||||
|
|
||||||
ZLayer::ZLayer(TilemapPrivate *p, Viewport *viewport)
|
ZLayer::ZLayer(TilemapPrivate *p, Viewport *viewport)
|
||||||
: ViewportElement(viewport, 0, p->elem.zlayerStamp),
|
: ViewportElement(viewport, 0),
|
||||||
index(0),
|
index(0),
|
||||||
vboOffset(0),
|
vboOffset(0),
|
||||||
vboCount(0),
|
vboCount(0),
|
||||||
|
|
|
@ -214,15 +214,11 @@ void Viewport::onGeometryChange(const Geometry &geo)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ViewportElement::ViewportElement(Viewport *viewport, int z, bool isSprite)
|
ViewportElement::ViewportElement(Viewport *viewport, int z, int spriteY)
|
||||||
: SceneElement(viewport ? *viewport : *shState->screen(), z, isSprite),
|
: SceneElement(viewport ? *viewport : *shState->screen(), z, spriteY),
|
||||||
m_viewport(viewport)
|
m_viewport(viewport)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
ViewportElement::ViewportElement(Viewport *viewport, int z, unsigned int cStamp)
|
|
||||||
: SceneElement(viewport ? *viewport : *shState->screen(), z, cStamp)
|
|
||||||
{}
|
|
||||||
|
|
||||||
Viewport *ViewportElement::getViewport() const
|
Viewport *ViewportElement::getViewport() const
|
||||||
{
|
{
|
||||||
return m_viewport;
|
return m_viewport;
|
||||||
|
|
|
@ -61,8 +61,7 @@ private:
|
||||||
class ViewportElement : public SceneElement
|
class ViewportElement : public SceneElement
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ViewportElement(Viewport *viewport = 0, int z = 0, bool isSprite = false);
|
ViewportElement(Viewport *viewport = 0, int z = 0, int spriteY = 0);
|
||||||
ViewportElement(Viewport *viewport, int z, unsigned int cStamp);
|
|
||||||
|
|
||||||
DECL_ATTR( Viewport, Viewport* )
|
DECL_ATTR( Viewport, Viewport* )
|
||||||
|
|
||||||
|
|
|
@ -32,12 +32,14 @@
|
||||||
#include "glstate.h"
|
#include "glstate.h"
|
||||||
#include "shader.h"
|
#include "shader.h"
|
||||||
|
|
||||||
|
#include <limits>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <sigc++/connection.h>
|
#include <sigc++/connection.h>
|
||||||
|
|
||||||
#define DEF_Z (rgssVer >= 3 ? 100 : 0)
|
#define DEF_Z (rgssVer >= 3 ? 100 : 0)
|
||||||
#define DEF_PADDING (rgssVer >= 3 ? 12 : 16)
|
#define DEF_PADDING (rgssVer >= 3 ? 12 : 16)
|
||||||
#define DEF_BACK_OPAC (rgssVer >= 3 ? 192 : 255)
|
#define DEF_BACK_OPAC (rgssVer >= 3 ? 192 : 255)
|
||||||
|
#define DEF_SPRITE_Y (rgssVer >= 3 ? std::numeric_limits<int>::max() : 0) /* See scene.h */
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct Sides
|
struct Sides
|
||||||
|
@ -811,14 +813,14 @@ struct WindowVXPrivate
|
||||||
};
|
};
|
||||||
|
|
||||||
WindowVX::WindowVX(Viewport *viewport)
|
WindowVX::WindowVX(Viewport *viewport)
|
||||||
: ViewportElement(viewport, DEF_Z)
|
: ViewportElement(viewport, DEF_Z, DEF_SPRITE_Y)
|
||||||
{
|
{
|
||||||
p = new WindowVXPrivate(0, 0, 0, 0);
|
p = new WindowVXPrivate(0, 0, 0, 0);
|
||||||
onGeometryChange(scene->getGeometry());
|
onGeometryChange(scene->getGeometry());
|
||||||
}
|
}
|
||||||
|
|
||||||
WindowVX::WindowVX(int x, int y, int width, int height)
|
WindowVX::WindowVX(int x, int y, int width, int height)
|
||||||
: ViewportElement(0, DEF_Z)
|
: ViewportElement(0, DEF_Z, DEF_SPRITE_Y)
|
||||||
{
|
{
|
||||||
p = new WindowVXPrivate(x, y, width, height);
|
p = new WindowVXPrivate(x, y, width, height);
|
||||||
onGeometryChange(scene->getGeometry());
|
onGeometryChange(scene->getGeometry());
|
||||||
|
|
Loading…
Reference in New Issue