Currently WIP: Blendmode and transparency support for MORE STUFF, including FOFs and linedefs (ported from Kart internal).

(I haven't been able to test this port due to requiring a patch.pk3 I do not have, and the Colour Cube settings are currently broken, but wanted to get the bulk of the work done while I had spare time and energy to later patch up.)
This commit is contained in:
toaster 2021-04-28 20:24:39 +01:00
parent 1355a82aa5
commit d066c47b21
28 changed files with 690 additions and 570 deletions

View file

@ -22,6 +22,7 @@
#include "v_video.h" // video flags (for lua)
#include "i_sound.h" // musictype_t (for lua)
#include "g_state.h" // gamestate_t (for lua)
#include "r_data.h" // patchalphastyle_t
#include "deh_tables.h"
@ -4841,6 +4842,13 @@ struct int_const_s const INT_CONST[] = {
{"FF_VERTICALFLIP",FF_VERTICALFLIP},
{"FF_HORIZONTALFLIP",FF_HORIZONTALFLIP},
{"FF_PAPERSPRITE",FF_PAPERSPRITE},
{"FF_FLOORSPRITE",FF_FLOORSPRITE},
{"FF_BLENDMASK",FF_BLENDMASK},
{"FF_BLENDSHIFT",FF_BLENDSHIFT},
{"FF_ADD",FF_ADD},
{"FF_SUBTRACT",FF_SUBTRACT},
{"FF_REVERSESUBTRACT",FF_REVERSESUBTRACT},
{"FF_MODULATE",FF_MODULATE},
{"FF_TRANSMASK",FF_TRANSMASK},
{"FF_TRANSSHIFT",FF_TRANSSHIFT},
// new preshifted translucency (used in source)
@ -4895,9 +4903,10 @@ struct int_const_s const INT_CONST[] = {
{"RF_OBJECTSLOPESPLAT",RF_OBJECTSLOPESPLAT},
{"RF_NOSPLATBILLBOARD",RF_NOSPLATBILLBOARD},
{"RF_NOSPLATROLLANGLE",RF_NOSPLATROLLANGLE},
{"RF_BLENDMASK",RF_BLENDMASK},
{"RF_BRIGHTMASK",RF_BRIGHTMASK},
{"RF_FULLBRIGHT",RF_FULLBRIGHT},
{"RF_FULLDARK",RF_FULLDARK},
{"RF_SEMIBRIGHT",RF_SEMIBRIGHT},
{"RF_NOCOLORMAPS",RF_NOCOLORMAPS},
{"RF_SPRITETYPEMASK",RF_SPRITETYPEMASK},
{"RF_PAPERSPRITE",RF_PAPERSPRITE},
@ -4905,6 +4914,27 @@ struct int_const_s const INT_CONST[] = {
{"RF_SHADOWDRAW",RF_SHADOWDRAW},
{"RF_SHADOWEFFECTS",RF_SHADOWEFFECTS},
{"RF_DROPSHADOW",RF_DROPSHADOW},
{"RF_DONTDRAW",RF_DONTDRAW},
{"RF_BLENDMASK",RF_BLENDMASK},
{"RF_BLENDSHIFT",RF_BLENDSHIFT},
{"RF_ADD",RF_ADD},
{"RF_SUBTRACT",RF_SUBTRACT},
{"RF_REVERSESUBTRACT",RF_REVERSESUBTRACT},
{"RF_MODULATE",RF_MODULATE},
{"RF_OVERLAY",RF_OVERLAY},
{"RF_TRANSMASK",RF_TRANSMASK},
{"RF_TRANSSHIFT",RF_TRANSSHIFT},
{"RF_TRANS10",RF_TRANS10},
{"RF_TRANS20",RF_TRANS20},
{"RF_TRANS30",RF_TRANS30},
{"RF_TRANS40",RF_TRANS40},
{"RF_TRANS50",RF_TRANS50},
{"RF_TRANS60",RF_TRANS60},
{"RF_TRANS70",RF_TRANS70},
{"RF_TRANS80",RF_TRANS80},
{"RF_TRANS90",RF_TRANS90},
{"RF_GHOSTLY",RF_GHOSTLY},
{"RF_GHOSTLYMASK",RF_GHOSTLYMASK},
// Level flags
{"LF_SCRIPTISFILE",LF_SCRIPTISFILE},
@ -5380,9 +5410,12 @@ struct int_const_s const INT_CONST[] = {
{"V_HUDTRANSHALF",V_HUDTRANSHALF},
{"V_HUDTRANS",V_HUDTRANS},
{"V_HUDTRANSDOUBLE",V_HUDTRANSDOUBLE},
{"V_AUTOFADEOUT",V_AUTOFADEOUT},
{"V_RETURN8",V_RETURN8},
{"V_OFFSET",V_OFFSET},
{"V_BLENDSHIFT",V_BLENDSHIFT},
{"V_BLENDMASK",V_BLENDMASK},
{"V_ADD",V_ADD},
{"V_SUBTRACT",V_SUBTRACT},
{"V_REVERSESUBTRACT",V_REVERSESUBTRACT},
{"V_MODULATE",V_MODULATE},
{"V_ALLOWLOWERCASE",V_ALLOWLOWERCASE},
{"V_FLIP",V_FLIP},
{"V_CENTERNAMETAG",V_CENTERNAMETAG},
@ -5390,8 +5423,8 @@ struct int_const_s const INT_CONST[] = {
{"V_SNAPTOBOTTOM",V_SNAPTOBOTTOM},
{"V_SNAPTOLEFT",V_SNAPTOLEFT},
{"V_SNAPTORIGHT",V_SNAPTORIGHT},
{"V_WRAPX",V_WRAPX},
{"V_WRAPY",V_WRAPY},
{"V_AUTOFADEOUT",V_AUTOFADEOUT},
{"V_RETURN8",V_RETURN8},
{"V_NOSCALESTART",V_NOSCALESTART},
{"V_PERPLAYER",V_PERPLAYER},

View file

@ -119,11 +119,6 @@ void HWR_DrawPatch(patch_t *gpatch, INT32 x, INT32 y, INT32 option)
flags = PF_Translucent|PF_NoDepthTest;
if (option & V_WRAPX)
flags |= PF_ForceWrapX;
if (option & V_WRAPY)
flags |= PF_ForceWrapY;
// clip it since it is used for bunny scroll in doom I
HWD.pfnDrawPolygon(NULL, v, 4, flags);
}
@ -134,7 +129,7 @@ void HWR_DrawStretchyFixedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t p
FBITFIELD flags;
float cx = FIXED_TO_FLOAT(x);
float cy = FIXED_TO_FLOAT(y);
UINT8 alphalevel = ((option & V_ALPHAMASK) >> V_ALPHASHIFT);
UINT32 alphalevel, blendmode;
GLPatch_t *hwrPatch;
// 3--2
@ -145,9 +140,6 @@ void HWR_DrawStretchyFixedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t p
UINT8 perplayershuffle = 0;
if (alphalevel >= 10 && alphalevel < 13)
return;
// make patch ready in hardware cache
if (!colormap)
HWR_GetPatch(gpatch);
@ -191,15 +183,9 @@ void HWR_DrawStretchyFixedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t p
offsetx = (float)(gpatch->leftoffset) * fscalew;
// top offset
// TODO: make some kind of vertical version of V_FLIP, maybe by deprecating V_OFFSET in future?!?
// TODO: make some kind of vertical version of V_FLIP
offsety = (float)(gpatch->topoffset) * fscaleh;
if ((option & (V_NOSCALESTART|V_OFFSET)) == (V_NOSCALESTART|V_OFFSET)) // Multiply by dupx/dupy for crosshairs
{
offsetx *= dupx;
offsety *= dupy;
}
cx -= offsetx;
cy -= offsety;
}
@ -359,27 +345,32 @@ void HWR_DrawStretchyFixedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t p
v[0].t = v[1].t = 0.0f;
v[2].t = v[3].t = hwrPatch->max_t;
flags = PF_Translucent|PF_NoDepthTest;
if (option & V_WRAPX)
flags |= PF_ForceWrapX;
if (option & V_WRAPY)
flags |= PF_ForceWrapY;
flags = PF_NoDepthTest;
// clip it since it is used for bunny scroll in doom I
if (alphalevel)
if ((blendmode = ((option & V_BLENDMASK) >> V_BLENDSHIFT)))
blendmode++; // realign to constants
if ((alphalevel = ((option & V_ALPHAMASK) >> V_ALPHASHIFT)) || blendmode)
{
FSurfaceInfo Surf;
Surf.PolyColor.s.red = Surf.PolyColor.s.green = Surf.PolyColor.s.blue = 0xff;
if (alphalevel == 13) Surf.PolyColor.s.alpha = softwaretranstogl_lo[st_translucency];
else if (alphalevel == 14) Surf.PolyColor.s.alpha = softwaretranstogl[st_translucency];
else if (alphalevel == 15) Surf.PolyColor.s.alpha = softwaretranstogl_hi[st_translucency];
else Surf.PolyColor.s.alpha = softwaretranstogl[10-alphalevel];
flags |= HWR_GetBlendModeFlag(blendmode);
if (alphalevel == 10)
Surf.PolyColor.s.alpha = softwaretranstogl_lo[st_translucency];
else if (alphalevel == 11)
Surf.PolyColor.s.alpha = softwaretranstogl[st_translucency];
else if (alphalevel == 12)
Surf.PolyColor.s.alpha = softwaretranstogl_hi[st_translucency];
else
Surf.PolyColor.s.alpha = softwaretranstogl[10-alphalevel];
flags |= PF_Modulated;
HWD.pfnDrawPolygon(&Surf, v, 4, flags);
HWD.pfnDrawPolygon(&Surf, v, 4, flags|PF_Modulated);
}
else
HWD.pfnDrawPolygon(NULL, v, 4, flags);
HWD.pfnDrawPolygon(NULL, v, 4, flags|PF_Translucent);
}
void HWR_DrawCroppedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale, INT32 option, fixed_t sx, fixed_t sy, fixed_t w, fixed_t h)
@ -388,7 +379,7 @@ void HWR_DrawCroppedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale,
FBITFIELD flags;
float cx = FIXED_TO_FLOAT(x);
float cy = FIXED_TO_FLOAT(y);
UINT8 alphalevel = ((option & V_ALPHAMASK) >> V_ALPHASHIFT);
UINT32 alphalevel, blendmode;
GLPatch_t *hwrPatch;
// 3--2
@ -397,9 +388,6 @@ void HWR_DrawCroppedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale,
// 0--1
float dupx, dupy, fscale, fwidth, fheight;
if (alphalevel >= 10 && alphalevel < 13)
return;
// make patch ready in hardware cache
HWR_GetPatch(gpatch);
hwrPatch = ((GLPatch_t *)gpatch->hardware);
@ -507,27 +495,32 @@ void HWR_DrawCroppedPatch(patch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale,
else
v[2].t = v[3].t = ((sy+h)/(float)(gpatch->height))*hwrPatch->max_t;
flags = PF_Translucent|PF_NoDepthTest;
if (option & V_WRAPX)
flags |= PF_ForceWrapX;
if (option & V_WRAPY)
flags |= PF_ForceWrapY;
flags = PF_NoDepthTest;
// clip it since it is used for bunny scroll in doom I
if (alphalevel)
if ((blendmode = ((option & V_BLENDMASK) >> V_BLENDSHIFT)))
blendmode++; // realign to constants
if ((alphalevel = ((option & V_ALPHAMASK) >> V_ALPHASHIFT)) || blendmode)
{
FSurfaceInfo Surf;
Surf.PolyColor.s.red = Surf.PolyColor.s.green = Surf.PolyColor.s.blue = 0xff;
if (alphalevel == 13) Surf.PolyColor.s.alpha = softwaretranstogl_lo[st_translucency];
else if (alphalevel == 14) Surf.PolyColor.s.alpha = softwaretranstogl[st_translucency];
else if (alphalevel == 15) Surf.PolyColor.s.alpha = softwaretranstogl_hi[st_translucency];
else Surf.PolyColor.s.alpha = softwaretranstogl[10-alphalevel];
flags |= HWR_GetBlendModeFlag(blendmode);
if (alphalevel == 10)
Surf.PolyColor.s.alpha = softwaretranstogl_lo[st_translucency];
else if (alphalevel == 11)
Surf.PolyColor.s.alpha = softwaretranstogl[st_translucency];
else if (alphalevel == 12)
Surf.PolyColor.s.alpha = softwaretranstogl_hi[st_translucency];
else
Surf.PolyColor.s.alpha = softwaretranstogl[10-alphalevel];
flags |= PF_Modulated;
HWD.pfnDrawPolygon(&Surf, v, 4, flags);
HWD.pfnDrawPolygon(&Surf, v, 4, flags|PF_Modulated);
}
else
HWD.pfnDrawPolygon(NULL, v, 4, flags);
HWD.pfnDrawPolygon(NULL, v, 4, flags|PF_Translucent);
}
void HWR_DrawPic(INT32 x, INT32 y, lumpnum_t lumpnum)

View file

@ -716,15 +716,15 @@ FBITFIELD HWR_GetBlendModeFlag(INT32 ast)
{
switch (ast)
{
case AST_COPY:
//case AST_COPY: -- intentionally defaults to translucent
case AST_OVERLAY:
return PF_Masked;
case AST_ADD:
return PF_Additive;
case AST_SUBTRACT:
return PF_Subtractive;
case AST_REVERSESUBTRACT:
return PF_ReverseSubtract;
case AST_REVERSESUBTRACT:
return PF_Subtractive;
case AST_MODULATE:
return PF_Multiplicative;
default:
@ -756,12 +756,14 @@ UINT8 HWR_GetTranstableAlpha(INT32 transtablenum)
}
FBITFIELD HWR_SurfaceBlend(INT32 style, INT32 transtablenum, FSurfaceInfo *pSurf)
{
if (!transtablenum || style == AST_COPY || style == AST_OVERLAY)
{
pSurf->PolyColor.s.alpha = 0xff;
return PF_Masked;
}
if (style == AST_MODULATE)
return PF_Multiplicative;
if (!transtablenum && !style)
pSurf->PolyColor.s.alpha = HWR_GetTranstableAlpha(transtablenum);
return HWR_GetBlendModeFlag(style);
@ -853,7 +855,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, FBITFIELD polyflags)
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
@ -990,12 +992,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|polyflags, true, lightnum, colormap);
else if (cutflag & FF_TRANSLUCENT)
HWR_AddTransparentWall(wallVerts, Surf, texnum, PF_Translucent|polyflags, false, lightnum, colormap);
if (blendmode & PF_Fog)
HWR_AddTransparentWall(wallVerts, Surf, texnum, blendmode, true, lightnum, colormap);
else if (blendmode & (PF_Translucent|PF_Additive|PF_Subtractive|PF_Environment))
HWR_AddTransparentWall(wallVerts, Surf, texnum, blendmode, false, lightnum, colormap);
else
HWR_ProjectWall(wallVerts, Surf, PF_Masked|polyflags, lightnum, colormap);
HWR_ProjectWall(wallVerts, Surf, blendmode, lightnum, colormap);
top = bot;
endtop = endbot;
@ -1019,12 +1021,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|polyflags, true, lightnum, colormap);
else if (cutflag & FF_TRANSLUCENT)
HWR_AddTransparentWall(wallVerts, Surf, texnum, PF_Translucent|polyflags, false, lightnum, colormap);
if (blendmode & PF_Fog)
HWR_AddTransparentWall(wallVerts, Surf, texnum, blendmode, true, lightnum, colormap);
else if (blendmode & (PF_Translucent|PF_Additive|PF_Subtractive|PF_Environment))
HWR_AddTransparentWall(wallVerts, Surf, texnum, blendmode, false, lightnum, colormap);
else
HWR_ProjectWall(wallVerts, Surf, PF_Masked|polyflags, lightnum, colormap);
HWR_ProjectWall(wallVerts, Surf, blendmode, lightnum, colormap);
}
// HWR_DrawSkyWall
@ -1204,12 +1206,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);
{
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, 0);
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, PF_Environment, false, lightnum, colormap);
HWR_AddTransparentWall(wallVerts, &Surf, gl_toptexture, blendmode, false, lightnum, colormap);
else
HWR_ProjectWall(wallVerts, &Surf, PF_Masked, lightnum, colormap);
HWR_ProjectWall(wallVerts, &Surf, blendmode, lightnum, colormap);
}
}
// check BOTTOM TEXTURE
@ -1270,12 +1279,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);
{
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, 0);
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, PF_Environment, false, lightnum, colormap);
HWR_AddTransparentWall(wallVerts, &Surf, gl_bottomtexture, blendmode, false, lightnum, colormap);
else
HWR_ProjectWall(wallVerts, &Surf, PF_Masked, lightnum, colormap);
HWR_ProjectWall(wallVerts, &Surf, blendmode, lightnum, colormap);
}
}
gl_midtexture = R_GetTextureNum(gl_sidedef->midtexture);
if (gl_midtexture)
@ -1468,12 +1484,26 @@ static void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
case 256:
blendmode = PF_Translucent;
break;
default:
if (gl_linedef->alpha >= 0 && gl_linedef->alpha < FRACUNIT)
blendmode = HWR_TranstableToAlpha(R_GetLinedefTransTable(gl_linedef->alpha), &Surf);
else
blendmode = PF_Masked;
case 913:
blendmode = PF_Multiplicative;
Surf.PolyColor.s.alpha = 0xff;
break;
default:
{
UINT32 blend = 0;
transnum_t transtable = R_GetLinedefTransTable(gl_linedef);
if (transtable == NUMTRANSMAPS)
transtable = 0;
if (gl_linedef->special == 910)
blend = AST_ADD;
else if (gl_linedef->special == 911)
blend = AST_SUBTRACT;
else if (gl_linedef->special == 912)
blend = AST_REVERSESUBTRACT;
blendmode = HWR_SurfaceBlend(blend, transtable, &Surf);
break;
}
}
if (gl_curline->polyseg && gl_curline->polyseg->translucency > 0)
@ -1494,10 +1524,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, PF_Decal);
HWR_SplitWall(gl_frontsector, wallVerts, gl_midtexture, &Surf, FF_TRANSLUCENT, NULL, blendmode);
else
{
HWR_SplitWall(gl_frontsector, wallVerts, gl_midtexture, &Surf, FF_CUTLEVEL, NULL, PF_Decal);
HWR_SplitWall(gl_frontsector, wallVerts, gl_midtexture, &Surf, FF_CUTLEVEL, NULL, blendmode);
}
}
else if (!(blendmode & PF_Masked))
@ -1578,15 +1608,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);
{
FBITFIELD blendmode = PF_Masked;
if (grTex->mipmap.flags & TF_TRANSPARENT)
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, 0);
HWR_SplitWall(gl_frontsector, wallVerts, gl_midtexture, &Surf, FF_CUTLEVEL, NULL, blendmode);
else
{
if (grTex->mipmap.flags & TF_TRANSPARENT)
HWR_AddTransparentWall(wallVerts, &Surf, gl_midtexture, PF_Environment, false, lightnum, colormap);
HWR_AddTransparentWall(wallVerts, &Surf, gl_midtexture, blendmode, false, lightnum, colormap);
else
HWR_ProjectWall(wallVerts, &Surf, PF_Masked, lightnum, colormap);
HWR_ProjectWall(wallVerts, &Surf, blendmode, lightnum, colormap);
}
}
}
@ -1743,7 +1779,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, 0);
HWR_SplitWall(gl_frontsector, wallVerts, 0, &Surf, rover->flags, rover, blendmode);
else
HWR_AddTransparentWall(wallVerts, &Surf, 0, blendmode, true, lightnum, colormap);
}
@ -1751,14 +1787,14 @@ 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) && (rover->alpha < 256 || rover->blend))
{
blendmode = PF_Translucent;
Surf.PolyColor.s.alpha = (UINT8)rover->alpha-1 > 255 ? 255 : rover->alpha-1;
blendmode = HWR_GetBlendModeFlag(rover->blend);
Surf.PolyColor.s.alpha = (UINT8)(rover->alpha-1);
}
if (gl_frontsector->numlights)
HWR_SplitWall(gl_frontsector, wallVerts, texnum, &Surf, rover->flags, rover, 0);
HWR_SplitWall(gl_frontsector, wallVerts, texnum, &Surf, rover->flags, rover, blendmode);
else
{
if (blendmode != PF_Masked)
@ -1855,7 +1891,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, 0);
HWR_SplitWall(gl_backsector, wallVerts, 0, &Surf, rover->flags, rover, blendmode);
else
HWR_AddTransparentWall(wallVerts, &Surf, 0, blendmode, true, lightnum, colormap);
}
@ -1863,14 +1899,14 @@ 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) && (rover->alpha < 256 || rover->blend))
{
blendmode = PF_Translucent;
Surf.PolyColor.s.alpha = (UINT8)rover->alpha-1 > 255 ? 255 : rover->alpha-1;
blendmode = HWR_GetBlendModeFlag(rover->blend);
Surf.PolyColor.s.alpha = (UINT8)(rover->alpha-1);
}
if (gl_backsector->numlights)
HWR_SplitWall(gl_backsector, wallVerts, texnum, &Surf, rover->flags, rover, 0);
HWR_SplitWall(gl_backsector, wallVerts, texnum, &Surf, rover->flags, rover, blendmode);
else
{
if (blendmode != PF_Masked)
@ -2946,6 +2982,13 @@ static void HWR_AddPolyObjectPlanes(void)
}
}
static FBITFIELD HWR_RippleBlend(sector_t *sector, ffloor_t *rover, boolean ceiling)
{
(void)sector;
(void)ceiling;
return /*R_IsRipplePlane(sector, rover, ceiling)*/ (rover->flags & FF_RIPPLE) ? PF_Ripple : 0;
}
// -----------------+
// HWR_Subsector : Determine floor/ceiling planes.
// : Add sprites of things in sector.
@ -3136,8 +3179,10 @@ 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->blend)) // SoM: Flags are more efficient
{
FBITFIELD blendmode = HWR_GetBlendModeFlag(rover->blend) | HWR_RippleBlend(gl_frontsector, rover, false);
light = R_GetPlaneLight(gl_frontsector, centerHeight, dup_viewz < cullHeight ? true : false);
HWR_AddTransparentFloor(&levelflats[*rover->bottompic],
@ -3145,14 +3190,14 @@ 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, rover->master->frontsector, blendmode,
false, *gl_frontsector->lightlist[light].extra_colormap);
}
else
{
HWR_GetLevelFlat(&levelflats[*rover->bottompic]);
light = R_GetPlaneLight(gl_frontsector, centerHeight, dup_viewz < cullHeight ? true : false);
HWR_RenderPlane(sub, &extrasubsectors[num], false, *rover->bottomheight, (rover->flags & FF_RIPPLE ? PF_Ripple : 0)|PF_Occlude, *gl_frontsector->lightlist[light].lightlevel, &levelflats[*rover->bottompic],
HWR_RenderPlane(sub, &extrasubsectors[num], false, *rover->bottomheight, HWR_RippleBlend(gl_frontsector, rover, false)|PF_Occlude, *gl_frontsector->lightlist[light].lightlevel, &levelflats[*rover->bottompic],
rover->master->frontsector, 255, *gl_frontsector->lightlist[light].extra_colormap);
}
}
@ -3181,8 +3226,10 @@ 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->blend))
{
FBITFIELD blendmode = HWR_GetBlendModeFlag(rover->blend) | HWR_RippleBlend(gl_frontsector, rover, false);
light = R_GetPlaneLight(gl_frontsector, centerHeight, dup_viewz < cullHeight ? true : false);
HWR_AddTransparentFloor(&levelflats[*rover->toppic],
@ -3190,14 +3237,14 @@ 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, rover->master->frontsector, blendmode,
false, *gl_frontsector->lightlist[light].extra_colormap);
}
else
{
HWR_GetLevelFlat(&levelflats[*rover->toppic]);
light = R_GetPlaneLight(gl_frontsector, centerHeight, dup_viewz < cullHeight ? true : false);
HWR_RenderPlane(sub, &extrasubsectors[num], true, *rover->topheight, (rover->flags & FF_RIPPLE ? PF_Ripple : 0)|PF_Occlude, *gl_frontsector->lightlist[light].lightlevel, &levelflats[*rover->toppic],
HWR_RenderPlane(sub, &extrasubsectors[num], true, *rover->topheight, HWR_RippleBlend(gl_frontsector, rover, false)|PF_Occlude, *gl_frontsector->lightlist[light].lightlevel, &levelflats[*rover->toppic],
rover->master->frontsector, 255, *gl_frontsector->lightlist[light].extra_colormap);
}
}
@ -3839,32 +3886,34 @@ static void HWR_SplitSprite(gl_vissprite_t *spr)
else
occlusion = PF_Occlude;
if (!cv_translucency.value) // translucency disabled
// Determine the blendmode and translucency value
{
Surf.PolyColor.s.alpha = 0xFF;
blend = PF_Translucent|occlusion;
if (!occlusion) use_linkdraw_hack = true;
}
else if (spr->mobj->flags2 & MF2_SHADOW)
{
Surf.PolyColor.s.alpha = 0x40;
blend = HWR_GetBlendModeFlag(spr->mobj->blendmode);
}
else if (spr->mobj->frame & FF_TRANSMASK)
{
INT32 trans = (spr->mobj->frame & FF_TRANSMASK)>>FF_TRANSSHIFT;
blend = HWR_SurfaceBlend(spr->mobj->blendmode, trans, &Surf);
}
UINT32 blendmode, trans;
if (spr->mobj->renderflags & RF_BLENDMASK)
blendmode = (spr->mobj->renderflags & RF_BLENDMASK) >> RF_BLENDSHIFT;
else
blendmode = (spr->mobj->frame & FF_BLENDMASK) >> FF_BLENDSHIFT;
if (blendmode)
blendmode++; // realign to constants
if (spr->mobj->renderflags & RF_TRANSMASK)
trans = (spr->mobj->renderflags & RF_TRANSMASK) >> RF_TRANSSHIFT;
else
trans = (spr->mobj->frame & FF_TRANSMASK) >> FF_TRANSSHIFT;
if (trans >= NUMTRANSMAPS)
return; // cap
blend = HWR_SurfaceBlend(blendmode, trans, &Surf);
if (!trans && !blendmode)
{
// BP: i agree that is little better in environement but it don't
// work properly under glide nor with fogcolor to ffffff :(
// Hurdler: PF_Environement would be cool, but we need to fix
// the issue with the fog before
Surf.PolyColor.s.alpha = 0xFF;
blend = HWR_GetBlendModeFlag(spr->mobj->blendmode)|occlusion;
blend |= occlusion;
if (!occlusion) use_linkdraw_hack = true;
}
}
if (HWR_UseShader())
{
@ -3902,6 +3951,9 @@ static void HWR_SplitSprite(gl_vissprite_t *spr)
}
}
if (R_ThingIsSemiBright(spr->mobj))
lightlevel = 128 + (lightlevel>>1);
for (i = 0; i < sector->numlights; i++)
{
if (endtop < endrealbot && top < realbot)
@ -4255,6 +4307,9 @@ static void HWR_DrawSprite(gl_vissprite_t *spr)
else if (!lightset)
lightlevel = sector->lightlevel > 255 ? 255 : sector->lightlevel;
if (R_ThingIsSemiBright(spr->mobj))
lightlevel = 128 + (lightlevel>>1);
HWR_Lighting(&Surf, lightlevel, colormap);
}
@ -4271,32 +4326,34 @@ static void HWR_DrawSprite(gl_vissprite_t *spr)
else
occlusion = PF_Occlude;
if (!cv_translucency.value) // translucency disabled
// Determine the blendmode and translucency value
{
Surf.PolyColor.s.alpha = 0xFF;
blend = PF_Translucent|occlusion;
if (!occlusion) use_linkdraw_hack = true;
}
else if (spr->mobj->flags2 & MF2_SHADOW)
{
Surf.PolyColor.s.alpha = 0x40;
blend = HWR_GetBlendModeFlag(spr->mobj->blendmode);
}
else if (spr->mobj->frame & FF_TRANSMASK)
{
INT32 trans = (spr->mobj->frame & FF_TRANSMASK)>>FF_TRANSSHIFT;
blend = HWR_SurfaceBlend(spr->mobj->blendmode, trans, &Surf);
}
UINT32 blendmode, trans;
if (spr->mobj->renderflags & RF_BLENDMASK)
blendmode = (spr->mobj->renderflags & RF_BLENDMASK) >> RF_BLENDSHIFT;
else
blendmode = (spr->mobj->frame & FF_BLENDMASK) >> FF_BLENDSHIFT;
if (blendmode)
blendmode++; // realign to constants
if (spr->mobj->renderflags & RF_TRANSMASK)
trans = (spr->mobj->renderflags & RF_TRANSMASK) >> RF_TRANSSHIFT;
else
trans = (spr->mobj->frame & FF_TRANSMASK) >> FF_TRANSSHIFT;
if (trans >= NUMTRANSMAPS)
return; // cap
blend = HWR_SurfaceBlend(blendmode, trans, &Surf);
if (!trans && !blendmode)
{
// BP: i agree that is little better in environement but it don't
// work properly under glide nor with fogcolor to ffffff :(
// Hurdler: PF_Environement would be cool, but we need to fix
// the issue with the fog before
Surf.PolyColor.s.alpha = 0xFF;
blend = HWR_GetBlendModeFlag(spr->mobj->blendmode)|occlusion;
blend |= occlusion;
if (!occlusion) use_linkdraw_hack = true;
}
}
if (spr->renderflags & RF_SHADOWEFFECTS)
{
@ -4401,19 +4458,32 @@ static inline void HWR_DrawPrecipitationSprite(gl_vissprite_t *spr)
HWR_Lighting(&Surf, lightlevel, colormap);
}
if (spr->mobj->frame & FF_TRANSMASK)
// Determine the blendmode and translucency value
{
INT32 trans = (spr->mobj->frame & FF_TRANSMASK)>>FF_TRANSSHIFT;
blend = HWR_SurfaceBlend(AST_TRANSLUCENT, trans, &Surf);
}
UINT32 blendmode, trans;
if (spr->mobj->renderflags & RF_BLENDMASK)
blendmode = (spr->mobj->renderflags & RF_BLENDMASK) >> RF_BLENDSHIFT;
else
blendmode = (spr->mobj->frame & FF_BLENDMASK) >> FF_BLENDSHIFT;
if (blendmode)
blendmode++; // realign to constants
if (spr->mobj->renderflags & RF_TRANSMASK)
trans = (spr->mobj->renderflags & RF_TRANSMASK) >> RF_TRANSSHIFT;
else
trans = (spr->mobj->frame & FF_TRANSMASK) >> FF_TRANSSHIFT;
if (trans >= NUMTRANSMAPS)
return; // cap
blend = HWR_SurfaceBlend(blendmode, trans, &Surf);
if (!trans && !blendmode)
{
// BP: i agree that is little better in environement but it don't
// work properly under glide nor with fogcolor to ffffff :(
// Hurdler: PF_Environement would be cool, but we need to fix
// the issue with the fog before
Surf.PolyColor.s.alpha = 0xFF;
blend = HWR_GetBlendModeFlag(spr->mobj->blendmode)|PF_Occlude;
blend |= PF_Occlude;
}
}
if (HWR_UseShader())
@ -4989,13 +5059,6 @@ static void HWR_ProjectSprite(mobj_t *thing)
if (thing->spritexscale < 1 || thing->spriteyscale < 1)
return;
// Visibility check by the blend mode.
if (thing->frame & FF_TRANSMASK)
{
if (!R_BlendLevelVisible(thing->blendmode, (thing->frame & FF_TRANSMASK)>>FF_TRANSSHIFT))
return;
}
dispoffset = thing->info->dispoffset;
this_scale = FIXED_TO_FLOAT(thing->scale);
@ -5382,13 +5445,6 @@ static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing)
unsigned rot = 0;
UINT8 flip;
// Visibility check by the blend mode.
if (thing->frame & FF_TRANSMASK)
{
if (!R_BlendLevelVisible(thing->blendmode, (thing->frame & FF_TRANSMASK)>>FF_TRANSSHIFT))
return;
}
// transform the origin point
tr_x = FIXED_TO_FLOAT(thing->x) - gl_viewx;
tr_y = FIXED_TO_FLOAT(thing->y) - gl_viewy;

