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
					
				
					 7 changed files with 25 additions and 44 deletions
				
			
		| 
						 | 
				
			
			@ -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),
 | 
			
		||||
      creationStamp(shState->genTimeStamp()),
 | 
			
		||||
      z(z),
 | 
			
		||||
      visible(true),
 | 
			
		||||
      scene(&scene),
 | 
			
		||||
      spriteY(0),
 | 
			
		||||
      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)
 | 
			
		||||
      spriteY(spriteY)
 | 
			
		||||
{
 | 
			
		||||
	scene.insert(*this);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -184,11 +171,11 @@ bool SceneElement::operator<(const SceneElement &o) const
 | 
			
		|||
				/* 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)
 | 
			
		||||
				if (spriteY != o.spriteY)
 | 
			
		||||
					return (spriteY < o.spriteY);
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			return (creationStamp <= o.creationStamp);
 | 
			
		||||
			return (creationStamp < o.creationStamp);
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		return true;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										14
									
								
								src/scene.h
									
										
									
									
									
								
							
							
						
						
									
										14
									
								
								src/scene.h
									
										
									
									
									
								
							| 
						 | 
				
			
			@ -71,8 +71,7 @@ protected:
 | 
			
		|||
class SceneElement
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
	SceneElement(Scene &scene, int z = 0, bool isSprite = false);
 | 
			
		||||
	SceneElement(Scene &scene, int z, unsigned int cStamp);
 | 
			
		||||
	SceneElement(Scene &scene, int z = 0, int spriteY = 0);
 | 
			
		||||
	virtual ~SceneElement();
 | 
			
		||||
 | 
			
		||||
	void setScene(Scene &scene);
 | 
			
		||||
| 
						 | 
				
			
			@ -122,8 +121,17 @@ protected:
 | 
			
		|||
	friend struct TilemapPrivate;
 | 
			
		||||
 | 
			
		||||
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;
 | 
			
		||||
	const bool isSprite;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#endif // SCENE_H
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -290,7 +290,7 @@ struct SpritePrivate
 | 
			
		|||
};
 | 
			
		||||
 | 
			
		||||
Sprite::Sprite(Viewport *viewport)
 | 
			
		||||
	: ViewportElement(viewport, 0, true)
 | 
			
		||||
    : ViewportElement(viewport)
 | 
			
		||||
{
 | 
			
		||||
	p = new SpritePrivate;
 | 
			
		||||
	onGeometryChange(scene->getGeometry());
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -313,14 +313,6 @@ struct TilemapPrivate
 | 
			
		|||
		size_t activeLayers;
 | 
			
		||||
		Scene::Geometry sceneGeo;
 | 
			
		||||
		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;
 | 
			
		||||
 | 
			
		||||
	/* Affected by: autotiles, tileset */
 | 
			
		||||
| 
						 | 
				
			
			@ -398,9 +390,6 @@ struct TilemapPrivate
 | 
			
		|||
		flash.quadCount = 0;
 | 
			
		||||
		flash.alphaIdx = 0;
 | 
			
		||||
 | 
			
		||||
		elem.groundStamp = shState->genTimeStamp();
 | 
			
		||||
		elem.zlayerStamp = shState->genTimeStamp();
 | 
			
		||||
 | 
			
		||||
		elem.ground = new GroundLayer(this, viewport);
 | 
			
		||||
 | 
			
		||||
		for (size_t i = 0; i < zlayersMax; ++i)
 | 
			
		||||
| 
						 | 
				
			
			@ -1077,7 +1066,7 @@ struct TilemapPrivate
 | 
			
		|||
};
 | 
			
		||||
 | 
			
		||||
GroundLayer::GroundLayer(TilemapPrivate *p, Viewport *viewport)
 | 
			
		||||
    : ViewportElement(viewport, 0, p->elem.groundStamp),
 | 
			
		||||
    : ViewportElement(viewport, 0),
 | 
			
		||||
      vboCount(0),
 | 
			
		||||
      p(p)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -1139,7 +1128,7 @@ void GroundLayer::onGeometryChange(const Scene::Geometry &geo)
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
ZLayer::ZLayer(TilemapPrivate *p, Viewport *viewport)
 | 
			
		||||
    : ViewportElement(viewport, 0, p->elem.zlayerStamp),
 | 
			
		||||
    : ViewportElement(viewport, 0),
 | 
			
		||||
      index(0),
 | 
			
		||||
      vboOffset(0),
 | 
			
		||||
      vboCount(0),
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -214,15 +214,11 @@ void Viewport::onGeometryChange(const Geometry &geo)
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
ViewportElement::ViewportElement(Viewport *viewport, int z, bool isSprite)
 | 
			
		||||
    : SceneElement(viewport ? *viewport : *shState->screen(), z, isSprite),
 | 
			
		||||
ViewportElement::ViewportElement(Viewport *viewport, int z, int spriteY)
 | 
			
		||||
    : SceneElement(viewport ? *viewport : *shState->screen(), z, spriteY),
 | 
			
		||||
      m_viewport(viewport)
 | 
			
		||||
{}
 | 
			
		||||
 | 
			
		||||
ViewportElement::ViewportElement(Viewport *viewport, int z, unsigned int cStamp)
 | 
			
		||||
    : SceneElement(viewport ? *viewport : *shState->screen(), z, cStamp)
 | 
			
		||||
{}
 | 
			
		||||
 | 
			
		||||
Viewport *ViewportElement::getViewport() const
 | 
			
		||||
{
 | 
			
		||||
	return m_viewport;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -61,8 +61,7 @@ private:
 | 
			
		|||
class ViewportElement : public SceneElement
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
	ViewportElement(Viewport *viewport = 0, int z = 0, bool isSprite = false);
 | 
			
		||||
	ViewportElement(Viewport *viewport, int z, unsigned int cStamp);
 | 
			
		||||
	ViewportElement(Viewport *viewport = 0, int z = 0, int spriteY = 0);
 | 
			
		||||
 | 
			
		||||
	DECL_ATTR( Viewport,  Viewport* )
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -32,12 +32,14 @@
 | 
			
		|||
#include "glstate.h"
 | 
			
		||||
#include "shader.h"
 | 
			
		||||
 | 
			
		||||
#include <limits>
 | 
			
		||||
#include <algorithm>
 | 
			
		||||
#include <sigc++/connection.h>
 | 
			
		||||
 | 
			
		||||
#define DEF_Z         (rgssVer >= 3 ? 100 :   0)
 | 
			
		||||
#define DEF_PADDING   (rgssVer >= 3 ?  12 :  16)
 | 
			
		||||
#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>
 | 
			
		||||
struct Sides
 | 
			
		||||
| 
						 | 
				
			
			@ -811,14 +813,14 @@ struct WindowVXPrivate
 | 
			
		|||
};
 | 
			
		||||
 | 
			
		||||
WindowVX::WindowVX(Viewport *viewport)
 | 
			
		||||
	: ViewportElement(viewport, DEF_Z)
 | 
			
		||||
    : ViewportElement(viewport, DEF_Z, DEF_SPRITE_Y)
 | 
			
		||||
{
 | 
			
		||||
	p = new WindowVXPrivate(0, 0, 0, 0);
 | 
			
		||||
	onGeometryChange(scene->getGeometry());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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);
 | 
			
		||||
	onGeometryChange(scene->getGeometry());
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue