From db8b252e9b42c66ee4fa412201385a814422ddf3 Mon Sep 17 00:00:00 2001 From: danij Date: Fri, 15 Mar 2013 12:07:51 +0000 Subject: [PATCH] Refactor|Surface: Surface can manage the missing-material-fix state internally --- doomsday/client/include/map/surface.h | 22 ++++++++++------ doomsday/client/src/map/r_world.cpp | 3 +-- doomsday/client/src/map/surface.cpp | 25 +++++++++++++------ doomsday/client/src/render/rend_fakeradio.cpp | 3 +-- doomsday/client/src/render/rend_main.cpp | 8 +++--- doomsday/server/src/server/sv_pool.cpp | 9 +++---- 6 files changed, 40 insertions(+), 30 deletions(-) diff --git a/doomsday/client/include/map/surface.h b/doomsday/client/include/map/surface.h index 5229f35c48..a8ea9502a5 100644 --- a/doomsday/client/include/map/surface.h +++ b/doomsday/client/include/map/surface.h @@ -102,9 +102,6 @@ class Surface : public de::MapElement /// @ref surfaceInternalFlags short inFlags; - /// Old @ref surfaceInternalFlags, for tracking changes. - short _oldInFlags; - uint numDecorations; struct surfacedecorsource_s *decorations; @@ -141,17 +138,27 @@ class Surface : public de::MapElement */ bool hasMaterial() const; + /** + * Returns @c true iff a @em fix material is bound to the surface, which + * was chosen automatically where one was missing. Clients should not be + * notified when a fix material is bound to the surface (as they should + * perform their fixing, locally). However, if the fix material is later + * replaced with a "normally-bound" material, clients should be notified + * as per usual. + */ + bool hasFixMaterial() const; + /** * Returns the material bound to the surface. * - * @see hasMaterial() + * @see hasMaterial(), hasFixMaterial() */ Material &material() const; /** * Returns a pointer to the material bound to the surface; otherwise @c 0. * - * @see hasMaterial() + * @see hasMaterial(), hasFixMaterial() */ inline Material *materialPtr() const { return hasMaterial()? &material() : 0; } @@ -193,9 +200,10 @@ class Surface : public de::MapElement /** * Change Material bound to this surface. * - * @param mat New Material. + * @param newMaterial New material to be bound. + * @param isMissingFix The new material is a fix for a "missing" material. */ - bool setMaterial(Material *material); + bool setMaterial(Material *material, bool isMissingFix = false); /** * Change Material origin. diff --git a/doomsday/client/src/map/r_world.cpp b/doomsday/client/src/map/r_world.cpp index cde408b75d..2fe0e3a594 100644 --- a/doomsday/client/src/map/r_world.cpp +++ b/doomsday/client/src/map/r_world.cpp @@ -1313,8 +1313,7 @@ static void addMissingMaterial(SideDef *s, SideDefSection section) if(surface.hasMaterial()) return; // Look for a suitable replacement. - surface.setMaterial(chooseFixMaterial(s, section)); - surface.inFlags |= SUIF_FIX_MISSING_MATERIAL; + surface.setMaterial(chooseFixMaterial(s, section), true/* is missing fix */); // During map load we log missing materials. if(ddMapSetup && verbose) diff --git a/doomsday/client/src/map/surface.cpp b/doomsday/client/src/map/surface.cpp index 24c1faf64a..12f87a4648 100644 --- a/doomsday/client/src/map/surface.cpp +++ b/doomsday/client/src/map/surface.cpp @@ -46,7 +46,6 @@ Surface::Surface(MapElement &owner) V2f_Set(visOffsetDelta, 0, 0); std::memset(rgba, 1, sizeof(rgba)); inFlags = 0; - _oldInFlags = 0; numDecorations = 0; decorations = 0; } @@ -68,7 +67,6 @@ Surface &Surface::operator = (Surface const &other) V2f_Copy(_oldOffset[1], other._oldOffset[1]); std::memcpy(rgba, other.rgba, sizeof(rgba)); inFlags = other.inFlags; - _oldInFlags = other._oldInFlags; // Reset the visual offset to the actual offset. V2f_Copy(visOffset, offset); @@ -87,6 +85,11 @@ bool Surface::hasMaterial() const return !!_material; } +bool Surface::hasFixMaterial() const +{ + return !!_material && !!(inFlags & SUIF_FIX_MISSING_MATERIAL); +} + Material &Surface::material() const { if(_material) @@ -123,16 +126,23 @@ bool Surface::isAttachedToMap() const return true; } -bool Surface::setMaterial(Material *newMaterial) +bool Surface::setMaterial(Material *newMaterial, bool isMissingFix) { if(_material != newMaterial) { - if(isAttachedToMap()) + // Update the missing-material-fix state. + if(!_material) { - // No longer a missing texture fix? - if(newMaterial && (_oldInFlags & SUIF_FIX_MISSING_MATERIAL)) - inFlags &= ~SUIF_FIX_MISSING_MATERIAL; + if(newMaterial && isMissingFix) + inFlags |= SUIF_FIX_MISSING_MATERIAL; + } + else if(newMaterial && (inFlags & SUIF_FIX_MISSING_MATERIAL)) + { + inFlags &= ~SUIF_FIX_MISSING_MATERIAL; + } + if(isAttachedToMap()) + { if(!ddMapSetup) { #ifdef __CLIENT__ @@ -170,7 +180,6 @@ bool Surface::setMaterial(Material *newMaterial) } _material = newMaterial; - _oldInFlags = inFlags; if(isAttachedToMap()) { inFlags |= SUIF_UPDATE_DECORATIONS; diff --git a/doomsday/client/src/render/rend_fakeradio.cpp b/doomsday/client/src/render/rend_fakeradio.cpp index 5764e43145..1873ca5425 100644 --- a/doomsday/client/src/render/rend_fakeradio.cpp +++ b/doomsday/client/src/render/rend_fakeradio.cpp @@ -1198,8 +1198,7 @@ static uint radioEdgeHackType(LineDef const *line, Sector const *front, Sector c { Surface const &surface = line->sideDef(backside).surface(isCeiling? SS_TOP:SS_BOTTOM); - if(fz < bz && !surface.hasMaterial() && - !(surface.inFlags & SUIF_FIX_MISSING_MATERIAL)) + if(fz < bz && !surface.hasMaterial()) return 3; // Consider it fully open. // Is the back sector closed? diff --git a/doomsday/client/src/render/rend_main.cpp b/doomsday/client/src/render/rend_main.cpp index 1110ad1889..55d0363d06 100644 --- a/doomsday/client/src/render/rend_main.cpp +++ b/doomsday/client/src/render/rend_main.cpp @@ -1626,8 +1626,7 @@ static boolean rendHEdgeSection(HEdge *hedge, SideDefSection section, // Lighting debug mode; render using System:gray. mat = &App_Materials().find(de::Uri("System", Path("gray"))).material(); } - else if(!surface->hasMaterial() || - ((surface->inFlags & SUIF_FIX_MISSING_MATERIAL) && devNoTexFix)) + else if(!surface->hasMaterial() || (surface->hasFixMaterial() && devNoTexFix)) { // Missing material debug mode; render using System:missing. mat = &App_Materials().find(de::Uri("System", Path("missing"))).material(); @@ -1710,8 +1709,7 @@ static boolean rendHEdgeSection(HEdge *hedge, SideDefSection section, // Do not apply an angle based lighting delta if this surface's material // has been chosen as a HOM fix (we must remain consistent with the lighting // applied to the back plane (on this half-edge's back side)). - if(frontSide && isTwoSided && section != SS_MIDDLE && - (surface->inFlags & SUIF_FIX_MISSING_MATERIAL)) + if(frontSide && isTwoSided && section != SS_MIDDLE && surface->hasFixMaterial()) { deltaL = deltaR = 0; } @@ -2717,7 +2715,7 @@ static void Rend_RenderPlanes() if(renderTextures == 2) texMode = 2; - else if(!suf->hasMaterial() || (devNoTexFix && (suf->inFlags & SUIF_FIX_MISSING_MATERIAL))) + else if(!suf->hasMaterial() || (devNoTexFix && suf->hasFixMaterial())) texMode = 1; else texMode = 0; diff --git a/doomsday/server/src/server/sv_pool.cpp b/doomsday/server/src/server/sv_pool.cpp index 6d827821ea..fcd560723d 100644 --- a/doomsday/server/src/server/sv_pool.cpp +++ b/doomsday/server/src/server/sv_pool.cpp @@ -756,24 +756,21 @@ boolean Sv_RegisterCompareSide(cregister_t *reg, uint number, byte sideFlags = s->flags & 0xff; int df = 0; - if(r->top.material != s->top().materialPtr() && - !(s->top().inFlags & SUIF_FIX_MISSING_MATERIAL)) + if(!s->top().hasFixMaterial() && r->top.material != s->top().materialPtr()) { df |= SIDF_TOP_MATERIAL; if(doUpdate) r->top.material = s->top().materialPtr(); } - if(r->middle.material != s->middle().materialPtr() && - !(s->middle().inFlags & SUIF_FIX_MISSING_MATERIAL)) + if(!s->middle().hasFixMaterial() && r->middle.material != s->middle().materialPtr()) { df |= SIDF_MID_MATERIAL; if(doUpdate) r->middle.material = s->middle().materialPtr(); } - if(r->bottom.material != s->bottom().materialPtr() && - !(s->bottom().inFlags & SUIF_FIX_MISSING_MATERIAL)) + if(!s->bottom().hasFixMaterial() && r->bottom.material != s->bottom().materialPtr()) { df |= SIDF_BOTTOM_MATERIAL; if(doUpdate)