diff --git a/doomsday/client/include/map/bsp/linedefinfo.h b/doomsday/client/include/map/bsp/linedefinfo.h index a9a56bb989..b796c7520d 100644 --- a/doomsday/client/include/map/bsp/linedefinfo.h +++ b/doomsday/client/include/map/bsp/linedefinfo.h @@ -78,7 +78,7 @@ struct LineDefInfo { flags |= Twosided; - if(lineDef->L_backsector == lineDef->L_frontsector) + if(lineDef->isSelfReferencing()) flags |= SelfRef; } } diff --git a/doomsday/client/include/map/linedef.h b/doomsday/client/include/map/linedef.h index a9ee76a0b2..44b387b6c3 100644 --- a/doomsday/client/include/map/linedef.h +++ b/doomsday/client/include/map/linedef.h @@ -46,10 +46,6 @@ class HEdge; #define L_sidedef(n) side(n).sideDef #define L_frontsidedef L_sidedef(FRONT) #define L_backsidedef L_sidedef(BACK) - -#define L_sector(n) side(n).sector -#define L_frontsector L_sector(FRONT) -#define L_backsector L_sector(BACK) ///@} // Internal flags: @@ -108,6 +104,9 @@ class HEdge; class LineDef : public de::MapElement { public: + /// Required sector attribution is missing. @ingroup errors + DENG2_ERROR(MissingSectorError); + /// The referenced property does not exist. @ingroup errors DENG2_ERROR(UnknownPropertyError); @@ -121,7 +120,7 @@ class LineDef : public de::MapElement { public: /// @todo make private: /// Sector on this side. - Sector *sector; + Sector *_sector; /// SideDef on this side. SideDef *sideDef; @@ -134,14 +133,36 @@ class LineDef : public de::MapElement /// Framecount of last time shadows were drawn on this side. ushort shadowVisFrame; + + public: + /** + * Returns @c true iff a Sector is attributed to the side. + */ + bool hasSector() const; + + /** + * Returns the Sector attributed to the side. + * + * @see hasSector() + */ + Sector §or() const; + + /** + * Returns a pointer to the sector attributed to the side; otherwise @c 0. + * + * @see hasSector() + */ + inline Sector *sectorPtr() const { return hasSector()? §or() : 0; } }; public: /// @todo make private: + /// Vertexes [From, To] Vertex *_v[2]; - /// Links to vertex line owner nodes [left, right]. + /// Links to vertex line owner nodes [From, To]. LineOwner *vo[2]; + /// Logical sides [Front, Back] Side _sides[2]; /// Public DDLF_* flags. @@ -150,6 +171,7 @@ class LineDef : public de::MapElement /// Internal LF_* flags. byte inFlags; + /// Logical slope type. slopetype_t slopeType; int validCount; @@ -200,15 +222,80 @@ class LineDef : public de::MapElement /// @copydoc back() inline Side const &back() const { return side(BACK); } + /** + * Returns @c true iff a sector is attributed to the specified side of the line. + * + * @param back If not @c 0 test the Back side; otherwise the Front side. + */ + inline bool hasSector(int back) const { return side(back).hasSector(); } + /** * Returns @c true iff a sector is attributed to the Front side of the line. */ - inline bool hasFrontSector() const { return !!front().sector; } + inline bool hasFrontSector() const { return hasSector(FRONT); } /** * Returns @c true iff a sector is attributed to the Back side of the line. */ - inline bool hasBackSector() const { return !!back().sector; } + inline bool hasBackSector() const { return hasSector(BACK); } + + /** + * Convenient accessor method for returning the sector attributed to the + * specified side of the line. + * + * @param back If not @c 0 return the sector for the Back side; otherwise + * the sector of the Front side. + */ + inline Sector §or(int back) { return side(back).sector(); } + + /// @copydoc sector() + inline Sector const §or(int back) const { return side(back).sector(); } + + /** + * Convenient accessor method for returning a pointer to the sector attributed + * to the specified side of the line. + * + * @param back If not @c 0 return the sector for the Back side; otherwise + * the sector of the Front side. + */ + inline Sector *sectorPtr(int back) { return side(back).sectorPtr(); } + + /// @copydoc sector() + inline Sector const *sectorPtr(int back) const { return side(back).sectorPtr(); } + + /** + * Returns the sector attributed to the Front side of the line. + */ + inline Sector &frontSector() { return sector(FRONT); } + + /// @copydoc backSector() + inline Sector const &frontSector() const { return sector(FRONT); } + + /** + * Returns the sector attributed to the Back side of the line. + */ + inline Sector &backSector() { return sector(BACK); } + + /// @copydoc backSector() + inline Sector const &backSector() const { return sector(BACK); } + + /** + * Convenient accessor method for returning a pointer to the sector attributed + * to the front side of the line. + */ + inline Sector *frontSectorPtr() { return sectorPtr(FRONT); } + + /// @copydoc frontSectorPtr() + inline Sector const *frontSectorPtr() const { return sectorPtr(FRONT); } + + /** + * Convenient accessor method for returning a pointer to the sector attributed + * to the back side of the line. + */ + inline Sector *backSectorPtr() { return sectorPtr(BACK); } + + /// @copydoc frontSectorPtr() + inline Sector const *backSectorPtr() const { return sectorPtr(BACK); } /** * Returns @c true iff the line is considered @em self-referencing. @@ -219,7 +306,7 @@ class LineDef : public de::MapElement */ inline bool isSelfReferencing() const { - return L_frontsidedef && L_backsidedef && L_frontsector == L_backsector; + return L_frontsidedef && L_backsidedef && frontSectorPtr() == backSectorPtr(); } /** diff --git a/doomsday/client/include/map/r_world.h b/doomsday/client/include/map/r_world.h index ce53cff542..bfecfbbd7d 100644 --- a/doomsday/client/include/map/r_world.h +++ b/doomsday/client/include/map/r_world.h @@ -108,11 +108,11 @@ void R_OrderVertices(LineDef *line, Sector const *sector, Vertex *verts[2]); * @return @c true iff the determined wall section height is @c >0 */ boolean R_FindBottomTop2(SideDefSection section, int lineFlags, - Sector* frontSec, Sector* backSec, SideDef* frontDef, SideDef* backDef, - coord_t* low, coord_t* hi, float matOffset[2]); + Sector const *frontSec, Sector const *backSec, SideDef const *frontDef, SideDef const *backDef, + coord_t *low, coord_t *hi, float matOffset[2]); boolean R_FindBottomTop(SideDefSection section, int lineFlags, - Sector* frontSec, Sector* backSec, SideDef* frontDef, SideDef* backDef, - coord_t* low, coord_t* hi) /* matOffset = 0 */; + Sector const *frontSec, Sector const *backSec, SideDef const *frontDef, SideDef const *backDef, + coord_t *low, coord_t *hi) /* matOffset = 0 */; /** * Find the "sharp" Z coordinate range of the opening between sectors @a frontSec @@ -144,8 +144,9 @@ coord_t R_VisOpenRange(Sector const* frontSec, Sector const* backSec, coord_t* r * @return @c true iff SideDef @a frontDef has a "middle" Material which completely * covers the open range defined by sectors @a frontSec and @a backSec. */ -boolean R_MiddleMaterialCoversOpening(int lineFlags, Sector* frontSec, Sector* backSec, - SideDef* frontDef, SideDef* backDef, boolean ignoreOpacity); +boolean R_MiddleMaterialCoversOpening(int lineFlags, Sector const *frontSec, + Sector const *backSec, SideDef const *frontDef, SideDef const *backDef, + boolean ignoreOpacity); /** * Same as @ref R_MiddleMaterialCoversOpening except all arguments are derived from diff --git a/doomsday/client/src/edit_bsp.cpp b/doomsday/client/src/edit_bsp.cpp index 67107cdfac..f603bc5d51 100644 --- a/doomsday/client/src/edit_bsp.cpp +++ b/doomsday/client/src/edit_bsp.cpp @@ -134,7 +134,7 @@ static void finishHEdges(GameMap *map) { Vertex const &vtx = hedge->lineDef->vertex(hedge->side); - hedge->sector = hedge->lineDef->L_sector(hedge->side); + hedge->sector = hedge->lineDef->sectorPtr(hedge->side); hedge->offset = V2d_Distance(hedge->HE_v1origin, vtx.origin()); } diff --git a/doomsday/client/src/edit_map.cpp b/doomsday/client/src/edit_map.cpp index 4905ac240f..84819911bd 100644 --- a/doomsday/client/src/edit_map.cpp +++ b/doomsday/client/src/edit_map.cpp @@ -537,29 +537,29 @@ static void buildSectorLineLists(GameMap* map) uint secIDX; linelink_t* link; - if(li->L_frontsector) + if(li->hasFrontSector()) { link = (linelink_t*) ZBlockSet_Allocate(lineLinksBlockSet); - secIDX = map->sectors.indexOf(static_cast(li->L_frontsector)); + secIDX = map->sectors.indexOf(&li->frontSector()); link->line = li; link->next = sectorLineLinks[secIDX]; sectorLineLinks[secIDX] = link; - li->L_frontsector->lineDefCount++; + li->frontSector().lineDefCount++; totallinks++; } - if(li->L_backsector && !li->isSelfReferencing()) + if(li->hasBackSector() && !li->isSelfReferencing()) { link = (linelink_t*) ZBlockSet_Allocate(lineLinksBlockSet); - secIDX = map->sectors.indexOf(static_cast(li->L_backsector)); + secIDX = map->sectors.indexOf(&li->backSector()); link->line = li; link->next = sectorLineLinks[secIDX]; sectorLineLinks[secIDX] = link; - li->L_backsector->lineDefCount++; + li->backSector().lineDefCount++; totallinks++; } } @@ -661,14 +661,14 @@ static void linkBaseToSectorChain(Sector* sector, ddmobj_base_t* base) * These chains are used for efficiently traversing all of the base objects in a * sector, for example; stopping sounds emitted from all origins within a sector. */ -static void chainSectorBases(GameMap* map) +static void chainSectorBases(GameMap *map) { DENG_ASSERT(map); for(uint i = 0; i < map->sectorCount(); ++i) { - Sector* sec = GameMap_Sector(map, i); - ddmobj_base_t* base = &sec->base; + Sector *sec = GameMap_Sector(map, i); + ddmobj_base_t *base = &sec->base; // Clear the chain head. base->thinker.next = base->thinker.prev = 0; @@ -676,24 +676,24 @@ static void chainSectorBases(GameMap* map) // Add all plane base mobjs. for(uint j = 0; j < sec->planeCount(); ++j) { - Plane* pln = sec->SP_plane(j); + Plane *pln = sec->SP_plane(j); linkBaseToSectorChain(sec, &pln->PS_base); } // Add all sidedef base mobjs. for(uint j = 0; j < sec->lineDefCount; ++j) { - LineDef* line = sec->lineDefs[j]; - if(line->L_frontsector == sec) + LineDef *line = sec->lineDefs[j]; + if(line->frontSectorPtr() == sec) { - SideDef* side = line->L_frontsidedef; + SideDef *side = line->L_frontsidedef; linkBaseToSectorChain(sec, &side->SW_middlesurface.base); linkBaseToSectorChain(sec, &side->SW_bottomsurface.base); linkBaseToSectorChain(sec, &side->SW_topsurface.base); } - if(line->L_backsidedef && line->L_backsector == sec) + if(line->L_backsidedef && line->backSectorPtr() == sec) { - SideDef* side = line->L_backsidedef; + SideDef *side = line->L_backsidedef; linkBaseToSectorChain(sec, &side->SW_middlesurface.base); linkBaseToSectorChain(sec, &side->SW_bottomsurface.base); linkBaseToSectorChain(sec, &side->SW_topsurface.base); @@ -1036,14 +1036,14 @@ static void hardenVertexOwnerRings(GameMap *dest, EditMap *src) } } -static void hardenLinedefs(GameMap* dest, EditMap* src) +static void hardenLinedefs(GameMap *dest, EditMap *src) { dest->lineDefs.clearAndResize(src->lineDefs.size()); for(uint i = 0; i < dest->lineDefCount(); ++i) { - LineDef* destL = &dest->lineDefs[i]; - LineDef* srcL = src->lineDefs[i]; + LineDef *destL = &dest->lineDefs[i]; + LineDef *srcL = src->lineDefs[i]; *destL = *srcL; @@ -1058,11 +1058,11 @@ static void hardenLinedefs(GameMap* dest, EditMap* src) if(destL->L_backsidedef) destL->L_backsidedef->line = destL; - destL->L_frontsector = (srcL->L_frontsector? - &dest->sectors[srcL->L_frontsector->buildData.index - 1] : NULL); + destL->front()._sector = (srcL->front()._sector? + &dest->sectors[srcL->front()._sector->buildData.index - 1] : NULL); - destL->L_backsector = (srcL->L_backsector? - &dest->sectors[srcL->L_backsector->buildData.index - 1] : NULL); + destL->back()._sector = (srcL->back()._sector? + &dest->sectors[srcL->back()._sector->buildData.index - 1] : NULL); } } @@ -1145,11 +1145,9 @@ static void hardenPolyobjs(GameMap* dest, EditMap* src) uint i; for(i = 0; i < dest->numPolyObjs; ++i) { - Polyobj* destP, *srcP = src->polyObjs[i]; - HEdge* hedges; - uint j; + Polyobj *srcP = src->polyObjs[i]; + Polyobj *destP = (Polyobj *) Z_Calloc(POLYOBJ_SIZE, PU_MAP, 0); - destP = (Polyobj*) Z_Calloc(POLYOBJ_SIZE, PU_MAP, 0); destP->idx = i; destP->crush = srcP->crush; destP->tag = srcP->tag; @@ -1159,18 +1157,18 @@ static void hardenPolyobjs(GameMap* dest, EditMap* src) destP->lineCount = srcP->lineCount; - destP->originalPts = (povertex_t*) Z_Malloc(destP->lineCount * sizeof(povertex_t), PU_MAP, 0); - destP->prevPts = (povertex_t*) Z_Malloc(destP->lineCount * sizeof(povertex_t), PU_MAP, 0); + destP->originalPts = (povertex_t *) Z_Malloc(destP->lineCount * sizeof(povertex_t), PU_MAP, 0); + destP->prevPts = (povertex_t *) Z_Malloc(destP->lineCount * sizeof(povertex_t), PU_MAP, 0); // Create a hedge for each line of this polyobj. // TODO: Polyobj has ownership, must free it. - hedges = new HEdge[destP->lineCount]; + HEdge *hedges = new HEdge[destP->lineCount]; - destP->lines = (LineDef**) Z_Malloc(sizeof(*destP->lines) * (destP->lineCount+1), PU_MAP, 0); - for(j = 0; j < destP->lineCount; ++j) + destP->lines = (LineDef **) Z_Malloc(sizeof(*destP->lines) * (destP->lineCount+1), PU_MAP, 0); + for(uint j = 0; j < destP->lineCount; ++j) { - LineDef* line = &dest->lineDefs[srcP->lines[j]->origIndex - 1]; - HEdge* hedge = &hedges[j]; + LineDef *line = &dest->lineDefs[srcP->lines[j]->origIndex - 1]; + HEdge *hedge = &hedges[j]; // This line belongs to a polyobj. line->inFlags |= LF_POLYOBJ; @@ -1180,13 +1178,13 @@ static void hardenPolyobjs(GameMap* dest, EditMap* src) hedge->length = V2d_Distance(line->v2Origin(), line->v1Origin()); hedge->twin = NULL; hedge->bspLeaf = NULL; - hedge->sector = line->L_frontsector; + hedge->sector = line->frontSectorPtr(); line->front().hedgeLeft = line->front().hedgeRight = hedge; destP->lines[j] = line; } - destP->lines[j] = NULL; // Terminate. + destP->lines[destP->lineCount] = NULL; // Terminate. // Add this polyobj to the global list. dest->polyObjs[i] = destP; @@ -1894,14 +1892,14 @@ uint MPE_LinedefCreate(uint v1, uint v2, uint frontSector, uint backSector, } l = createLine(); - l->_v[0] = vtx1; - l->_v[1] = vtx2; + l->_v[FROM] = vtx1; + l->_v[TO] = vtx2; - l->_v[0]->_buildData.refCount++; - l->_v[1]->_buildData.refCount++; + l->_v[FROM]->_buildData.refCount++; + l->_v[TO]->_buildData.refCount++; - l->L_frontsector = (frontSector == 0? NULL: e_map->sectors[frontSector-1]); - l->L_backsector = (backSector == 0? NULL: e_map->sectors[backSector-1]); + l->_sides[FRONT]._sector = (frontSector == 0? NULL: e_map->sectors[frontSector-1]); + l->_sides[BACK]._sector = (backSector == 0? NULL: e_map->sectors[backSector-1]); l->L_frontsidedef = front; l->L_backsidedef = back; diff --git a/doomsday/client/src/map/bsp/partitioner.cpp b/doomsday/client/src/map/bsp/partitioner.cpp index 4773aa978a..3cd8e4b350 100644 --- a/doomsday/client/src/map/bsp/partitioner.cpp +++ b/doomsday/client/src/map/bsp/partitioner.cpp @@ -305,7 +305,7 @@ struct Partitioner::Instance dist = fabs(dist); if(dist < DIST_EPSILON) return false; // Too close (overlapping lines ?) - hitSector = line->L_sector((p.testLine->direction[VY] > 0) ^ (line->direction[VY] > 0) ^ !isFront); + hitSector = line->sectorPtr((p.testLine->direction[VY] > 0) ^ (line->direction[VY] > 0) ^ !isFront); } else // Cast vertically. { @@ -320,7 +320,7 @@ struct Partitioner::Instance dist = fabs(dist); - hitSector = line->L_sector((p.testLine->direction[VX] > 0) ^ (line->direction[VX] > 0) ^ !isFront); + hitSector = line->sectorPtr((p.testLine->direction[VX] > 0) ^ (line->direction[VX] > 0) ^ !isFront); } if(dist < DIST_EPSILON) return false; // Too close (overlapping lines ?) @@ -373,7 +373,7 @@ struct Partitioner::Instance validCount++; GameMap_LineDefsBoxIterator(map, &scanRegion, testForWindowEffectWorker, &p); - if(p.backOpen && p.frontOpen && line->L_frontsector == p.backOpen) + if(p.backOpen && p.frontOpen && line->frontSectorPtr() == p.backOpen) { LOG_VERBOSE("LineDef #%d seems to be a One-Sided Window (back faces sector #%d).") << line->origIndex - 1 << p.backOpen->buildData.index - 1; @@ -435,7 +435,7 @@ struct Partitioner::Instance return right; } - inline HEdge* linkHEdgeInSuperBlockmap(SuperBlock& block, HEdge* hedge) + inline HEdge *linkHEdgeInSuperBlockmap(SuperBlock &block, HEdge *hedge) { DENG2_ASSERT(hedge); // Associate this half-edge with the final subblock. @@ -446,30 +446,30 @@ struct Partitioner::Instance /** * Initially create all half-edges and add them to specified SuperBlock. */ - void createInitialHEdges(SuperBlock& hedgeList) + void createInitialHEdges(SuperBlock &hedgeList) { DENG2_FOR_EACH(LineDefInfos, i, lineDefInfos) { LineDefInfo const& lineInfo = *i; - LineDef* line = lineInfo.lineDef; + LineDef *line = lineInfo.lineDef; // Polyobj lines are completely ignored. if(line->inFlags & LF_POLYOBJ) continue; - HEdge* front = 0; + HEdge *front = 0; coord_t angle = 0; if(!lineInfo.flags.testFlag(LineDefInfo::ZeroLength)) { - Sector* frontSec = line->L_frontsector; - Sector* backSec = 0; + Sector *frontSec = line->frontSectorPtr(); + Sector *backSec = 0; if(line->L_backsidedef) { - backSec = line->L_backsector; + backSec = line->backSectorPtr(); } else { // Handle the 'One-Sided Window' trick. - Sector* windowSec = lineInfo.windowEffect; + Sector *windowSec = lineInfo.windowEffect; if(windowSec) backSec = windowSec; } @@ -490,7 +490,7 @@ struct Partitioner::Instance } } - bool buildBsp(SuperBlock& rootBlock) + bool buildBsp(SuperBlock &rootBlock) { try { @@ -502,7 +502,7 @@ struct Partitioner::Instance windLeafs(); } - catch(de::Error& /*er*/) + catch(de::Error & /*er*/) { // Don't handle the error here, simply record failure. builtOK = false; @@ -1323,18 +1323,18 @@ struct Partitioner::Instance * * @return Newly created BspLeaf else @c NULL if degenerate. */ - BspLeaf* buildBspLeaf(HEdgeList const& hedges) + BspLeaf *buildBspLeaf(HEdgeList const &hedges) { if(!hedges.size()) return 0; // Collapse all degenerate and orphaned leafs. #if 0 - const bool isDegenerate = hedges.size() < 3; + bool const isDegenerate = hedges.size() < 3; bool isOrphan = true; DENG2_FOR_EACH_CONST(HEdgeList, it, hedges) { - const HEdge* hedge = *it; - if(hedge->lineDef && hedge->lineDef->L_sector(hedge->side)) + HEdge const *hedge = *it; + if(hedge->lineDef && hedge->lineDef->hasSector(hedge->side)) { isOrphan = false; break; @@ -1342,13 +1342,13 @@ struct Partitioner::Instance } #endif - BspLeaf* leaf = 0; + BspLeaf *leaf = 0; DENG2_FOR_EACH_CONST(HEdgeList, it, hedges) { - HEdge* hedge = *it; + HEdge *hedge = *it; #if 0 HEdgeInfos::iterator hInfoIt = hedgeInfos.find(hedge); - HEdgeInfo& hInfo = hInfoIt->second; + HEdgeInfo &hInfo = hInfoIt->second; if(isDegenerate || isOrphan) { @@ -1743,7 +1743,7 @@ struct Partitioner::Instance do { LineDef *line = hedge->lineDef; - Sector *sector = line? line->L_sector(hedge->side) : 0; + Sector *sector = line? line->sectorPtr(hedge->side) : 0; if(sector) { // The first sector from a non self-referencing line is our best choice. diff --git a/doomsday/client/src/map/dam_file.cpp b/doomsday/client/src/map/dam_file.cpp index b65de27545..5c755ad747 100644 --- a/doomsday/client/src/map/dam_file.cpp +++ b/doomsday/client/src/map/dam_file.cpp @@ -240,10 +240,10 @@ static void archiveVertexes(GameMap *map, boolean write) assertSegment(DAMSEG_END); } -static void writeLine(GameMap* map, uint idx) +static void writeLine(GameMap *map, uint idx) { int i; - LineDef* l = &map->lineDefs[idx]; + LineDef *l = &map->lineDefs[idx]; writeLong((long) (map->vertexes.indexOf(static_cast(l->_v[0])) + 1)); writeLong((long) (map->vertexes.indexOf(static_cast(l->_v[1])) + 1)); @@ -264,11 +264,13 @@ static void writeLine(GameMap* map, uint idx) for(i = 0; i < 2; ++i) { - writeLong(l->L_sector(i)? (GameMap_SectorIndex(map, static_cast(l->L_sector(i))) + 1) : 0); - writeLong(l->L_sidedef(i)? (GameMap_SideDefIndex(map, l->L_sidedef(i)) + 1) : 0); + LineDef::Side &side = l->side(i); + + writeLong(side._sector? (GameMap_SectorIndex(map, static_cast(side._sector)) + 1) : 0); + writeLong(side.sideDef? (GameMap_SideDefIndex(map, side.sideDef) + 1) : 0); - writeLong(l->side(i).hedgeLeft? (GameMap_HEdgeIndex(map, l->side(i).hedgeLeft) + 1) : 0); - writeLong(l->side(i).hedgeRight? (GameMap_HEdgeIndex(map, l->side(i).hedgeRight) + 1) : 0); + writeLong(side.hedgeLeft? (GameMap_HEdgeIndex(map, side.hedgeLeft) + 1) : 0); + writeLong(side.hedgeRight? (GameMap_HEdgeIndex(map, side.hedgeRight) + 1) : 0); } } @@ -297,19 +299,20 @@ static void readLine(GameMap* map, uint idx) for(i = 0; i < 2; ++i) { + LineDef::Side &side = l->side(i); long index; - index= readLong(); - l->L_sector(i) = (index? GameMap_Sector(map, index-1) : NULL); + index = readLong(); + side._sector = (index? GameMap_Sector(map, index-1) : NULL); index = readLong(); - l->L_sidedef(i) = (index? GameMap_SideDef(map, index-1) : NULL); + side.sideDef = (index? GameMap_SideDef(map, index-1) : NULL); index = readLong(); - l->side(i).hedgeLeft = (index? GameMap_HEdge(map, index-1) : NULL); + side.hedgeLeft = (index? GameMap_HEdge(map, index-1) : NULL); index = readLong(); - l->side(i).hedgeRight = (index? GameMap_HEdge(map, index-1) : NULL); + side.hedgeRight = (index? GameMap_HEdge(map, index-1) : NULL); } } diff --git a/doomsday/client/src/map/hedge.cpp b/doomsday/client/src/map/hedge.cpp index bf846b2627..18ce15f000 100644 --- a/doomsday/client/src/map/hedge.cpp +++ b/doomsday/client/src/map/hedge.cpp @@ -101,7 +101,7 @@ static void addWallDivNodesForPlaneIntercepts(HEdge const *hedge, walldivs_t *wa bool const isTwoSided = (hedge->lineDef && hedge->lineDef->L_frontsidedef && hedge->lineDef->L_backsidedef)? true:false; bool const clockwise = !doRight; LineDef const *line = hedge->lineDef; - Sector *frontSec = line->L_sector(hedge->side); + Sector const *frontSec = line->sectorPtr(hedge->side); // Check for neighborhood division? if(section == SS_MIDDLE && isTwoSided) return; @@ -141,10 +141,10 @@ static void addWallDivNodesForPlaneIntercepts(HEdge const *hedge, walldivs_t *wa do { // First front, then back. Sector *scanSec = NULL; - if(!i && iter->L_frontsidedef && iter->L_frontsector != frontSec) - scanSec = iter->L_frontsector; - else if(i && iter->L_backsidedef && iter->L_backsector != frontSec) - scanSec = iter->L_backsector; + if(!i && iter->L_frontsidedef && iter->frontSectorPtr() != frontSec) + scanSec = iter->frontSectorPtr(); + else if(i && iter->L_backsidedef && iter->backSectorPtr() != frontSec) + scanSec = iter->backSectorPtr(); if(scanSec) { diff --git a/doomsday/client/src/map/linedef.cpp b/doomsday/client/src/map/linedef.cpp index 2835d84e44..597a5e316a 100644 --- a/doomsday/client/src/map/linedef.cpp +++ b/doomsday/client/src/map/linedef.cpp @@ -30,6 +30,21 @@ using namespace de; +bool LineDef::Side::hasSector() const +{ + return !!_sector; +} + +Sector &LineDef::Side::sector() const +{ + if(_sector) + { + return *_sector; + } + /// @throw LineDef::MissingSectorError Attempted with no sector attributed. + throw LineDef::MissingSectorError("LineDef::Side::sector", "No sector is attributed"); +} + LineDef::LineDef() : MapElement(DMU_LINEDEF) { std::memset(_v, 0, sizeof(_v)); @@ -95,11 +110,11 @@ static bool backClosedForBlendNeighbor(LineDef const *lineDef, int side, { DENG_ASSERT(lineDef); - if(!lineDef->L_frontsidedef) return false; + if(!lineDef->L_frontsidedef) return false; if(!lineDef->L_backsidedef) return true; - Sector *frontSec = lineDef->L_sector(side); - Sector *backSec = lineDef->L_sector(side^1); + Sector const *frontSec = lineDef->sectorPtr(side); + Sector const *backSec = lineDef->sectorPtr(side^1); if(frontSec == backSec) return false; // Never. if(frontSec && backSec) @@ -118,9 +133,9 @@ static LineDef *findBlendNeighbor(LineDef const *l, byte side, byte right, LineOwner const *farVertOwner = l->L_vo(right^side); if(backClosedForBlendNeighbor(l, side, true/*ignore opacity*/)) { - return R_FindSolidLineNeighbor(l->L_sector(side), l, farVertOwner, right, diff); + return R_FindSolidLineNeighbor(l->sectorPtr(side), l, farVertOwner, right, diff); } - return R_FindLineNeighbor(l->L_sector(side), l, farVertOwner, right, diff); + return R_FindLineNeighbor(l->sectorPtr(side), l, farVertOwner, right, diff); } #endif // __CLIENT__ @@ -181,12 +196,12 @@ void LineDef::configureDivline(divline_t &dl) const coord_t LineDef::openRange(int side_, coord_t *retBottom, coord_t *retTop) const { - return R_OpenRange(side(side_).sector, side(side_^1).sector, retBottom, retTop); + return R_OpenRange(side(side_).sectorPtr(), side(side_^1).sectorPtr(), retBottom, retTop); } coord_t LineDef::visOpenRange(int side_, coord_t *retBottom, coord_t *retTop) const { - return R_VisOpenRange(side(side_).sector, side(side_^1).sector, retBottom, retTop); + return R_VisOpenRange(side(side_).sectorPtr(), side(side_^1).sectorPtr(), retBottom, retTop); } void LineDef::configureTraceOpening(TraceOpening &opening) const @@ -203,16 +218,16 @@ void LineDef::configureTraceOpening(TraceOpening &opening) const opening.top = float( top ); // Determine the "low floor". - Sector *front = L_frontsector; - Sector *back = L_backsector; + Sector const &fsec = frontSector(); + Sector const &bsec = backSector(); - if(front->SP_floorheight > back->SP_floorheight) + if(fsec.SP_floorheight > bsec.SP_floorheight) { - opening.lowFloor = float( back->SP_floorheight ); + opening.lowFloor = float( bsec.SP_floorheight ); } else { - opening.lowFloor = float( front->SP_floorheight ); + opening.lowFloor = float( fsec.SP_floorheight ); } } @@ -355,11 +370,11 @@ int LineDef::property(setargs_t &args) const DMU_GetValue(DMT_LINEDEF_SLOPETYPE, &slopeType, &args, 0); break; case DMU_FRONT_SECTOR: { - Sector *sec = (L_frontsidedef? L_frontsector : NULL); + Sector *sec = (_sides[FRONT].sideDef? _sides[FRONT]._sector : NULL); DMU_GetValue(DMT_LINEDEF_SECTOR, &sec, &args, 0); break; } case DMU_BACK_SECTOR: { - Sector *sec = (L_backsidedef? L_backsector : NULL); + Sector *sec = (_sides[BACK].sideDef? _sides[BACK]._sector : NULL); DMU_GetValue(DMT_LINEDEF_SECTOR, &sec, &args, 0); break; } case DMU_FLAGS: @@ -401,10 +416,10 @@ int LineDef::setProperty(setargs_t const &args) switch(args.prop) { case DMU_FRONT_SECTOR: - DMU_SetValue(DMT_LINEDEF_SECTOR, &L_frontsector, &args, 0); + DMU_SetValue(DMT_LINEDEF_SECTOR, &_sides[FRONT]._sector, &args, 0); break; case DMU_BACK_SECTOR: - DMU_SetValue(DMT_LINEDEF_SECTOR, &L_backsector, &args, 0); + DMU_SetValue(DMT_LINEDEF_SECTOR, &_sides[BACK]._sector, &args, 0); break; case DMU_SIDEDEF0: DMU_SetValue(DMT_LINEDEF_SIDEDEF, &L_frontsidedef, &args, 0); diff --git a/doomsday/client/src/map/p_dmu.cpp b/doomsday/client/src/map/p_dmu.cpp index 8c336605ec..80a3eff33d 100644 --- a/doomsday/client/src/map/p_dmu.cpp +++ b/doomsday/client/src/map/p_dmu.cpp @@ -1088,8 +1088,8 @@ static int setProperty(void *ptr, void *context) { if(R_UpdateLinedef(updateLinedef, false)) { - updateSector1 = updateLinedef->L_frontsector; - updateSector2 = updateLinedef->L_backsector; + updateSector1 = updateLinedef->frontSectorPtr(); + updateSector2 = updateLinedef->backSectorPtr(); } } diff --git a/doomsday/client/src/map/p_maputil.cpp b/doomsday/client/src/map/p_maputil.cpp index 5a34b830ea..89cb67cc85 100644 --- a/doomsday/client/src/map/p_maputil.cpp +++ b/doomsday/client/src/map/p_maputil.cpp @@ -422,7 +422,7 @@ int GameMap_MobjSectorsIterator(GameMap *map, mobj_t *mo, LineDef *ld = (LineDef *) tn[nix].ptr; // All these lines are two-sided. Try front side. - Sector &frontSec = *ld->L_frontsector; + Sector &frontSec = ld->frontSector(); if(frontSec.validCount != validCount) { *end++ = &frontSec; @@ -432,7 +432,7 @@ int GameMap_MobjSectorsIterator(GameMap *map, mobj_t *mo, // And then the back side. if(ld->L_backsidedef) { - Sector &backSec = *ld->L_backsector; + Sector &backSec = ld->backSector(); if(backSec.validCount != validCount) { *end++ = &backSec; diff --git a/doomsday/client/src/map/p_particle.cpp b/doomsday/client/src/map/p_particle.cpp index e52c3c80f9..d873fe56a2 100644 --- a/doomsday/client/src/map/p_particle.cpp +++ b/doomsday/client/src/map/p_particle.cpp @@ -781,8 +781,8 @@ int PIT_CheckLinePtc(LineDef *ld, void *parameters) ptcHitLine = ld; if(!ld->L_backsidedef) return true; // Boing! - Sector *front = ld->L_frontsector; - Sector *back = ld->L_backsector; + Sector *front = ld->frontSectorPtr(); + Sector *back = ld->backSectorPtr(); // Determine the opening we have here. /// @todo Use LineDef::openRange() @@ -1070,8 +1070,8 @@ static void P_MoveParticle(ptcgen_t *gen, particle_t *pt) // particle should be killed (if it's moving slowly at max). if(pt->contact) { - Sector *front = (pt->contact->L_frontsidedef? pt->contact->L_frontsector : NULL); - Sector *back = (pt->contact->L_backsidedef? pt->contact->L_backsector : NULL); + Sector *front = (pt->contact->L_frontsidedef? pt->contact->frontSectorPtr() : NULL); + Sector *back = (pt->contact->L_backsidedef? pt->contact->backSectorPtr() : NULL); if(front && back && abs(pt->mov[VZ]) < FRACUNIT / 2) { diff --git a/doomsday/client/src/map/p_sight.cpp b/doomsday/client/src/map/p_sight.cpp index c3e736e93f..8cdbfc90e7 100644 --- a/doomsday/client/src/map/p_sight.cpp +++ b/doomsday/client/src/map/p_sight.cpp @@ -73,29 +73,24 @@ static boolean interceptLineDef(LineDef const *li, losdata_t *los, divline_t *dl return true; // Crossed. } -static boolean crossLineDef(const LineDef* li, byte side, losdata_t* los) +static boolean crossLineDef(LineDef const *li, byte side, losdata_t *los) { #define RTOP 0x1 #define RBOTTOM 0x2 - float frac; - byte ranges = 0; divline_t dl; - const Sector* fsec, *bsec; - boolean noBack; - if(!interceptLineDef(li, los, &dl)) return true; // Ray does not intercept hedge on the X/Y plane. if(!li->L_sidedef(side)) return true; // HEdge is on the back side of a one-sided window. - if(!li->L_sector(side)) /*$degenleaf*/ + if(!li->hasSector(side)) /*$degenleaf*/ return false; - fsec = li->L_sector(side); - bsec = (li->L_backsidedef? li->L_sector(side^1) : NULL); - noBack = (li->L_backsidedef? false : true); + Sector const *fsec = li->sectorPtr(side); + Sector const *bsec = (li->L_backsidedef? li->sectorPtr(side^1) : NULL); + boolean noBack = (li->L_backsidedef? false : true); if(!noBack && !(los->flags & LS_PASSLEFT) && (!(bsec->SP_floorheight < fsec->SP_ceilheight) || @@ -114,6 +109,7 @@ static boolean crossLineDef(const LineDef* li, byte side, losdata_t* los) } // Handle the case of a zero height backside in the top range. + byte ranges = 0; if(noBack) { ranges |= RTOP; @@ -129,7 +125,7 @@ static boolean crossLineDef(const LineDef* li, byte side, losdata_t* los) if(!ranges) return true; - frac = FIX2FLT(Divline_Intersection(&dl, &los->trace)); + float frac = FIX2FLT(Divline_Intersection(&dl, &los->trace)); if((los->flags & LS_PASSOVER) && los->bottomSlope > (fsec->SP_ceilheight - los->startZ) / frac) diff --git a/doomsday/client/src/map/r_world.cpp b/doomsday/client/src/map/r_world.cpp index ee857ed201..621193b683 100644 --- a/doomsday/client/src/map/r_world.cpp +++ b/doomsday/client/src/map/r_world.cpp @@ -421,7 +421,7 @@ void GameMap_UpdateSkyFixForSector(GameMap *map, Sector *sec) // Must be twosided. if(li->L_frontsidedef && li->L_backsidedef) { - SideDef *si = li->L_frontsector == sec? li->L_frontsidedef : li->L_backsidedef; + SideDef *si = li->frontSectorPtr() == sec? li->L_frontsidedef : li->L_backsidedef; if(si->SW_middlematerial) { @@ -502,13 +502,13 @@ DENG_EXTERN_C void R_SetupFogDefaults() void R_OrderVertices(LineDef *line, Sector const *sector, Vertex *verts[2]) { - byte edge = (sector == line->L_frontsector? 0:1); + byte edge = (sector == line->frontSectorPtr()? 0:1); verts[0] = &line->vertex(edge); verts[1] = &line->vertex(edge^1); } boolean R_FindBottomTop2(SideDefSection section, int lineFlags, - Sector *frontSec, Sector *backSec, SideDef *frontDef, SideDef *backDef, + const Sector *frontSec, const Sector *backSec, const SideDef *frontDef, const SideDef *backDef, coord_t *low, coord_t *hi, float matOffset[2]) { bool const unpegBottom = !!(lineFlags & DDLF_DONTPEGBOTTOM); @@ -522,9 +522,9 @@ boolean R_FindBottomTop2(SideDefSection section, int lineFlags, if(matOffset) { - Surface *suf = &frontDef->SW_middlesurface; - matOffset[0] = suf->visOffset[0]; - matOffset[1] = suf->visOffset[1]; + Surface const &suf = frontDef->SW_middlesurface; + matOffset[0] = suf.visOffset[0]; + matOffset[1] = suf.visOffset[1]; if(unpegBottom) { matOffset[1] -= *hi - *low; @@ -534,11 +534,11 @@ boolean R_FindBottomTop2(SideDefSection section, int lineFlags, else { boolean const stretchMiddle = !!(frontDef->flags & SDF_MIDDLE_STRETCH); - Plane *ffloor = &frontSec->floor(); - Plane *fceil = &frontSec->ceiling(); - Plane *bfloor = &backSec->floor(); - Plane *bceil = &backSec->ceiling(); - Surface *suf = &frontDef->SW_surface(section); + Plane const *ffloor = &frontSec->floor(); + Plane const *fceil = &frontSec->ceiling(); + Plane const *bfloor = &backSec->floor(); + Plane const *bceil = &backSec->ceiling(); + Surface const *suf = &frontDef->SW_surface(section); switch(section) { @@ -659,7 +659,7 @@ boolean R_FindBottomTop2(SideDefSection section, int lineFlags, } boolean R_FindBottomTop(SideDefSection section, int lineFlags, - Sector *frontSec, Sector *backSec, SideDef *frontDef, SideDef *backDef, + const Sector *frontSec, const Sector *backSec, const SideDef *frontDef, const SideDef *backDef, coord_t *low, coord_t *hi) { return R_FindBottomTop2(section, lineFlags, frontSec, backSec, frontDef, backDef, @@ -727,8 +727,9 @@ coord_t R_VisOpenRange(Sector const *frontSec, Sector const *backSec, coord_t *r } #ifdef __CLIENT__ -boolean R_MiddleMaterialCoversOpening(int lineFlags, Sector *frontSec, Sector *backSec, - SideDef *frontDef, SideDef *backDef, boolean ignoreOpacity) +boolean R_MiddleMaterialCoversOpening(int lineFlags, Sector const *frontSec, + Sector const *backSec, SideDef const *frontDef, SideDef const *backDef, + boolean ignoreOpacity) { if(!frontSec || !frontDef) return false; // Never. @@ -765,10 +766,10 @@ boolean R_MiddleMaterialCoversOpening(int lineFlags, Sector *frontSec, Sector *b boolean R_MiddleMaterialCoversLineOpening(LineDef const *line, int side, boolean ignoreOpacity) { DENG_ASSERT(line); - Sector *frontSec = line->L_sector(side); - Sector *backSec = line->L_sector(side ^ 1); - SideDef *frontDef = line->L_sidedef(side); - SideDef *backDef = line->L_sidedef(side ^ 1); + Sector const *frontSec = line->sectorPtr(side); + Sector const *backSec = line->sectorPtr(side ^ 1); + SideDef const *frontDef = line->L_sidedef(side); + SideDef const *backDef = line->L_sidedef(side ^ 1); return R_MiddleMaterialCoversOpening(line->flags, frontSec, backSec, frontDef, backDef, ignoreOpacity); } @@ -783,12 +784,12 @@ LineDef *R_FindLineNeighbor(Sector const *sector, LineDef const *line, if(diff) *diff += (antiClockwise? cown->angle() : own->angle()); - if(!other->L_backsidedef || other->L_frontsector != other->L_backsector) + if(!other->L_backsidedef || other->frontSectorPtr() != other->backSectorPtr()) { if(sector) // Must one of the sectors match? { - if(other->L_frontsector == sector || - (other->L_backsidedef && other->L_backsector == sector)) + if(other->frontSectorPtr() == sector || + (other->L_backsidedef && other->backSectorPtr() == sector)) return other; } else @@ -812,30 +813,30 @@ LineDef *R_FindSolidLineNeighbor(Sector const *sector, LineDef const *line, if(diff) *diff += (antiClockwise? cown->angle() : own->angle()); - if(!((other->inFlags & LF_BSPWINDOW) && other->L_frontsector != sector)) + if(!((other->inFlags & LF_BSPWINDOW) && other->frontSectorPtr() != sector)) { if(!other->L_frontsidedef || !other->L_backsidedef) return other; if(!other->isSelfReferencing() && - (other->L_frontsector->SP_floorvisheight >= sector->SP_ceilvisheight || - other->L_frontsector->SP_ceilvisheight <= sector->SP_floorvisheight || - other->L_backsector->SP_floorvisheight >= sector->SP_ceilvisheight || - other->L_backsector->SP_ceilvisheight <= sector->SP_floorvisheight || - other->L_backsector->SP_ceilvisheight <= other->L_backsector->SP_floorvisheight)) + (other->frontSector().SP_floorvisheight >= sector->SP_ceilvisheight || + other->frontSector().SP_ceilvisheight <= sector->SP_floorvisheight || + other->backSector().SP_floorvisheight >= sector->SP_ceilvisheight || + other->backSector().SP_ceilvisheight <= sector->SP_floorvisheight || + other->backSector().SP_ceilvisheight <= other->backSector().SP_floorvisheight)) return other; // Both front and back MUST be open by this point. // Check for mid texture which fills the gap between floor and ceiling. // We should not give away the location of false walls (secrets). - side = (other->L_frontsector == sector? 0 : 1); + side = (other->frontSectorPtr() == sector? 0 : 1); if(other->L_sidedef(side)->SW_middlematerial) { - float oFCeil = other->L_frontsector->SP_ceilvisheight; - float oFFloor = other->L_frontsector->SP_floorvisheight; - float oBCeil = other->L_backsector->SP_ceilvisheight; - float oBFloor = other->L_backsector->SP_floorvisheight; + float oFCeil = other->frontSector().SP_ceilvisheight; + float oFFloor = other->frontSector().SP_floorvisheight; + float oBCeil = other->backSector().SP_ceilvisheight; + float oBFloor = other->backSector().SP_floorvisheight; if((side == 0 && ((oBCeil > sector->SP_floorvisheight && @@ -873,11 +874,11 @@ LineDef *R_FindLineBackNeighbor(Sector const *sector, LineDef const *line, if(diff) *diff += (antiClockwise? cown->angle() : own->angle()); - if(!other->L_backsidedef || other->L_frontsector != other->L_backsector || + if(!other->L_backsidedef || other->frontSectorPtr() != other->backSectorPtr() || (other->inFlags & LF_BSPWINDOW)) { - if(!(other->L_frontsector == sector || - (other->L_backsidedef && other->L_backsector == sector))) + if(!(other->frontSectorPtr() == sector || + (other->L_backsidedef && other->backSectorPtr() == sector))) return other; } @@ -903,7 +904,7 @@ LineDef *R_FindLineAlignNeighbor(Sector const *sec, LineDef const *line, if(alignment < 0) diff -= BANG_180; - if(other->L_frontsector != sec) + if(other->frontSectorPtr() != sec) diff -= BANG_180; if(diff < SEP || diff > BANG_360 - SEP) return other; @@ -1220,8 +1221,8 @@ static Material *chooseFixMaterial(SideDef *s, SideDefSection section) Material *choice1 = 0, *choice2 = 0; LineDef *line = s->line; byte side = (line->L_frontsidedef == s? FRONT : BACK); - Sector *frontSec = line->L_sector(side); - Sector *backSec = line->L_sidedef(side ^ 1)? line->L_sector(side ^ 1) : 0; + Sector *frontSec = line->sectorPtr(side); + Sector *backSec = line->L_sidedef(side ^ 1)? line->sectorPtr(side ^ 1) : 0; if(backSec) { @@ -1269,16 +1270,17 @@ static Material *chooseFixMaterial(SideDef *s, SideDefSection section) else { // Compare the relative heights to decide. - SideDef *otherSide = other->L_sidedef(other->L_frontsector == frontSec? FRONT : BACK); - Sector *otherSec = other->L_sector(other->L_frontsector == frontSec? BACK : FRONT); - if(otherSec->SP_ceilheight <= frontSec->SP_floorheight) - choice1 = otherSide->SW_topmaterial; - else if(otherSec->SP_floorheight >= frontSec->SP_ceilheight) - choice1 = otherSide->SW_bottommaterial; - else if(otherSec->SP_ceilheight < frontSec->SP_ceilheight) - choice1 = otherSide->SW_topmaterial; - else if(otherSec->SP_floorheight > frontSec->SP_floorheight) - choice1 = otherSide->SW_bottommaterial; + SideDef &otherSide = *other->L_sidedef(&other->frontSector() == frontSec? FRONT : BACK); + Sector &otherSec = other->sector(&other->frontSector() == frontSec? BACK : FRONT); + + if(otherSec.SP_ceilheight <= frontSec->SP_floorheight) + choice1 = otherSide.SW_topmaterial; + else if(otherSec.SP_floorheight >= frontSec->SP_ceilheight) + choice1 = otherSide.SW_bottommaterial; + else if(otherSec.SP_ceilheight < frontSec->SP_ceilheight) + choice1 = otherSide.SW_topmaterial; + else if(otherSec.SP_floorheight > frontSec->SP_floorheight) + choice1 = otherSide.SW_bottommaterial; // else we'll settle for a plane material. } } @@ -1342,8 +1344,8 @@ static void R_UpdateLinedefsOfSector(Sector *sec) SideDef *front = li->L_frontsidedef; SideDef *back = li->L_backsidedef; - Sector *frontSec = li->L_frontsector; - Sector *backSec = li->L_backsector; + Sector *frontSec = li->frontSectorPtr(); + Sector *backSec = li->backSectorPtr(); // Do not fix "windows". if(!front || (!back && backSec)) continue; diff --git a/doomsday/client/src/map/sidedef.cpp b/doomsday/client/src/map/sidedef.cpp index 44015b77e7..a27bb44f95 100644 --- a/doomsday/client/src/map/sidedef.cpp +++ b/doomsday/client/src/map/sidedef.cpp @@ -75,7 +75,7 @@ int SideDef::property(setargs_t &args) const switch(args.prop) { case DMU_SECTOR: { - Sector *sector = line->L_sector(this == line->L_frontsidedef? FRONT : BACK); + Sector *sector = line->sectorPtr(this == line->L_frontsidedef? FRONT : BACK); DMU_GetValue(DMT_SIDEDEF_SECTOR, §or, &args, 0); break; } case DMU_LINEDEF: diff --git a/doomsday/client/src/map/surface.cpp b/doomsday/client/src/map/surface.cpp index 99b32afc39..855f4299c0 100644 --- a/doomsday/client/src/map/surface.cpp +++ b/doomsday/client/src/map/surface.cpp @@ -298,7 +298,7 @@ void Surface::updateBaseOrigin() base.origin[VX] = (line->v1Origin()[VX] + line->v2Origin()[VX]) / 2; base.origin[VY] = (line->v1Origin()[VY] + line->v2Origin()[VY]) / 2; - Sector *sec = line->L_sector(side == line->L_frontsidedef? FRONT:BACK); + Sector *sec = line->sectorPtr(side == line->L_frontsidedef? FRONT:BACK); if(sec) { coord_t const ffloor = sec->SP_floorheight; @@ -309,26 +309,26 @@ void Surface::updateBaseOrigin() if(!line->L_backsidedef || line->isSelfReferencing()) base.origin[VZ] = (ffloor + fceil) / 2; else - base.origin[VZ] = (MAX_OF(ffloor, line->L_backsector->SP_floorheight) + - MIN_OF(fceil, line->L_backsector->SP_ceilheight)) / 2; + base.origin[VZ] = (MAX_OF(ffloor, line->backSector().SP_floorheight) + + MIN_OF(fceil, line->backSector().SP_ceilheight)) / 2; break; } else if(this == &side->SW_bottomsurface) { if(!line->L_backsidedef || line->isSelfReferencing() || - line->L_backsector->SP_floorheight <= ffloor) + line->backSector().SP_floorheight <= ffloor) base.origin[VZ] = ffloor; else - base.origin[VZ] = (MIN_OF(line->L_backsector->SP_floorheight, fceil) + ffloor) / 2; + base.origin[VZ] = (MIN_OF(line->backSector().SP_floorheight, fceil) + ffloor) / 2; break; } else if(this == &side->SW_topsurface) { if(!line->L_backsidedef || line->isSelfReferencing() || - line->L_backsector->SP_ceilheight >= fceil) + line->backSector().SP_ceilheight >= fceil) base.origin[VZ] = fceil; else - base.origin[VZ] = (MAX_OF(line->L_backsector->SP_ceilheight, ffloor) + fceil) / 2; + base.origin[VZ] = (MAX_OF(line->backSector().SP_ceilheight, ffloor) + fceil) / 2; break; } } diff --git a/doomsday/client/src/render/r_fakeradio.cpp b/doomsday/client/src/render/r_fakeradio.cpp index f757d8e002..1330cc4e90 100644 --- a/doomsday/client/src/render/r_fakeradio.cpp +++ b/doomsday/client/src/render/r_fakeradio.cpp @@ -232,7 +232,7 @@ void Rend_RadioInitForMap() for(uint j = 0; j < 2; ++j) { - if(!line->L_sector(j) || !line->L_sidedef(j)) continue; + if(!line->hasSector(j) || !line->L_sidedef(j)) continue; Vertex &vtx0 = line->vertex(j); Vertex &vtx1 = line->vertex(j^1); @@ -255,7 +255,7 @@ void Rend_RadioInitForMap() data.lineDef = line; data.side = j; - P_BspLeafsBoxIterator(&bounds, static_cast(line->L_sector(j)), + P_BspLeafsBoxIterator(&bounds, line->sectorPtr(j), RIT_ShadowBspLeafLinker, &data); } } diff --git a/doomsday/client/src/render/rend_decor.cpp b/doomsday/client/src/render/rend_decor.cpp index 92118e6ea4..65c49a785a 100644 --- a/doomsday/client/src/render/rend_decor.cpp +++ b/doomsday/client/src/render/rend_decor.cpp @@ -468,8 +468,8 @@ static void plotSourcesForLineDef(LineDef &line, byte side, SideDefSection secti { if(!line.L_sidedef(side)) return; - Sector *frontSec = line.L_sector(side); - Sector *backSec = line.L_sector(side ^ 1); + Sector *frontSec = line.sectorPtr(side); + Sector *backSec = line.sectorPtr(side ^ 1); SideDef *frontDef = line.L_sidedef(side); SideDef *backDef = line.L_sidedef(side ^ 1); Surface &suf = line.L_sidedef(side)->SW_surface(section); diff --git a/doomsday/client/src/render/rend_fakeradio.cpp b/doomsday/client/src/render/rend_fakeradio.cpp index 2e73872bc0..31e1291c30 100644 --- a/doomsday/client/src/render/rend_fakeradio.cpp +++ b/doomsday/client/src/render/rend_fakeradio.cpp @@ -82,7 +82,7 @@ void Rend_RadioUpdateLinedef(LineDef *line, boolean backSide) if(!devFakeRadioUpdate) return; // Sides without sectors don't need updating. $degenleaf - if(!line || !line->L_sector(backSide)) return; + if(!line || !line->hasSector(backSide)) return; // Have already determined the shadow properties on this side? SideDef *s = line->L_sidedef(backSide); @@ -116,7 +116,7 @@ static void setRendpolyColor(ColorRawf *rcolors, uint num, float const shadowRGB } /// @return @c true, if there is open space in the sector. -static inline boolean isSectorOpen(Sector *sector) +static inline boolean isSectorOpen(Sector const *sector) { return (sector && sector->SP_ceilheight > sector->SP_floorheight); } @@ -156,15 +156,15 @@ static void scanNeighbor(boolean scanTop, LineDef const *line, uint side, coord_t iFFloor, iFCeil; coord_t iBFloor, iBCeil; int scanSecSide = side; - Sector *startSector = line->L_sector(side); - Sector *scanSector; + Sector const *startSector = line->sectorPtr(side); + Sector const *scanSector; boolean clockwise = toLeft; boolean stopScan = false; boolean closed; coord_t fCeil, fFloor; - fFloor = line->L_sector(side)->SP_floorvisheight; - fCeil = line->L_sector(side)->SP_ceilvisheight; + fFloor = startSector->SP_floorvisheight; + fCeil = startSector->SP_ceilvisheight; // Retrieve the start owner node. own = R_GetVtxLineOwner(&line->vertex(side^!toLeft), line); @@ -175,35 +175,35 @@ static void scanNeighbor(boolean scanTop, LineDef const *line, uint side, diff = (clockwise? own->angle() : own->prev().angle()); iter = &own->_link[clockwise]->lineDef(); - scanSecSide = (iter->L_frontsector && iter->L_frontsector == startSector); + scanSecSide = (iter->hasFrontSector() && iter->frontSectorPtr() == startSector); // Step over selfreferencing lines. - while((!iter->L_frontsector && !iter->L_backsector) || // $degenleaf + while((!iter->hasFrontSector() && !iter->hasBackSector()) || // $degenleaf iter->isSelfReferencing()) { own = own->_link[clockwise]; diff += (clockwise? own->angle() : own->prev().angle()); iter = &own->_link[clockwise]->lineDef(); - scanSecSide = (iter->L_frontsector == startSector); + scanSecSide = (iter->frontSectorPtr() == startSector); } // Determine the relative backsector. if(iter->L_sidedef(scanSecSide)) - scanSector = iter->L_sector(scanSecSide); + scanSector = iter->sectorPtr(scanSecSide); else scanSector = NULL; // Pick plane heights for relative offset comparison. if(!stopScan) { - iFFloor = iter->L_frontsector->SP_floorvisheight; - iFCeil = iter->L_frontsector->SP_ceilvisheight; + iFFloor = iter->frontSector().SP_floorvisheight; + iFCeil = iter->frontSector().SP_ceilvisheight; if(iter->L_backsidedef) { - iBFloor = iter->L_backsector->SP_floorvisheight; - iBCeil = iter->L_backsector->SP_ceilvisheight; + iBFloor = iter->backSector().SP_floorvisheight; + iBCeil = iter->backSector().SP_ceilvisheight; } else iBFloor = iBCeil = 0; @@ -216,7 +216,7 @@ static void scanNeighbor(boolean scanTop, LineDef const *line, uint side, // Store identity for later use. edge->diff = diff; edge->line = iter; - edge->sector = scanSector; + edge->sector = const_cast(scanSector); closed = false; if(side == 0 && iter->L_backsidedef) @@ -238,13 +238,13 @@ static void scanNeighbor(boolean scanTop, LineDef const *line, uint side, if(scanTop) { if(iter->L_backsidedef && - ((side == 0 && iter->L_backsector == line->L_frontsector && + ((side == 0 && iter->backSectorPtr() == line->frontSectorPtr() && iFCeil >= fCeil) || - (side == 1 && iter->L_backsector == line->L_backsector && + (side == 1 && iter->backSectorPtr() == line->backSectorPtr() && iFCeil >= fCeil) || - (side == 0 && closed == false && iter->L_backsector != line->L_frontsector && + (side == 0 && closed == false && iter->backSectorPtr() != line->frontSectorPtr() && iBCeil >= fCeil && - isSectorOpen(iter->L_backsector)))) + isSectorOpen(iter->backSectorPtr())))) { gap += iter->length; // Should we just mark it done instead? } @@ -257,13 +257,13 @@ static void scanNeighbor(boolean scanTop, LineDef const *line, uint side, else { if(iter->L_backsidedef && - ((side == 0 && iter->L_backsector == line->L_frontsector && + ((side == 0 && iter->backSectorPtr() == line->frontSectorPtr() && iFFloor <= fFloor) || - (side == 1 && iter->L_backsector == line->L_backsector && + (side == 1 && iter->backSectorPtr() == line->backSectorPtr() && iFFloor <= fFloor) || - (side == 0 && closed == false && iter->L_backsector != line->L_frontsector && + (side == 0 && closed == false && iter->backSectorPtr() != line->frontSectorPtr() && iBFloor <= fFloor && - isSectorOpen(iter->L_backsector)))) + isSectorOpen(iter->backSectorPtr())))) { gap += iter->length; // Should we just mark it done instead? } @@ -325,7 +325,7 @@ static void scanNeighbor(boolean scanTop, LineDef const *line, uint side, // Skip into the back neighbor sector of the iter line if // heights are within accepted range. if(scanSector && line->L_sidedef(side^1) && - scanSector != line->L_sector(side^1) && + scanSector != line->sectorPtr(side^1) && ((scanTop && scanSector->SP_ceilvisheight == startSector->SP_ceilvisheight) || (!scanTop && scanSector->SP_floorvisheight == @@ -359,7 +359,7 @@ static void scanNeighbor(boolean scanTop, LineDef const *line, uint side, // get the next neighbor (it IS the backneighbor). edge->line = R_FindLineNeighbor(edge->sector, edge->line, - edge->line->vo[(edge->line->L_backsidedef && edge->line->L_backsector == edge->sector)^!toLeft], + edge->line->vo[(edge->line->L_backsidedef && edge->line->backSectorPtr() == edge->sector)^!toLeft], !toLeft, &edge->diff); } } @@ -369,8 +369,8 @@ static void scanNeighbors(shadowcorner_t top[2], shadowcorner_t bottom[2], { if(line->isSelfReferencing()) return; - coord_t fFloor = line->L_sector(side)->SP_floorvisheight; - coord_t fCeil = line->L_sector(side)->SP_ceilvisheight; + coord_t fFloor = line->sector(side).SP_floorvisheight; + coord_t fCeil = line->sector(side).SP_ceilvisheight; edge_t edges[2]; // {bottom, top} std::memset(edges, 0, sizeof(edges)); @@ -474,7 +474,7 @@ static void scanEdges(shadowcorner_t topCorners[2], shadowcorner_t bottomCorners binangle_t diff = 0; LineOwner* vo = line->L_vo(i ^ sid); - LineDef* other = R_FindSolidLineNeighbor(line->L_sector(sid), line, vo, i, &diff); + LineDef* other = R_FindSolidLineNeighbor(line->sectorPtr(sid), line, vo, i, &diff); if(other && other != line) { if(diff > BANG_180) @@ -1307,11 +1307,11 @@ static void processEdgeShadow(BspLeaf const *bspLeaf, LineDef const *lineDef, { DENG_ASSERT(bspLeaf); DENG_ASSERT(lineDef && (side == FRONT || side == BACK) && lineDef->L_sidedef(side)); - DENG_ASSERT(planeId < lineDef->L_sector(side)->planeCount()); + DENG_ASSERT(planeId < lineDef->sector(side).planeCount()); if(!(shadowDark > .0001)) return; - Plane const *pln = lineDef->L_sector(side)->SP_plane(planeId); + Plane const *pln = lineDef->sector(side).SP_plane(planeId); Surface const *suf = &pln->surface(); coord_t plnHeight = pln->visHeight(); @@ -1324,12 +1324,13 @@ static void processEdgeShadow(BspLeaf const *bspLeaf, LineDef const *lineDef, // changes in the polygon corner vertices (placement, colour). vec2d_t inner[2], outer[2]; vec2f_t edgeOpen, sideOpen; - Sector *front = 0, *back = 0; + Sector const *front = 0; + Sector const *back = 0; coord_t fz = 0, bz = 0, bhz = 0; if(lineDef->L_backsidedef) { - front = lineDef->L_sector(side); - back = lineDef->L_sector(side ^ 1); + front = lineDef->sectorPtr(side); + back = lineDef->sectorPtr(side ^ 1); setRelativeHeights(front, back, planeId == Plane::Ceiling, &fz, &bz, &bhz); uint hackType = radioEdgeHackType(lineDef, front, back, side, planeId == Plane::Ceiling, fz, bz); @@ -1359,7 +1360,7 @@ static void processEdgeShadow(BspLeaf const *bspLeaf, LineDef const *lineDef, if(neighbor != lineDef && !neighbor->L_backsidedef && (neighbor->inFlags & LF_BSPWINDOW) && - neighbor->L_frontsector != bspLeaf->sectorPtr()) + neighbor->frontSectorPtr() != bspLeaf->sectorPtr()) { // A one-way window, edgeOpen side. sideOpen[i] = 1; @@ -1367,7 +1368,7 @@ static void processEdgeShadow(BspLeaf const *bspLeaf, LineDef const *lineDef, else if(!(neighbor == lineDef || !neighbor->L_backsidedef)) { byte otherSide = (&lineDef->vertex(i^side) == &neighbor->v1()? i : i^1); - Sector *othersec = neighbor->L_sector(otherSide); + Sector *othersec = neighbor->sectorPtr(otherSide); if(R_MiddleMaterialCoversLineOpening(neighbor, otherSide^1, false)) { @@ -1380,12 +1381,12 @@ static void processEdgeShadow(BspLeaf const *bspLeaf, LineDef const *lineDef, else { // Its a normal neighbor. - if(neighbor->L_sector(otherSide) != lineDef->L_sector(side) && + if(neighbor->sectorPtr(otherSide) != lineDef->sectorPtr(side) && !((pln->type() == Plane::Floor && othersec->SP_ceilvisheight <= pln->visHeight()) || (pln->type() == Plane::Ceiling && othersec->SP_floorheight >= pln->visHeight()))) { - front = lineDef->L_sector(side); - back = neighbor->L_sector(otherSide); + front = lineDef->sectorPtr(side); + back = neighbor->sectorPtr(otherSide); setRelativeHeights(front, back, planeId == Plane::Ceiling, &fz, &bz, &bhz); sideOpen[i] = radioEdgeOpenness(fz, bz, bhz); @@ -1605,7 +1606,7 @@ void Rend_DrawShadowOffsetVerts() do { coord_t pos[3]; - pos[VZ] = own->lineDef().L_frontsector->SP_floorvisheight; + pos[VZ] = own->lineDef().frontSector().SP_floorvisheight; V2d_Sum(pos, vtx.origin(), own->extendedShadowOffset()); drawPoint(pos, 1, yellow); diff --git a/doomsday/client/src/render/rend_main.cpp b/doomsday/client/src/render/rend_main.cpp index 76cb4ebe53..e5a5568cd7 100644 --- a/doomsday/client/src/render/rend_main.cpp +++ b/doomsday/client/src/render/rend_main.cpp @@ -367,7 +367,7 @@ static byte pvisibleLineSections(LineDef *line, int backSide) if(!line || !line->L_sidedef(backSide)) return 0; - if(!line->L_sector(backSide^1) /*$degenleaf*/ || !line->L_backsidedef) + if(!line->hasSector(backSide^1) /*$degenleaf*/ || !line->L_backsidedef) { // Only a middle. sections |= SSF_MIDDLE; @@ -375,8 +375,8 @@ static byte pvisibleLineSections(LineDef *line, int backSide) else { SideDef const *sideDef = line->L_sidedef(backSide); - Sector const *fsec = line->L_sector(backSide); - Sector const *bsec = line->L_sector(backSide^1); + Sector const *fsec = line->sectorPtr(backSide); + Sector const *bsec = line->sectorPtr(backSide^1); Plane const *fceil = &fsec->ceiling(); Plane const *ffloor = &fsec->floor(); Plane const *bceil = &bsec->ceiling(); @@ -1808,15 +1808,15 @@ static boolean Rend_RenderHEdgeTwosided(HEdge *hedge, byte sections) reportLineDefDrawn(line); - if(back->sector == front->sector && + if(back->sectorPtr() == front->sectorPtr() && !front->sideDef->SW_topmaterial && !front->sideDef->SW_bottommaterial && !front->sideDef->SW_middlematerial) return false; // Ugh... an obvious wall hedge hack. Best take no chances... Plane *ffloor = &leaf->sector().floor(); Plane *fceil = &leaf->sector().ceiling(); - Plane *bfloor = &back->sector->floor(); - Plane *bceil = &back->sector->ceiling(); + Plane *bfloor = &back->sector().floor(); + Plane *bceil = &back->sector().ceiling(); /** * Create the wall sections. @@ -1842,7 +1842,7 @@ static boolean Rend_RenderHEdgeTwosided(HEdge *hedge, byte sections) Rend_RadioUpdateLinedef(hedge->lineDef, hedge->side); solidSeg = rendHEdgeSection(hedge, SS_MIDDLE, rhFlags, - front->sector->lightLevel, R_GetSectorLightColor(front->sector), + front->sector().lightLevel, R_GetSectorLightColor(front->sectorPtr()), &leftWallDivs, &rightWallDivs, matOffset); if(solidSeg) { @@ -1882,7 +1882,7 @@ static boolean Rend_RenderHEdgeTwosided(HEdge *hedge, byte sections) { Rend_RadioUpdateLinedef(hedge->lineDef, hedge->side); rendHEdgeSection(hedge, SS_TOP, RHF_ADD_DYNLIGHTS|RHF_ADD_DYNSHADOWS|RHF_ADD_RADIO, - front->sector->lightLevel, R_GetSectorLightColor(front->sector), + front->sector().lightLevel, R_GetSectorLightColor(front->sectorPtr()), &leftWallDivs, &rightWallDivs, matOffset); } } @@ -1898,7 +1898,7 @@ static boolean Rend_RenderHEdgeTwosided(HEdge *hedge, byte sections) { Rend_RadioUpdateLinedef(hedge->lineDef, hedge->side); rendHEdgeSection(hedge, SS_BOTTOM, RHF_ADD_DYNLIGHTS|RHF_ADD_DYNSHADOWS|RHF_ADD_RADIO, - front->sector->lightLevel, R_GetSectorLightColor(front->sector), + front->sector().lightLevel, R_GetSectorLightColor(front->sectorPtr()), &leftWallDivs, &rightWallDivs, matOffset); } } @@ -1907,16 +1907,17 @@ static boolean Rend_RenderHEdgeTwosided(HEdge *hedge, byte sections) if(solidSeg == -1) return false; // NEVER (we have a hole we couldn't fix). - if(front->sideDef && back->sideDef && front->sector == back->sector) + if(line->isSelfReferencing()) return false; if(!solidSeg) // We'll have to determine whether we can... { - if(back->sector == front->sector) + /*if(back->sector == front->sector) { // An obvious hack, what to do though?? } - else if( (bceil->visHeight() <= ffloor->visHeight() && + else*/ + if( (bceil->visHeight() <= ffloor->visHeight() && (front->sideDef->SW_topmaterial || front->sideDef->SW_middlematerial)) || (bfloor->visHeight() >= fceil->visHeight() && (front->sideDef->SW_bottommaterial || front->sideDef->SW_middlematerial))) @@ -2078,16 +2079,16 @@ static void skyFixZCoords(HEdge* hedge, int skyCap, coord_t* bottom, coord_t* to * Tests consider all Planes which interface with this and the "middle" * Material used on the relative front side (if any). */ -static boolean hedgeBackClosedForSkyFix(const HEdge* hedge) +static boolean hedgeBackClosedForSkyFix(HEdge const *hedge) { DENG_ASSERT(hedge && hedge->lineDef); -{ + byte side = hedge->side; - LineDef* line = hedge->lineDef; - Sector* frontSec = line->L_sector(side); - Sector* backSec = line->L_sector(side^1); - SideDef* frontDef = line->L_sidedef(side); - SideDef* backDef = line->L_sidedef(side^1); + LineDef *line = hedge->lineDef; + Sector *frontSec = line->sectorPtr(side); + Sector *backSec = line->sectorPtr(side^1); + SideDef *frontDef = line->L_sidedef(side); + SideDef *backDef = line->L_sidedef(side^1); if(!frontDef) return false; if(!backDef) return true; @@ -2102,7 +2103,7 @@ static boolean hedgeBackClosedForSkyFix(const HEdge* hedge) return R_MiddleMaterialCoversOpening(line->flags, frontSec, backSec, frontDef, backDef, false/*don't ignore opacity*/); -}} +} /** * Determine which sky fixes are necessary for the specified @a hedge. @@ -3191,20 +3192,20 @@ static void getVertexPlaneMinMax(Vertex const *vtx, coord_t *min, coord_t *max) if(li->L_frontsidedef) { - if(min && li->L_frontsector->SP_floorvisheight < *min) - *min = li->L_frontsector->SP_floorvisheight; + if(min && li->frontSector().SP_floorvisheight < *min) + *min = li->frontSector().SP_floorvisheight; - if(max && li->L_frontsector->SP_ceilvisheight > *max) - *max = li->L_frontsector->SP_ceilvisheight; + if(max && li->frontSector().SP_ceilvisheight > *max) + *max = li->frontSector().SP_ceilvisheight; } if(li->L_backsidedef) { - if(min && li->L_backsector->SP_floorvisheight < *min) - *min = li->L_backsector->SP_floorvisheight; + if(min && li->backSector().SP_floorvisheight < *min) + *min = li->backSector().SP_floorvisheight; - if(max && li->L_backsector->SP_ceilvisheight > *max) - *max = li->L_backsector->SP_ceilvisheight; + if(max && li->backSector().SP_ceilvisheight > *max) + *max = li->backSector().SP_ceilvisheight; } own = &own->next();