Add lightlevel field to mobj_t

Adds r_spritefx.cpp

lightlevel should be -255 to 255, relative offset to
normal sector lightlevel.

If RF_ABSOLUTELIGHTLEVEL, mobj_t.lightlevel becomes an
absolute lightlevel in the range 0 to 255.
This commit is contained in:
James R 2023-06-05 16:36:24 -07:00
parent 50a6896cce
commit 018f6f3410
9 changed files with 79 additions and 16 deletions

View file

@ -75,6 +75,7 @@ add_executable(SRB2SDL2 MACOSX_BUNDLE WIN32
r_skins.c
r_sky.c
r_splats.c
r_spritefx.cpp
r_things.c
r_bbox.c
r_textures.c

View file

@ -6323,6 +6323,7 @@ struct int_const_s const INT_CONST[] = {
{"RF_SHADOWDRAW",RF_SHADOWDRAW},
{"RF_SHADOWEFFECTS",RF_SHADOWEFFECTS},
{"RF_DROPSHADOW",RF_DROPSHADOW},
{"RF_ABSOLUTELIGHTLEVEL",RF_ABSOLUTELIGHTLEVEL},
{"RF_DONTDRAW",RF_DONTDRAW},
{"RF_DONTDRAWP1",RF_DONTDRAWP1},
{"RF_DONTDRAWP2",RF_DONTDRAWP2},

View file

@ -42,6 +42,7 @@ enum mobj_e {
mobj_spritexoffset,
mobj_spriteyoffset,
mobj_floorspriteslope,
mobj_lightlevel,
mobj_touching_sectorlist,
mobj_subsector,
mobj_floorz,
@ -124,6 +125,7 @@ static const char *const mobj_opt[] = {
"spritexoffset",
"spriteyoffset",
"floorspriteslope",
"lightlevel",
"touching_sectorlist",
"subsector",
"floorz",
@ -266,6 +268,9 @@ static int mobj_get(lua_State *L)
case mobj_floorspriteslope:
LUA_PushUserdata(L, mo->floorspriteslope, META_SLOPE);
break;
case mobj_lightlevel:
lua_pushinteger(L, mo->lightlevel);
break;
case mobj_touching_sectorlist:
return UNIMPLEMENTED;
case mobj_subsector:
@ -569,6 +574,9 @@ static int mobj_set(lua_State *L)
break;
case mobj_floorspriteslope:
return NOSET;
case mobj_lightlevel:
mo->lightlevel = (INT16)luaL_checkinteger(L, 3);
break;
case mobj_touching_sectorlist:
return UNIMPLEMENTED;
case mobj_subsector:

View file

@ -312,6 +312,7 @@ struct mobj_t
fixed_t old_spritexscale, old_spriteyscale;
fixed_t old_spritexoffset, old_spriteyoffset;
pslope_t *floorspriteslope; // The slope that the floorsprite is rotated by
INT16 lightlevel; // Add to sector lightlevel, -255 - 255
msecnode_t *touching_sectorlist; // a linked list of sectors where this object appears
@ -469,6 +470,7 @@ struct precipmobj_t
fixed_t old_spritexscale, old_spriteyscale;
fixed_t old_spritexoffset, old_spriteyoffset;
pslope_t *floorspriteslope; // The slope that the floorsprite is rotated by
INT16 lightlevel; // Add to sector lightlevel, -255 - 255
mprecipsecnode_t *touching_sectorlist; // a linked list of sectors where this object appears

View file

@ -2228,6 +2228,7 @@ typedef enum
MD2_LASTMOMZ = 1<<28,
MD2_TERRAIN = 1<<29,
MD2_WATERSKIP = 1<<30,
MD2_LIGHTLEVEL = (INT32)(1U<<31),
} mobj_diff2_t;
typedef enum
@ -2466,6 +2467,8 @@ static void SaveMobjThinker(savebuffer_t *save, const thinker_t *th, const UINT8
|| (slope->normal.z != FRACUNIT))
diff2 |= MD2_FLOORSPRITESLOPE;
}
if (mobj->lightlevel)
diff2 |= MD2_LIGHTLEVEL;
if (mobj->hitlag)
diff2 |= MD2_HITLAG;
if (mobj->waterskip)
@ -2675,6 +2678,10 @@ static void SaveMobjThinker(savebuffer_t *save, const thinker_t *th, const UINT8
WRITEFIXED(save->p, slope->normal.y);
WRITEFIXED(save->p, slope->normal.z);
}
if (diff2 & MD2_LIGHTLEVEL)
{
WRITEINT16(save->p, mobj->lightlevel);
}
if (diff2 & MD2_HITLAG)
{
WRITEINT32(save->p, mobj->hitlag);
@ -3834,6 +3841,10 @@ static thinker_t* LoadMobjThinker(savebuffer_t *save, actionf_p1 thinker)
P_UpdateSlopeLightOffset(slope);
}
if (diff2 & MD2_LIGHTLEVEL)
{
mobj->lightlevel = READINT16(save->p);
}
if (diff2 & MD2_HITLAG)
{
mobj->hitlag = READINT32(save->p);

View file

@ -961,6 +961,8 @@ typedef enum
RF_SHADOWEFFECTS = 0x00008000, // Scales and becomes transparent like a shadow.
RF_DROPSHADOW = (RF_SHADOWDRAW | RF_SHADOWEFFECTS | RF_FULLDARK),
RF_ABSOLUTELIGHTLEVEL = 0x00010000, // mobj_t.lightlevel is absolute instead of relative
RF_DONTDRAW = 0x00F00000, // --Don't generate a vissprite
RF_DONTDRAWP1 = 0x00100000, // No P1
RF_DONTDRAWP2 = 0x00200000, // No P2

18
src/r_spritefx.cpp Normal file
View file

@ -0,0 +1,18 @@
// DR. ROBOTNIK'S RING RACERS
//-----------------------------------------------------------------------------
// Copyright (C) 2023 by Kart Krew.
//
// This program is free software distributed under the
// terms of the GNU General Public License, version 2.
// See the 'LICENSE' file for more details.
//-----------------------------------------------------------------------------
/// \brief Special effects for sprite rendering
#include "r_things.h"
INT32 R_ThingLightLevel(mobj_t* thing)
{
INT32 lightlevel = thing->lightlevel;
return lightlevel;
}

View file

@ -1690,6 +1690,7 @@ static void R_ProjectSprite(mobj_t *thing)
fixed_t gz = 0, gzt = 0;
INT32 heightsec, phs;
INT32 light = 0;
lighttable_t **lights_array = spritelights;
fixed_t this_scale;
fixed_t spritexscale, spriteyscale;
@ -2239,29 +2240,46 @@ static void R_ProjectSprite(mobj_t *thing)
return;
}
if (thing->subsector->sector->numlights)
if (thing->renderflags & RF_ABSOLUTELIGHTLEVEL)
{
const UINT8 n = R_ThingLightLevel(thing);
// n = uint8 aka 0 - 255, so the shift will always be 0 - LIGHTLEVELS - 1
lights_array = scalelight[n >> LIGHTSEGSHIFT];
}
else
{
INT32 lightnum;
fixed_t top = (splat) ? gz : gzt;
light = thing->subsector->sector->numlights - 1;
// R_GetPlaneLight won't work on sloped lights!
for (lightnum = 1; lightnum < thing->subsector->sector->numlights; lightnum++) {
fixed_t h = P_GetLightZAt(&thing->subsector->sector->lightlist[lightnum], interp.x, interp.y);
if (h <= top) {
light = lightnum - 1;
break;
if (thing->subsector->sector->numlights)
{
fixed_t top = (splat) ? gz : gzt;
light = thing->subsector->sector->numlights - 1;
// R_GetPlaneLight won't work on sloped lights!
for (lightnum = 1; lightnum < thing->subsector->sector->numlights; lightnum++) {
fixed_t h = P_GetLightZAt(&thing->subsector->sector->lightlist[lightnum], interp.x, interp.y);
if (h <= top) {
light = lightnum - 1;
break;
}
}
//light = R_GetPlaneLight(thing->subsector->sector, gzt, false);
lightnum = *thing->subsector->sector->lightlist[light].lightlevel;
}
//light = R_GetPlaneLight(thing->subsector->sector, gzt, false);
lightnum = (*thing->subsector->sector->lightlist[light].lightlevel >> LIGHTSEGSHIFT);
else
{
lightnum = thing->subsector->sector->lightlevel;
}
lightnum = (lightnum + R_ThingLightLevel(thing)) >> 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;
@ -2414,7 +2432,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];
}
if (vflip)
@ -2425,7 +2443,7 @@ static void R_ProjectSprite(mobj_t *thing)
vis->patch = patch;
vis->bright = R_CacheSpriteBrightMap(sprinfo, frame);
if (thing->subsector->sector->numlights && !(shadowdraw || splat))
if (thing->subsector->sector->numlights && !(shadowdraw || splat) && !(thing->renderflags & RF_ABSOLUTELIGHTLEVEL))
R_SplitSprite(vis);
if (oldthing->shadowscale && cv_shadow.value)

View file

@ -93,6 +93,8 @@ boolean R_ThingIsFullDark (mobj_t *thing);
boolean R_ThingIsFlashing(mobj_t *thing);
INT32 R_ThingLightLevel(mobj_t *thing);
// --------------
// MASKED DRAWING
// --------------