View file

@ -414,7 +414,7 @@ static void md2_loadTexture(md2_t *model)
size = w*h;
while (size--)
{
V_CubeApply(&image->s.red, &image->s.green, &image->s.blue);
image->rgba = V_CubeApply(image);
image++;
}
}
@ -1354,12 +1354,24 @@ boolean HWR_DrawModel(gl_vissprite_t *spr)
//if (tics > durs)
//durs = tics;
if (spr->mobj->frame & FF_TRANSMASK)
Surf.PolyFlags = HWR_SurfaceBlend(spr->mobj->blendmode, (spr->mobj->frame & FF_TRANSMASK)>>FF_TRANSSHIFT, &Surf);
else
// Determine the blendmode and translucency value
{
Surf.PolyColor.s.alpha = (spr->mobj->flags2 & MF2_SHADOW) ? 0x40 : 0xff;
Surf.PolyFlags = HWR_GetBlendModeFlag(spr->mobj->blendmode);
UINT32 blendmode, trans;
if (spr->mobj->renderflags & RF_BLENDMASK)
blendmode = (spr->mobj->renderflags & RF_BLENDMASK) >> RF_BLENDSHIFT;
else
blendmode = (spr->mobj->frame & FF_BLENDMASK) >> FF_BLENDSHIFT;
if (blendmode)
blendmode++; // realign to constants
if (spr->mobj->renderflags & RF_TRANSMASK)
trans = (spr->mobj->renderflags & RF_TRANSMASK) >> RF_TRANSSHIFT;
else
trans = (spr->mobj->frame & FF_TRANSMASK) >> FF_TRANSSHIFT;
if (trans >= NUMTRANSMAPS)
return false; // cap
Surf.PolyFlags = HWR_SurfaceBlend(blendmode, trans, &Surf);
}
// don't forget to enable the depth test because we can't do this

