Compare commits
33
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7d1eb398cf | ||
|
|
97df54a760 | ||
|
|
2edada8ce3 | ||
|
|
17e85df813 | ||
|
|
a3b5c4dff8 | ||
|
|
2b13af2367 | ||
|
|
ff895f3251 | ||
|
|
130c1aba67 | ||
|
|
a07c2f4c32 | ||
|
|
96b7a4efe6 | ||
|
|
124b2ff431 | ||
|
|
c1ec72e606 | ||
|
|
ef1faf9f68 | ||
|
|
02595b9ea6 | ||
|
|
c1514635b0 | ||
|
|
e5e7205c95 | ||
|
|
f8d1bf0811 | ||
|
|
d2ca916043 | ||
|
|
09e901b31b | ||
|
|
8bd943eb71 | ||
|
|
d8fe3920b1 | ||
|
|
a920556feb | ||
|
|
351cb4a1ac | ||
|
|
9d1bef9ab9 | ||
|
|
feeb2d0f1a | ||
|
|
13a5909c3f | ||
|
|
40be4d25a5 | ||
|
|
d84f887be8 | ||
|
|
bc29d77aff | ||
|
|
8db2e646db | ||
|
|
3b2e207b6b | ||
|
|
f061d66a16 | ||
|
|
8c295e8d5f |
No files matched your search
@@ -690,6 +690,20 @@ static const struct {
|
||||
{NULL, 0}
|
||||
};
|
||||
|
||||
static mapheader_lighting_t *usemaplighting(INT32 mapnum, const char *word)
|
||||
{
|
||||
if (fastncmp(word, "ENCORE", 6))
|
||||
{
|
||||
mapheaderinfo[mapnum]->use_encore_lighting = true;
|
||||
|
||||
return &mapheaderinfo[mapnum]->lighting_encore;
|
||||
}
|
||||
else
|
||||
{
|
||||
return &mapheaderinfo[mapnum]->lighting;
|
||||
}
|
||||
}
|
||||
|
||||
static void readlevelheader(MYFILE *f, INT32 num, INT32 wadnum)
|
||||
{
|
||||
char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL);
|
||||
@@ -983,6 +997,35 @@ static void readlevelheader(MYFILE *f, INT32 num, INT32 wadnum)
|
||||
}*/
|
||||
else if (fastcmp(word, "MOBJSCALE"))
|
||||
mapheaderinfo[num-1]->mobj_scale = get_number(word2);
|
||||
else if (fastcmp(word, "LIGHTCONTRAST") || fastcmp(word, "ENCORELIGHTCONTRAST"))
|
||||
{
|
||||
mapheader_lighting_t *lighting = usemaplighting(num-1, word);
|
||||
lighting->light_contrast = (UINT8)i;
|
||||
lighting->use_custom_light = true;
|
||||
}
|
||||
else if (fastcmp(word, "SPRITEBACKLIGHT") || fastcmp(word, "ENCORESPRITEBACKLIGHT"))
|
||||
{
|
||||
mapheader_lighting_t *lighting = usemaplighting(num-1, word);
|
||||
lighting->sprite_backlight = (SINT8)i;
|
||||
lighting->use_custom_light = true;
|
||||
}
|
||||
else if (fastcmp(word, "LIGHTANGLE") || fastcmp(word, "ENCORELIGHTANGLE"))
|
||||
{
|
||||
mapheader_lighting_t *lighting = usemaplighting(num-1, word);
|
||||
|
||||
if (fastcmp(word2, "EVEN"))
|
||||
{
|
||||
lighting->use_light_angle = false;
|
||||
lighting->light_angle = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
lighting->use_light_angle = true;
|
||||
lighting->light_angle = FixedAngle(FloatToFixed(atof(word2)));
|
||||
}
|
||||
|
||||
lighting->use_custom_light = true;
|
||||
}
|
||||
|
||||
// Individual triggers for level flags, for ease of use (and 2.0 compatibility)
|
||||
else if (fastcmp(word, "SCRIPTISFILE"))
|
||||
|
||||
@@ -222,6 +222,15 @@ typedef struct
|
||||
char value[256]; // 255 usable characters. If this seriously isn't enough then wtf.
|
||||
} customoption_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
boolean use_custom_light;
|
||||
UINT8 light_contrast; ///< Range of wall lighting. 0 is no lighting.
|
||||
SINT8 sprite_backlight; ///< Subtract from wall lighting for sprites only.
|
||||
boolean use_light_angle; ///< When false, wall lighting is evenly distributed. When true, wall lighting is directional.
|
||||
angle_t light_angle; ///< Angle of directional wall lighting.
|
||||
} mapheader_lighting_t;
|
||||
|
||||
/** Map header information.
|
||||
*/
|
||||
typedef struct
|
||||
@@ -269,6 +278,10 @@ typedef struct
|
||||
//boolean automap; ///< Displays a level's white map outline in modified games
|
||||
fixed_t mobj_scale; ///< Replacement for TOL_ERZ3
|
||||
|
||||
mapheader_lighting_t lighting; ///< Wall and sprite lighting
|
||||
mapheader_lighting_t lighting_encore; ///< Alternative lighting for Encore mode
|
||||
boolean use_encore_lighting; ///< Whether to use separate Encore lighting
|
||||
|
||||
// Music stuff.
|
||||
UINT32 musinterfadeout; ///< Fade out level music on intermission screen in milliseconds
|
||||
char musintername[7]; ///< Intermission screen music.
|
||||
@@ -464,6 +477,14 @@ extern tic_t racecountdown, exitcountdown;
|
||||
extern fixed_t gravity;
|
||||
extern fixed_t mapobjectscale;
|
||||
|
||||
extern struct maplighting
|
||||
{
|
||||
UINT8 contrast;
|
||||
SINT8 backlight;
|
||||
boolean directional;
|
||||
angle_t angle;
|
||||
} maplighting;
|
||||
|
||||
//for CTF balancing
|
||||
extern INT16 autobalance;
|
||||
extern INT16 teamscramble;
|
||||
|
||||
@@ -240,6 +240,8 @@ tic_t racecountdown, exitcountdown; // for racing
|
||||
fixed_t gravity;
|
||||
fixed_t mapobjectscale;
|
||||
|
||||
struct maplighting maplighting;
|
||||
|
||||
INT16 autobalance; //for CTF team balance
|
||||
INT16 teamscramble; //for CTF team scramble
|
||||
INT16 scrambleplayers[MAXPLAYERS]; //for CTF team scramble
|
||||
|
||||
@@ -172,6 +172,10 @@ static int comparePolygons(const void *p1, const void *p2)
|
||||
diff = poly1->surf.LightInfo.fade_start - poly2->surf.LightInfo.fade_start;
|
||||
if (diff != 0) return diff;
|
||||
diff = poly1->surf.LightInfo.fade_end - poly2->surf.LightInfo.fade_end;
|
||||
if (diff != 0) return diff;
|
||||
|
||||
diff = poly1->surf.LightInfo.directional - poly2->surf.LightInfo.directional;
|
||||
|
||||
return diff;
|
||||
}
|
||||
|
||||
@@ -229,6 +233,7 @@ void HWR_RenderBatches(void)
|
||||
nextSurfaceInfo.LightInfo.fade_end = 0;
|
||||
nextSurfaceInfo.LightInfo.fade_start = 0;
|
||||
nextSurfaceInfo.LightInfo.light_level = 0;
|
||||
nextSurfaceInfo.LightInfo.directional = false;
|
||||
|
||||
currently_batching = false;// no longer collecting batches
|
||||
if (!polygonArraySize)
|
||||
@@ -380,7 +385,8 @@ void HWR_RenderBatches(void)
|
||||
currentSurfaceInfo.FadeColor.rgba != nextSurfaceInfo.FadeColor.rgba ||
|
||||
currentSurfaceInfo.LightInfo.light_level != nextSurfaceInfo.LightInfo.light_level ||
|
||||
currentSurfaceInfo.LightInfo.fade_start != nextSurfaceInfo.LightInfo.fade_start ||
|
||||
currentSurfaceInfo.LightInfo.fade_end != nextSurfaceInfo.LightInfo.fade_end)
|
||||
currentSurfaceInfo.LightInfo.fade_end != nextSurfaceInfo.LightInfo.fade_end ||
|
||||
currentSurfaceInfo.LightInfo.directional != nextSurfaceInfo.LightInfo.directional)
|
||||
{
|
||||
changeState = true;
|
||||
changeSurfaceInfo = true;
|
||||
|
||||
@@ -289,6 +289,7 @@ struct FLightInfo
|
||||
FUINT light_level;
|
||||
FUINT fade_start;
|
||||
FUINT fade_end;
|
||||
boolean directional;
|
||||
};
|
||||
typedef struct FLightInfo FLightInfo;
|
||||
|
||||
@@ -327,6 +328,11 @@ typedef enum hwdsetspecialstate hwdspecialstate_t;
|
||||
enum hwdshaderinfo
|
||||
{
|
||||
HWD_SHADERINFO_LEVELTIME = 1,
|
||||
HWD_SHADERINFO_LIGHT_X,
|
||||
HWD_SHADERINFO_LIGHT_Y,
|
||||
HWD_SHADERINFO_LIGHT_Z,
|
||||
HWD_SHADERINFO_LIGHT_CONTRAST,
|
||||
HWD_SHADERINFO_LIGHT_BACKLIGHT,
|
||||
};
|
||||
|
||||
typedef enum hwdshaderinfo hwdshaderinfo_t;
|
||||
|
||||
@@ -43,6 +43,8 @@ typedef struct gl_vissprite_s
|
||||
INT32 dispoffset; // copy of info->dispoffset, affects ordering but not drawing
|
||||
} gl_vissprite_t;
|
||||
|
||||
void HWR_ObjectLightLevelPost(gl_vissprite_t *spr, const sector_t *sector, INT32 *lightlevel, boolean model);
|
||||
|
||||
// --------
|
||||
// hw_bsp.c
|
||||
// --------
|
||||
|
||||
+109
-54
@@ -322,7 +322,61 @@ static void HWR_SetShaderState(void)
|
||||
GL_SetSpecialState(HWD_SET_SHADERS, HWR_UseShader() ? 1 : 0);
|
||||
}
|
||||
|
||||
void HWR_Lighting(FSurfaceInfo *Surface, INT32 light_level, extracolormap_t *colormap)
|
||||
static boolean HWR_OverrideObjectLightLevel(mobj_t *thing, INT32 *lightlevel)
|
||||
{
|
||||
if (R_ThingIsFullBright(thing))
|
||||
*lightlevel = 255;
|
||||
else if (R_ThingIsFullDark(thing))
|
||||
*lightlevel = 0;
|
||||
else if (thing->frame & FF_ABSOLUTELIGHTLEVEL)
|
||||
*lightlevel = R_ThingLightLevel(thing);
|
||||
else
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void HWR_ObjectLightLevelPost(gl_vissprite_t *spr, const sector_t *sector, INT32 *lightlevel, boolean model)
|
||||
{
|
||||
const boolean semibright = R_ThingIsSemiBright(spr->mobj);
|
||||
|
||||
*lightlevel += R_ThingLightLevel(spr->mobj);
|
||||
|
||||
if (maplighting.directional == true && P_SectorUsesDirectionalLighting(sector))
|
||||
{
|
||||
if (model == false) // this is implemented by shader
|
||||
{
|
||||
fixed_t extralight = R_GetSpriteDirectionalLighting(R_PointToAngle(spr->mobj->x, spr->mobj->y));
|
||||
|
||||
// Less change in contrast in dark sectors
|
||||
extralight = FixedMul(extralight, min(max(0, *lightlevel), 255) * FRACUNIT / 255);
|
||||
|
||||
// simple OGL approximation
|
||||
fixed_t tr = R_PointToDist(spr->mobj->x, spr->mobj->y);
|
||||
fixed_t xscale = FixedDiv((vid.width / 2) << FRACBITS, tr);
|
||||
|
||||
// Less change in contrast at further distances, to counteract DOOM diminished light
|
||||
fixed_t n = FixedDiv(FixedMul(xscale, LIGHTRESOLUTIONFIX), ((MAXLIGHTSCALE-1) << LIGHTSCALESHIFT));
|
||||
extralight = FixedMul(extralight, min(n, FRACUNIT));
|
||||
|
||||
// Contrast is stronger for normal sprites, stronger than wall lighting is at the same distance
|
||||
*lightlevel += FixedFloor((extralight * 2) + (FRACUNIT / 2)) / FRACUNIT;
|
||||
}
|
||||
|
||||
// Semibright objects will be made slightly brighter to compensate contrast
|
||||
if (semibright)
|
||||
{
|
||||
*lightlevel += 16;
|
||||
}
|
||||
}
|
||||
|
||||
if (semibright)
|
||||
{
|
||||
*lightlevel = 128 + (*lightlevel >> 1);
|
||||
}
|
||||
}
|
||||
|
||||
void HWR_Lighting(FSurfaceInfo *Surface, INT32 light_level, extracolormap_t *colormap, const boolean directional)
|
||||
{
|
||||
RGBA_t poly_color, tint_color, fade_color;
|
||||
|
||||
@@ -382,6 +436,7 @@ void HWR_Lighting(FSurfaceInfo *Surface, INT32 light_level, extracolormap_t *col
|
||||
Surface->LightInfo.light_level = light_level;
|
||||
Surface->LightInfo.fade_start = (colormap != NULL) ? colormap->fadestart : 0;
|
||||
Surface->LightInfo.fade_end = (colormap != NULL) ? colormap->fadeend : 31;
|
||||
Surface->LightInfo.directional = (maplighting.directional == true && directional == true);
|
||||
Surface->LightTableId = HWR_ShouldUsePaletteRendering() ? HWR_GetLightTableID(colormap) : 0;
|
||||
}
|
||||
|
||||
@@ -414,43 +469,33 @@ static FUINT HWR_CalcWallLight(FUINT lightnum, seg_t *seg)
|
||||
{
|
||||
INT16 finallight = lightnum;
|
||||
|
||||
if (seg != NULL && cv_glfakecontrast.value != 0)
|
||||
if (cv_glfakecontrast.value == 0)
|
||||
return (FUINT)finallight;
|
||||
|
||||
if (seg != NULL && P_ApplyLightOffsetFine(lightnum, seg->frontsector))
|
||||
{
|
||||
fixed_t extralight = 0;
|
||||
INT16 offset = (cv_glfakecontrast.value == 2) ? seg->hwLightOffset : ((INT16)seg->lightOffset * 8);
|
||||
|
||||
if (cv_glfakecontrast.value == 2) // Smooth setting
|
||||
extralight += seg->hwLightOffset;
|
||||
else
|
||||
extralight += seg->lightOffset * 8;
|
||||
|
||||
if (extralight != 0)
|
||||
{
|
||||
finallight += extralight;
|
||||
finallight = CLAMP(finallight, 0 , 255);
|
||||
}
|
||||
finallight += offset;
|
||||
finallight = CLAMP(finallight, 0 , 255);
|
||||
}
|
||||
|
||||
return (FUINT)finallight;
|
||||
}
|
||||
|
||||
static FUINT HWR_CalcSlopeLight(FUINT lightnum, pslope_t *slope)
|
||||
static FUINT HWR_CalcSlopeLight(FUINT lightnum, pslope_t *slope, const sector_t *sector, const boolean fof)
|
||||
{
|
||||
INT16 finallight = lightnum;
|
||||
|
||||
if (slope != NULL && cv_glfakecontrast.value != 0 && cv_glslopecontrast.value != 0)
|
||||
if (cv_glfakecontrast.value == 0 || cv_glslopecontrast.value == 0)
|
||||
return (FUINT)finallight;
|
||||
|
||||
if (slope != NULL && sector != NULL && P_ApplyLightOffsetFine(lightnum, sector))
|
||||
{
|
||||
fixed_t extralight = 0;
|
||||
INT16 offset = (cv_glfakecontrast.value == 2) ? slope->hwLightOffset : ((INT16)slope->lightOffset * 8);
|
||||
|
||||
if (cv_glfakecontrast.value == 2) // Smooth setting
|
||||
extralight += slope->hwLightOffset;
|
||||
else
|
||||
extralight += slope->lightOffset * 8;
|
||||
|
||||
if (extralight != 0)
|
||||
{
|
||||
finallight += extralight;
|
||||
finallight = CLAMP(finallight, 0 , 255);
|
||||
}
|
||||
finallight += (fof ? -offset : offset);
|
||||
finallight = CLAMP(finallight, 0 , 255);
|
||||
}
|
||||
|
||||
return (FUINT)finallight;
|
||||
@@ -636,9 +681,9 @@ static void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, bool
|
||||
SETUP3DVERT(v3d, pv->x, pv->y);
|
||||
|
||||
if (slope)
|
||||
lightlevel = HWR_CalcSlopeLight(lightlevel, slope);
|
||||
lightlevel = HWR_CalcSlopeLight(lightlevel, slope, gl_frontsector, (FOFsector != NULL));
|
||||
|
||||
HWR_Lighting(&Surf, lightlevel, planecolormap);
|
||||
HWR_Lighting(&Surf, lightlevel, planecolormap, P_SectorUsesDirectionalLighting(gl_frontsector));
|
||||
|
||||
if (PolyFlags & (PF_Translucent|PF_Fog|PF_Additive|PF_Subtractive|PF_ReverseSubtract|PF_Multiplicative|PF_Environment))
|
||||
{
|
||||
@@ -895,7 +940,7 @@ static void HWR_ProjectWall(FOutVector *wallVerts, FSurfaceInfo *pSurf, FBITFIEL
|
||||
{
|
||||
INT32 shader = SHADER_NONE;
|
||||
|
||||
HWR_Lighting(pSurf, lightlevel, wallcolormap);
|
||||
HWR_Lighting(pSurf, lightlevel, wallcolormap, P_SectorUsesDirectionalLighting(gl_frontsector));
|
||||
|
||||
if (HWR_UseShader())
|
||||
{
|
||||
@@ -2627,7 +2672,7 @@ static void HWR_RenderPolyObjectPlane(polyobj_t *polysector, boolean isceiling,
|
||||
v3d->z = FIXED_TO_FLOAT(polysector->vertices[i]->y);
|
||||
}
|
||||
|
||||
HWR_Lighting(&Surf, lightlevel, planecolormap);
|
||||
HWR_Lighting(&Surf, lightlevel, planecolormap, P_SectorUsesDirectionalLighting((FOFsector != NULL) ? FOFsector : gl_frontsector));
|
||||
|
||||
if (blendmode & PF_Translucent)
|
||||
{
|
||||
@@ -3494,7 +3539,8 @@ static void HWR_SplitSprite(gl_vissprite_t *spr, const boolean papersprite)
|
||||
GLPatch_t *gpatch;
|
||||
FSurfaceInfo Surf;
|
||||
extracolormap_t *colormap;
|
||||
FUINT lightlevel;
|
||||
INT32 lightlevel;
|
||||
boolean lightset = true;
|
||||
FBITFIELD blend = 0;
|
||||
UINT8 alpha;
|
||||
|
||||
@@ -3630,10 +3676,7 @@ static void HWR_SplitSprite(gl_vissprite_t *spr, const boolean papersprite)
|
||||
i = 0;
|
||||
temp = FLOAT_TO_FIXED(realtop);
|
||||
|
||||
if (R_ThingIsFullBright(spr->mobj))
|
||||
lightlevel = 255;
|
||||
else if (R_ThingIsFullDark(spr->mobj))
|
||||
lightlevel = 0;
|
||||
lightset = HWR_OverrideObjectLightLevel(spr->mobj, &lightlevel);
|
||||
|
||||
for (i = 1; i < sector->numlights; i++)
|
||||
{
|
||||
@@ -3641,14 +3684,14 @@ static void HWR_SplitSprite(gl_vissprite_t *spr, const boolean papersprite)
|
||||
if (!(h <= temp))
|
||||
continue;
|
||||
|
||||
if (!(spr->mobj->frame & FF_FULLBRIGHT))
|
||||
if (!lightset)
|
||||
lightlevel = min(*list[i-1].lightlevel, 255);
|
||||
colormap = list[i-1].extra_colormap;
|
||||
break;
|
||||
}
|
||||
|
||||
if (R_ThingIsSemiBright(spr->mobj))
|
||||
lightlevel = 128 + (lightlevel>>1);
|
||||
if (!lightset)
|
||||
HWR_ObjectLightLevelPost(spr, sector, &lightlevel, false);
|
||||
|
||||
for (i = 0; i < sector->numlights; i++)
|
||||
{
|
||||
@@ -3658,8 +3701,12 @@ static void HWR_SplitSprite(gl_vissprite_t *spr, const boolean papersprite)
|
||||
// even if we aren't changing colormap or lightlevel, we still need to continue drawing down the sprite
|
||||
if (!(list[i].flags & FF_NOSHADE) && (list[i].flags & FF_CUTSPRITES))
|
||||
{
|
||||
if (!(spr->mobj->frame & FF_FULLBRIGHT))
|
||||
if (!lightset)
|
||||
{
|
||||
lightlevel = min(*list[i].lightlevel, 255);
|
||||
HWR_ObjectLightLevelPost(spr, sector, &lightlevel, false);
|
||||
}
|
||||
|
||||
colormap = list[i].extra_colormap;
|
||||
}
|
||||
|
||||
@@ -3720,7 +3767,7 @@ static void HWR_SplitSprite(gl_vissprite_t *spr, const boolean papersprite)
|
||||
wallVerts[1].z = baseWallVerts[2].z + (baseWallVerts[2].z - baseWallVerts[1].z) * heightmult;
|
||||
}
|
||||
|
||||
HWR_Lighting(&Surf, lightlevel, colormap);
|
||||
HWR_Lighting(&Surf, lightlevel, colormap, P_SectorUsesDirectionalLighting(sector) && !(spr->mobj->frame & FF_FULLBRIGHT));
|
||||
|
||||
Surf.PolyColor.s.alpha = alpha;
|
||||
|
||||
@@ -3747,7 +3794,7 @@ static void HWR_SplitSprite(gl_vissprite_t *spr, const boolean papersprite)
|
||||
wallVerts[0].y = bot;
|
||||
wallVerts[1].y = endbot;
|
||||
|
||||
HWR_Lighting(&Surf, lightlevel, colormap);
|
||||
HWR_Lighting(&Surf, lightlevel, colormap, P_SectorUsesDirectionalLighting(sector));
|
||||
|
||||
Surf.PolyColor.s.alpha = alpha;
|
||||
|
||||
@@ -3765,7 +3812,6 @@ static void HWR_DrawSprite(gl_vissprite_t *spr)
|
||||
GLPatch_t *gpatch; // sprite patch converted to hardware
|
||||
FSurfaceInfo Surf;
|
||||
FBITFIELD blend = 0;
|
||||
INT32 blendmode;
|
||||
|
||||
INT32 shader = SHADER_NONE;
|
||||
|
||||
@@ -3854,19 +3900,20 @@ static void HWR_DrawSprite(gl_vissprite_t *spr)
|
||||
|
||||
// colormap test
|
||||
sector_t *sector = spr->mobj->subsector->sector;
|
||||
UINT8 lightlevel = 255;
|
||||
INT32 lightlevel = 255;
|
||||
boolean lightset = HWR_OverrideObjectLightLevel(spr->mobj, &lightlevel);
|
||||
extracolormap_t *colormap = sector->extra_colormap;
|
||||
const boolean fullbright = R_ThingIsFullBright(spr->mobj);
|
||||
|
||||
if (R_ThingIsFullDark(spr->mobj))
|
||||
lightlevel = 0;
|
||||
else if (!(R_ThingIsFullBright(spr->mobj)))
|
||||
if (!lightset)
|
||||
lightlevel = min(sector->lightlevel, 255);
|
||||
|
||||
if (R_ThingIsSemiBright(spr->mobj))
|
||||
lightlevel = 128 + (lightlevel>>1);
|
||||
if (!lightset)
|
||||
HWR_ObjectLightLevelPost(spr, sector, &lightlevel, false);
|
||||
|
||||
HWR_Lighting(&Surf, lightlevel, colormap);
|
||||
HWR_Lighting(&Surf, lightlevel, colormap, P_SectorUsesDirectionalLighting(sector) && !fullbright);
|
||||
|
||||
INT32 blendmode;
|
||||
if (spr->mobj->frame & FF_BLENDMASK)
|
||||
blendmode = ((spr->mobj->frame & FF_BLENDMASK) >> FF_BLENDSHIFT) + 1;
|
||||
else
|
||||
@@ -3977,7 +4024,7 @@ static void HWR_DrawPrecipitationSprite(gl_vissprite_t *spr)
|
||||
colormap = sector->extra_colormap;
|
||||
}
|
||||
|
||||
HWR_Lighting(&Surf, lightlevel, colormap);
|
||||
HWR_Lighting(&Surf, lightlevel, colormap, P_SectorUsesDirectionalLighting(sector));
|
||||
|
||||
if (spr->mobj->frame & FF_TRANSMASK)
|
||||
{
|
||||
@@ -4488,7 +4535,6 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
||||
float this_scale;
|
||||
float spritexscale, spriteyscale;
|
||||
float gz, gzt;
|
||||
INT32 blendmode;
|
||||
spritedef_t *sprdef;
|
||||
spriteframe_t *sprframe;
|
||||
#ifdef ROTSPRITE
|
||||
@@ -4537,6 +4583,7 @@ static void HWR_ProjectSprite(mobj_t *thing)
|
||||
|
||||
const boolean papersprite = (thing->frame & FF_PAPERSPRITE);
|
||||
|
||||
INT32 blendmode;
|
||||
if (thing->frame & FF_BLENDMASK)
|
||||
blendmode = ((thing->frame & FF_BLENDMASK) >> FF_BLENDSHIFT) + 1;
|
||||
else
|
||||
@@ -5527,9 +5574,17 @@ void HWR_RenderPlayerView(void)
|
||||
GL_ClearBuffer(true, false, false, &ClearColor);
|
||||
}
|
||||
|
||||
if (HWR_UseShader() && cv_ripplewater.value)
|
||||
if (HWR_UseShader())
|
||||
{
|
||||
GL_SetShaderInfo(HWD_SHADERINFO_LEVELTIME, (INT32)leveltime); // The water surface shader needs the leveltime.
|
||||
if (cv_ripplewater.value)
|
||||
GL_SetShaderInfo(HWD_SHADERINFO_LEVELTIME, (INT32)leveltime); // The water surface shader needs the leveltime.
|
||||
const angle_t light_angle = maplighting.angle - viewangle + ANGLE_90; // I fucking hate OGL's coordinate system
|
||||
GL_SetShaderInfo(HWD_SHADERINFO_LIGHT_X, FINECOSINE(light_angle >> ANGLETOFINESHIFT));
|
||||
GL_SetShaderInfo(HWD_SHADERINFO_LIGHT_Y, 0);
|
||||
GL_SetShaderInfo(HWD_SHADERINFO_LIGHT_Z, -FINESINE(light_angle >> ANGLETOFINESHIFT));
|
||||
|
||||
GL_SetShaderInfo(HWD_SHADERINFO_LIGHT_CONTRAST, maplighting.contrast);
|
||||
GL_SetShaderInfo(HWD_SHADERINFO_LIGHT_BACKLIGHT, maplighting.backlight);
|
||||
}
|
||||
|
||||
if (viewssnum > 3)
|
||||
@@ -5777,7 +5832,7 @@ static void HWR_RenderWall(FOutVector *wallVerts, FSurfaceInfo *pSurf, FBITFIELD
|
||||
INT32 shader = SHADER_NONE;
|
||||
|
||||
// Lighting is done here instead so that fog isn't drawn incorrectly on transparent walls after sorting
|
||||
HWR_Lighting(pSurf, lightlevel, wallcolormap);
|
||||
HWR_Lighting(pSurf, lightlevel, wallcolormap, P_SectorUsesDirectionalLighting(gl_frontsector));
|
||||
|
||||
pSurf->PolyColor.s.alpha = alpha; // put the alpha back after lighting
|
||||
|
||||
|
||||
@@ -118,7 +118,7 @@ void HWR_SetStencilState(int state, int level);
|
||||
// into files like hw_bsp.c, hw_sprites.c...
|
||||
|
||||
// hw_main.c: Lighting and fog
|
||||
void HWR_Lighting(FSurfaceInfo *Surface, INT32 light_level, extracolormap_t *colormap);
|
||||
void HWR_Lighting(FSurfaceInfo *Surface, INT32 light_level, extracolormap_t *colormap, const boolean directional);
|
||||
|
||||
UINT8 HWR_GetTranstableAlpha(INT32 transtablenum);
|
||||
FBITFIELD HWR_GetBlendModeFlag(INT32 ast);
|
||||
|
||||
@@ -1120,7 +1120,7 @@ void HWR_DrawMD2(gl_vissprite_t *spr)
|
||||
{
|
||||
sector_t *sector = spr->mobj->subsector->sector;
|
||||
extracolormap_t *colormap = sector->extra_colormap;
|
||||
UINT8 lightlevel = 255;
|
||||
INT32 lightlevel = 255;
|
||||
|
||||
if (sector->numlights)
|
||||
{
|
||||
@@ -1143,7 +1143,9 @@ void HWR_DrawMD2(gl_vissprite_t *spr)
|
||||
colormap = sector->extra_colormap;
|
||||
}
|
||||
|
||||
HWR_Lighting(&Surf, lightlevel, colormap);
|
||||
HWR_ObjectLightLevelPost(spr, sector, &lightlevel, true);
|
||||
|
||||
HWR_Lighting(&Surf, lightlevel, colormap, P_SectorUsesDirectionalLighting(sector) && !(spr->mobj->frame & FF_FULLBRIGHT));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -36,7 +36,7 @@ static struct {
|
||||
{GLSL_DEFAULT_VERTEX_SHADER, GLSL_WALL_FRAGMENT_SHADER},
|
||||
|
||||
// Model shader
|
||||
{GLSL_DEFAULT_VERTEX_SHADER, GLSL_WALL_FRAGMENT_SHADER},
|
||||
{GLSL_MODEL_LIGHTING_VERTEX_SHADER, GLSL_WALL_FRAGMENT_SHADER},
|
||||
|
||||
// Water shader
|
||||
{GLSL_DEFAULT_VERTEX_SHADER, GLSL_WATER_FRAGMENT_SHADER},
|
||||
|
||||
@@ -31,6 +31,31 @@
|
||||
"gl_ClipVertex = gl_ModelViewMatrix * gl_Vertex;\n" \
|
||||
"}\0"
|
||||
|
||||
// reinterpretation of sprite lighting for models
|
||||
// it's a combination of how it works for normal sprites & papersprites
|
||||
#define GLSL_MODEL_LIGHTING_VERTEX_SHADER \
|
||||
"uniform float lighting;\n" \
|
||||
"uniform vec3 light_dir;\n" \
|
||||
"uniform float light_contrast;\n" \
|
||||
"uniform float light_backlight;\n" \
|
||||
"void main()\n" \
|
||||
"{\n" \
|
||||
"gl_Position = gl_ProjectionMatrix * gl_ModelViewMatrix * gl_Vertex;\n" \
|
||||
"float light = lighting;\n" \
|
||||
"if (length(light_dir) > 0.000001) {\n" \
|
||||
"mat4 m4 = gl_ProjectionMatrix * gl_ModelViewMatrix;\n" \
|
||||
"mat3 m3 = mat3( m4[0].xyz, m4[1].xyz, m4[2].xyz );\n" \
|
||||
"float extralight = -dot(normalize(gl_Normal * m3), normalize(light_dir));\n" \
|
||||
"extralight *= light_contrast - light_backlight;\n" \
|
||||
"extralight *= lighting / 255.0;\n" \
|
||||
"light += extralight * 2.5;\n" \
|
||||
"}\n" \
|
||||
"light = clamp(light / 255.0, 0.0, 1.0);\n" \
|
||||
"gl_FrontColor = vec4(light, light, light, 1.0);\n" \
|
||||
"gl_TexCoord[0].xy = gl_MultiTexCoord0.xy;\n" \
|
||||
"gl_ClipVertex = gl_ModelViewMatrix * gl_Vertex;\n" \
|
||||
"}\0"
|
||||
|
||||
// ==================
|
||||
// Fragment shaders
|
||||
// ==================
|
||||
@@ -195,21 +220,28 @@
|
||||
|
||||
// hand tuned adjustments for light level calculation
|
||||
#define GLSL_FLOOR_FUDGES \
|
||||
"#version 120\n" \
|
||||
"#define STARTMAP_FUDGE 1.06\n" \
|
||||
"#define SCALE_FUDGE 1.15\n"
|
||||
|
||||
#define GLSL_WALL_FUDGES \
|
||||
"#version 120\n" \
|
||||
"#define STARTMAP_FUDGE 1.05\n" \
|
||||
"#define SCALE_FUDGE 2.2\n"
|
||||
|
||||
#define GLSL_FLOOR_FRAGMENT_SHADER \
|
||||
"#version 120\n" \
|
||||
GLSL_FLOOR_FUDGES \
|
||||
GLSL_SOFTWARE_FRAGMENT_SHADER
|
||||
|
||||
// this is very backwards
|
||||
// but we wanna have the game look like vanilla does
|
||||
// oh well
|
||||
#define GLSL_WALL_FRAGMENT_SHADER \
|
||||
"#version 120\n" \
|
||||
"#ifdef SRB2_PALETTE_RENDERING\n" \
|
||||
GLSL_WALL_FUDGES \
|
||||
"#else\n" \
|
||||
GLSL_FLOOR_FUDGES \
|
||||
"#endif\n" \
|
||||
GLSL_SOFTWARE_FRAGMENT_SHADER
|
||||
|
||||
//
|
||||
@@ -227,6 +259,7 @@
|
||||
"vec4 texel = texture2D(tex, vec2(gl_TexCoord[0].s - sdistort, gl_TexCoord[0].t - cdistort));\n"
|
||||
|
||||
#define GLSL_WATER_FRAGMENT_SHADER \
|
||||
"#version 120\n" \
|
||||
GLSL_FLOOR_FUDGES \
|
||||
"const float freq = 0.025;\n" \
|
||||
"const float amp = 0.025;\n" \
|
||||
@@ -275,6 +308,7 @@
|
||||
// The floor fudges are used, but should the wall fudges be used instead? or something inbetween?
|
||||
// or separate values for floors and walls? (need to change more than this shader for that)
|
||||
#define GLSL_FOG_FRAGMENT_SHADER \
|
||||
"#version 120\n" \
|
||||
GLSL_FLOOR_FUDGES \
|
||||
"uniform vec4 tint_color;\n" \
|
||||
"uniform vec4 fade_color;\n" \
|
||||
|
||||
@@ -670,6 +670,9 @@ typedef enum
|
||||
gluniform_lighting,
|
||||
gluniform_fade_start,
|
||||
gluniform_fade_end,
|
||||
gluniform_light_dir,
|
||||
gluniform_light_contrast,
|
||||
gluniform_light_backlight,
|
||||
|
||||
// palette rendering
|
||||
gluniform_palette_tex, // 1d texture containing a palette
|
||||
@@ -707,6 +710,11 @@ static gl_shaderstate_t gl_shaderstate;
|
||||
|
||||
// Shader info
|
||||
static float shader_leveltime = 0;
|
||||
static float shader_light_x = 0.0f;
|
||||
static float shader_light_y = 0.0f;
|
||||
static float shader_light_z = 0.0f;
|
||||
static INT32 shader_light_contrast = 0;
|
||||
static INT32 shader_light_backlight = 0;
|
||||
|
||||
// Lactozilla: Shader functions
|
||||
static boolean GL_Shader_CompileProgram(gl_shader_t *shader, GLint i);
|
||||
@@ -867,6 +875,21 @@ void GL_SetShaderInfo(hwdshaderinfo_t info, INT32 value)
|
||||
case HWD_SHADERINFO_LEVELTIME:
|
||||
shader_leveltime = (((float)(value-1)) + FIXED_TO_FLOAT(rendertimefrac)) / TICRATE;
|
||||
break;
|
||||
case HWD_SHADERINFO_LIGHT_X:
|
||||
shader_light_x = FixedToFloat(value);
|
||||
break;
|
||||
case HWD_SHADERINFO_LIGHT_Y:
|
||||
shader_light_y = FixedToFloat(value);
|
||||
break;
|
||||
case HWD_SHADERINFO_LIGHT_Z:
|
||||
shader_light_z = FixedToFloat(value);
|
||||
break;
|
||||
case HWD_SHADERINFO_LIGHT_CONTRAST:
|
||||
shader_light_contrast = value;
|
||||
break;
|
||||
case HWD_SHADERINFO_LIGHT_BACKLIGHT:
|
||||
shader_light_backlight = value;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -1600,8 +1623,8 @@ void GL_SetBlend(FBITFIELD PolyFlags)
|
||||
GL_SetNoTexture();
|
||||
}
|
||||
}
|
||||
|
||||
CurrentPolyFlags = PolyFlags;
|
||||
|
||||
}
|
||||
|
||||
static void GL_AllocTextureBuffer(GLMipmap_t *pTexInfo)
|
||||
@@ -1868,11 +1891,32 @@ static void GL_Shader_SetUniforms(FSurfaceInfo *Surface, GLRGBAFloat *poly, GLRG
|
||||
UNIFORM_4(shader->uniforms[gluniform_tint_color], tint->red, tint->green, tint->blue, tint->alpha, pglUniform4f);
|
||||
UNIFORM_4(shader->uniforms[gluniform_fade_color], fade->red, fade->green, fade->blue, fade->alpha, pglUniform4f);
|
||||
|
||||
boolean directional = false;
|
||||
if (Surface != NULL)
|
||||
{
|
||||
UNIFORM_1(shader->uniforms[gluniform_lighting], (GLfloat)Surface->LightInfo.light_level, pglUniform1f);
|
||||
UNIFORM_1(shader->uniforms[gluniform_fade_start], (GLfloat)Surface->LightInfo.fade_start, pglUniform1f);
|
||||
UNIFORM_1(shader->uniforms[gluniform_fade_end], (GLfloat)Surface->LightInfo.fade_end, pglUniform1f);
|
||||
directional = Surface->LightInfo.directional;
|
||||
}
|
||||
else
|
||||
{
|
||||
UNIFORM_1(shader->uniforms[gluniform_lighting], 255, pglUniform1f);
|
||||
UNIFORM_1(shader->uniforms[gluniform_fade_start], 0, pglUniform1f);
|
||||
UNIFORM_1(shader->uniforms[gluniform_fade_end], 31, pglUniform1f);
|
||||
}
|
||||
|
||||
if (directional)
|
||||
{
|
||||
UNIFORM_3(shader->uniforms[gluniform_light_dir], shader_light_x, shader_light_y, shader_light_z, pglUniform3f);
|
||||
UNIFORM_1(shader->uniforms[gluniform_light_contrast], shader_light_contrast, pglUniform1f);
|
||||
UNIFORM_1(shader->uniforms[gluniform_light_backlight], shader_light_backlight, pglUniform1f);
|
||||
}
|
||||
else
|
||||
{
|
||||
UNIFORM_3(shader->uniforms[gluniform_light_dir], 0, 0, 0, pglUniform3f);
|
||||
UNIFORM_1(shader->uniforms[gluniform_light_contrast], 0, pglUniform1f);
|
||||
UNIFORM_1(shader->uniforms[gluniform_light_backlight], 0, pglUniform1f);
|
||||
}
|
||||
|
||||
UNIFORM_1(shader->uniforms[gluniform_leveltime], shader_leveltime, pglUniform1f);
|
||||
@@ -1997,6 +2041,9 @@ static boolean GL_Shader_CompileProgram(gl_shader_t *shader, GLint i)
|
||||
shader->uniforms[gluniform_lighting] = GETUNI("lighting");
|
||||
shader->uniforms[gluniform_fade_start] = GETUNI("fade_start");
|
||||
shader->uniforms[gluniform_fade_end] = GETUNI("fade_end");
|
||||
shader->uniforms[gluniform_light_dir] = GETUNI("light_dir");
|
||||
shader->uniforms[gluniform_light_contrast] = GETUNI("light_contrast");
|
||||
shader->uniforms[gluniform_light_backlight] = GETUNI("light_backlight");
|
||||
|
||||
// palette rendering
|
||||
shader->uniforms[gluniform_palette_tex] = GETUNI("palette_tex");
|
||||
|
||||
+2
-2
@@ -5410,7 +5410,7 @@ static boolean K_SpeedLinesShouldBlend(player_t *player)
|
||||
if (player->kartstuff[k_sneakertimer])
|
||||
return true;
|
||||
|
||||
// this is how the percentage speedometer calcs, i suck at maths so this was the easiest thing to fo lmao
|
||||
// this is how the percentage speedometer calcs, i suck at maths so this was the easiest thing to do lmao
|
||||
percentspeed = (FixedDiv(player->speed, FixedMul(K_GetKartSpeed(player, false), ORIG_FRICTION))*100)>>FRACBITS;
|
||||
|
||||
if (percentspeed > 127) // sneaker boost is around 25%
|
||||
@@ -5421,7 +5421,7 @@ static boolean K_SpeedLinesShouldBlend(player_t *player)
|
||||
|
||||
typedef INT32 (*randomFunc)(INT32 min, INT32 max);
|
||||
|
||||
static inline void K_SpawnNormalSpeedLines(player_t *player, boolean synched)
|
||||
FUNCINLINE static ATTRINLINE void K_SpawnNormalSpeedLines(player_t *player, boolean synched)
|
||||
{
|
||||
randomFunc randomfunc = synched ? P_RandomRange : M_RandomRange;
|
||||
|
||||
|
||||
@@ -99,6 +99,7 @@ static const udata_field_t mobj_fields[] = {
|
||||
FIELD(mobj_t, spritexoffset, udatalib_getter_fixed, mobj_spriteoffset_setter),
|
||||
FIELD(mobj_t, spriteyoffset, udatalib_getter_fixed, mobj_spriteoffset_setter),
|
||||
FIELD(mobj_t, touching_sectorlist, mobj_touching_sectorlist_unimplemented, mobj_touching_sectorlist_unimplemented),
|
||||
FIELD(mobj_t, lightlevel, udatalib_getter_int16, udatalib_setter_int16),
|
||||
FIELD(mobj_t, subsector, udatalib_getter_subsector, mobj_nosetpos_subsector),
|
||||
FIELD(mobj_t, floorz, udatalib_getter_fixed, mobj_nosetpos_floorz),
|
||||
FIELD(mobj_t, ceilingz, udatalib_getter_fixed, mobj_nosetpos_ceilingz),
|
||||
|
||||
+30
-27
@@ -1393,31 +1393,30 @@ static const char* OP_MouseTooltips[] =
|
||||
|
||||
static menuitem_t OP_VideoOptionsMenu[] =
|
||||
{
|
||||
{IT_STRING | IT_CALL, NULL, "Set Resolution...", M_VideoModeMenu, 10},
|
||||
{IT_STRING | IT_CALL, NULL, "Set Resolution...", M_VideoModeMenu, 10},
|
||||
#if defined (__unix__) || defined (UNIXCOMMON) || defined (HAVE_SDL)
|
||||
{IT_STRING|IT_CVAR, NULL, "Fullscreen", &cv_fullscreen, 20},
|
||||
{IT_STRING|IT_CVAR, NULL, "Fullscreen", &cv_fullscreen, 20},
|
||||
#endif
|
||||
{IT_STRING | IT_CVAR | IT_CV_SLIDER,
|
||||
NULL, "Brightness", &cv_globalgamma, 30},
|
||||
NULL, "Brightness", &cv_globalgamma, 30},
|
||||
|
||||
{IT_STRING | IT_CVAR | IT_CV_SLIDER,
|
||||
NULL, "Saturation", &cv_globalsaturation , 40},
|
||||
NULL, "Saturation", &cv_globalsaturation , 40},
|
||||
|
||||
{IT_SUBMENU|IT_STRING, NULL, "Advanced Color Settings...", &OP_ColorOptionsDef, 50},
|
||||
{IT_SUBMENU|IT_STRING, NULL, "Advanced Color Settings...", &OP_ColorOptionsDef, 50},
|
||||
|
||||
{IT_STRING | IT_CVAR, NULL, "Draw Distance", &cv_drawdist, 65},
|
||||
{IT_STRING | IT_CVAR, NULL, "Weather Draw Distance",&cv_drawdist_precip, 75},
|
||||
{IT_STRING | IT_CVAR, NULL, "Draw Distance", &cv_drawdist, 65},
|
||||
{IT_STRING | IT_CVAR, NULL, "Weather Draw Distance", &cv_drawdist_precip, 75},
|
||||
|
||||
{IT_STRING | IT_CVAR, NULL, "Show FPS", &cv_ticrate, 95},
|
||||
{IT_STRING | IT_CVAR, NULL, "Vertical Sync", &cv_vidwait, 105},
|
||||
{IT_STRING | IT_CVAR, NULL, "FPS Cap", &cv_fpscap, 115},
|
||||
{IT_STRING | IT_CVAR, NULL, "Drift spark pulse size",&cv_driftsparkpulse, 125},
|
||||
{IT_STRING | IT_CVAR, NULL, "VHS effect", &cv_vhseffect, 135},
|
||||
{IT_STRING | IT_CVAR, NULL, "Show FPS", &cv_ticrate, 95},
|
||||
{IT_STRING | IT_CVAR, NULL, "Vertical Sync", &cv_vidwait, 105},
|
||||
{IT_STRING | IT_CVAR, NULL, "FPS Cap", &cv_fpscap, 115},
|
||||
{IT_STRING | IT_CVAR, NULL, "Drift spark pulse size", &cv_driftsparkpulse, 125},
|
||||
{IT_STRING | IT_CVAR, NULL, "VHS effect", &cv_vhseffect, 135},
|
||||
#ifdef HWRENDER
|
||||
{IT_SUBMENU|IT_STRING, NULL, "OpenGL Options...", &OP_OpenGLOptionsDef, 145},
|
||||
{IT_SUBMENU|IT_STRING, NULL, "OpenGL Options...", &OP_OpenGLOptionsDef, 145},
|
||||
#endif
|
||||
{IT_SUBMENU|IT_STRING, NULL, "Advanced Video Options...", &OP_ExpOptionsDef, 155},
|
||||
|
||||
{IT_SUBMENU|IT_STRING, NULL, "Advanced Video Options...", &OP_ExpOptionsDef, 155},
|
||||
};
|
||||
|
||||
static const char* OP_VideoTooltips[] =
|
||||
@@ -1513,23 +1512,25 @@ static menuitem_t OP_ColorOptionsMenu[] =
|
||||
|
||||
static menuitem_t OP_ExpOptionsMenu[] =
|
||||
{
|
||||
{IT_HEADER, NULL, "Advanced Video Options", NULL, 10},
|
||||
{IT_STRING|IT_CVAR, NULL, "Interpolation Distance", &cv_maxinterpdist, 30},
|
||||
{IT_STRING | IT_CVAR, NULL, "Weather Interpolation", &cv_precipinterp, 40},
|
||||
{IT_HEADER, NULL, "Advanced Video Options", NULL, 15},
|
||||
{IT_STRING|IT_CVAR, NULL, "Interpolation Distance", &cv_maxinterpdist, 25},
|
||||
{IT_STRING | IT_CVAR, NULL, "Weather Interpolation", &cv_precipinterp, 30},
|
||||
|
||||
{IT_STRING | IT_CVAR, NULL, "Scale Weather with Mobjscale", &cv_mobjscaleprecip, 60},
|
||||
{IT_STRING | IT_CVAR, NULL, "Less Weather Effects", &cv_lessprecip, 70},
|
||||
{IT_STRING | IT_CVAR, NULL, "Scale Weather with Mobjscale", &cv_mobjscaleprecip, 40},
|
||||
{IT_STRING | IT_CVAR, NULL, "Less Weather Effects", &cv_lessprecip, 45},
|
||||
|
||||
{IT_STRING | IT_CVAR, NULL, "Skyboxes", &cv_skybox, 80},
|
||||
{IT_STRING | IT_CVAR, NULL, "Randomized Directional Light", &cv_randomdirlight, 55},
|
||||
|
||||
{IT_STRING | IT_CVAR, NULL, "FPS counter sampling", &cv_accuratefps, 90},
|
||||
{IT_STRING | IT_CVAR, NULL, "Skyboxes", &cv_skybox, 65},
|
||||
|
||||
{IT_STRING | IT_CVAR, NULL, "FPS counter sampling", &cv_accuratefps, 75},
|
||||
|
||||
#ifdef HWRENDER
|
||||
{IT_STRING | IT_CVAR, NULL, "Screen Textures", &cv_glscreentextures, 110},
|
||||
{IT_STRING | IT_CVAR, NULL, "Screen Textures", &cv_glscreentextures, 85},
|
||||
#ifdef USE_FBO_OGL
|
||||
{IT_STRING | IT_CVAR, NULL, "FBO Downsampling support", &cv_glframebuffer, 120},
|
||||
{IT_STRING | IT_CVAR, NULL, "FBO Downsampling support", &cv_glframebuffer, 90},
|
||||
#endif
|
||||
{IT_STRING | IT_CVAR, NULL, "Palette Depth", &cv_glpalettedepth, 140},
|
||||
{IT_STRING | IT_CVAR, NULL, "Palette Depth", &cv_glpalettedepth, 100},
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -1540,6 +1541,7 @@ static const char* OP_ExpTooltips[] =
|
||||
"Should weather be interpolated? Weather should look about the\nsame but perform a bit better when disabled.",
|
||||
"Should weather be scaled with Mapobjectscale?.",
|
||||
"When weather is on this will cut the object amount used in half.",
|
||||
"Should the directional lightning be randomized each map?\nTakes effect on next map load.",
|
||||
"Toggle being able to see the sky.",
|
||||
"Change the FPS counter sampling method\nInaccurate updates slower and might miss frame drops and such\nAccurate updates faster and is more accurate, but might be less readable", // how to ingles??
|
||||
#ifdef HWRENDER
|
||||
@@ -1558,6 +1560,7 @@ enum
|
||||
op_exp_precipinter,
|
||||
op_exp_precipmoscale,
|
||||
op_exp_lessprecip,
|
||||
op_exp_dirlight,
|
||||
op_exp_skybox,
|
||||
op_exp_accuratefps,
|
||||
#ifdef HWRENDER
|
||||
@@ -3178,7 +3181,7 @@ menu_t OP_MonitorToggleDef =
|
||||
menu_t OP_OpenGLOptionsDef = DEFAULTSCROLLSTYLE("M_VIDEO", OP_OpenGLOptionsMenu, &OP_VideoOptionsDef, 30, 30);
|
||||
#endif
|
||||
|
||||
menu_t OP_ExpOptionsDef = DEFAULTMENUSTYLE("M_VIDEO", OP_ExpOptionsMenu, &OP_VideoOptionsDef, 30, 30);
|
||||
menu_t OP_ExpOptionsDef = DEFAULTSCROLLSTYLE("M_VIDEO", OP_ExpOptionsMenu, &OP_VideoOptionsDef, 30, 25);
|
||||
|
||||
menu_t OP_DataOptionsDef = DEFAULTMENUSTYLE("M_DATA", OP_DataOptionsMenu, &OP_MainDef, 60, 30);
|
||||
menu_t OP_ScreenshotOptionsDef = DEFAULTMENUSTYLE("M_SCSHOT", OP_ScreenshotOptionsMenu, &OP_DataOptionsDef, 30, 30);
|
||||
@@ -5322,7 +5325,6 @@ static void M_DrawGenericMenu(void)
|
||||
DoToolTips(OP_ControlsDef, OP_ControlsTooltips);
|
||||
DoToolTips(OP_MouseOptionsDef, OP_MouseTooltips);
|
||||
DoToolTips(OP_VideoOptionsDef, OP_VideoTooltips);
|
||||
DoToolTips(OP_ExpOptionsDef, OP_ExpTooltips);
|
||||
DoToolTips(OP_SoundOptionsDef, OP_SoundTooltips);
|
||||
DoToolTips(OP_SoundAdvancedDef, OP_SoundAdvancedTooltips);
|
||||
DoToolTips(OP_ChatOptionsDef, OP_ChatOptionsTooltips);
|
||||
@@ -5468,6 +5470,7 @@ static void M_DrawGenericScrollMenu(void)
|
||||
// dumb hack
|
||||
// tooltips
|
||||
// same macro here
|
||||
DoToolTips(OP_ExpOptionsDef, OP_ExpTooltips);
|
||||
#ifdef HWRENDER
|
||||
DoToolTips(OP_OpenGLOptionsDef, OP_OpenGLTooltips);
|
||||
#endif
|
||||
|
||||
@@ -294,6 +294,7 @@ typedef struct mobj_s
|
||||
fixed_t spritexoffset, spriteyoffset;
|
||||
fixed_t old_spritexscale, old_spriteyscale;
|
||||
fixed_t old_spritexoffset, old_spriteyoffset;
|
||||
INT16 lightlevel; // Add to sector lightlevel, -255 - 255
|
||||
|
||||
fixed_t realxscale, realyscale; // funn-E streeetch
|
||||
fixed_t realxoffset, realyoffset;
|
||||
@@ -447,6 +448,7 @@ typedef struct precipmobj_s
|
||||
fixed_t spritexoffset, spriteyoffset;
|
||||
fixed_t old_spritexscale, old_spriteyscale;
|
||||
fixed_t old_spritexoffset, old_spriteyoffset;
|
||||
INT16 lightlevel; // Add to sector lightlevel, -255 - 255
|
||||
|
||||
fixed_t realxscale, realyscale; // funn-E streeetch
|
||||
fixed_t realxoffset, realyoffset;
|
||||
|
||||
@@ -2157,6 +2157,9 @@ static void LoadMobjThinker(savebuffer_t *save, actionf_p1 thinker)
|
||||
// Timer for slam sound effect
|
||||
mobj->slamsoundtimer = 0;
|
||||
|
||||
// extra mobjlightlevel
|
||||
mobj->lightlevel = 0;
|
||||
|
||||
//}
|
||||
|
||||
if (diff & MD_REDFLAG)
|
||||
|
||||
+136
-4
@@ -279,6 +279,15 @@ FUNCNORETURN static ATTRNORETURN void CorruptMapError(const char *msg)
|
||||
|
||||
#define NUMLAPS_DEFAULT 3
|
||||
|
||||
static void P_ClearMapHeaderLighting(mapheader_lighting_t *lighting)
|
||||
{
|
||||
lighting->light_contrast = 8;
|
||||
lighting->sprite_backlight = 0;
|
||||
lighting->use_light_angle = false;
|
||||
lighting->light_angle = 0;
|
||||
lighting->use_custom_light = false;
|
||||
}
|
||||
|
||||
/** Clears the data from a single map header.
|
||||
*
|
||||
* \param i Map number to clear header for.
|
||||
@@ -325,9 +334,13 @@ static void P_ClearSingleMapHeaderInfo(INT16 i)
|
||||
// SRB2Kart
|
||||
//mapheaderinfo[num]->automap = false;
|
||||
mapheaderinfo[num]->mobj_scale = FRACUNIT;
|
||||
// an even further impossibility, delfile custom opts support
|
||||
|
||||
mapheaderinfo[num]->customopts = NULL;
|
||||
mapheaderinfo[num]->numCustomOptions = 0;
|
||||
|
||||
P_ClearMapHeaderLighting(&mapheaderinfo[num]->lighting);
|
||||
P_ClearMapHeaderLighting(&mapheaderinfo[num]->lighting_encore);
|
||||
mapheaderinfo[num]->use_encore_lighting = false;
|
||||
}
|
||||
|
||||
/** Allocates a new map-header structure.
|
||||
@@ -497,21 +510,137 @@ static inline float P_SegLengthFloat(seg_t *seg)
|
||||
*/
|
||||
void P_UpdateSegLightOffset(seg_t *li)
|
||||
{
|
||||
const UINT8 contrast = 8;
|
||||
const UINT8 contrast = maplighting.contrast;
|
||||
const fixed_t contrastFixed = ((fixed_t)contrast) * FRACUNIT;
|
||||
fixed_t light = FRACUNIT;
|
||||
fixed_t extralight = 0;
|
||||
|
||||
light = FixedDiv(R_PointToAngle2(0, 0, abs(li->v1->x - li->v2->x), abs(li->v1->y - li->v2->y)), ANGLE_90);
|
||||
if (maplighting.directional == true)
|
||||
{
|
||||
angle_t liAngle = R_PointToAngle2(0, 0, (li->v1->x - li->v2->x), (li->v1->y - li->v2->y)) - ANGLE_90;
|
||||
|
||||
light = FixedMul(FINECOSINE(liAngle >> ANGLETOFINESHIFT), FINECOSINE(maplighting.angle >> ANGLETOFINESHIFT))
|
||||
+ FixedMul(FINESINE(liAngle >> ANGLETOFINESHIFT), FINESINE(maplighting.angle >> ANGLETOFINESHIFT));
|
||||
light = (light + FRACUNIT) / 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
light = FixedDiv(R_PointToAngle2(0, 0, abs(li->v1->x - li->v2->x), abs(li->v1->y - li->v2->y)), ANGLE_90);
|
||||
}
|
||||
|
||||
extralight = -contrastFixed + FixedMul(light, contrastFixed * 2);
|
||||
|
||||
// Between -2 and 2 for software, -8 and 8 for hardware
|
||||
li->lightOffset = FixedFloor((extralight / contrast) + (FRACUNIT / 2)) / FRACUNIT;
|
||||
li->lightOffset = FixedFloor((extralight / 8) + (FRACUNIT / 2)) / FRACUNIT;
|
||||
#ifdef HWRENDER
|
||||
li->hwLightOffset = FixedFloor(extralight + (FRACUNIT / 2)) / FRACUNIT;
|
||||
#endif
|
||||
}
|
||||
|
||||
boolean P_SectorUsesDirectionalLighting(const sector_t *sector)
|
||||
{
|
||||
if (sector != NULL)
|
||||
{
|
||||
// automatically turned on
|
||||
if (sector->ceilingpic == skyflatnum || sector->floorpic == skyflatnum)
|
||||
{
|
||||
// sky is visible
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// default is off, for indoors
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean P_ApplyLightOffset(UINT8 baselightnum, const sector_t *sector)
|
||||
{
|
||||
mapheader_lighting_t *lighting = &mapheaderinfo[gamemap-1]->lighting;
|
||||
|
||||
if (encoremode && mapheaderinfo[gamemap-1]->use_encore_lighting)
|
||||
{
|
||||
lighting = &mapheaderinfo[gamemap-1]->lighting_encore;
|
||||
}
|
||||
|
||||
if (!cv_randomdirlight.value && lighting->use_custom_light == false)
|
||||
return (baselightnum < LIGHTLEVELS-1 && baselightnum > 0);
|
||||
|
||||
if (!P_SectorUsesDirectionalLighting(sector))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Don't apply light offsets at full bright or full dark.
|
||||
// Is in steps of light num .
|
||||
return (baselightnum < LIGHTLEVELS-1 && baselightnum > 0);
|
||||
}
|
||||
|
||||
boolean P_ApplyLightOffsetFine(UINT8 baselightlevel, const sector_t *sector)
|
||||
{
|
||||
mapheader_lighting_t *lighting = &mapheaderinfo[gamemap-1]->lighting;
|
||||
|
||||
if (encoremode && mapheaderinfo[gamemap-1]->use_encore_lighting)
|
||||
{
|
||||
lighting = &mapheaderinfo[gamemap-1]->lighting_encore;
|
||||
}
|
||||
|
||||
if (!cv_randomdirlight.value && lighting->use_custom_light == false)
|
||||
return (baselightlevel < 255 && baselightlevel > 0);
|
||||
|
||||
if (!P_SectorUsesDirectionalLighting(sector))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Don't apply light offsets at full bright or full dark.
|
||||
// Uses exact light levels for more smoothness.
|
||||
return (baselightlevel < 255 && baselightlevel > 0);
|
||||
}
|
||||
|
||||
// dumb thing to reset maplight on next map change when its toggled
|
||||
boolean reinitmaplight = false;
|
||||
static void P_SetupDirectionalLight(void)
|
||||
{
|
||||
mapheader_lighting_t *lighting = &mapheaderinfo[gamemap-1]->lighting;
|
||||
|
||||
if (encoremode && mapheaderinfo[gamemap-1]->use_encore_lighting)
|
||||
{
|
||||
lighting = &mapheaderinfo[gamemap-1]->lighting_encore;
|
||||
}
|
||||
|
||||
if (cv_randomdirlight.value && lighting->use_custom_light == false)
|
||||
{
|
||||
static INT16 oldmap = 0; // dont reset stuff when you restart a map
|
||||
static boolean oldencore = false;
|
||||
|
||||
if (gamemap != oldmap || encoremode != oldencore || reinitmaplight)
|
||||
{
|
||||
maplighting.contrast = M_RandomRange(0, 58);
|
||||
maplighting.backlight = 0;
|
||||
maplighting.directional = M_RandomRange(0, 1); // either on or off
|
||||
maplighting.angle = M_RandomRange(-382, 382);
|
||||
|
||||
reinitmaplight = false;
|
||||
}
|
||||
|
||||
oldmap = gamemap;
|
||||
oldencore = encoremode;
|
||||
return;
|
||||
}
|
||||
else if (lighting->use_custom_light == false)
|
||||
{
|
||||
maplighting.contrast = 8;
|
||||
maplighting.backlight = 0;
|
||||
maplighting.directional = false;
|
||||
maplighting.angle = 0;
|
||||
}
|
||||
|
||||
maplighting.contrast = lighting->light_contrast;
|
||||
maplighting.backlight = lighting->sprite_backlight;
|
||||
maplighting.directional = lighting->use_light_angle;
|
||||
maplighting.angle = lighting->light_angle;
|
||||
}
|
||||
|
||||
// Loads the SEGS resource from a level.
|
||||
static void P_LoadRawSegs(UINT8 *data)
|
||||
{
|
||||
@@ -521,6 +650,9 @@ static void P_LoadRawSegs(UINT8 *data)
|
||||
line_t *ldef;
|
||||
size_t i;
|
||||
|
||||
// Set map lighting settings.
|
||||
P_SetupDirectionalLight();
|
||||
|
||||
for (i = 0; i < numsegs; i++, li++, ml++)
|
||||
{
|
||||
li->v1 = &vertexes[SHORT(ml->v1)];
|
||||
|
||||
@@ -99,8 +99,14 @@ void P_WriteThings(lumpnum_t lump);
|
||||
fixed_t P_SegLength(seg_t *seg);
|
||||
#endif
|
||||
|
||||
extern boolean reinitmaplight;
|
||||
void P_UpdateSegLightOffset(seg_t *li);
|
||||
boolean P_ApplyLightOffset(UINT8 baselightnum, const sector_t *sector);
|
||||
boolean P_ApplyLightOffsetFine(UINT8 baselightlevel, const sector_t *sector);
|
||||
boolean P_SectorUsesDirectionalLighting(const sector_t *sector);
|
||||
|
||||
size_t P_PrecacheLevelFlats(void);
|
||||
|
||||
void P_AllocMapHeader(INT16 i);
|
||||
|
||||
// Needed for NiGHTS
|
||||
|
||||
+39
-7
@@ -30,14 +30,14 @@ static UINT16 slopecount = 0;
|
||||
// Calculate light
|
||||
static void P_UpdateSlopeLightOffset(pslope_t *slope)
|
||||
{
|
||||
const boolean ceiling = (slope->normal.z < 0);
|
||||
const UINT8 contrast = 8;
|
||||
const UINT8 contrast = maplighting.contrast;
|
||||
|
||||
fixed_t contrastFixed = ((fixed_t)contrast) * FRACUNIT;
|
||||
fixed_t zMul = FRACUNIT;
|
||||
angle_t slopeDir = ANGLE_MAX;
|
||||
fixed_t light = FRACUNIT;
|
||||
fixed_t extralight = 0;
|
||||
|
||||
|
||||
if (slope->normal.z == 0)
|
||||
{
|
||||
slope->lightOffset = 0;
|
||||
@@ -47,15 +47,47 @@ static void P_UpdateSlopeLightOffset(pslope_t *slope)
|
||||
return;
|
||||
}
|
||||
|
||||
slopeDir = R_PointToAngle2(0, 0, abs(slope->normal.y), abs(slope->normal.x));
|
||||
if (ceiling == true)
|
||||
if (maplighting.directional == true)
|
||||
{
|
||||
slopeDir ^= ANGLE_180;
|
||||
fixed_t nX = -slope->normal.x;
|
||||
fixed_t nY = -slope->normal.y;
|
||||
fixed_t nLen = FixedHypot(nX, nY);
|
||||
|
||||
if (nLen == 0)
|
||||
{
|
||||
slope->lightOffset = 0;
|
||||
#ifdef HWRENDER
|
||||
slope->hwLightOffset = 0;
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
nX = FixedDiv(nX, nLen);
|
||||
nY = FixedDiv(nY, nLen);
|
||||
|
||||
/*
|
||||
* if (slope is ceiling)
|
||||
* {
|
||||
* // There is no good way to calculate this condition here.
|
||||
* // We reverse it in R_FindPlane now.
|
||||
* nX = -nX;
|
||||
* nY = -nY;
|
||||
}
|
||||
*/
|
||||
|
||||
light = FixedMul(nX, FINECOSINE(maplighting.angle >> ANGLETOFINESHIFT))
|
||||
+ FixedMul(nY, FINESINE(maplighting.angle >> ANGLETOFINESHIFT));
|
||||
light = (light + FRACUNIT) / 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
light = FixedDiv(R_PointToAngle2(0, 0, abs(slope->d.x), abs(slope->d.y)), ANGLE_90);
|
||||
}
|
||||
|
||||
zMul = min(FRACUNIT, abs(slope->zdelta)*3/2); // *3/2, to make 60 degree slopes match walls.
|
||||
contrastFixed = FixedMul(contrastFixed, zMul);
|
||||
extralight = -contrastFixed + FixedMul(FixedDiv(AngleFixed(slopeDir), ANGLE_90), (contrastFixed * 2));
|
||||
|
||||
extralight = -contrastFixed + FixedMul(light, contrastFixed * 2);
|
||||
|
||||
// Between -2 and 2 for software, -8 and 8 for hardware
|
||||
slope->lightOffset = FixedFloor((extralight / 8) + (FRACUNIT / 2)) / FRACUNIT;
|
||||
|
||||
+6
-7
@@ -928,7 +928,7 @@ static void R_Subsector(size_t num)
|
||||
frontsector->floor_xoffs, frontsector->floor_yoffs, frontsector->floorpic_angle, floorcolormap, NULL
|
||||
, NULL
|
||||
, frontsector->f_slope
|
||||
, R_NoEncore(frontsector, false));
|
||||
, R_NoEncore(frontsector, false), false, frontsector);
|
||||
}
|
||||
else
|
||||
floorplane = NULL;
|
||||
@@ -944,7 +944,7 @@ static void R_Subsector(size_t num)
|
||||
ceilingcolormap, NULL
|
||||
, NULL
|
||||
, frontsector->c_slope
|
||||
, R_NoEncore(frontsector, true));
|
||||
, R_NoEncore(frontsector, true), true, frontsector);
|
||||
}
|
||||
else
|
||||
ceilingplane = NULL;
|
||||
@@ -994,7 +994,7 @@ static void R_Subsector(size_t num)
|
||||
*rover->bottomyoffs, *rover->bottomangle, frontsector->lightlist[light].extra_colormap, rover
|
||||
, NULL
|
||||
, *rover->b_slope
|
||||
, R_NoEncore(rover->master->frontsector, true));
|
||||
, R_NoEncore(rover->master->frontsector, true), true, frontsector);
|
||||
|
||||
ffloor[numffloors].slope = *rover->b_slope;
|
||||
|
||||
@@ -1030,7 +1030,7 @@ static void R_Subsector(size_t num)
|
||||
frontsector->lightlist[light].extra_colormap, rover
|
||||
, NULL
|
||||
, *rover->t_slope
|
||||
, R_NoEncore(rover->master->frontsector, false));
|
||||
, R_NoEncore(rover->master->frontsector, false), false, frontsector);
|
||||
|
||||
ffloor[numffloors].slope = *rover->t_slope;
|
||||
|
||||
@@ -1075,7 +1075,7 @@ static void R_Subsector(size_t num)
|
||||
polysec->floorpic_angle-po->angle,
|
||||
(light == -1 ? frontsector->extra_colormap : frontsector->lightlist[light].extra_colormap), NULL, po
|
||||
,NULL // will ffloors be slopable eventually?
|
||||
, R_NoEncore(polysec, false));
|
||||
, R_NoEncore(polysec, false), false, frontsector);
|
||||
|
||||
ffloor[numffloors].height = polysec->floorheight;
|
||||
ffloor[numffloors].polyobj = po;
|
||||
@@ -1099,7 +1099,7 @@ static void R_Subsector(size_t num)
|
||||
(light == -1 ? frontsector->lightlevel : *frontsector->lightlist[light].lightlevel), polysec->ceiling_xoffs, polysec->ceiling_yoffs, polysec->ceilingpic_angle-po->angle,
|
||||
(light == -1 ? frontsector->extra_colormap : frontsector->lightlist[light].extra_colormap), NULL, po
|
||||
,NULL // will ffloors be slopable eventually?
|
||||
, R_NoEncore(polysec, true));
|
||||
, R_NoEncore(polysec, true), false, frontsector);
|
||||
|
||||
ffloor[numffloors].polyobj = po;
|
||||
ffloor[numffloors].height = polysec->ceilingheight;
|
||||
@@ -1317,7 +1317,6 @@ void R_RenderBSPNode(INT32 bspnum)
|
||||
|
||||
// Decide which side the view point is on.
|
||||
side = R_PointOnSideFast(viewx, viewy, bsp);
|
||||
|
||||
// Recursively divide front space.
|
||||
R_RenderBSPNode(bsp->children[side]);
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@
|
||||
#include "d_main.h"
|
||||
#include "v_video.h"
|
||||
#include "p_spec.h" // skyboxmo
|
||||
#include "p_setup.h"
|
||||
#include "z_zone.h"
|
||||
#include "m_random.h" // quake camera shake
|
||||
#include "r_portal.h"
|
||||
@@ -160,6 +161,8 @@ void SendWeaponPref2(void);
|
||||
void SendWeaponPref3(void);
|
||||
void SendWeaponPref4(void);
|
||||
|
||||
static void DirLight_OnChange(void);
|
||||
|
||||
static void Precipstuff_OnChange(void);
|
||||
|
||||
consvar_t cv_tailspickup = {"tailspickup", "On", CV_NETVAR|CV_NOSHOWHELP, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
@@ -208,6 +211,15 @@ consvar_t cv_homremoval = {"homremoval", "Yes", CV_SAVE, homremoval_cons_t, NULL
|
||||
|
||||
consvar_t cv_maxportals = {"maxportals", "2", CV_SAVE, maxportals_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
// randomized directional lightning
|
||||
consvar_t cv_randomdirlight = {"randomdirectionallight", "Off", CV_SAVE|CV_CALL|CV_NOINIT, CV_OnOff, DirLight_OnChange, 0, NULL, NULL, 0, 0, NULL};
|
||||
|
||||
// tells to reset the maplight at next map change
|
||||
static void DirLight_OnChange(void)
|
||||
{
|
||||
reinitmaplight = true;
|
||||
}
|
||||
|
||||
void SplitScreen_OnChange(void)
|
||||
{
|
||||
UINT8 i;
|
||||
@@ -1585,6 +1597,8 @@ void R_RegisterEngineStuff(void)
|
||||
|
||||
CV_RegisterVar(&cv_maxportals);
|
||||
|
||||
CV_RegisterVar(&cv_randomdirlight);
|
||||
|
||||
CV_RegisterVar(&cv_maxinterpdist);
|
||||
|
||||
CV_RegisterVar(&cv_ripplewater);
|
||||
|
||||
@@ -188,6 +188,8 @@ extern consvar_t cv_tailspickup;
|
||||
extern consvar_t cv_maxinterpdist;
|
||||
extern consvar_t cv_ripplewater;
|
||||
|
||||
extern consvar_t cv_randomdirlight;
|
||||
|
||||
// Called by startup code.
|
||||
void R_Init(void);
|
||||
|
||||
|
||||
+11
-3
@@ -350,7 +350,8 @@ visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel,
|
||||
ffloor_t *pfloor
|
||||
, polyobj_t *polyobj
|
||||
, pslope_t *slope
|
||||
, boolean noencore)
|
||||
, boolean noencore
|
||||
, boolean reverseLight, const sector_t *lighting_sector)
|
||||
{
|
||||
visplane_t *check;
|
||||
unsigned hash;
|
||||
@@ -387,9 +388,16 @@ visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel,
|
||||
}
|
||||
}
|
||||
|
||||
if (slope != NULL)
|
||||
if (slope != NULL && P_ApplyLightOffset(lightlevel >> LIGHTSEGSHIFT, lighting_sector))
|
||||
{
|
||||
lightlevel += slope->lightOffset * 8;
|
||||
if (reverseLight)
|
||||
{
|
||||
lightlevel -= slope->lightOffset * 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
lightlevel += slope->lightOffset * 8;
|
||||
}
|
||||
}
|
||||
|
||||
// This appears to fix the Nimbus Ruins sky bug.
|
||||
|
||||
+2
-1
@@ -87,7 +87,8 @@ visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel, fixed_t
|
||||
extracolormap_t *planecolormap, ffloor_t *ffloor
|
||||
, polyobj_t *polyobj
|
||||
, pslope_t *slope
|
||||
, boolean noencore);
|
||||
, boolean noencore
|
||||
, boolean reverseLight, const sector_t *lighting_sector);
|
||||
visplane_t *R_CheckPlane(visplane_t *pl, INT32 start, INT32 stop);
|
||||
void R_ExpandPlane(visplane_t *pl, INT32 start, INT32 stop);
|
||||
void R_PlaneBounds(visplane_t *plane);
|
||||
|
||||
+8
-6
@@ -23,6 +23,7 @@
|
||||
#include "d_netcmd.h"
|
||||
#include "m_misc.h"
|
||||
#include "p_local.h" // Camera...
|
||||
#include "p_setup.h"
|
||||
#include "p_slopes.h"
|
||||
#include "console.h" // con_clipviewtop
|
||||
|
||||
@@ -434,7 +435,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
|
||||
|
||||
if (rlight->extra_colormap && rlight->extra_colormap->fog)
|
||||
;
|
||||
else
|
||||
else if (P_ApplyLightOffset(lightnum, frontsector))
|
||||
lightnum += curline->lightOffset;
|
||||
|
||||
rlight->lightnum = lightnum;
|
||||
@@ -455,7 +456,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
|
||||
if (colfunc == R_DrawFogColumn_8
|
||||
|| (frontsector->extra_colormap && frontsector->extra_colormap->fog))
|
||||
;
|
||||
else
|
||||
else if (P_ApplyLightOffset(lightnum, frontsector))
|
||||
lightnum += curline->lightOffset;
|
||||
|
||||
if (lightnum < 0)
|
||||
@@ -849,7 +850,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
|
||||
|
||||
if (pfloor->flags & FF_FOG || rlight->flags & FF_FOG || (rlight->extra_colormap && rlight->extra_colormap->fog))
|
||||
;
|
||||
else
|
||||
else if (P_ApplyLightOffset(rlight->lightnum, frontsector))
|
||||
rlight->lightnum += curline->lightOffset;
|
||||
|
||||
p++;
|
||||
@@ -872,7 +873,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
|
||||
|
||||
if (pfloor->flags & FF_FOG || (frontsector->extra_colormap && frontsector->extra_colormap->fog))
|
||||
;
|
||||
else
|
||||
else if (P_ApplyLightOffset(lightnum, frontsector))
|
||||
lightnum += curline->lightOffset;
|
||||
|
||||
if (lightnum < 0)
|
||||
@@ -1427,7 +1428,7 @@ static void R_RenderSegLoop (void)
|
||||
|
||||
if (dc_lightlist[i].extra_colormap)
|
||||
;
|
||||
else
|
||||
else if (P_ApplyLightOffset(lightnum, curline->frontsector))
|
||||
lightnum += curline->lightOffset;
|
||||
|
||||
if (lightnum < 0)
|
||||
@@ -2426,7 +2427,8 @@ void R_StoreWallRange(INT32 start, INT32 stop)
|
||||
// OPTIMIZE: get rid of LIGHTSEGSHIFT globally
|
||||
lightnum = (frontsector->lightlevel >> LIGHTSEGSHIFT);
|
||||
|
||||
lightnum += curline->lightOffset;
|
||||
if (P_ApplyLightOffset(lightnum, frontsector))
|
||||
lightnum += curline->lightOffset;
|
||||
|
||||
if (lightnum < 0)
|
||||
walllights = scalelight[0];
|
||||
|
||||
+97
-15
@@ -27,6 +27,7 @@
|
||||
#include "r_plane.h"
|
||||
#include "p_tick.h"
|
||||
#include "p_local.h"
|
||||
#include "p_setup.h"
|
||||
#include "p_slopes.h"
|
||||
#include "dehacked.h" // get_number (for thok)
|
||||
#include "d_netfil.h" // blargh. for nameonly().
|
||||
@@ -108,6 +109,13 @@ static drawseg_xrange_item_t *drawsegs_xrange;
|
||||
static size_t drawsegs_xrange_size = 0;
|
||||
static INT32 drawsegs_xrange_count = 0;
|
||||
|
||||
INT32 R_ThingLightLevel(mobj_t* thing)
|
||||
{
|
||||
INT32 lightlevel = thing->lightlevel;
|
||||
|
||||
return lightlevel;
|
||||
}
|
||||
|
||||
// ==========================================================================
|
||||
//
|
||||
// Sprite loading routines: support sprites in pwad, dehacked sprite renaming,
|
||||
@@ -1113,6 +1121,26 @@ fixed_t R_GetShadowZ(mobj_t *thing, pslope_t **shadowslope)
|
||||
#undef CHECKZ
|
||||
}
|
||||
|
||||
fixed_t R_GetSpriteDirectionalLighting(angle_t angle)
|
||||
{
|
||||
// Copied from P_UpdateSegLightOffset
|
||||
const UINT8 contrast = min(max(0, maplighting.contrast - maplighting.backlight), UINT8_MAX);
|
||||
const fixed_t contrastFixed = ((fixed_t)contrast) * FRACUNIT;
|
||||
|
||||
fixed_t light = FRACUNIT;
|
||||
fixed_t extralight = 0;
|
||||
|
||||
light = FixedMul(FINECOSINE(angle >> ANGLETOFINESHIFT), FINECOSINE(maplighting.angle >> ANGLETOFINESHIFT))
|
||||
+ FixedMul(FINESINE(angle >> ANGLETOFINESHIFT), FINESINE(maplighting.angle >> ANGLETOFINESHIFT));
|
||||
light = (light + FRACUNIT) / 2;
|
||||
|
||||
light = FixedMul(light, FRACUNIT - FSIN(abs(AngleDeltaSigned(angle, maplighting.angle)) / 2));
|
||||
|
||||
extralight = -contrastFixed + FixedMul(light, contrastFixed * 2);
|
||||
|
||||
return extralight;
|
||||
}
|
||||
|
||||
//
|
||||
// R_ProjectSprite
|
||||
// Generates a vissprite for a thing
|
||||
@@ -1151,11 +1179,14 @@ static void R_ProjectSprite(mobj_t *thing)
|
||||
fixed_t offset, offset2;
|
||||
fixed_t paperoffset = 0, paperdistance = 0; angle_t centerangle = 0;
|
||||
|
||||
INT32 lightnum;
|
||||
|
||||
//SoM: 3/17/2000
|
||||
fixed_t gz, gzt;
|
||||
INT32 heightsec, phs;
|
||||
INT32 dist = -1;
|
||||
INT32 light = 0;
|
||||
lighttable_t **lights_array = spritelights;
|
||||
fixed_t this_scale;
|
||||
fixed_t spritexscale, spriteyscale;
|
||||
|
||||
@@ -1587,28 +1618,79 @@ static void R_ProjectSprite(mobj_t *thing)
|
||||
return;
|
||||
}
|
||||
|
||||
if (thing->subsector->sector->numlights)
|
||||
if (oldthing->frame & FF_ABSOLUTELIGHTLEVEL)
|
||||
{
|
||||
INT32 lightnum;
|
||||
light = thing->subsector->sector->numlights - 1;
|
||||
const UINT8 n = R_ThingLightLevel(oldthing);
|
||||
|
||||
for (lightnum = 1; lightnum < thing->subsector->sector->numlights; lightnum++) {
|
||||
fixed_t h = thing->subsector->sector->lightlist[lightnum].slope ? P_GetZAt(thing->subsector->sector->lightlist[lightnum].slope, interp.x, interp.y)
|
||||
: thing->subsector->sector->lightlist[lightnum].height;
|
||||
if (h <= gzt)
|
||||
// n = uint8 aka 0 - 255, so the shift will always be 0 - LIGHTLEVELS - 1
|
||||
lights_array = scalelight[n >> LIGHTSEGSHIFT];
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
if (thing->subsector->sector->numlights)
|
||||
{
|
||||
light = thing->subsector->sector->numlights - 1;
|
||||
|
||||
for (lightnum = 1; lightnum < thing->subsector->sector->numlights; lightnum++) {
|
||||
fixed_t h = thing->subsector->sector->lightlist[lightnum].slope ? P_GetZAt(thing->subsector->sector->lightlist[lightnum].slope, interp.x, interp.y)
|
||||
: thing->subsector->sector->lightlist[lightnum].height;
|
||||
if (h <= gzt)
|
||||
{
|
||||
light = lightnum - 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
lightnum = *thing->subsector->sector->lightlist[light].lightlevel;
|
||||
}
|
||||
else
|
||||
{
|
||||
lightnum = thing->subsector->sector->lightlevel;
|
||||
}
|
||||
|
||||
lightnum = (lightnum + R_ThingLightLevel(thing)) >> LIGHTSEGSHIFT;
|
||||
|
||||
if (maplighting.directional == true && P_SectorUsesDirectionalLighting(thing->subsector->sector))
|
||||
{
|
||||
fixed_t extralight = R_GetSpriteDirectionalLighting(papersprite
|
||||
? interp.angle + (ang >= ANGLE_180 ? -ANGLE_90 : ANGLE_90)
|
||||
: R_PointToAngle(interp.x, interp.y));
|
||||
|
||||
// Krangle contrast in 3P/4P because scalelight
|
||||
// scales differently depending on the screen
|
||||
// width (which is halved in 3P/4P).
|
||||
if (splitscreen > 1)
|
||||
{
|
||||
light = lightnum - 1;
|
||||
break;
|
||||
extralight *= 2;
|
||||
}
|
||||
|
||||
// Less change in contrast in dark sectors
|
||||
extralight = FixedMul(extralight, min(max(0, lightnum), LIGHTLEVELS - 1) * FRACUNIT / (LIGHTLEVELS - 1));
|
||||
|
||||
if (papersprite)
|
||||
{
|
||||
// Papersprite contrast should match walls
|
||||
lightnum += FixedFloor((extralight / 8) + (FRACUNIT / 2)) / FRACUNIT;
|
||||
}
|
||||
else
|
||||
{
|
||||
fixed_t n = FixedDiv(FixedMul(xscale, LIGHTRESOLUTIONFIX), ((MAXLIGHTSCALE-1) << LIGHTSCALESHIFT));
|
||||
|
||||
// Less change in contrast at further distances, to counteract DOOM diminished light
|
||||
extralight = FixedMul(extralight, min(n, FRACUNIT));
|
||||
|
||||
// Contrast is stronger for normal sprites, stronger than wall lighting is at the same distance
|
||||
lightnum += FixedFloor((extralight / 4) + (FRACUNIT / 2)) / FRACUNIT;
|
||||
}
|
||||
}
|
||||
lightnum = (*thing->subsector->sector->lightlist[light].lightlevel >> LIGHTSEGSHIFT);
|
||||
|
||||
if (lightnum < 0)
|
||||
spritelights = scalelight[0];
|
||||
lights_array = scalelight[0];
|
||||
else if (lightnum >= LIGHTLEVELS)
|
||||
spritelights = scalelight[LIGHTLEVELS-1];
|
||||
lights_array = scalelight[LIGHTLEVELS-1];
|
||||
else
|
||||
spritelights = scalelight[lightnum];
|
||||
lights_array = scalelight[lightnum];
|
||||
}
|
||||
|
||||
heightsec = thing->subsector->sector->heightsec;
|
||||
@@ -1736,7 +1818,7 @@ static void R_ProjectSprite(mobj_t *thing)
|
||||
if (vis->cut & SC_SEMIBRIGHT)
|
||||
lindex = (MAXLIGHTSCALE/2) + (lindex >> 1);
|
||||
|
||||
vis->colormap = spritelights[lindex];
|
||||
vis->colormap = lights_array[lindex];
|
||||
}
|
||||
|
||||
vis->precip = false;
|
||||
@@ -2026,7 +2108,7 @@ void R_AddPrecipitationSprites(void)
|
||||
{
|
||||
for (th = precipblocklinks[(by * bmapwidth) + bx]; th; th = next)
|
||||
{
|
||||
// Store this beforehand because R_ProjectPrecipitionSprite may free th (see P_PrecipThinker)
|
||||
// Store this beforehand because R_ProjectPrecipitationSprite may free th (see P_PrecipThinker)
|
||||
next = th->bnext;
|
||||
|
||||
if (th->precipflags & PCF_INVISIBLE)
|
||||
|
||||
@@ -57,6 +57,9 @@ extern fixed_t windowtop;
|
||||
extern fixed_t windowbottom;
|
||||
extern INT32 lengthcol;
|
||||
|
||||
INT32 R_ThingLightLevel(mobj_t *thing);
|
||||
fixed_t R_GetSpriteDirectionalLighting(angle_t angle);
|
||||
|
||||
fixed_t R_GetShadowZ(mobj_t *thing, pslope_t **shadowslope);
|
||||
|
||||
void R_DrawMaskedColumn(column_t *column);
|
||||
|
||||
+1
-4
@@ -423,10 +423,7 @@ static INT32 S_ScaleVolumeWithSplitscreen(INT32 volume)
|
||||
|
||||
root = FixedSqrt((splitscreen + 1) * (FRACUNIT/3));
|
||||
|
||||
return FixedDiv(
|
||||
volume * FRACUNIT,
|
||||
root
|
||||
) / FRACUNIT;
|
||||
return FixedDiv(volume * FRACUNIT, root) / FRACUNIT;
|
||||
}
|
||||
|
||||
void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume)
|
||||
|
||||
+6
-1
@@ -176,13 +176,18 @@ fixed_t *finecosine = &finesine[FINEANGLES/4];
|
||||
|
||||
#include "t_facon.c"
|
||||
|
||||
|
||||
FUNCMATH angle_t FixedAcos(fixed_t x)
|
||||
{
|
||||
if (-FRACUNIT > x || x >= FRACUNIT) return 0;
|
||||
return fineacon[((x<<(FINE_FRACBITS-FRACBITS)))+FRACUNIT];
|
||||
}
|
||||
|
||||
INT32 AngleDeltaSigned(angle_t a1, angle_t a2)
|
||||
{
|
||||
// Silly but easy way to do it through integer conversion.
|
||||
return (INT32)(a1) - (INT32)(a2);
|
||||
}
|
||||
|
||||
//
|
||||
// AngleBetweenVectors
|
||||
//
|
||||
|
||||
@@ -110,6 +110,8 @@ FUNCMATH angle_t FixedAngleC(fixed_t fa, fixed_t factor);
|
||||
/// The FixedAcos function
|
||||
FUNCMATH angle_t FixedAcos(fixed_t x);
|
||||
|
||||
FUNCMATH INT32 AngleDeltaSigned(angle_t a1, angle_t a2);
|
||||
|
||||
/// Fixed Point Vector functions
|
||||
angle_t FV2_AngleBetweenVectors(const vector2_t *Vector1, const vector2_t *Vector2);
|
||||
angle_t FV3_AngleBetweenVectors(const vector3_t *Vector1, const vector3_t *Vector2);
|
||||
|
||||
Reference in new issue
Block a user