Merge branch 'master' into model-texture-fix

This commit is contained in:
Sally Coolatta 2020-10-28 15:58:00 -04:00
commit bac7de9b0f
16 changed files with 359 additions and 210 deletions

View file

@ -1116,7 +1116,7 @@ static void IdentifyVersion(void)
}
MUSICTEST("sounds.wad")
MUSICTEST("music.wad")
MUSICTEST("music.pk3")
#undef MUSICTEST

View file

@ -11123,6 +11123,8 @@ struct {
{"FF_TRANS70",FF_TRANS70},
{"FF_TRANS80",FF_TRANS80},
{"FF_TRANS90",FF_TRANS90},
{"FF_TRANSADD",FF_TRANSADD},
{"FF_TRANSSUB",FF_TRANSSUB},
// compatibility
// Transparency for SOCs is pre-shifted
{"TR_TRANS10",tr_trans10<<FF_TRANSSHIFT},
@ -11134,6 +11136,8 @@ struct {
{"TR_TRANS70",tr_trans70<<FF_TRANSSHIFT},
{"TR_TRANS80",tr_trans80<<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.
{"tr_trans10",tr_trans10},
{"tr_trans20",tr_trans20},
@ -11145,6 +11149,9 @@ struct {
{"tr_trans80",tr_trans80},
{"tr_trans90",tr_trans90},
{"NUMTRANSMAPS",NUMTRANSMAPS},
{"tr_transadd",tr_transadd},
{"tr_transsub",tr_transsub},
{"NUMEFFECTMAPS",NUMEFFECTMAPS},
// Type of levels
{"TOL_RACE",TOL_RACE},
@ -11653,6 +11660,8 @@ struct {
{"MFD_TRANS70",MFD_TRANS70},
{"MFD_TRANS80",MFD_TRANS80},
{"MFD_TRANS90",MFD_TRANS90},
{"MFD_TRANSADD",MFD_TRANSADD},
{"MFD_TRANSSUB",MFD_TRANSSUB},
{"MFD_TRANSMASK",MFD_TRANSMASK},
{"MFD_FULLBRIGHT",MFD_FULLBRIGHT},
{"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);
if (PolyFlags & (PF_Translucent|PF_Fog))
if (PolyFlags & (PF_Translucent|PF_Additive|PF_Substractive|PF_Fog))
{
Surf.PolyColor.s.alpha = (UINT8)alpha;
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_trans80 : pSurf->PolyColor.s.alpha = 0x33;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;
}
@ -856,7 +858,7 @@ static float HWR_ClipViewSegment(INT32 x, polyvertex_t *v1, polyvertex_t *v2)
//
// 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
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[1].y = endbot;
if (cutflag & FF_FOG)
HWR_AddTransparentWall(wallVerts, Surf, texnum, PF_Fog|PF_NoTexture, true, lightnum, colormap);
else if (cutflag & FF_TRANSLUCENT)
HWR_AddTransparentWall(wallVerts, Surf, texnum, PF_Translucent, false, lightnum, colormap);
if (blendmode & PF_Fog)
HWR_AddTransparentWall(wallVerts, Surf, texnum, blendmode, true, lightnum, colormap);
else if (blendmode & (PF_Translucent|PF_Additive|PF_Substractive|PF_Environment))
HWR_AddTransparentWall(wallVerts, Surf, texnum, blendmode, false, lightnum, colormap);
else
HWR_ProjectWall(wallVerts, Surf, PF_Masked, lightnum, colormap);
HWR_ProjectWall(wallVerts, Surf, blendmode, lightnum, colormap);
top = bot;
endtop = endbot;
@ -1022,12 +1024,12 @@ static void HWR_SplitWall(sector_t *sector, FOutVector *wallVerts, INT32 texnum,
wallVerts[0].y = bot;
wallVerts[1].y = endbot;
if (cutflag & FF_FOG)
HWR_AddTransparentWall(wallVerts, Surf, texnum, PF_Fog|PF_NoTexture, true, lightnum, colormap);
else if (cutflag & FF_TRANSLUCENT)
HWR_AddTransparentWall(wallVerts, Surf, texnum, PF_Translucent, false, lightnum, colormap);
if (blendmode & PF_Fog)
HWR_AddTransparentWall(wallVerts, Surf, texnum, blendmode, true, lightnum, colormap);
else if (blendmode & (PF_Translucent|PF_Additive|PF_Substractive|PF_Environment))
HWR_AddTransparentWall(wallVerts, Surf, texnum, blendmode, false, lightnum, colormap);
else
HWR_ProjectWall(wallVerts, Surf, PF_Masked, lightnum, colormap);
HWR_ProjectWall(wallVerts, Surf, blendmode, lightnum, colormap);
}
// 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[1].y = FIXED_TO_FLOAT(worldhighslope);
if (gl_frontsector->numlights)
HWR_SplitWall(gl_frontsector, wallVerts, gl_toptexture, &Surf, FF_CUTLEVEL, NULL);
else if (grTex->mipmap.flags & TF_TRANSPARENT)
HWR_AddTransparentWall(wallVerts, &Surf, gl_toptexture, PF_Environment, false, lightnum, colormap);
else
HWR_ProjectWall(wallVerts, &Surf, PF_Masked, lightnum, colormap);
{
FBITFIELD blendmode = PF_Masked;
if (grTex->mipmap.flags & TF_TRANSPARENT)
blendmode = PF_Environment;
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
@ -1273,12 +1282,19 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
wallVerts[2].y = FIXED_TO_FLOAT(worldlowslope);
wallVerts[1].y = FIXED_TO_FLOAT(worldbottomslope);
if (gl_frontsector->numlights)
HWR_SplitWall(gl_frontsector, wallVerts, gl_bottomtexture, &Surf, FF_CUTLEVEL, NULL);
else if (grTex->mipmap.flags & TF_TRANSPARENT)
HWR_AddTransparentWall(wallVerts, &Surf, gl_bottomtexture, PF_Environment, false, lightnum, colormap);
else
HWR_ProjectWall(wallVerts, &Surf, PF_Masked, lightnum, colormap);
{
FBITFIELD blendmode = PF_Masked;
if (grTex->mipmap.flags & TF_TRANSPARENT)
blendmode = PF_Environment;
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);
if (gl_midtexture)
@ -1472,16 +1488,19 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
blendmode = PF_Translucent;
break;
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
blendmode = PF_Masked;
break;
}
}
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
blendmode = PF_Masked;
@ -1493,10 +1512,10 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
if (gl_frontsector->numlights)
{
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
{
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))
@ -1577,15 +1596,21 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
wallVerts[2].y = FIXED_TO_FLOAT(worldtopslope);
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)
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
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);
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
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;
if (rover->flags & FF_TRANSLUCENT && rover->alpha < 256)
if (rover->flags & FF_TRANSLUCENT)
{
blendmode = PF_Translucent;
Surf.PolyColor.s.alpha = (UINT8)rover->alpha-1 > 255 ? 255 : rover->alpha-1;
if (rover->alpha < 256)
{
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)
HWR_SplitWall(gl_frontsector, wallVerts, texnum, &Surf, rover->flags, rover);
HWR_SplitWall(gl_frontsector, wallVerts, texnum, &Surf, rover->flags, rover, blendmode);
else
{
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);
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
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;
if (rover->flags & FF_TRANSLUCENT && rover->alpha < 256)
if (rover->flags & FF_TRANSLUCENT)
{
blendmode = PF_Translucent;
Surf.PolyColor.s.alpha = (UINT8)rover->alpha-1 > 255 ? 255 : rover->alpha-1;
if (rover->alpha < 256)
{
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)
HWR_SplitWall(gl_backsector, wallVerts, texnum, &Surf, rover->flags, rover);
HWR_SplitWall(gl_backsector, wallVerts, texnum, &Surf, rover->flags, rover, blendmode);
else
{
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
continue;
if (po_ptrs[i]->translucency >= NUMTRANSMAPS)
if (po_ptrs[i]->translucency >= NUMEFFECTMAPS)
continue;
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,
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);
HWR_AddTransparentFloor(&levelflats[*rover->bottompic],
@ -3115,7 +3162,7 @@ static void HWR_Subsector(size_t num)
false,
*rover->bottomheight,
*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);
}
else
@ -3151,8 +3198,16 @@ static void HWR_Subsector(size_t num)
alpha, rover->master->frontsector, PF_Fog|PF_NoTexture,
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);
HWR_AddTransparentFloor(&levelflats[*rover->toppic],
@ -3160,7 +3215,7 @@ static void HWR_Subsector(size_t num)
true,
*rover->topheight,
*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);
}
else

View file

@ -2231,9 +2231,9 @@ state_t states[NUMSTATES] =
{SPR_CHAN, 0, -1, {NULL}, 0, 0, S_NULL}, // S_CEZCHAIN
// Flame
{SPR_FLAM, FF_FULLBRIGHT|FF_ANIMATE, 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, -1, {NULL}, 7, 3, S_NULL}, // S_FLAMEREST
{SPR_FLAM, FF_FULLBRIGHT|FF_ANIMATE|FF_TRANSADD, 3*8, {A_FlameParticle}, 7, 3, S_FLAME}, // S_FLAME
{SPR_FLAM, FF_FULLBRIGHT|FF_ANIMATE|FF_TRANSADD|8, TICRATE, {NULL}, 3, 3, S_NULL}, // S_FLAMEPARTICLE
{SPR_FLAM, FF_FULLBRIGHT|FF_ANIMATE|FF_TRANSADD, -1, {NULL}, 7, 3, S_NULL}, // S_FLAMEREST
// Eggman statue
{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_FLAM, 0, 3, {NULL}, 0, 0, S_FLAYM2}, // S_FLAYM1,
{SPR_FLAM, 1, 3, {NULL}, 0, 0, S_FLAYM3}, // S_FLAYM2,
{SPR_FLAM, 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|0, 3, {NULL}, 0, 0, S_FLAYM2}, // S_FLAYM1,
{SPR_FLAM, FF_FULLBRIGHT|FF_TRANSADD|1, 3, {NULL}, 0, 0, S_FLAYM3}, // S_FLAYM2,
{SPR_FLAM, FF_FULLBRIGHT|FF_TRANSADD|2, 3, {NULL}, 0, 0, S_FLAYM4}, // S_FLAYM3,
{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, 1, -1, {NULL}, 0, 0, S_NULL}, // S_ANGEL,

View file

@ -268,6 +268,8 @@ typedef enum
MFD_TRANS70 = 0x0070,
MFD_TRANS80 = 0x0080,
MFD_TRANS90 = 0x0090,
MFD_TRANSADD = 0x00A0,
MFD_TRANSSUB = 0x00B0,
MFD_TRANSMASK = 0x00F0,
// Brightness override flags
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
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;
@ -2563,7 +2563,7 @@ void T_PolyObjFade(polyfade_t *th)
{
if (po->translucency >= NUMTRANSMAPS)
// HACK: OpenGL renders fully opaque when >= NUMTRANSMAPS
po->translucency = NUMTRANSMAPS-1;
po->translucency = tr_trans90;
po->flags |= (po->spawnflags & POF_RENDERALL);

View file

@ -59,6 +59,8 @@
#define FF_TRANS70 (tr_trans70<<FF_TRANSSHIFT)
#define FF_TRANS80 (tr_trans80<<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)
#define FF_FULLBRIGHT 0x00100000
@ -99,7 +101,10 @@ typedef enum
tr_trans70,
tr_trans80,
tr_trans90,
NUMTRANSMAPS
NUMTRANSMAPS,
tr_transadd = NUMTRANSMAPS,
tr_transsub,
NUMEFFECTMAPS,
} transnum_t;
#endif

View file

@ -1213,7 +1213,7 @@ static void PolyTranslucency(line_t *line)
else
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

View file

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

View file

@ -81,7 +81,7 @@ UINT8 *dc_source;
// -----------------------
// 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
@ -172,6 +172,8 @@ void R_InitTranslationTables(void)
W_ReadLump(W_GetNumForName("TRANS70"), transtables+0x60000);
W_ReadLump(W_GetNumForName("TRANS80"), transtables+0x70000);
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.

View file

@ -780,7 +780,7 @@ void R_DrawSinglePlane(visplane_t *pl)
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)
if (pl->polyobj->translucency >= 10)
if (pl->polyobj->translucency >= NUMEFFECTMAPS)
return; // Don't even draw it
else if (pl->polyobj->translucency > 0)
{
@ -841,6 +841,10 @@ void R_DrawSinglePlane(visplane_t *pl)
ds_transmap = transtables + ((tr_trans20-1)<<FF_TRANSSHIFT);
else if (pl->ffloor->alpha < 243)
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
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)
@ -298,6 +312,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
INT32 times, repeats;
INT64 overflow_test;
INT32 range;
transnum_t transtable = NUMEFFECTMAPS;
// Calculate light table.
// Use different light tables
@ -314,9 +329,10 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
if (!ldef->alpha)
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];
}
@ -331,7 +347,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
if (curline->polyseg && curline->polyseg->translucency > 0)
{
if (curline->polyseg->translucency >= NUMTRANSMAPS)
if (curline->polyseg->translucency >= NUMEFFECTMAPS)
return;
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);
else if (pfloor->alpha < 243)
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
fuzzy = false; // Opaque

