TilemapVX: Clean up the horrible map viewport calculation code
Also rename "offset" to "origin" which makes a lot more sense for ox/oy attributes.
This commit is contained in:
		
							parent
							
								
									5aaeb0206c
								
							
						
					
					
						commit
						dd7545fcf2
					
				
					 3 changed files with 36 additions and 47 deletions
				
			
		| 
						 | 
					@ -136,6 +136,11 @@ struct Vec2i
 | 
				
			||||||
		return Vec2i(x % value, y % value);
 | 
							return Vec2i(x % value, y % value);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						Vec2i operator&(unsigned value) const
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return Vec2i(x & value, y & value);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Vec2i operator-() const
 | 
						Vec2i operator-() const
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		return Vec2i(-x, -y);
 | 
							return Vec2i(-x, -y);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -46,6 +46,13 @@ wrap(int value, int range)
 | 
				
			||||||
	return res < 0 ? res + range : res;
 | 
						return res < 0 ? res + range : res;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static inline Vec2i
 | 
				
			||||||
 | 
					wrap(const Vec2i &value, int range)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return Vec2i(wrap(value.x, range),
 | 
				
			||||||
 | 
						             wrap(value.y, range));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline int16_t
 | 
					static inline int16_t
 | 
				
			||||||
tableGetWrapped(const Table &t, int x, int y, int z = 0)
 | 
					tableGetWrapped(const Table &t, int x, int y, int z = 0)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -57,12 +57,12 @@ struct TilemapVXPrivate : public ViewportElement, TileAtlasVX::Reader
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Table *mapData;
 | 
						Table *mapData;
 | 
				
			||||||
	Table *flags;
 | 
						Table *flags;
 | 
				
			||||||
	Vec2i offset;
 | 
						Vec2i origin;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Vec2i dispPos;
 | 
						/* Subregion of the map that is drawn to screen (map viewport) */
 | 
				
			||||||
	/* Map viewport position */
 | 
					 | 
				
			||||||
	IntRect mapViewp;
 | 
						IntRect mapViewp;
 | 
				
			||||||
	Vec2i sceneOffset;
 | 
						/* Position on screen the map subregion is drawn at */
 | 
				
			||||||
 | 
						Vec2i dispPos;
 | 
				
			||||||
	Scene::Geometry sceneGeo;
 | 
						Scene::Geometry sceneGeo;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	std::vector<SVertex> groundVert;
 | 
						std::vector<SVertex> groundVert;
 | 
				
			||||||
| 
						 | 
					@ -179,48 +179,29 @@ struct TilemapVXPrivate : public ViewportElement, TileAtlasVX::Reader
 | 
				
			||||||
		TileAtlasVX::build(atlas, bitmaps);
 | 
							TileAtlasVX::build(atlas, bitmaps);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void updatePosition()
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		dispPos = -(offset - mapViewp.pos() * 32) + sceneOffset;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	void updateMapViewport()
 | 
						void updateMapViewport()
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		int tileOX, tileOY;
 | 
							IntRect newMvp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Vec2i offs = offset + sceneGeo.orig;
 | 
							const Vec2i combOrigin = origin + sceneGeo.orig;
 | 
				
			||||||
 | 
							const Vec2i geoSize = sceneGeo.rect.size();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (offs.x >= 0)
 | 
							/* Round the combined origin (which is in pixels) down to the nearest
 | 
				
			||||||
			tileOX = offs.x / 32;
 | 
							 * top left tile boundary, by masking off the lower 5 bits (2^5 = 32) */
 | 
				
			||||||
		else
 | 
							newMvp.setPos((combOrigin & ~(32-1)) / 32);
 | 
				
			||||||
			tileOX = -(-(offs.x-31) / 32);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (offs.y >= 0)
 | 
							/* Ensure that the size is big enough to cover the whole viewport,
 | 
				
			||||||
			tileOY = offs.y / 32;
 | 
							 * and add one tile row/column as a buffer for scrolling */
 | 
				
			||||||
		else
 | 
							newMvp.setSize((geoSize / 32) + !!(geoSize % 32) + Vec2i(1));
 | 
				
			||||||
			tileOY = -(-(offs.y-31) / 32);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		bool dirty = false;
 | 
							if (newMvp != mapViewp)
 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (tileOX < mapViewp.x || tileOX > mapViewp.x)
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			mapViewp.x = tileOX;
 | 
					 | 
				
			||||||
			dirty = true;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (tileOY < mapViewp.y || tileOY > mapViewp.y)
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			mapViewp.y = tileOY;
 | 
					 | 
				
			||||||
			dirty = true;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (dirty)
 | 
					 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
 | 
								mapViewp = newMvp;
 | 
				
			||||||
 | 
								flashMap.setViewport(newMvp);
 | 
				
			||||||
			buffersDirty = true;
 | 
								buffersDirty = true;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		updatePosition();
 | 
							dispPos = sceneGeo.rect.pos() - wrap(combOrigin, 32);
 | 
				
			||||||
		flashMap.setViewport(mapViewp);
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	static size_t quadBytes(size_t quads)
 | 
						static size_t quadBytes(size_t quads)
 | 
				
			||||||
