Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • STJr/SRB2
  • Sryder/SRB2
  • wolfy852/SRB2
  • Alpha2244/SRB2
  • Inuyasha/SRB2
  • yoshibot/SRB2
  • TehRealSalt/SRB2
  • PrisimaTF/SRB2
  • Hatninja/SRB2
  • SteelT/SRB2
  • james/SRB2
  • ShaderWraith/SRB2
  • SinnamonLat/SRB2
  • mazmazz_/SRB2
  • filpAM/SRB2
  • chaoloveicemdboy/SRB2
  • Whooa21/SRB2
  • Machturne/SRB2
  • Golden/SRB2
  • Tatsuru/SRB2
  • Snu/SRB2
  • Zwip-Zwap_Zapony/SRB2
  • fickleheart/SRB2
  • alphaRexJames/SRB2
  • JJK/SRB2
  • diskpoppy/SRB2
  • Hannu_Hanhi/SRB2
  • ZipperQR/SRB2
  • kays/SRB2
  • spherallic/SRB2
  • Zippy_Zolton/SRB2
  • namiishere/SRB2
  • Ors/SRB2
  • SMS_Alfredo/SRB2
  • sonic_edge/SRB2
  • lavla/SRB2
  • ashi/SRB2
  • X.organic/SRB2
  • Fafabis/SRB2
  • Meziu/SRB2
  • v-rob/SRB2
  • tertu/SRB2
  • bitten2up/SRB2
  • flarn2006/SRB2
  • Krabs/SRB2
  • clairebun/SRB2
  • Lactozilla/SRB2
  • thehackstack/SRB2
  • Spice/SRB2
  • win8linux/SRB2
  • JohnFrostFox/SRB2
  • talktoneon726/SRB2
  • Wane/SRB2
  • Lamibe/SRB2
  • spectrumuk2/srb-2
  • nerdyminer18/srb-2
  • 256nil/SRB2
  • ARJr/SRB2
  • Alam/SRB2
  • Zenya/srb-2-marathon-demos
  • Acelite/srb-2-archivedmodifications
  • MIDIMan/SRB2
  • Lach/SRB2
  • Frostiikin/bounce-tweaks
  • Hanicef/SRB2Classic
  • Jaden/SRB2
  • Tyron/SRB2
  • Astronight/SRB2
  • Mari0shi06/SRB2
  • aiire/SRB2
  • Galactice/SRB2
  • srb2-ports/srb2-dreamcast
  • sdasdas/SRB2
  • chreas/srb-2-vr
  • StarManiaKG/the-story-of-sinically-rocketing-and-botching-the-2nd
  • LoganAir/SRB2
  • NepDisk/srb-2
  • alufolie91/SRB2
  • Felicia.iso/SRB2
  • twi/SRB2
  • BarrelsOFun/SRB2
  • Speed2411/SRB2
  • Leather_Realms/SRB2
  • Ayemar/SRB2
  • Acelite/SRB2
  • VladDoc/SRB2
  • kaldrum/model-features
  • strawberryfox417/SRB2
  • Lugent/SRB2
  • Jisk/SRB2
  • Rem/SRB2
  • Refrag/SRB2
  • Henry_3230/srb-3230
  • TehPuertoRicanSpartan2/tprs-srb2
  • Leminn/srb-2-marathon-stuff
  • chromaticpipe2/SRB2
  • MiguelGustavo15/SRB2
  • Maru/srb-2-tests
  • SilicDev/SRB2
  • UnmatchedBracket/SRB2
  • HybridDog/SRB2
  • xordspar0/SRB2
  • jsjhbewfhh/SRB2
  • Fancy2209/SRB2
  • Lorsoen/SRB2
  • shindoukin/SRB2
  • GamerOfDays/SRB2
  • Craftyawesome/SRB2
  • tenshi-tensai-tennoji/SRB2
  • Scarfdudebalder/SRB2
  • luigi-budd/srb-2-fix-interplag-lockon
  • mskluesner/SRB2
  • johnpetersa19/SRB2
  • Pheazant/SRB2
  • chromaticpipe2/srb2classic
  • romoney5/SRB2
  • PAS/SRB2Classic
  • BlueStaggo/SRB2