View file

@ -1869,7 +1869,7 @@ static void HU_DrawChat_Old(void)
static inline void HU_DrawCrosshair(void)
{
INT32 i, y;
INT32 i, y, dupz;
i = cv_crosshair.value & 3;
if (!i)
@ -1885,12 +1885,14 @@ static inline void HU_DrawCrosshair(void)
#endif
y = viewwindowy + (viewheight>>1);
V_DrawScaledPatch(vid.width>>1, y, V_NOSCALESTART|V_OFFSET|V_TRANSLUCENT, crosshair[i - 1]);
dupz = (vid.dupx < vid.dupy ? vid.dupx : vid.dupy);
V_DrawFixedPatch(vid.width<<(FRACBITS-1), y<<FRACBITS, FRACUNIT/dupz, V_TRANSLUCENT, crosshair[i - 1], NULL);
}
static inline void HU_DrawCrosshair2(void)
{
INT32 i, y;
INT32 i, y, dupz;
i = cv_crosshair2.value & 3;
if (!i)
@ -1906,8 +1908,9 @@ static inline void HU_DrawCrosshair2(void)
#endif
y = viewwindowy + (viewheight>>1);
if (splitscreen)
{
if (!splitscreen)
return;
#ifdef HWRENDER
if (rendermode != render_soft)
y += (INT32)gl_viewheight;
@ -1915,8 +1918,9 @@ static inline void HU_DrawCrosshair2(void)
#endif
y += viewheight;
V_DrawScaledPatch(vid.width>>1, y, V_NOSCALESTART|V_OFFSET|V_TRANSLUCENT, crosshair[i - 1]);
}
dupz = (vid.dupx < vid.dupy ? vid.dupx : vid.dupy);
V_DrawFixedPatch(vid.width<<(FRACBITS-1), y<<FRACBITS, FRACUNIT/dupz, V_TRANSLUCENT, crosshair[i - 1], NULL);
}
static void HU_DrawCEcho(void)