| 
						 | 
					@ -365,10 +346,6 @@ struct TilemapVXPrivate : public ViewportElement, TileAtlasVX::Reader
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void onGeometryChange(const Scene::Geometry &geo)
 | 
						void onGeometryChange(const Scene::Geometry &geo)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		const Vec2i geoSize = geo.rect.size();
 | 
					 | 
				
			||||||
		mapViewp.setSize((geoSize / 32) + !!(geoSize % 32) + Vec2i(1));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		sceneOffset = geo.offset();
 | 
					 | 
				
			||||||
		sceneGeo = geo;
 | 
							sceneGeo = geo;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		buffersDirty = true;
 | 
							buffersDirty = true;
 | 
				
			||||||
| 
						 | 
					@ -466,8 +443,8 @@ TilemapVX::BitmapArray &TilemapVX::getBitmapArray()
 | 
				
			||||||
DEF_ATTR_RD_SIMPLE(TilemapVX, MapData, Table*, p->mapData)
 | 
					DEF_ATTR_RD_SIMPLE(TilemapVX, MapData, Table*, p->mapData)
 | 
				
			||||||
DEF_ATTR_RD_SIMPLE(TilemapVX, FlashData, Table*, p->flashMap.getData())
 | 
					DEF_ATTR_RD_SIMPLE(TilemapVX, FlashData, Table*, p->flashMap.getData())
 | 
				
			||||||
DEF_ATTR_RD_SIMPLE(TilemapVX, Flags, Table*, p->flags)
 | 
					DEF_ATTR_RD_SIMPLE(TilemapVX, Flags, Table*, p->flags)
 | 
				
			||||||
DEF_ATTR_RD_SIMPLE(TilemapVX, OX, int, p->offset.x)
 | 
					DEF_ATTR_RD_SIMPLE(TilemapVX, OX, int, p->origin.x)
 | 
				
			||||||
DEF_ATTR_RD_SIMPLE(TilemapVX, OY, int, p->offset.y)
 | 
					DEF_ATTR_RD_SIMPLE(TilemapVX, OY, int, p->origin.y)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Viewport *TilemapVX::getViewport() const
 | 
					Viewport *TilemapVX::getViewport() const
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -540,10 +517,10 @@ void TilemapVX::setOX(int value)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	guardDisposed();
 | 
						guardDisposed();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (p->offset.x == value)
 | 
						if (p->origin.x == value)
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	p->offset.x = value;
 | 
						p->origin.x = value;
 | 
				
			||||||
	p->mapViewportDirty = true;
 | 
						p->mapViewportDirty = true;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -551,10 +528,10 @@ void TilemapVX::setOY(int value)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	guardDisposed();
 | 
						guardDisposed();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (p->offset.y == value)
 | 
						if (p->origin.y == value)
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	p->offset.y = value;
 | 
						p->origin.y = value;
 | 
				
			||||||
	p->mapViewportDirty = true;
 | 
						p->mapViewportDirty = true;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue