From 9acf65b9a457b7ffdc52bfaed43e463bf1e9179d Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Fri, 4 Nov 2011 01:12:53 +0000 Subject: [PATCH] - Added support for a PALVERS lump. This specifies replacement textures to be used when for walls and floors when the renderer is paletted. The format is very simple: rgbtex1 paltex1 rgbtex2 paltex2 ... The first texture is the one to be used normally, and the second is the one to be used in paletted modes. The vid_nopalsubstitutions cvar can be used to ignore this lump. SVN r3311 (trunk) --- src/r_plane.cpp | 10 +++--- src/r_segs.cpp | 41 ++++++++++++------------ src/textures/texturemanager.cpp | 56 ++++++++++++++++++++++++++++++++- src/textures/textures.h | 17 ++++++++-- 4 files changed, 95 insertions(+), 29 deletions(-) diff --git a/src/r_plane.cpp b/src/r_plane.cpp index 9e754853f..0652121f7 100644 --- a/src/r_plane.cpp +++ b/src/r_plane.cpp @@ -1080,7 +1080,7 @@ void R_DrawSinglePlane (visplane_t *pl, fixed_t alpha, bool additive, bool maske } else { // regular flat - FTexture *tex = TexMan(pl->picnum); + FTexture *tex = TexMan(pl->picnum, true); if (tex->UseType == FTexture::TEX_Null) { @@ -1368,9 +1368,9 @@ void R_DrawSkyPlane (visplane_t *pl) if (!(pl->sky & PL_SKYFLAT)) { // use sky1 sky1: - frontskytex = TexMan(sky1tex); + frontskytex = TexMan(sky1tex, true); if (level.flags & LEVEL_DOUBLESKY) - backskytex = TexMan(sky2tex); + backskytex = TexMan(sky2tex, true); else backskytex = NULL; skyflip = 0; @@ -1381,7 +1381,7 @@ void R_DrawSkyPlane (visplane_t *pl) } else if (pl->sky == PL_SKYFLAT) { // use sky2 - frontskytex = TexMan(sky2tex); + frontskytex = TexMan(sky2tex, true); backskytex = NULL; frontcyl = sky2cyl; skyflip = 0; @@ -1407,7 +1407,7 @@ void R_DrawSkyPlane (visplane_t *pl) pos = side_t::top; } - frontskytex = TexMan(s->GetTexture(pos)); + frontskytex = TexMan(s->GetTexture(pos), true); if (frontskytex == NULL || frontskytex->UseType == FTexture::TEX_Null) { // [RH] The blank texture: Use normal sky instead. goto sky1; diff --git a/src/r_segs.cpp b/src/r_segs.cpp index 7e69190e5..525052328 100644 --- a/src/r_segs.cpp +++ b/src/r_segs.cpp @@ -240,7 +240,7 @@ void R_RenderMaskedSegRange (drawseg_t *ds, int x1, int x2) frontsector = curline->frontsector; backsector = curline->backsector; - tex = TexMan(curline->sidedef->GetTexture(side_t::mid)); + tex = TexMan(curline->sidedef->GetTexture(side_t::mid), true); if (i_compatflags & COMPATF_MASKEDMIDTEX) { tex = tex->GetRawTexture(); @@ -705,15 +705,15 @@ void R_RenderFakeWallRange (drawseg_t *ds, int x1, int x2) } else if(fover->flags & FF_UPPERTEXTURE) { - rw_pic = TexMan(curline->sidedef->GetTexture(side_t::top)); + rw_pic = TexMan(curline->sidedef->GetTexture(side_t::top), true); } else if(fover->flags & FF_LOWERTEXTURE) { - rw_pic = TexMan(curline->sidedef->GetTexture(side_t::bottom)); + rw_pic = TexMan(curline->sidedef->GetTexture(side_t::bottom), true); } else { - rw_pic = TexMan(fover->master->sidedef[0]->GetTexture(side_t::mid)); + rw_pic = TexMan(fover->master->sidedef[0]->GetTexture(side_t::mid), true); } } else if (frontsector->e->XFloor.ffloors.Size()) @@ -764,15 +764,15 @@ void R_RenderFakeWallRange (drawseg_t *ds, int x1, int x2) fover = NULL; if (rover->flags & FF_UPPERTEXTURE) { - rw_pic = TexMan(curline->sidedef->GetTexture(side_t::top)); + rw_pic = TexMan(curline->sidedef->GetTexture(side_t::top), true); } else if(rover->flags & FF_LOWERTEXTURE) { - rw_pic = TexMan(curline->sidedef->GetTexture(side_t::bottom)); + rw_pic = TexMan(curline->sidedef->GetTexture(side_t::bottom), true); } else { - rw_pic = TexMan(rover->master->sidedef[0]->GetTexture(side_t::mid)); + rw_pic = TexMan(rover->master->sidedef[0]->GetTexture(side_t::mid), true); } } // correct colors now @@ -881,15 +881,15 @@ void R_RenderFakeWallRange (drawseg_t *ds, int x1, int x2) } else if (fover->flags & FF_UPPERTEXTURE) { - rw_pic = TexMan(curline->sidedef->GetTexture(side_t::top)); + rw_pic = TexMan(curline->sidedef->GetTexture(side_t::top), true); } else if (fover->flags & FF_LOWERTEXTURE) { - rw_pic = TexMan(curline->sidedef->GetTexture(side_t::bottom)); + rw_pic = TexMan(curline->sidedef->GetTexture(side_t::bottom), true); } else { - rw_pic = TexMan(fover->master->sidedef[0]->GetTexture(side_t::mid)); + rw_pic = TexMan(fover->master->sidedef[0]->GetTexture(side_t::mid), true); } } else if (frontsector->e->XFloor.ffloors.Size()) @@ -937,15 +937,15 @@ void R_RenderFakeWallRange (drawseg_t *ds, int x1, int x2) fover = NULL; if (rover->flags & FF_UPPERTEXTURE) { - rw_pic = TexMan(curline->sidedef->GetTexture(side_t::top)); + rw_pic = TexMan(curline->sidedef->GetTexture(side_t::top), true); } else if (rover->flags & FF_LOWERTEXTURE) { - rw_pic = TexMan(curline->sidedef->GetTexture(side_t::bottom)); + rw_pic = TexMan(curline->sidedef->GetTexture(side_t::bottom), true); } else { - rw_pic = TexMan(rover->master->sidedef[0]->GetTexture(side_t::mid)); + rw_pic = TexMan(rover->master->sidedef[0]->GetTexture(side_t::mid), true); } } // correct colors now @@ -1799,7 +1799,7 @@ void R_NewWall (bool needlights) // [RH] Horizon lines do not need to be textured if (linedef->special != Line_Horizon) { - midtexture = TexMan(sidedef->GetTexture(side_t::mid)); + midtexture = TexMan(sidedef->GetTexture(side_t::mid), true); rw_offset_mid = sidedef->GetTextureXOffset(side_t::mid); rowoffset = sidedef->GetTextureYOffset(side_t::mid); rw_midtexturescalex = sidedef->GetTextureXScale(side_t::mid); @@ -1943,7 +1943,7 @@ void R_NewWall (bool needlights) if (rw_havehigh) { // top texture - toptexture = TexMan(sidedef->GetTexture(side_t::top)); + toptexture = TexMan(sidedef->GetTexture(side_t::top), true); rw_offset_top = sidedef->GetTextureXOffset(side_t::top); rowoffset = sidedef->GetTextureYOffset(side_t::top); @@ -1973,7 +1973,7 @@ void R_NewWall (bool needlights) } if (rw_havelow) { // bottom texture - bottomtexture = TexMan(sidedef->GetTexture(side_t::bottom)); + bottomtexture = TexMan(sidedef->GetTexture(side_t::bottom), true); rw_offset_bottom = sidedef->GetTextureXOffset(side_t::bottom); rowoffset = sidedef->GetTextureYOffset(side_t::bottom); @@ -2016,7 +2016,7 @@ void R_NewWall (bool needlights) markceiling = false; } - FTexture *midtex = TexMan(sidedef->GetTexture(side_t::mid)); + FTexture *midtex = TexMan(sidedef->GetTexture(side_t::mid), true); segtextured = midtex != NULL || toptexture != NULL || bottomtexture != NULL; @@ -2218,7 +2218,7 @@ void R_StoreWallRange (int start, int stop) if(!ds_p->fake) // allocate space for masked texture tables, if needed // [RH] Don't just allocate the space; fill it in too. - if ((TexMan(sidedef->GetTexture(side_t::mid))->UseType != FTexture::TEX_Null || ds_p->bFakeBoundary || IsFogBoundary (frontsector, backsector)) && + if ((TexMan(sidedef->GetTexture(side_t::mid), true)->UseType != FTexture::TEX_Null || ds_p->bFakeBoundary || IsFogBoundary (frontsector, backsector)) && (rw_ceilstat != 12 || !sidedef->GetTexture(side_t::top).isValid()) && (rw_floorstat != 3 || !sidedef->GetTexture(side_t::bottom).isValid()) && (WallSZ1 >= TOO_CLOSE_Z && WallSZ2 >= TOO_CLOSE_Z)) @@ -2244,7 +2244,7 @@ void R_StoreWallRange (int start, int stop) lwal = (fixed_t *)(openings + ds_p->maskedtexturecol); swal = (fixed_t *)(openings + ds_p->swall); - FTexture *pic = TexMan(sidedef->GetTexture(side_t::mid)); + FTexture *pic = TexMan(sidedef->GetTexture(side_t::mid), true); fixed_t yrepeat = FixedMul(pic->yScale, sidedef->GetTextureYScale(side_t::mid)); fixed_t xoffset = sidedef->GetTextureXOffset(side_t::mid); @@ -2550,6 +2550,7 @@ int WallMost (short *mostbuf, const secplane_t &plane) { clearbufshort (&mostbuf[ix1], ix2-ix1, viewheight); return bad; + } if (bad&3) @@ -2759,7 +2760,7 @@ static void R_RenderDecal (side_t *wall, DBaseDecal *decal, drawseg_t *clipper, xscale = decal->ScaleX; yscale = decal->ScaleY; - WallSpriteTile = TexMan(decal->PicNum); + WallSpriteTile = TexMan(decal->PicNum, true); flipx = (BYTE)(decal->RenderFlags & RF_XFLIP); if (WallSpriteTile == NULL || WallSpriteTile->UseType == FTexture::TEX_Null) diff --git a/src/textures/texturemanager.cpp b/src/textures/texturemanager.cpp index 622d92f75..1abbab29f 100644 --- a/src/textures/texturemanager.cpp +++ b/src/textures/texturemanager.cpp @@ -55,6 +55,8 @@ FTextureManager TexMan; +CVAR(Bool, vid_nopalsubstitutions, false, CVAR_ARCHIVE) + //========================================================================== // // FTextureManager :: FTextureManager @@ -749,7 +751,7 @@ void FTextureManager::AddPatches (int lumpnum) { file->Read (name, 8); - if (CheckForTexture (name, FTexture::TEX_WallPatch, false) == -1) + if (CheckForTexture (name, FTexture::TEX_WallPatch, 0) == -1) { CreateTexture (Wads.CheckNumForName (name, ns_patches), FTexture::TEX_WallPatch); } @@ -1001,6 +1003,57 @@ void FTextureManager::Init() InitAnimDefs(); FixAnimations(); InitSwitchList(); + InitPalettedVersions(); +} + +//========================================================================== +// +// FTextureManager :: InitPalettedVersions +// +//========================================================================== + +void FTextureManager::InitPalettedVersions() +{ + int lump, lastlump = 0; + + PalettedVersions.Clear(); + while ((lump = Wads.FindLump("PALVERS", &lastlump)) != -1) + { + FScanner sc(lump); + + while (sc.GetString()) + { + FTextureID pic1 = CheckForTexture(sc.String, FTexture::TEX_Any); + if (!pic1.isValid()) + { + sc.ScriptMessage("Unknown texture %s to replace"); + } + sc.MustGetString(); + FTextureID pic2 = CheckForTexture(sc.String, FTexture::TEX_Any); + if (!pic2.isValid()) + { + sc.ScriptMessage("Unknown texture %s to use as replacement"); + } + if (pic1.isValid() && pic2.isValid()) + { + PalettedVersions[pic1.GetIndex()] = pic2.GetIndex(); + } + } + } +} + +//========================================================================== +// +// FTextureManager :: PalCheck +// +//========================================================================== + +FTextureID FTextureManager::PalCheck(FTextureID tex) +{ + if (vid_nopalsubstitutions) return tex; + int *newtex = PalettedVersions.CheckKey(tex.GetIndex()); + if (newtex == NULL || *newtex == 0) return tex; + return *newtex; } //========================================================================== @@ -1152,6 +1205,7 @@ int FTextureManager::CountLumpTextures (int lumpnum) // // R_PrecacheLevel // + // Preloads all relevant graphics for the level. // //=========================================================================== diff --git a/src/textures/textures.h b/src/textures/textures.h index a35c911ad..6c1b8f717 100644 --- a/src/textures/textures.h +++ b/src/textures/textures.h @@ -332,15 +332,20 @@ public: FTexture *FindTexture(const char *texname, int usetype = FTexture::TEX_MiscPatch, BITFIELD flags = TEXMAN_TryAny); // Get texture with translation - FTexture *operator() (FTextureID texnum) + FTexture *operator() (FTextureID texnum, bool withpalcheck=false) { if ((size_t)texnum.texnum >= Textures.Size()) return NULL; - return Textures[Translation[texnum.texnum]].Texture; + int picnum = Translation[texnum.texnum]; + if (withpalcheck) + { + picnum = PalCheck(picnum).GetIndex(); + } + return Textures[picnum].Texture; } FTexture *operator() (const char *texname) { FTextureID texnum = GetTexture (texname, FTexture::TEX_MiscPatch); - if (texnum.texnum==-1) return NULL; + if (texnum.texnum == -1) return NULL; return Textures[Translation[texnum.texnum]].Texture; } @@ -350,6 +355,8 @@ public: return Textures[Translation[i]].Texture; } + FTextureID PalCheck(FTextureID tex); + enum { TEXMAN_TryAny = 1, @@ -434,6 +441,8 @@ private: void SetTranslation (FTextureID fromtexnum, FTextureID totexnum); void ParseAnimatedDoor(FScanner &sc); + void InitPalettedVersions(); + // Switches void InitSwitchList (); @@ -452,6 +461,7 @@ private: int HashFirst[HASH_SIZE]; FTextureID DefaultTexture; TArray FirstTextureForFile; + TMap PalettedVersions; // maps from normal -> paletted version TArray mAnimations; TArray mSwitchDefs; @@ -529,6 +539,7 @@ public: void MakeTexture (); protected: + DSimpleCanvas *Canvas; BYTE *Pixels; Span DummySpans[2];