View file

@ -196,6 +196,7 @@ enum ffloor_e {
ffloor_next,
ffloor_prev,
ffloor_alpha,
ffloor_blend,
};
static const char *const ffloor_opt[] = {
@ -214,6 +215,7 @@ static const char *const ffloor_opt[] = {
"next",
"prev",
"alpha",
"blend",
NULL};
#ifdef HAVE_LUA_SEGS
@ -1807,6 +1809,9 @@ static int ffloor_get(lua_State *L)
case ffloor_alpha:
lua_pushinteger(L, ffloor->alpha);
return 1;
case ffloor_blend:
lua_pushinteger(L, ffloor->blend);
return 1;
}
return 0;
}
@ -1885,6 +1890,9 @@ static int ffloor_set(lua_State *L)
case ffloor_alpha:
ffloor->alpha = (INT32)luaL_checkinteger(L, 3);
break;
case ffloor_blend:
ffloor->blend = (INT32)luaL_checkinteger(L, 3);
break;
}
return 0;
}

View file

@ -316,7 +316,12 @@ static int mobj_get(lua_State *L)
lua_pushinteger(L, mo->color);
break;
case mobj_blendmode:
lua_pushinteger(L, mo->blendmode);
{
INT32 backcompat = (mo->renderflags & RF_BLENDMASK) >> RF_BLENDSHIFT;
if (backcompat)
backcompat++;
lua_pushinteger(L, backcompat);
}
break;
case mobj_bnext:
LUA_PushUserdata(L, mo->bnext, META_MOBJ);
@ -654,8 +659,15 @@ static int mobj_set(lua_State *L)
break;
}
case mobj_blendmode:
mo->blendmode = (INT32)luaL_checkinteger(L, 3);
{
INT32 backcompat = (INT32)luaL_checkinteger(L, 3);
if (backcompat < 0 || backcompat > AST_OVERLAY)
return luaL_error(L, "mobj.blendmode %d out of range (0 - %d).", backcompat, AST_OVERLAY);
if (backcompat)
backcompat--;
mo->renderflags = (mo->renderflags & ~RF_BLENDMASK)|(backcompat << RF_BLENDSHIFT);
break;
}
case mobj_bnext:
return NOSETPOS;
case mobj_bprev:

View file

@ -4034,7 +4034,7 @@ static void M_DrawThermo(INT32 x, INT32 y, consvar_t *cv)
xx += p->width - p->leftoffset;
for (i = 0; i < 16; i++)
{
V_DrawScaledPatch(xx, y, V_WRAPX, W_CachePatchNum(centerlump[i & 1], PU_PATCH));
V_DrawScaledPatch(xx, y, 0, W_CachePatchNum(centerlump[i & 1], PU_PATCH));
xx += 8;
}
V_DrawScaledPatch(xx, y, 0, W_CachePatchNum(rightlump, PU_PATCH));
@ -4130,7 +4130,7 @@ void M_DrawTextBox(INT32 x, INT32 y, INT32 width, INT32 boxlines)
p = W_CachePatchNum(viewborderlump[BRDR_L], PU_PATCH);
for (n = 0; n < boxlines; n++)
{
V_DrawScaledPatch(cx, cy, V_WRAPY, p);
V_DrawScaledPatch(cx, cy, 0, p);
cy += step;
}
V_DrawScaledPatch(cx, cy, 0, W_CachePatchNum(viewborderlump[BRDR_BL], PU_PATCH));
@ -4142,8 +4142,8 @@ void M_DrawTextBox(INT32 x, INT32 y, INT32 width, INT32 boxlines)
cy = y;
while (width > 0)
{
V_DrawScaledPatch(cx, cy, V_WRAPX, W_CachePatchNum(viewborderlump[BRDR_T], PU_PATCH));
V_DrawScaledPatch(cx, y + boff + boxlines*step, V_WRAPX, W_CachePatchNum(viewborderlump[BRDR_B], PU_PATCH));
V_DrawScaledPatch(cx, cy, 0, W_CachePatchNum(viewborderlump[BRDR_T], PU_PATCH));
V_DrawScaledPatch(cx, y + boff + boxlines*step, 0, W_CachePatchNum(viewborderlump[BRDR_B], PU_PATCH));
width--;
cx += step;
}
@ -4155,7 +4155,7 @@ void M_DrawTextBox(INT32 x, INT32 y, INT32 width, INT32 boxlines)
p = W_CachePatchNum(viewborderlump[BRDR_R], PU_PATCH);
for (n = 0; n < boxlines; n++)
{
V_DrawScaledPatch(cx, cy, V_WRAPY, p);
V_DrawScaledPatch(cx, cy, 0, p);
cy += step;
}
V_DrawScaledPatch(cx, cy, 0, W_CachePatchNum(viewborderlump[BRDR_BR], PU_PATCH));

View file

@ -10477,7 +10477,6 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
mobj->destscale = FRACUNIT/2;
// Sprite rendering
mobj->blendmode = AST_TRANSLUCENT;
mobj->spritexscale = mobj->spriteyscale = mobj->scale;
mobj->spritexoffset = mobj->spriteyoffset = 0;
mobj->floorspriteslope = NULL;

View file

@ -288,7 +288,6 @@ typedef struct mobj_s
UINT16 anim_duration; // for FF_ANIMATE states
UINT32 renderflags; // render flags
INT32 blendmode; // blend mode
fixed_t spritexscale, spriteyscale;
fixed_t spritexoffset, spriteyoffset;
struct pslope_s *floorspriteslope; // The slope that the floorsprite is rotated by
@ -415,7 +414,6 @@ typedef struct precipmobj_s
UINT16 anim_duration; // for FF_ANIMATE states
UINT32 renderflags; // render flags
INT32 blendmode; // blend mode
fixed_t spritexscale, spriteyscale;
fixed_t spritexoffset, spriteyoffset;
struct pslope_s *floorspriteslope; // The slope that the floorsprite is rotated by

View file

