diff --git a/source/core/maptypes.h b/source/core/maptypes.h index 813836a37..5a85fe562 100644 --- a/source/core/maptypes.h +++ b/source/core/maptypes.h @@ -454,12 +454,6 @@ struct sectortype // same for SW bool hasU() const { return u_defined; } - - // Refactoring helper to remove all places that will need the tile num from future searches - int legacyTileNum(int which) const - { - return which? ceilingpicnum : floorpicnum; - } }; //============================================================================= diff --git a/source/games/blood/src/actor.cpp b/source/games/blood/src/actor.cpp index 7e592a9c6..0d24d760f 100644 --- a/source/games/blood/src/actor.cpp +++ b/source/games/blood/src/actor.cpp @@ -3942,7 +3942,7 @@ static void actImpactMissile(DBloodActor* missileActor, int hitCode) actDamageSprite(missileOwner, actorHit, kDamageBullet, nDamage); } - if (surfType[actorHit->spr.picnum] == kSurfFlesh) + if (tprops[actorHit->spr.spritetexture()].surfType == kSurfFlesh) { missileActor->spr.picnum = 2123; missileActor->SetTarget(actorHit); @@ -4108,7 +4108,7 @@ static void actTouchFloor(DBloodActor* actor, sectortype* pSector) actDamageSprite(actor, actor, nDamageType, Scale(4, nDamage, 120) << 4); } - if (tileGetSurfType(pSector->floorpicnum) == kSurfLava) + if (tprops[pSector->floortexture()].surfType == kSurfLava) { actDamageSprite(actor, actor, kDamageBurn, 16); sfxPlay3DSound(actor, 352, 5, 2); @@ -6630,7 +6630,7 @@ void actFireVector(DBloodActor* shooter, double offset, double zoffset, DVector3 if (pSector->ceilingstat & CSTAT_SECTOR_SKY) nSurf = kSurfNone; else - nSurf = surfType[pSector->ceilingpicnum]; + nSurf = tprops[pSector->ceilingtexture()].surfType; break; } case 2: @@ -6638,17 +6638,17 @@ void actFireVector(DBloodActor* shooter, double offset, double zoffset, DVector3 if (pSector->floorstat & CSTAT_SECTOR_SKY) nSurf = kSurfNone; else - nSurf = surfType[pSector->floorpicnum]; + nSurf = tprops[pSector->floortexture()].surfType; break; } case 0: { auto pWall = gHitInfo.hitWall; - nSurf = surfType[pWall->wallpicnum]; + nSurf = tprops[pWall->walltexture()].surfType; if (actCanSplatWall(pWall)) { auto ppos = gHitInfo.hitpos - dv; - int nnSurf = surfType[pWall->wallpicnum]; + int nnSurf = tprops[pWall->walltexture()].surfType; assert(nnSurf < kSurfMax); if (pVectorData->surfHit[nnSurf].fx1 >= 0) { @@ -6666,7 +6666,7 @@ void actFireVector(DBloodActor* shooter, double offset, double zoffset, DVector3 case 4: { auto pWall = gHitInfo.hitWall; - nSurf = surfType[pWall->overpicnum]; + nSurf = tprops[pWall->overtexture()].surfType; if (pWall->hasX()) { if (pWall->xw().triggerVector) @@ -6677,7 +6677,7 @@ void actFireVector(DBloodActor* shooter, double offset, double zoffset, DVector3 case 3: { auto actor = gHitInfo.actor(); - nSurf = surfType[actor->spr.picnum]; + nSurf = tprops[actor->spr.spritetexture()].surfType; pos -= 7 * dv; int shift = 4; if (vectorType == kVectorTine && !actor->IsPlayerActor()) shift = 3; @@ -6741,7 +6741,7 @@ void actFireVector(DBloodActor* shooter, double offset, double zoffset, DVector3 if (actCanSplatWall(pWall)) { auto ppos = gHitInfo.hitpos - dv; - int nnSurf = surfType[pWall->wallpicnum]; + int nnSurf = tprops[pWall->walltexture()].surfType; const VECTORDATA* pVectorData1 = &gVectorData[19]; FX_ID t2 = pVectorData1->surfHit[nnSurf].fx2; FX_ID t3 = pVectorData1->surfHit[nnSurf].fx3; diff --git a/source/games/blood/src/aiunicult.cpp b/source/games/blood/src/aiunicult.cpp index 676f074ab..bd4e14571 100644 --- a/source/games/blood/src/aiunicult.cpp +++ b/source/games/blood/src/aiunicult.cpp @@ -1574,7 +1574,7 @@ static void scaleDamage(DBloodActor* actor) } // take surface type into account - int surfType = tileGetSurfType(actor->spr.picnum); + int surfType = tprops[actor->spr.spritetexture()].surfType; switch (surfType) { case 1: // stone diff --git a/source/games/blood/src/animatesprite.cpp b/source/games/blood/src/animatesprite.cpp index 9bba3bc33..80e9dec96 100644 --- a/source/games/blood/src/animatesprite.cpp +++ b/source/games/blood/src/animatesprite.cpp @@ -630,14 +630,14 @@ void viewProcessSprites(tspriteArray& tsprites, const DVector3& cPos, DAngle cA, break; // Can be overridden by def script - if (r_voxels && tiletovox[pTSprite->picnum] == -1 && voxelIndex[pTSprite->picnum] != -1 && !(owneractor->sprext.renderflags & SPREXT_NOTMD)) + if (r_voxels && tiletovox[pTSprite->picnum] == -1 && tprops[pTSprite->spritetexture()].voxelIndex != -1 && !(owneractor->sprext.renderflags & SPREXT_NOTMD)) { if ((pTSprite->flags & kHitagRespawn) == 0) { pTSprite->cstat |= CSTAT_SPRITE_ALIGNMENT_SLAB; pTSprite->cstat &= ~(CSTAT_SPRITE_XFLIP | CSTAT_SPRITE_YFLIP); pTSprite->yoffset += tileTopOffset(pTSprite->picnum); - pTSprite->picnum = voxelIndex[pTSprite->picnum]; + pTSprite->picnum = tprops[pTSprite->spritetexture()].voxelIndex; if ((picanm[nTile].extra & 7) == 7) { pTSprite->Angles.Yaw = myclock.Normalized360(); @@ -694,13 +694,13 @@ void viewProcessSprites(tspriteArray& tsprites, const DVector3& cPos, DAngle cA, if ((pSector->ceilingstat & CSTAT_SECTOR_SKY) && (pSector->floorstat & CSTAT_SECTOR_NO_CEILINGSHADE) == 0) { - nShade += tileShade[pSector->ceilingpicnum] + pSector->ceilingshade; + nShade += tprops[pSector->ceilingtexture()].tileShade + pSector->ceilingshade; } else { - nShade += tileShade[pSector->floorpicnum] + pSector->floorshade; + nShade += tprops[pSector->floortexture()].tileShade + pSector->floorshade; } - nShade += tileShade[pTSprite->picnum]; + nShade += tprops[pTSprite->spritetexture()].tileShade; pTSprite->shade = ClipRange(nShade, -128, 127); if ((pTSprite->flags & kHitagRespawn) && pTSprite->ownerActor->spr.intowner == 3 && owneractor->hasX()) // Where does this 3 come from? Nothing sets it. { diff --git a/source/games/blood/src/db.cpp b/source/games/blood/src/db.cpp index 912424dc0..9c365510a 100644 --- a/source/games/blood/src/db.cpp +++ b/source/games/blood/src/db.cpp @@ -402,8 +402,8 @@ void dbLoadMap(const char* pPath, DVector3& pos, short* pAngle, sectortype** cur pWall->nextwall = LittleShort(load.nextwall); pWall->nextsector = LittleShort(load.nextsector); pWall->cstat = EWallFlags::FromInt(LittleShort(load.cstat)); - pWall->wallpicnum = EWallFlags::FromInt(LittleShort(load.picnum)); - pWall->overpicnum = LittleShort(load.overpicnum); + pWall->setwalltexture(tileGetTextureID(LittleShort(load.picnum))); + pWall->setovertexture(tileGetTextureID(LittleShort(load.overpicnum))); pWall->type = LittleShort(load.type); pWall->hitag = LittleShort(load.hitag); pWall->extra = LittleShort(load.extra); diff --git a/source/games/blood/src/misc.h b/source/games/blood/src/misc.h index 126b3dd9e..c01860965 100644 --- a/source/games/blood/src/misc.h +++ b/source/games/blood/src/misc.h @@ -90,8 +90,6 @@ enum SurfaceType { kSurfMax }; -extern uint8_t surfType[MAXTILES]; -extern int8_t tileShade[MAXTILES]; extern short voxelIndex[MAXTILES]; extern int nPrecacheCount; @@ -99,7 +97,36 @@ inline FTextureID mirrortile; void tilePrecacheTile(int nTile, int nType, int palette); -int tileGetSurfType(int hit); int tileGetSurfType(CollisionBase& hit); +struct TextureAttr +{ + uint8_t surfType = kSurfNone; + int8_t tileShade = 0; + int16_t voxelIndex = -1; +}; + +class FTextureAttrArray +{ + TextureAttr defaultattr; +public: + TArray Types; + + TextureAttr operator [](FTextureID tex) const + { + if ((unsigned)tex.GetIndex() >= Types.Size()) return defaultattr; + return Types[tex.GetIndex()]; + } + void Set(int index, const TextureAttr& value) + { + if ((unsigned)index >= Types.Size()) + { + Types.Resize(index + 1); + } + Types[index] = value; + } +}; + +inline FTextureAttrArray tprops; + END_BLD_NS diff --git a/source/games/blood/src/nnexts.cpp b/source/games/blood/src/nnexts.cpp index 570654a44..3aecd68fc 100644 --- a/source/games/blood/src/nnexts.cpp +++ b/source/games/blood/src/nnexts.cpp @@ -1446,7 +1446,7 @@ int getSpriteMassBySize(DBloodActor* actor) int yscale = int(actor->spr.scale.Y * 64); // take surface type into account - switch (tileGetSurfType(actor->spr.picnum)) + switch (tprops[actor->spr.spritetexture()].surfType) { case 1: massDiv = 16; break; // stone case 2: massDiv = 18; break; // metal @@ -3945,8 +3945,8 @@ bool condCheckMixed(DBloodActor* aCond, const EVENT& event, int cmpOp, bool PUSH walltype* pObj = eob.wall(); switch (cond) { - case 24: return condCmp(surfType[pObj->wallpicnum], arg1, arg2, cmpOp); - case 25: return condCmp(pObj->wallpicnum, arg1, arg2, cmpOp); + case 24: return condCmp(tprops[pObj->walltexture()].surfType, arg1, arg2, cmpOp); + case 25: return condCmp(legacyTileNum(pObj->walltexture()), arg1, arg2, cmpOp); case 26: return condCmp(pObj->pal, arg1, arg2, cmpOp); case 27: return condCmp(pObj->shade, arg1, arg2, cmpOp); case 28: return (arg3) ? condCmp((pObj->cstat & EWallFlags::FromInt(arg3)), arg1, arg2, cmpOp) : (pObj->cstat & EWallFlags::FromInt(arg1)); @@ -3963,7 +3963,7 @@ bool condCheckMixed(DBloodActor* aCond, const EVENT& event, int cmpOp, bool PUSH if (!actor) break; switch (cond) { - case 24: return condCmp(surfType[actor->spr.picnum], arg1, arg2, cmpOp); + case 24: return condCmp(tprops[actor->spr.spritetexture()].surfType, arg1, arg2, cmpOp); case 25: return condCmp(actor->spr.picnum, arg1, arg2, cmpOp); case 26: return condCmp(actor->spr.pal, arg1, arg2, cmpOp); case 27: return condCmp(actor->spr.shade, arg1, arg2, cmpOp); @@ -3983,17 +3983,17 @@ bool condCheckMixed(DBloodActor* aCond, const EVENT& event, int cmpOp, bool PUSH case 24: switch (arg3) { - default: return (condCmp(surfType[pObj->legacyTileNum(sectortype::floor)], arg1, arg2, cmpOp) || condCmp(surfType[pObj->legacyTileNum(sectortype::ceiling)], arg1, arg2, cmpOp)); - case 1: return condCmp(surfType[pObj->legacyTileNum(sectortype::floor)], arg1, arg2, cmpOp); - case 2: return condCmp(surfType[pObj->legacyTileNum(sectortype::ceiling)], arg1, arg2, cmpOp); + default: return (condCmp(tprops[pObj->floortexture()].surfType, arg1, arg2, cmpOp) || condCmp(tprops[pObj->ceilingtexture()].surfType, arg1, arg2, cmpOp)); + case 1: return condCmp(tprops[pObj->floortexture()].surfType, arg1, arg2, cmpOp); + case 2: return condCmp(tprops[pObj->ceilingtexture()].surfType, arg1, arg2, cmpOp); } break; case 25: switch (arg3) { - default: return (condCmp(pObj->legacyTileNum(sectortype::floor), arg1, arg2, cmpOp) || condCmp(pObj->legacyTileNum(sectortype::ceiling), arg1, arg2, cmpOp)); - case 1: return condCmp(pObj->legacyTileNum(sectortype::floor), arg1, arg2, cmpOp); - case 2: return condCmp(pObj->legacyTileNum(sectortype::ceiling), arg1, arg2, cmpOp); + default: return (condCmp(legacyTileNum(pObj->floortexture()), arg1, arg2, cmpOp) || condCmp(legacyTileNum(pObj->ceilingtexture()), arg1, arg2, cmpOp)); + case 1: return condCmp(legacyTileNum(pObj->floortexture()), arg1, arg2, cmpOp); + case 2: return condCmp(legacyTileNum(pObj->ceilingtexture()), arg1, arg2, cmpOp); } break; case 26: diff --git a/source/games/blood/src/sectorfx.cpp b/source/games/blood/src/sectorfx.cpp index 634863e05..5e5aace65 100644 --- a/source/games/blood/src/sectorfx.cpp +++ b/source/games/blood/src/sectorfx.cpp @@ -320,9 +320,9 @@ void DoSectorPanning(void) psx = MulScale(psx, pXWall->busy, 16); psy = MulScale(psy, pXWall->busy, 16); } - int nTile = pWall->wallpicnum; - int px = (psx << 2) / tileWidth(nTile); - int py = (psy << 2) / tileHeight(nTile); + auto nTex = TexMan.GetGameTexture(pWall->walltexture()); + int px = (psx << 2) / int(nTex->GetDisplayWidth()); + int py = (psy << 2) / int(nTex->GetDisplayHeight()); pWall->addxpan(px * (1.f / 256)); pWall->addypan(py * (1.f / 256)); diff --git a/source/games/blood/src/seq.cpp b/source/games/blood/src/seq.cpp index 5a82c85f5..c98ce9bb6 100644 --- a/source/games/blood/src/seq.cpp +++ b/source/games/blood/src/seq.cpp @@ -128,7 +128,7 @@ void seqPrecacheId(int id, int palette) void UpdateCeiling(sectortype* pSector, SEQFRAME* pFrame) { - pSector->ceilingpicnum = seqGetTile(pFrame); + pSector->setceilingtexture(seqGetTexture(pFrame)); pSector->ceilingshade = pFrame->shade; if (pFrame->palette) pSector->ceilingpal = pFrame->palette; @@ -142,7 +142,7 @@ void UpdateCeiling(sectortype* pSector, SEQFRAME* pFrame) void UpdateFloor(sectortype* pSector, SEQFRAME* pFrame) { - pSector->floorpicnum = seqGetTile(pFrame); + pSector->setfloortexture(seqGetTexture(pFrame)); pSector->floorshade = pFrame->shade; if (pFrame->palette) pSector->floorpal = pFrame->palette; @@ -157,7 +157,7 @@ void UpdateFloor(sectortype* pSector, SEQFRAME* pFrame) void UpdateWall(walltype* pWall, SEQFRAME* pFrame) { assert(pWall->hasX()); - pWall->wallpicnum = seqGetTile(pFrame); + pWall->setwalltexture(seqGetTexture(pFrame)); if (pFrame->palette) pWall->pal = pFrame->palette; if (pFrame->transparent) @@ -188,7 +188,9 @@ void UpdateMasked(walltype* pWall, SEQFRAME* pFrame) { assert(pWall->hasX()); walltype* pWallNext = pWall->nextWall(); - pWall->overpicnum = pWallNext->overpicnum = seqGetTile(pFrame); + auto texid = seqGetTexture(pFrame); + pWall->setovertexture(texid); + pWallNext->setovertexture(texid); if (pFrame->palette) pWall->pal = pWallNext->pal = pFrame->palette; if (pFrame->transparent) @@ -356,7 +358,7 @@ void SEQINST::Update() if (!VanillaMode() && pSequence->frames[frameIndex].surfaceSound && actor->vel.Z == 0 && actor->vel.X != 0) { if (actor->sector()->upperLink) break; // don't play surface sound for stacked sectors - int surf = tileGetSurfType(actor->sector()->floorpicnum); + int surf = tprops[actor->sector()->floortexture()].surfType; if (!surf) break; static int surfSfxMove[15][4] = { /* {snd1, snd2, gameVolume, myVolume} */ diff --git a/source/games/blood/src/seq.h b/source/games/blood/src/seq.h index 29771dc54..0147202ac 100644 --- a/source/games/blood/src/seq.h +++ b/source/games/blood/src/seq.h @@ -91,6 +91,11 @@ inline int seqGetTile(SEQFRAME* pFrame) return pFrame->tile + (pFrame->tile2 << 12); } +inline FTextureID seqGetTexture(SEQFRAME* pFrame) +{ + return tileGetTextureID(pFrame->tile + (pFrame->tile2 << 12)); +} + int seqRegisterClient(void(*pClient)(int, int)); void seqPrecacheId(int id, int palette); SEQINST* GetInstance(int a1, EventObject& a2); diff --git a/source/games/blood/src/tile.cpp b/source/games/blood/src/tile.cpp index 0bb8e3692..bb5dbf29d 100644 --- a/source/games/blood/src/tile.cpp +++ b/source/games/blood/src/tile.cpp @@ -34,19 +34,11 @@ BEGIN_BLD_NS int nTileFiles = 0; -uint8_t surfType[kMaxTiles]; -int8_t tileShade[kMaxTiles]; +// these arrays get partially filled by .def, so they need to remain global. +static uint8_t surfType[kMaxTiles]; +static int8_t tileShade[kMaxTiles]; short voxelIndex[kMaxTiles]; -struct TextureProps -{ - uint8_t surfType; - int8_t tileShade; - int16_t voxelIndex; -}; - -TArray tprops; - #define x(a, b) registerName(#a, b); static void SetTileNames() { @@ -106,6 +98,15 @@ void GameInterface::SetupSpecialTextures() TileFiles.tileMakeWritable(2342); TileFiles.lock(); // from this point on the tile<->texture associations may not change anymore. mirrortile = tileGetTextureID(504); + for (int i = 0; i < MAXTILES; i++) + { + auto tex = tileGetTexture(i); + if (tex) + { + TextureAttr a = { surfType[i], tileShade[i], voxelIndex[i] }; + tprops.Set(tex->GetID().GetIndex(), a); + } + } } //--------------------------------------------------------------------------- @@ -114,11 +115,6 @@ void GameInterface::SetupSpecialTextures() // //--------------------------------------------------------------------------- -int tileGetSurfType(int hit) -{ - return surfType[hit]; -} - int tileGetSurfType(CollisionBase& hit) { switch (hit.type) @@ -126,11 +122,11 @@ int tileGetSurfType(CollisionBase& hit) default: return 0; case kHitSector: - return surfType[hit.hitSector->floorpicnum]; + return tprops[hit.hitSector->floortexture()].surfType; case kHitWall: - return surfType[hit.hitWall->wallpicnum]; + return tprops[hit.hitWall->walltexture()].surfType; case kHitSprite: - return surfType[hit.hitActor->spr.picnum]; + return tprops[hit.hitActor->spr.spritetexture()].surfType; } }