Merge branch 'additive-transmap' into 'master'

Additive and Subtractive Translation Maps

See merge request KartKrew/Kart!323
This commit is contained in:
Sal 2020-10-28 15:50:22 -04:00
commit 8b20a94202
12 changed files with 169 additions and 69 deletions

View file

@ -11123,6 +11123,8 @@ struct {
{"FF_TRANS70",FF_TRANS70}, {"FF_TRANS70",FF_TRANS70},
{"FF_TRANS80",FF_TRANS80}, {"FF_TRANS80",FF_TRANS80},
{"FF_TRANS90",FF_TRANS90}, {"FF_TRANS90",FF_TRANS90},
{"FF_TRANSADD",FF_TRANSADD},
{"FF_TRANSSUB",FF_TRANSSUB},
// compatibility // compatibility
// Transparency for SOCs is pre-shifted // Transparency for SOCs is pre-shifted
{"TR_TRANS10",tr_trans10<<FF_TRANSSHIFT}, {"TR_TRANS10",tr_trans10<<FF_TRANSSHIFT},
@ -11134,6 +11136,8 @@ struct {
{"TR_TRANS70",tr_trans70<<FF_TRANSSHIFT}, {"TR_TRANS70",tr_trans70<<FF_TRANSSHIFT},
{"TR_TRANS80",tr_trans80<<FF_TRANSSHIFT}, {"TR_TRANS80",tr_trans80<<FF_TRANSSHIFT},
{"TR_TRANS90",tr_trans90<<FF_TRANSSHIFT}, {"TR_TRANS90",tr_trans90<<FF_TRANSSHIFT},
{"TR_TRANSADD",tr_transadd<<FF_TRANSSHIFT},
{"TR_TRANSSUB",tr_transsub<<FF_TRANSSHIFT},
// Transparency for Lua is not, unless capitalized as above. // Transparency for Lua is not, unless capitalized as above.
{"tr_trans10",tr_trans10}, {"tr_trans10",tr_trans10},
{"tr_trans20",tr_trans20}, {"tr_trans20",tr_trans20},
@ -11145,6 +11149,9 @@ struct {
{"tr_trans80",tr_trans80}, {"tr_trans80",tr_trans80},
{"tr_trans90",tr_trans90}, {"tr_trans90",tr_trans90},
{"NUMTRANSMAPS",NUMTRANSMAPS}, {"NUMTRANSMAPS",NUMTRANSMAPS},
{"tr_transadd",tr_transadd},
{"tr_transsub",tr_transsub},
{"NUMEFFECTMAPS",NUMEFFECTMAPS},
// Type of levels // Type of levels
{"TOL_RACE",TOL_RACE}, {"TOL_RACE",TOL_RACE},
@ -11653,6 +11660,8 @@ struct {
{"MFD_TRANS70",MFD_TRANS70}, {"MFD_TRANS70",MFD_TRANS70},
{"MFD_TRANS80",MFD_TRANS80}, {"MFD_TRANS80",MFD_TRANS80},
{"MFD_TRANS90",MFD_TRANS90}, {"MFD_TRANS90",MFD_TRANS90},
{"MFD_TRANSADD",MFD_TRANSADD},
{"MFD_TRANSSUB",MFD_TRANSSUB},
{"MFD_TRANSMASK",MFD_TRANSMASK}, {"MFD_TRANSMASK",MFD_TRANSMASK},
{"MFD_FULLBRIGHT",MFD_FULLBRIGHT}, {"MFD_FULLBRIGHT",MFD_FULLBRIGHT},
{"MFD_SEMIBRIGHT",MFD_SEMIBRIGHT}, {"MFD_SEMIBRIGHT",MFD_SEMIBRIGHT},

View file

@ -559,7 +559,7 @@ static void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, bool
HWR_Lighting(&Surf, lightlevel, planecolormap); HWR_Lighting(&Surf, lightlevel, planecolormap);
if (PolyFlags & (PF_Translucent|PF_Fog)) if (PolyFlags & (PF_Translucent|PF_Additive|PF_Substractive|PF_Fog))
{ {
Surf.PolyColor.s.alpha = (UINT8)alpha; Surf.PolyColor.s.alpha = (UINT8)alpha;
PolyFlags |= PF_Modulated; PolyFlags |= PF_Modulated;
@ -789,6 +789,8 @@ FBITFIELD HWR_TranstableToAlpha(INT32 transtablenum, FSurfaceInfo *pSurf)
case tr_trans70 : pSurf->PolyColor.s.alpha = 0x4c;return PF_Translucent; case tr_trans70 : pSurf->PolyColor.s.alpha = 0x4c;return PF_Translucent;
case tr_trans80 : pSurf->PolyColor.s.alpha = 0x33;return PF_Translucent; case tr_trans80 : pSurf->PolyColor.s.alpha = 0x33;return PF_Translucent;
case tr_trans90 : pSurf->PolyColor.s.alpha = 0x19;return PF_Translucent; case tr_trans90 : pSurf->PolyColor.s.alpha = 0x19;return PF_Translucent;
case tr_transadd : pSurf->PolyColor.s.alpha = 0xFF;return PF_Additive;
case tr_transsub : pSurf->PolyColor.s.alpha = 0xFF;return PF_Substractive;
} }
return PF_Translucent; return PF_Translucent;
} }
@ -856,7 +858,7 @@ static float HWR_ClipViewSegment(INT32 x, polyvertex_t *v1, polyvertex_t *v2)
// //
// HWR_SplitWall // HWR_SplitWall
// //
static void HWR_SplitWall(sector_t *sector, FOutVector *wallVerts, INT32 texnum, FSurfaceInfo* Surf, INT32 cutflag, ffloor_t *pfloor) static void HWR_SplitWall(sector_t *sector, FOutVector *wallVerts, INT32 texnum, FSurfaceInfo* Surf, INT32 cutflag, ffloor_t *pfloor, FBITFIELD blendmode)
{ {
/* SoM: split up and light walls according to the /* SoM: split up and light walls according to the
lightlist. This may also include leaving out parts lightlist. This may also include leaving out parts
@ -993,12 +995,12 @@ static void HWR_SplitWall(sector_t *sector, FOutVector *wallVerts, INT32 texnum,
wallVerts[0].y = bot; wallVerts[0].y = bot;
wallVerts[1].y = endbot; wallVerts[1].y = endbot;
if (cutflag & FF_FOG) if (blendmode & PF_Fog)
HWR_AddTransparentWall(wallVerts, Surf, texnum, PF_Fog|PF_NoTexture, true, lightnum, colormap); HWR_AddTransparentWall(wallVerts, Surf, texnum, blendmode, true, lightnum, colormap);
else if (cutflag & FF_TRANSLUCENT) else if (blendmode & (PF_Translucent|PF_Additive|PF_Substractive|PF_Environment))
HWR_AddTransparentWall(wallVerts, Surf, texnum, PF_Translucent, false, lightnum, colormap); HWR_AddTransparentWall(wallVerts, Surf, texnum, blendmode, false, lightnum, colormap);
else else
HWR_ProjectWall(wallVerts, Surf, PF_Masked, lightnum, colormap); HWR_ProjectWall(wallVerts, Surf, blendmode, lightnum, colormap);
top = bot; top = bot;
endtop = endbot; endtop = endbot;
@ -1022,12 +1024,12 @@ static void HWR_SplitWall(sector_t *sector, FOutVector *wallVerts, INT32 texnum,
wallVerts[0].y = bot; wallVerts[0].y = bot;
wallVerts[1].y = endbot; wallVerts[1].y = endbot;
if (cutflag & FF_FOG) if (blendmode & PF_Fog)
HWR_AddTransparentWall(wallVerts, Surf, texnum, PF_Fog|PF_NoTexture, true, lightnum, colormap); HWR_AddTransparentWall(wallVerts, Surf, texnum, blendmode, true, lightnum, colormap);
else if (cutflag & FF_TRANSLUCENT) else if (blendmode & (PF_Translucent|PF_Additive|PF_Substractive|PF_Environment))
HWR_AddTransparentWall(wallVerts, Surf, texnum, PF_Translucent, false, lightnum, colormap); HWR_AddTransparentWall(wallVerts, Surf, texnum, blendmode, false, lightnum, colormap);
else else
HWR_ProjectWall(wallVerts, Surf, PF_Masked, lightnum, colormap); HWR_ProjectWall(wallVerts, Surf, blendmode, lightnum, colormap);
} }
// HWR_DrawSkyWall // HWR_DrawSkyWall
@ -1207,12 +1209,19 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
wallVerts[2].y = FIXED_TO_FLOAT(worldtopslope); wallVerts[2].y = FIXED_TO_FLOAT(worldtopslope);
wallVerts[1].y = FIXED_TO_FLOAT(worldhighslope); wallVerts[1].y = FIXED_TO_FLOAT(worldhighslope);
if (gl_frontsector->numlights) {
HWR_SplitWall(gl_frontsector, wallVerts, gl_toptexture, &Surf, FF_CUTLEVEL, NULL); FBITFIELD blendmode = PF_Masked;
else if (grTex->mipmap.flags & TF_TRANSPARENT)
HWR_AddTransparentWall(wallVerts, &Surf, gl_toptexture, PF_Environment, false, lightnum, colormap); if (grTex->mipmap.flags & TF_TRANSPARENT)
else blendmode = PF_Environment;
HWR_ProjectWall(wallVerts, &Surf, PF_Masked, lightnum, colormap);
if (gl_frontsector->numlights)
HWR_SplitWall(gl_frontsector, wallVerts, gl_toptexture, &Surf, FF_CUTLEVEL, NULL, blendmode);
else if (grTex->mipmap.flags & TF_TRANSPARENT)
HWR_AddTransparentWall(wallVerts, &Surf, gl_toptexture, blendmode, false, lightnum, colormap);
else
HWR_ProjectWall(wallVerts, &Surf, blendmode, lightnum, colormap);
}
} }
// check BOTTOM TEXTURE // check BOTTOM TEXTURE
@ -1273,12 +1282,19 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
wallVerts[2].y = FIXED_TO_FLOAT(worldlowslope); wallVerts[2].y = FIXED_TO_FLOAT(worldlowslope);
wallVerts[1].y = FIXED_TO_FLOAT(worldbottomslope); wallVerts[1].y = FIXED_TO_FLOAT(worldbottomslope);
if (gl_frontsector->numlights) {
HWR_SplitWall(gl_frontsector, wallVerts, gl_bottomtexture, &Surf, FF_CUTLEVEL, NULL); FBITFIELD blendmode = PF_Masked;
else if (grTex->mipmap.flags & TF_TRANSPARENT)
HWR_AddTransparentWall(wallVerts, &Surf, gl_bottomtexture, PF_Environment, false, lightnum, colormap); if (grTex->mipmap.flags & TF_TRANSPARENT)
else blendmode = PF_Environment;
HWR_ProjectWall(wallVerts, &Surf, PF_Masked, lightnum, colormap);
if (gl_frontsector->numlights)
HWR_SplitWall(gl_frontsector, wallVerts, gl_bottomtexture, &Surf, FF_CUTLEVEL, NULL, blendmode);
else if (grTex->mipmap.flags & TF_TRANSPARENT)
HWR_AddTransparentWall(wallVerts, &Surf, gl_bottomtexture, blendmode, false, lightnum, colormap);
else
HWR_ProjectWall(wallVerts, &Surf, blendmode, lightnum, colormap);
}
} }
gl_midtexture = R_GetTextureNum(gl_sidedef->midtexture); gl_midtexture = R_GetTextureNum(gl_sidedef->midtexture);
if (gl_midtexture) if (gl_midtexture)
@ -1472,16 +1488,19 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
blendmode = PF_Translucent; blendmode = PF_Translucent;
break; break;
default: default:
if (gl_linedef->alpha >= 0 && gl_linedef->alpha < FRACUNIT) {
blendmode = HWR_TranstableToAlpha(R_GetLinedefTransTable(gl_linedef->alpha), &Surf); transnum_t transtable = R_GetLinedefTransTable(gl_linedef);
if (transtable != NUMEFFECTMAPS)
blendmode = HWR_TranstableToAlpha(transtable, &Surf);
else else
blendmode = PF_Masked; blendmode = PF_Masked;
break; break;
}
} }
if (gl_curline->polyseg && gl_curline->polyseg->translucency > 0) if (gl_curline->polyseg && gl_curline->polyseg->translucency > 0)
{ {
if (gl_curline->polyseg->translucency >= NUMTRANSMAPS) // wall not drawn if (gl_curline->polyseg->translucency >= NUMEFFECTMAPS) // wall not drawn
{ {
Surf.PolyColor.s.alpha = 0x00; // This shouldn't draw anything regardless of blendmode Surf.PolyColor.s.alpha = 0x00; // This shouldn't draw anything regardless of blendmode
blendmode = PF_Masked; blendmode = PF_Masked;
@ -1493,10 +1512,10 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
if (gl_frontsector->numlights) if (gl_frontsector->numlights)
{ {
if (!(blendmode & PF_Masked)) if (!(blendmode & PF_Masked))
HWR_SplitWall(gl_frontsector, wallVerts, gl_midtexture, &Surf, FF_TRANSLUCENT, NULL); HWR_SplitWall(gl_frontsector, wallVerts, gl_midtexture, &Surf, FF_TRANSLUCENT, NULL, blendmode);
else else
{ {
HWR_SplitWall(gl_frontsector, wallVerts, gl_midtexture, &Surf, FF_CUTLEVEL, NULL); HWR_SplitWall(gl_frontsector, wallVerts, gl_midtexture, &Surf, FF_CUTLEVEL, NULL, blendmode);
} }
} }
else if (!(blendmode & PF_Masked)) else if (!(blendmode & PF_Masked))
@ -1577,15 +1596,21 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
wallVerts[2].y = FIXED_TO_FLOAT(worldtopslope); wallVerts[2].y = FIXED_TO_FLOAT(worldtopslope);
wallVerts[1].y = FIXED_TO_FLOAT(worldbottomslope); wallVerts[1].y = FIXED_TO_FLOAT(worldbottomslope);
// I don't think that solid walls can use translucent linedef types...
if (gl_frontsector->numlights)
HWR_SplitWall(gl_frontsector, wallVerts, gl_midtexture, &Surf, FF_CUTLEVEL, NULL);
else
{ {
FBITFIELD blendmode = PF_Masked;
if (grTex->mipmap.flags & TF_TRANSPARENT) if (grTex->mipmap.flags & TF_TRANSPARENT)
HWR_AddTransparentWall(wallVerts, &Surf, gl_midtexture, PF_Environment, false, lightnum, colormap); blendmode = PF_Environment;
// I don't think that solid walls can use translucent linedef types...
if (gl_frontsector->numlights)
HWR_SplitWall(gl_frontsector, wallVerts, gl_midtexture, &Surf, FF_CUTLEVEL, NULL, blendmode);
else else
HWR_ProjectWall(wallVerts, &Surf, PF_Masked, lightnum, colormap); {
if (grTex->mipmap.flags & TF_TRANSPARENT)
HWR_AddTransparentWall(wallVerts, &Surf, gl_midtexture, blendmode, false, lightnum, colormap);
else
HWR_ProjectWall(wallVerts, &Surf, blendmode, lightnum, colormap);
}
} }
} }
@ -1730,7 +1755,7 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
Surf.PolyColor.s.alpha = HWR_FogBlockAlpha(rover->master->frontsector->lightlevel, rover->master->frontsector->extra_colormap); Surf.PolyColor.s.alpha = HWR_FogBlockAlpha(rover->master->frontsector->lightlevel, rover->master->frontsector->extra_colormap);
if (gl_frontsector->numlights) if (gl_frontsector->numlights)
HWR_SplitWall(gl_frontsector, wallVerts, 0, &Surf, rover->flags, rover); HWR_SplitWall(gl_frontsector, wallVerts, 0, &Surf, rover->flags, rover, blendmode);
else else
HWR_AddTransparentWall(wallVerts, &Surf, 0, blendmode, true, lightnum, colormap); HWR_AddTransparentWall(wallVerts, &Surf, 0, blendmode, true, lightnum, colormap);
} }
@ -1738,14 +1763,21 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
{ {
FBITFIELD blendmode = PF_Masked; FBITFIELD blendmode = PF_Masked;
if (rover->flags & FF_TRANSLUCENT && rover->alpha < 256) if (rover->flags & FF_TRANSLUCENT)
{ {
blendmode = PF_Translucent; if (rover->alpha < 256)
Surf.PolyColor.s.alpha = (UINT8)rover->alpha-1 > 255 ? 255 : rover->alpha-1; {
blendmode = PF_Translucent;
Surf.PolyColor.s.alpha = (UINT8)(rover->alpha-1 > 255 ? 255 : rover->alpha-1);
}
else if (rover->alpha == FFLOOR_ALPHA_SPECIAL_ADDITIVE)
blendmode = PF_Additive;
else if (rover->alpha == FFLOOR_ALPHA_SPECIAL_SUBTRACTIVE)
blendmode = PF_Substractive;
} }
if (gl_frontsector->numlights) if (gl_frontsector->numlights)
HWR_SplitWall(gl_frontsector, wallVerts, texnum, &Surf, rover->flags, rover); HWR_SplitWall(gl_frontsector, wallVerts, texnum, &Surf, rover->flags, rover, blendmode);
else else
{ {
if (blendmode != PF_Masked) if (blendmode != PF_Masked)
@ -1830,7 +1862,7 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
Surf.PolyColor.s.alpha = HWR_FogBlockAlpha(rover->master->frontsector->lightlevel, rover->master->frontsector->extra_colormap); Surf.PolyColor.s.alpha = HWR_FogBlockAlpha(rover->master->frontsector->lightlevel, rover->master->frontsector->extra_colormap);
if (gl_backsector->numlights) if (gl_backsector->numlights)
HWR_SplitWall(gl_backsector, wallVerts, 0, &Surf, rover->flags, rover); HWR_SplitWall(gl_backsector, wallVerts, 0, &Surf, rover->flags, rover, blendmode);
else else
HWR_AddTransparentWall(wallVerts, &Surf, 0, blendmode, true, lightnum, colormap); HWR_AddTransparentWall(wallVerts, &Surf, 0, blendmode, true, lightnum, colormap);
} }
@ -1838,14 +1870,21 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
{ {
FBITFIELD blendmode = PF_Masked; FBITFIELD blendmode = PF_Masked;
if (rover->flags & FF_TRANSLUCENT && rover->alpha < 256) if (rover->flags & FF_TRANSLUCENT)
{ {
blendmode = PF_Translucent; if (rover->alpha < 256)
Surf.PolyColor.s.alpha = (UINT8)rover->alpha-1 > 255 ? 255 : rover->alpha-1; {
blendmode = PF_Translucent;
Surf.PolyColor.s.alpha = (UINT8)(rover->alpha-1 > 255 ? 255 : rover->alpha-1);
}
else if (rover->alpha == FFLOOR_ALPHA_SPECIAL_ADDITIVE)
blendmode = PF_Additive;
else if (rover->alpha == FFLOOR_ALPHA_SPECIAL_SUBTRACTIVE)
blendmode = PF_Substractive;
} }
if (gl_backsector->numlights) if (gl_backsector->numlights)
HWR_SplitWall(gl_backsector, wallVerts, texnum, &Surf, rover->flags, rover); HWR_SplitWall(gl_backsector, wallVerts, texnum, &Surf, rover->flags, rover, blendmode);
else else
{ {
if (blendmode != PF_Masked) if (blendmode != PF_Masked)
@ -2865,7 +2904,7 @@ static void HWR_AddPolyObjectPlanes(void)
if (!(po_ptrs[i]->flags & POF_RENDERPLANES)) // Only render planes when you should if (!(po_ptrs[i]->flags & POF_RENDERPLANES)) // Only render planes when you should
continue; continue;
if (po_ptrs[i]->translucency >= NUMTRANSMAPS) if (po_ptrs[i]->translucency >= NUMEFFECTMAPS)
continue; continue;
if (polyobjsector->floorheight <= gl_frontsector->ceilingheight if (polyobjsector->floorheight <= gl_frontsector->ceilingheight
@ -3106,8 +3145,16 @@ static void HWR_Subsector(size_t num)
alpha, rover->master->frontsector, PF_Fog|PF_NoTexture, alpha, rover->master->frontsector, PF_Fog|PF_NoTexture,
true, rover->master->frontsector->extra_colormap); true, rover->master->frontsector->extra_colormap);
} }
else if (rover->flags & FF_TRANSLUCENT && rover->alpha < 256) // SoM: Flags are more efficient else if (rover->flags & FF_TRANSLUCENT
&& (rover->alpha < 256
|| rover->alpha == FFLOOR_ALPHA_SPECIAL_ADDITIVE || rover->alpha == FFLOOR_ALPHA_SPECIAL_SUBTRACTIVE)) // SoM: Flags are more efficient
{ {
FBITFIELD blendmode = PF_Translucent;
if (rover->alpha == FFLOOR_ALPHA_SPECIAL_ADDITIVE)
blendmode = PF_Additive;
else if (rover->alpha == FFLOOR_ALPHA_SPECIAL_SUBTRACTIVE)
blendmode = PF_Substractive;
light = R_GetPlaneLight(gl_frontsector, centerHeight, dup_viewz < cullHeight ? true : false); light = R_GetPlaneLight(gl_frontsector, centerHeight, dup_viewz < cullHeight ? true : false);
HWR_AddTransparentFloor(&levelflats[*rover->bottompic], HWR_AddTransparentFloor(&levelflats[*rover->bottompic],
@ -3115,7 +3162,7 @@ static void HWR_Subsector(size_t num)
false, false,
*rover->bottomheight, *rover->bottomheight,
*gl_frontsector->lightlist[light].lightlevel, *gl_frontsector->lightlist[light].lightlevel,
rover->alpha-1 > 255 ? 255 : rover->alpha-1, rover->master->frontsector, (rover->flags & FF_RIPPLE ? PF_Ripple : 0)|PF_Translucent, rover->alpha-1 > 255 ? 255 : rover->alpha-1, rover->master->frontsector, (rover->flags & FF_RIPPLE ? PF_Ripple : 0)|blendmode,
false, *gl_frontsector->lightlist[light].extra_colormap); false, *gl_frontsector->lightlist[light].extra_colormap);
} }
else else
@ -3151,8 +3198,16 @@ static void HWR_Subsector(size_t num)
alpha, rover->master->frontsector, PF_Fog|PF_NoTexture, alpha, rover->master->frontsector, PF_Fog|PF_NoTexture,
true, rover->master->frontsector->extra_colormap); true, rover->master->frontsector->extra_colormap);
} }
else if (rover->flags & FF_TRANSLUCENT && rover->alpha < 256) else if (rover->flags & FF_TRANSLUCENT
&& (rover->alpha < 256
|| rover->alpha == FFLOOR_ALPHA_SPECIAL_ADDITIVE || rover->alpha == FFLOOR_ALPHA_SPECIAL_SUBTRACTIVE)) // SoM: Flags are more efficient
{ {
FBITFIELD blendmode = PF_Translucent;
if (rover->alpha == FFLOOR_ALPHA_SPECIAL_ADDITIVE)
blendmode = PF_Additive;
else if (rover->alpha == FFLOOR_ALPHA_SPECIAL_SUBTRACTIVE)
blendmode = PF_Substractive;
light = R_GetPlaneLight(gl_frontsector, centerHeight, dup_viewz < cullHeight ? true : false); light = R_GetPlaneLight(gl_frontsector, centerHeight, dup_viewz < cullHeight ? true : false);
HWR_AddTransparentFloor(&levelflats[*rover->toppic], HWR_AddTransparentFloor(&levelflats[*rover->toppic],
@ -3160,7 +3215,7 @@ static void HWR_Subsector(size_t num)
true, true,
*rover->topheight, *rover->topheight,
*gl_frontsector->lightlist[light].lightlevel, *gl_frontsector->lightlist[light].lightlevel,
rover->alpha-1 > 255 ? 255 : rover->alpha-1, rover->master->frontsector, (rover->flags & FF_RIPPLE ? PF_Ripple : 0)|PF_Translucent, rover->alpha-1 > 255 ? 255 : rover->alpha-1, rover->master->frontsector, (rover->flags & FF_RIPPLE ? PF_Ripple : 0)|blendmode,
false, *gl_frontsector->lightlist[light].extra_colormap); false, *gl_frontsector->lightlist[light].extra_colormap);
} }
else else

View file

@ -2231,9 +2231,9 @@ state_t states[NUMSTATES] =
{SPR_CHAN, 0, -1, {NULL}, 0, 0, S_NULL}, // S_CEZCHAIN {SPR_CHAN, 0, -1, {NULL}, 0, 0, S_NULL}, // S_CEZCHAIN
// Flame // Flame
{SPR_FLAM, FF_FULLBRIGHT|FF_ANIMATE, 3*8, {A_FlameParticle}, 7, 3, S_FLAME}, // S_FLAME {SPR_FLAM, FF_FULLBRIGHT|FF_ANIMATE|FF_TRANSADD, 3*8, {A_FlameParticle}, 7, 3, S_FLAME}, // S_FLAME
{SPR_FLAM, FF_FULLBRIGHT|FF_ANIMATE|8, TICRATE, {NULL}, 3, 3, S_NULL}, // S_FLAMEPARTICLE {SPR_FLAM, FF_FULLBRIGHT|FF_ANIMATE|FF_TRANSADD|8, TICRATE, {NULL}, 3, 3, S_NULL}, // S_FLAMEPARTICLE
{SPR_FLAM, FF_FULLBRIGHT|FF_ANIMATE, -1, {NULL}, 7, 3, S_NULL}, // S_FLAMEREST {SPR_FLAM, FF_FULLBRIGHT|FF_ANIMATE|FF_TRANSADD, -1, {NULL}, 7, 3, S_NULL}, // S_FLAMEREST
// Eggman statue // Eggman statue
{SPR_ESTA, 0, -1, {NULL}, 0, 0, S_NULL}, // S_EGGSTATUE1 {SPR_ESTA, 0, -1, {NULL}, 0, 0, S_NULL}, // S_EGGSTATUE1
@ -4383,10 +4383,10 @@ state_t states[NUMSTATES] =
{SPR_AUDI, 4|FF_ANIMATE, -1, {NULL}, 1, 17, S_NULL}, // S_AUDIENCE_CHAO_LOSE {SPR_AUDI, 4|FF_ANIMATE, -1, {NULL}, 1, 17, S_NULL}, // S_AUDIENCE_CHAO_LOSE
{SPR_FLAM, 0, 3, {NULL}, 0, 0, S_FLAYM2}, // S_FLAYM1, {SPR_FLAM, FF_FULLBRIGHT|FF_TRANSADD|0, 3, {NULL}, 0, 0, S_FLAYM2}, // S_FLAYM1,
{SPR_FLAM, 1, 3, {NULL}, 0, 0, S_FLAYM3}, // S_FLAYM2, {SPR_FLAM, FF_FULLBRIGHT|FF_TRANSADD|1, 3, {NULL}, 0, 0, S_FLAYM3}, // S_FLAYM2,
{SPR_FLAM, 2, 3, {NULL}, 0, 0, S_FLAYM4}, // S_FLAYM3, {SPR_FLAM, FF_FULLBRIGHT|FF_TRANSADD|2, 3, {NULL}, 0, 0, S_FLAYM4}, // S_FLAYM3,
{SPR_FLAM, 3, 3, {NULL}, 0, 0, S_FLAYM1}, // S_FLAYM4, {SPR_FLAM, FF_FULLBRIGHT|FF_TRANSADD|3, 3, {NULL}, 0, 0, S_FLAYM1}, // S_FLAYM4,
{SPR_DECO, 0, -1, {NULL}, 0, 0, S_NULL}, // S_DEVIL, {SPR_DECO, 0, -1, {NULL}, 0, 0, S_NULL}, // S_DEVIL,
{SPR_DECO, 1, -1, {NULL}, 0, 0, S_NULL}, // S_ANGEL, {SPR_DECO, 1, -1, {NULL}, 0, 0, S_NULL}, // S_ANGEL,

View file

@ -268,6 +268,8 @@ typedef enum
MFD_TRANS70 = 0x0070, MFD_TRANS70 = 0x0070,
MFD_TRANS80 = 0x0080, MFD_TRANS80 = 0x0080,
MFD_TRANS90 = 0x0090, MFD_TRANS90 = 0x0090,
MFD_TRANSADD = 0x00A0,
MFD_TRANSSUB = 0x00B0,
MFD_TRANSMASK = 0x00F0, MFD_TRANSMASK = 0x00F0,
// Brightness override flags // Brightness override flags
MFD_FULLBRIGHT = 0x0100, MFD_FULLBRIGHT = 0x0100,

View file

@ -212,7 +212,7 @@ static void Polyobj_GetInfo(polyobj_t *po, line_t *line)
if (po->parent == po->id) // do not allow a self-reference if (po->parent == po->id) // do not allow a self-reference
po->parent = -1; po->parent = -1;
po->translucency = max(min(line->args[2], NUMTRANSMAPS), 0); po->translucency = max(min(line->args[2], NUMEFFECTMAPS), 0);
po->flags = POF_SOLID|POF_TESTHEIGHT|POF_RENDERSIDES|POF_RENDERPLANES; po->flags = POF_SOLID|POF_TESTHEIGHT|POF_RENDERSIDES|POF_RENDERPLANES;
@ -2563,7 +2563,7 @@ void T_PolyObjFade(polyfade_t *th)
{ {
if (po->translucency >= NUMTRANSMAPS) if (po->translucency >= NUMTRANSMAPS)
// HACK: OpenGL renders fully opaque when >= NUMTRANSMAPS // HACK: OpenGL renders fully opaque when >= NUMTRANSMAPS
po->translucency = NUMTRANSMAPS-1; po->translucency = tr_trans90;
po->flags |= (po->spawnflags & POF_RENDERALL); po->flags |= (po->spawnflags & POF_RENDERALL);

View file

@ -59,6 +59,8 @@
#define FF_TRANS70 (tr_trans70<<FF_TRANSSHIFT) #define FF_TRANS70 (tr_trans70<<FF_TRANSSHIFT)
#define FF_TRANS80 (tr_trans80<<FF_TRANSSHIFT) #define FF_TRANS80 (tr_trans80<<FF_TRANSSHIFT)
#define FF_TRANS90 (tr_trans90<<FF_TRANSSHIFT) #define FF_TRANS90 (tr_trans90<<FF_TRANSSHIFT)
#define FF_TRANSADD (tr_transadd<<FF_TRANSSHIFT)
#define FF_TRANSSUB (tr_transsub<<FF_TRANSSHIFT)
/// \brief Frame flags: frame always appears full bright (mutually exclusive with below, currently takes priority) /// \brief Frame flags: frame always appears full bright (mutually exclusive with below, currently takes priority)
#define FF_FULLBRIGHT 0x00100000 #define FF_FULLBRIGHT 0x00100000
@ -99,7 +101,10 @@ typedef enum
tr_trans70, tr_trans70,
tr_trans80, tr_trans80,
tr_trans90, tr_trans90,
NUMTRANSMAPS NUMTRANSMAPS,
tr_transadd = NUMTRANSMAPS,
tr_transsub,
NUMEFFECTMAPS,
} transnum_t; } transnum_t;
#endif #endif

View file

@ -1213,7 +1213,7 @@ static void PolyTranslucency(line_t *line)
else else
po->translucency = value; po->translucency = value;
po->translucency = max(min(po->translucency, NUMTRANSMAPS), 0); po->translucency = max(min(po->translucency, NUMEFFECTMAPS), 0);
} }
// Makes a polyobject translucency fade and applies tangibility // Makes a polyobject translucency fade and applies tangibility

View file

@ -152,6 +152,9 @@ typedef enum
FF_GOOWATER = FF_SHATTERBOTTOM, ///< Used with ::FF_SWIMMABLE. Makes thick bouncey goop. FF_GOOWATER = FF_SHATTERBOTTOM, ///< Used with ::FF_SWIMMABLE. Makes thick bouncey goop.
} ffloortype_e; } ffloortype_e;
#define FFLOOR_ALPHA_SPECIAL_ADDITIVE (901)
#define FFLOOR_ALPHA_SPECIAL_SUBTRACTIVE (902)
typedef struct ffloor_s typedef struct ffloor_s
{ {
fixed_t *topheight; fixed_t *topheight;

View file

@ -81,7 +81,7 @@ UINT8 *dc_source;
// ----------------------- // -----------------------
// translucency stuff here // translucency stuff here
// ----------------------- // -----------------------
#define NUMTRANSTABLES 9 // how many translucency tables are used #define NUMTRANSTABLES 11 // how many translucency tables are used
UINT8 *transtables; // translucency tables UINT8 *transtables; // translucency tables
@ -172,6 +172,8 @@ void R_InitTranslationTables(void)
W_ReadLump(W_GetNumForName("TRANS70"), transtables+0x60000); W_ReadLump(W_GetNumForName("TRANS70"), transtables+0x60000);
W_ReadLump(W_GetNumForName("TRANS80"), transtables+0x70000); W_ReadLump(W_GetNumForName("TRANS80"), transtables+0x70000);
W_ReadLump(W_GetNumForName("TRANS90"), transtables+0x80000); W_ReadLump(W_GetNumForName("TRANS90"), transtables+0x80000);
W_ReadLump(W_GetNumForName("TRANSADD"),transtables+0x90000);
W_ReadLump(W_GetNumForName("TRANSSUB"),transtables+0xA0000);
} }
/** \brief Retrieves a translation colormap from the cache. /** \brief Retrieves a translation colormap from the cache.

View file

@ -780,7 +780,7 @@ void R_DrawSinglePlane(visplane_t *pl)
if (pl->polyobj) if (pl->polyobj)
{ {
// Hacked up support for alpha value in software mode Tails 09-24-2002 (sidenote: ported to polys 10-15-2014, there was no time travel involved -Red) // Hacked up support for alpha value in software mode Tails 09-24-2002 (sidenote: ported to polys 10-15-2014, there was no time travel involved -Red)
if (pl->polyobj->translucency >= 10) if (pl->polyobj->translucency >= NUMEFFECTMAPS)
return; // Don't even draw it return; // Don't even draw it
else if (pl->polyobj->translucency > 0) else if (pl->polyobj->translucency > 0)
{ {
@ -841,6 +841,10 @@ void R_DrawSinglePlane(visplane_t *pl)
ds_transmap = transtables + ((tr_trans20-1)<<FF_TRANSSHIFT); ds_transmap = transtables + ((tr_trans20-1)<<FF_TRANSSHIFT);
else if (pl->ffloor->alpha < 243) else if (pl->ffloor->alpha < 243)
ds_transmap = transtables + ((tr_trans10-1)<<FF_TRANSSHIFT); ds_transmap = transtables + ((tr_trans10-1)<<FF_TRANSSHIFT);
else if (pl->ffloor->alpha == FFLOOR_ALPHA_SPECIAL_ADDITIVE)
ds_transmap = transtables + ((tr_transadd-1)<<FF_TRANSSHIFT);
else if (pl->ffloor->alpha == FFLOOR_ALPHA_SPECIAL_SUBTRACTIVE)
ds_transmap = transtables + ((tr_transsub-1)<<FF_TRANSSHIFT);
else // Opaque, but allow transparent flat pixels else // Opaque, but allow transparent flat pixels
spanfunctype = SPANDRAWFUNC_SPLAT; spanfunctype = SPANDRAWFUNC_SPLAT;

View file

@ -279,9 +279,23 @@ static void R_Render2sidedMultiPatchColumn(column_t *column)
} }
} }
transnum_t R_GetLinedefTransTable(fixed_t alpha) transnum_t R_GetLinedefTransTable(line_t *ldef)
{ {
return (20*(FRACUNIT - alpha - 1) + FRACUNIT) >> (FRACBITS+1); transnum_t transnum = NUMEFFECTMAPS; // Send back NUMEFFECTMAPS for none
fixed_t alpha = ldef->alpha;
if (alpha > 0 && alpha < FRACUNIT)
transnum = (20*(FRACUNIT - alpha - 1) + FRACUNIT) >> (FRACBITS+1);
else
{
switch (ldef->special)
{
case 910: transnum = tr_transadd; break;
case 911: transnum = tr_transsub; break;
default: transnum = NUMEFFECTMAPS; break;
}
}
return transnum;
} }
void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
@ -298,6 +312,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
INT32 times, repeats; INT32 times, repeats;
INT64 overflow_test; INT64 overflow_test;
INT32 range; INT32 range;
transnum_t transtable = NUMEFFECTMAPS;
// Calculate light table. // Calculate light table.
// Use different light tables // Use different light tables
@ -314,9 +329,10 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
if (!ldef->alpha) if (!ldef->alpha)
return; return;
if (ldef->alpha > 0 && ldef->alpha < FRACUNIT) transtable = R_GetLinedefTransTable(ldef);
if (transtable != NUMEFFECTMAPS)
{ {
dc_transmap = transtables + ((R_GetLinedefTransTable(ldef->alpha) - 1) << FF_TRANSSHIFT); dc_transmap = transtables + ((transtable - 1) << FF_TRANSSHIFT);
colfunc = colfuncs[COLDRAWFUNC_FUZZY]; colfunc = colfuncs[COLDRAWFUNC_FUZZY];
} }
@ -331,7 +347,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
if (curline->polyseg && curline->polyseg->translucency > 0) if (curline->polyseg && curline->polyseg->translucency > 0)
{ {
if (curline->polyseg->translucency >= NUMTRANSMAPS) if (curline->polyseg->translucency >= NUMEFFECTMAPS)
return; return;
dc_transmap = transtables + ((curline->polyseg->translucency-1)<<FF_TRANSSHIFT); dc_transmap = transtables + ((curline->polyseg->translucency-1)<<FF_TRANSSHIFT);
@ -781,6 +797,10 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
dc_transmap = transtables + ((tr_trans20-1)<<FF_TRANSSHIFT); dc_transmap = transtables + ((tr_trans20-1)<<FF_TRANSSHIFT);
else if (pfloor->alpha < 243) else if (pfloor->alpha < 243)
dc_transmap = transtables + ((tr_trans10-1)<<FF_TRANSSHIFT); dc_transmap = transtables + ((tr_trans10-1)<<FF_TRANSSHIFT);
else if (pfloor->alpha == FFLOOR_ALPHA_SPECIAL_ADDITIVE)
dc_transmap = transtables + ((tr_transadd-1)<<FF_TRANSSHIFT);
else if (pfloor->alpha == FFLOOR_ALPHA_SPECIAL_SUBTRACTIVE)
dc_transmap = transtables + ((tr_transsub-1)<<FF_TRANSSHIFT);
else else
fuzzy = false; // Opaque fuzzy = false; // Opaque

View file

@ -18,7 +18,7 @@
#pragma interface #pragma interface
#endif #endif
transnum_t R_GetLinedefTransTable(fixed_t alpha); transnum_t R_GetLinedefTransTable(line_t *line);
void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2); void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2);
void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pffloor); void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pffloor);
void R_StoreWallRange(INT32 start, INT32 stop); void R_StoreWallRange(INT32 start, INT32 stop);