@ -41,9 +41,20 @@
/// \brief Frame flags - SPR2: Super sprite2
#define FF_SPR2SUPER 0x80
/// \brief Frame flags - SPR2: A change of state at the end of Sprite2 animation
#define FF_SPR2ENDSTATE 0x1000
#define FF_SPR2ENDSTATE 0x100
/// \brief Frame flags - SPR2: 50% of starting in middle of Sprite2 animation
#define FF_SPR2MIDSTART 0x2000
#define FF_SPR2MIDSTART 0x200
/// \brief Frame flags: blend types
#define FF_BLENDMASK 0x7000
/// \brief shift for FF_BLENDMASK
#define FF_BLENDSHIFT 12
/// \brief preshifted blend flags minus 1 as effects don't distinguish between AST_COPY and AST_TRANSLUCENT
#define FF_ADD ((AST_ADD-1)<<FF_BLENDSHIFT)
#define FF_SUBTRACT ((AST_SUBTRACT-1)<<FF_BLENDSHIFT)
#define FF_REVERSESUBTRACT ((AST_REVERSESUBTRACT-1)<<FF_BLENDSHIFT)
#define FF_MODULATE ((AST_MODULATE-1)<<FF_BLENDSHIFT)
#define FF_OVERLAY ((AST_OVERLAY-1)<<FF_BLENDSHIFT)
/// \brief Frame flags: 0 = no trans(opaque), 1-15 = transl. table
#define FF_TRANSMASK 0xf0000
@ -60,21 +71,31 @@
#define FF_TRANS80 (tr_trans80<<FF_TRANSSHIFT)
#define FF_TRANS90 (tr_trans90<<FF_TRANSSHIFT)
/// \brief Frame flags: brightness mask
#define FF_BRIGHTMASK 0x00300000
/// \brief Frame flags: frame always appears full bright
#define FF_FULLBRIGHT 0x00100000
/// \brief Frame flags: Flip sprite vertically (relative to what it should be for its gravity)
#define FF_VERTICALFLIP 0x00200000
/// \brief Frame flags: Flip sprite horizontally
#define FF_HORIZONTALFLIP 0x00400000
/// \brief Frame flags: frame always appears full darkness
#define FF_FULLDARK 0x00200000
/// \brief Frame flags: frame appears between sector bright and full bright
#define FF_SEMIBRIGHT (FF_FULLBRIGHT|FF_FULLDARK)
/// \brief Frame flags: Thin, paper-like sprite (for collision equivalent, see MF_PAPERCOLLISION)
#define FF_PAPERSPRITE 0x00800000
#define FF_PAPERSPRITE 0x00400000
/// \brief Frame flags: Splat!
#define FF_FLOORSPRITE 0x00800000
/// \brief Frame flags: Flip sprite vertically (relative to what it should be for its gravity)
#define FF_VERTICALFLIP 0x01000000
/// \brief Frame flags: Flip sprite horizontally
#define FF_HORIZONTALFLIP 0x02000000
/// \brief Frame flags - Animate: Simple stateless animation
#define FF_ANIMATE 0x01000000
/// \brief Frame flags - Animate: Start at a random place in the animation (mutually exclusive with below)
#define FF_RANDOMANIM 0x02000000
/// \brief Frame flags - Animate: Sync animation to global timer (mutually exclusive with above)
#define FF_GLOBALANIM 0x04000000
#define FF_ANIMATE 0x10000000
/// \brief Frame flags - Animate: Sync animation to global timer (mutually exclusive with below, currently takes priority)
#define FF_GLOBALANIM 0x20000000
/// \brief Frame flags - Animate: Start at a random place in the animation (mutually exclusive with above)
#define FF_RANDOMANIM 0x40000000
/** \brief translucency tables

View file

@ -1418,7 +1418,7 @@ typedef enum
MD2_ROLLANGLE = 1<<14,
MD2_SHADOWSCALE = 1<<15,
MD2_RENDERFLAGS = 1<<16,
MD2_BLENDMODE = 1<<17,
// 1<<17 was taken out, maybe reuse later
MD2_SPRITEXSCALE = 1<<18,
MD2_SPRITEYSCALE = 1<<19,
MD2_SPRITEXOFFSET = 1<<20,
@ -1638,8 +1638,6 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type)
diff2 |= MD2_SHADOWSCALE;
if (mobj->renderflags)
diff2 |= MD2_RENDERFLAGS;
if (mobj->blendmode != AST_TRANSLUCENT)
diff2 |= MD2_BLENDMODE;
if (mobj->spritexscale != FRACUNIT)
diff2 |= MD2_SPRITEXSCALE;
if (mobj->spriteyscale != FRACUNIT)
@ -1803,8 +1801,6 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type)
WRITEFIXED(save_p, mobj->shadowscale);
if (diff2 & MD2_RENDERFLAGS)
WRITEUINT32(save_p, mobj->renderflags);
if (diff2 & MD2_BLENDMODE)
WRITEINT32(save_p, mobj->blendmode);
if (diff2 & MD2_SPRITEXSCALE)
WRITEFIXED(save_p, mobj->spritexscale);
if (diff2 & MD2_SPRITEYSCALE)
@ -2843,10 +2839,6 @@ static thinker_t* LoadMobjThinker(actionf_p1 thinker)
mobj->shadowscale = READFIXED(save_p);
if (diff2 & MD2_RENDERFLAGS)
mobj->renderflags = READUINT32(save_p);
if (diff2 & MD2_BLENDMODE)
mobj->blendmode = READINT32(save_p);
else
mobj->blendmode = AST_TRANSLUCENT;
if (diff2 & MD2_SPRITEXSCALE)
mobj->spritexscale = READFIXED(save_p);
else

View file

@ -1350,8 +1350,11 @@ static void P_LoadSidedefs(UINT8 *data)
if (msd->toptexture[0] == '#')
{
char *col = msd->toptexture;
sd->toptexture = sd->bottomtexture =
sd->toptexture =
((col[1]-'0')*100 + (col[2]-'0')*10 + col[3]-'0')+1;
if (col[4]) // extra num for blendmode
sd->toptexture += (col[4]-'0')*1000;
sd->bottomtexture = sd->toptexture;
sd->midtexture = R_TextureNumForName(msd->midtexture);
}
else

View file

@ -5629,8 +5629,31 @@ static ffloor_t *P_AddFakeFloor(sector_t *sec, sector_t *sec2, line_t *master, f
if (flags & FF_TRANSLUCENT)
{
if (sides[master->sidenum[0]].toptexture > 0)
fflr->alpha = sides[master->sidenum[0]].toptexture; // for future reference, "#0" is 1, and "#255" is 256. Be warned
{
// for future reference, "#0" is 1, and "#255" is 256. Be warned
fflr->alpha = sides[master->sidenum[0]].toptexture;
#if 0 // kart indev compat
if (fflr->alpha == 901) // additive special
{
fflr->blend = AST_ADD;
fflr->alpha = 0xff;
}
else if (fflr->alpha == 902) // subtractive special
{
fflr->blend = AST_SUBTRACT;
fflr->alpha = 0xff;
}
else
#endif
if (fflr->alpha >= 1001) // fourth digit
{
fflr->blend = (fflr->alpha/1000)+1; // becomes an AST
fflr->alpha %= 1000;
}
}
else
fflr->alpha = 0x80;
}
else

View file

@ -94,7 +94,7 @@ UINT32 ASTBlendPixel(RGBA_t background, RGBA_t foreground, int style, UINT8 alph
#define clamp(c) max(min(c, 0xFF), 0x00);
else
{
float falpha = ((float)alpha / 256.0f);
float falpha = ((float)alpha / 255.0f);
float fr = ((float)foreground.s.red * falpha);
float fg = ((float)foreground.s.green * falpha);
float fb = ((float)foreground.s.blue * falpha);

View file

@ -30,9 +30,6 @@ typedef struct
size_t numlumps;
} lumplist_t;
// Possible alpha types for a patch.
enum patchalphastyle {AST_COPY, AST_TRANSLUCENT, AST_ADD, AST_SUBTRACT, AST_REVERSESUBTRACT, AST_MODULATE, AST_OVERLAY};
UINT32 ASTBlendPixel(RGBA_t background, RGBA_t foreground, int style, UINT8 alpha);
UINT32 ASTBlendTexturePixel(RGBA_t background, RGBA_t foreground, int style, UINT8 alpha);
UINT8 ASTBlendPaletteIndexes(UINT8 background, UINT8 foreground, int style, UINT8 alpha);

View file

@ -184,6 +184,7 @@ typedef struct ffloor_s
INT32 lastlight;
INT32 alpha;
UINT8 blend;
tic_t norender; // for culling
// these are saved for netgames, so do not let Lua touch these!
@ -713,6 +714,9 @@ typedef struct
#pragma pack()
#endif
// Possible alpha types for a patch.
typedef enum {AST_COPY, AST_TRANSLUCENT, AST_ADD, AST_SUBTRACT, AST_REVERSESUBTRACT, AST_MODULATE, AST_OVERLAY} patchalphastyle_t;
typedef enum
{
RF_HORIZONTALFLIP = 0x0001, // Flip sprite horizontally
@ -726,18 +730,51 @@ typedef enum
RF_NOSPLATBILLBOARD = 0x0040, // Don't billboard floor sprites (faces forward from the view angle)
RF_NOSPLATROLLANGLE = 0x0080, // Don't rotate floor sprites by the object's rollangle (uses rotated patches instead)
RF_BLENDMASK = 0x0F00, // --Blending modes
RF_FULLBRIGHT = 0x0100, // Sprite is drawn at full brightness
RF_FULLDARK = 0x0200, // Sprite is drawn completely dark
RF_NOCOLORMAPS = 0x0400, // Sprite is not drawn with colormaps
RF_BRIGHTMASK = 0x00000300, // --Bright modes
RF_FULLBRIGHT = 0x00000100, // Sprite is drawn at full brightness
RF_FULLDARK = 0x00000200, // Sprite is drawn completely dark
RF_SEMIBRIGHT = (RF_FULLBRIGHT | RF_FULLDARK), // between sector bright and full bright
RF_SPRITETYPEMASK = 0x7000, // ---Different sprite types
RF_PAPERSPRITE = 0x1000, // Paper sprite
RF_FLOORSPRITE = 0x2000, // Floor sprite
RF_NOCOLORMAPS = 0x00000400, // Sprite is not drawn with colormaps
RF_SHADOWDRAW = 0x10000, // Stretches and skews the sprite like a shadow.
RF_SHADOWEFFECTS = 0x20000, // Scales and becomes transparent like a shadow.
RF_SPRITETYPEMASK = 0x00003000, // --Different sprite types
RF_PAPERSPRITE = 0x00001000, // Paper sprite
RF_FLOORSPRITE = 0x00002000, // Floor sprite
RF_SHADOWDRAW = 0x00004000, // Stretches and skews the sprite like a shadow.
RF_SHADOWEFFECTS = 0x00008000, // Scales and becomes transparent like a shadow.
RF_DROPSHADOW = (RF_SHADOWDRAW | RF_SHADOWEFFECTS | RF_FULLDARK),
RF_DONTDRAW = 0x00F00000, // --Don't generate a vissprite
#if 0 // kart compat, ask sal if you're gonna implement - this is why RF_DONTDRAW *must* take four bits
RF_DONTDRAWP1 = 0x00100000, // No P1
RF_DONTDRAWP2 = 0x00200000, // No P2
RF_DONTDRAWP3 = 0x00400000, // No P3
RF_DONTDRAWP4 = 0x00800000, // No P4
#endif
RF_BLENDMASK = 0x07000000, // --Blending override - see patchalphastyle_t
RF_BLENDSHIFT = (6*4),
// minus 1 as effects don't distinguish between AST_COPY and AST_TRANSLUCENT
RF_ADD = ((AST_ADD-1)<<RF_BLENDSHIFT),
RF_SUBTRACT = ((AST_SUBTRACT-1)<<RF_BLENDSHIFT),
RF_REVERSESUBTRACT = ((AST_REVERSESUBTRACT-1)<<RF_BLENDSHIFT),
RF_MODULATE = ((AST_MODULATE-1)<<RF_BLENDSHIFT),
RF_OVERLAY = ((AST_OVERLAY-1)<<RF_BLENDSHIFT),
RF_TRANSMASK = 0xF0000000, // --Transparency override
RF_TRANSSHIFT = (7*4),
RF_TRANS10 = (1<<RF_TRANSSHIFT), // 10%
RF_TRANS20 = (2<<RF_TRANSSHIFT), // 20%
RF_TRANS30 = (3<<RF_TRANSSHIFT), // 30%
RF_TRANS40 = (4<<RF_TRANSSHIFT), // 40%
RF_TRANS50 = (5<<RF_TRANSSHIFT), // 50%
RF_TRANS60 = (6<<RF_TRANSSHIFT), // 60%
RF_TRANS70 = (7<<RF_TRANSSHIFT), // 70%
RF_TRANS80 = (8<<RF_TRANSSHIFT), // 80%
RF_TRANS90 = (9<<RF_TRANSSHIFT), // 90%
RF_GHOSTLY = (RF_TRANS80 | RF_FULLBRIGHT),
RF_GHOSTLYMASK = (RF_TRANSMASK | RF_FULLBRIGHT),
} renderflags_t;
typedef enum

View file

@ -173,6 +173,8 @@ static INT32 CacheIndexToSkin(INT32 ttc)
CV_PossibleValue_t Color_cons_t[MAXSKINCOLORS+1];
#define TRANSTAB_AMTMUL10 (255.0f / 10.0f)
/** \brief Initializes the translucency tables used by the Software renderer.
*/
void R_InitTranslucencyTables(void)
@ -196,140 +198,58 @@ void R_InitTranslucencyTables(void)
R_GenerateBlendTables();
}
static colorlookup_t transtab_lut;
static void BlendTab_Translucent(UINT8 *table, int style, UINT8 blendamt)
{
INT16 bg, fg;
if (table == NULL)
I_Error("BlendTab_Translucent: input table was NULL!");
for (bg = 0; bg < 0xFF; bg++)
{
for (fg = 0; fg < 0xFF; fg++)
{
RGBA_t backrgba = V_GetMasterColor(bg);
RGBA_t frontrgba = V_GetMasterColor(fg);
RGBA_t result;
result.rgba = ASTBlendPixel(backrgba, frontrgba, style, 0xFF);
result.rgba = ASTBlendPixel(result, frontrgba, AST_TRANSLUCENT, blendamt);
table[((bg * 0x100) + fg)] = GetColorLUT(&transtab_lut, result.s.red, result.s.green, result.s.blue);
}
}
}
static void BlendTab_Subtractive(UINT8 *table, int style, UINT8 blendamt)
{
INT16 bg, fg;
if (table == NULL)
I_Error("BlendTab_Subtractive: input table was NULL!");
if (blendamt == 0xFF)
{
memset(table, GetColorLUT(&transtab_lut, 0, 0, 0), 0x10000);
return;
}
for (bg = 0; bg < 0xFF; bg++)
{
for (fg = 0; fg < 0xFF; fg++)
{
RGBA_t backrgba = V_GetMasterColor(bg);
RGBA_t frontrgba = V_GetMasterColor(fg);
RGBA_t result;
result.rgba = ASTBlendPixel(backrgba, frontrgba, style, 0xFF);
result.s.red = max(0, result.s.red - blendamt);
result.s.green = max(0, result.s.green - blendamt);
result.s.blue = max(0, result.s.blue - blendamt);
table[((bg * 0x100) + fg)] = GetColorLUT(&transtab_lut, result.s.red, result.s.green, result.s.blue);
}
}
}
static void BlendTab_Modulative(UINT8 *table)
{
INT16 bg, fg;
if (table == NULL)
I_Error("BlendTab_Modulative: input table was NULL!");
for (bg = 0; bg < 0xFF; bg++)
{
for (fg = 0; fg < 0xFF; fg++)
{
RGBA_t backrgba = V_GetMasterColor(bg);
RGBA_t frontrgba = V_GetMasterColor(fg);
RGBA_t result;
result.rgba = ASTBlendPixel(backrgba, frontrgba, AST_MODULATE, 0);
table[((bg * 0x100) + fg)] = GetColorLUT(&transtab_lut, result.s.red, result.s.green, result.s.blue);
}
}
}
static INT32 BlendTab_Count[NUMBLENDMAPS] =
{
NUMTRANSTABLES+1, // blendtab_add
NUMTRANSTABLES+1, // blendtab_subtract
NUMTRANSTABLES+1, // blendtab_reversesubtract
1 // blendtab_modulate
};
static INT32 BlendTab_FromStyle[] =
{
0, // AST_COPY
0, // AST_TRANSLUCENT
blendtab_add, // AST_ADD
blendtab_subtract, // AST_SUBTRACT
blendtab_reversesubtract, // AST_REVERSESUBTRACT
blendtab_modulate, // AST_MODULATE
0 // AST_OVERLAY
};
static void BlendTab_GenerateMaps(INT32 tab, INT32 style, void (*genfunc)(UINT8 *, int, UINT8))
{
INT32 i = 0, num = BlendTab_Count[tab];
const float amtmul = (256.0f / (float)(NUMTRANSTABLES + 1));
for (; i < num; i++)
{
const size_t offs = (0x10000 * i);
const UINT16 alpha = min(amtmul * i, 0xFF);
genfunc(blendtables[tab] + offs, style, alpha);
}
}
void R_GenerateBlendTables(void)
{
INT32 i;
for (i = 0; i < NUMBLENDMAPS; i++)
blendtables[i] = Z_MallocAlign(BlendTab_Count[i] * 0x10000, PU_STATIC, NULL, 16);
InitColorLUT(&transtab_lut, pMasterPalette, false);
// Additive
BlendTab_GenerateMaps(blendtab_add, AST_ADD, BlendTab_Translucent);
// Subtractive
#if 1
BlendTab_GenerateMaps(blendtab_subtract, AST_SUBTRACT, BlendTab_Subtractive);
#else
BlendTab_GenerateMaps(blendtab_subtract, AST_SUBTRACT, BlendTab_Translucent);
#endif
// Reverse subtractive
BlendTab_GenerateMaps(blendtab_reversesubtract, AST_REVERSESUBTRACT, BlendTab_Translucent);
// Modulative blending only requires a single table
BlendTab_Modulative(blendtables[blendtab_modulate]);
{
if (i == blendtab_modulate)
continue;
blendtables[i] = Z_MallocAlign((NUMTRANSTABLES + 1) * 0x10000, PU_STATIC, NULL, 16);
}
for (i = 0; i <= 9; i++)
{
const size_t offs = (0x10000 * i);
const UINT8 alpha = (TRANSTAB_AMTMUL10 * ((float)(10-i)));
R_GenerateTranslucencyTable(blendtables[blendtab_add] + offs, AST_ADD, alpha);
R_GenerateTranslucencyTable(blendtables[blendtab_subtract] + offs, AST_SUBTRACT, alpha);
R_GenerateTranslucencyTable(blendtables[blendtab_reversesubtract] + offs, AST_REVERSESUBTRACT, alpha);
}
// Modulation blending only requires a single table
blendtables[blendtab_modulate] = Z_MallocAlign(0x10000, PU_STATIC, NULL, 16);
R_GenerateTranslucencyTable(blendtables[blendtab_modulate], AST_MODULATE, 0);
}
void R_GenerateTranslucencyTable(UINT8 *table, int style, UINT8 blendamt)
{
INT16 bg, fg;
RGBA_t backrgba, frontrgba, result;
if (table == NULL)
I_Error("R_GenerateTranslucencyTable: input table was NULL!");
for (bg = 0; bg <= 0xFF; bg++)
{
backrgba = pGammaCorrectedPalette[bg];
for (fg = 0; fg <= 0xFF; fg++)
{
frontrgba = pGammaCorrectedPalette[fg];
#if 0 // perfect implementation
result.rgba = V_GammaEncode(ASTBlendPixel(backrgba, frontrgba, style, blendamt));
table[((fg * 0x100) + bg)] = NearestPaletteColor(result.s.red, result.s.green, result.s.blue, pMasterPalette);
#else // performance scrabbler
result.rgba = ASTBlendPixel(backrgba, frontrgba, style, blendamt);
table[((fg * 0x100) + bg)] = NearestPaletteColor(result.s.red, result.s.green, result.s.blue, pGammaCorrectedPalette);
#endif
}
}
}
#define ClipBlendLevel(style, trans) max(min((trans), BlendTab_Count[BlendTab_FromStyle[style]]-1), 0)
#define ClipTransLevel(trans) max(min((trans), NUMTRANSMAPS-2), 0)
UINT8 *R_GetTranslucencyTable(INT32 alphalevel)
@ -339,12 +259,7 @@ UINT8 *R_GetTranslucencyTable(INT32 alphalevel)
UINT8 *R_GetBlendTable(int style, INT32 alphalevel)
{
size_t offs;
if (style == AST_COPY || style == AST_OVERLAY)
return NULL;
offs = (ClipBlendLevel(style, alphalevel) << FF_TRANSSHIFT);
size_t offs = (ClipTransLevel(alphalevel) << FF_TRANSSHIFT);
// Lactozilla: Returns the equivalent to AST_TRANSLUCENT
// if no alpha style matches any of the blend tables.
@ -363,18 +278,9 @@ UINT8 *R_GetBlendTable(int style, INT32 alphalevel)
}
// Return a normal translucency table
if (--alphalevel >= 0)
return transtables + (ClipTransLevel(alphalevel) << FF_TRANSSHIFT);
else
if (--alphalevel < 0)
return NULL;
}
boolean R_BlendLevelVisible(INT32 blendmode, INT32 alphalevel)
{
if (blendmode == AST_COPY || blendmode == AST_SUBTRACT || blendmode == AST_MODULATE || blendmode == AST_OVERLAY)
return true;
return (alphalevel < BlendTab_Count[BlendTab_FromStyle[blendmode]]);
return transtables + (ClipTransLevel(alphalevel) << FF_TRANSSHIFT);
}
// Define for getting accurate color brightness readings according to how the human eye sees them.