View file

@ -18,7 +18,7 @@
#pragma interface
#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_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pffloor);
void R_StoreWallRange(INT32 start, INT32 stop);

View file

@ -1598,172 +1598,219 @@ static tic_t pause_starttic;
/// Music Definitions
/// ------------------------
enum
{
MUSICDEF_20,
};
musicdef_t *musicdefstart = NULL;
struct cursongcredit cursongcredit; // Currently displayed song credit info
int musicdef_volume;
//
// search for music definition in wad
//
static UINT16 W_CheckForMusicDefInPwad(UINT16 wadid)
{
UINT16 i;
lumpinfo_t *lump_p;
static boolean
MusicDefError
(
alerttype_t level,
const char * description,
const char * field,
lumpnum_t lumpnum,
int line
){
const wadfile_t * wad = wadfiles[WADFILENUM (lumpnum)];
const lumpinfo_t * lump = &wad->lumpinfo[LUMPNUM (lumpnum)];
lump_p = wadfiles[wadid]->lumpinfo;
for (i = 0; i < wadfiles[wadid]->numlumps; i++, lump_p++)
if (memcmp(lump_p->name, "MUSICDEF", 8) == 0)
return i;
CONS_Alert(level,
va("%%s|%%s: %s (line %%d)\n", description),
wad->filename,
lump->fullname,
field,
line
);
return INT16_MAX; // not found
return false;
}
void S_LoadMusicDefs(UINT16 wadnum)
{
UINT16 lump;
char *buf;
char *buf2;
char *stoken;
static boolean
ReadMusicDefFields
(
lumpnum_t lumpnum,
int line,
char * stoken,
musicdef_t ** defp
){
musicdef_t *def;
char *value;
size_t size;
musicdef_t *def, *prev;
UINT16 line = 1; // for better error msgs
char *textline;
lump = W_CheckForMusicDefInPwad(wadnum);
if (lump == INT16_MAX)
return;
buf = W_CacheLumpNumPwad(wadnum, lump, PU_CACHE);
size = W_LumpLengthPwad(wadnum, lump);
// for strtok
buf2 = malloc(size+1);
if (!buf2)
I_Error("S_LoadMusicDefs: No more free memory\n");
M_Memcpy(buf2,buf,size);
buf2[size] = '\0';
def = prev = NULL;
stoken = strtok (buf2, "\r\n ");
// Find music def
while (stoken)
if (!stricmp(stoken, "lump"))
{
/*if ((stoken[0] == '/' && stoken[1] == '/')
|| (stoken[0] == '#')) // skip comments
value = strtok(NULL, " ");
if (!value)
{
stoken = strtok(NULL, "\r\n"); // skip end of line
if (def)
stoken = strtok(NULL, "\r\n= ");
else
stoken = strtok(NULL, "\r\n ");
line++;
}
else*/ if (!stricmp(stoken, "lump"))
{
value = strtok(NULL, "\r\n ");
if (!value)
{
CONS_Alert(CONS_WARNING, "MUSICDEF: Lump '%s' is missing name. (file %s, line %d)\n", stoken, wadfiles[wadnum]->filename, line);
stoken = strtok(NULL, "\r\n"); // skip end of line
goto skip_lump;
}
// No existing musicdefs
if (!musicdefstart)
{
musicdefstart = Z_Calloc(sizeof (musicdef_t), PU_STATIC, NULL);
STRBUFCPY(musicdefstart->name, value);
strlwr(musicdefstart->name);
def = musicdefstart;
//CONS_Printf("S_LoadMusicDefs: Initialized musicdef w/ song '%s'\n", def->name);
}
else
{
def = musicdefstart;
// Search if this is a replacement
//CONS_Printf("S_LoadMusicDefs: Searching for song replacement...\n");
while (def)
{
if (!stricmp(def->name, value))
{
//CONS_Printf("S_LoadMusicDefs: Found song replacement '%s'\n", def->name);
break;
}
prev = def;
def = def->next;
}
// Nothing found, add to the end.
if (!def)
{
def = Z_Calloc(sizeof (musicdef_t), PU_STATIC, NULL);
STRBUFCPY(def->name, value);
strlwr(def->name);
if (prev != NULL)
prev->next = def;
//CONS_Printf("S_LoadMusicDefs: Added song '%s'\n", def->name);
}
}
def->volume = DEFAULT_MUSICDEF_VOLUME;
skip_lump:
stoken = strtok(NULL, "\r\n ");
line++;
return MusicDefError(CONS_WARNING,
"Field '%'s is missing name.",
stoken, lumpnum, line);
}
else
{
value = strtok(NULL, "\r\n= ");
musicdef_t **tail = &musicdefstart;
if (!value)
// Search if this is a replacement
while (*tail)
{
CONS_Alert(CONS_WARNING, "MUSICDEF: Field '%s' is missing value. (file %s, line %d)\n", stoken, wadfiles[wadnum]->filename, line);
stoken = strtok(NULL, "\r\n"); // skip end of line
goto skip_field;
if (!stricmp((*tail)->name, value))
{
break;
}
tail = &(*tail)->next;
}
// Nothing found, add to the end.
if (!(*tail))
{
def = Z_Calloc(sizeof (musicdef_t), PU_STATIC, NULL);
STRBUFCPY(def->name, value);
strlwr(def->name);
def->volume = DEFAULT_MUSICDEF_VOLUME;
(*tail) = def;
}
(*defp) = (*tail);
}
}
else
{
value = strtok(NULL, "");
if (value)
{
// Find the equals sign.
value = strchr(value, '=');
}
if (!value)
{
return MusicDefError(CONS_WARNING,
"Field '%s' is missing value.",
stoken, lumpnum, line);
}
else
{
def = (*defp);
if (!def)
{
CONS_Alert(CONS_ERROR, "MUSICDEF: No music definition before field '%s'. (file %s, line %d)\n", stoken, wadfiles[wadnum]->filename, line);
free(buf2);
return;
return MusicDefError(CONS_ERROR,
"No music definition before field '%s'.",
stoken, lumpnum, line);
}
// Skip the equals sign.
value++;
// Now skip funny whitespace.
value += strspn(value, "\t ");
textline = value;
/* based ignored lumps */
if (!stricmp(stoken, "usage")) {
#if 0 // Ignore for now
STRBUFCPY(def->usage, value);
for (value = def->usage; *value; value++)
if (*value == '_') *value = ' '; // turn _ into spaces.
//CONS_Printf("S_LoadMusicDefs: Set usage to '%s'\n", def->usage);
STRBUFCPY(def->usage, textline);
#endif
} else if (!stricmp(stoken, "source")) {
STRBUFCPY(def->source, value);
for (value = def->source; *value; value++)
if (*value == '_') *value = ' '; // turn _ into spaces.
//CONS_Printf("S_LoadMusicDefs: Set source to '%s'\n", def->source);
STRBUFCPY(def->source, textline);
} else if (!stricmp(stoken, "volume")) {
def->volume = atoi(value);
def->volume = atoi(textline);
} else {
CONS_Alert(CONS_WARNING, "MUSICDEF: Invalid field '%s'. (file %s, line %d)\n", stoken, wadfiles[wadnum]->filename, line);
MusicDefError(CONS_WARNING,
"Unknown field '%s'.",
stoken, lumpnum, line);
}
skip_field:
stoken = strtok(NULL, "\r\n= ");
line++;
}
}
free(buf2);
return;
return true;
}
static void S_LoadMusicDefLump(lumpnum_t lumpnum)
{
char *lump;
char *musdeftext;
size_t size;
char *lf;
char *stoken;
size_t nlf;
size_t ncr;
musicdef_t *def = NULL;
int line = 1; // for better error msgs
lump = W_CacheLumpNum(lumpnum, PU_CACHE);
size = W_LumpLength(lumpnum);
// Null-terminated MUSICDEF lump.
musdeftext = malloc(size+1);
if (!musdeftext)
I_Error("S_LoadMusicDefs: No more free memory for the parser\n");
M_Memcpy(musdeftext, lump, size);
musdeftext[size] = '\0';
// Find music def
stoken = musdeftext;
for (;;)
{
lf = strpbrk(stoken, "\r\n");
if (lf)
{
if (*lf == '\n')
nlf = 1;
else
nlf = 0;
*lf++ = '\0';/* now we can delimit to here */
}
stoken = strtok(stoken, " ");
if (stoken)
{
if (! ReadMusicDefFields(lumpnum, line, stoken, &def))
break;
}
if (lf)
{
do
{
line += nlf;
ncr = strspn(lf, "\r");/* skip CR */
lf += ncr;
nlf = strspn(lf, "\n");
lf += nlf;
}
while (nlf || ncr) ;
stoken = lf;/* now the next nonempty line */
}
else
break;/* EOF */
}
free(musdeftext);
}
void S_LoadMusicDefs(UINT16 wad)
{
const lumpnum_t wadnum = wad << 16;
UINT16 lump = 0;
while (( lump = W_CheckNumForNamePwad("MUSICDEF", wad, lump) ) != INT16_MAX)
{
S_LoadMusicDefLump(wadnum | lump);
lump++;
}
}
//

View file

@ -118,13 +118,16 @@ anchor_height
const mapthing_t * a,
const sector_t * s
){
const fixed_t x = a->x << FRACBITS;
const fixed_t y = a->y << FRACBITS;
if (a->options & MTF_OBJECTFLIP)
{
return ( s->ceilingheight >> FRACBITS ) - a->z;
return ( P_GetSectorCeilingZAt(s, x, y) >> FRACBITS ) - a->z;
}
else
{
return ( s->floorheight >> FRACBITS ) + a->z;
return ( P_GetSectorFloorZAt(s, x, y) >> FRACBITS ) + a->z;
}
}
@ -144,13 +147,13 @@ set_anchor
fixed_t closeness;
a->z = anchor_height(a, sub->sector);
v = nearest_point(&closeness, a, sub->sector);
a->x = ( v->x >> FRACBITS );
a->y = ( v->y >> FRACBITS );
a->z = anchor_height(a, sub->sector);
list->anchors [list->count] = a;
list->points [list->count] = v;
list->closeness[list->count] = closeness;

View file

@ -54,9 +54,8 @@ main (int ac, char **av)
if (( var = strtok(buf, " =") ))
{
if (!(
strcasecmp(var, "TITLE") &&
strcasecmp(var, "ALTTITLE") &&
strcasecmp(var, "AUTHORS")
strcasecmp(var, "USAGE") &&
strcasecmp(var, "SOURCE")
)){
if (( val = strtok(0, "") ))
{