From 266364fc2e0d5eef9458f5ddc677adff88458b13 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 24 May 2020 12:31:38 +0200 Subject: [PATCH] - properly implement texture offsets --- source/blood/src/db.h | 4 ++-- source/blood/src/gameutil.cpp | 28 ++++++++++++------------ source/blood/src/nnexts.cpp | 2 +- source/blood/src/seq.cpp | 2 +- source/blood/src/tile.cpp | 4 +--- source/blood/src/tile.h | 2 +- source/blood/src/view.cpp | 16 +++++++------- source/build/include/build.h | 2 +- source/build/src/defs.cpp | 31 +++++++++++++++++++++------ source/build/src/engine.cpp | 4 ++-- source/build/src/engine_priv.h | 4 ++-- source/build/src/polymost.cpp | 6 +++--- source/core/2d/v_2ddrawer.cpp | 4 ++-- source/core/fonts/fontchars.cpp | 4 ++-- source/core/savegamehelp.cpp | 9 ++++++++ source/core/textures/buildtiles.cpp | 21 ++++++++++++------ source/core/textures/buildtiles.h | 29 +++++++++++++++++++++---- source/core/textures/imagetexture.cpp | 4 ++-- source/core/textures/textures.h | 17 +++++++++------ source/duke3d/src/gamestructures.cpp | 9 ++++---- source/duke3d/src/screens.cpp | 6 +++--- source/exhumed/src/d_menu.cpp | 4 +--- source/exhumed/src/enginesubs.cpp | 6 +++--- source/exhumed/src/sequence.cpp | 4 ++-- source/rr/src/screens.cpp | 6 +++--- source/sw/src/game.cpp | 6 +++--- source/sw/src/game.h | 24 ++++++++++----------- source/sw/src/save.cpp | 9 -------- source/sw/src/sprite.cpp | 4 ++-- 29 files changed, 159 insertions(+), 112 deletions(-) diff --git a/source/blood/src/db.h b/source/blood/src/db.h index f6902e11e..119c011af 100644 --- a/source/blood/src/db.h +++ b/source/blood/src/db.h @@ -321,8 +321,8 @@ template void GetSpriteExtents(T const * const pSprite, int *top, in *top = *bottom = pSprite->z; if ((pSprite->cstat & 0x30) != 0x20) { - int height = tilesiz[pSprite->picnum].y; - int center = height / 2 + picanm[pSprite->picnum].yofs; + int height = tileHeight(pSprite->picnum); + int center = height / 2 + tileTopOffset(pSprite->picnum); *top -= (pSprite->yrepeat << 2)*center; *bottom += (pSprite->yrepeat << 2)*(height - center); } diff --git a/source/blood/src/gameutil.cpp b/source/blood/src/gameutil.cpp index ede4502aa..00d16bc79 100644 --- a/source/blood/src/gameutil.cpp +++ b/source/blood/src/gameutil.cpp @@ -487,32 +487,32 @@ int VectorScan(spritetype *pSprite, int nOffset, int nZOffset, int dx, int dy, i if ((pOther->cstat & 0x30) != 0) return 3; int nPicnum = pOther->picnum; - if (tilesiz[nPicnum].x == 0 || tilesiz[nPicnum].y == 0) + if (tileWidth(nPicnum) == 0 || tileHeight(nPicnum) == 0) return 3; - int height = (tilesiz[nPicnum].y*pOther->yrepeat)<<2; + int height = (tileHeight(nPicnum)*pOther->yrepeat)<<2; int otherZ = pOther->z; if (pOther->cstat & 0x80) otherZ += height / 2; - int nOffset = picanm[nPicnum].yofs; + int nOffset = tileTopOffset(nPicnum); if (nOffset) otherZ -= (nOffset*pOther->yrepeat)<<2; 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)) - height2 = tilesiz[nPicnum].y-height2; - if (height2 >= 0 && height2 < tilesiz[nPicnum].y) + height2 = tileHeight(nPicnum)-height2; + 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; int check1 = ((y1 - pOther->y)*dx - (x1 - pOther->x)*dy) / ksqrt(dx*dx+dy*dy); dassert(width > 0); - int width2 = scale(check1, tilesiz[nPicnum].x, width); - int nOffset = picanm[nPicnum].xofs; - width2 += nOffset + tilesiz[nPicnum].x / 2; - if (width2 >= 0 && width2 < tilesiz[nPicnum].x) + int width2 = scale(check1, tileWidth(nPicnum), width); + int nOffset = tileTopOffset(nPicnum); + width2 += nOffset + tileWidth(nPicnum) / 2; + if (width2 >= 0 && width2 < tileWidth(nPicnum)) { auto pData = tileLoadTile(nPicnum); - if (pData[width2*tilesiz[nPicnum].y+height2] != TRANSPARENT_INDEX) + if (pData[width2*tileHeight(nPicnum)+height2] != TRANSPARENT_INDEX) return 3; } } @@ -566,8 +566,8 @@ int VectorScan(spritetype *pSprite, int nOffset, int nZOffset, int dx, int dy, i nOffset = -nOffset; int nPicnum = pWall->overpicnum; - int nSizX = tilesiz[nPicnum].x; - int nSizY = tilesiz[nPicnum].y; + int nSizX = tileWidth(nPicnum); + int nSizY = tileHeight(nPicnum); if (!nSizX || !nSizY) return 0; diff --git a/source/blood/src/nnexts.cpp b/source/blood/src/nnexts.cpp index 5aa47df11..a719267a7 100644 --- a/source/blood/src/nnexts.cpp +++ b/source/blood/src/nnexts.cpp @@ -2147,7 +2147,7 @@ void useEffectGen(XSPRITE* pXSource, spritetype* pSprite) { pos = bottom; break; 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; case 3: case 4: diff --git a/source/blood/src/seq.cpp b/source/blood/src/seq.cpp index c852a039f..1e319af39 100644 --- a/source/blood/src/seq.cpp +++ b/source/blood/src/seq.cpp @@ -102,7 +102,7 @@ void UpdateSprite(int nXSprite, SEQFRAME *pFrame) dassert(pSprite->extra == nXSprite); 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)) pSprite->flags |= 4; } diff --git a/source/blood/src/tile.cpp b/source/blood/src/tile.cpp index 9e672d976..3878e94d0 100644 --- a/source/blood/src/tile.cpp +++ b/source/blood/src/tile.cpp @@ -144,13 +144,11 @@ const uint8_t * tileLoadTile(int 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); uint8_t *p = TileFiles.tileCreate(nTile, x, y); dassert(p != NULL); - picanm[nTile].xofs = ClipRange(ox, -127, 127); - picanm[nTile].yofs = ClipRange(oy, -127, 127); return p; } diff --git a/source/blood/src/tile.h b/source/blood/src/tile.h index 51c24dc60..9d9fed6c0 100644 --- a/source/blood/src/tile.h +++ b/source/blood/src/tile.h @@ -59,7 +59,7 @@ int tileInit(char a1, const char *a2); void tileProcessGLVoxels(void); #endif 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 tilePrecacheTile(int nTile, int nType = 1); char tileGetSurfType(int hit); diff --git a/source/blood/src/view.cpp b/source/blood/src/view.cpp index 9ce0f2444..05e61b196 100644 --- a/source/blood/src/view.cpp +++ b/source/blood/src/view.cpp @@ -1822,7 +1822,7 @@ void viewInit(void) lensTable[i] = B_LITTLE32(lensTable[i]); } #endif - uint8_t *data = tileAllocTile(4077, kLensSize, kLensSize, 0, 0); + uint8_t *data = tileAllocTile(4077, kLensSize, kLensSize); memset(data, TRANSPARENT_INDEX, kLensSize*kLensSize); gGameMessageMgr.SetState(hud_messages); gGameMessageMgr.SetCoordinates(1, 1); @@ -2157,7 +2157,7 @@ tspritetype *viewAddEffect(int nTSprite, VIEW_EFFECT nViewEffect) pNSprite->picnum = pTSprite->picnum; pNSprite->pal = 5; 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); 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 &= ~(4|8); - pTSprite->yoffset += picanm[pTSprite->picnum].yofs; + pTSprite->yoffset += tileTopOffset(pTSprite->picnum); pTSprite->picnum = voxelIndex[pTSprite->picnum]; if (!voxoff[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 (tiletovox[nAnimTile] != -1) { - pTSprite->yoffset += picanm[nAnimTile].yofs; - pTSprite->xoffset += picanm[nAnimTile].xofs; + pTSprite->yoffset += tileTopOffset(nAnimTile); + pTSprite->xoffset += tileLeftOffset(nAnimTile); } #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 && tile2model[Ptile2tile(nAnimTile, pTSprite->pal)].framenum >= 0) { - pTSprite->yoffset += picanm[nAnimTile].yofs; - pTSprite->xoffset += picanm[nAnimTile].xofs; + pTSprite->yoffset += tileTopOffset(nAnimTile); + pTSprite->xoffset += tileLeftOffset(nAnimTile); if ((picanm[nRootTile].extra&7) == 7) pTSprite->ang = (pTSprite->ang+((int)totalclock<<3))&2047; @@ -3237,7 +3237,7 @@ void viewDrawScreen(bool sceneonly) //othercameraclock = gGameClock; if (!tileData(4079)) { - tileAllocTile(4079, 128, 128, 0, 0); + tileAllocTile(4079, 128, 128); } r enderSetTarget(4079, 128, 128); renderSetAspect(65536, 78643); diff --git a/source/build/include/build.h b/source/build/include/build.h index cce35e4a6..82496f43c 100644 --- a/source/build/include/build.h +++ b/source/build/include/build.h @@ -1084,7 +1084,7 @@ void renderSetRollAngle(float rolla); // bit 6: 33% translucence, using clamping // bit 7: 67% translucence, using clamping // 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 PrecacheHardwareTextures(int nTile); diff --git a/source/build/src/defs.cpp b/source/build/src/defs.cpp index 975288d3f..1a60d586c 100644 --- a/source/build/src/defs.cpp +++ b/source/build/src/defs.cpp @@ -766,10 +766,19 @@ static int32_t defsparser(scriptfile *script) { // tilefromtexture { texhitscan } sets the bit but doesn't change tile data picanm[tile].sf |= flags; + int xo, yo; if (havexoffset) - picanm[tile].xofs = xoffset; + xo = xoffset; + else + xo = tileLeftOffset(tile); if (haveyoffset) - picanm[tile].yofs = yoffset; + yo = yoffset; + else + yo = tileTopOffset(tile); + + auto tex = tileGetTexture(tile); + if (tex) tex->SetOffsets(xo, yo); + if (haveextra) picanm[tile].extra = extra; @@ -791,15 +800,25 @@ static int32_t defsparser(scriptfile *script) picanm[tile].sf |= flags; + int xo; if (havexoffset) - picanm[tile].xofs = xoffset; + xo = xoffset; else if (texstatus == 0) - picanm[tile].xofs = 0; + xo = 0; + else + xo = tileLeftOffset(tile); + + int yo; if (haveyoffset) - picanm[tile].yofs = yoffset; + yo = yoffset; 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) picanm[tile].extra = extra; diff --git a/source/build/src/engine.cpp b/source/build/src/engine.cpp index ea29378cc..47679fc9d 100644 --- a/source/build/src/engine.cpp +++ b/source/build/src/engine.cpp @@ -2522,7 +2522,7 @@ static void sortsprites(int const start, int const end) spritesxyz[k].z = s->z; 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); 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 // negative world z direction (i.e. upward). if (alsotileyofs) - zofs -= picanm[picnum].yofs*yrepeat<<2; + zofs -= tileTopOffset(picnum) *yrepeat<<2; return zofs; } diff --git a/source/build/src/engine_priv.h b/source/build/src/engine_priv.h index d616a40f8..7d0e25a35 100644 --- a/source/build/src/engine_priv.h +++ b/source/build/src/engine_priv.h @@ -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 xrepeat = spr->xrepeat; - int32_t xoff = picanm[tilenum].xofs + spr->xoffset; + int32_t xoff = tileLeftOffset(tilenum) + spr->xoffset; int32_t k, l, dax, day; 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 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) adjofs.x = -adjofs.x; diff --git a/source/build/src/polymost.cpp b/source/build/src/polymost.cpp index 03e62e110..7b93a8bf4 100644 --- a/source/build/src/polymost.cpp +++ b/source/build/src/polymost.cpp @@ -3821,8 +3821,8 @@ void polymost_drawsprite(int32_t snum) if ((globalorientation & 48) != 48) // only non-voxel sprites should do this { int const flag = hw_hightile && h_xsize[globalpicnum]; - off = { (int32_t)tspr->xoffset + (flag ? h_xoffs[globalpicnum] : picanm[globalpicnum].xofs), - (int32_t)tspr->yoffset + (flag ? h_yoffs[globalpicnum] : picanm[globalpicnum].yofs) }; + off = { (int32_t)tspr->xoffset + (flag ? h_xoffs[globalpicnum] : tileLeftOffset(globalpicnum)), + (int32_t)tspr->yoffset + (flag ? h_yoffs[globalpicnum] : tileTopOffset(globalpicnum)) }; } 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) { 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)); cosang2 = cosang = (float)sintable[(a + 512) & 2047] * d; diff --git a/source/core/2d/v_2ddrawer.cpp b/source/core/2d/v_2ddrawer.cpp index 8b6d33097..668336654 100644 --- a/source/core/2d/v_2ddrawer.cpp +++ b/source/core/2d/v_2ddrawer.cpp @@ -674,8 +674,8 @@ void F2DDrawer::rotatesprite(int32_t sx, int32_t sy, int32_t z, int16_t a, int16 { if (!pic) { - ofs = { int16_t(picanm[picnum].xofs + (siz.x >> 1)), - int16_t(picanm[picnum].yofs + (siz.y >> 1)) }; + ofs = { int16_t(tileLeftOffset(picnum) + (siz.x >> 1)), + int16_t(tileTopOffset(picnum) + (siz.y >> 1)) }; } else { diff --git a/source/core/fonts/fontchars.cpp b/source/core/fonts/fontchars.cpp index becaaa9cc..465ccf524 100644 --- a/source/core/fonts/fontchars.cpp +++ b/source/core/fonts/fontchars.cpp @@ -94,8 +94,8 @@ FFontChar2::FFontChar2 (TArray& sourcelump, int sourcepos, int width, i { Size.x = width; Size.y = height; - PicAnim.xofs = leftofs; - PicAnim.yofs = topofs; + leftoffset = leftofs; + topoffset = topofs; } //========================================================================== diff --git a/source/core/savegamehelp.cpp b/source/core/savegamehelp.cpp index bb63302bb..c980ccb09 100644 --- a/source/core/savegamehelp.cpp +++ b/source/core/savegamehelp.cpp @@ -466,6 +466,15 @@ void SaveEngineState() fw->Write(prevspritestat, sizeof(prevspritestat)); fw->Write(nextspritestat, sizeof(nextspritestat)); 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(&myconnectindex, sizeof(myconnectindex)); diff --git a/source/core/textures/buildtiles.cpp b/source/core/textures/buildtiles.cpp index dfb1cd4de..35f988d72 100644 --- a/source/core/textures/buildtiles.cpp +++ b/source/core/textures/buildtiles.cpp @@ -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. picanm_t anm; anm.num = picanimraw & 63; - anm.xofs = (picanimraw >> 8) & 255; - anm.yofs = (picanimraw >> 16) & 255; + *lo = (int8_t)((picanimraw >> 8) & 255); + *to = (int8_t)((picanimraw >> 16) & 255); anm.sf = ((picanimraw >> 24) & 15) | (picanimraw & 192); anm.extra = (picanimraw >> 28) & 15; 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. picanm_t* picanm = nullptr; picanm_t* sourceanm = nullptr; + int srcxo, srcyo; + FTexture* tex; if (pal == -1 && tile == source) { // Only modify the picanm info. - FTexture* tex = TileFiles.tiles[tile]; + tex = TileFiles.tiles[tile]; if (!tex) return; picanm = &tex->PicAnim; sourceanm = picanm; + srcxo = tex->GetLeftOffset(); + srcyo = tex->GetTopOffset(); } else { if (source == -1) source = tile; - FTexture* tex = TileFiles.tiles[source]; + tex = TileFiles.tiles[source]; if (!tex) return; sourceanm = &tex->PicAnim; + srcxo = tex->GetLeftOffset(); + srcyo = tex->GetTopOffset(); TArray buffer(tex->GetWidth() * tex->GetHeight(), true); 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); } - picanm->xofs = xoffset != -1024 ? clamp(xoffset, -128, 127) : sourceanm->xofs; - picanm->yofs = yoffset != -1024 ? clamp(yoffset, -128, 127) : sourceanm->yofs; + if (xoffset != -1024) srcxo = clamp(xoffset, -128, 127); + 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; } diff --git a/source/core/textures/buildtiles.h b/source/core/textures/buildtiles.h index 928f4c937..36069910b 100644 --- a/source/core/textures/buildtiles.h +++ b/source/core/textures/buildtiles.h @@ -45,7 +45,7 @@ public: : RawPixels(backingstore), Offset(offset) { SetSize(width, height); - PicAnim = tileConvertAnimFormat(picanm); + PicAnim = tileConvertAnimFormat(picanm, &leftoffset, &topoffset); } const uint8_t* Get8BitPixels() override @@ -215,6 +215,7 @@ struct TileDesc FTexture* backup; // original backup for map tiles RawCacheNode rawCache; // this is needed for hitscan testing to avoid reloading the texture each time. picanm_t picanm; // animation descriptor + picanm_t picanmbackup; // animation descriptor backup when using map tiles rottile_t RotTile;// = { -1,-1 }; TArray Hightiles; ReplacementType replacement; @@ -365,12 +366,26 @@ extern PicAnm picanm; // Helpers to read the refactored tilesiz array. inline int tileWidth(int num) { - return tilesiz[num].x; + assert(num < MAXTILES); + return TileFiles.tiles[num]->GetDisplayWidth(); } 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) @@ -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); } + +inline FTexture* tileGetTexture(int tile) +{ + assert(tile < MAXTILES); + return TileFiles.tiles[tile]; +} \ No newline at end of file diff --git a/source/core/textures/imagetexture.cpp b/source/core/textures/imagetexture.cpp index 902bfce43..92654b8bc 100644 --- a/source/core/textures/imagetexture.cpp +++ b/source/core/textures/imagetexture.cpp @@ -55,8 +55,8 @@ FImageTexture::FImageTexture(FImageSource *img, const char *name) SetSize(img->GetWidth(), img->GetHeight()); auto offsets = img->GetOffsets(); - PicAnim.xofs = offsets.first; - PicAnim.yofs = offsets.second; + leftoffset = offsets.first; + topoffset = offsets.second; bMasked = img->bMasked; bTranslucent = img->bTranslucent; diff --git a/source/core/textures/textures.h b/source/core/textures/textures.h index e68f846ca..c75ecbcc6 100644 --- a/source/core/textures/textures.h +++ b/source/core/textures/textures.h @@ -84,13 +84,12 @@ enum struct picanm_t { uint8_t num; // animate number - int8_t xofs, yofs; uint8_t sf; // anim. speed and flags uint8_t extra; void Clear() { - extra = sf = yofs = xofs = num = 0; + extra = sf = num = 0; } }; @@ -114,7 +113,7 @@ class FMultipatchTextureBuilder; 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 @@ -223,8 +222,11 @@ public: int GetDisplayWidth() const { return Size.x; } int GetDisplayHeight() const { return Size.y; } const vec2_16_t &GetSize() const { return Size; } - int GetLeftOffset() const { return PicAnim.xofs; } - int GetTopOffset() const { return PicAnim.yofs; } + int GetLeftOffset() const { return leftoffset; } + 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. rottile_t& GetRotTile() { return RotTile; } FTextureBuffer CreateTexBuffer(const PalEntry *palette, int flags = 0); @@ -254,8 +256,8 @@ protected: { Size.x = BaseTexture->GetWidth(); Size.y = BaseTexture->GetHeight(); - PicAnim.xofs = BaseTexture->PicAnim.xofs; - PicAnim.yofs = BaseTexture->PicAnim.yofs; + leftoffset = BaseTexture->leftoffset; + topoffset = BaseTexture->topoffset; } 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. struct { uint16_t Width, Height; }; }; + int leftoffset = 0, topoffset = 0; rottile_t RotTile = { -1,-1 }; uint8_t bMasked = true; // Texture (might) have holes int8_t bTranslucent = -1; // Does this texture have an active alpha channel? diff --git a/source/duke3d/src/gamestructures.cpp b/source/duke3d/src/gamestructures.cpp index a033bc191..98ff5e3cd 100644 --- a/source/duke3d/src/gamestructures.cpp +++ b/source/duke3d/src/gamestructures.cpp @@ -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_ANIMFRAMES: labelNum = p.num; break; - case TILEDATA_XOFFSET: labelNum = p.xofs; break; - case TILEDATA_YOFFSET: labelNum = p.yofs; break; + case TILEDATA_XOFFSET: labelNum = tileLeftOffset(tileNum); break; + case TILEDATA_YOFFSET: labelNum = tileTopOffset(tileNum); break; case TILEDATA_ANIMSPEED: labelNum = (p.sf & PICANM_ANIMSPEED_MASK); 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; } + // WTF is this??? This stuff is supposed to be immutable! auto &p = picanm[tileNum]; 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_ANIMFRAMES: p.num = newValue; break; - case TILEDATA_XOFFSET: p.xofs = newValue; break; - case TILEDATA_YOFFSET: p.yofs = newValue; break; + //case TILEDATA_XOFFSET: p.xofs = 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_ANIMTYPE: p.sf = (p.sf & ~PICANM_ANIMTYPE_MASK) | ((newValue << PICANM_ANIMTYPE_SHIFT) & PICANM_ANIMTYPE_MASK); break; diff --git a/source/duke3d/src/screens.cpp b/source/duke3d/src/screens.cpp index df2227324..730ffe486 100644 --- a/source/duke3d/src/screens.cpp +++ b/source/duke3d/src/screens.cpp @@ -337,7 +337,7 @@ static void G_DrawOverheadMap(int32_t cposx, int32_t cposy, int32_t czoom, int16 x1 = sprx; y1 = spry; tilenum = spr->picnum; - xoff = picanm[tilenum].xofs + spr->xoffset; + xoff = tileLeftOffset(tilenum) + spr->xoffset; if ((spr->cstat&4) > 0) xoff = -xoff; k = spr->ang; l = spr->xrepeat; @@ -368,8 +368,8 @@ static void G_DrawOverheadMap(int32_t cposx, int32_t cposy, int32_t czoom, int16 case 32: tilenum = spr->picnum; - xoff = picanm[tilenum].xofs + spr->xoffset; - yoff = picanm[tilenum].yofs + spr->yoffset; + xoff = tileLeftOffset(tilenum) + spr->xoffset; + yoff = tileTopOffset(tilenum) + spr->yoffset; if ((spr->cstat&4) > 0) xoff = -xoff; if ((spr->cstat&8) > 0) yoff = -yoff; diff --git a/source/exhumed/src/d_menu.cpp b/source/exhumed/src/d_menu.cpp index f225ed168..cbd617e6d 100644 --- a/source/exhumed/src/d_menu.cpp +++ b/source/exhumed/src/d_menu.cpp @@ -142,9 +142,7 @@ void GameInterface::DrawNativeMenuText(int fontnum, int state, double xpos, doub shade = 25; } - picanm[tilenum].xofs = 0; - picanm[tilenum].yofs = 0; - rotatesprite(160 << 16, int((y + tilesiz[tilenum].y) *65536), zoomsize, 0, tilenum, shade, 0, 2, 0, 0, xdim, ydim); + rotatesprite(160 << 16, int((y + tilesiz[tilenum].y) *65536), zoomsize, 0, tilenum, shade, 0, 2|RS_TOPLEFT, 0, 0, xdim, ydim); // tilesizx is 51 // tilesizy is 33 diff --git a/source/exhumed/src/enginesubs.cpp b/source/exhumed/src/enginesubs.cpp index 5b610cb32..c4fc253d1 100644 --- a/source/exhumed/src/enginesubs.cpp +++ b/source/exhumed/src/enginesubs.cpp @@ -42,10 +42,10 @@ void overwritesprite(int thex, int they, short tilenum, signed char shade, char { offx -= tilesiz[tilenum].x>>1; if (stat & 8) - offx += picanm[tilenum].xofs; + offx += tileLeftOffset(tilenum); else - offx -= picanm[tilenum].xofs; - offy -= (tilesiz[tilenum].y>>1)+picanm[tilenum].yofs; + offx -= tileLeftOffset(tilenum); + offy -= (tilesiz[tilenum].y>>1)+tileTopOffset(tilenum); } if (stat&8) offx += tilesiz[tilenum].x; diff --git a/source/exhumed/src/sequence.cpp b/source/exhumed/src/sequence.cpp index ccb84a495..3b1e97e18 100644 --- a/source/exhumed/src/sequence.cpp +++ b/source/exhumed/src/sequence.cpp @@ -353,8 +353,8 @@ void seq_LoadSequences() for (i = 0; i < nSize; i++) { - picanm[nFontFirstChar + i].xofs = 0; - picanm[nFontFirstChar + i].yofs = 0; + auto tex = tileGetTexture(nFontFirstChar + i); + tex->SetOffsets(0, 0); } } diff --git a/source/rr/src/screens.cpp b/source/rr/src/screens.cpp index 3dc9bf31f..c7151ace2 100644 --- a/source/rr/src/screens.cpp +++ b/source/rr/src/screens.cpp @@ -337,7 +337,7 @@ static void G_DrawOverheadMap(int32_t cposx, int32_t cposy, int32_t czoom, int16 x1 = sprx; y1 = spry; tilenum = spr->picnum; - xoff = picanm[tilenum].xofs + spr->xoffset; + xoff = tileLeftOffset(tilenum) + spr->xoffset; if ((spr->cstat&4) > 0) xoff = -xoff; k = spr->ang; l = spr->xrepeat; @@ -368,8 +368,8 @@ static void G_DrawOverheadMap(int32_t cposx, int32_t cposy, int32_t czoom, int16 case 32: tilenum = spr->picnum; - xoff = picanm[tilenum].xofs + spr->xoffset; - yoff = picanm[tilenum].yofs + spr->yoffset; + xoff = tileLeftOffset(tilenum) + spr->xoffset; + yoff = tileTopOffset(tilenum) + spr->yoffset; if ((spr->cstat&4) > 0) xoff = -xoff; if ((spr->cstat&8) > 0) yoff = -yoff; diff --git a/source/sw/src/game.cpp b/source/sw/src/game.cpp index 83e221220..62e3f6b98 100644 --- a/source/sw/src/game.cpp +++ b/source/sw/src/game.cpp @@ -3733,7 +3733,7 @@ SHOWSPRITE: x1 = sprx; y1 = spry; tilenum = spr->picnum; - xoff = (int)picanm[tilenum].xofs + (int)spr->xoffset; + xoff = (int)tileLeftOffset(tilenum) + (int)spr->xoffset; if ((spr->cstat & 4) > 0) xoff = -xoff; k = spr->ang; @@ -3765,8 +3765,8 @@ SHOWSPRITE: if (dimensionmode == 5) { tilenum = spr->picnum; - xoff = (int)picanm[tilenum].xofs + (int)spr->xoffset; - yoff = (int)picanm[tilenum].yofs + (int)spr->yoffset; + xoff = (int)tileLeftOffset(tilenum) + (int)spr->xoffset; + yoff = (int)tileTopOffset(tilenum) + (int)spr->yoffset; if ((spr->cstat & 4) > 0) xoff = -xoff; if ((spr->cstat & 8) > 0) diff --git a/source/sw/src/game.h b/source/sw/src/game.h index d59c06032..2734e58e5 100644 --- a/source/sw/src/game.h +++ b/source/sw/src/game.h @@ -486,8 +486,8 @@ int StdRandomRange(int range); // that uses this macro #define DISTANCE(x1, y1, x2, y2, dist, tx, ty, tmin) \ { \ - tx = labs(x2-x1); \ - ty = labs(y2-y1); \ + tx = abs(x2-x1); \ + ty = abs(y2-y1); \ tmin = min(tx,ty); \ dist = tx + ty - DIV2(tmin); \ } @@ -530,12 +530,12 @@ int StdRandomRange(int range); // x & y offset of tile -#define TILE_XOFF(picnum) (picanm[(picnum)].xofs) -#define TILE_YOFF(picnum) (picanm[(picnum)].yofs) +#define TILE_XOFF(picnum) (tileLeftOffset(picnum)) +#define TILE_YOFF(picnum) (tileTopOffset(picnum)) // x & y offset of current sprite tile -#define SPRITEp_XOFF(sp) (picanm[(sp)->picnum].xofs) -#define SPRITEp_YOFF(sp) (picanm[(sp)->picnum].yofs) +#define SPRITEp_XOFF(sp) (tileLeftOffset((sp)->picnum)) +#define SPRITEp_YOFF(sp) (tileTopOffset((sp)->picnum)) // 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))) @@ -561,13 +561,13 @@ int StdRandomRange(int range); #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 FACING_PLAYER(pp,sp) (labs(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 FACING(sp1,sp2) (labs(GetDeltaAngle((sp2)->ang, NORM_ANGLE(getangle((sp1)->x - (sp2)->x, (sp1)->y - (sp2)->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) (abs(GetDeltaAngle(fix16_to_int((pp)->q16ang), NORM_ANGLE(getangle((sp)->x - (pp)->posx, (sp)->y - (pp)->posy)))) < 320) +#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 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 FACING_RANGE(sp1,sp2,range) (labs(GetDeltaAngle((sp2)->ang, NORM_ANGLE(getangle((sp1)->x - (sp2)->x, (sp1)->y - (sp2)->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) (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) (abs(GetDeltaAngle((sp2)->ang, NORM_ANGLE(getangle((sp1)->x - (sp2)->x, (sp1)->y - (sp2)->y)))) < (range)) // two vectors // can determin direction diff --git a/source/sw/src/save.cpp b/source/sw/src/save.cpp index b4ed91438..f31b7d10d 100644 --- a/source/sw/src/save.cpp +++ b/source/sw/src/save.cpp @@ -656,10 +656,6 @@ bool GameInterface::SaveGame(FSaveGameNode *sv) MWRITE(&gNet,sizeof(gNet),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); @@ -1051,11 +1047,6 @@ bool GameInterface::LoadGame(FSaveGameNode* sv) 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(&Bunny_Count,sizeof(Bunny_Count),1,fil); diff --git a/source/sw/src/sprite.cpp b/source/sw/src/sprite.cpp index 0b84576b4..744272b79 100644 --- a/source/sw/src/sprite.cpp +++ b/source/sw/src/sprite.cpp @@ -4778,8 +4778,8 @@ getzrangepoint(int x, int y, int z, short sectnum, // Calculate and store centering offset information into xoff&yoff tilenum = spr->picnum; - xoff = (int)picanm[tilenum].xofs + (int)spr->xoffset; - yoff = (int)picanm[tilenum].yofs + (int)spr->yoffset; + xoff = (int)tileLeftOffset(tilenum) + (int)spr->xoffset; + yoff = (int)tileTopOffset(tilenum) + (int)spr->yoffset; if (cstat & 4) xoff = -xoff; if (cstat & 8)