View file

@ -140,11 +140,11 @@ extern UINT8 *blendtables[NUMBLENDMAPS];
void R_InitTranslucencyTables(void);
void R_GenerateBlendTables(void);
void R_GenerateTranslucencyTable(UINT8 *table, int style, UINT8 blendamt);
UINT8 *R_GetTranslucencyTable(INT32 alphalevel);
UINT8 *R_GetBlendTable(int style, INT32 alphalevel);
boolean R_BlendLevelVisible(INT32 blendmode, INT32 alphalevel);
// Color ramp modification should force a recache
extern UINT8 skincolor_modified[];

View file

@ -842,28 +842,14 @@ void R_DrawSinglePlane(visplane_t *pl)
spanfunctype = (pl->ffloor->master->flags & ML_EFFECT6) ? SPANDRAWFUNC_TRANSSPLAT : SPANDRAWFUNC_TRANS;
// Hacked up support for alpha value in software mode Tails 09-24-2002
if (pl->ffloor->alpha < 12)
// ...unhacked by toaster 04-01-2021
{
INT32 trans = (10*((256+12) - pl->ffloor->alpha))/255;
if (trans >= 10)
return; // Don't even draw it
else if (pl->ffloor->alpha < 38)
ds_transmap = R_GetTranslucencyTable(tr_trans90);
else if (pl->ffloor->alpha < 64)
ds_transmap = R_GetTranslucencyTable(tr_trans80);
else if (pl->ffloor->alpha < 89)
ds_transmap = R_GetTranslucencyTable(tr_trans70);
else if (pl->ffloor->alpha < 115)
ds_transmap = R_GetTranslucencyTable(tr_trans60);
else if (pl->ffloor->alpha < 140)
ds_transmap = R_GetTranslucencyTable(tr_trans50);
else if (pl->ffloor->alpha < 166)
ds_transmap = R_GetTranslucencyTable(tr_trans40);
else if (pl->ffloor->alpha < 192)
ds_transmap = R_GetTranslucencyTable(tr_trans30);
else if (pl->ffloor->alpha < 217)
ds_transmap = R_GetTranslucencyTable(tr_trans20);
else if (pl->ffloor->alpha < 243)
ds_transmap = R_GetTranslucencyTable(tr_trans10);
else // Opaque, but allow transparent flat pixels
spanfunctype = SPANDRAWFUNC_SPLAT;
if (!(ds_transmap = R_GetBlendTable(pl->ffloor->blend, trans)))
spanfunctype = SPANDRAWFUNC_SPLAT; // Opaque, but allow transparent flat pixels
}
if ((spanfunctype == SPANDRAWFUNC_SPLAT) || (pl->extra_colormap && (pl->extra_colormap->flags & CMF_FOG)))
light = (pl->lightlevel >> LIGHTSEGSHIFT);

View file

@ -120,9 +120,13 @@ 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 = NUMTRANSMAPS; // Send back NUMTRANSMAPS for none
fixed_t alpha = ldef->alpha;
if (alpha > 0 && alpha < FRACUNIT)
transnum = (20*(FRACUNIT - alpha - 1) + FRACUNIT) >> (FRACBITS+1);
return transnum;
}
void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
@ -139,6 +143,8 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
INT32 times, repeats;
INT64 overflow_test;
INT32 range;
transnum_t transtable = NUMTRANSMAPS;
patchalphastyle_t blendmode = 0;
// Calculate light table.
// Use different light tables
@ -155,11 +161,33 @@ 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 (ldef->special == 910)
{
if (transtable == NUMTRANSMAPS)
transtable = 0;
blendmode = AST_ADD;
}
else if (ldef->special == 911)
{
if (transtable == NUMTRANSMAPS)
transtable = 0;
blendmode = AST_SUBTRACT;
}
else if (ldef->special == 912)
{
if (transtable == NUMTRANSMAPS)
transtable = 0;
blendmode = AST_REVERSESUBTRACT;
}
else if (ldef->special == 913)
{
transtable = 0;
blendmode = AST_MODULATE;
}
if ((dc_transmap = R_GetBlendTable(blendmode, transtable)))
{
dc_transmap = R_GetTranslucencyTable(R_GetLinedefTransTable(ldef->alpha));
colfunc = colfuncs[COLDRAWFUNC_FUZZY];
}
else if (ldef->special == 909)
{
@ -600,28 +628,14 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
boolean fuzzy = true;
// Hacked up support for alpha value in software mode Tails 09-24-2002
if (pfloor->alpha < 12)
// ...unhacked by toaster 04-01-2021
{
INT32 trans = (10*((256+12) - pfloor->alpha))/255;
if (trans >= 10)
return; // Don't even draw it
else if (pfloor->alpha < 38)
dc_transmap = R_GetTranslucencyTable(tr_trans90);
else if (pfloor->alpha < 64)
dc_transmap = R_GetTranslucencyTable(tr_trans80);
else if (pfloor->alpha < 89)
dc_transmap = R_GetTranslucencyTable(tr_trans70);
else if (pfloor->alpha < 115)
dc_transmap = R_GetTranslucencyTable(tr_trans60);
else if (pfloor->alpha < 140)
dc_transmap = R_GetTranslucencyTable(tr_trans50);
else if (pfloor->alpha < 166)
dc_transmap = R_GetTranslucencyTable(tr_trans40);
else if (pfloor->alpha < 192)
dc_transmap = R_GetTranslucencyTable(tr_trans30);
else if (pfloor->alpha < 217)
dc_transmap = R_GetTranslucencyTable(tr_trans20);
else if (pfloor->alpha < 243)
dc_transmap = R_GetTranslucencyTable(tr_trans10);
else
if (!(dc_transmap = R_GetBlendTable(pfloor->blend, trans)))
fuzzy = false; // Opaque
}
if (fuzzy)
colfunc = colfuncs[COLDRAWFUNC_FUZZY];

View file

@ -18,7 +18,7 @@
#pragma interface
#endif
transnum_t R_GetLinedefTransTable(fixed_t alpha);
transnum_t R_GetLinedefTransTable(line_t *ldef);
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

@ -1072,7 +1072,7 @@ static texpatch_t *R_ParsePatch(boolean actuallyLoadPatch)
INT16 patchYPos;
UINT8 flip = 0;
UINT8 alpha = 255;
enum patchalphastyle style = AST_COPY;
patchalphastyle_t style = AST_COPY;
texpatch_t *resultPatch = NULL;
lumpnum_t patchLumpNum;

View file

@ -33,7 +33,7 @@ typedef struct
UINT16 wad, lump;
UINT8 flip; // 1 = flipx, 2 = flipy, 3 = both
UINT8 alpha; // Translucency value
enum patchalphastyle style;
patchalphastyle_t style;
} texpatch_t;
// texture type

