Compare commits

...
Author SHA1 Message Date
Alug 7d1eb398cf goddamit 2025-03-16 12:24:47 +01:00
Alug 97df54a760 oops 2025-03-16 12:24:08 +01:00
Alug 2edada8ce3 slight cleanup HWR_ObjectLightLevelPost 2025-03-16 12:18:20 +01:00
Alug 17e85df813 changes from testing branch 2025-03-16 11:55:10 +01:00
Alug a3b5c4dff8 Merge branch 'Saturn-Next' into directionallight 2025-03-16 11:52:38 +01:00
Alug 2b13af2367 setup maplight stuff earlier
otherwise it doesent init early enough
2025-01-25 08:41:22 +01:00
Alug ff895f3251 fix frame flag clash 2025-01-11 19:54:28 +01:00
Alug 130c1aba67 put random direction light toggle into advanced video options
also make it a scoll menu
2025-01-11 18:10:24 +01:00
Alug a07c2f4c32 reinit random maplight on mapchange when toggled
the condition may otherwise not change the light if you restart the same map
2025-01-11 08:52:49 +01:00
Alug 96b7a4efe6 add FF_ABSOLUTELIGHTLEVEL
mobj_t.lightlevel is absolute instead of relative when set
2025-01-11 08:33:02 +01:00
Alug 124b2ff431 add encore variants of maplight 2025-01-11 08:32:59 +01:00
Alug c1ec72e606 oops 2025-01-11 08:28:57 +01:00
Alug ef1faf9f68 those somehow got lost 2025-01-11 08:26:12 +01:00
Alug 02595b9ea6 forgor this 2025-01-11 07:50:25 +01:00
Alug c1514635b0 if disabled and no soc overrides light behave like vanilla
always apply wall and slope contrast pls
2025-01-11 07:50:22 +01:00
Alug e5e7205c95 change how randomized light works
so it doesent kill actual soc set randomlight if you toggle it
2025-01-11 07:26:44 +01:00
Alug f8d1bf0811 Merge branch 'Saturn-Next' into directionallight 2025-01-11 07:26:37 +01:00
Alug d2ca916043 settable mobj lightlevel from lua 2024-12-22 20:58:23 +01:00
Alug 09e901b31b readd mobj lightlevel field so i dont have to edit frameflags 2024-12-22 20:58:20 +01:00
Alug 8bd943eb71 Merge remote-tracking branch 'origin/Saturn-Next' into directionallight 2024-12-22 18:57:38 +01:00
Alug d8fe3920b1 fix papersprite lightlevels again kek + remove shit that does nothing 2024-12-14 17:14:20 +01:00
Alug a920556feb fix papersprite directional light
uhhh idk??
also passes papersprite bool directly instead of rechecking every frame for it
2024-12-14 16:53:23 +01:00
Alug 351cb4a1ac Merge branch 'Saturn-Next' into directionallight 2024-12-14 16:53:20 +01:00
Alug 9d1bef9ab9 i love menus 2024-12-09 10:19:32 +01:00
Alug feeb2d0f1a use early return
no need to check for all this crap if we can use it anyways
2024-12-08 04:39:12 +01:00
Alug 13a5909c3f oop 2024-12-08 04:13:16 +01:00
Alug 40be4d25a5 menu oopsie 2024-12-08 04:07:05 +01:00
Alug d84f887be8 clear maplight on toggling
so you only have to wait until nextmap for effect to do smth instead of game restart
2024-12-08 04:07:03 +01:00
Alug bc29d77aff menu entry 2024-12-08 03:31:53 +01:00
Alug 8db2e646db oop 2024-12-08 03:28:44 +01:00
Alug 3b2e207b6b make random directionallight toggable 2024-12-08 03:27:45 +01:00
Alug f061d66a16 conflict fix 2024-12-08 03:24:58 +01:00
Alug 8c295e8d5f port rr´s directional light 2024-12-08 03:22:34 +01:00
31 changed files with 651 additions and 139 deletions

No files matched your search

+43
View File
@@ -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"))
+21
View File
@@ -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;
+2
View File
@@ -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
+7 -1
View File
@@ -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;
+6
View File
@@ -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;
+2
View File
@@ -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
View File
@@ -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
+1 -1
View File
@@ -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);
+4 -2
View File
@@ -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
{
+1 -1
View File
@@ -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},
+36 -2
View File
@@ -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" \
+48 -1
View File
@@ -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
View File
@@ -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;
+1
View File
@@ -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
View File
@@ -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
+2
View File
@@ -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;
+3
View File
@@ -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
View File
@@ -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)];
+6
View File
@@ -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
View File
@@ -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
View File
@@ -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]);
+14
View File
@@ -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);
+2
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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)
+3
View File
@@ -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
View File
@@ -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
View File
@@ -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
//
+2
View File
@@ -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);