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_skins.c
r_sky.c r_sky.c
r_splats.c r_splats.c
r_spritefx.cpp
r_things.c r_things.c
r_bbox.c r_bbox.c
r_textures.c r_textures.c

View file

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

View file

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

View file

@ -312,6 +312,7 @@ struct mobj_t
fixed_t old_spritexscale, old_spriteyscale; fixed_t old_spritexscale, old_spriteyscale;
fixed_t old_spritexoffset, old_spriteyoffset; fixed_t old_spritexoffset, old_spriteyoffset;
pslope_t *floorspriteslope; // The slope that the floorsprite is rotated by 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 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_spritexscale, old_spriteyscale;
fixed_t old_spritexoffset, old_spriteyoffset; fixed_t old_spritexoffset, old_spriteyoffset;
pslope_t *floorspriteslope; // The slope that the floorsprite is rotated by 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 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_LASTMOMZ = 1<<28,
MD2_TERRAIN = 1<<29, MD2_TERRAIN = 1<<29,
MD2_WATERSKIP = 1<<30, MD2_WATERSKIP = 1<<30,
MD2_LIGHTLEVEL = (INT32)(1U<<31),
} mobj_diff2_t; } mobj_diff2_t;
typedef enum typedef enum
@ -2466,6 +2467,8 @@ static void SaveMobjThinker(savebuffer_t *save, const thinker_t *th, const UINT8
|| (slope->normal.z != FRACUNIT)) || (slope->normal.z != FRACUNIT))
diff2 |= MD2_FLOORSPRITESLOPE; diff2 |= MD2_FLOORSPRITESLOPE;
} }
if (mobj->lightlevel)
diff2 |= MD2_LIGHTLEVEL;
if (mobj->hitlag) if (mobj->hitlag)
diff2 |= MD2_HITLAG; diff2 |= MD2_HITLAG;
if (mobj->waterskip) 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.y);
WRITEFIXED(save->p, slope->normal.z); WRITEFIXED(save->p, slope->normal.z);
} }
if (diff2 & MD2_LIGHTLEVEL)
{
WRITEINT16(save->p, mobj->lightlevel);
}
if (diff2 & MD2_HITLAG) if (diff2 & MD2_HITLAG)
{ {
WRITEINT32(save->p, mobj->hitlag); WRITEINT32(save->p, mobj->hitlag);
@ -3834,6 +3841,10 @@ static thinker_t* LoadMobjThinker(savebuffer_t *save, actionf_p1 thinker)
P_UpdateSlopeLightOffset(slope); P_UpdateSlopeLightOffset(slope);
} }
if (diff2 & MD2_LIGHTLEVEL)
{
mobj->lightlevel = READINT16(save->p);
}
if (diff2 & MD2_HITLAG) if (diff2 & MD2_HITLAG)
{ {
mobj->hitlag = READINT32(save->p); mobj->hitlag = READINT32(save->p);

View file

@ -961,6 +961,8 @@ typedef enum
RF_SHADOWEFFECTS = 0x00008000, // Scales and becomes transparent like a shadow. RF_SHADOWEFFECTS = 0x00008000, // Scales and becomes transparent like a shadow.
RF_DROPSHADOW = (RF_SHADOWDRAW | RF_SHADOWEFFECTS | RF_FULLDARK), 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_DONTDRAW = 0x00F00000, // --Don't generate a vissprite
RF_DONTDRAWP1 = 0x00100000, // No P1 RF_DONTDRAWP1 = 0x00100000, // No P1
RF_DONTDRAWP2 = 0x00200000, // No P2 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; fixed_t gz = 0, gzt = 0;
INT32 heightsec, phs; INT32 heightsec, phs;
INT32 light = 0; INT32 light = 0;
lighttable_t **lights_array = spritelights;
fixed_t this_scale; fixed_t this_scale;
fixed_t spritexscale, spriteyscale; fixed_t spritexscale, spriteyscale;
@ -2239,29 +2240,46 @@ static void R_ProjectSprite(mobj_t *thing)
return; 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; INT32 lightnum;
fixed_t top = (splat) ? gz : gzt;
light = thing->subsector->sector->numlights - 1;
// R_GetPlaneLight won't work on sloped lights! if (thing->subsector->sector->numlights)
for (lightnum = 1; lightnum < thing->subsector->sector->numlights; lightnum++) { {
fixed_t h = P_GetLightZAt(&thing->subsector->sector->lightlist[lightnum], interp.x, interp.y); fixed_t top = (splat) ? gz : gzt;
if (h <= top) { light = thing->subsector->sector->numlights - 1;
light = lightnum - 1;
break; // 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); else
lightnum = (*thing->subsector->sector->lightlist[light].lightlevel >> LIGHTSEGSHIFT); {
lightnum = thing->subsector->sector->lightlevel;
}
lightnum = (lightnum + R_ThingLightLevel(thing)) >> LIGHTSEGSHIFT;
if (lightnum < 0) if (lightnum < 0)
spritelights = scalelight[0]; lights_array = scalelight[0];
else if (lightnum >= LIGHTLEVELS) else if (lightnum >= LIGHTLEVELS)
spritelights = scalelight[LIGHTLEVELS-1]; lights_array = scalelight[LIGHTLEVELS-1];
else else
spritelights = scalelight[lightnum]; lights_array = scalelight[lightnum];
} }
heightsec = thing->subsector->sector->heightsec; heightsec = thing->subsector->sector->heightsec;
@ -2414,7 +2432,7 @@ static void R_ProjectSprite(mobj_t *thing)
if (vis->cut & SC_SEMIBRIGHT) if (vis->cut & SC_SEMIBRIGHT)
lindex = (MAXLIGHTSCALE/2) + (lindex >> 1); lindex = (MAXLIGHTSCALE/2) + (lindex >> 1);
vis->colormap = spritelights[lindex]; vis->colormap = lights_array[lindex];
} }
if (vflip) if (vflip)
@ -2425,7 +2443,7 @@ static void R_ProjectSprite(mobj_t *thing)
vis->patch = patch; vis->patch = patch;
vis->bright = R_CacheSpriteBrightMap(sprinfo, frame); 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); R_SplitSprite(vis);
if (oldthing->shadowscale && cv_shadow.value) if (oldthing->shadowscale && cv_shadow.value)

View file

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