Blending modes (and a few refactors) #158

Merged
Chearii merged 6 commits from blendmodes into Saturn 2025-03-05 10:12:55 +01:00
34 changed files with 1038 additions and 312 deletions

No files matched your search

+28
View File
@@ -7721,7 +7721,18 @@ struct {
{"FF_HORIZONTALFLIP",FF_HORIZONTALFLIP},
{"FF_PAPERSPRITE",FF_PAPERSPRITE},
{"FF_ANIMATE",FF_ANIMATE},
// brightness
{"FF_BRIGHTMASK",FF_BRIGHTMASK},
{"FF_FULLBRIGHT",FF_FULLBRIGHT},
{"FF_SEMIBRIGHT",FF_SEMIBRIGHT},
{"FF_FULLDARK",FF_FULLDARK},
// blending
{"FF_BLENDMASK",FF_BLENDMASK},
{"FF_BLENDSHIFT",FF_BRIGHTMASK},
{"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)
@@ -7757,6 +7768,15 @@ struct {
{"tr_trans90",tr_trans90},
{"NUMTRANSMAPS",NUMTRANSMAPS},
// Alpha styles (blend modes)
{"AST_COPY",AST_COPY},
{"AST_TRANSLUCENT",AST_TRANSLUCENT},
{"AST_ADD",AST_ADD},
{"AST_SUBTRACT",AST_SUBTRACT},
{"AST_REVERSESUBTRACT",AST_REVERSESUBTRACT},
{"AST_MODULATE",AST_MODULATE},
{"AST_OVERLAY",AST_OVERLAY},
// Type of levels
{"TOL_SP",TOL_SP},
{"TOL_COOP",TOL_COOP},
@@ -8121,6 +8141,14 @@ struct {
{"V_CHARCOLORSHIFT",V_CHARCOLORSHIFT},
{"V_ALPHASHIFT",V_ALPHASHIFT},
// Blending
{"V_BLENDSHIFT",V_BLENDSHIFT},
{"V_BLENDMASK",V_BLENDMASK},
{"B_ADD",B_ADD},
{"B_SUBTRACT",B_SUBTRACT},
{"B_REVERSESUBTRACT",B_REVERSESUBTRACT},
{"B_MODULATE",B_MODULATE},
//Kick Reasons
{"KR_KICK",KR_KICK},
{"KR_PINGLIMIT",KR_PINGLIMIT},
+1 -1
View File
@@ -273,7 +273,7 @@ static void F_DoWipe(fademask_t *fademask)
else
{
// pointer to transtable that this mask would use
transtbl = transtables + ((9 - *mask)<<FF_TRANSSHIFT);
transtbl = R_GetTranslucencyTable((9 - *mask) + 1);
// DRAWING LOOP
while (draw_linestogo--)
+13 -13
View File
@@ -213,22 +213,22 @@ enum EPolyFlags
{
// the first 5 are mutually exclusive
PF_Masked = 0x00000001, // Poly is alpha scaled and 0 alpha pels are discarded (holes in texture)
PF_Masked = 0x00000001, // Poly is alpha scaled and 0 alpha pixels are discarded (holes in texture)
PF_Translucent = 0x00000002, // Poly is transparent, alpha = level of transparency
PF_Additive = 0x00000004, // Poly is added to the frame buffer
PF_Environment = 0x00000008, // Poly should be drawn environment mapped.
// Hurdler: used for text drawing
PF_Substractive = 0x00000010, // for splat
PF_NoAlphaTest = 0x00000020, // hiden param
PF_Fog = 0x00000040, // Fog blocks
PF_Blending = (PF_Environment|PF_Additive|PF_Translucent|PF_Masked|PF_Substractive|PF_Fog)&~PF_NoAlphaTest,
PF_Environment = 0x00000004, // Poly should be drawn environment mapped. (Hurdler: used for text drawing)
PF_Additive = 0x00000008, // Source blending factor is additive.
PF_Subtractive = 0x00000010, // Subtractive color blending
PF_ReverseSubtract = 0x00000020, // Reverse subtract, used in wall splats (decals)
PF_Multiplicative = 0x00000040, // Multiplicative color blending
PF_Fog = 0x20000000, // Fog blocks
PF_NoAlphaTest = 0x40000000, // Disables alpha testing
PF_Blending = (PF_Masked|PF_Translucent|PF_Environment|PF_Additive|PF_Subtractive|PF_ReverseSubtract|PF_Multiplicative|PF_Fog) & ~PF_NoAlphaTest,
// other flag bits
PF_Occlude = 0x00000100, // Update the depth buffer
PF_NoDepthTest = 0x00000200, // Disable the depth test mode
PF_Invisible = 0x00000400, // Disable write to color buffer
PF_Decal = 0x00000800, // Enable polygon offset
PF_Occlude = 0x00000100, // Updates the depth buffer
PF_NoDepthTest = 0x00000200, // Disables the depth test mode
PF_Invisible = 0x00000400, // Disables write to color buffer
PF_Decal = 0x00000800, // Enables polygon offset
PF_Modulated = 0x00001000, // Modulation (multiply output with constant RGBA)
// When set, pass the color constant into the FSurfaceInfo -> FlatColor
PF_NoTexture = 0x00002000, // Disable texture
+12 -2
View File
@@ -125,13 +125,14 @@ void HWR_DrawPatch(GLPatch_t *gpatch, INT32 x, INT32 y, INT32 option)
HWD.pfnDrawPolygon(NULL, v, 4, flags);
}
void HWR_DrawStretchyFixedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale, fixed_t vscale, INT32 option, const UINT8 *colormap)
void HWR_DrawStretchyFixedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale, fixed_t vscale, INT32 option, const UINT8 *colormap, INT32 bflags)
{
FOutVector v[4];
FBITFIELD flags;
float cx = FIXED_TO_FLOAT(x);
float cy = FIXED_TO_FLOAT(y);
UINT8 alphalevel = ((option & V_ALPHAMASK) >> V_ALPHASHIFT);
UINT8 blendmode = ((bflags & V_BLENDMASK) >> V_BLENDSHIFT);
// 3--2
// | /|
@@ -286,7 +287,11 @@ void HWR_DrawStretchyFixedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t
v[0].t = v[1].t = 0.0f;
alufolie91 commented 2025-03-04 21:32:11 +01:00 (Migrated from github.com)
Review

ok for whatever reason github refused to show my comment here so let me requote it lel

Noticed this while compiling with clang, the flag assingment should be moved back to before the "V_WRAP" handling, otherwise those options get overwritten (and doing any operation on an unitialized value may lead to undefined behaviour)

ok for whatever reason github refused to show my comment here so let me requote it lel > Noticed this while compiling with clang, the flag assingment should be moved back to before the "V_WRAP" handling, otherwise those options get overwritten (and doing any operation on an unitialized value may lead to undefined behaviour)
Chearii commented 2025-03-05 01:47:35 +01:00 (Migrated from github.com)
Review

ah, good catch
hopefully these last few commits fix this and the performance issues mentioned

ah, good catch hopefully these last few commits fix this and the performance issues mentioned
alufolie91 commented 2025-03-05 08:00:47 +01:00 (Migrated from github.com)
Review

yeah everything looks good to me now c:
sorry again this took so long, the above comment sat here for 2 weeks until i noticed it wasnt even visible lol

yeah everything looks good to me now c: sorry again this took so long, the above comment sat here for 2 weeks until i noticed it wasnt even visible lol
v[2].t = v[3].t = gpatch->max_t;
flags = PF_Translucent|PF_NoDepthTest;
// whoops
if (blendmode)
flags = HWR_GetBlendModeFlag(blendmode+1)|PF_NoDepthTest;
else
flags = PF_Translucent|PF_NoDepthTest;
if (option & V_WRAPX)
flags |= PF_ForceWrapX;
@@ -294,14 +299,17 @@ void HWR_DrawStretchyFixedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t
flags |= PF_ForceWrapY;
// clip it since it is used for bunny scroll in doom I
if (alphalevel)
{
FSurfaceInfo Surf;
Surf.PolyColor.s.red = Surf.PolyColor.s.green = Surf.PolyColor.s.blue = 0xff;
if (alphalevel == 13) Surf.PolyColor.s.alpha = softwaretranstogl_lo[hudtrans];
else if (alphalevel == 14) Surf.PolyColor.s.alpha = softwaretranstogl[hudtrans];
else if (alphalevel == 15) Surf.PolyColor.s.alpha = softwaretranstogl_hi[hudtrans];
else Surf.PolyColor.s.alpha = softwaretranstogl[10-alphalevel];
flags |= PF_Modulated;
HWD.pfnDrawPolygon(&Surf, v, 4, flags);
}
@@ -455,10 +463,12 @@ void HWR_DrawCroppedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscal
{
FSurfaceInfo Surf;
Surf.PolyColor.s.red = Surf.PolyColor.s.green = Surf.PolyColor.s.blue = 0xff;
if (alphalevel == 13) Surf.PolyColor.s.alpha = softwaretranstogl_lo[cv_translucenthud.value];
else if (alphalevel == 14) Surf.PolyColor.s.alpha = softwaretranstogl[cv_translucenthud.value];
else if (alphalevel == 15) Surf.PolyColor.s.alpha = softwaretranstogl_hi[cv_translucenthud.value];
else Surf.PolyColor.s.alpha = softwaretranstogl[10-alphalevel];
flags |= PF_Modulated;
HWD.pfnDrawPolygon(&Surf, v, 4, flags);
}
+169 -76
View File
@@ -654,7 +654,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_Fog|PF_Additive|PF_Subtractive|PF_ReverseSubtract|PF_Multiplicative|PF_Environment))
{
Surf.PolyColor.s.alpha = (UINT8)alpha;
PolyFlags |= PF_Modulated;
@@ -836,20 +836,67 @@ static void HWR_DrawSegsSplats(FSurfaceInfo * pSurf)
}
#endif
FBITFIELD HWR_TranstableToAlpha(INT32 transtablenum, FSurfaceInfo *pSurf)
FBITFIELD HWR_GetBlendModeFlag(INT32 ast)
{
switch (ast)
{
case AST_TRANSLUCENT:
return PF_Translucent;
case AST_ADD:
return PF_Additive;
case AST_SUBTRACT:
return PF_Subtractive;
case AST_REVERSESUBTRACT:
return PF_ReverseSubtract;
case AST_MODULATE:
return PF_Multiplicative;
default:
return PF_Masked;
}
return 0;
}
UINT8 HWR_GetTranstableAlpha(INT32 transtablenum)
{
switch (transtablenum)
{
case tr_trans10 : pSurf->PolyColor.s.alpha = 0xe6;return PF_Translucent;
case tr_trans20 : pSurf->PolyColor.s.alpha = 0xcc;return PF_Translucent;
case tr_trans30 : pSurf->PolyColor.s.alpha = 0xb3;return PF_Translucent;
case tr_trans40 : pSurf->PolyColor.s.alpha = 0x99;return PF_Translucent;
case tr_trans50 : pSurf->PolyColor.s.alpha = 0x80;return PF_Translucent;
case tr_trans60 : pSurf->PolyColor.s.alpha = 0x66;return PF_Translucent;
case tr_trans70 : pSurf->PolyColor.s.alpha = 0x4c;return PF_Translucent;
case tr_trans80 : pSurf->PolyColor.s.alpha = 0x33;return PF_Translucent;
case tr_trans90 : pSurf->PolyColor.s.alpha = 0x19;return PF_Translucent;
case 0 : return 0xff;
case tr_trans10 : return 0xe6;
case tr_trans20 : return 0xcc;
case tr_trans30 : return 0xb3;
case tr_trans40 : return 0x99;
case tr_trans50 : return 0x80;
case tr_trans60 : return 0x66;
case tr_trans70 : return 0x4c;
case tr_trans80 : return 0x33;
case tr_trans90 : return 0x19;
}
return 0xff;
}
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;
}
pSurf->PolyColor.s.alpha = HWR_GetTranstableAlpha(transtablenum);
return HWR_GetBlendModeFlag(style);
}
FBITFIELD HWR_TranstableToAlpha(INT32 transtablenum, FSurfaceInfo *pSurf)
{
if (!transtablenum)
{
pSurf->PolyColor.s.alpha = 0x00;
return PF_Masked;
}
pSurf->PolyColor.s.alpha = HWR_GetTranstableAlpha(transtablenum);
return PF_Translucent;
}
@@ -1038,8 +1085,8 @@ static void HWR_SplitWall(sector_t *sector, FOutVector *wallVerts, INT32 texnum,
if (cutflag & FF_FOG)
HWR_AddTransparentWall(wallVerts, Surf, texnum, noencore, PF_Fog|PF_NoTexture|polyflags, true, lightnum, colormap);
else if (cutflag & FF_TRANSLUCENT)
HWR_AddTransparentWall(wallVerts, Surf, texnum, noencore, PF_Translucent|polyflags, false, lightnum, colormap);
else if (polyflags & (PF_Translucent|PF_Additive|PF_Subtractive|PF_ReverseSubtract|PF_Multiplicative|PF_Environment))
HWR_AddTransparentWall(wallVerts, Surf, texnum, noencore, polyflags, false, lightnum, colormap);
else
HWR_ProjectWall(wallVerts, Surf, PF_Masked|polyflags, lightnum, colormap);
@@ -1067,8 +1114,8 @@ static void HWR_SplitWall(sector_t *sector, FOutVector *wallVerts, INT32 texnum,
if (cutflag & FF_FOG)
HWR_AddTransparentWall(wallVerts, Surf, texnum, noencore, PF_Fog|PF_NoTexture|polyflags, true, lightnum, colormap);
else if (cutflag & FF_TRANSLUCENT)
HWR_AddTransparentWall(wallVerts, Surf, texnum, noencore, PF_Translucent|polyflags, false, lightnum, colormap);
else if (polyflags & (PF_Translucent|PF_Additive|PF_Subtractive|PF_ReverseSubtract|PF_Multiplicative|PF_Environment))
HWR_AddTransparentWall(wallVerts, Surf, texnum, noencore, polyflags, false, lightnum, colormap);
else
HWR_ProjectWall(wallVerts, Surf, PF_Masked|polyflags, lightnum, colormap);
}
@@ -1161,33 +1208,6 @@ static boolean HWR_BlendMidtextureSurface(FSurfaceInfo *pSurf)
// set alpha for transparent walls
switch (gl_linedef->special)
{
case 900:
blendmode = HWR_TranstableToAlpha(tr_trans10, pSurf);
break;
case 901:
blendmode = HWR_TranstableToAlpha(tr_trans20, pSurf);
break;
case 902:
blendmode = HWR_TranstableToAlpha(tr_trans30, pSurf);
break;
case 903:
blendmode = HWR_TranstableToAlpha(tr_trans40, pSurf);
break;
case 904:
blendmode = HWR_TranstableToAlpha(tr_trans50, pSurf);
break;
case 905:
blendmode = HWR_TranstableToAlpha(tr_trans60, pSurf);
break;
case 906:
blendmode = HWR_TranstableToAlpha(tr_trans70, pSurf);
break;
case 907:
blendmode = HWR_TranstableToAlpha(tr_trans80, pSurf);
break;
case 908:
blendmode = HWR_TranstableToAlpha(tr_trans90, pSurf);
break;
// Translucent
case 102:
case 121:
@@ -1205,10 +1225,23 @@ static boolean HWR_BlendMidtextureSurface(FSurfaceInfo *pSurf)
case 221:
case 253:
case 256:
blendmode = PF_Translucent;
if (gl_linedef->blendmode)
blendmode = HWR_SurfaceBlend(gl_linedef->blendmode, R_GetLinedefTransTable(gl_linedef->alpha), pSurf);
else
blendmode = PF_Translucent;
break;
default:
blendmode = PF_Masked;
if (gl_linedef->blendmode)
{
if (gl_linedef->alpha >= 0 && gl_linedef->alpha < FRACUNIT)
blendmode = HWR_SurfaceBlend(gl_linedef->blendmode, R_GetLinedefTransTable(gl_linedef->alpha), pSurf);
else
blendmode = HWR_GetBlendModeFlag(gl_linedef->blendmode);
}
else if (gl_linedef->alpha >= 0 && gl_linedef->alpha < FRACUNIT)
blendmode = HWR_TranstableToAlpha(R_GetLinedefTransTable(gl_linedef->alpha), pSurf);
else
blendmode = PF_Masked;
break;
}
}
@@ -1699,7 +1732,7 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
blendmode |= PF_Decal;
if (!gl_drawing_stencil && gl_frontsector->numlights)
HWR_SplitWall(gl_frontsector, wallVerts, gl_midtexture, noencore, &Surf, (!(blendmode & PF_Masked)) ? FF_TRANSLUCENT : FF_CUTLEVEL, NULL, PF_Decal);
HWR_SplitWall(gl_frontsector, wallVerts, gl_midtexture, noencore, &Surf, (!(blendmode & PF_Masked)) ? FF_TRANSLUCENT : FF_CUTLEVEL, NULL, blendmode);
else if (!gl_drawing_stencil && !(blendmode & PF_Masked))
HWR_AddTransparentWall(wallVerts, &Surf, gl_midtexture, noencore, blendmode, false, lightnum, colormap);
else
@@ -1754,7 +1787,9 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
wallVerts[1].y = FIXED_TO_FLOAT(worldbottomslope);
if (gl_frontsector->numlights)
{
HWR_SplitWall(gl_frontsector, wallVerts, gl_midtexture, noencore, &Surf, FF_CUTLEVEL, NULL, 0);
}
else // I don't think that solid walls can use translucent linedef types...
{
if (glTex->mipmap.flags & TF_TRANSPARENT)
@@ -1921,10 +1956,10 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
wallVerts[0].s = wallVerts[3].s = cliplow * glTex->scaleX;
wallVerts[2].s = wallVerts[1].s = cliphigh * glTex->scaleX;
}
FBITFIELD blendmode;
if (rover->flags & FF_FOG)
{
FBITFIELD blendmode;
blendmode = PF_Fog|PF_NoTexture;
lightnum = rover->master->frontsector->lightlevel;
@@ -1935,22 +1970,22 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
lightnum = (HWR_ShouldUsePaletteRendering() && colormap) ? lightnum : HWR_CalcWallLight(lightnum, gl_curline);
if (gl_frontsector->numlights)
HWR_SplitWall(gl_frontsector, wallVerts, 0, false, &Surf, rover->flags, rover, 0);
HWR_SplitWall(gl_frontsector, wallVerts, 0, false, &Surf, rover->flags, rover, blendmode);
else
HWR_AddTransparentWall(wallVerts, &Surf, 0, false, blendmode, true, lightnum, colormap);
}
else
{
FBITFIELD blendmode = PF_Masked;
blendmode = PF_Masked;
if (rover->flags & FF_TRANSLUCENT && rover->alpha < 256)
if ((rover->flags & FF_TRANSLUCENT && rover->alpha < 256) || rover->blend)
{
blendmode = PF_Translucent;
blendmode = rover->blend ? HWR_GetBlendModeFlag(rover->blend) : PF_Translucent;
Surf.PolyColor.s.alpha = CLAMP(rover->alpha, 0, 255);
}
if (gl_frontsector->numlights)
HWR_SplitWall(gl_frontsector, wallVerts, texnum, noencore, &Surf, rover->flags, rover, 0);
HWR_SplitWall(gl_frontsector, wallVerts, texnum, noencore, &Surf, rover->flags, rover, blendmode);
else
{
if (blendmode != PF_Masked)
@@ -2036,10 +2071,10 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
wallVerts[2].s = wallVerts[1].s = cliphigh * glTex->scaleX;
}
FBITFIELD blendmode;
if (rover->flags & FF_FOG)
{
FBITFIELD blendmode;
blendmode = PF_Fog|PF_NoTexture;
lightnum = rover->master->frontsector->lightlevel;
@@ -2050,22 +2085,22 @@ void HWR_ProcessSeg(void) // Sort of like GLWall::Process in GZDoom
lightnum = (HWR_ShouldUsePaletteRendering() && colormap) ? lightnum : HWR_CalcWallLight(lightnum, gl_curline);
if (gl_backsector->numlights)
HWR_SplitWall(gl_backsector, wallVerts, 0, false, &Surf, rover->flags, rover, 0);
HWR_SplitWall(gl_backsector, wallVerts, 0, false, &Surf, rover->flags, rover, blendmode);
else
HWR_AddTransparentWall(wallVerts, &Surf, 0, false, blendmode, true, lightnum, colormap);
}
else
{
FBITFIELD blendmode = PF_Masked;
blendmode = PF_Masked;
if (rover->flags & FF_TRANSLUCENT && rover->alpha < 256)
if ((rover->flags & FF_TRANSLUCENT && rover->alpha < 256) || rover->blend)
{
blendmode = PF_Translucent;
blendmode = rover->blend ? HWR_GetBlendModeFlag(rover->blend) : PF_Translucent;
Surf.PolyColor.s.alpha = CLAMP(rover->alpha, 0, 255);
}
if (gl_backsector->numlights)
HWR_SplitWall(gl_backsector, wallVerts, texnum, noencore, &Surf, rover->flags, rover, 0);
HWR_SplitWall(gl_backsector, wallVerts, texnum, noencore, &Surf, rover->flags, rover, blendmode);
else
{
if (blendmode != PF_Masked)
@@ -2774,6 +2809,13 @@ static inline void HWR_PortalSubsector(seg_t *line, subsector_t *sub, INT16 coun
sub->validcount = validcount;
}
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.
@@ -2958,7 +3000,7 @@ 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
{
light = R_GetPlaneLight(gl_frontsector, centerHeight, viewz < bottomCullHeight ? true : false);
@@ -2967,7 +3009,7 @@ static void HWR_Subsector(size_t num)
false,
*rover->bottomheight,
*gl_frontsector->lightlist[light].lightlevel,
CLAMP(rover->alpha, 0 ,255), rover->master->frontsector, (rover->flags & FF_RIPPLE ? PF_Ripple : 0)|PF_Translucent,
CLAMP(rover->alpha, 0 ,255), rover->master->frontsector, HWR_RippleBlend(gl_frontsector, rover, false) | (rover->blend ? HWR_GetBlendModeFlag(rover->blend) : PF_Translucent),
false, gl_frontsector->lightlist[light].extra_colormap);
}
else
@@ -2975,7 +3017,7 @@ static void HWR_Subsector(size_t num)
HWR_GetFlat(levelflats[*rover->bottompic].lumpnum, R_NoEncore(gl_frontsector, false));
light = R_GetPlaneLight(gl_frontsector, centerHeight, viewz < bottomCullHeight ? 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].lumpnum,
HWR_RenderPlane(sub, &extrasubsectors[num], false, *rover->bottomheight, HWR_RippleBlend(gl_frontsector, rover, false)|PF_Occlude, *gl_frontsector->lightlist[light].lightlevel, levelflats[*rover->bottompic].lumpnum,
rover->master->frontsector, 255, gl_frontsector->lightlist[light].extra_colormap);
}
}
@@ -3004,7 +3046,7 @@ 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)
{
light = R_GetPlaneLight(gl_frontsector, centerHeight, viewz < topCullHeight ? true : false);
@@ -3013,7 +3055,7 @@ static void HWR_Subsector(size_t num)
true,
*rover->topheight,
*gl_frontsector->lightlist[light].lightlevel,
CLAMP(rover->alpha, 0 ,255), rover->master->frontsector, (rover->flags & FF_RIPPLE ? PF_Ripple : 0)|PF_Translucent,
CLAMP(rover->alpha, 0 ,255), rover->master->frontsector, HWR_RippleBlend(gl_frontsector, rover, false) | (rover->blend ? HWR_GetBlendModeFlag(rover->blend) : PF_Translucent),
false, gl_frontsector->lightlist[light].extra_colormap);
}
else
@@ -3021,7 +3063,7 @@ static void HWR_Subsector(size_t num)
HWR_GetFlat(levelflats[*rover->toppic].lumpnum, R_NoEncore(gl_frontsector, true));
light = R_GetPlaneLight(gl_frontsector, centerHeight, viewz < topCullHeight ? 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].lumpnum,
HWR_RenderPlane(sub, &extrasubsectors[num], true, *rover->topheight, HWR_RippleBlend(gl_frontsector, rover, false)|PF_Occlude, *gl_frontsector->lightlist[light].lightlevel, levelflats[*rover->toppic].lumpnum,
rover->master->frontsector, 255, gl_frontsector->lightlist[light].extra_colormap);
}
}
@@ -3562,6 +3604,12 @@ static void HWR_SplitSprite(gl_vissprite_t *spr)
// co-ordinates
memcpy(wallVerts, baseWallVerts, sizeof(baseWallVerts));
INT32 blendmode;
if (spr->mobj->frame & FF_BLENDMASK)
blendmode = ((spr->mobj->frame & FF_BLENDMASK) >> FF_BLENDSHIFT) + 1;
else
blendmode = spr->mobj->blendmode;
if (!cv_translucency.value) // translucency disabled
{
Surf.PolyColor.s.alpha = 0xFF;
@@ -3570,10 +3618,13 @@ static void HWR_SplitSprite(gl_vissprite_t *spr)
else if (spr->mobj->flags2 & MF2_SHADOW)
{
Surf.PolyColor.s.alpha = 0x40;
blend = PF_Translucent;
blend = HWR_GetBlendModeFlag(blendmode);
}
else if (spr->mobj->frame & FF_TRANSMASK)
blend = HWR_TranstableToAlpha((spr->mobj->frame & FF_TRANSMASK)>>FF_TRANSSHIFT, &Surf);
{
INT32 trans = (spr->mobj->frame & FF_TRANSMASK)>>FF_TRANSSHIFT;
blend = HWR_SurfaceBlend(blendmode, trans, &Surf);
}
else
{
// BP: i agree that is little better in environement but it don't
@@ -3581,7 +3632,7 @@ static void HWR_SplitSprite(gl_vissprite_t *spr)
// Hurdler: PF_Environement would be cool, but we need to fix
// the issue with the fog before
Surf.PolyColor.s.alpha = 0xFF;
blend = PF_Translucent|PF_Occlude;
blend = HWR_GetBlendModeFlag(blendmode)|PF_Occlude;
}
if (HWR_UseShader())
@@ -3599,8 +3650,10 @@ static void HWR_SplitSprite(gl_vissprite_t *spr)
i = 0;
temp = FLOAT_TO_FIXED(realtop);
if (spr->mobj->frame & FF_FULLBRIGHT)
if (R_ThingIsFullBright(spr->mobj))
lightlevel = 255;
else if (R_ThingIsFullDark(spr->mobj))
lightlevel = 0;
for (i = 1; i < sector->numlights; i++)
{
@@ -3614,6 +3667,9 @@ static void HWR_SplitSprite(gl_vissprite_t *spr)
break;
}
if (R_ThingIsSemiBright(spr->mobj))
lightlevel = 128 + (lightlevel>>1);
for (i = 0; i < sector->numlights; i++)
{
if (endtop < endrealbot && top < realbot)
@@ -3832,11 +3888,22 @@ static void HWR_DrawSprite(gl_vissprite_t *spr)
UINT8 lightlevel = 255;
extracolormap_t *colormap = sector->extra_colormap;
if (!(spr->mobj->frame & FF_FULLBRIGHT))
if (R_ThingIsFullDark(spr->mobj))
lightlevel = 0;
else if (!(R_ThingIsFullBright(spr->mobj)))
lightlevel = min(sector->lightlevel, 255);
if (R_ThingIsSemiBright(spr->mobj))
lightlevel = 128 + (lightlevel>>1);
HWR_Lighting(&Surf, lightlevel, colormap);
INT32 blendmode;
if (spr->mobj->frame & FF_BLENDMASK)
blendmode = ((spr->mobj->frame & FF_BLENDMASK) >> FF_BLENDSHIFT) + 1;
else
blendmode = spr->mobj->blendmode;
if (!cv_translucency.value) // translucency disabled
{
Surf.PolyColor.s.alpha = 0xFF;
@@ -3845,10 +3912,13 @@ static void HWR_DrawSprite(gl_vissprite_t *spr)
else if (spr->mobj->flags2 & MF2_SHADOW)
{
Surf.PolyColor.s.alpha = 0x40;
blend = PF_Translucent;
blend = HWR_GetBlendModeFlag(blendmode);
}
else if (spr->mobj->frame & FF_TRANSMASK)
blend = HWR_TranstableToAlpha((spr->mobj->frame & FF_TRANSMASK)>>FF_TRANSSHIFT, &Surf);
{
INT32 trans = (spr->mobj->frame & FF_TRANSMASK)>>FF_TRANSSHIFT;
blend = HWR_SurfaceBlend(blendmode, trans, &Surf);
}
else
{
// BP: i agree that is little better in environement but it don't
@@ -3856,7 +3926,7 @@ static void HWR_DrawSprite(gl_vissprite_t *spr)
// Hurdler: PF_Environement would be cool, but we need to fix
// the issue with the fog before
Surf.PolyColor.s.alpha = 0xFF;
blend = PF_Translucent|PF_Occlude;
blend = HWR_GetBlendModeFlag(blendmode)|PF_Occlude;
}
if (HWR_UseShader())
@@ -3946,7 +4016,10 @@ static inline void HWR_DrawPrecipitationSprite(gl_vissprite_t *spr)
HWR_Lighting(&Surf, lightlevel, colormap);
if (spr->mobj->frame & FF_TRANSMASK)
blend = HWR_TranstableToAlpha((spr->mobj->frame & FF_TRANSMASK)>>FF_TRANSSHIFT, &Surf);
{
INT32 trans = (spr->mobj->frame & FF_TRANSMASK)>>FF_TRANSSHIFT;
blend = HWR_SurfaceBlend(AST_TRANSLUCENT, trans, &Surf);
}
else
{
// BP: i agree that is little better in environement but it don't
@@ -3954,7 +4027,7 @@ static inline void HWR_DrawPrecipitationSprite(gl_vissprite_t *spr)
// Hurdler: PF_Environement would be cool, but we need to fix
// the issue with the fog before
Surf.PolyColor.s.alpha = 0xFF;
blend = PF_Translucent|PF_Occlude;
blend = HWR_GetBlendModeFlag(AST_TRANSLUCENT)|PF_Occlude;
}
if (HWR_UseShader())
@@ -4473,6 +4546,19 @@ static void HWR_ProjectSprite(mobj_t *thing)
if (interp.spritexscale < 1 || interp.spriteyscale < 1)
return;
INT32 blendmode;
if (thing->frame & FF_BLENDMASK)
blendmode = ((thing->frame & FF_BLENDMASK) >> FF_BLENDSHIFT) + 1;
else
blendmode = thing->blendmode;
// Visibility check by the blend mode.
if (thing->frame & FF_TRANSMASK)
{
if (!R_BlendLevelVisible(blendmode, (thing->frame & FF_TRANSMASK)>>FF_TRANSSHIFT))
return;
}
this_scale = FIXED_TO_FLOAT(interp.scale);
spritexscale = FIXED_TO_FLOAT(interp.spritexscale);
spriteyscale = FIXED_TO_FLOAT(interp.spriteyscale);
@@ -4797,6 +4883,13 @@ static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing)
R_InterpolatePrecipMobjState(thing, FRACUNIT, &interp);
}
// Visibility check by the blend mode.
if (thing->frame & FF_TRANSMASK)
{
if (!R_BlendLevelVisible(thing->blendmode, (thing->frame & FF_TRANSMASK)>>FF_TRANSSHIFT))
return;
}
this_scale = FIXED_TO_FLOAT(interp.scale);
// transform the origin point
@@ -5190,7 +5283,7 @@ static void HWR_RenderFrame(INT32 viewnumber, player_t *player, boolean skybox)
for (x = vid.width>>1; x < vid.width; x += pw)
{
for (y = vid.height>>1; y < vid.height; y += ph)
HWR_DrawStretchyFixedPatch(gpatch, (x)<<FRACBITS, (y)<<FRACBITS, FRACUNIT, FRACUNIT, V_NOSCALESTART, NULL);
HWR_DrawStretchyFixedPatch(gpatch, (x)<<FRACBITS, (y)<<FRACBITS, FRACUNIT, FRACUNIT, V_NOSCALESTART, NULL, 0);
}
}
+4 -1
View File
@@ -84,7 +84,7 @@ extern boolean gl_shadersavailable;
// hw_draw.c
void HWR_DrawPatch(GLPatch_t *gpatch, INT32 x, INT32 y, INT32 option);
void HWR_DrawStretchyFixedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale, fixed_t vscale, INT32 option, const UINT8 *colormap);
void HWR_DrawStretchyFixedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale, fixed_t vscale, INT32 option, const UINT8 *colormap, INT32 bflags);
void HWR_DrawCroppedPatch(GLPatch_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);
void HWR_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color);
void HWR_DrawConsoleFill(INT32 x, INT32 y, INT32 w, INT32 h, UINT32 color, INT32 options); // Lat: separate flags from color since color needs to be an uint to work right.
@@ -119,6 +119,9 @@ boolean HWR_PalRenderFlashpal(void);
// hw_main.c: Lighting and fog
void HWR_Lighting(FSurfaceInfo *Surface, INT32 light_level, extracolormap_t *colormap);
UINT8 HWR_GetTranstableAlpha(INT32 transtablenum);
FBITFIELD HWR_GetBlendModeFlag(INT32 ast);
FBITFIELD HWR_SurfaceBlend(INT32 style, INT32 transtablenum, FSurfaceInfo *pSurf);
FBITFIELD HWR_TranstableToAlpha(INT32 transtablenum, FSurfaceInfo *pSurf);
// Get amount of memory used by gpu textures in bytes
+19 -1
View File
@@ -1178,13 +1178,31 @@ void HWR_DrawMD2(gl_vissprite_t *spr)
// Apparently people don't like jump frames like that, so back it goes
//if (tics > durs)
//durs = tics;
INT32 blendmode;
if (spr->mobj->frame & FF_BLENDMASK)
blendmode = ((spr->mobj->frame & FF_BLENDMASK) >> FF_BLENDSHIFT) + 1;
else
blendmode = spr->mobj->blendmode;
blendmode = min(AST_MODULATE, blendmode);
if (spr->mobj->flags2 & MF2_SHADOW)
{
Surf.PolyColor.s.alpha = 0x40;
Surf.PolyFlags = HWR_GetBlendModeFlag(blendmode);
}
else if (spr->mobj->frame & FF_TRANSMASK)
{
HWR_TranstableToAlpha((spr->mobj->frame & FF_TRANSMASK)>>FF_TRANSSHIFT, &Surf);
Surf.PolyFlags = HWR_SurfaceBlend(blendmode, (spr->mobj->frame & FF_TRANSMASK)>>FF_TRANSSHIFT, &Surf);
}
else
Surf.PolyColor.s.alpha = 0xFF;
{
// this hack is dumb, but the blendmodes refuse to work otherwise
Surf.PolyColor.s.alpha = (blendmode == AST_TRANSLUCENT) ? 0xFF : 0xFE;
Surf.PolyFlags = HWR_GetBlendModeFlag(blendmode);
}
// dont forget to enabled the depth test because we can't do this like
// before: polygons models are not sorted
+105 -58
View File
@@ -490,6 +490,10 @@ static PFNglDeleteBuffers pglDeleteBuffers;
typedef void (APIENTRY *PFNglColorPointer) (GLint, GLenum, GLsizei, const GLvoid*);
static PFNglColorPointer pglColorPointer;
/* 2.0 functions */
typedef void (APIENTRY * PFNglBlendEquation) (GLenum mode);
static PFNglBlendEquation pglBlendEquation;
/* 1.2 Parms */
/* GL_CLAMP_TO_EDGE_EXT */
#ifndef GL_CLAMP_TO_EDGE
@@ -734,6 +738,9 @@ void SetupGLFunc4(void)
pglBufferData = GetGLFunc("glBufferData");
pglDeleteBuffers = GetGLFunc("glDeleteBuffers");
pglColorPointer = GetGLFunc("glColorPointer");
/* 2.0 funcs */
pglBlendEquation = GetGLFunc("glBlendEquation");
pglStencilFuncSeparate = GetGLFunc("glStencilFuncSeparate");
pglStencilOpSeparate = GetGLFunc("glStencilOpSeparate");
@@ -1397,7 +1404,11 @@ EXPORT void HWRAPI(Draw2DLine) (F2DCoord * v1,
pglEnableClientState(GL_TEXTURE_COORD_ARRAY);
pglEnable(GL_TEXTURE_2D);
}
// -----------------+
// SetBlend : Set render mode
// -----------------+
// PF_Masked - we could use an ALPHA_TEST of GL_EQUAL, and alpha ref of 0,
// is it faster when pixels are discarded ?
static void Clamp2D(GLenum pname)
{
pglTexParameteri(GL_TEXTURE_2D, pname, GL_CLAMP); // fallback clamp
@@ -1406,57 +1417,95 @@ static void Clamp2D(GLenum pname)
#endif
}
// -----------------+
// SetBlend : Set render mode
// -----------------+
// PF_Masked - we could use an ALPHA_TEST of GL_EQUAL, and alpha ref of 0,
// is it faster when pixels are discarded ?
static void SetBlendEquation(GLenum mode)
{
if (pglBlendEquation)
pglBlendEquation(mode);
}
static void SetBlendMode(FBITFIELD flags)
{
// Set blending function
switch (flags)
{
case PF_Translucent & PF_Blending:
pglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // alpha = level of transparency
break;
case PF_Masked & PF_Blending:
// Hurdler: does that mean lighting is only made by alpha src?
// it sounds ok, but not for polygonsmooth
pglBlendFunc(GL_SRC_ALPHA, GL_ZERO); // 0 alpha = holes in texture
break;
case PF_Additive & PF_Blending:
case PF_Subtractive & PF_Blending:
case PF_ReverseSubtract & PF_Blending:
pglBlendFunc(GL_SRC_ALPHA, GL_ONE); // src * alpha + dest
break;
case PF_Environment & PF_Blending:
pglBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
break;
case PF_Multiplicative & PF_Blending:
pglBlendFunc(GL_DST_COLOR, GL_ZERO);
break;
case PF_Fog & PF_Fog:
// Sryder: Fog
// multiplies input colour by input alpha, and destination colour by input colour, then adds them
pglBlendFunc(GL_SRC_ALPHA, GL_SRC_COLOR);
break;
default: // must be 0, otherwise it's an error
// No blending
pglBlendFunc(GL_ONE, GL_ZERO); // the same as no blending
break;
}
// Set blending equation
switch (flags)
{
case PF_Subtractive & PF_Blending:
SetBlendEquation(GL_FUNC_SUBTRACT);
break;
case PF_ReverseSubtract & PF_Blending:
// good for shadow
// not really but what else ?
SetBlendEquation(GL_FUNC_REVERSE_SUBTRACT);
break;
default:
SetBlendEquation(GL_FUNC_ADD);
break;
}
// Alpha test
switch (flags)
{
case PF_Masked & PF_Blending:
pglAlphaFunc(GL_GREATER, 0.5f);
break;
case PF_Translucent & PF_Blending:
case PF_Additive & PF_Blending:
case PF_Subtractive & PF_Blending:
case PF_ReverseSubtract & PF_Blending:
case PF_Environment & PF_Blending:
case PF_Multiplicative & PF_Blending:
pglAlphaFunc(GL_NOTEQUAL, 0.0f);
break;
case PF_Fog & PF_Fog:
pglAlphaFunc(GL_ALWAYS, 0.0f); // Don't discard zero alpha fragments
break;
default:
pglAlphaFunc(GL_GREATER, 0.5f);
break;
}
}
EXPORT void HWRAPI(SetBlend) (FBITFIELD PolyFlags)
{
FBITFIELD Xor;
Xor = CurrentPolyFlags^PolyFlags;
if (Xor & (PF_Blending|PF_RemoveYWrap|PF_ForceWrapX|PF_ForceWrapY|PF_Occlude|PF_NoTexture|PF_Modulated|PF_NoDepthTest|PF_Decal|PF_Invisible|PF_NoAlphaTest))
if (Xor & (PF_Blending|PF_RemoveYWrap|PF_ForceWrapX|PF_ForceWrapY|PF_Occlude|PF_NoTexture|PF_Modulated|PF_NoDepthTest|PF_Decal|PF_Invisible))
{
if (Xor&(PF_Blending)) // if blending mode must be changed
{
switch (PolyFlags & PF_Blending) {
case PF_Translucent & PF_Blending:
pglBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // alpha = level of transparency
pglAlphaFunc(GL_NOTEQUAL, 0.0f);
break;
case PF_Masked & PF_Blending:
// Hurdler: does that mean lighting is only made by alpha src?
// it sounds ok, but not for polygonsmooth
pglBlendFunc(GL_SRC_ALPHA, GL_ZERO); // 0 alpha = holes in texture
pglAlphaFunc(GL_GREATER, 0.5f);
break;
case PF_Additive & PF_Blending:
pglBlendFunc(GL_SRC_ALPHA, GL_ONE); // src * alpha + dest
pglAlphaFunc(GL_NOTEQUAL, 0.0f);
break;
case PF_Environment & PF_Blending:
pglBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
pglAlphaFunc(GL_NOTEQUAL, 0.0f);
break;
case PF_Substractive & PF_Blending:
// good for shadow
// not really but what else ?
pglBlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_COLOR);
pglAlphaFunc(GL_NOTEQUAL, 0.0f);
break;
case PF_Fog & PF_Fog:
// Sryder: Fog
// multiplies input colour by input alpha, and destination colour by input colour, then adds them
pglBlendFunc(GL_SRC_ALPHA, GL_SRC_COLOR);
pglAlphaFunc(GL_ALWAYS, 0.0f); // Don't discard zero alpha fragments
break;
default : // must be 0, otherwise it's an error
// No blending
pglBlendFunc(GL_ONE, GL_ZERO); // the same as no blending
pglAlphaFunc(GL_GREATER, 0.5f);
break;
}
}
if (Xor & PF_Blending) // if blending mode must be changed
SetBlendMode(PolyFlags & PF_Blending);
if (Xor & PF_NoAlphaTest)
{
if (PolyFlags & PF_NoAlphaTest)
@@ -1472,7 +1521,8 @@ EXPORT void HWRAPI(SetBlend) (FBITFIELD PolyFlags)
else
pglDisable(GL_POLYGON_OFFSET_FILL);
}
if (Xor&PF_NoDepthTest)
if (Xor & PF_NoDepthTest)
{
if (PolyFlags & PF_NoDepthTest)
pglDepthFunc(GL_ALWAYS); //pglDisable(GL_DEPTH_TEST);
@@ -1480,25 +1530,25 @@ EXPORT void HWRAPI(SetBlend) (FBITFIELD PolyFlags)
pglDepthFunc(GL_LEQUAL); //pglEnable(GL_DEPTH_TEST);
}
if (Xor&PF_RemoveYWrap)
if (Xor & PF_RemoveYWrap)
{
if (PolyFlags & PF_RemoveYWrap)
Clamp2D(GL_TEXTURE_WRAP_T);
}
if (Xor&PF_ForceWrapX)
if (Xor & PF_ForceWrapX)
{
if (PolyFlags & PF_ForceWrapX)
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
}
if (Xor&PF_ForceWrapY)
if (Xor & PF_ForceWrapY)
{
if (PolyFlags & PF_ForceWrapY)
pglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
}
if (Xor&PF_Modulated)
if (Xor & PF_Modulated)
{
#if defined (__unix__) || defined (UNIXCOMMON)
if (oglflags & GLF_NOTEXENV)
@@ -2721,14 +2771,11 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, float duration, float
poly.green = byte2float[Surface->PolyColor.s.green];
poly.blue = byte2float[Surface->PolyColor.s.blue];
poly.alpha = byte2float[Surface->PolyColor.s.alpha];
if (poly.alpha < 1)
SetBlend(PF_Translucent|PF_Modulated);
else
SetBlend(PF_Masked|PF_Modulated|PF_Occlude);
pglColor4ubv((GLubyte*)&Surface->PolyColor.s);
SetBlend((poly.alpha < 1 ? Surface->PolyFlags : (PF_Masked|PF_Occlude))|PF_Modulated);
tint.red = byte2float[Surface->TintColor.s.red];
tint.green = byte2float[Surface->TintColor.s.green];
tint.blue = byte2float[Surface->TintColor.s.blue];
+3 -3
View File
@@ -8851,10 +8851,10 @@ static void K_drawKartSpeedometer(void)
if (K_UseColorHud() && xtra_speedo_clr3) //Colourized hud
{
UINT8 *colormap = R_GetTranslationColormap(TC_DEFAULT, K_GetHudColor(), GTC_CACHE);
V_DrawStretchyFixedPatch((SPDM_X-1)<<FRACBITS, (SPDM_Y + 5)<<FRACBITS, FRACUNIT*0.765, FRACUNIT*0.55, (V_HUDTRANS|splitflags), (skp_smallstickerclr3), colormap);
V_DrawStretchyFixedPatch((SPDM_X-1)<<FRACBITS, (SPDM_Y + 5)<<FRACBITS, FRACUNIT*0.765, FRACUNIT*0.55, (V_HUDTRANS|splitflags), (skp_smallstickerclr3), colormap, 0);
}
else
V_DrawStretchyFixedPatch((SPDM_X-1)<<FRACBITS, (SPDM_Y + 5)<<FRACBITS, FRACUNIT*0.765, FRACUNIT*0.55, (V_HUDTRANS|splitflags), (skp_smallsticker3), NULL);
V_DrawStretchyFixedPatch((SPDM_X-1)<<FRACBITS, (SPDM_Y + 5)<<FRACBITS, FRACUNIT*0.765, FRACUNIT*0.55, (V_HUDTRANS|splitflags), (skp_smallsticker3), NULL, 0);
V_DrawRankNum(SPDM_X + 26, SPDM_Y + 4, V_HUDTRANS|splitflags, convSpeed, 3, NULL);
V_DrawScaledPatch(SPDM_X + 31, SPDM_Y + 4, V_HUDTRANS|splitflags, skp_speedpatches[cv_kartspeedometer.value]);
@@ -9230,7 +9230,7 @@ static void K_drawNameTags(void)
if (!flipped)
V_DrawFixedPatch(namex<<FRACBITS, namey<<FRACBITS, FRACUNIT/2, vflags, nametagline, cm);
V_DrawStretchyFixedPatch(((namex+dup*3)<<FRACBITS), namey<<FRACBITS,
tagwidthsmall<<FRACBITS, FRACUNIT/2, vflags, nametagpic, cm);
tagwidthsmall<<FRACBITS, FRACUNIT/2, vflags, nametagpic, cm, 0);
namex += dup*2;
namey -= dup*4;
+13 -10
View File
@@ -525,7 +525,7 @@ static int libd_getSpritePatch(lua_State *L)
static int libd_draw(lua_State *L)
{
INT32 x, y, flags;
INT32 x, y, flags, blend;
patch_t *patch;
UINT8 *colormap = NULL;
huddrawlist_h list;
@@ -537,6 +537,7 @@ static int libd_draw(lua_State *L)
flags = luaL_optinteger(L, 4, 0);
if (!lua_isnoneornil(L, 5))
colormap = *((UINT8 **)luaL_checkudata(L, 5, META_COLORMAP));
blend = luaL_optinteger(L, 6, 0);
flags &= ~V_PARAMMASK; // Don't let crashes happen.
@@ -545,16 +546,16 @@ static int libd_draw(lua_State *L)
lua_pop(L, 1);
if (LUA_HUD_IsDrawListValid(list))
LUA_HUD_AddDraw(list, x, y, patch, flags, colormap);
LUA_HUD_AddDraw(list, x, y, patch, flags, colormap, blend);
else
V_DrawFixedPatch(x<<FRACBITS, y<<FRACBITS, FRACUNIT, flags, patch, colormap);
V_DrawBlendingFixedPatch(x<<FRACBITS, y<<FRACBITS, FRACUNIT, flags, patch, colormap, blend);
return 0;
}
static int libd_drawScaled(lua_State *L)
{
fixed_t x, y, scale;
INT32 flags;
INT32 flags, blend;
patch_t *patch;
UINT8 *colormap = NULL;
huddrawlist_h list;
@@ -569,6 +570,7 @@ static int libd_drawScaled(lua_State *L)
flags = luaL_optinteger(L, 5, 0);
if (!lua_isnoneornil(L, 6))
colormap = *((UINT8 **)luaL_checkudata(L, 6, META_COLORMAP));
blend = luaL_optinteger(L, 7, 0);
flags &= ~V_PARAMMASK; // Don't let crashes happen.
@@ -577,9 +579,9 @@ static int libd_drawScaled(lua_State *L)
lua_pop(L, 1);
if (LUA_HUD_IsDrawListValid(list))
LUA_HUD_AddDrawScaled(list, x, y, scale, patch, flags, colormap);
LUA_HUD_AddDrawScaled(list, x, y, scale, patch, flags, colormap, blend);
else
V_DrawFixedPatch(x, y, scale, flags, patch, colormap);
V_DrawBlendingFixedPatch(x, y, scale, flags, patch, colormap, blend);
return 0;
}
@@ -723,7 +725,7 @@ static int libd_drawOnMinimap(lua_State *L)
if (LUA_HUD_IsDrawListValid(list))
{
LUA_HUD_AddDrawScaled(list, amxpos, amypos, scale, patch, splitflags, colormap);
LUA_HUD_AddDrawScaled(list, amxpos, amypos, scale, patch, splitflags, colormap, 0);
}
else
{
@@ -736,7 +738,7 @@ static int libd_drawOnMinimap(lua_State *L)
static int libd_drawStretched(lua_State *L)
{
fixed_t x, y, hscale, vscale;
INT32 flags;
INT32 flags, blend;
patch_t *patch;
UINT8 *colormap = NULL;
huddrawlist_h list;
@@ -754,6 +756,7 @@ static int libd_drawStretched(lua_State *L)
flags = luaL_optinteger(L, 6, 0);
if (!lua_isnoneornil(L, 7))
colormap = *((UINT8 **)luaL_checkudata(L, 7, META_COLORMAP));
blend = luaL_optinteger(L, 8, 0);
flags &= ~V_PARAMMASK; // Don't let crashes happen.
@@ -762,9 +765,9 @@ static int libd_drawStretched(lua_State *L)
lua_pop(L, 1);
if (LUA_HUD_IsDrawListValid(list))
LUA_HUD_AddDrawStretched(list, x, y, hscale, vscale, patch, flags, colormap);
LUA_HUD_AddDrawStretched(list, x, y, hscale, vscale, patch, flags, colormap, blend);
else
V_DrawStretchyFixedPatch(x, y, hscale, vscale, flags, patch, colormap);
V_DrawStretchyFixedPatch(x, y, hscale, vscale, flags, patch, colormap, blend);
return 0;
}
+13 -6
View File
@@ -69,6 +69,7 @@ typedef struct drawitem_s {
size_t stroffset; // offset into strbuf to get str
};
const UINT8 *colormap;
INT32 blend;
} drawitem_t;
// The internal structure of a drawlist.
@@ -345,7 +346,8 @@ void LUA_HUD_AddDraw(
INT32 y,
patch_t *patch,
INT32 flags,
UINT8 *colormap
UINT8 *colormap,
INT32 blend
)
{
size_t i = AllocateDrawItem(list);
@@ -357,6 +359,7 @@ void LUA_HUD_AddDraw(
item->patch = patch;
item->flags = flags;
item->colormap = colormap;
item->blend = blend;
}
void LUA_HUD_AddDrawScaled(
@@ -366,7 +369,8 @@ void LUA_HUD_AddDrawScaled(
fixed_t scale,
patch_t *patch,
INT32 flags,
UINT8 *colormap
UINT8 *colormap,
INT32 blend
)
{
size_t i = AllocateDrawItem(list);
@@ -379,6 +383,7 @@ void LUA_HUD_AddDrawScaled(
item->patch = patch;
item->flags = flags;
item->colormap = colormap;
item->blend = blend;
}
void LUA_HUD_AddDrawStretched(
@@ -389,7 +394,8 @@ void LUA_HUD_AddDrawStretched(
fixed_t vscale,
patch_t *patch,
INT32 flags,
UINT8 *colormap
UINT8 *colormap,
INT32 blend
)
{
size_t i = AllocateDrawItem(list);
@@ -403,6 +409,7 @@ void LUA_HUD_AddDrawStretched(
item->patch = patch;
item->flags = flags;
item->colormap = colormap;
item->blend = blend;
}
void LUA_HUD_AddDrawNum(
@@ -634,17 +641,17 @@ void LUA_HUD_DrawList(huddrawlist_h list)
case DI_Draw:
if (!item->patch || item->patch == NULL)
return;
V_DrawFixedPatch(LERPS(x), LERPS(y), FRACUNIT, item->flags, item->patch, item->colormap);
V_DrawBlendingFixedPatch(LERPS(x), LERPS(y), FRACUNIT, item->flags, item->patch, item->colormap, item->blend);
break;
case DI_DrawScaled:
if (!item->patch || item->patch == NULL)
return;
V_DrawFixedPatch(LERPS(x), LERPS(y), LERP(scale), item->flags, item->patch, item->colormap);
V_DrawBlendingFixedPatch(LERPS(x), LERPS(y), LERP(scale), item->flags, item->patch, item->colormap, item->blend);
break;
case DI_DrawStretched:
if (!item->patch || item->patch == NULL)
return;
V_DrawStretchyFixedPatch(LERPS(x), LERPS(y), LERP(hscale), LERP(vscale), item->flags, item->patch, item->colormap);
V_DrawStretchyFixedPatch(LERPS(x), LERPS(y), LERP(hscale), LERP(vscale), item->flags, item->patch, item->colormap, item->blend);
break;
case DI_DrawNum:
V_DrawTallNum(LERPS(x), LERPS(y), item->flags, item->num);
+6 -3
View File
@@ -40,7 +40,8 @@ void LUA_HUD_AddDraw(
INT32 y,
patch_t *patch,
INT32 flags,
UINT8 *colormap
UINT8 *colormap,
INT32 blend
);
void LUA_HUD_AddDrawStretched(
huddrawlist_h list,
@@ -50,7 +51,8 @@ void LUA_HUD_AddDrawStretched(
fixed_t vscale,
patch_t *patch,
INT32 flags,
UINT8 *colormap
UINT8 *colormap,
INT32 blend
);
void LUA_HUD_AddDrawScaled(
huddrawlist_h list,
@@ -59,7 +61,8 @@ void LUA_HUD_AddDrawScaled(
fixed_t scale,
patch_t *patch,
INT32 flags,
UINT8 *colormap
UINT8 *colormap,
INT32 blend
);
void LUA_HUD_AddDrawNum(
huddrawlist_h list,
+13
View File
@@ -94,6 +94,7 @@ enum line_e {
line_sidenum,
line_frontside,
line_backside,
line_alpha,
line_slopetype,
line_frontsector,
line_backsector,
@@ -115,6 +116,7 @@ static const char *const line_opt[] = {
"sidenum",
"frontside",
"backside",
"alpha",
"slopetype",
"frontsector",
"backsector",
@@ -186,6 +188,7 @@ enum ffloor_e {
ffloor_next,
ffloor_prev,
ffloor_alpha,
ffloor_blend,
};
static const char *const ffloor_opt[] = {
@@ -204,6 +207,7 @@ static const char *const ffloor_opt[] = {
"next",
"prev",
"alpha",
"blend",
NULL};
static int ffloor_fields_ref = LUA_NOREF;
@@ -652,6 +656,9 @@ static int line_get(lua_State *L)
return 0;
LUA_PushUserdata(L, &sides[line->sidenum[1]], META_SIDE);
return 1;
case line_alpha:
lua_pushfixed(L, line->alpha);
return 1;
case line_slopetype:
switch(line->slopetype)
{
@@ -1168,6 +1175,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;
}
@@ -1246,6 +1256,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;
}
+14
View File
@@ -52,6 +52,7 @@ int mobj_skin_setter(lua_State *L);
int mobj_localskin_getter(lua_State *L);
int mobj_localskin_setter(lua_State *L);
int mobj_color_setter(lua_State *L);
int mobj_blendmode_setter(lua_State *L);
int mobj_bnext_noset(lua_State *L);
int mobj_bprev_unimplemented(lua_State *L);
int mobj_hnext_setter(lua_State *L);
@@ -114,6 +115,7 @@ static const udata_field_t mobj_fields[] = {
FIELD(mobj_t, skin, mobj_skin_getter, mobj_skin_setter),
FIELD(mobj_t, localskin, mobj_localskin_getter, mobj_localskin_setter),
FIELD(mobj_t, color, udatalib_getter_uint8, mobj_color_setter),
FIELD(mobj_t, blendmode, udatalib_getter_int32, mobj_blendmode_setter),
FIELD(mobj_t, bnext, udatalib_getter_mobj, mobj_bnext_noset),
FIELD(mobj_t, bprev, mobj_bprev_unimplemented, mobj_bprev_unimplemented),
FIELD(mobj_t, hnext, udatalib_getter_mobj, mobj_hnext_setter),
@@ -476,6 +478,18 @@ int mobj_color_setter(lua_State *L)
return 0;
}
int mobj_blendmode_setter(lua_State *L)
{
mobj_t *mo = GETMO();
INT32 blendmode = (INT32)luaL_checkinteger(L, 2);
if (blendmode < 0 || blendmode > AST_OVERLAY)
return luaL_error(L, "mobj.blendmode %d out of range (0 - %d).", blendmode, AST_OVERLAY);
mo->blendmode = blendmode;
return 0;
}
int mobj_hnext_setter(lua_State *L)
{
mobj_t *mo = GETMO();
+9 -2
View File
@@ -32,6 +32,7 @@ consvar_t cv_gif_downscale = {"gif_downscale", "On", CV_SAVE, CV_OnOff, NULL, 0
#ifdef HAVE_ANIGIF
static boolean gif_optimize = false; // So nobody can do something dumb
static boolean gif_downscale = false; // like changing cvars mid output
static RGBA_t *gif_palette = NULL;
static FILE *gif_out = NULL;
static INT32 gif_frames = 0;
@@ -461,13 +462,15 @@ static size_t gifframe_size = 8192;
// converts an RGB frame to a frame with a palette.
//
#ifdef HWRENDER
static colorlookup_t gif_colorlookup;
static void GIF_rgbconvert(UINT8 *linear, UINT8 *scr)
{
UINT8 r, g, b;
size_t src, dest;
int x, y;
InitColorLUT();
InitColorLUT(&gif_colorlookup, gif_palette, true);
for (x = 0; x < vid.width; x += scrbuf_downscaleamt)
{
@@ -479,7 +482,7 @@ static void GIF_rgbconvert(UINT8 *linear, UINT8 *scr)
r = (UINT8)linear[src];
g = (UINT8)linear[src + 1];
b = (UINT8)linear[src + 2];
scr[dest] = colorlookup[r >> SHIFTCOLORBITS][g >> SHIFTCOLORBITS][b >> SHIFTCOLORBITS];
scr[dest] = GetColorLUTDirect(&gif_colorlookup, r, g, b);
}
}
}
@@ -636,6 +639,10 @@ INT32 GIF_open(const char *filename)
gif_optimize = (!!cv_gif_optimize.value);
gif_downscale = (!!cv_gif_downscale.value);
// no master palettes in SRB2Kart land
gif_palette = pLocalPalette;
GIF_headwrite();
gif_frames = 0;
return 1;
+2
View File
@@ -9413,6 +9413,7 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
}
// Sprite rendering
mobj->blendmode = AST_TRANSLUCENT;
mobj->realxscale = mobj->realyscale = mobj->scale;
mobj->spritexscale = mobj->realxscale;
mobj->spriteyscale = mobj->realyscale;
@@ -9836,6 +9837,7 @@ mobj_t *P_SpawnShadowMobj(mobj_t * caster)
mobj->radius = info->radius;
mobj->height = info->height;
mobj->flags = info->flags;
mobj->blendmode = AST_TRANSLUCENT;
mobj->health = info->spawnhealth;
+2
View File
@@ -289,6 +289,7 @@ typedef struct mobj_s
UINT32 frame; // frame number, plus bits see p_pspr.h
UINT16 anim_duration; // for FF_ANIMATE states
INT32 blendmode; // blend mode
fixed_t spritexscale, spriteyscale;
fixed_t spritexoffset, spriteyoffset;
fixed_t old_spritexscale, old_spriteyscale;
@@ -441,6 +442,7 @@ typedef struct precipmobj_s
UINT32 frame; // frame number, plus bits see p_pspr.h
UINT16 anim_duration; // for FF_ANIMATE states
INT32 blendmode; // blend mode
fixed_t spritexscale, spriteyscale;
fixed_t spritexoffset, spriteyoffset;
fixed_t old_spritexscale, old_spriteyscale;
+24 -4
View File
@@ -41,10 +41,18 @@
#define FF_HORIZONTALFLIP 0x400
/// \brief Frame flags: Thin, paper-like sprite (for collision equivalent, see MF_PAPERCOLLISION)
#define FF_PAPERSPRITE 0x800
/// \brief Frame flags: Simple stateless animation
#define FF_ANIMATE 0x4000
/// \brief Frame flags: frame always appears full bright
#define FF_FULLBRIGHT 0x8000
/// \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
/// \brief shift for FF_TRANSMASK
@@ -60,6 +68,18 @@
#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: 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: Simple stateless animation
#define FF_ANIMATE 0x10000000
/** \brief translucency tables
\todo add another asm routine which use the fg and bg indexes in the
+1
View File
@@ -2165,6 +2165,7 @@ static void LoadMobjThinker(actionf_p1 thinker)
mobj->mirrored = 0;
// Sprite Rendering stuff
mobj->blendmode = AST_TRANSLUCENT;
mobj->spritexoffset = 0;
mobj->spriteyoffset = 0;
mobj->spritexscale = FRACUNIT;
+27 -2
View File
@@ -1071,6 +1071,9 @@ static void P_SetupLines(void)
ld->dx = v2->x - v1->x;
ld->dy = v2->y - v1->y;
ld->alpha = FRACUNIT;
ld->blendmode = 0;
if (!ld->dx)
ld->slopetype = ST_VERTICAL;
else if (!ld->dy)
@@ -1178,6 +1181,26 @@ static void P_LoadLineDefs2(void)
}
break;
}
// Set alpha for translucent walls
if (ld->special >= 900 && ld->special < 909)
ld->alpha = ((909 - ld->special) << FRACBITS)/10;
// Set alpha for additive/subtractive/reverse subtractive walls
if (ld->special >= 910 && ld->special <= 939)
ld->alpha = ((10 - ld->special % 10) << FRACBITS)/10;
if (ld->special >= 910 && ld->special <= 919) // additive
ld->blendmode = AST_ADD;
if (ld->special >= 920 && ld->special <= 929) // subtractive
ld->blendmode = AST_SUBTRACT;
if (ld->special >= 930 && ld->special <= 939) // reverse subtractive
ld->blendmode = AST_REVERSESUBTRACT;
if (ld->special == 940) // modulate
ld->blendmode = AST_MODULATE;
}
}
@@ -1456,8 +1479,10 @@ static void P_LoadRawSideDefs2(void *data)
if (msd->toptexture[0] == '#')
{
char *col = msd->toptexture;
sd->toptexture = sd->bottomtexture =
((col[1]-'0')*100 + (col[2]-'0')*10 + col[3]-'0') + 1;
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->midtexture = R_TextureNumForName(msd->midtexture);
}
else
+20 -2
View File
@@ -4807,16 +4807,34 @@ static ffloor_t *P_AddFakeFloor(sector_t *sec, sector_t *sec2, line_t *master, f
else th = th->next;
}
if (flags & FF_TRANSLUCENT)
{
if (sides[master->sidenum[0]].toptexture > 0)
ffloor->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
ffloor->alpha = sides[master->sidenum[0]].toptexture;
if (ffloor->alpha >= 1001) // fourth digit
{
ffloor->blend = (ffloor->alpha/1000)+1; // becomes an AST
ffloor->alpha %= 1000;
}
else
{
ffloor->blend = 0;
}
}
else
{
ffloor->alpha = 0x80;
ffloor->blend = 0;
}
}
else
{
ffloor->alpha = 0xff;
ffloor->blend = 0;
}
ffloor->spawnalpha = ffloor->alpha; // save for netgames
+107
View File
@@ -126,6 +126,113 @@ size_t flatmemory, spritememory, texturememory; // gotta play by 2.2 rules to ge
INT16 color8to16[256]; // remap color index to highcolor rgb value
INT16 *hicolormaps; // test a 32k colormap remaps high -> high
// Blends two pixels together, using the equation
// that matches the specified alpha style.
UINT32 ASTBlendPixel(RGBA_t background, RGBA_t foreground, int style, UINT8 alpha)
{
RGBA_t output;
INT16 fullalpha = (alpha - (0xFF - foreground.s.alpha));
if (style == AST_TRANSLUCENT)
{
if (fullalpha <= 0)
output.rgba = background.rgba;
else
{
// don't go too high
if (fullalpha >= 0xFF)
fullalpha = 0xFF;
alpha = (UINT8)fullalpha;
// if the background pixel is empty,
// match software and don't blend anything
if (!background.s.alpha)
{
// ...unless the foreground pixel ISN'T actually translucent.
if (alpha == 0xFF)
output.rgba = foreground.rgba;
else
output.rgba = 0;
}
else
{
UINT8 beta = (0xFF - alpha);
output.s.red = ((background.s.red * beta) + (foreground.s.red * alpha)) / 0xFF;
output.s.green = ((background.s.green * beta) + (foreground.s.green * alpha)) / 0xFF;
output.s.blue = ((background.s.blue * beta) + (foreground.s.blue * alpha)) / 0xFF;
output.s.alpha = 0xFF;
}
}
return output.rgba;
}
#define clamp(c) max(min(c, 0xFF), 0x00);
else
{
float falpha = ((float)alpha / 256.0f);
float fr = ((float)foreground.s.red * falpha);
float fg = ((float)foreground.s.green * falpha);
float fb = ((float)foreground.s.blue * falpha);
if (style == AST_ADD)
{
output.s.red = clamp((int)(background.s.red + fr));
output.s.green = clamp((int)(background.s.green + fg));
output.s.blue = clamp((int)(background.s.blue + fb));
}
else if (style == AST_SUBTRACT)
{
output.s.red = clamp((int)(background.s.red - fr));
output.s.green = clamp((int)(background.s.green - fg));
output.s.blue = clamp((int)(background.s.blue - fb));
}
else if (style == AST_REVERSESUBTRACT)
{
output.s.red = clamp((int)((-background.s.red) + fr));
output.s.green = clamp((int)((-background.s.green) + fg));
output.s.blue = clamp((int)((-background.s.blue) + fb));
}
else if (style == AST_MODULATE)
{
fr = ((float)foreground.s.red / 256.0f);
fg = ((float)foreground.s.green / 256.0f);
fb = ((float)foreground.s.blue / 256.0f);
output.s.red = clamp((int)(background.s.red * fr));
output.s.green = clamp((int)(background.s.green * fg));
output.s.blue = clamp((int)(background.s.blue * fb));
}
// just copy the pixel
else if (style == AST_COPY)
output.rgba = foreground.rgba;
output.s.alpha = 0xFF;
return output.rgba;
}
#undef clamp
return 0;
}
INT32 ASTTextureBlendingThreshold[2] = {255/11, (10*255/11)};
// Blends a pixel for a texture patch.
UINT32 ASTBlendTexturePixel(RGBA_t background, RGBA_t foreground, int style, UINT8 alpha)
{
// Alpha style set to translucent?
if (style == AST_TRANSLUCENT)
{
// Is the alpha small enough for translucency?
if (alpha <= ASTTextureBlendingThreshold[1])
{
// Is the patch way too translucent? Don't blend then.
if (alpha < ASTTextureBlendingThreshold[0])
return background.rgba;
return ASTBlendPixel(background, foreground, style, alpha);
}
else // just copy the pixel
return foreground.rgba;
}
else
return ASTBlendPixel(background, foreground, style, alpha);
}
// Painfully simple texture id cacheing to make maps load faster. :3
static struct {
char name[9];
+3
View File
@@ -56,6 +56,9 @@ extern INT32 *texturewidthmask;
extern fixed_t *textureheight; // needed for texture pegging
UINT32 ASTBlendPixel(RGBA_t background, RGBA_t foreground, int style, UINT8 alpha);
UINT32 ASTBlendTexturePixel(RGBA_t background, RGBA_t foreground, int style, UINT8 alpha);
extern INT16 color8to16[256]; // remap color index to highcolor
extern INT16 *hicolormaps; // remap high colors to high colors..
+6
View File
@@ -172,6 +172,7 @@ typedef struct ffloor_s
INT32 lastlight;
INT32 alpha;
UINT8 blend; // blendmode
tic_t norender; // for culling
// these are saved for netgames, so do not let Lua touch these!
@@ -402,6 +403,8 @@ typedef struct line_s
// Visual appearance: sidedefs.
UINT16 sidenum[2]; // sidenum[1] will be 0xffff if one-sided
fixed_t alpha; // translucency
UINT8 blendmode; // blendmode
fixed_t bbox[4]; // bounding box for the extent of the linedef
@@ -687,6 +690,9 @@ typedef struct
#pragma pack()
#endif
// Possible alpha types for a patch.
enum patchalphastyle {AST_COPY, AST_TRANSLUCENT, AST_ADD, AST_SUBTRACT, AST_REVERSESUBTRACT, AST_MODULATE, AST_OVERLAY};
typedef enum
{
SRF_SINGLE = 0, // 0-angle for all rotations
+187 -3
View File
@@ -86,6 +86,7 @@ INT32 dc_sourcelength;
#define NUMTRANSTABLES 9 // how many translucency tables are used
UINT8 *transtables; // translucency tables
UINT8 *blendtables[NUMBLENDMAPS];
/** \brief R_DrawTransColumn uses this
*/
@@ -213,11 +214,11 @@ const UINT8 Color_Opposite[MAXSKINCOLORS*2] =
CV_PossibleValue_t Color_cons_t[MAXSKINCOLORS+1];
/** \brief The R_InitTranslationTables
#define TRANSTAB_AMTMUL10 (256.0f / 10.0f)
load in color translation tables
/** \brief Initializes the translucency tables used by the Software renderer.
*/
void R_InitTranslationTables(void)
void R_InitTranslucencyTables(void)
{
// Load here the transparency lookup tables 'TINTTAB'
// NOTE: the TINTTAB resource MUST BE aligned on 64k for the asm
@@ -234,6 +235,189 @@ void R_InitTranslationTables(void)
W_ReadLump(W_GetNumForName("TRANS70"), transtables+0x60000);
Indev450 commented 2025-02-04 18:04:10 +01:00 (Migrated from github.com)
Review

Figured white pixel bug out!
Here, and in all other similar loops, condition should be either <= 0xFF of < 0x100, because otherwise it misses 1 last palette index every time (because 0xFF is 255, so it ignores it even though it is valid index)

Figured white pixel bug out! Here, and in all other similar loops, condition should be either `<= 0xFF` of `< 0x100`, because otherwise it misses 1 last palette index every time (because 0xFF is 255, so it ignores it even though it is valid index)
Chearii commented 2025-02-04 22:33:11 +01:00 (Migrated from github.com)
Review

wow, how didn't I catch that? ^^;
def seemed to do the trick, I'm not encountering the white pixel bug anymore
kart0056

wow, how didn't I catch that? ^^; def seemed to do the trick, I'm not encountering the white pixel bug anymore ![kart0056](https://github.com/user-attachments/assets/6ba36ea0-4046-40c9-b06d-a61c670098a7)
W_ReadLump(W_GetNumForName("TRANS80"), transtables+0x70000);
W_ReadLump(W_GetNumForName("TRANS90"), transtables+0x80000);
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 < 0x100; bg++)
{
for (fg = 0; fg < 0x100; fg++)
{
RGBA_t backrgba = V_GetColor(bg);
RGBA_t frontrgba = V_GetColor(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 < 0x100; bg++)
{
for (fg = 0; fg < 0x100; fg++)
{
RGBA_t backrgba = V_GetColor(bg);
RGBA_t frontrgba = V_GetColor(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 < 0x100; bg++)
{
for (fg = 0; fg < 0x100; fg++)
{
RGBA_t backrgba = V_GetColor(bg);
RGBA_t frontrgba = V_GetColor(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, // 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));
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, pLocalPalette, 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]);
}
#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)
{
return transtables + (ClipTransLevel(alphalevel-1) << FF_TRANSSHIFT);
}
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);
// Lactozilla: Returns the equivalent to AST_TRANSLUCENT
// if no alpha style matches any of the blend tables.
switch (style)
{
case AST_ADD:
return blendtables[blendtab_add] + offs;
case AST_SUBTRACT:
return blendtables[blendtab_subtract] + offs;
case AST_REVERSESUBTRACT:
return blendtables[blendtab_reversesubtract] + offs;
case AST_MODULATE:
return blendtables[blendtab_modulate];
default:
break;
}
// Return a normal translucency table
if (--alphalevel >= 0)
return transtables + (ClipTransLevel(alphalevel) << FF_TRANSSHIFT);
else
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]]);
}
/** \brief Retrieves a translation colormap from the cache.
+21 -2
View File
@@ -40,7 +40,6 @@ extern UINT8 dc_hires;
extern UINT8 *dc_source; // first pixel in a column
// translucency stuff here
extern UINT8 *transtables; // translucency tables, should be (*transtables)[5][256][256]
extern UINT8 *dc_transmap;
// translation stuff here
@@ -117,7 +116,6 @@ extern lumpnum_t viewborderlump[8];
#define TC_BLINK -6 // For item blinking
// Initialize color translation tables, for player rendering etc.
void R_InitTranslationTables(void);
UINT8* R_GetTranslationColormap(INT32 skinnum, skincolors_t color, UINT8 flags);
UINT8* R_GetLocalTranslationColormap(skin_t *skin, skin_t *localskin, skincolors_t color, UINT8 flags, boolean local);
patch_t* R_GetSkinFaceRank(player_t* ply);
@@ -126,6 +124,27 @@ patch_t* R_GetSkinFaceMini(player_t* ply);
void R_FlushTranslationColormapCache(void);
UINT8 R_GetColorByName(const char *name);
extern UINT8 *transtables; // translucency tables, should be (*transtables)[5][256][256]
enum
{
blendtab_add,
blendtab_subtract,
blendtab_reversesubtract,
blendtab_modulate,
NUMBLENDMAPS
};
extern UINT8 *blendtables[NUMBLENDMAPS];
void R_InitTranslucencyTables(void);
void R_GenerateBlendTables(void);
UINT8 *R_GetTranslucencyTable(INT32 alphalevel);
UINT8 *R_GetBlendTable(int style, INT32 alphalevel);
boolean R_BlendLevelVisible(INT32 blendmode, INT32 alphalevel);
// Custom player skin translation
void R_InitViewBuffer(INT32 width, INT32 height);
void R_InitViewBorder(void);
+2 -2
View File
@@ -1036,8 +1036,8 @@ void R_Init(void)
//I_OutputMsg("\nR_InitLightTables");
R_InitLightTables();
//I_OutputMsg("\nR_InitTranslationTables\n");
R_InitTranslationTables();
//I_OutputMsg("\nR_InitTranslucencyTables\n");
R_InitTranslucencyTables();
R_InitDrawNodes();
+13 -24
View File
@@ -796,7 +796,7 @@ void R_DrawSinglePlane(visplane_t *pl)
if (pl->polyobj->translucency >= 10)
return; // Don't even draw it
else if (pl->polyobj->translucency > 0)
ds_transmap = transtables + ((pl->polyobj->translucency-1)<<FF_TRANSSHIFT);
ds_transmap = R_GetTranslucencyTable(pl->polyobj->translucency);
else // Opaque, but allow transparent flat pixels
spanfunc = splatfunc;
@@ -833,28 +833,17 @@ void R_DrawSinglePlane(visplane_t *pl)
spanfunc = R_DrawTranslucentSpan_8;
// Hacked up support for alpha value in software mode Tails 09-24-2002
if (pl->ffloor->alpha < 12)
return; // Don't even draw it
else if (pl->ffloor->alpha < 38)
ds_transmap = transtables + ((tr_trans90-1)<<FF_TRANSSHIFT);
else if (pl->ffloor->alpha < 64)
ds_transmap = transtables + ((tr_trans80-1)<<FF_TRANSSHIFT);
else if (pl->ffloor->alpha < 89)
ds_transmap = transtables + ((tr_trans70-1)<<FF_TRANSSHIFT);
else if (pl->ffloor->alpha < 115)
ds_transmap = transtables + ((tr_trans60-1)<<FF_TRANSSHIFT);
else if (pl->ffloor->alpha < 140)
ds_transmap = transtables + ((tr_trans50-1)<<FF_TRANSSHIFT);
else if (pl->ffloor->alpha < 166)
ds_transmap = transtables + ((tr_trans40-1)<<FF_TRANSSHIFT);
else if (pl->ffloor->alpha < 192)
ds_transmap = transtables + ((tr_trans30-1)<<FF_TRANSSHIFT);
else if (pl->ffloor->alpha < 217)
ds_transmap = transtables + ((tr_trans20-1)<<FF_TRANSSHIFT);
else if (pl->ffloor->alpha < 243)
ds_transmap = transtables + ((tr_trans10-1)<<FF_TRANSSHIFT);
else // Opaque, but allow transparent flat pixels
spanfunc = splatfunc;
// ...unhacked by toaster 04-01-2021, re-hacked a little by sphere 19-11-2021
// and mercilessly shoved into saturn by chearii 02-02-2025
{
INT32 trans = (10*((256+12) - pl->ffloor->alpha))/255;
if (trans >= 10)
return; // Don't even draw it
if (pl->ffloor->blend) // additive, (reverse) subtractive, modulative
ds_transmap = R_GetBlendTable(pl->ffloor->blend, trans);
else if (!(ds_transmap = R_GetTranslucencyTable(trans)) || trans == 0)
spanfunc = splatfunc; // Opaque, but allow transparent flat pixels
}
#ifdef SHITPLANESPARENCY
if (spanfunc == splatfunc || (pl->extra_colormap && pl->extra_colormap->fog))
@@ -1129,7 +1118,7 @@ using the palette colors.
if (spanfunc == R_DrawSpan_8)
{
INT32 i;
ds_transmap = transtables + ((tr_trans50-1)<<FF_TRANSSHIFT);
ds_transmap = R_GetTranslucencyTable(tr_trans50);
spanfunc = R_DrawTranslucentSpan_8;
for (i=0; i<4; i++)
{
+60 -45
View File
@@ -189,7 +189,7 @@ static void R_DrawWallSplats(void)
colfunc = basecolfunc;
else
{
dc_transmap = transtables + ((tr_trans50 - 1)<<FF_TRANSSHIFT);
dc_transmap = R_GetTranslucencyTable(tr_trans50);
colfunc = fuzzcolfunc;
}
@@ -287,6 +287,28 @@ static void R_Render2sidedMultiPatchColumn(column_t *column)
}
}
transnum_t R_GetLinedefTransTable(fixed_t alpha)
{
if (alpha < 9830)
return tr_trans90;
else if (alpha < 16384)
return tr_trans80;
else if (alpha < 22937)
return tr_trans70;
else if (alpha < 29491)
return tr_trans60;
else if (alpha < 36044)
return tr_trans50;
else if (alpha < 42598)
return tr_trans40;
else if (alpha < 49152)
return tr_trans30;
else if (alpha < 55705)
return tr_trans20;
else
return tr_trans10;
}
void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
{
size_t pindex;
@@ -314,28 +336,32 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
// hack translucent linedef types (900-909 for transtables 1-9)
ldef = curline->linedef;
switch (ldef->special)
if (!ldef->alpha)
return;
if (ldef->blendmode)
{
case 900:
case 901:
case 902:
case 903:
case 904:
case 905:
case 906:
case 907:
case 908:
dc_transmap = transtables + ((ldef->special-900)<<FF_TRANSSHIFT);
colfunc = fuzzcolfunc;
break;
case 909:
colfunc = R_DrawFogColumn_8;
windowtop = frontsector->ceilingheight;
windowbottom = frontsector->floorheight;
break;
default:
colfunc = wallcolfunc;
break;
if (ldef->alpha == NUMTRANSMAPS || ldef->blendmode == AST_MODULATE)
dc_transmap = R_GetBlendTable(ldef->blendmode, 0);
else
dc_transmap = R_GetBlendTable(ldef->blendmode, R_GetLinedefTransTable(ldef->alpha));
colfunc = fuzzcolfunc;
}
else if (ldef->alpha > 0 && ldef->alpha < FRACUNIT)
{
dc_transmap = transtables + ((R_GetLinedefTransTable(ldef->alpha) - 1) << FF_TRANSSHIFT);
colfunc = fuzzcolfunc;
}
else if (ldef->special == 909)
{
colfunc = R_DrawFogColumn_8;
windowtop = frontsector->ceilingheight;
windowbottom = frontsector->floorheight;
}
else
{
colfunc = wallcolfunc;
}
if (curline->polyseg && curline->polyseg->translucency > 0)
@@ -343,7 +369,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
if (curline->polyseg->translucency >= NUMTRANSMAPS)
return;
dc_transmap = transtables + ((curline->polyseg->translucency-1)<<FF_TRANSSHIFT);
dc_transmap = R_GetTranslucencyTable(curline->polyseg->translucency);
colfunc = fuzzcolfunc;
}
@@ -711,28 +737,17 @@ 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)
return; // Don't even draw it
else if (pfloor->alpha < 38)
dc_transmap = transtables + ((tr_trans90-1)<<FF_TRANSSHIFT);
else if (pfloor->alpha < 64)
dc_transmap = transtables + ((tr_trans80-1)<<FF_TRANSSHIFT);
else if (pfloor->alpha < 89)
dc_transmap = transtables + ((tr_trans70-1)<<FF_TRANSSHIFT);
else if (pfloor->alpha < 115)
dc_transmap = transtables + ((tr_trans60-1)<<FF_TRANSSHIFT);
else if (pfloor->alpha < 140)
dc_transmap = transtables + ((tr_trans50-1)<<FF_TRANSSHIFT);
else if (pfloor->alpha < 166)
dc_transmap = transtables + ((tr_trans40-1)<<FF_TRANSSHIFT);
else if (pfloor->alpha < 192)
dc_transmap = transtables + ((tr_trans30-1)<<FF_TRANSSHIFT);
else if (pfloor->alpha < 217)
dc_transmap = transtables + ((tr_trans20-1)<<FF_TRANSSHIFT);
else if (pfloor->alpha < 243)
dc_transmap = transtables + ((tr_trans10-1)<<FF_TRANSSHIFT);
else
fuzzy = false; // Opaque
// ...unhacked by toaster 04-01-2021, re-hacked a little by sphere 19-11-2021
// and mercilessly shoved into saturn by chearii 02-02-2025
{
INT32 trans = (10*((256+12) - pfloor->alpha))/255;
if (trans >= 10)
return; // Don't even draw it
if (pfloor->blend) // additive, (reverse) subtractive, modulative
dc_transmap = R_GetBlendTable(pfloor->blend, trans);
else if (!(dc_transmap = R_GetTranslucencyTable(trans)) || trans == 0)
fuzzy = false; // Opaque
}
if (fuzzy)
colfunc = fuzzcolfunc;
+1
View File
@@ -18,6 +18,7 @@
#pragma interface
#endif
transnum_t R_GetLinedefTransTable(fixed_t alpha);
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);
+61 -16
View File
@@ -1032,7 +1032,7 @@ static void R_SplitSprite(vissprite_t *sprite, mobj_t *thing)
newsprite->extra_colormap = sector->lightlist[i].extra_colormap;
if (!((thing->frame & (FF_FULLBRIGHT|FF_TRANSMASK) || thing->flags2 & MF2_SHADOW)
if (!((newsprite->cut & SC_FULLBRIGHT)
&& (!newsprite->extra_colormap || !(newsprite->extra_colormap->fog & 1))))
{
lindex = FixedMul(sprite->xscale, LIGHTRESOLUTIONFIX)>>(LIGHTSCALESHIFT);
@@ -1040,6 +1040,9 @@ static void R_SplitSprite(vissprite_t *sprite, mobj_t *thing)
// Mitigate against negative xscale and arithmetic overflow
lindex = CLAMP(lindex, 0, MAXLIGHTSCALE - 1);
if (newsprite->cut & SC_SEMIBRIGHT)
lindex = (MAXLIGHTSCALE/2) + (lindex >>1);
newsprite->colormap = spritelights[lindex];
}
}
@@ -1138,6 +1141,7 @@ static void R_ProjectSprite(mobj_t *thing)
boolean hflip = (!(thing->frame & FF_HORIZONTALFLIP) != !mirrored);
INT32 lindex;
INT32 trans;
vissprite_t *vis;
@@ -1535,6 +1539,24 @@ static void R_ProjectSprite(mobj_t *thing)
return;
}
INT32 blendmode;
if (oldthing->frame & FF_BLENDMASK)
blendmode = ((oldthing->frame & FF_BLENDMASK) >> FF_BLENDSHIFT) + 1;
else
blendmode = oldthing->blendmode;
// 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(blendmode, trans))
return;
}
else
trans = 0;
//SoM: 3/17/2000: Disregard sprites that are out of view..
if (thing->eflags & MFE_VERTICALFLIP)
{
@@ -1661,6 +1683,18 @@ static void R_ProjectSprite(mobj_t *thing)
vis->scale += FixedMul(scalestep, spriteyscale) * (vis->x1 - x1);
}
if ((blendmode != AST_COPY) && cv_translucency.value)
vis->transmap = R_GetBlendTable(blendmode, trans);
else
vis->transmap = NULL;
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;
//Fab: lumppat is the lump number of the patch to use, this is different
// than lumpid for sprites-in-pwad : the graphics are patched
#ifdef ROTSPRITE
@@ -1670,25 +1704,18 @@ static void R_ProjectSprite(mobj_t *thing)
#endif
vis->patch = W_CachePatchNum(sprframe->lumppat[rot], PU_CACHE);
//
// determine the colormap (lightlevel & special effects)
//
vis->transmap = NULL;
//
// determine the colormap (lightlevel & special effects)
//
// specific translucency
if (!cv_translucency.value)
; // no translucency
else if (thing->flags2 & MF2_SHADOW) // actually only the player should use this (temporary invisibility)
vis->transmap = transtables + ((tr_trans80-1)<<FF_TRANSSHIFT); // because now the translucency is set through FF_TRANSMASK
else if (thing->frame & FF_TRANSMASK)
vis->transmap = transtables + (thing->frame & FF_TRANSMASK) - 0x10000;
if (((thing->frame & FF_FULLBRIGHT) || (thing->flags2 & MF2_SHADOW))
if ((vis->cut & SC_FULLBRIGHT)
&& (!vis->extra_colormap || !(vis->extra_colormap->fog & 1)))
{
// full bright: goggles
vis->colormap = colormaps;
}
else if (vis->cut & SC_FULLDARK)
vis->colormap = scalelight[0][0];
else
{
// diminished light
@@ -1697,6 +1724,9 @@ static void R_ProjectSprite(mobj_t *thing)
// Mitigate against negative xscale and arithmetic overflow
lindex = CLAMP(lindex, 0, MAXLIGHTSCALE - 1);
if (vis->cut & SC_SEMIBRIGHT)
lindex = (MAXLIGHTSCALE/2) + (lindex >> 1);
vis->colormap = spritelights[lindex];
}
@@ -1886,8 +1916,8 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing)
vis->patch = W_CachePatchNum(sprframe->lumppat[0], PU_CACHE);
// specific translucency
if (thing->frame & FF_TRANSMASK)
vis->transmap = (thing->frame & FF_TRANSMASK) - 0x10000 + transtables;
if ((thing->blendmode != AST_COPY) && cv_translucency.value)
vis->transmap = R_GetTranslucencyTable((thing->frame & FF_TRANSMASK) >> FF_TRANSSHIFT);
else
vis->transmap = NULL;
@@ -2788,6 +2818,21 @@ boolean R_ThingWithinDist (mobj_t *thing, fixed_t limit_dist)
return true;
}
boolean R_ThingIsFullBright(mobj_t *thing)
{
return ((thing->frame & FF_BRIGHTMASK) == FF_FULLBRIGHT);
}
boolean R_ThingIsSemiBright(mobj_t *thing)
{
return ((thing->frame & FF_BRIGHTMASK) == FF_SEMIBRIGHT);
}
boolean R_ThingIsFullDark(mobj_t *thing)
{
return ((thing->frame & FF_BRIGHTMASK) == FF_FULLDARK);
}
//
// R_DrawMasked
//
+7
View File
@@ -76,6 +76,10 @@ void R_DrawMasked(void);
boolean R_ThingVisible (mobj_t *thing);
boolean R_ThingWithinDist (mobj_t *thing, fixed_t limit_dist);
boolean R_ThingIsFullBright (mobj_t *thing);
boolean R_ThingIsSemiBright (mobj_t *thing);
boolean R_ThingIsFullDark (mobj_t *thing);
// -----------
// SKINS STUFF
// -----------
@@ -128,6 +132,9 @@ typedef enum
SC_BOTTOM = 2,
SC_VFLIP = 3,
SC_NOTVISIBLE = 4,
SC_FULLBRIGHT = 8,
SC_SEMIBRIGHT = 16,
SC_FULLDARK = 32,
SC_CUTMASK = SC_TOP|SC_BOTTOM|SC_NOTVISIBLE,
SC_FLAGMASK = ~SC_CUTMASK
} spritecut_e;
+47 -25
View File
@@ -635,10 +635,11 @@ static inline UINT8 transmappedpdraw(const UINT8 *dest, const UINT8 *source, fix
}
// Draws a patch scaled to arbitrary size.
void V_DrawStretchyFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, fixed_t vscale, INT32 scrn, patch_t *patch, const UINT8 *colormap)
void V_DrawStretchyFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, fixed_t vscale, INT32 scrn, patch_t *patch, const UINT8 *colormap, INT32 bflags)
{
UINT8 (*patchdrawfunc)(const UINT8*, const UINT8*, fixed_t);
UINT32 alphalevel = 0;
UINT32 alphalevel = ((scrn & V_ALPHAMASK) >> V_ALPHASHIFT);
UINT32 blendmode = ((bflags & V_BLENDMASK) >> V_BLENDSHIFT);
fixed_t col, ofs, colfrac, rowfrac, fdup, vdup;
INT32 dupx, dupy;
@@ -655,7 +656,7 @@ void V_DrawStretchyFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, fixed_t vsca
//if (rendermode != render_soft && !con_startup) // Why?
if (rendermode == render_opengl)
{
HWR_DrawStretchyFixedPatch((GLPatch_t *)patch, x, y, pscale, vscale, scrn, colormap);
HWR_DrawStretchyFixedPatch((GLPatch_t *)patch, x, y, pscale, vscale, scrn, colormap, bflags);
return;
}
#endif
@@ -663,7 +664,7 @@ void V_DrawStretchyFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, fixed_t vsca
patchdrawfunc = standardpdraw;
v_translevel = NULL;
if ((alphalevel = ((scrn & V_ALPHAMASK) >> V_ALPHASHIFT)))
if (alphalevel || blendmode)
{
if (alphalevel == 13)
alphalevel = hudminusalpha[hudtrans];
@@ -675,9 +676,9 @@ void V_DrawStretchyFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, fixed_t vsca
if (alphalevel >= 10)
return; // invis
if (alphalevel)
if (alphalevel || blendmode)
{
v_translevel = transtables + ((alphalevel-1)<<FF_TRANSSHIFT);
v_translevel = R_GetBlendTable(blendmode+1, alphalevel);
patchdrawfunc = translucentpdraw;
}
}
@@ -3386,30 +3387,51 @@ void V_DoPostProcessor(INT32 view, player_t *player, INT32 param)
#endif
}
// Taken from my videos-in-SRB2 project
// Generates a color look-up table
// which has up to 64 colors at each channel
// (see the defines in v_video.h)
UINT8 colorlookup[CLUTSIZE][CLUTSIZE][CLUTSIZE];
void InitColorLUT(void)
// Generates a RGB565 color look-up table
void InitColorLUT(colorlookup_t *lut, RGBA_t *palette, boolean makecolors)
{
UINT8 r, g, b;
static boolean clutinit = false;
static RGBA_t *lastpalette = NULL;
if ((!clutinit) || (lastpalette != pLocalPalette))
size_t palsize = (sizeof(RGBA_t) * 256);
if (!lut->init || memcmp(lut->palette, palette, palsize))
{
for (r = 0; r < CLUTSIZE; r++)
for (g = 0; g < CLUTSIZE; g++)
for (b = 0; b < CLUTSIZE; b++)
colorlookup[r][g][b] = NearestColor(r << SHIFTCOLORBITS, g << SHIFTCOLORBITS, b << SHIFTCOLORBITS);
clutinit = true;
lastpalette = pLocalPalette;
INT32 i;
lut->init = true;
memcpy(lut->palette, palette, palsize);
for (i = 0; i < 0xFFFF; i++)
lut->table[i] = 0xFFFF;
if (makecolors)
{
UINT8 r, g, b;
for (r = 0; r < 0xFF; r++)
for (g = 0; g < 0xFF; g++)
for (b = 0; b < 0xFF; b++)
{
i = CLUTINDEX(r, g, b);
if (lut->table[i] == 0xFFFF)
lut->table[i] = NearestPaletteColor(r, g, b, palette);
}
}
}
}
UINT8 GetColorLUT(colorlookup_t *lut, UINT8 r, UINT8 g, UINT8 b)
{
INT32 i = CLUTINDEX(r, g, b);
if (lut->table[i] == 0xFFFF)
lut->table[i] = NearestPaletteColor(r, g, b, lut->palette);
return lut->table[i];
}
UINT8 GetColorLUTDirect(colorlookup_t *lut, UINT8 r, UINT8 g, UINT8 b)
{
INT32 i = CLUTINDEX(r, g, b);
return lut->table[i];
}
// V_Init
// old software stuff, buffers are allocated at video mode setup
// here we set the screens[x] pointers accordingly
+25 -11
View File
@@ -37,17 +37,19 @@ cv_rsaturation, cv_ysaturation, cv_gsaturation, cv_csaturation, cv_bsaturation,
// Allocates buffer screens, call before R_Init.
void V_Init(void);
// Taken from my videos-in-SRB2 project
// Generates a color look-up table
// which has up to 64 colors at each channel
// Color look-up table
#define CLUTINDEX(r, g, b) (((r) >> 3) << 11) | (((g) >> 2) << 5) | ((b) >> 3)
#define COLORBITS 6
#define SHIFTCOLORBITS (8-COLORBITS)
#define CLUTSIZE (1<<COLORBITS)
typedef struct
{
boolean init;
RGBA_t palette[256];
UINT16 table[0xFFFF];
} colorlookup_t;
extern UINT8 colorlookup[CLUTSIZE][CLUTSIZE][CLUTSIZE];
void InitColorLUT(void);
void InitColorLUT(colorlookup_t *lut, RGBA_t *palette, boolean makecolors);
UINT8 GetColorLUT(colorlookup_t *lut, UINT8 r, UINT8 g, UINT8 b);
UINT8 GetColorLUTDirect(colorlookup_t *lut, UINT8 r, UINT8 g, UINT8 b);
// Loads the correct palette into memory
void V_ReloadPalette(void);
@@ -142,6 +144,17 @@ void V_CubeApply(UINT8 *red, UINT8 *green, UINT8 *blue);
#define V_SPLITSCREEN 0x40000000
#define V_HORZSCREEN 0x80000000
// blendmodes are separated into their own category so as to allow older visflags to coexist
// 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 B_ADD ((AST_ADD-1)<<V_BLENDSHIFT) // Additive
#define B_SUBTRACT ((AST_SUBTRACT-1)<<V_BLENDSHIFT) // Subtractive
#define B_REVERSESUBTRACT ((AST_REVERSESUBTRACT-1)<<V_BLENDSHIFT) // Reverse subtractive
#define B_MODULATE ((AST_MODULATE-1)<<V_BLENDSHIFT) // Modulate
// defines for old functions
#define V_DrawPatch(x,y,s,p) V_DrawFixedPatch((x)<<FRACBITS, (y)<<FRACBITS, FRACUNIT, s|V_NOSCALESTART|V_NOSCALEPATCH, p, NULL)
#define V_DrawTranslucentMappedPatch(x,y,s,p,c) V_DrawFixedPatch((x)<<FRACBITS, (y)<<FRACBITS, FRACUNIT, s, p, c)
@@ -157,8 +170,9 @@ void V_CubeApply(UINT8 *red, UINT8 *green, UINT8 *blue);
#define V_DrawSmallTranslucentPatch(x,y,s,p) V_DrawFixedPatch((x)<<FRACBITS, (y)<<FRACBITS, FRACUNIT/2, s, p, NULL)
#define V_DrawTinyTranslucentPatch(x,y,s,p) V_DrawFixedPatch((x)<<FRACBITS, (y)<<FRACBITS, FRACUNIT/4, s, p, NULL)
#define V_DrawSciencePatch(x,y,s,p,sc) V_DrawFixedPatch(x,y,sc,s,p,NULL)
#define V_DrawFixedPatch(x,y,sc,s,p,c) V_DrawStretchyFixedPatch(x,y,sc,sc,s,p,c)
void V_DrawStretchyFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, fixed_t vscale, INT32 scrn, patch_t *patch, const UINT8 *colormap);
#define V_DrawFixedPatch(x,y,sc,s,p,c) V_DrawStretchyFixedPatch(x,y,sc,sc,s,p,c,0)
#define V_DrawBlendingFixedPatch(x,y,sc,s,p,c,b) V_DrawStretchyFixedPatch(x,y,sc,sc,s,p,c,b)
void V_DrawStretchyFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, fixed_t vscale, INT32 scrn, patch_t *patch, const UINT8 *colormap, INT32 bflags);
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);
void V_DrawContinueIcon(INT32 x, INT32 y, INT32 flags, INT32 skinnum, UINT8 skincolor);