Tilemap: Fix map viewport calculation
Calculation was completely off as it didn't take into account the imposed viewport origin. All in all, similar fixes as the previous ones to TilemapVX.
This commit is contained in:
parent
dd7545fcf2
commit
30465691ae
|
@ -61,6 +61,16 @@ tableGetWrapped(const Table &t, int x, int y, int z = 0)
|
||||||
z);
|
z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Calculate the tile x/y on which this pixel x/y lies */
|
||||||
|
static inline Vec2i
|
||||||
|
getTilePos(const Vec2i &pixelPos)
|
||||||
|
{
|
||||||
|
/* Round the pixel position down to the nearest top left
|
||||||
|
* tile boundary, by masking off the lower 5 bits (2^5 = 32).
|
||||||
|
* Then divide by 32 to convert into tile units. */
|
||||||
|
return (pixelPos & ~(32-1)) / 32;
|
||||||
|
}
|
||||||
|
|
||||||
enum AtSubPos
|
enum AtSubPos
|
||||||
{
|
{
|
||||||
TopLeft = 0,
|
TopLeft = 0,
|
||||||
|
|
|
@ -236,7 +236,7 @@ struct TilemapPrivate
|
||||||
Table *mapData;
|
Table *mapData;
|
||||||
Table *priorities;
|
Table *priorities;
|
||||||
bool visible;
|
bool visible;
|
||||||
Vec2i offset;
|
Vec2i origin;
|
||||||
|
|
||||||
Vec2i dispPos;
|
Vec2i dispPos;
|
||||||
|
|
||||||
|
@ -294,7 +294,6 @@ struct TilemapPrivate
|
||||||
/* Used layers out of 'zlayers' (rest is hidden) */
|
/* Used layers out of 'zlayers' (rest is hidden) */
|
||||||
size_t activeLayers;
|
size_t activeLayers;
|
||||||
Scene::Geometry sceneGeo;
|
Scene::Geometry sceneGeo;
|
||||||
Vec2i sceneOffset;
|
|
||||||
} elem;
|
} elem;
|
||||||
|
|
||||||
/* Affected by: autotiles, tileset */
|
/* Affected by: autotiles, tileset */
|
||||||
|
@ -394,7 +393,7 @@ struct TilemapPrivate
|
||||||
|
|
||||||
void updateFlashMapViewport()
|
void updateFlashMapViewport()
|
||||||
{
|
{
|
||||||
flashMap.setViewport(IntRect(viewpPos.x, viewpPos.y, viewpW, viewpH));
|
flashMap.setViewport(IntRect(viewpPos, Vec2i(viewpW, viewpH)));
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateAtlasInfo()
|
void updateAtlasInfo()
|
||||||
|
@ -442,13 +441,8 @@ struct TilemapPrivate
|
||||||
|
|
||||||
void updateSceneGeometry(const Scene::Geometry &geo)
|
void updateSceneGeometry(const Scene::Geometry &geo)
|
||||||
{
|
{
|
||||||
elem.sceneOffset = geo.offset();
|
|
||||||
elem.sceneGeo = geo;
|
elem.sceneGeo = geo;
|
||||||
}
|
mapViewportDirty = true;
|
||||||
|
|
||||||
void updatePosition()
|
|
||||||
{
|
|
||||||
dispPos = -(offset - viewpPos * 32) + elem.sceneOffset;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void invalidateAtlasSize()
|
void invalidateAtlasSize()
|
||||||
|
@ -898,38 +892,17 @@ struct TilemapPrivate
|
||||||
|
|
||||||
void updateMapViewport()
|
void updateMapViewport()
|
||||||
{
|
{
|
||||||
int tileOX, tileOY;
|
const Vec2i combOrigin = origin + elem.sceneGeo.orig;
|
||||||
|
const Vec2i mvpPos = getTilePos(combOrigin);
|
||||||
|
|
||||||
if (offset.x >= 0)
|
if (mvpPos != viewpPos)
|
||||||
tileOX = offset.x / 32;
|
|
||||||
else
|
|
||||||
tileOX = -(-(offset.x-31) / 32);
|
|
||||||
|
|
||||||
if (offset.y >= 0)
|
|
||||||
tileOY = offset.y / 32;
|
|
||||||
else
|
|
||||||
tileOY = -(-(offset.y-31) / 32);
|
|
||||||
|
|
||||||
bool dirty = false;
|
|
||||||
|
|
||||||
if (tileOX < viewpPos.x || tileOX + 21 > viewpPos.x + viewpW)
|
|
||||||
{
|
|
||||||
viewpPos.x = tileOX;
|
|
||||||
dirty = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tileOY < viewpPos.y || tileOY + 16 > viewpPos.y + viewpH)
|
|
||||||
{
|
|
||||||
viewpPos.y = tileOY;
|
|
||||||
dirty = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dirty)
|
|
||||||
{
|
{
|
||||||
|
viewpPos = mvpPos;
|
||||||
buffersDirty = true;
|
buffersDirty = true;
|
||||||
updateFlashMapViewport();
|
updateFlashMapViewport();
|
||||||
updatePosition();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dispPos = elem.sceneGeo.rect.pos() - wrap(combOrigin, 32);
|
||||||
}
|
}
|
||||||
|
|
||||||
void prepare()
|
void prepare()
|
||||||
|
@ -1024,7 +997,6 @@ void GroundLayer::drawInt()
|
||||||
void GroundLayer::onGeometryChange(const Scene::Geometry &geo)
|
void GroundLayer::onGeometryChange(const Scene::Geometry &geo)
|
||||||
{
|
{
|
||||||
p->updateSceneGeometry(geo);
|
p->updateSceneGeometry(geo);
|
||||||
p->updatePosition();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ZLayer::ZLayer(TilemapPrivate *p, Viewport *viewport)
|
ZLayer::ZLayer(TilemapPrivate *p, Viewport *viewport)
|
||||||
|
@ -1072,7 +1044,7 @@ void ZLayer::drawInt()
|
||||||
|
|
||||||
int ZLayer::calculateZ(TilemapPrivate *p, int index)
|
int ZLayer::calculateZ(TilemapPrivate *p, int index)
|
||||||
{
|
{
|
||||||
return 32 * (index + p->viewpPos.y + 1) - p->offset.y;
|
return 32 * (index + p->viewpPos.y + 1) - p->origin.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ZLayer::initUpdateZ()
|
void ZLayer::initUpdateZ()
|
||||||
|
@ -1172,8 +1144,8 @@ DEF_ATTR_RD_SIMPLE(Tilemap, MapData, Table*, p->mapData)
|
||||||
DEF_ATTR_RD_SIMPLE(Tilemap, FlashData, Table*, p->flashMap.getData())
|
DEF_ATTR_RD_SIMPLE(Tilemap, FlashData, Table*, p->flashMap.getData())
|
||||||
DEF_ATTR_RD_SIMPLE(Tilemap, Priorities, Table*, p->priorities)
|
DEF_ATTR_RD_SIMPLE(Tilemap, Priorities, Table*, p->priorities)
|
||||||
DEF_ATTR_RD_SIMPLE(Tilemap, Visible, bool, p->visible)
|
DEF_ATTR_RD_SIMPLE(Tilemap, Visible, bool, p->visible)
|
||||||
DEF_ATTR_RD_SIMPLE(Tilemap, OX, int, p->offset.x)
|
DEF_ATTR_RD_SIMPLE(Tilemap, OX, int, p->origin.x)
|
||||||
DEF_ATTR_RD_SIMPLE(Tilemap, OY, int, p->offset.y)
|
DEF_ATTR_RD_SIMPLE(Tilemap, OY, int, p->origin.y)
|
||||||
|
|
||||||
void Tilemap::setTileset(Bitmap *value)
|
void Tilemap::setTileset(Bitmap *value)
|
||||||
{
|
{
|
||||||
|
@ -1259,11 +1231,10 @@ void Tilemap::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->updatePosition();
|
|
||||||
p->mapViewportDirty = true;
|
p->mapViewportDirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1271,11 +1242,10 @@ void Tilemap::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->updatePosition();
|
|
||||||
p->zOrderDirty = true;
|
p->zOrderDirty = true;
|
||||||
p->mapViewportDirty = true;
|
p->mapViewportDirty = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -186,9 +186,7 @@ struct TilemapVXPrivate : public ViewportElement, TileAtlasVX::Reader
|
||||||
const Vec2i combOrigin = origin + sceneGeo.orig;
|
const Vec2i combOrigin = origin + sceneGeo.orig;
|
||||||
const Vec2i geoSize = sceneGeo.rect.size();
|
const Vec2i geoSize = sceneGeo.rect.size();
|
||||||
|
|
||||||
/* Round the combined origin (which is in pixels) down to the nearest
|
newMvp.setPos(getTilePos(combOrigin));
|
||||||
* top left tile boundary, by masking off the lower 5 bits (2^5 = 32) */
|
|
||||||
newMvp.setPos((combOrigin & ~(32-1)) / 32);
|
|
||||||
|
|
||||||
/* Ensure that the size is big enough to cover the whole viewport,
|
/* Ensure that the size is big enough to cover the whole viewport,
|
||||||
* and add one tile row/column as a buffer for scrolling */
|
* and add one tile row/column as a buffer for scrolling */
|
||||||
|
|
Loading…
Reference in New Issue