118 results
Show changes
Commits on Source (54)
Showing with 1125 additions and 53 deletions
File added
File added
......@@ -3,7 +3,7 @@
#
ifndef MINGW64
EXENAME?=srb2win.exe
EXENAME?=srb2rr-2214nightly.exe
else
EXENAME?=srb2win64.exe
endif
......
......@@ -98,3 +98,4 @@ lua_hudlib.c
lua_hudlib_drawlist.c
lua_inputlib.c
lua_colorlib.c
k_brightmap.c
......@@ -1352,6 +1352,12 @@ void readgametype(MYFILE *f, char *gtname)
CONS_Printf("Added gametype %s\n", Gametype_Names[newgtidx]);
}
// rr
static mapheader_lighting_t *usemaplighting(INT32 mapnum)
{
return &mapheaderinfo[mapnum]->lighting;
}
void readlevelheader(MYFILE *f, INT32 num)
{
char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL);
......@@ -1712,6 +1718,31 @@ void readlevelheader(MYFILE *f, INT32 num)
else if (fastcmp(word, "SKYBOXSCALEZ"))
mapheaderinfo[num-1]->skybox_scalez = (INT16)i;
// rr
else if (fastcmp(word, "LIGHTCONTRAST") || fastcmp(word, "ENCORELIGHTCONTRAST"))
{
usemaplighting(num-1)->light_contrast = (UINT8)i;
}
else if (fastcmp(word, "SPRITEBACKLIGHT") || fastcmp(word, "ENCORESPRITEBACKLIGHT"))
{
usemaplighting(num-1)->sprite_backlight = (SINT8)i;
}
else if (fastcmp(word, "LIGHTANGLE") || fastcmp(word, "ENCORELIGHTANGLE"))
{
mapheader_lighting_t *lighting = usemaplighting(num-1);
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)));
}
}
else if (fastcmp(word, "BONUSTYPE"))
{
if (fastcmp(word2, "NONE")) i = -1;
......
......@@ -106,7 +106,7 @@
FILE *fopenfile(const char*, const char*);
//#define NOMD5
#define NOMD5
// If you don't disable ALL debug first, you get ALL debug enabled
#if !defined (NDEBUG)
......@@ -553,6 +553,7 @@ void *M_Memcpy(void* dest, const void* src, size_t n);
char *va(const char *format, ...) FUNCPRINTF;
char *M_GetToken(const char *inputString);
void M_UnGetToken(void);
UINT32 M_GetTokenPos(void); // rr
void M_TokenizerOpen(const char *inputString, size_t len);
void M_TokenizerClose(void);
const char *M_TokenizerRead(UINT32 i);
......
......@@ -291,6 +291,23 @@ typedef struct
char value[256]; // 255 usable characters. If this seriously isn't enough then wtf.
} customoption_t;
// rr
extern struct maplighting
{
UINT8 contrast;
SINT8 backlight;
boolean directional;
angle_t angle;
} maplighting;
typedef struct
{
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
......@@ -361,6 +378,11 @@ typedef struct
SINT8 musforcereset; ///< Force resetmusic (-1 for default; 0 for force off; 1 for force on)
// rr
//fixed_t darkness; ///< Pohbee darkness multiplier
//fixed_t mobj_scale; ///< Defines the size all object calculations are relative to
mapheader_lighting_t lighting; ///< Wall and sprite lighting
// Lua stuff.
// (This is not ifdeffed so the map header structure can stay identical, just in case.)
UINT8 numCustomOptions; ///< Internal. For Lua custom value support.
......
......@@ -235,6 +235,9 @@ UINT32 countdown, countdown2; // for racing
fixed_t gravity;
// rr
struct maplighting maplighting;
INT16 autobalance; //for CTF team balance
INT16 teamscramble; //for CTF team scramble
INT16 scrambleplayers[MAXPLAYERS]; //for CTF team scramble
......
......@@ -17,6 +17,7 @@
// The texture for the next polygon given to HWR_ProcessPolygon.
// Set with HWR_SetCurrentTexture.
GLMipmap_t *current_texture = NULL;
GLMipmap_t *current_brightmap = NULL; // rr
boolean currently_batching = false;
......@@ -61,7 +62,7 @@ void HWR_StartBatching(void)
// This replaces the direct calls to pfnSetTexture in cases where batching is available.
// The texture selection is saved for the next HWR_ProcessPolygon call.
// Doing this was easier than getting a texture pointer to HWR_ProcessPolygon.
void HWR_SetCurrentTexture(GLMipmap_t *texture)
/*void HWR_SetCurrentTexture(GLMipmap_t *texture)
{
if (currently_batching)
{
......@@ -71,6 +72,34 @@ void HWR_SetCurrentTexture(GLMipmap_t *texture)
{
HWD.pfnSetTexture(texture);
}
}*/
// rr
void HWR_SetCurrentTexture(GLMipmap_t *texture)
{
if (currently_batching)
{
if (texture != NULL)
{
if (texture->flags & TF_BRIGHTMAP)
{
current_brightmap = texture;
}
else
{
current_texture = texture;
current_brightmap = NULL;
}
}
else
{
current_texture = current_brightmap = NULL;
}
}
else
{
HWD.pfnSetTexture(texture);
}
}
// If batching is enabled, this function collects the polygon data and the chosen texture
......@@ -114,6 +143,7 @@ void HWR_ProcessPolygon(FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPt
polygonArray[polygonArraySize].numVerts = iNumPts;
polygonArray[polygonArraySize].polyFlags = PolyFlags;
polygonArray[polygonArraySize].texture = current_texture;
polygonArray[polygonArraySize].brightmap = current_brightmap; // rr
polygonArray[polygonArraySize].shader = (shader_target != -1) ? HWR_GetShaderFromTarget(shader_target) : shader_target;
polygonArray[polygonArraySize].horizonSpecial = horizonSpecial;
// default to polygonArraySize so we don't lose order on horizon lines
......@@ -129,6 +159,7 @@ void HWR_ProcessPolygon(FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPt
if (current_texture)
{
DIGEST(hash, current_texture->downloaded);
//DIGEST(hash, current_brightmap->downloaded); // rr
}
DIGEST(hash, PolyFlags);
DIGEST(hash, pSurf->PolyColor.rgba);
......@@ -140,6 +171,7 @@ void HWR_ProcessPolygon(FSurfaceInfo *pSurf, FOutVector *pOutVerts, FUINT iNumPt
DIGEST(hash, pSurf->LightInfo.light_level);
DIGEST(hash, pSurf->LightInfo.fade_start);
DIGEST(hash, pSurf->LightInfo.fade_end);
DIGEST(hash, pSurf->LightInfo.directional); // rr
}
#undef DIGEST
// remove the sign bit to ensure that skybox and horizon line comes first.
......@@ -178,6 +210,8 @@ void HWR_RenderBatches(void)
int nextShader = 0;
GLMipmap_t *currentTexture;
GLMipmap_t *nextTexture = NULL;
GLMipmap_t *currentBrightmap = NULL; // rr
GLMipmap_t *nextBrightmap = NULL; // rr
FBITFIELD currentPolyFlags = 0;
FBITFIELD nextPolyFlags = 0;
FSurfaceInfo currentSurfaceInfo;
......@@ -191,6 +225,7 @@ void HWR_RenderBatches(void)
nextSurfaceInfo.LightInfo.fade_end = 0;
nextSurfaceInfo.LightInfo.fade_start = 0;
nextSurfaceInfo.LightInfo.light_level = 0;
nextSurfaceInfo.LightInfo.directional = false; // rr
currently_batching = false;// no longer collecting batches
if (!polygonArraySize)
......@@ -226,6 +261,7 @@ void HWR_RenderBatches(void)
currentShader = polygonArray[polygonIndexArray[0]].shader;
currentTexture = polygonArray[polygonIndexArray[0]].texture;
currentBrightmap = polygonArray[polygonIndexArray[0]].brightmap; // rr - 3rd in sort order now
currentPolyFlags = polygonArray[polygonIndexArray[0]].polyFlags;
currentSurfaceInfo = polygonArray[polygonIndexArray[0]].surf;
// For now, will sort and track the colors. Vertex attributes could be used instead of uniforms
......@@ -238,10 +274,21 @@ void HWR_RenderBatches(void)
HWD.pfnSetShader(currentShader);
}
if (currentPolyFlags & PF_NoTexture)
/*if (currentPolyFlags & PF_NoTexture)
currentTexture = NULL;
else
HWD.pfnSetTexture(currentTexture);
HWD.pfnSetTexture(currentTexture);*/
// rr
if (currentPolyFlags & PF_NoTexture)
{
currentTexture = currentBrightmap = NULL;
}
else
{
HWD.pfnSetTexture(currentTexture);
if (currentBrightmap)
HWD.pfnSetTexture(currentBrightmap);
}
while (1)// note: remember handling notexture polyflag as having texture number 0 (also in comparePolygons)
{
......@@ -314,15 +361,18 @@ void HWR_RenderBatches(void)
changeState = true;
nextShader = polygonArray[nextIndex].shader;
nextTexture = polygonArray[nextIndex].texture;
nextBrightmap = polygonArray[nextIndex].brightmap; // rr
nextPolyFlags = polygonArray[nextIndex].polyFlags;
nextSurfaceInfo = polygonArray[nextIndex].surf;
if (nextPolyFlags & PF_NoTexture)
nextTexture = 0;
//nextTexture = 0;
nextTexture = nextBrightmap = 0; // rr
if (currentShader != nextShader && cv_glshaders.value && gl_shadersavailable)
{
changeShader = true;
}
if (currentTexture != nextTexture)
//if (currentTexture != nextTexture)
if (currentTexture != nextTexture || currentBrightmap != nextBrightmap) // rr
{
changeTexture = true;
}
......@@ -337,7 +387,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) // rr
{
changeSurfaceInfo = true;
}
......@@ -384,6 +435,12 @@ void HWR_RenderBatches(void)
// texture should be already ready for use from calls to SetTexture during batch collection
HWD.pfnSetTexture(nextTexture);
currentTexture = nextTexture;
// rr
if (nextBrightmap)
HWD.pfnSetTexture(nextBrightmap);
currentBrightmap = nextBrightmap;
changeTexture = false;
ps_hw_numtextures.value.i++;
......
......@@ -23,6 +23,7 @@ typedef struct
FUINT numVerts;
FBITFIELD polyFlags;
GLMipmap_t *texture;
GLMipmap_t *brightmap; // rr
int shader;
// this tells batching that the plane belongs to a horizon line and must be drawn in correct order with the skywalls
boolean horizonSpecial;
......
......@@ -788,6 +788,52 @@ GLMapTexture_t *HWR_GetTexture(INT32 tex, boolean chromakeyed)
HWR_SetCurrentTexture(grMipmap);
Z_ChangeTag(grMipmap->data, PU_HWRCACHE_UNLOCKED);
// rr
if (R_GetTextureBrightmap(tex))
{
GLMapTexture_t *grtexbright = &gl_textures[R_GetTextureBrightmap(tex)];
GLMipmap_t *grMipmapBright = &grtexbright->mipmap;
GLMipmap_t *originalMipmapBright = grMipmapBright;
if (!originalMipmapBright->downloaded)
{
originalMipmapBright->flags = TF_WRAPXY | TF_BRIGHTMAP;
originalMipmapBright->width = (UINT16)textures[tex]->width;
originalMipmapBright->height = (UINT16)textures[tex]->height;
originalMipmapBright->format = textureformat;
}
// If chroma-keyed, create or use a different mipmap for the variant
if (chromakeyed && !textures[tex]->transparency)
{
// Allocate it if it wasn't already
if (!originalMipmapBright->nextcolormap)
{
GLMipmap_t *newMipmapBright = calloc(1, sizeof (*grMipmapBright));
if (newMipmapBright == NULL)
I_Error("%s: Out of memory", "HWR_GetTexture");
newMipmapBright->flags = originalMipmapBright->flags | TF_CHROMAKEYED | TF_BRIGHTMAP;
newMipmapBright->width = originalMipmapBright->width;
newMipmapBright->height = originalMipmapBright->height;
newMipmapBright->format = originalMipmapBright->format;
originalMipmapBright->nextcolormap = newMipmapBright;
}
// Generate, upload and bind the variant texture instead of the original one
grMipmapBright = originalMipmapBright->nextcolormap;
}
if (!grMipmapBright->data)
HWR_GenerateTexture(R_GetTextureBrightmap(tex), grtexbright, grMipmapBright);
if (!grMipmapBright->downloaded)
HWD.pfnSetTexture(grMipmapBright);
HWR_SetCurrentTexture(grMipmapBright);
Z_ChangeTag(grMipmapBright->data, PU_HWRCACHE_UNLOCKED);
}
return grtex;
}
......@@ -897,6 +943,59 @@ void HWR_GetLevelFlat(levelflat_t *levelflat, boolean chromakeyed)
HWR_SetCurrentTexture(grMipmap);
Z_ChangeTag(grMipmap->data, PU_HWRCACHE_UNLOCKED);
// rr
if ((texturenum = R_GetTextureBrightmap(texturenum)))
{
grtex = &gl_flats[texturenum];
grMipmap = &grtex->mipmap;
originalMipmap = grMipmap;
INT32 bmNum = R_GetTextureBrightmap(R_GetTextureNumForFlat(levelflat));
if (bmNum == 0) { bmNum = texturenum; }
if (!originalMipmap->downloaded)
MakeLevelFlatMipmap(originalMipmap, texturenum, TF_WRAPXY | TF_BRIGHTMAP);
if (!originalMipmap->data)
{
size_t size = originalMipmap->width * originalMipmap->height;
memcpy(Z_Malloc(size, PU_HWRCACHE, &originalMipmap->data), R_GetFlatForTexture(bmNum), size);
}
// If chroma-keyed, create or use a different mipmap for the variant
if (chromakeyed)
{
if (!originalMipmap->data)
{
HWR_SetCurrentTexture(NULL);
return;
}
// Allocate it if it wasn't already
if (!originalMipmap->nextcolormap)
{
GLMipmap_t *newMipmap = calloc(1, sizeof (*grMipmap));
if (newMipmap == NULL)
I_Error("%s: Out of memory", "HWR_GetLevelFlat");
MakeLevelFlatMipmap(newMipmap, texturenum, TF_WRAPXY | TF_CHROMAKEYED | TF_BRIGHTMAP);
originalMipmap->nextcolormap = newMipmap;
}
// Upload and bind the variant texture instead of the original one
grMipmap = originalMipmap->nextcolormap;
// Use the original texture's pixel data
// It can just be a pointer to it, since the r_opengl backend deals with the pixels
// that are supposed to be transparent.
grMipmap->data = originalMipmap->data;
}
if (!grMipmap->downloaded)
HWD.pfnSetTexture(grMipmap);
HWR_SetCurrentTexture(grMipmap);
Z_ChangeTag(grMipmap->data, PU_HWRCACHE_UNLOCKED);
}
}
// --------------------+
......
......@@ -248,6 +248,9 @@ enum ETextureFlags
TF_WRAPXY = TF_WRAPY|TF_WRAPX, // very common so use alias is more easy
TF_CHROMAKEYED = 0x00000010, // Used only for flats with pixels that have palette index 255
TF_TRANSPARENT = 0x00000040, // texture with some alpha == 0
// rr
TF_BRIGHTMAP = 0x00000080,
};
struct FTextureInfo
......@@ -266,6 +269,7 @@ struct FLightInfo
FUINT light_level;
FUINT fade_start;
FUINT fade_end;
boolean directional; // rr
};
typedef struct FLightInfo FLightInfo;
......@@ -310,6 +314,13 @@ typedef enum hwdshaderstage hwdshaderstage_t;
enum hwdshaderinfo
{
HWD_SHADERINFO_LEVELTIME = 1,
// rr
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;
......
......@@ -93,6 +93,8 @@ typedef struct gl_vissprite_s
mobj_t *mobj; // NOTE: This is a precipmobj_t if precip is true !!! Watch out.
} gl_vissprite_t;
void HWR_ObjectLightLevelPost(gl_vissprite_t *spr, const sector_t *sector, INT32 *lightlevel, boolean model); // rr
// --------
// hw_bsp.c
// --------
......
......@@ -133,7 +133,62 @@ static boolean HWR_IsWireframeMode(void)
return (cv_glwireframe.value && cv_debug);
}
void HWR_Lighting(FSurfaceInfo *Surface, INT32 light_level, extracolormap_t *colormap)
// rr
void HWR_ObjectLightLevelPost(gl_vissprite_t *spr, const sector_t *sector, INT32 *lightlevel, boolean model)
{
const boolean semibright = R_ThingIsSemiBright(spr->mobj);
const boolean papersprite = R_ThingIsPaperSprite(spr->mobj);
//*lightlevel += R_ThingLightLevel(spr->mobj);
//*lightlevel += spr->mobj->lightlevel;
if (maplighting.directional == true && P_SectorUsesDirectionalLighting(sector))
{
if (model == false) // this is implemented by shader
{
fixed_t extralight = R_GetSpriteDirectionalLighting(
papersprite
? spr->angle + (spr->flip ? -ANGLE_90 : ANGLE_90)
: R_PointToAngle(spr->mobj->x, spr->mobj->y) // fixme
);
// Less change in contrast in dark sectors
extralight = FixedMul(extralight, min(max(0, *lightlevel), 255) * FRACUNIT / 255);
if (papersprite)
{
// Papersprite contrast should match walls
*lightlevel += FixedFloor(extralight + (FRACUNIT / 2)) / FRACUNIT;
}
else
{
// 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 = 192 + (*lightlevel >> 1);
}
}
void HWR_Lighting(FSurfaceInfo *Surface, INT32 light_level, extracolormap_t *colormap, const boolean directional) // rr
{
RGBA_t poly_color, tint_color, fade_color;
......@@ -189,6 +244,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); // rr
if (HWR_ShouldUsePaletteRendering())
Surface->LightTableId = HWR_GetLightTableID(colormap);
......@@ -226,7 +282,7 @@ UINT8 HWR_FogBlockAlpha(INT32 light, extracolormap_t *colormap) // Let's see if
return surfcolor.s.alpha;
}
static FUINT HWR_CalcWallLight(FUINT lightnum, fixed_t v1x, fixed_t v1y, fixed_t v2x, fixed_t v2y)
/*static FUINT HWR_CalcWallLight(FUINT lightnum, fixed_t v1x, fixed_t v1y, fixed_t v2x, fixed_t v2y)
{
INT16 finallight = lightnum;
......@@ -306,6 +362,37 @@ static FUINT HWR_CalcSlopeLight(FUINT lightnum, angle_t dir, fixed_t delta)
}
}
return (FUINT)finallight;
}*/
// rr - functions before HWR_SideLightLevel
static FUINT HWR_CalcWallLight(FUINT lightnum, seg_t *seg)
{
INT16 finallight = lightnum;
if (seg != NULL && P_ApplyLightOffsetFine(lightnum, seg->frontsector))
{
finallight += seg->hwLightOffset;
if (finallight > 255) finallight = 255;
if (finallight < 0) finallight = 0;
}
return (FUINT)finallight;
}
static FUINT HWR_CalcSlopeLight(FUINT lightnum, pslope_t *slope, const sector_t *sector, const boolean fof)
{
INT16 finallight = lightnum;
if (slope != NULL && sector != NULL && P_ApplyLightOffsetFine(lightnum, sector))
{
finallight += (fof ? -slope->hwLightOffset : slope->hwLightOffset);
if (finallight > 255) finallight = 255;
if (finallight < 0) finallight = 0;
}
return (FUINT)finallight;
}
......@@ -499,9 +586,10 @@ static void HWR_RenderPlane(subsector_t *subsector, extrasubsector_t *xsub, bool
SETUP3DVERT(v3d, pv->x, pv->y);
if (slope)
lightlevel = HWR_CalcSlopeLight(lightlevel, R_PointToAngle2(0, 0, slope->normal.x, slope->normal.y), abs(slope->zdelta));
//lightlevel = HWR_CalcSlopeLight(lightlevel, R_PointToAngle2(0, 0, slope->normal.x, slope->normal.y), abs(slope->zdelta));
lightlevel = HWR_CalcSlopeLight(lightlevel, slope, gl_frontsector, (FOFsector != NULL)); // rr
HWR_Lighting(&Surf, lightlevel, planecolormap);
HWR_Lighting(&Surf, lightlevel, planecolormap, P_SectorUsesDirectionalLighting(gl_frontsector)); // rr
if (PolyFlags & (PF_Translucent|PF_Fog|PF_Additive|PF_Subtractive|PF_ReverseSubtract|PF_Multiplicative|PF_Environment))
{
......@@ -708,7 +796,7 @@ static void HWR_ProjectWall(FOutVector *wallVerts, FSurfaceInfo *pSurf, FBITFIEL
if (!r_renderwalls)
return;
HWR_Lighting(pSurf, lightlevel, wallcolormap);
HWR_Lighting(pSurf, lightlevel, wallcolormap, P_SectorUsesDirectionalLighting(gl_frontsector)); // rr
if (HWR_UseShader())
{
......@@ -742,9 +830,10 @@ static void HWR_SplitWall(sector_t *sector, FOutVector *wallVerts, INT32 texnum,
fixed_t v2x = FloatToFixed(wallVerts[1].x);
fixed_t v2y = FloatToFixed(wallVerts[1].z);
FUINT lightnum = HWR_SideLightLevel(gl_sidedef, sector->lightlevel);
//FUINT lightnum = HWR_SideLightLevel(gl_sidedef, sector->lightlevel);
const UINT8 alpha = Surf->PolyColor.s.alpha;
lightnum = HWR_CalcWallLight(lightnum, v1x, v1y, v2x, v2y);
//lightnum = HWR_CalcWallLight(lightnum, v1x, v1y, v2x, v2y);
FUINT lightnum = sector->lightlevel; // rr - (NOTE: this is currently overriding wall lighting, plz change)
extracolormap_t *colormap = NULL;
if (!r_renderwalls)
......@@ -788,15 +877,17 @@ static void HWR_SplitWall(sector_t *sector, FOutVector *wallVerts, INT32 texnum,
{
if (pfloor && (pfloor->fofflags & FOF_FOG))
{
lightnum = HWR_SideLightLevel(gl_sidedef, pfloor->master->frontsector->lightlevel);
//lightnum = HWR_SideLightLevel(gl_sidedef, pfloor->master->frontsector->lightlevel);
lightnum = pfloor->master->frontsector->lightlevel; // rr
colormap = pfloor->master->frontsector->extra_colormap;
lightnum = colormap ? lightnum : HWR_CalcWallLight(lightnum, v1x, v1y, v2x, v2y);
//lightnum = colormap ? lightnum : HWR_CalcWallLight(lightnum, v1x, v1y, v2x, v2y); // temp disable
}
else
{
lightnum = HWR_SideLightLevel(gl_sidedef, *list[i].lightlevel);
//lightnum = HWR_SideLightLevel(gl_sidedef, *list[i].lightlevel);
lightnum = *list[i].lightlevel; // rr
colormap = *list[i].extra_colormap;
lightnum = colormap ? lightnum : HWR_CalcWallLight(lightnum, v1x, v1y, v2x, v2y);
//lightnum = colormap ? lightnum : HWR_CalcWallLight(lightnum, v1x, v1y, v2x, v2y); // temp disable
}
}
......@@ -862,12 +953,19 @@ static void HWR_SplitWall(sector_t *sector, FOutVector *wallVerts, INT32 texnum,
wallVerts[0].y = bot;
wallVerts[1].y = endbot;
if (cutflag & FOF_FOG)
/*if (cutflag & FOF_FOG)
HWR_AddTransparentWall(wallVerts, Surf, texnum, PF_Fog|PF_NoTexture|polyflags, true, lightnum, colormap);
else if (polyflags & (PF_Translucent|PF_Additive|PF_Subtractive|PF_ReverseSubtract|PF_Multiplicative|PF_Environment))
HWR_AddTransparentWall(wallVerts, Surf, texnum, polyflags, false, lightnum, colormap);
else
HWR_ProjectWall(wallVerts, Surf, PF_Masked|polyflags, lightnum, colormap);
HWR_ProjectWall(wallVerts, Surf, PF_Masked|polyflags, lightnum, colormap);*/
// rr
if (cutflag & FOF_FOG)
HWR_AddTransparentWall(wallVerts, Surf, texnum, PF_Fog|PF_NoTexture|polyflags, true, HWR_CalcWallLight(lightnum, gl_curline), colormap);
else if (polyflags & (PF_Translucent|PF_Additive|PF_Subtractive|PF_ReverseSubtract|PF_Multiplicative|PF_Environment))
HWR_AddTransparentWall(wallVerts, Surf, texnum, polyflags, false, HWR_CalcWallLight(lightnum, gl_curline), colormap);
else
HWR_ProjectWall(wallVerts, Surf, PF_Masked|polyflags, HWR_CalcWallLight(lightnum, gl_curline), colormap);
top = bot;
endtop = endbot;
......@@ -891,12 +989,19 @@ static void HWR_SplitWall(sector_t *sector, FOutVector *wallVerts, INT32 texnum,
wallVerts[0].y = bot;
wallVerts[1].y = endbot;
if (cutflag & FOF_FOG)
/*if (cutflag & FOF_FOG)
HWR_AddTransparentWall(wallVerts, Surf, texnum, PF_Fog|PF_NoTexture|polyflags, true, lightnum, colormap);
else if (polyflags & (PF_Translucent|PF_Additive|PF_Subtractive|PF_ReverseSubtract|PF_Multiplicative|PF_Environment))
HWR_AddTransparentWall(wallVerts, Surf, texnum, polyflags, false, lightnum, colormap);
else
HWR_ProjectWall(wallVerts, Surf, PF_Masked|polyflags, lightnum, colormap);
HWR_ProjectWall(wallVerts, Surf, PF_Masked|polyflags, lightnum, colormap);*/
// rr
if (cutflag & FOF_FOG)
HWR_AddTransparentWall(wallVerts, Surf, texnum, PF_Fog|PF_NoTexture|polyflags, true, HWR_CalcWallLight(lightnum, gl_curline), colormap);
else if (polyflags & (PF_Translucent|PF_Additive|PF_Subtractive|PF_ReverseSubtract|PF_Multiplicative|PF_Environment))
HWR_AddTransparentWall(wallVerts, Surf, texnum, polyflags, false, HWR_CalcWallLight(lightnum, gl_curline), colormap);
else
HWR_ProjectWall(wallVerts, Surf, PF_Masked|polyflags, HWR_CalcWallLight(lightnum, gl_curline), colormap);
}
// HWR_DrawSkyWall
......@@ -1205,9 +1310,10 @@ static void HWR_ProcessSeg(void)
float cliplow = (float)gl_curline->offset;
float cliphigh = cliplow + (gl_curline->flength * FRACUNIT);
FUINT lightnum = HWR_SideLightLevel(gl_sidedef, gl_frontsector->lightlevel);
//FUINT lightnum = HWR_SideLightLevel(gl_sidedef, gl_frontsector->lightlevel);
FUINT lightnum = HWR_CalcWallLight(gl_frontsector->lightlevel, gl_curline); // rr
extracolormap_t *colormap = gl_frontsector->extra_colormap;
lightnum = colormap ? lightnum : HWR_CalcWallLight(lightnum, vs.x, vs.y, ve.x, ve.y);
//lightnum = colormap ? lightnum : HWR_CalcWallLight(lightnum, vs.x, vs.y, ve.x, ve.y); // rr - temp disable
FSurfaceInfo Surf;
Surf.PolyColor.s.alpha = 255;
......@@ -1666,9 +1772,10 @@ static void HWR_ProcessSeg(void)
{
blendmode = PF_Fog|PF_NoTexture;
lightnum = HWR_SideLightLevel(gl_sidedef, rover->master->frontsector->lightlevel);
//lightnum = HWR_SideLightLevel(gl_sidedef, rover->master->frontsector->lightlevel);
lightnum = HWR_CalcWallLight(rover->master->frontsector->lightlevel, gl_curline); // rr
colormap = rover->master->frontsector->extra_colormap;
lightnum = colormap ? lightnum : HWR_CalcWallLight(lightnum, vs.x, vs.y, ve.x, ve.y);
//lightnum = colormap ? lightnum : HWR_CalcWallLight(lightnum, vs.x, vs.y, ve.x, ve.y); // temp disable
Surf.PolyColor.s.alpha = HWR_FogBlockAlpha(HWR_SideLightLevel(gl_sidedef, rover->master->frontsector->lightlevel), rover->master->frontsector->extra_colormap);
......@@ -1823,9 +1930,10 @@ static void HWR_ProcessSeg(void)
{
blendmode = PF_Fog|PF_NoTexture;
lightnum = HWR_SideLightLevel(gl_sidedef, rover->master->frontsector->lightlevel);
//lightnum = HWR_SideLightLevel(gl_sidedef, rover->master->frontsector->lightlevel);
lightnum = HWR_CalcWallLight(rover->master->frontsector->lightlevel, gl_curline); // rr
colormap = rover->master->frontsector->extra_colormap;
lightnum = colormap ? lightnum : HWR_CalcWallLight(lightnum, vs.x, vs.y, ve.x, ve.y);
//lightnum = colormap ? lightnum : HWR_CalcWallLight(lightnum, vs.x, vs.y, ve.x, ve.y); // temp disable
Surf.PolyColor.s.alpha = HWR_FogBlockAlpha(rover->master->frontsector->lightlevel, rover->master->frontsector->extra_colormap);
......@@ -2236,7 +2344,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)); // rr
if (blendmode & PF_Translucent)
{
......@@ -2919,7 +3027,7 @@ static void HWR_DrawDropShadow(mobj_t *thing, fixed_t scale)
colormap = thing->subsector->sector->extra_colormap;
}
HWR_Lighting(&sSurf, 0, colormap);
HWR_Lighting(&sSurf, 255, colormap, P_SectorUsesDirectionalLighting(thing->subsector->sector)); // rr
sSurf.PolyColor.s.alpha = FixedMul(thing->alpha, alpha);
if (HWR_UseShader())
......@@ -2931,6 +3039,259 @@ static void HWR_DrawDropShadow(mobj_t *thing, fixed_t scale)
HWR_ProcessPolygon(&sSurf, shadowVerts, 4, blendmode, shader, false);
}
// GLBADSHADOWS
static void HWR_DrawSpriteShadow(gl_vissprite_t *spr, patch_t *gpatch)
{
FOutVector swallVerts[4];
FSurfaceInfo sSurf;
fixed_t floorheight, mobjfloor;
SINT8 flip = P_MobjFlip(spr->mobj);
UINT8 i;
fixed_t slopez;
pslope_t *groundslope;
mobjfloor = R_GetShadowZ(spr->mobj, &groundslope);
extracolormap_t *colormap = NULL;
INT32 light;
INT32 shader = SHADER_NONE;
FBITFIELD blendmode = PF_Translucent|PF_Modulated;
pslope_t *sectorslope;
sector_t *sector;
ffloor_t *rover;
fixed_t secfoftop;
float this_scale = 1.0f;
const boolean hires = (spr->mobj && spr->mobj->skin && ((skin_t *)spr->mobj->skin)->flags & SF_HIRES);
if (spr->mobj)
this_scale = FIXED_TO_FLOAT(spr->mobj->scale);
if (hires)
this_scale = this_scale * FIXED_TO_FLOAT(((skin_t *)spr->mobj->skin)->highresscale);
if (spr->mobj->type == MT_PLAYER && spr->mobj->shadowscale == 0) { return; }
if (spr->mobj->eflags & MFE_VERTICALFLIP) { return; } // temporary disable
// uncapped/interpolation
interpmobjstate_t interp = {0};
if (R_UsingFrameInterpolation() && !paused)
{
R_InterpolateMobjState(spr->mobj, rendertimefrac, &interp);
}
else
{
R_InterpolateMobjState(spr->mobj, FRACUNIT, &interp);
}
// direction splat code
F2DCoord verts[4];
F2DCoord rotated[4];
float xscale, yscale;
float xoffset, yoffset;
float ca, sa;
float w, h;
float leftoffset, topoffset;
angle_t angle = (cv_shadowsprdirection.value) ? maplighting.angle : viewangle;
angle = -angle;
angle += ANGLE_90;
topoffset = spr->spriteyoffset;
leftoffset = spr->spritexoffset;
if (spr->flip)
leftoffset = ((float)gpatch->width - leftoffset);
// floorheight
angle_t shadowdir = (cv_shadowsprdirection.value) ? maplighting.angle : viewangle;
fixed_t mobjthrustfloor;
mobjthrustfloor = P_FloorzAtPos(
interp.x + P_ReturnThrustX(spr->mobj, shadowdir, interp.z - mobjfloor),
interp.y + P_ReturnThrustY(spr->mobj, shadowdir, interp.z - mobjfloor),
interp.z, spr->mobj->height);
fixed_t thrustfloorz;
thrustfloorz = P_FloorzAtPos(
interp.x + P_ReturnThrustX(spr->mobj, shadowdir, interp.z - mobjthrustfloor),
interp.y + P_ReturnThrustY(spr->mobj, shadowdir, interp.z - mobjthrustfloor),
interp.z, spr->mobj->height);
if (((thrustfloorz < mobjthrustfloor) && ((mobjthrustfloor - thrustfloorz) > FRACUNIT*70))
|| ((thrustfloorz > mobjthrustfloor) && (thrustfloorz - mobjthrustfloor > FRACUNIT*20)))
return;
mobjfloor = mobjthrustfloor;
sector = R_PointInSubsector(
interp.x + P_ReturnThrustX(spr->mobj, shadowdir, interp.z - mobjfloor),
interp.y + P_ReturnThrustY(spr->mobj, shadowdir, interp.z - mobjfloor))->sector;
sectorslope = sector->f_slope;
if (sector->ffloors)
{
for (rover = sector->ffloors; rover; rover = rover->next)
{
if (!(rover->fofflags & FOF_EXISTS) || !(rover->fofflags & FOF_RENDERPLANES) || (rover->alpha < 90 && !(rover->fofflags & FOF_SWIMMABLE)))
continue;
secfoftop = P_GetFFloorTopZAt(rover,
interp.x + P_ReturnThrustX(spr->mobj, shadowdir, interp.z - mobjfloor),
interp.y + P_ReturnThrustY(spr->mobj, shadowdir, interp.z - mobjfloor));
/*if ((rover->fofflags & FOF_SWIMMABLE)
&& (mobjfloor < secfoftop)
&& (interp.z > secfoftop)) {
mobjfloor = secfoftop;
sectorslope = *rover->t_slope;
continue;
}*/
if (interp.z >= secfoftop
&& !(rover->fofflags & FOF_SWIMMABLE)
&& !(rover->fofflags & FOF_QUICKSAND))
{
sectorslope = *rover->t_slope;
}
}
}
if (interp.z < mobjfloor) {return;}
floorheight = FixedInt(interp.z - mobjfloor);
// offset
if (spr->mobj && fabsf(this_scale - 1.0f) > 1.0E-36f)
topoffset = spr->spriteyoffset + ((FixedInt(interp.z - mobjfloor))/this_scale);
else
topoffset = spr->spriteyoffset + FixedInt(interp.z - mobjfloor);
xscale = spr->scale * spr->spritexscale;
yscale = spr->scale * spr->spriteyscale;
xoffset = leftoffset * xscale;
yoffset = topoffset * yscale;
w = (float)gpatch->width * xscale;
h = (float)gpatch->height * yscale;
// 3--2
// | |
// 0--1
verts[3].x = -xoffset;
verts[3].y = yoffset;
verts[2].x = w - xoffset;
verts[2].y = yoffset;
verts[1].x = w - xoffset;
verts[1].y = -h + yoffset;
verts[0].x = -xoffset;
verts[0].y = -h + yoffset;
ca = FIXED_TO_FLOAT(FINECOSINE((-angle)>>ANGLETOFINESHIFT));
sa = FIXED_TO_FLOAT(FINESINE((-angle)>>ANGLETOFINESHIFT));
// Rotate
for (i = 0; i < 4; i++)
{
rotated[i].x = (verts[i].x * ca) - (verts[i].y * sa);
rotated[i].y = (verts[i].x * sa) + (verts[i].y * ca);
}
// Translate
for (i = 0; i < 4; i++)
{
swallVerts[i].x = rotated[i].x + FIXED_TO_FLOAT(interp.x);
swallVerts[i].z = rotated[i].y + FIXED_TO_FLOAT(interp.y);
}
if (spr->flip)
{
swallVerts[0].s = swallVerts[3].s = ((GLPatch_t *)gpatch->hardware)->max_s;
swallVerts[2].s = swallVerts[1].s = 0;
}
else
{
swallVerts[0].s = swallVerts[3].s = 0;
swallVerts[2].s = swallVerts[1].s = ((GLPatch_t *)gpatch->hardware)->max_s;
}
// flip the texture coords (look familiar?)
if (spr->vflip)
{
swallVerts[3].t = swallVerts[2].t = ((GLPatch_t *)gpatch->hardware)->max_t;
swallVerts[0].t = swallVerts[1].t = 0;
}
else
{
swallVerts[3].t = swallVerts[2].t = 0;
swallVerts[0].t = swallVerts[1].t = ((GLPatch_t *)gpatch->hardware)->max_t;
}
// slopes
if (sectorslope)
{
for (i = 0; i < 4; i++)
{
slopez = P_GetSlopeZAt(sectorslope, FLOAT_TO_FIXED(swallVerts[i].x), FLOAT_TO_FIXED(swallVerts[i].z));
swallVerts[i].y = FIXED_TO_FLOAT(slopez) + flip * 0.50f;
}
}
else
{
for (i = 0; i < 4; i++)
swallVerts[i].y = FIXED_TO_FLOAT(mobjfloor) + flip * 0.50f;
}
// colormap
if (!(spr->mobj->renderflags & RF_NOCOLORMAPS))
{
if (spr->mobj->subsector->sector->numlights)
{
// Always use the light at the top instead of whatever I was doing before
light = R_GetPlaneLight(spr->mobj->subsector->sector, mobjfloor, false);
if (*spr->mobj->subsector->sector->lightlist[light].extra_colormap)
colormap = *spr->mobj->subsector->sector->lightlist[light].extra_colormap;
}
else if (spr->mobj->subsector->sector->extra_colormap)
colormap = spr->mobj->subsector->sector->extra_colormap;
}
HWR_Lighting(&sSurf, 0, colormap, P_SectorUsesDirectionalLighting(spr->mobj->subsector->sector));
if (HWR_UseShader())
{
shader = SHADER_SPRITE;
blendmode |= PF_ColorMapped;
}
sSurf.PolyColor.s.red = 0x00;
sSurf.PolyColor.s.blue = 0x00;
sSurf.PolyColor.s.green = 0x00;
// shadow is always half as translucent as the sprite itself
if (!cv_translucency.value) // use default translucency (main sprite won't have any translucency)
sSurf.PolyColor.s.alpha = 0x80; // default
else if (spr->mobj->flags2 & MF2_SHADOW)
sSurf.PolyColor.s.alpha = 0x20;
else if (spr->mobj->frame & FF_TRANSMASK)
{
HWR_TranstableToAlpha((spr->mobj->frame & FF_TRANSMASK)>>FF_TRANSSHIFT, &sSurf);
sSurf.PolyColor.s.alpha /= 2; //cut alpha in half!
}
else
sSurf.PolyColor.s.alpha = 0x80; // default
sSurf.PolyColor.s.alpha += maplighting.contrast-64;
if (sSurf.PolyColor.s.alpha > floorheight/4)
{
sSurf.PolyColor.s.alpha = (UINT8)(sSurf.PolyColor.s.alpha - floorheight/4);
HWR_ProcessPolygon(&sSurf, swallVerts, 4, blendmode, shader, false);
}
}
// This is expecting a pointer to an array containing 4 wallVerts for a sprite
static void HWR_RotateSpritePolyToAim(gl_vissprite_t *spr, FOutVector *wallVerts, const boolean precip)
{
......@@ -3004,7 +3365,8 @@ static void HWR_SplitSprite(gl_vissprite_t *spr)
patch_t *gpatch;
FSurfaceInfo Surf;
extracolormap_t *colormap = NULL;
FUINT lightlevel;
//FUINT lightlevel;
INT32 lightlevel = 0; // rr
boolean lightset = true;
FBITFIELD blend = 0;
FBITFIELD occlusion;
......@@ -3031,6 +3393,25 @@ static void HWR_SplitSprite(gl_vissprite_t *spr)
//12/12/99: Hurdler: same comment as above (for md2)
//Hurdler: 25/04/2000: now support colormap in hardware mode
HWR_GetMappedPatch(gpatch, spr->colormap);
// GLBADSHADOWS
// Draw shadow BEFORE sprite
if (cv_shadowspr.value // Shadows enabled
&& (spr->mobj->flags & (MF_SCENERY|MF_SPAWNCEILING|MF_NOGRAVITY)) != (MF_SCENERY|MF_SPAWNCEILING|MF_NOGRAVITY) // Ceiling scenery have no shadow.
&& !(spr->mobj->flags2 & MF2_DEBRIS) // Debris have no corona or shadow.
&& !(spr->mobj->frame & FF_TRANSMASK) // Transparent objects have no shadow
//&& (spr->mobj->z <= viewz) // Only render if below camera
#ifdef ALAM_LIGHTING
&& !(t_lspr[spr->mobj->sprite]->type // Things with dynamic lights have no shadow.
&& (!spr->mobj->player || spr->mobj->player->powers[pw_super])) // Except for non-super players.
#endif
&& (spr->mobj->z >= spr->mobj->floorz)) // Without this, your shadow shows on the floor, even after you die and fall through the ground.
{
////////////////////
// SHADOW SPRITE! //
////////////////////
HWR_DrawSpriteShadow(spr, gpatch);
}
baseWallVerts[0].x = baseWallVerts[3].x = spr->x1;
baseWallVerts[2].x = baseWallVerts[1].x = spr->x2;
......@@ -3180,6 +3561,10 @@ static void HWR_SplitSprite(gl_vissprite_t *spr)
if (R_ThingIsSemiBright(spr->mobj))
lightlevel = 128 + (lightlevel>>1);
// rr
if (!lightset)
HWR_ObjectLightLevelPost(spr, sector, &lightlevel, false);
for (i = 0; i < sector->numlights; i++)
{
......@@ -3189,8 +3574,10 @@ static void HWR_SplitSprite(gl_vissprite_t *spr)
// even if we aren't changing colormap or lightlevel, we still need to continue drawing down the sprite
if (!(list[i].flags & FOF_NOSHADE) && (list[i].flags & FOF_CUTSPRITES))
{
if (!lightset)
if (!lightset) {
lightlevel = *list[i].lightlevel > 255 ? 255 : *list[i].lightlevel;
HWR_ObjectLightLevelPost(spr, sector, &lightlevel, false); // rr
}
if (!(spr->mobj->renderflags & RF_NOCOLORMAPS))
colormap = *list[i].extra_colormap;
}
......@@ -3255,7 +3642,7 @@ static void HWR_SplitSprite(gl_vissprite_t *spr)
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) && !R_ThingIsFullBright(spr->mobj)); // rr
Surf.PolyColor.s.alpha = alpha;
......@@ -3284,7 +3671,7 @@ static void HWR_SplitSprite(gl_vissprite_t *spr)
wallVerts[0].y = bot;
wallVerts[1].y = endbot;
HWR_Lighting(&Surf, lightlevel, colormap);
HWR_Lighting(&Surf, lightlevel, colormap, P_SectorUsesDirectionalLighting(sector)); // rr
Surf.PolyColor.s.alpha = alpha;
......@@ -3509,6 +3896,25 @@ static void HWR_DrawSprite(gl_vissprite_t *spr)
//12/12/99: Hurdler: same comment as above (for md2)
//Hurdler: 25/04/2000: now support colormap in hardware mode
HWR_GetMappedPatch(gpatch, spr->colormap);
// GLBADSHADOWS
// Draw shadow BEFORE sprite
if (cv_shadowspr.value // Shadows enabled
&& (spr->mobj->flags & (MF_SCENERY|MF_SPAWNCEILING|MF_NOGRAVITY)) != (MF_SCENERY|MF_SPAWNCEILING|MF_NOGRAVITY) // Ceiling scenery have no shadow.
&& !(spr->mobj->flags2 & MF2_DEBRIS) // Debris have no corona or shadow.
&& !(spr->mobj->frame & FF_TRANSMASK) // Transparent objects have no shadow
//&& (spr->mobj->z <= viewz) // Only render if below camera
#ifdef ALAM_LIGHTING
&& !(t_lspr[spr->mobj->sprite]->type // Things with dynamic lights have no shadow.
&& (!spr->mobj->player || spr->mobj->player->powers[pw_super])) // Except for non-super players.
#endif
&& (spr->mobj->z >= spr->mobj->floorz)) // Without this, your shadow shows on the floor, even after you die and fall through the ground.
{
////////////////////
// SHADOW SPRITE! //
////////////////////
HWR_DrawSpriteShadow(spr, gpatch);
}
if (spr->flip)
{
......@@ -3552,7 +3958,8 @@ static void HWR_DrawSprite(gl_vissprite_t *spr)
// colormap test
{
sector_t *sector = spr->mobj->subsector->sector;
UINT8 lightlevel = 0;
//UINT8 lightlevel = 0;
INT32 lightlevel = 0; // rr
boolean lightset = true;
extracolormap_t *colormap = NULL;
......@@ -3581,8 +3988,12 @@ static void HWR_DrawSprite(gl_vissprite_t *spr)
if (R_ThingIsSemiBright(spr->mobj))
lightlevel = 128 + (lightlevel>>1);
// rr
if (!lightset)
HWR_ObjectLightLevelPost(spr, sector, &lightlevel, false);
HWR_Lighting(&Surf, lightlevel, colormap);
HWR_Lighting(&Surf, lightlevel, colormap, P_SectorUsesDirectionalLighting(sector) && !R_ThingIsFullBright(spr->mobj)); // rr
}
{
......@@ -3736,7 +4147,7 @@ static inline void HWR_DrawPrecipitationSprite(gl_vissprite_t *spr)
colormap = sector->extra_colormap;
}
HWR_Lighting(&Surf, lightlevel, colormap);
HWR_Lighting(&Surf, lightlevel, colormap, P_SectorUsesDirectionalLighting(sector)); // rr
}
if (spr->mobj->frame & FF_TRANSMASK)
......@@ -5476,8 +5887,18 @@ void HWR_RenderPlayerView(INT32 viewnumber, player_t *player)
ClearColor.blue = 0.0f;
ClearColor.alpha = 1.0f;
if (cv_glshaders.value)
if (cv_glshaders.value) {
HWD.pfnSetShaderInfo(HWD_SHADERINFO_LEVELTIME, (INT32)leveltime); // The water surface shader needs the leveltime.
// rr
const angle_t light_angle = maplighting.angle - viewangle + ANGLE_90; // I fucking hate OGL's coordinate system
HWD.pfnSetShaderInfo(HWD_SHADERINFO_LIGHT_X, FINECOSINE(light_angle >> ANGLETOFINESHIFT));
HWD.pfnSetShaderInfo(HWD_SHADERINFO_LIGHT_Y, 0);
HWD.pfnSetShaderInfo(HWD_SHADERINFO_LIGHT_Z, -FINESINE(light_angle >> ANGLETOFINESHIFT));
HWD.pfnSetShaderInfo(HWD_SHADERINFO_LIGHT_CONTRAST, maplighting.contrast);
HWD.pfnSetShaderInfo(HWD_SHADERINFO_LIGHT_BACKLIGHT, maplighting.backlight);
}
if (viewnumber == 0) // Only do it if it's the first screen being rendered
HWD.pfnClearBuffer(true, false, &ClearColor); // Clear the Color Buffer, stops HOMs. Also seems to fix the skybox issue on Intel GPUs.
......@@ -5692,6 +6113,10 @@ consvar_t cv_glcoronas = CVAR_INIT ("gr_coronas", "On", CV_SAVE, CV_OnOff, NULL)
consvar_t cv_glcoronasize = CVAR_INIT ("gr_coronasize", "1", CV_SAVE|CV_FLOAT, 0, NULL);
#endif
// GLBADSHADOWS
consvar_t cv_shadowspr = CVAR_INIT ("shadowsprites", "Off", CV_SAVE, CV_OnOff, NULL);
consvar_t cv_shadowsprdirection = CVAR_INIT ("shadowspritedirection", "On", CV_SAVE, CV_OnOff, NULL);
consvar_t cv_glmodels = CVAR_INIT ("gr_models", "Off", CV_SAVE, CV_OnOff, NULL);
consvar_t cv_glmodelinterpolation = CVAR_INIT ("gr_modelinterpolation", "Sometimes", CV_SAVE, glmodelinterpolation_cons_t, NULL);
consvar_t cv_glmodellighting = CVAR_INIT ("gr_modellighting", "Off", CV_SAVE|CV_CALL, CV_OnOff, CV_glmodellighting_OnChange);
......@@ -5795,6 +6220,10 @@ void HWR_AddCommands(void)
CV_RegisterVar(&cv_glpaletterendering);
CV_RegisterVar(&cv_glpalettedepth);
CV_RegisterVar(&cv_glwireframe);
// GLBADSHADOWS
CV_RegisterVar(&cv_shadowspr);
CV_RegisterVar(&cv_shadowsprdirection);
}
// --------------------------------------------------------------------------
......@@ -5919,7 +6348,7 @@ void HWR_RenderWall(FOutVector *wallVerts, FSurfaceInfo *pSurf, FBITFIELD blend,
return;
// 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)); // rr
pSurf->PolyColor.s.alpha = alpha; // put the alpha back after lighting
......
......@@ -62,7 +62,7 @@ void HWR_DrawScreenFinalTexture(int width, int height);
// This stuff is put here so models can use them
boolean HWR_UseShader(void);
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); // rr
UINT8 HWR_FogBlockAlpha(INT32 light, extracolormap_t *colormap); // Let's see if this can work
UINT8 HWR_GetTranstableAlpha(INT32 transtablenum);
......@@ -81,6 +81,10 @@ extern consvar_t cv_glcoronas;
extern consvar_t cv_glcoronasize;
#endif
// GLBADSHADOWS
extern consvar_t cv_shadowspr;
extern consvar_t cv_shadowsprdirection;
extern consvar_t cv_glshaders, cv_glallowshaders;
extern consvar_t cv_glmodels;
extern consvar_t cv_glmodelinterpolation;
......
......@@ -1225,7 +1225,8 @@ boolean HWR_DrawModel(gl_vissprite_t *spr)
if (spr->mobj->subsector)
{
sector_t *sector = spr->mobj->subsector->sector;
UINT8 lightlevel = 255;
//UINT8 lightlevel = 255;
INT32 lightlevel = 255; // rr
extracolormap_t *colormap = NULL;
if (sector->numlights)
......@@ -1257,7 +1258,11 @@ boolean HWR_DrawModel(gl_vissprite_t *spr)
colormap = sector->extra_colormap;
}
HWR_Lighting(&Surf, lightlevel, colormap);
//HWR_Lighting(&Surf, lightlevel, colormap);
// rr
//if (!lightset)
HWR_ObjectLightLevelPost(spr, sector, &lightlevel, true);
HWR_Lighting(&Surf, lightlevel, colormap, P_SectorUsesDirectionalLighting(sector) && !R_ThingIsFullBright(spr->mobj));
}
else
Surf.PolyColor.rgba = 0xFFFFFFFF;
......
......@@ -626,6 +626,13 @@ typedef enum
gluniform_palette_lookup_tex, // 3d texture containing the rgb->index lookup table
gluniform_lighttable_tex, // 2d texture containing a light table
// rr
gluniform_tex,
gluniform_brightmap,
gluniform_light_dir,
gluniform_light_contrast,
gluniform_light_backlight,
// misc.
gluniform_leveltime,
......@@ -657,6 +664,13 @@ static gl_shaderstate_t gl_shaderstate;
// Shader info
static float shader_leveltime = 0;
// rr
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 Shader_CompileProgram(gl_shader_t *shader, GLint i);
static void Shader_CompileError(const char *message, GLuint program, INT32 shadernum);
......@@ -799,6 +813,22 @@ EXPORT void HWRAPI(SetShaderInfo) (hwdshaderinfo_t info, INT32 value)
case HWD_SHADERINFO_LEVELTIME:
shader_leveltime = (((float)(value-1)) + FIXED_TO_FLOAT(rendertimefrac)) / TICRATE;
break;
// rr
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;
}
......@@ -862,14 +892,17 @@ EXPORT void HWRAPI(UnSetShader) (void)
// -----------------+
// SetNoTexture : Disable texture
// -----------------+
static void SetNoTexture(void)
//static void SetNoTexture(void)
static void SetNoTexture(GLenum texture) // rr
{
// Disable texture.
if (tex_downloaded != NOTEXTURE_NUM)
{
if (NOTEXTURE_NUM == 0)
pglGenTextures(1, &NOTEXTURE_NUM);
pglActiveTexture(texture); // rr
pglBindTexture(GL_TEXTURE_2D, NOTEXTURE_NUM);
pglActiveTexture(GL_TEXTURE0); // rr
tex_downloaded = NOTEXTURE_NUM;
}
}
......@@ -1015,7 +1048,7 @@ void SetStates(void)
SetBlend(0);
tex_downloaded = 0;
SetNoTexture();
SetNoTexture(GL_TEXTURE0); // rr
pglPolygonOffset(-1.0f, -1.0f);
......@@ -1473,7 +1506,7 @@ EXPORT void HWRAPI(SetBlend) (FBITFIELD PolyFlags)
}
if (PolyFlags & PF_NoTexture)
{
SetNoTexture();
SetNoTexture(GL_TEXTURE0); // rr
}
}
CurrentPolyFlags = PolyFlags;
......@@ -1597,6 +1630,14 @@ EXPORT void HWRAPI(UpdateTexture) (GLMipmap_t *pTexInfo)
else
GL_MSG_Warning("UpdateTexture: bad format %d\n", pTexInfo->format);
// rr
if (!(pTexInfo->flags & TF_BRIGHTMAP))
{
tex_downloaded = 0; // force update
SetNoTexture(GL_TEXTURE1); // will be assigned later, if needed
}
pglActiveTexture(pTexInfo->flags & TF_BRIGHTMAP ? GL_TEXTURE1 : GL_TEXTURE0); // rr
pglBindTexture(GL_TEXTURE_2D, num);
tex_downloaded = num;
......@@ -1696,14 +1737,23 @@ EXPORT void HWRAPI(SetTexture) (GLMipmap_t *pTexInfo)
{
if (!pTexInfo)
{
SetNoTexture();
SetNoTexture(GL_TEXTURE0); // rr
return;
}
else if (pTexInfo->downloaded)
{
if (pTexInfo->downloaded != tex_downloaded)
{
// rr
if (!(pTexInfo->flags & TF_BRIGHTMAP))
{
tex_downloaded = 0; // force update
SetNoTexture(GL_TEXTURE1); // will be assigned later, if needed
}
pglActiveTexture(pTexInfo->flags & TF_BRIGHTMAP ? GL_TEXTURE1 : GL_TEXTURE0); // rr
pglBindTexture(GL_TEXTURE_2D, pTexInfo->downloaded);
pglActiveTexture(GL_TEXTURE0); // rr
tex_downloaded = pTexInfo->downloaded;
}
}
......@@ -1775,15 +1825,33 @@ static void Shader_SetUniforms(FSurfaceInfo *Surface, GLRGBAFloat *poly, GLRGBAF
function (uniform, a, b, c, d);
// polygon
UNIFORM_1(shader->uniforms[gluniform_tex], 0, pglUniform1i); // rr
UNIFORM_1(shader->uniforms[gluniform_brightmap], 1, pglUniform1i); // rr
UNIFORM_4(shader->uniforms[gluniform_poly_color], poly->red, poly->green, poly->blue, poly->alpha, pglUniform4f);
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; // rr
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; // rr
}
// rr
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);
......@@ -1911,6 +1979,13 @@ static boolean Shader_CompileProgram(gl_shader_t *shader, GLint i)
shader->uniforms[gluniform_palette_lookup_tex] = GETUNI("palette_lookup_tex");
shader->uniforms[gluniform_lighttable_tex] = GETUNI("lighttable_tex");
// rr
shader->uniforms[gluniform_tex] = GETUNI("tex");
shader->uniforms[gluniform_brightmap] = GETUNI("brightmap");
shader->uniforms[gluniform_light_dir] = GETUNI("light_dir");
shader->uniforms[gluniform_light_contrast] = GETUNI("light_contrast");
shader->uniforms[gluniform_light_backlight] = GETUNI("light_backlight");
// misc.
shader->uniforms[gluniform_leveltime] = GETUNI("leveltime");
#undef GETUNI
......@@ -1923,9 +1998,14 @@ static boolean Shader_CompileProgram(gl_shader_t *shader, GLint i)
pglUseProgram(shader->program);
// texture unit numbers for the samplers used for palette rendering
UNIFORM_1(shader->uniforms[gluniform_palette_tex], 2, pglUniform1i);
/*UNIFORM_1(shader->uniforms[gluniform_palette_tex], 2, pglUniform1i);
UNIFORM_1(shader->uniforms[gluniform_palette_lookup_tex], 1, pglUniform1i);
UNIFORM_1(shader->uniforms[gluniform_lighttable_tex], 2, pglUniform1i);
UNIFORM_1(shader->uniforms[gluniform_lighttable_tex], 2, pglUniform1i);*/
// rr
UNIFORM_1(shader->uniforms[gluniform_palette_tex], 3, pglUniform1i);
UNIFORM_1(shader->uniforms[gluniform_palette_lookup_tex], 2, pglUniform1i);
UNIFORM_1(shader->uniforms[gluniform_lighttable_tex], 3, pglUniform1i);
// restore gl shader state
pglUseProgram(gl_shaderstate.program);
......@@ -1997,7 +2077,8 @@ static void PreparePolygon(FSurfaceInfo *pSurf, FOutVector *pOutVerts, FBITFIELD
if (pSurf->LightTableId && pSurf->LightTableId != lt_downloaded)
{
pglActiveTexture(GL_TEXTURE2);
//pglActiveTexture(GL_TEXTURE2);
pglActiveTexture(GL_TEXTURE3); // rr
pglBindTexture(GL_TEXTURE_2D, pSurf->LightTableId);
pglActiveTexture(GL_TEXTURE0);
lt_downloaded = pSurf->LightTableId;
......@@ -2564,7 +2645,8 @@ static void DrawModelEx(model_t *model, INT32 frameIndex, float duration, float
if (Surface->LightTableId && Surface->LightTableId != lt_downloaded)
{
pglActiveTexture(GL_TEXTURE2);
//pglActiveTexture(GL_TEXTURE2);
pglActiveTexture(GL_TEXTURE3); // rr
pglBindTexture(GL_TEXTURE_2D, Surface->LightTableId);
pglActiveTexture(GL_TEXTURE0);
lt_downloaded = Surface->LightTableId;
......@@ -3223,7 +3305,8 @@ EXPORT void HWRAPI(SetPaletteLookup)(UINT8 *lut)
}
if (!paletteLookupTex)
pglGenTextures(1, &paletteLookupTex);
pglActiveTexture(GL_TEXTURE1);
//pglActiveTexture(GL_TEXTURE1);
pglActiveTexture(GL_TEXTURE2); // rr
pglBindTexture(GL_TEXTURE_3D, paletteLookupTex);
pglTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
pglTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
......@@ -3282,7 +3365,8 @@ EXPORT void HWRAPI(SetScreenPalette)(RGBA_t *palette)
memcpy(screenPalette, palette, sizeof(screenPalette));
if (!screenPaletteTex)
pglGenTextures(1, &screenPaletteTex);
pglActiveTexture(GL_TEXTURE2);
//pglActiveTexture(GL_TEXTURE2);
pglActiveTexture(GL_TEXTURE3); // rr
pglBindTexture(GL_TEXTURE_1D, screenPaletteTex);
pglTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
pglTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
......
// DR. ROBOTNIK'S RING RACERS
//-----------------------------------------------------------------------------
// Copyright (C) 2024 by Sally "TehRealSalt" Cochenour
// Copyright (C) 2024 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.
//-----------------------------------------------------------------------------
/// \file k_brightmap.c
/// \brief Brightmap texture loading.
#include "k_brightmap.h"
#include "doomdata.h"
#include "doomdef.h"
#include "doomtype.h"
#include "fastcmp.h"
#include "r_textures.h"
#include "w_wad.h"
#include "z_zone.h"
static brightmapStorage_t *brightmapStorage = NULL;
static size_t maxBrightmapStorage = 0;
/*--------------------------------------------------
static brightmapStorage_t *K_NewBrightmap(void)
Increases the size of maxBrightmapStorage by 1.
Input Arguments:-
None
Return:-
The new brightmap storage struct.
--------------------------------------------------*/
static brightmapStorage_t *K_NewBrightmap(void)
{
maxBrightmapStorage++;
brightmapStorage = (brightmapStorage_t *)Z_Realloc(brightmapStorage, sizeof(brightmapStorage_t) * (maxBrightmapStorage + 1), PU_STATIC, &brightmapStorage);
return &brightmapStorage[ maxBrightmapStorage - 1 ];
}
/*--------------------------------------------------
static brightmapStorage_t *K_GetBrightmapStorageByIndex(size_t checkIndex)
See header file for description.
--------------------------------------------------*/
static brightmapStorage_t *K_GetBrightmapStorageByIndex(size_t checkIndex)
{
if (checkIndex >= maxBrightmapStorage)
{
return NULL;
}
return &brightmapStorage[checkIndex];
}
/*--------------------------------------------------
static brightmapStorage_t *K_GetBrightmapStorageByTextureName(const char *checkName)
See header file for description.
--------------------------------------------------*/
static brightmapStorage_t *K_GetBrightmapStorageByTextureName(const char *checkName)
{
UINT32 checkHash = quickncasehash(checkName, 8);
size_t i;
if (maxBrightmapStorage == 0)
{
return NULL;
}
for (i = 0; i < maxBrightmapStorage; i++)
{
brightmapStorage_t *bms = &brightmapStorage[i];
if (checkHash == bms->textureHash && !strncmp(checkName, bms->textureName, 8))
{
// Name matches.
return bms;
}
}
return NULL;
}
/*--------------------------------------------------
static boolean K_BRIGHTLumpParser(char *data, size_t size)
Parses inputted lump data as a BRIGHT lump.
Input Arguments:-
data - Pointer to lump data.
size - The length of the lump data.
Return:-
false if any errors occured, otherwise true.
--------------------------------------------------*/
static boolean K_BRIGHTLumpParser(char *data, size_t size)
{
char *tkn = M_GetToken((char *)data);
size_t pos = 0;
while (tkn && (pos = M_GetTokenPos()) < size)
{
boolean valid = true;
if (stricmp(tkn, "texture") == 0)
{
Z_Free(tkn);
tkn = M_GetToken(NULL);
pos = M_GetTokenPos();
if (tkn && pos < size)
{
brightmapStorage_t *bms = K_GetBrightmapStorageByTextureName(tkn);
if (bms == NULL)
{
bms = K_NewBrightmap();
strncpy(bms->textureName, tkn, 8);
bms->textureHash = quickncasehash(tkn, 8);
}
Z_Free(tkn);
tkn = M_GetToken(NULL);
pos = M_GetTokenPos();
if (tkn && pos < size)
{
strncpy(bms->brightmapName, tkn, 8);
bms->brightmapHash = quickncasehash(tkn, 8);
}
else
{
CONS_Alert(CONS_ERROR, "No brightmap for brightmap definition.\n");
valid = false;
}
}
else
{
CONS_Alert(CONS_ERROR, "No texture for brightmap definition.\n");
valid = false;
}
}
// todo: SPRITE brightmaps?!
else
{
CONS_Alert(CONS_ERROR, "Unknown keyword '%s' found in BRIGHT lump.\n", tkn);
valid = false;
}
Z_Free(tkn);
if (valid == false)
{
return false;
}
tkn = M_GetToken(NULL);
}
Z_Free(tkn);
return true;
}
/*--------------------------------------------------
void K_InitBrightmapsPwad(INT32 wadNum)
See header file for description.
--------------------------------------------------*/
void K_InitBrightmapsPwad(INT32 wadNum)
{
UINT16 lumpNum;
size_t i;
I_Assert(brightmapStorage == NULL);
// Find BRIGHT lump in the WAD
lumpNum = W_CheckNumForNamePwad("BRIGHT", wadNum, 0);
while (lumpNum != INT16_MAX)
{
UINT8 *data = (UINT8 *)W_CacheLumpNumPwad(wadNum, lumpNum, PU_CACHE);
if (data != NULL)
{
lumpinfo_t *lump_p = &wadfiles[wadNum]->lumpinfo[lumpNum];
size_t size = W_LumpLengthPwad(wadNum, lumpNum);
char *datacopy;
size_t nameLength = strlen(wadfiles[wadNum]->filename) + 1 + strlen(lump_p->fullname); // length of file name, '|', and lump name
char *name = malloc(nameLength + 1);
sprintf(name, "%s|%s", wadfiles[wadNum]->filename, lump_p->fullname);
name[nameLength] = '\0';
size = W_LumpLengthPwad(wadNum, lumpNum);
CONS_Printf(M_GetText("Loading BRIGHT from %s\n"), name);
datacopy = (char *)Z_Malloc((size+1)*sizeof(char),PU_STATIC,NULL);
memmove(datacopy,data,size);
datacopy[size] = '\0';
Z_Free(data);
K_BRIGHTLumpParser(datacopy, size);
Z_Free(datacopy);
free(name);
}
lumpNum = W_CheckNumForNamePwad("BRIGHT", (UINT16)wadNum, lumpNum + 1);
}
if (maxBrightmapStorage == 0)
{
// No brightmaps were defined.
return;
}
for (i = 0; i < maxBrightmapStorage; i++)
{
brightmapStorage_t *bms = K_GetBrightmapStorageByIndex(i);
INT32 texNum, bmNum;
if (bms == NULL)
{
// Shouldn't happen.
break;
}
texNum = R_CheckTextureNumForName(bms->textureName);
if (texNum != -1)
{
bmNum = R_CheckTextureNumForName(bms->brightmapName);
R_UpdateTextureBrightmap(texNum, (bmNum == -1 ? 0 : bmNum));
}
}
R_ClearTextureNumCache(false);
// Clear brightmapStorage now that we're done with it.
Z_Free(brightmapStorage);
brightmapStorage = NULL;
maxBrightmapStorage = 0;
}
/*--------------------------------------------------
void K_InitBrightmaps(void)
See header file for description.
--------------------------------------------------*/
void K_InitBrightmaps(void)
{
INT32 wadNum;
for (wadNum = 0; wadNum < numwadfiles; wadNum++)
{
K_InitBrightmapsPwad(wadNum);
}
}
// DR. ROBOTNIK'S RING RACERS
//-----------------------------------------------------------------------------
// Copyright (C) 2024 by Sally "TehRealSalt" Cochenour
// Copyright (C) 2024 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.
//-----------------------------------------------------------------------------
/// \file k_brightmap.h
/// \brief Brightmap texture loading.
#ifndef __K_BRIGHTMAP_H__
#define __K_BRIGHTMAP_H__
#include "doomdata.h"
#include "doomdef.h"
#include "doomtype.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct
{
// Brightmap storage struct.
// Stores data for brightmap definitions,
// before putting them into texturebrightmaps.
char textureName[9]; // The texture's name.
UINT32 textureHash; // The texture name's hash.
char brightmapName[9]; // The brightmap's name.
UINT32 brightmapHash; // The brightmap name's hash.
} brightmapStorage_t;
/*--------------------------------------------------
void K_InitBrightmapsPwad(INT32 wadNum);
Finds all BRIGHT lumps for one WAD/PK3 and processes them.
--------------------------------------------------*/
void K_InitBrightmapsPwad(INT32 wadNum);
/*--------------------------------------------------
void K_InitBrightmaps(void);
Finds all BRIGHT lumps and processes them.
--------------------------------------------------*/
void K_InitBrightmaps(void);
#ifdef __cplusplus
} // extern "C"
#endif
#endif // __K_BRIGHTMAP_H__