- properly implement texture offsets

This commit is contained in:
Christoph Oelckers 2020-05-24 12:31:38 +02:00
parent db4850a028
commit 266364fc2e
29 changed files with 159 additions and 112 deletions

View file

@ -321,8 +321,8 @@ template<typename T> void GetSpriteExtents(T const * const pSprite, int *top, in
*top = *bottom = pSprite->z; *top = *bottom = pSprite->z;
if ((pSprite->cstat & 0x30) != 0x20) if ((pSprite->cstat & 0x30) != 0x20)
{ {
int height = tilesiz[pSprite->picnum].y; int height = tileHeight(pSprite->picnum);
int center = height / 2 + picanm[pSprite->picnum].yofs; int center = height / 2 + tileTopOffset(pSprite->picnum);
*top -= (pSprite->yrepeat << 2)*center; *top -= (pSprite->yrepeat << 2)*center;
*bottom += (pSprite->yrepeat << 2)*(height - center); *bottom += (pSprite->yrepeat << 2)*(height - center);
} }

View file

@ -487,32 +487,32 @@ int VectorScan(spritetype *pSprite, int nOffset, int nZOffset, int dx, int dy, i
if ((pOther->cstat & 0x30) != 0) if ((pOther->cstat & 0x30) != 0)
return 3; return 3;
int nPicnum = pOther->picnum; int nPicnum = pOther->picnum;
if (tilesiz[nPicnum].x == 0 || tilesiz[nPicnum].y == 0) if (tileWidth(nPicnum) == 0 || tileHeight(nPicnum) == 0)
return 3; return 3;
int height = (tilesiz[nPicnum].y*pOther->yrepeat)<<2; int height = (tileHeight(nPicnum)*pOther->yrepeat)<<2;
int otherZ = pOther->z; int otherZ = pOther->z;
if (pOther->cstat & 0x80) if (pOther->cstat & 0x80)
otherZ += height / 2; otherZ += height / 2;
int nOffset = picanm[nPicnum].yofs; int nOffset = tileTopOffset(nPicnum);
if (nOffset) if (nOffset)
otherZ -= (nOffset*pOther->yrepeat)<<2; otherZ -= (nOffset*pOther->yrepeat)<<2;
dassert(height > 0); dassert(height > 0);
int height2 = scale(otherZ-gHitInfo.hitz, tilesiz[nPicnum].y, height); int height2 = scale(otherZ-gHitInfo.hitz, tileHeight(nPicnum), height);
if (!(pOther->cstat & 8)) if (!(pOther->cstat & 8))
height2 = tilesiz[nPicnum].y-height2; height2 = tileHeight(nPicnum)-height2;
if (height2 >= 0 && height2 < tilesiz[nPicnum].y) if (height2 >= 0 && height2 < tileHeight(nPicnum))
{ {
int width = (tilesiz[nPicnum].x*pOther->xrepeat)>>2; int width = (tileWidth(nPicnum)*pOther->xrepeat)>>2;
width = (width*3)/4; width = (width*3)/4;
int check1 = ((y1 - pOther->y)*dx - (x1 - pOther->x)*dy) / ksqrt(dx*dx+dy*dy); int check1 = ((y1 - pOther->y)*dx - (x1 - pOther->x)*dy) / ksqrt(dx*dx+dy*dy);
dassert(width > 0); dassert(width > 0);
int width2 = scale(check1, tilesiz[nPicnum].x, width); int width2 = scale(check1, tileWidth(nPicnum), width);
int nOffset = picanm[nPicnum].xofs; int nOffset = tileTopOffset(nPicnum);
width2 += nOffset + tilesiz[nPicnum].x / 2; width2 += nOffset + tileWidth(nPicnum) / 2;
if (width2 >= 0 && width2 < tilesiz[nPicnum].x) if (width2 >= 0 && width2 < tileWidth(nPicnum))
{ {
auto pData = tileLoadTile(nPicnum); auto pData = tileLoadTile(nPicnum);
if (pData[width2*tilesiz[nPicnum].y+height2] != TRANSPARENT_INDEX) if (pData[width2*tileHeight(nPicnum)+height2] != TRANSPARENT_INDEX)
return 3; return 3;
} }
} }
@ -566,8 +566,8 @@ int VectorScan(spritetype *pSprite, int nOffset, int nZOffset, int dx, int dy, i
nOffset = -nOffset; nOffset = -nOffset;
int nPicnum = pWall->overpicnum; int nPicnum = pWall->overpicnum;
int nSizX = tilesiz[nPicnum].x; int nSizX = tileWidth(nPicnum);
int nSizY = tilesiz[nPicnum].y; int nSizY = tileHeight(nPicnum);
if (!nSizX || !nSizY) if (!nSizX || !nSizY)
return 0; return 0;

View file

@ -2147,7 +2147,7 @@ void useEffectGen(XSPRITE* pXSource, spritetype* pSprite) {
pos = bottom; pos = bottom;
break; break;
case 2: // middle case 2: // middle
pos = pSprite->z + (tilesiz[pSprite->picnum].y / 2 + picanm[pSprite->picnum].yofs); pos = pSprite->z + (tilesiz[pSprite->picnum].y / 2 + tileTopOffset(pSprite->picnum));
break; break;
case 3: case 3:
case 4: case 4:

View file

@ -102,7 +102,7 @@ void UpdateSprite(int nXSprite, SEQFRAME *pFrame)
dassert(pSprite->extra == nXSprite); dassert(pSprite->extra == nXSprite);
if (pSprite->flags & 2) if (pSprite->flags & 2)
{ {
if (tilesiz[pSprite->picnum].y != tilesiz[seqGetTile(pFrame)].y || picanm[pSprite->picnum].yofs != picanm[seqGetTile(pFrame)].yofs if (tilesiz[pSprite->picnum].y != tilesiz[seqGetTile(pFrame)].y || tileTopOffset(pSprite->picnum) != tileTopOffset(seqGetTile(pFrame))
|| (pFrame->at3_0 && pFrame->at3_0 != pSprite->yrepeat)) || (pFrame->at3_0 && pFrame->at3_0 != pSprite->yrepeat))
pSprite->flags |= 4; pSprite->flags |= 4;
} }

View file

@ -144,13 +144,11 @@ const uint8_t * tileLoadTile(int nTile)
return (const uint8_t*)tilePtr(nTile); return (const uint8_t*)tilePtr(nTile);
} }
uint8_t * tileAllocTile(int nTile, int x, int y, int ox, int oy) uint8_t * tileAllocTile(int nTile, int x, int y)
{ {
dassert(nTile >= 0 && nTile < kMaxTiles); dassert(nTile >= 0 && nTile < kMaxTiles);
uint8_t *p = TileFiles.tileCreate(nTile, x, y); uint8_t *p = TileFiles.tileCreate(nTile, x, y);
dassert(p != NULL); dassert(p != NULL);
picanm[nTile].xofs = ClipRange(ox, -127, 127);
picanm[nTile].yofs = ClipRange(oy, -127, 127);
return p; return p;
} }

View file

@ -59,7 +59,7 @@ int tileInit(char a1, const char *a2);
void tileProcessGLVoxels(void); void tileProcessGLVoxels(void);
#endif #endif
const uint8_t * tileLoadTile(int nTile); const uint8_t * tileLoadTile(int nTile);
uint8_t * tileAllocTile(int nTile, int x, int y, int ox, int oy); uint8_t * tileAllocTile(int nTile, int x, int y);
void tilePreloadTile(int nTile); void tilePreloadTile(int nTile);
void tilePrecacheTile(int nTile, int nType = 1); void tilePrecacheTile(int nTile, int nType = 1);
char tileGetSurfType(int hit); char tileGetSurfType(int hit);

View file

@ -1822,7 +1822,7 @@ void viewInit(void)
lensTable[i] = B_LITTLE32(lensTable[i]); lensTable[i] = B_LITTLE32(lensTable[i]);
} }
#endif #endif
uint8_t *data = tileAllocTile(4077, kLensSize, kLensSize, 0, 0); uint8_t *data = tileAllocTile(4077, kLensSize, kLensSize);
memset(data, TRANSPARENT_INDEX, kLensSize*kLensSize); memset(data, TRANSPARENT_INDEX, kLensSize*kLensSize);
gGameMessageMgr.SetState(hud_messages); gGameMessageMgr.SetState(hud_messages);
gGameMessageMgr.SetCoordinates(1, 1); gGameMessageMgr.SetCoordinates(1, 1);
@ -2157,7 +2157,7 @@ tspritetype *viewAddEffect(int nTSprite, VIEW_EFFECT nViewEffect)
pNSprite->picnum = pTSprite->picnum; pNSprite->picnum = pTSprite->picnum;
pNSprite->pal = 5; pNSprite->pal = 5;
int height = tilesiz[pNSprite->picnum].y; int height = tilesiz[pNSprite->picnum].y;
int center = height/2+picanm[pNSprite->picnum].yofs; int center = height / 2 + tileTopOffset(pNSprite->picnum);
pNSprite->z -= (pNSprite->yrepeat<<2)*(height-center); pNSprite->z -= (pNSprite->yrepeat<<2)*(height-center);
break; break;
} }
@ -2381,7 +2381,7 @@ void viewProcessSprites(int32_t cX, int32_t cY, int32_t cZ, int32_t cA, int32_t
{ {
pTSprite->cstat |= 48; pTSprite->cstat |= 48;
pTSprite->cstat &= ~(4|8); pTSprite->cstat &= ~(4|8);
pTSprite->yoffset += picanm[pTSprite->picnum].yofs; pTSprite->yoffset += tileTopOffset(pTSprite->picnum);
pTSprite->picnum = voxelIndex[pTSprite->picnum]; pTSprite->picnum = voxelIndex[pTSprite->picnum];
if (!voxoff[pTSprite->picnum]) if (!voxoff[pTSprite->picnum])
qloadvoxel(pTSprite->picnum); qloadvoxel(pTSprite->picnum);
@ -2408,8 +2408,8 @@ void viewProcessSprites(int32_t cX, int32_t cY, int32_t cZ, int32_t cA, int32_t
#if 0 #if 0
if (tiletovox[nAnimTile] != -1) if (tiletovox[nAnimTile] != -1)
{ {
pTSprite->yoffset += picanm[nAnimTile].yofs; pTSprite->yoffset += tileTopOffset(nAnimTile);
pTSprite->xoffset += picanm[nAnimTile].xofs; pTSprite->xoffset += tileLeftOffset(nAnimTile);
} }
#endif #endif
@ -2427,8 +2427,8 @@ void viewProcessSprites(int32_t cX, int32_t cY, int32_t cZ, int32_t cA, int32_t
if (tile2model[Ptile2tile(nAnimTile, pTSprite->pal)].modelid >= 0 && if (tile2model[Ptile2tile(nAnimTile, pTSprite->pal)].modelid >= 0 &&
tile2model[Ptile2tile(nAnimTile, pTSprite->pal)].framenum >= 0) tile2model[Ptile2tile(nAnimTile, pTSprite->pal)].framenum >= 0)
{ {
pTSprite->yoffset += picanm[nAnimTile].yofs; pTSprite->yoffset += tileTopOffset(nAnimTile);
pTSprite->xoffset += picanm[nAnimTile].xofs; pTSprite->xoffset += tileLeftOffset(nAnimTile);
if ((picanm[nRootTile].extra&7) == 7) if ((picanm[nRootTile].extra&7) == 7)
pTSprite->ang = (pTSprite->ang+((int)totalclock<<3))&2047; pTSprite->ang = (pTSprite->ang+((int)totalclock<<3))&2047;
@ -3237,7 +3237,7 @@ void viewDrawScreen(bool sceneonly)
//othercameraclock = gGameClock; //othercameraclock = gGameClock;
if (!tileData(4079)) if (!tileData(4079))
{ {
tileAllocTile(4079, 128, 128, 0, 0); tileAllocTile(4079, 128, 128);
} }
r enderSetTarget(4079, 128, 128); r enderSetTarget(4079, 128, 128);
renderSetAspect(65536, 78643); renderSetAspect(65536, 78643);

View file

@ -1084,7 +1084,7 @@ void renderSetRollAngle(float rolla);
// bit 6: 33% translucence, using clamping // bit 6: 33% translucence, using clamping
// bit 7: 67% translucence, using clamping // bit 7: 67% translucence, using clamping
// clamping is for sprites, repeating is for walls // clamping is for sprites, repeating is for walls
void tileInvalidate(int16_t tilenume, int32_t pal, int32_t how); void tileInvalidate(int tilenume, int32_t pal, int32_t how);
void polymost_glreset(void); void polymost_glreset(void);
void PrecacheHardwareTextures(int nTile); void PrecacheHardwareTextures(int nTile);

View file

@ -766,10 +766,19 @@ static int32_t defsparser(scriptfile *script)
{ {
// tilefromtexture <tile> { texhitscan } sets the bit but doesn't change tile data // tilefromtexture <tile> { texhitscan } sets the bit but doesn't change tile data
picanm[tile].sf |= flags; picanm[tile].sf |= flags;
int xo, yo;
if (havexoffset) if (havexoffset)
picanm[tile].xofs = xoffset; xo = xoffset;
else
xo = tileLeftOffset(tile);
if (haveyoffset) if (haveyoffset)
picanm[tile].yofs = yoffset; yo = yoffset;
else
yo = tileTopOffset(tile);
auto tex = tileGetTexture(tile);
if (tex) tex->SetOffsets(xo, yo);
if (haveextra) if (haveextra)
picanm[tile].extra = extra; picanm[tile].extra = extra;
@ -791,15 +800,25 @@ static int32_t defsparser(scriptfile *script)
picanm[tile].sf |= flags; picanm[tile].sf |= flags;
int xo;
if (havexoffset) if (havexoffset)
picanm[tile].xofs = xoffset; xo = xoffset;
else if (texstatus == 0) else if (texstatus == 0)
picanm[tile].xofs = 0; xo = 0;
else
xo = tileLeftOffset(tile);
int yo;
if (haveyoffset) if (haveyoffset)
picanm[tile].yofs = yoffset; yo = yoffset;
else if (texstatus == 0) else if (texstatus == 0)
picanm[tile].yofs = 0; yo = 0;
else
yo = tileTopOffset(tile);
auto tex = tileGetTexture(tile);
if (tex) tex->SetOffsets(xo, yo);
if (haveextra) if (haveextra)
picanm[tile].extra = extra; picanm[tile].extra = extra;

View file

@ -2522,7 +2522,7 @@ static void sortsprites(int const start, int const end)
spritesxyz[k].z = s->z; spritesxyz[k].z = s->z;
if ((s->cstat&48) != 32) if ((s->cstat&48) != 32)
{ {
int32_t yoff = picanm[s->picnum].yofs + s->yoffset; int32_t yoff = tileTopOffset(s->picnum) + s->yoffset;
int32_t yspan = (tilesiz[s->picnum].y*s->yrepeat<<2); int32_t yspan = (tilesiz[s->picnum].y*s->yrepeat<<2);
spritesxyz[k].z -= (yoff*s->yrepeat)<<2; spritesxyz[k].z -= (yoff*s->yrepeat)<<2;
@ -4068,7 +4068,7 @@ int32_t spriteheightofsptr(uspriteptr_t spr, int32_t *height, int32_t alsotileyo
// NOTE: a positive per-tile yoffset translates the sprite into the // NOTE: a positive per-tile yoffset translates the sprite into the
// negative world z direction (i.e. upward). // negative world z direction (i.e. upward).
if (alsotileyofs) if (alsotileyofs)
zofs -= picanm[picnum].yofs*yrepeat<<2; zofs -= tileTopOffset(picnum) *yrepeat<<2;
return zofs; return zofs;
} }

View file

@ -232,7 +232,7 @@ static inline void get_wallspr_points(T const * const spr, int32_t *x1, int32_t
const int32_t tilenum=spr->picnum, ang=spr->ang; const int32_t tilenum=spr->picnum, ang=spr->ang;
const int32_t xrepeat = spr->xrepeat; const int32_t xrepeat = spr->xrepeat;
int32_t xoff = picanm[tilenum].xofs + spr->xoffset; int32_t xoff = tileLeftOffset(tilenum) + spr->xoffset;
int32_t k, l, dax, day; int32_t k, l, dax, day;
if (spr->cstat&4) if (spr->cstat&4)
@ -265,7 +265,7 @@ static inline void get_floorspr_points(T const * const spr, int32_t px, int32_t
vec2_t const span = { tilesiz[tilenum].x, tilesiz[tilenum].y}; vec2_t const span = { tilesiz[tilenum].x, tilesiz[tilenum].y};
vec2_t const repeat = { spr->xrepeat, spr->yrepeat }; vec2_t const repeat = { spr->xrepeat, spr->yrepeat };
vec2_t adjofs = { picanm[tilenum].xofs + spr->xoffset, picanm[tilenum].yofs + spr->yoffset }; vec2_t adjofs = { tileLeftOffset(tilenum) + spr->xoffset, tileTopOffset(tilenum) + spr->yoffset };
if (spr->cstat & 4) if (spr->cstat & 4)
adjofs.x = -adjofs.x; adjofs.x = -adjofs.x;

View file

@ -3821,8 +3821,8 @@ void polymost_drawsprite(int32_t snum)
if ((globalorientation & 48) != 48) // only non-voxel sprites should do this if ((globalorientation & 48) != 48) // only non-voxel sprites should do this
{ {
int const flag = hw_hightile && h_xsize[globalpicnum]; int const flag = hw_hightile && h_xsize[globalpicnum];
off = { (int32_t)tspr->xoffset + (flag ? h_xoffs[globalpicnum] : picanm[globalpicnum].xofs), off = { (int32_t)tspr->xoffset + (flag ? h_xoffs[globalpicnum] : tileLeftOffset(globalpicnum)),
(int32_t)tspr->yoffset + (flag ? h_yoffs[globalpicnum] : picanm[globalpicnum].yofs) }; (int32_t)tspr->yoffset + (flag ? h_yoffs[globalpicnum] : tileTopOffset(globalpicnum)) };
} }
int32_t method = DAMETH_MASK | DAMETH_CLAMPED; int32_t method = DAMETH_MASK | DAMETH_CLAMPED;
@ -4472,7 +4472,7 @@ void polymost_dorotatespritemodel(int32_t sx, int32_t sy, int32_t z, int16_t a,
if (dastat & RS_TOPLEFT) if (dastat & RS_TOPLEFT)
{ {
vec2_16_t siz = tilesiz[picnum]; vec2_16_t siz = tilesiz[picnum];
vec2_16_t off = { (int16_t)((siz.x >> 1) + picanm[picnum].xofs), (int16_t)((siz.y >> 1) + picanm[picnum].yofs) }; vec2_16_t off = { (int16_t)((siz.x >> 1) + tileLeftOffset(picnum)), (int16_t)((siz.y >> 1) + tileTopOffset(picnum)) };
d = (float)z * (1.0f / (65536.f * 16384.f)); d = (float)z * (1.0f / (65536.f * 16384.f));
cosang2 = cosang = (float)sintable[(a + 512) & 2047] * d; cosang2 = cosang = (float)sintable[(a + 512) & 2047] * d;

View file

@ -674,8 +674,8 @@ void F2DDrawer::rotatesprite(int32_t sx, int32_t sy, int32_t z, int16_t a, int16
{ {
if (!pic) if (!pic)
{ {
ofs = { int16_t(picanm[picnum].xofs + (siz.x >> 1)), ofs = { int16_t(tileLeftOffset(picnum) + (siz.x >> 1)),
int16_t(picanm[picnum].yofs + (siz.y >> 1)) }; int16_t(tileTopOffset(picnum) + (siz.y >> 1)) };
} }
else else
{ {

View file

@ -94,8 +94,8 @@ FFontChar2::FFontChar2 (TArray<uint8_t>& sourcelump, int sourcepos, int width, i
{ {
Size.x = width; Size.x = width;
Size.y = height; Size.y = height;
PicAnim.xofs = leftofs; leftoffset = leftofs;
PicAnim.yofs = topofs; topoffset = topofs;
} }
//========================================================================== //==========================================================================

View file

@ -466,6 +466,15 @@ void SaveEngineState()
fw->Write(prevspritestat, sizeof(prevspritestat)); fw->Write(prevspritestat, sizeof(prevspritestat));
fw->Write(nextspritestat, sizeof(nextspritestat)); fw->Write(nextspritestat, sizeof(nextspritestat));
WriteMagic(fw); WriteMagic(fw);
for (int i = 0; i < MAXTILES; i++)
{
fw->Write(&picanm[i], sizeof(picanm[i]));
}
for (int i = 0; i < MAXTILES; i++)
{
MREAD(&picanm[i], sizeof(picanm[i]), 1, fil);
}
fw->Write(&tailspritefree, sizeof(tailspritefree)); fw->Write(&tailspritefree, sizeof(tailspritefree));
fw->Write(&myconnectindex, sizeof(myconnectindex)); fw->Write(&myconnectindex, sizeof(myconnectindex));

View file

@ -60,13 +60,13 @@ BuildTiles TileFiles;
// //
//========================================================================== //==========================================================================
picanm_t tileConvertAnimFormat(int32_t const picanimraw) picanm_t tileConvertAnimFormat(int32_t const picanimraw, int* lo, int* to)
{ {
// Unpack a 4 byte packed anim descriptor into the internal 5 byte format. // Unpack a 4 byte packed anim descriptor into the internal 5 byte format.
picanm_t anm; picanm_t anm;
anm.num = picanimraw & 63; anm.num = picanimraw & 63;
anm.xofs = (picanimraw >> 8) & 255; *lo = (int8_t)((picanimraw >> 8) & 255);
anm.yofs = (picanimraw >> 16) & 255; *to = (int8_t)((picanimraw >> 16) & 255);
anm.sf = ((picanimraw >> 24) & 15) | (picanimraw & 192); anm.sf = ((picanimraw >> 24) & 15) | (picanimraw & 192);
anm.extra = (picanimraw >> 28) & 15; anm.extra = (picanimraw >> 28) & 15;
return anm; return anm;
@ -589,21 +589,27 @@ void tileCopy(int tile, int source, int pal, int xoffset, int yoffset, int flags
// Let's get things working first. // Let's get things working first.
picanm_t* picanm = nullptr; picanm_t* picanm = nullptr;
picanm_t* sourceanm = nullptr; picanm_t* sourceanm = nullptr;
int srcxo, srcyo;
FTexture* tex;
if (pal == -1 && tile == source) if (pal == -1 && tile == source)
{ {
// Only modify the picanm info. // Only modify the picanm info.
FTexture* tex = TileFiles.tiles[tile]; tex = TileFiles.tiles[tile];
if (!tex) return; if (!tex) return;
picanm = &tex->PicAnim; picanm = &tex->PicAnim;
sourceanm = picanm; sourceanm = picanm;
srcxo = tex->GetLeftOffset();
srcyo = tex->GetTopOffset();
} }
else else
{ {
if (source == -1) source = tile; if (source == -1) source = tile;
FTexture* tex = TileFiles.tiles[source]; tex = TileFiles.tiles[source];
if (!tex) return; if (!tex) return;
sourceanm = &tex->PicAnim; sourceanm = &tex->PicAnim;
srcxo = tex->GetLeftOffset();
srcyo = tex->GetTopOffset();
TArray<uint8_t> buffer(tex->GetWidth() * tex->GetHeight(), true); TArray<uint8_t> buffer(tex->GetWidth() * tex->GetHeight(), true);
tex->Create8BitPixels(buffer.Data()); tex->Create8BitPixels(buffer.Data());
@ -621,8 +627,9 @@ void tileCopy(int tile, int source, int pal, int xoffset, int yoffset, int flags
TileFiles.AddTile(tile, tex); TileFiles.AddTile(tile, tex);
} }
picanm->xofs = xoffset != -1024 ? clamp(xoffset, -128, 127) : sourceanm->xofs; if (xoffset != -1024) srcxo = clamp(xoffset, -128, 127);
picanm->yofs = yoffset != -1024 ? clamp(yoffset, -128, 127) : sourceanm->yofs; if (yoffset != -1024) srcyo = clamp(yoffset, -128, 127);
tex->SetOffsets(srcxo, srcyo);
picanm->sf = (picanm->sf & ~PICANM_MISC_MASK) | (sourceanm->sf & PICANM_MISC_MASK) | flags; picanm->sf = (picanm->sf & ~PICANM_MISC_MASK) | (sourceanm->sf & PICANM_MISC_MASK) | flags;
} }

View file

@ -45,7 +45,7 @@ public:
: RawPixels(backingstore), Offset(offset) : RawPixels(backingstore), Offset(offset)
{ {
SetSize(width, height); SetSize(width, height);
PicAnim = tileConvertAnimFormat(picanm); PicAnim = tileConvertAnimFormat(picanm, &leftoffset, &topoffset);
} }
const uint8_t* Get8BitPixels() override const uint8_t* Get8BitPixels() override
@ -215,6 +215,7 @@ struct TileDesc
FTexture* backup; // original backup for map tiles FTexture* backup; // original backup for map tiles
RawCacheNode rawCache; // this is needed for hitscan testing to avoid reloading the texture each time. RawCacheNode rawCache; // this is needed for hitscan testing to avoid reloading the texture each time.
picanm_t picanm; // animation descriptor picanm_t picanm; // animation descriptor
picanm_t picanmbackup; // animation descriptor backup when using map tiles
rottile_t RotTile;// = { -1,-1 }; rottile_t RotTile;// = { -1,-1 };
TArray<HightileReplacement> Hightiles; TArray<HightileReplacement> Hightiles;
ReplacementType replacement; ReplacementType replacement;
@ -365,12 +366,26 @@ extern PicAnm picanm;
// Helpers to read the refactored tilesiz array. // Helpers to read the refactored tilesiz array.
inline int tileWidth(int num) inline int tileWidth(int num)
{ {
return tilesiz[num].x; assert(num < MAXTILES);
return TileFiles.tiles[num]->GetDisplayWidth();
} }
inline int tileHeight(int num) inline int tileHeight(int num)
{ {
return tilesiz[num].y; assert(num < MAXTILES);
return TileFiles.tiles[num]->GetDisplayHeight();
}
inline int tileLeftOffset(int num)
{
assert(num < MAXTILES);
return TileFiles.tiles[num]->GetDisplayLeftOffset();
}
inline int tileTopOffset(int num)
{
assert(num < MAXTILES);
return TileFiles.tiles[num]->GetDisplayTopOffset();
} }
inline int widthBits(int num) inline int widthBits(int num)
@ -400,7 +415,13 @@ inline rottile_t& RotTile(int tile)
} }
inline void tileInvalidate(int16_t tilenume, int32_t, int32_t) inline void tileInvalidate(int tilenume, int32_t, int32_t)
{ {
TileFiles.InvalidateTile(tilenume); TileFiles.InvalidateTile(tilenume);
} }
inline FTexture* tileGetTexture(int tile)
{
assert(tile < MAXTILES);
return TileFiles.tiles[tile];
}

View file

@ -55,8 +55,8 @@ FImageTexture::FImageTexture(FImageSource *img, const char *name)
SetSize(img->GetWidth(), img->GetHeight()); SetSize(img->GetWidth(), img->GetHeight());
auto offsets = img->GetOffsets(); auto offsets = img->GetOffsets();
PicAnim.xofs = offsets.first; leftoffset = offsets.first;
PicAnim.yofs = offsets.second; topoffset = offsets.second;
bMasked = img->bMasked; bMasked = img->bMasked;
bTranslucent = img->bTranslucent; bTranslucent = img->bTranslucent;

View file

@ -84,13 +84,12 @@ enum
struct picanm_t struct picanm_t
{ {
uint8_t num; // animate number uint8_t num; // animate number
int8_t xofs, yofs;
uint8_t sf; // anim. speed and flags uint8_t sf; // anim. speed and flags
uint8_t extra; uint8_t extra;
void Clear() void Clear()
{ {
extra = sf = yofs = xofs = num = 0; extra = sf = num = 0;
} }
}; };
@ -114,7 +113,7 @@ class FMultipatchTextureBuilder;
extern int r_spriteadjustSW, r_spriteadjustHW; extern int r_spriteadjustSW, r_spriteadjustHW;
picanm_t tileConvertAnimFormat(int32_t const picanmdisk); picanm_t tileConvertAnimFormat(int32_t const picanmdisk, int *lo, int *to);
class FNullTextureID : public FTextureID class FNullTextureID : public FTextureID
@ -223,8 +222,11 @@ public:
int GetDisplayWidth() const { return Size.x; } int GetDisplayWidth() const { return Size.x; }
int GetDisplayHeight() const { return Size.y; } int GetDisplayHeight() const { return Size.y; }
const vec2_16_t &GetSize() const { return Size; } const vec2_16_t &GetSize() const { return Size; }
int GetLeftOffset() const { return PicAnim.xofs; } int GetLeftOffset() const { return leftoffset; }
int GetTopOffset() const { return PicAnim.yofs; } int GetTopOffset() const { return topoffset; }
int GetDisplayLeftOffset() const { return leftoffset; }
int GetDisplayTopOffset() const { return topoffset; }
void SetOffsets(int x, int y) { leftoffset = x; topoffset = y; }
picanm_t& GetAnim() { return PicAnim; } // This must be modifiable. There's quite a bit of code messing around with the flags in here. picanm_t& GetAnim() { return PicAnim; } // This must be modifiable. There's quite a bit of code messing around with the flags in here.
rottile_t& GetRotTile() { return RotTile; } rottile_t& GetRotTile() { return RotTile; }
FTextureBuffer CreateTexBuffer(const PalEntry *palette, int flags = 0); FTextureBuffer CreateTexBuffer(const PalEntry *palette, int flags = 0);
@ -254,8 +256,8 @@ protected:
{ {
Size.x = BaseTexture->GetWidth(); Size.x = BaseTexture->GetWidth();
Size.y = BaseTexture->GetHeight(); Size.y = BaseTexture->GetHeight();
PicAnim.xofs = BaseTexture->PicAnim.xofs; leftoffset = BaseTexture->leftoffset;
PicAnim.yofs = BaseTexture->PicAnim.yofs; topoffset = BaseTexture->topoffset;
} }
void SetSize(int w, int h) void SetSize(int w, int h)
@ -269,6 +271,7 @@ protected:
vec2_16_t Size = { 0,0 }; // Keep this in the native format so that we can use it without copying it around. vec2_16_t Size = { 0,0 }; // Keep this in the native format so that we can use it without copying it around.
struct { uint16_t Width, Height; }; struct { uint16_t Width, Height; };
}; };
int leftoffset = 0, topoffset = 0;
rottile_t RotTile = { -1,-1 }; rottile_t RotTile = { -1,-1 };
uint8_t bMasked = true; // Texture (might) have holes uint8_t bMasked = true; // Texture (might) have holes
int8_t bTranslucent = -1; // Does this texture have an active alpha channel? int8_t bTranslucent = -1; // Does this texture have an active alpha channel?

View file

@ -1862,8 +1862,8 @@ int32_t __fastcall VM_GetTileData(int const tileNum, int32_t labelNum)
case TILEDATA_GAMEFLAGS: labelNum = g_tile[tileNum].flags; break; case TILEDATA_GAMEFLAGS: labelNum = g_tile[tileNum].flags; break;
case TILEDATA_ANIMFRAMES: labelNum = p.num; break; case TILEDATA_ANIMFRAMES: labelNum = p.num; break;
case TILEDATA_XOFFSET: labelNum = p.xofs; break; case TILEDATA_XOFFSET: labelNum = tileLeftOffset(tileNum); break;
case TILEDATA_YOFFSET: labelNum = p.yofs; break; case TILEDATA_YOFFSET: labelNum = tileTopOffset(tileNum); break;
case TILEDATA_ANIMSPEED: labelNum = (p.sf & PICANM_ANIMSPEED_MASK); break; case TILEDATA_ANIMSPEED: labelNum = (p.sf & PICANM_ANIMSPEED_MASK); break;
case TILEDATA_ANIMTYPE: labelNum = (p.sf & PICANM_ANIMTYPE_MASK) >> PICANM_ANIMTYPE_SHIFT; break; case TILEDATA_ANIMTYPE: labelNum = (p.sf & PICANM_ANIMTYPE_MASK) >> PICANM_ANIMTYPE_SHIFT; break;
@ -1882,6 +1882,7 @@ void __fastcall VM_SetTileData(int const tileNum, int const labelNum, int32_t ne
return; return;
} }
// WTF is this??? This stuff is supposed to be immutable!
auto &p = picanm[tileNum]; auto &p = picanm[tileNum];
switch (labelNum) switch (labelNum)
@ -1892,8 +1893,8 @@ void __fastcall VM_SetTileData(int const tileNum, int const labelNum, int32_t ne
case TILEDATA_GAMEFLAGS: g_tile[tileNum].flags = newValue; break; case TILEDATA_GAMEFLAGS: g_tile[tileNum].flags = newValue; break;
case TILEDATA_ANIMFRAMES: p.num = newValue; break; case TILEDATA_ANIMFRAMES: p.num = newValue; break;
case TILEDATA_XOFFSET: p.xofs = newValue; break; //case TILEDATA_XOFFSET: p.xofs = newValue; break;
case TILEDATA_YOFFSET: p.yofs = newValue; break; //case TILEDATA_YOFFSET: p.yofs = newValue; break;
case TILEDATA_ANIMSPEED: p.sf = (p.sf & ~PICANM_ANIMSPEED_MASK) | (newValue & PICANM_ANIMSPEED_MASK); break; case TILEDATA_ANIMSPEED: p.sf = (p.sf & ~PICANM_ANIMSPEED_MASK) | (newValue & PICANM_ANIMSPEED_MASK); break;
case TILEDATA_ANIMTYPE: p.sf = (p.sf & ~PICANM_ANIMTYPE_MASK) | ((newValue << PICANM_ANIMTYPE_SHIFT) & PICANM_ANIMTYPE_MASK); break; case TILEDATA_ANIMTYPE: p.sf = (p.sf & ~PICANM_ANIMTYPE_MASK) | ((newValue << PICANM_ANIMTYPE_SHIFT) & PICANM_ANIMTYPE_MASK); break;

View file

@ -337,7 +337,7 @@ static void G_DrawOverheadMap(int32_t cposx, int32_t cposy, int32_t czoom, int16
x1 = sprx; x1 = sprx;
y1 = spry; y1 = spry;
tilenum = spr->picnum; tilenum = spr->picnum;
xoff = picanm[tilenum].xofs + spr->xoffset; xoff = tileLeftOffset(tilenum) + spr->xoffset;
if ((spr->cstat&4) > 0) xoff = -xoff; if ((spr->cstat&4) > 0) xoff = -xoff;
k = spr->ang; k = spr->ang;
l = spr->xrepeat; l = spr->xrepeat;
@ -368,8 +368,8 @@ static void G_DrawOverheadMap(int32_t cposx, int32_t cposy, int32_t czoom, int16
case 32: case 32:
tilenum = spr->picnum; tilenum = spr->picnum;
xoff = picanm[tilenum].xofs + spr->xoffset; xoff = tileLeftOffset(tilenum) + spr->xoffset;
yoff = picanm[tilenum].yofs + spr->yoffset; yoff = tileTopOffset(tilenum) + spr->yoffset;
if ((spr->cstat&4) > 0) xoff = -xoff; if ((spr->cstat&4) > 0) xoff = -xoff;
if ((spr->cstat&8) > 0) yoff = -yoff; if ((spr->cstat&8) > 0) yoff = -yoff;

View file

@ -142,9 +142,7 @@ void GameInterface::DrawNativeMenuText(int fontnum, int state, double xpos, doub
shade = 25; shade = 25;
} }
picanm[tilenum].xofs = 0; rotatesprite(160 << 16, int((y + tilesiz[tilenum].y) *65536), zoomsize, 0, tilenum, shade, 0, 2|RS_TOPLEFT, 0, 0, xdim, ydim);
picanm[tilenum].yofs = 0;
rotatesprite(160 << 16, int((y + tilesiz[tilenum].y) *65536), zoomsize, 0, tilenum, shade, 0, 2, 0, 0, xdim, ydim);
// tilesizx is 51 // tilesizx is 51
// tilesizy is 33 // tilesizy is 33

View file

@ -42,10 +42,10 @@ void overwritesprite(int thex, int they, short tilenum, signed char shade, char
{ {
offx -= tilesiz[tilenum].x>>1; offx -= tilesiz[tilenum].x>>1;
if (stat & 8) if (stat & 8)
offx += picanm[tilenum].xofs; offx += tileLeftOffset(tilenum);
else else
offx -= picanm[tilenum].xofs; offx -= tileLeftOffset(tilenum);
offy -= (tilesiz[tilenum].y>>1)+picanm[tilenum].yofs; offy -= (tilesiz[tilenum].y>>1)+tileTopOffset(tilenum);
} }
if (stat&8) if (stat&8)
offx += tilesiz[tilenum].x; offx += tilesiz[tilenum].x;

View file

@ -353,8 +353,8 @@ void seq_LoadSequences()
for (i = 0; i < nSize; i++) for (i = 0; i < nSize; i++)
{ {
picanm[nFontFirstChar + i].xofs = 0; auto tex = tileGetTexture(nFontFirstChar + i);
picanm[nFontFirstChar + i].yofs = 0; tex->SetOffsets(0, 0);
} }
} }

View file

@ -337,7 +337,7 @@ static void G_DrawOverheadMap(int32_t cposx, int32_t cposy, int32_t czoom, int16
x1 = sprx; x1 = sprx;
y1 = spry; y1 = spry;
tilenum = spr->picnum; tilenum = spr->picnum;
xoff = picanm[tilenum].xofs + spr->xoffset; xoff = tileLeftOffset(tilenum) + spr->xoffset;
if ((spr->cstat&4) > 0) xoff = -xoff; if ((spr->cstat&4) > 0) xoff = -xoff;
k = spr->ang; k = spr->ang;
l = spr->xrepeat; l = spr->xrepeat;
@ -368,8 +368,8 @@ static void G_DrawOverheadMap(int32_t cposx, int32_t cposy, int32_t czoom, int16
case 32: case 32:
tilenum = spr->picnum; tilenum = spr->picnum;
xoff = picanm[tilenum].xofs + spr->xoffset; xoff = tileLeftOffset(tilenum) + spr->xoffset;
yoff = picanm[tilenum].yofs + spr->yoffset; yoff = tileTopOffset(tilenum) + spr->yoffset;
if ((spr->cstat&4) > 0) xoff = -xoff; if ((spr->cstat&4) > 0) xoff = -xoff;
if ((spr->cstat&8) > 0) yoff = -yoff; if ((spr->cstat&8) > 0) yoff = -yoff;

View file

@ -3733,7 +3733,7 @@ SHOWSPRITE:
x1 = sprx; x1 = sprx;
y1 = spry; y1 = spry;
tilenum = spr->picnum; tilenum = spr->picnum;
xoff = (int)picanm[tilenum].xofs + (int)spr->xoffset; xoff = (int)tileLeftOffset(tilenum) + (int)spr->xoffset;
if ((spr->cstat & 4) > 0) if ((spr->cstat & 4) > 0)
xoff = -xoff; xoff = -xoff;
k = spr->ang; k = spr->ang;
@ -3765,8 +3765,8 @@ SHOWSPRITE:
if (dimensionmode == 5) if (dimensionmode == 5)
{ {
tilenum = spr->picnum; tilenum = spr->picnum;
xoff = (int)picanm[tilenum].xofs + (int)spr->xoffset; xoff = (int)tileLeftOffset(tilenum) + (int)spr->xoffset;
yoff = (int)picanm[tilenum].yofs + (int)spr->yoffset; yoff = (int)tileTopOffset(tilenum) + (int)spr->yoffset;
if ((spr->cstat & 4) > 0) if ((spr->cstat & 4) > 0)
xoff = -xoff; xoff = -xoff;
if ((spr->cstat & 8) > 0) if ((spr->cstat & 8) > 0)

View file

@ -486,8 +486,8 @@ int StdRandomRange(int range);
// that uses this macro // that uses this macro
#define DISTANCE(x1, y1, x2, y2, dist, tx, ty, tmin) \ #define DISTANCE(x1, y1, x2, y2, dist, tx, ty, tmin) \
{ \ { \
tx = labs(x2-x1); \ tx = abs(x2-x1); \
ty = labs(y2-y1); \ ty = abs(y2-y1); \
tmin = min(tx,ty); \ tmin = min(tx,ty); \
dist = tx + ty - DIV2(tmin); \ dist = tx + ty - DIV2(tmin); \
} }
@ -530,12 +530,12 @@ int StdRandomRange(int range);
// x & y offset of tile // x & y offset of tile
#define TILE_XOFF(picnum) (picanm[(picnum)].xofs) #define TILE_XOFF(picnum) (tileLeftOffset(picnum))
#define TILE_YOFF(picnum) (picanm[(picnum)].yofs) #define TILE_YOFF(picnum) (tileTopOffset(picnum))
// x & y offset of current sprite tile // x & y offset of current sprite tile
#define SPRITEp_XOFF(sp) (picanm[(sp)->picnum].xofs) #define SPRITEp_XOFF(sp) (tileLeftOffset((sp)->picnum))
#define SPRITEp_YOFF(sp) (picanm[(sp)->picnum].yofs) #define SPRITEp_YOFF(sp) (tileTopOffset((sp)->picnum))
// Z size of top (TOS) and bottom (BOS) part of sprite // Z size of top (TOS) and bottom (BOS) part of sprite
#define SPRITEp_SIZE_TOS(sp) (DIV2(SPRITEp_SIZE_Z(sp)) + Z(SPRITEp_YOFF(sp))) #define SPRITEp_SIZE_TOS(sp) (DIV2(SPRITEp_SIZE_Z(sp)) + Z(SPRITEp_YOFF(sp)))
@ -561,13 +561,13 @@ int StdRandomRange(int range);
#define SQ(val) ((val) * (val)) #define SQ(val) ((val) * (val))
#define KENFACING_PLAYER(pp,sp) (sintable[NORM_ANGLE(sp->ang+512)]*(pp->posy-sp->y) >= sintable[NORM_ANGLE(sp-ang)]*(pp->posx-sp->x)) #define KENFACING_PLAYER(pp,sp) (sintable[NORM_ANGLE(sp->ang+512)]*(pp->posy-sp->y) >= sintable[NORM_ANGLE(sp-ang)]*(pp->posx-sp->x))
#define FACING_PLAYER(pp,sp) (labs(GetDeltaAngle((sp)->ang, NORM_ANGLE(getangle((pp)->posx - (sp)->x, (pp)->posy - (sp)->y)))) < 512) #define FACING_PLAYER(pp,sp) (abs(GetDeltaAngle((sp)->ang, NORM_ANGLE(getangle((pp)->posx - (sp)->x, (pp)->posy - (sp)->y)))) < 512)
#define PLAYER_FACING(pp,sp) (labs(GetDeltaAngle(fix16_to_int((pp)->q16ang), NORM_ANGLE(getangle((sp)->x - (pp)->posx, (sp)->y - (pp)->posy)))) < 320) #define PLAYER_FACING(pp,sp) (abs(GetDeltaAngle(fix16_to_int((pp)->q16ang), NORM_ANGLE(getangle((sp)->x - (pp)->posx, (sp)->y - (pp)->posy)))) < 320)
#define FACING(sp1,sp2) (labs(GetDeltaAngle((sp2)->ang, NORM_ANGLE(getangle((sp1)->x - (sp2)->x, (sp1)->y - (sp2)->y)))) < 512) #define FACING(sp1,sp2) (abs(GetDeltaAngle((sp2)->ang, NORM_ANGLE(getangle((sp1)->x - (sp2)->x, (sp1)->y - (sp2)->y)))) < 512)
#define FACING_PLAYER_RANGE(pp,sp,range) (labs(GetDeltaAngle((sp)->ang, NORM_ANGLE(getangle((pp)->posx - (sp)->x, (pp)->posy - (sp)->y)))) < (range)) #define FACING_PLAYER_RANGE(pp,sp,range) (abs(GetDeltaAngle((sp)->ang, NORM_ANGLE(getangle((pp)->posx - (sp)->x, (pp)->posy - (sp)->y)))) < (range))
#define PLAYER_FACING_RANGE(pp,sp,range) (labs(GetDeltaAngle(fix16_to_int((pp)->q16ang), NORM_ANGLE(getangle((sp)->x - (pp)->posx, (sp)->y - (pp)->posy)))) < (range)) #define PLAYER_FACING_RANGE(pp,sp,range) (abs(GetDeltaAngle(fix16_to_int((pp)->q16ang), NORM_ANGLE(getangle((sp)->x - (pp)->posx, (sp)->y - (pp)->posy)))) < (range))
#define FACING_RANGE(sp1,sp2,range) (labs(GetDeltaAngle((sp2)->ang, NORM_ANGLE(getangle((sp1)->x - (sp2)->x, (sp1)->y - (sp2)->y)))) < (range)) #define FACING_RANGE(sp1,sp2,range) (abs(GetDeltaAngle((sp2)->ang, NORM_ANGLE(getangle((sp1)->x - (sp2)->x, (sp1)->y - (sp2)->y)))) < (range))
// two vectors // two vectors
// can determin direction // can determin direction

View file

@ -656,10 +656,6 @@ bool GameInterface::SaveGame(FSaveGameNode *sv)
MWRITE(&gNet,sizeof(gNet),1,fil); MWRITE(&gNet,sizeof(gNet),1,fil);
MWRITE(&gs,sizeof(gs),1,fil); MWRITE(&gs,sizeof(gs),1,fil);
for (int i = 0; i < MAXTILES; i++)
{
MWRITE(&picanm[i], sizeof(picanm[i]), 1, fil);
}
MWRITE(&LevelSecrets,sizeof(LevelSecrets),1,fil); MWRITE(&LevelSecrets,sizeof(LevelSecrets),1,fil);
@ -1051,11 +1047,6 @@ bool GameInterface::LoadGame(FSaveGameNode* sv)
MREAD(&gs,sizeof(gs),1,fil); MREAD(&gs,sizeof(gs),1,fil);
for (int i = 0; i < MAXTILES; i++)
{
MREAD(&picanm[i], sizeof(picanm[i]), 1, fil);
}
MREAD(&LevelSecrets,sizeof(LevelSecrets),1,fil); MREAD(&LevelSecrets,sizeof(LevelSecrets),1,fil);
MREAD(&Bunny_Count,sizeof(Bunny_Count),1,fil); MREAD(&Bunny_Count,sizeof(Bunny_Count),1,fil);

View file

@ -4778,8 +4778,8 @@ getzrangepoint(int x, int y, int z, short sectnum,
// Calculate and store centering offset information into xoff&yoff // Calculate and store centering offset information into xoff&yoff
tilenum = spr->picnum; tilenum = spr->picnum;
xoff = (int)picanm[tilenum].xofs + (int)spr->xoffset; xoff = (int)tileLeftOffset(tilenum) + (int)spr->xoffset;
yoff = (int)picanm[tilenum].yofs + (int)spr->yoffset; yoff = (int)tileTopOffset(tilenum) + (int)spr->yoffset;
if (cstat & 4) if (cstat & 4)
xoff = -xoff; xoff = -xoff;
if (cstat & 8) if (cstat & 8)