View file

@ -1109,6 +1109,10 @@ static void R_SplitSprite(vissprite_t *sprite)
if (lindex >= MAXLIGHTSCALE)
lindex = MAXLIGHTSCALE-1;
if (newsprite->cut & SC_SEMIBRIGHT)
lindex = (MAXLIGHTSCALE/2) + (lindex >> 1);
newsprite->colormap = spritelights[lindex];
}
}
@ -1410,7 +1414,8 @@ static void R_ProjectSprite(mobj_t *thing)
boolean hflip = (!R_ThingHorizontallyFlipped(thing) != !mirrored);
INT32 lindex;
INT32 trans;
UINT32 blendmode;
UINT32 trans;
vissprite_t *vis;
patch_t *patch;
@ -1799,15 +1804,26 @@ static void R_ProjectSprite(mobj_t *thing)
// Determine the translucency value.
if (oldthing->flags2 & MF2_SHADOW || thing->flags2 & MF2_SHADOW) // actually only the player should use this (temporary invisibility)
trans = tr_trans80; // because now the translucency is set through FF_TRANSMASK
else if (oldthing->frame & FF_TRANSMASK)
{
trans = (oldthing->frame & FF_TRANSMASK) >> FF_TRANSSHIFT;
if (!R_BlendLevelVisible(oldthing->blendmode, trans))
return;
trans = tr_trans80; // because now the translucency is set through FF_TRANSMASK
blendmode = 0;
}
else
trans = 0;
{
if (oldthing->renderflags & RF_BLENDMASK)
blendmode = (oldthing->renderflags & RF_BLENDMASK) >> RF_BLENDSHIFT;
else
blendmode = (oldthing->frame & FF_BLENDMASK) >> FF_BLENDSHIFT;
if (blendmode)
blendmode++; // realign to constants
if (oldthing->renderflags & RF_TRANSMASK)
trans = (oldthing->renderflags & RF_TRANSMASK) >> RF_TRANSSHIFT;
else
trans = (oldthing->frame & FF_TRANSMASK) >> FF_TRANSSHIFT;
if (trans >= NUMTRANSMAPS)
return; // cap
}
// Check if this sprite needs to be rendered like a shadow
shadowdraw = (!!(thing->renderflags & RF_SHADOWDRAW) && !(papersprite || splat));
@ -2012,13 +2028,12 @@ static void R_ProjectSprite(mobj_t *thing)
vis->scale += FixedMul(scalestep, spriteyscale) * (vis->x1 - x1);
}
if ((oldthing->blendmode != AST_COPY) && cv_translucency.value)
vis->transmap = R_GetBlendTable(oldthing->blendmode, trans);
else
vis->transmap = NULL;
vis->transmap = R_GetBlendTable(blendmode, trans);
if (R_ThingIsFullBright(oldthing) || oldthing->flags2 & MF2_SHADOW || thing->flags2 & MF2_SHADOW)
vis->cut |= SC_FULLBRIGHT;
else if (R_ThingIsSemiBright(oldthing))
vis->cut |= SC_SEMIBRIGHT;
else if (R_ThingIsFullDark(oldthing))
vis->cut |= SC_FULLDARK;
@ -2041,6 +2056,9 @@ static void R_ProjectSprite(mobj_t *thing)
if (lindex >= MAXLIGHTSCALE)
lindex = MAXLIGHTSCALE-1;
if (vis->cut & SC_SEMIBRIGHT)
lindex = (MAXLIGHTSCALE/2) + (lindex >> 1);
vis->colormap = spritelights[lindex];
}
@ -3008,7 +3026,7 @@ boolean R_ThingVisible (mobj_t *thing)
{
return (!(
thing->sprite == SPR_NULL ||
( thing->flags2 & (MF2_DONTDRAW) ) ||
( thing->flags2 & (MF2_DONTDRAW) ) || ( thing->renderflags & (RF_DONTDRAW) ) ||
(r_viewmobj && (thing == r_viewmobj || (r_viewmobj->player && r_viewmobj->player->followmobj == thing)))
));
}
@ -3069,19 +3087,31 @@ boolean R_ThingIsPaperSprite(mobj_t *thing)
boolean R_ThingIsFloorSprite(mobj_t *thing)
{
return (thing->flags2 & MF2_SPLAT || thing->renderflags & RF_FLOORSPRITE);
return (thing->flags2 & MF2_SPLAT || thing->frame & FF_FLOORSPRITE || thing->renderflags & RF_FLOORSPRITE);
}
boolean R_ThingIsFullBright(mobj_t *thing)
{
return (thing->frame & FF_FULLBRIGHT || thing->renderflags & RF_FULLBRIGHT);
if (thing->renderflags & RF_BRIGHTMASK)
return ((thing->renderflags & RF_BRIGHTMASK) == RF_FULLBRIGHT);
return ((thing->frame & FF_BRIGHTMASK) == FF_FULLBRIGHT);
}
boolean R_ThingIsSemiBright(mobj_t *thing)
{
if (thing->renderflags & RF_BRIGHTMASK)
return ((thing->renderflags & RF_BRIGHTMASK) == RF_SEMIBRIGHT);
return ((thing->frame & FF_BRIGHTMASK) == FF_SEMIBRIGHT);
}
boolean R_ThingIsFullDark(mobj_t *thing)
{
return (thing->renderflags & RF_FULLDARK);
if (thing->renderflags & RF_BRIGHTMASK)
return ((thing->renderflags & RF_BRIGHTMASK) == RF_FULLDARK);
return ((thing->frame & FF_BRIGHTMASK) == FF_FULLDARK);
}
//
// R_DrawMasked
//

View file

@ -82,6 +82,7 @@ boolean R_ThingIsPaperSprite (mobj_t *thing);
boolean R_ThingIsFloorSprite (mobj_t *thing);
boolean R_ThingIsFullBright (mobj_t *thing);
boolean R_ThingIsSemiBright (mobj_t *thing);
boolean R_ThingIsFullDark (mobj_t *thing);
// --------------
@ -123,13 +124,14 @@ typedef enum
SC_PRECIP = 1<<2,
SC_LINKDRAW = 1<<3,
SC_FULLBRIGHT = 1<<4,
SC_FULLDARK = 1<<5,
SC_VFLIP = 1<<6,
SC_ISSCALED = 1<<7,
SC_ISROTATED = 1<<8,
SC_SHADOW = 1<<9,
SC_SHEAR = 1<<10,
SC_SPLAT = 1<<11,
SC_SEMIBRIGHT = 1<<5,
SC_FULLDARK = 1<<6,
SC_VFLIP = 1<<7,
SC_ISSCALED = 1<<8,
SC_ISROTATED = 1<<9,
SC_SHADOW = 1<<10,
SC_SHEAR = 1<<11,
SC_SPLAT = 1<<12,
// masks
SC_CUTMASK = SC_TOP|SC_BOTTOM,
SC_FLAGMASK = ~SC_CUTMASK

View file

@ -86,6 +86,7 @@ consvar_t cv_constextsize = CVAR_INIT ("con_textsize", "Medium", CV_SAVE|CV_CALL
// local copy of the palette for V_GetColor()
RGBA_t *pLocalPalette = NULL;
RGBA_t *pMasterPalette = NULL;
RGBA_t *pGammaCorrectedPalette = NULL;
/*
The following was an extremely helpful resource when developing my Colour Cube LUT.
@ -279,33 +280,25 @@ static boolean InitCube(void)
return true;
}
#ifdef BACKWARDSCOMPATCORRECTION
/*
So it turns out that the way gamma was implemented previously, the default
colour profile of the game was messed up. Since this bad decision has been
around for a long time, and the intent is to keep the base game looking the
same, I'm not gonna be the one to remove this base modification.
toast 20/04/17
... welp yes i am (27/07/19, see the ifdef around it)
*/
const UINT8 correctiontable[256] =
{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,
17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,
33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,
49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,
65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,
81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,
97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,
113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,
128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,
160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,
176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,
192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,
208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,
224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,
240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255};
#endif
UINT32 V_GammaCorrect(UINT32 input, double power)
{
RGBA_t result;
double linear;
result.rgba = input;
linear = ((double)result.s.red)/255.0f;
linear = pow(linear, power)*255.0f;
result.s.red = (UINT8)(linear);
linear = ((double)result.s.green)/255.0f;
linear = pow(linear, power)*255.0f;
result.s.green = (UINT8)(linear);
linear = ((double)result.s.blue)/255.0f;
linear = pow(linear, power)*255.0f;
result.s.blue = (UINT8)(linear);
return result.rgba;
}
// keep a copy of the palette so that we can get the RGB value for a color index at any time.
static void LoadPalette(const char *lumpname)
@ -316,42 +309,45 @@ static void LoadPalette(const char *lumpname)
Cubeapply = InitCube();
if (pLocalPalette != pMasterPalette)
Z_Free(pLocalPalette);
Z_Free(pMasterPalette);
pLocalPalette = Z_Malloc(sizeof (*pLocalPalette)*palsize, PU_STATIC, NULL);
pMasterPalette = Z_Malloc(sizeof (*pMasterPalette)*palsize, PU_STATIC, NULL);
if (Cubeapply)
pLocalPalette = Z_Malloc(sizeof (*pLocalPalette)*palsize, PU_STATIC, NULL);
else
pLocalPalette = pMasterPalette;
pGammaCorrectedPalette = Z_Malloc(sizeof (*pGammaCorrectedPalette)*palsize, PU_STATIC, NULL);
pal = W_CacheLumpNum(lumpnum, PU_CACHE);
for (i = 0; i < palsize; i++)
{
#ifdef BACKWARDSCOMPATCORRECTION
pMasterPalette[i].s.red = pLocalPalette[i].s.red = correctiontable[*pal++];
pMasterPalette[i].s.green = pLocalPalette[i].s.green = correctiontable[*pal++];
pMasterPalette[i].s.blue = pLocalPalette[i].s.blue = correctiontable[*pal++];
#else
pMasterPalette[i].s.red = pLocalPalette[i].s.red = *pal++;
pMasterPalette[i].s.green = pLocalPalette[i].s.green = *pal++;
pMasterPalette[i].s.blue = pLocalPalette[i].s.blue = *pal++;
#endif
pMasterPalette[i].s.alpha = pLocalPalette[i].s.alpha = 0xFF;
pMasterPalette[i].s.red = *pal++;
pMasterPalette[i].s.green = *pal++;
pMasterPalette[i].s.blue = *pal++;
pMasterPalette[i].s.alpha = 0xFF;
// lerp of colour cubing! if you want, make it smoother yourself
if (Cubeapply)
V_CubeApply(&pLocalPalette[i].s.red, &pLocalPalette[i].s.green, &pLocalPalette[i].s.blue);
pGammaCorrectedPalette[i].rgba = V_GammaDecode(pMasterPalette[i].rgba);
if (!Cubeapply)
continue;
pLocalPalette[i].rgba = V_GammaEncode(V_CubeApply(&pGammaCorrectedPalette[i]));
}
}
void V_CubeApply(UINT8 *red, UINT8 *green, UINT8 *blue)
UINT32 V_CubeApply(RGBA_t *input)
{
float working[4][3];
float linear;
UINT8 q;
RGBA_t result;
if (!Cubeapply)
return;
return (*input).rgba;
linear = (*red/255.0);
linear = ((*input).s.red/255.0);
#define dolerp(e1, e2) ((1 - linear)*e1 + linear*e2)
for (q = 0; q < 3; q++)
{
@ -360,13 +356,13 @@ void V_CubeApply(UINT8 *red, UINT8 *green, UINT8 *blue)
working[2][q] = dolerp(Cubepal[0][0][1][q], Cubepal[1][0][1][q]);
working[3][q] = dolerp(Cubepal[0][1][1][q], Cubepal[1][1][1][q]);
}
linear = (*green/255.0);
linear = ((*input).s.green/255.0);
for (q = 0; q < 3; q++)
{
working[0][q] = dolerp(working[0][q], working[1][q]);
working[1][q] = dolerp(working[2][q], working[3][q]);
}
linear = (*blue/255.0);
linear = ((*input).s.blue/255.0);
for (q = 0; q < 3; q++)
{
working[0][q] = 255*dolerp(working[0][q], working[1][q]);
@ -377,9 +373,12 @@ void V_CubeApply(UINT8 *red, UINT8 *green, UINT8 *blue)
}
#undef dolerp
*red = (UINT8)(working[0][0]);
*green = (UINT8)(working[0][1]);
*blue = (UINT8)(working[0][2]);
result.s.red = (UINT8)(working[0][0]);
result.s.green = (UINT8)(working[0][1]);
result.s.blue = (UINT8)(working[0][2]);
result.s.alpha = (*input).s.alpha;
return result.rgba;
}
const char *R_GetPalname(UINT16 num)
@ -510,7 +509,7 @@ static inline UINT8 transmappedpdraw(const UINT8 *dest, const UINT8 *source, fix
void V_DrawStretchyFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, fixed_t vscale, INT32 scrn, patch_t *patch, const UINT8 *colormap)
{
UINT8 (*patchdrawfunc)(const UINT8*, const UINT8*, fixed_t);
UINT32 alphalevel = 0;
UINT32 alphalevel, blendmode;
fixed_t col, ofs, colfrac, rowfrac, fdup, vdup;
INT32 dupx, dupy;
@ -536,25 +535,22 @@ void V_DrawStretchyFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, fixed_t vsca
patchdrawfunc = standardpdraw;
v_translevel = NULL;
if ((blendmode = ((scrn & V_BLENDMASK) >> V_BLENDSHIFT)))
blendmode++; // realign to constants
if ((alphalevel = ((scrn & V_ALPHAMASK) >> V_ALPHASHIFT)))
{
if (alphalevel == 13)
if (alphalevel == 10) // V_HUDTRANSHALF
alphalevel = hudminusalpha[st_translucency];
else if (alphalevel == 14)
else if (alphalevel == 11) // V_HUDTRANS
alphalevel = 10 - st_translucency;
else if (alphalevel == 15)
else if (alphalevel == 12) // V_HUDTRANSDOUBLE
alphalevel = hudplusalpha[st_translucency];
if (alphalevel >= 10)
return; // invis
if (alphalevel)
{
v_translevel = R_GetTranslucencyTable(alphalevel);
if (alphalevel >= 10) // Still inelegible to render?
return;
}
if ((v_translevel = R_GetBlendTable(blendmode, alphalevel)))
patchdrawfunc = translucentpdraw;
}
}
v_colormap = NULL;
if (colormap)
@ -590,10 +586,6 @@ void V_DrawStretchyFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, fixed_t vsca
colfrac = FixedDiv(FRACUNIT, fdup);
rowfrac = FixedDiv(FRACUNIT, vdup);
// So it turns out offsets aren't scaled in V_NOSCALESTART unless V_OFFSET is applied ...poo, that's terrible
// For now let's just at least give V_OFFSET the ability to support V_FLIP
// I'll probably make a better fix for 2.2 where I don't have to worry about breaking existing support for stuff
// -- Monster Iestyn 29/10/18
{
fixed_t offsetx = 0, offsety = 0;
@ -604,15 +596,9 @@ void V_DrawStretchyFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, fixed_t vsca
offsetx = FixedMul(patch->leftoffset<<FRACBITS, pscale);
// top offset
// TODO: make some kind of vertical version of V_FLIP, maybe by deprecating V_OFFSET in future?!?
// TODO: make some kind of vertical version of V_FLIP
offsety = FixedMul(patch->topoffset<<FRACBITS, vscale);
if ((scrn & (V_NOSCALESTART|V_OFFSET)) == (V_NOSCALESTART|V_OFFSET)) // Multiply by dupx/dupy for crosshairs
{
offsetx = FixedMul(offsetx, dupx<<FRACBITS);
offsety = FixedMul(offsety, dupy<<FRACBITS);
}
// Subtract the offsets from x/y positions
x -= offsetx;
y -= offsety;
@ -811,7 +797,7 @@ void V_DrawStretchyFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, fixed_t vsca
void V_DrawCroppedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_t *patch, fixed_t sx, fixed_t sy, fixed_t w, fixed_t h)
{
UINT8 (*patchdrawfunc)(const UINT8*, const UINT8*, fixed_t);
UINT32 alphalevel = 0;
UINT32 alphalevel, blendmode;
// boolean flip = false;
fixed_t col, ofs, colfrac, rowfrac, fdup;
@ -836,25 +822,22 @@ void V_DrawCroppedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_
patchdrawfunc = standardpdraw;
v_translevel = NULL;
if ((blendmode = ((scrn & V_BLENDMASK) >> V_BLENDSHIFT)))
blendmode++; // realign to constants
if ((alphalevel = ((scrn & V_ALPHAMASK) >> V_ALPHASHIFT)))
{
if (alphalevel == 13)
if (alphalevel == 10) // V_HUDTRANSHALF
alphalevel = hudminusalpha[st_translucency];
else if (alphalevel == 14)
else if (alphalevel == 11) // V_HUDTRANS
alphalevel = 10 - st_translucency;
else if (alphalevel == 15)
else if (alphalevel == 12) // V_HUDTRANSDOUBLE
alphalevel = hudplusalpha[st_translucency];
if (alphalevel >= 10)
return; // invis
if (alphalevel)
{
v_translevel = R_GetTranslucencyTable(alphalevel);
if (alphalevel >= 10) // Still inelegible to render?
return;
}
if ((v_translevel = R_GetBlendTable(blendmode, alphalevel)))
patchdrawfunc = translucentpdraw;
}
}
// only use one dup, to avoid stretching (har har)
dupx = dupy = (vid.dupx < vid.dupy ? vid.dupx : vid.dupy);
@ -1358,15 +1341,15 @@ void V_DrawFillConsoleMap(INT32 x, INT32 y, INT32 w, INT32 h, INT32 c)
if ((alphalevel = ((c & V_ALPHAMASK) >> V_ALPHASHIFT)))
{
if (alphalevel == 13)
if (alphalevel == 10) // V_HUDTRANSHALF
alphalevel = hudminusalpha[st_translucency];
else if (alphalevel == 14)
else if (alphalevel == 11) // V_HUDTRANS
alphalevel = 10 - st_translucency;
else if (alphalevel == 15)
else if (alphalevel == 12) // V_HUDTRANSDOUBLE
alphalevel = hudplusalpha[st_translucency];
if (alphalevel >= 10)
return; // invis
if (alphalevel >= 10) // Still inelegible to render?
return;
}
if (splitscreen && (c & V_PERPLAYER))

View file

@ -63,8 +63,13 @@ const char *GetPalette(void);
extern RGBA_t *pLocalPalette;
extern RGBA_t *pMasterPalette;
extern RGBA_t *pGammaCorrectedPalette;
void V_CubeApply(UINT8 *red, UINT8 *green, UINT8 *blue);
UINT32 V_GammaCorrect(UINT32 input, double power);
#define V_GammaDecode(input) V_GammaCorrect(input, 2.2f)
#define V_GammaEncode(input) V_GammaCorrect(input, (1/2.2f))
UINT32 V_CubeApply(RGBA_t *input);
// Retrieve the ARGB value from a palette color index
#define V_GetColor(color) (pLocalPalette[color&0xFF])
@ -122,17 +127,23 @@ void V_CubeApply(UINT8 *red, UINT8 *green, UINT8 *blue);
#define V_70TRANS 0x00070000
#define V_80TRANS 0x00080000 // used to be V_8020TRANS
#define V_90TRANS 0x00090000
#define V_HUDTRANSHALF 0x000D0000
#define V_HUDTRANS 0x000E0000 // draw the hud translucent
#define V_HUDTRANSDOUBLE 0x000F0000
#define V_HUDTRANSHALF 0x000A0000
#define V_HUDTRANS 0x000B0000 // draw the hud translucent
#define V_HUDTRANSDOUBLE 0x000C0000
// Macros follow
#define V_USERHUDTRANSHALF ((10-(cv_translucenthud.value/2))<<V_ALPHASHIFT)
#define V_USERHUDTRANS ((10-cv_translucenthud.value)<<V_ALPHASHIFT)
#define V_USERHUDTRANSDOUBLE ((10-min(cv_translucenthud.value*2, 10))<<V_ALPHASHIFT)
#define V_AUTOFADEOUT 0x00100000 // used by CECHOs, automatic fade out when almost over
#define V_RETURN8 0x00200000 // 8 pixel return instead of 12
#define V_OFFSET 0x00400000 // account for offsets in patches
// use bits 21-23 for blendmodes
#define V_BLENDSHIFT 20
#define V_BLENDMASK 0x00700000
// preshifted blend flags minus 1 as effects don't distinguish between AST_COPY and AST_TRANSLUCENT
#define V_ADD ((AST_ADD-1)<<V_BLENDSHIFT) // Additive
#define V_SUBTRACT ((AST_SUBTRACT-1)<<V_BLENDSHIFT) // Subtractive
#define V_REVERSESUBTRACT ((AST_REVERSESUBTRACT-1)<<V_BLENDSHIFT) // Reverse subtractive
#define V_MODULATE ((AST_MODULATE-1)<<V_BLENDSHIFT) // Modulate
#define V_ALLOWLOWERCASE 0x00800000 // (strings only) allow fonts that have lowercase letters to use them
#define V_FLIP 0x00800000 // (patches only) Horizontal flip
#define V_CENTERNAMETAG 0x00800000 // (nametag only) center nametag lines
@ -142,8 +153,8 @@ void V_CubeApply(UINT8 *red, UINT8 *green, UINT8 *blue);
#define V_SNAPTOLEFT 0x04000000 // for centering
#define V_SNAPTORIGHT 0x08000000 // for centering
#define V_WRAPX 0x10000000 // Don't clamp texture on X (for HW mode)
#define V_WRAPY 0x20000000 // Don't clamp texture on Y (for HW mode)
#define V_AUTOFADEOUT 0x10000000 // used by CECHOs, automatic fade out when almost over
#define V_RETURN8 0x20000000 // 8 pixel return instead of 12
#define V_NOSCALESTART 0x40000000 // don't scale x, y, start coords
#define V_PERPLAYER 0x80000000 // automatically adjust coordinates/scaling for splitscreen mode