From 04c1a9dcb1b3068434bb5a80ed05ebdb76f03448 Mon Sep 17 00:00:00 2001 From: Sally Coolatta Date: Thu, 16 Dec 2021 09:40:14 -0500 Subject: [PATCH] Brightmaps on walls --- src/Sourcefile | 1 + src/k_brightmap.c | 256 ++++++++++++++++++++++++++++++++++++++++++++++ src/k_brightmap.h | 38 +++++++ src/p_setup.c | 4 + src/r_data.c | 6 ++ src/r_draw.c | 2 + src/r_draw.h | 3 + src/r_draw8.c | 153 ++++++++++++++++++++++++--- src/r_plane.c | 5 + src/r_segs.c | 95 +++++++++++++---- src/r_state.h | 3 + src/r_textures.c | 21 ++++ src/r_textures.h | 1 + src/r_things.c | 50 +++++++-- src/r_things.h | 4 +- 15 files changed, 597 insertions(+), 45 deletions(-) create mode 100644 src/k_brightmap.c create mode 100644 src/k_brightmap.h diff --git a/src/Sourcefile b/src/Sourcefile index 9bc27d4da..e142ebcc1 100644 --- a/src/Sourcefile +++ b/src/Sourcefile @@ -111,3 +111,4 @@ k_botitem.c k_botsearch.c k_grandprix.c k_hud.c +k_brightmap.c diff --git a/src/k_brightmap.c b/src/k_brightmap.c new file mode 100644 index 000000000..b9ef07ab8 --- /dev/null +++ b/src/k_brightmap.c @@ -0,0 +1,256 @@ +// DR. ROBOTNIK'S RING RACERS +//----------------------------------------------------------------------------- +// Copyright (C) 2021 by Sally "TehRealSalt" Cochenour +// Copyright (C) 2021 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, NULL); + 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) +{ + size_t i; + + if (maxBrightmapStorage == 0) + { + return NULL; + } + + for (i = 0; i < maxBrightmapStorage; i++) + { + brightmapStorage_t *bms = &brightmapStorage[i]; + + if (stricmp(checkName, bms->textureName) == 0) + { + // Name matches. + return bms; + } + } + + return NULL; +} + +/*-------------------------------------------------- + static boolean K_BRIGHTLumpParser(UINT8 *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(UINT8 *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, 9); + } + + Z_Free(tkn); + tkn = M_GetToken(NULL); + pos = M_GetTokenPos(); + + if (tkn && pos < size) + { + strncpy(bms->brightmapName, tkn, 9); + } + 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_InitBrightmaps(void) + + See header file for description. +--------------------------------------------------*/ +void K_InitBrightmaps(void) +{ + INT32 wadNum; + size_t i; + + I_Assert(brightmapStorage == NULL); + maxBrightmapStorage = 0; + + for (wadNum = 0; wadNum < numwadfiles; wadNum++) + { + lumpinfo_t *lump_p = wadfiles[wadNum]->lumpinfo; + UINT16 lumpNum; + + // Find BRIGHT lump in the WAD + lumpNum = W_CheckNumForNamePwad("BRIGHT", wadNum, 0); + + while (lumpNum != INT16_MAX) + { + UINT8 *data; + data = (UINT8 *)W_CacheLumpNumPwad(wadNum, lumpNum, PU_STATIC); + + // If that didn't exist, we have nothing to do here. + if (data == NULL) + { + lumpNum = W_CheckNumForNamePwad("BRIGHT", (UINT16)wadNum, lumpNum + 1); + continue; + } + else + { + size_t size = W_LumpLengthPwad(wadNum, lumpNum); + + 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); + K_BRIGHTLumpParser(data, size); + + 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); + if (bmNum == -1) + { + texturebrightmaps[texNum] = 0; + } + else + { + texturebrightmaps[texNum] = bmNum; + } + } + } + + R_ClearTextureNumCache(false); + + // Clear brightmapStorage now that we're done with it. + Z_Free(brightmapStorage); + brightmapStorage = NULL; +} diff --git a/src/k_brightmap.h b/src/k_brightmap.h new file mode 100644 index 000000000..8d33ae5cb --- /dev/null +++ b/src/k_brightmap.h @@ -0,0 +1,38 @@ +// DR. ROBOTNIK'S RING RACERS +//----------------------------------------------------------------------------- +// Copyright (C) 2021 by Sally "TehRealSalt" Cochenour +// Copyright (C) 2021 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" + +typedef struct brightmapStorage_s +{ + // Brightmap storage struct. + // Stores data for brightmap definitions, + // before putting them into texturebrightmaps. + + char textureName[9]; // The texture's name. + char brightmapName[9]; // The brightmap's name. +} brightmapStorage_t; + +/*-------------------------------------------------- + void K_InitBrightmaps(void); + + Finds all BRIGHT lumps and processes them. +--------------------------------------------------*/ + +void K_InitBrightmaps(void); + +#endif // __K_BRIGHTMAP_H__ diff --git a/src/p_setup.c b/src/p_setup.c index fab5429b8..db9a35a11 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -91,6 +91,7 @@ #include "k_waypoint.h" #include "k_bot.h" #include "k_grandprix.h" +#include "k_brightmap.h" // Replay names have time #if !defined (UNDER_CE) @@ -4457,6 +4458,9 @@ boolean P_AddWadFile(const char *wadfilename) // Reload ANIMDEFS P_InitPicAnims(); + // Reload BRIGHT + K_InitBrightmaps(); + // Flush and reload HUD graphics ST_UnloadGraphics(); HU_LoadGraphics(); diff --git a/src/r_data.c b/src/r_data.c index bb2e508ba..ddeb5e3b5 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -30,6 +30,9 @@ #include "byteptr.h" #include "dehacked.h" +// DRRR +#include "k_brightmap.h" + // // Graphics. // SRB2 graphics for walls and sprites @@ -1175,6 +1178,9 @@ void R_InitTextureData(void) CONS_Printf("P_InitPicAnims()...\n"); P_InitPicAnims(); + + CONS_Printf("K_InitBrightmaps()...\n"); + K_InitBrightmaps(); } // diff --git a/src/r_draw.c b/src/r_draw.c index 4adfb6663..c3bc2ac3c 100644 --- a/src/r_draw.c +++ b/src/r_draw.c @@ -71,12 +71,14 @@ UINT8 *topleft; // ========================================================================= lighttable_t *dc_colormap; +lighttable_t *dc_fullbright; INT32 dc_x = 0, dc_yl = 0, dc_yh = 0; fixed_t dc_iscale, dc_texturemid; UINT8 dc_hires; // under MSVC boolean is a byte, while on other systems, it a bit, // soo lets make it a byte on all system for the ASM code UINT8 *dc_source; +UINT8 *dc_brightmap; // ----------------------- // translucency stuff here diff --git a/src/r_draw.h b/src/r_draw.h index 646eb5ec8..b5cea0420 100644 --- a/src/r_draw.h +++ b/src/r_draw.h @@ -32,11 +32,13 @@ extern UINT8 *topleft; // ------------------------- extern lighttable_t *dc_colormap; +extern lighttable_t *dc_fullbright; extern INT32 dc_x, dc_yl, dc_yh; extern fixed_t dc_iscale, dc_texturemid; extern UINT8 dc_hires; extern UINT8 *dc_source; // first pixel in a column +extern UINT8 *dc_brightmap; // brightmap texture column, can be NULL // translucency stuff here extern UINT8 *dc_transmap; @@ -167,6 +169,7 @@ void R_DrawViewBorder(void); #endif #define TRANSPARENTPIXEL 255 +#define BRIGHTPIXEL 0 // ----------------- // 8bpp DRAWING CODE diff --git a/src/r_draw8.c b/src/r_draw8.c index af64edbce..1771614db 100644 --- a/src/r_draw8.c +++ b/src/r_draw8.c @@ -57,7 +57,9 @@ void R_DrawColumn_8(void) // This is as fast as it gets. { register const UINT8 *source = dc_source; + register const UINT8 *brightmap = dc_brightmap; register const lighttable_t *colormap = dc_colormap; + register const lighttable_t *fullbright = dc_fullbright; register INT32 heightmask = dc_texheight-1; if (dc_texheight & heightmask) // not a power of 2 -- killough { @@ -75,7 +77,14 @@ void R_DrawColumn_8(void) // Re-map color indices from wall texture column // using a lighting/special effects LUT. // heightmask is the Tutti-Frutti fix - *dest = colormap[source[frac>>FRACBITS]]; + if (brightmap != NULL && brightmap[frac>>FRACBITS] == BRIGHTPIXEL) + { + *dest = fullbright[source[frac>>FRACBITS]]; + } + else + { + *dest = colormap[source[frac>>FRACBITS]]; + } dest += vid.width; // Avoid overflow. @@ -92,15 +101,42 @@ void R_DrawColumn_8(void) { while ((count -= 2) >= 0) // texture height is a power of 2 { - *dest = colormap[source[(frac>>FRACBITS) & heightmask]]; + if (brightmap != NULL && brightmap[frac>>FRACBITS] == BRIGHTPIXEL) + { + *dest = fullbright[source[(frac>>FRACBITS) & heightmask]]; + } + else + { + *dest = colormap[source[(frac>>FRACBITS) & heightmask]]; + } + dest += vid.width; frac += fracstep; - *dest = colormap[source[(frac>>FRACBITS) & heightmask]]; + + if (brightmap != NULL && brightmap[frac>>FRACBITS] == BRIGHTPIXEL) + { + *dest = fullbright[source[(frac>>FRACBITS) & heightmask]]; + } + else + { + *dest = colormap[source[(frac>>FRACBITS) & heightmask]]; + } + dest += vid.width; frac += fracstep; } + if (count & 1) - *dest = colormap[source[(frac>>FRACBITS) & heightmask]]; + { + if (brightmap != NULL && brightmap[frac>>FRACBITS] == BRIGHTPIXEL) + { + *dest = fullbright[source[(frac>>FRACBITS) & heightmask]]; + } + else + { + *dest = colormap[source[(frac>>FRACBITS) & heightmask]]; + } + } } } } @@ -140,7 +176,9 @@ void R_Draw2sMultiPatchColumn_8(void) // This is as fast as it gets. { register const UINT8 *source = dc_source; + register const UINT8 *brightmap = dc_brightmap; register const lighttable_t *colormap = dc_colormap; + register const lighttable_t *fullbright = dc_fullbright; register INT32 heightmask = dc_texheight-1; register UINT8 val; if (dc_texheight & heightmask) // not a power of 2 -- killough @@ -160,9 +198,17 @@ void R_Draw2sMultiPatchColumn_8(void) // using a lighting/special effects LUT. // heightmask is the Tutti-Frutti fix val = source[frac>>FRACBITS]; - if (val != TRANSPARENTPIXEL) - *dest = colormap[val]; + { + if (brightmap != NULL && brightmap[frac>>FRACBITS] == BRIGHTPIXEL) + { + *dest = fullbright[val]; + } + else + { + *dest = colormap[val]; + } + } dest += vid.width; @@ -182,20 +228,51 @@ void R_Draw2sMultiPatchColumn_8(void) { val = source[(frac>>FRACBITS) & heightmask]; if (val != TRANSPARENTPIXEL) - *dest = colormap[val]; + { + if (brightmap != NULL && brightmap[frac>>FRACBITS] == BRIGHTPIXEL) + { + *dest = fullbright[val]; + } + else + { + *dest = colormap[val]; + } + } + dest += vid.width; frac += fracstep; + val = source[(frac>>FRACBITS) & heightmask]; if (val != TRANSPARENTPIXEL) - *dest = colormap[val]; + { + if (brightmap != NULL && brightmap[frac>>FRACBITS] == BRIGHTPIXEL) + { + *dest = fullbright[val]; + } + else + { + *dest = colormap[val]; + } + } + dest += vid.width; frac += fracstep; } + if (count & 1) { val = source[(frac>>FRACBITS) & heightmask]; if (val != TRANSPARENTPIXEL) - *dest = colormap[val]; + { + if (brightmap != NULL && brightmap[frac>>FRACBITS] == BRIGHTPIXEL) + { + *dest = fullbright[val]; + } + else + { + *dest = colormap[val]; + } + } } } } @@ -236,8 +313,10 @@ void R_Draw2sMultiPatchTranslucentColumn_8(void) // This is as fast as it gets. { register const UINT8 *source = dc_source; + register const UINT8 *brightmap = dc_brightmap; register const UINT8 *transmap = dc_transmap; register const lighttable_t *colormap = dc_colormap; + register const lighttable_t *fullbright = dc_fullbright; register INT32 heightmask = dc_texheight-1; register UINT8 val; if (dc_texheight & heightmask) // not a power of 2 -- killough @@ -257,9 +336,17 @@ void R_Draw2sMultiPatchTranslucentColumn_8(void) // using a lighting/special effects LUT. // heightmask is the Tutti-Frutti fix val = source[frac>>FRACBITS]; - if (val != TRANSPARENTPIXEL) - *dest = *(transmap + (colormap[val]<<8) + (*dest)); + { + if (brightmap != NULL && brightmap[frac>>FRACBITS] == BRIGHTPIXEL) + { + *dest = *(transmap + (fullbright[val]<<8) + (*dest)); + } + else + { + *dest = *(transmap + (colormap[val]<<8) + (*dest)); + } + } dest += vid.width; @@ -279,12 +366,33 @@ void R_Draw2sMultiPatchTranslucentColumn_8(void) { val = source[(frac>>FRACBITS) & heightmask]; if (val != TRANSPARENTPIXEL) - *dest = *(transmap + (colormap[val]<<8) + (*dest)); + { + if (brightmap != NULL && brightmap[frac>>FRACBITS] == BRIGHTPIXEL) + { + *dest = *(transmap + (fullbright[val]<<8) + (*dest)); + } + else + { + *dest = *(transmap + (colormap[val]<<8) + (*dest)); + } + } + dest += vid.width; frac += fracstep; + val = source[(frac>>FRACBITS) & heightmask]; if (val != TRANSPARENTPIXEL) - *dest = *(transmap + (colormap[val]<<8) + (*dest)); + { + if (brightmap != NULL && brightmap[frac>>FRACBITS] == BRIGHTPIXEL) + { + *dest = *(transmap + (fullbright[val]<<8) + (*dest)); + } + else + { + *dest = *(transmap + (colormap[val]<<8) + (*dest)); + } + } + dest += vid.width; frac += fracstep; } @@ -292,7 +400,16 @@ void R_Draw2sMultiPatchTranslucentColumn_8(void) { val = source[(frac>>FRACBITS) & heightmask]; if (val != TRANSPARENTPIXEL) - *dest = *(transmap + (colormap[val]<<8) + (*dest)); + { + if (brightmap != NULL && brightmap[frac>>FRACBITS] == BRIGHTPIXEL) + { + *dest = *(transmap + (fullbright[val]<<8) + (*dest)); + } + else + { + *dest = *(transmap + (colormap[val]<<8) + (*dest)); + } + } } } } @@ -2114,8 +2231,12 @@ void R_DrawColumnShadowed_8(void) if (height <= dc_yl) { dc_colormap = dc_lightlist[i].rcolormap; + dc_fullbright = colormaps; if (encoremap) + { dc_colormap += COLORMAP_REMAPOFFSET; + dc_fullbright += COLORMAP_REMAPOFFSET; + } if (solid && dc_yl < bheight) dc_yl = bheight; continue; @@ -2132,8 +2253,12 @@ void R_DrawColumnShadowed_8(void) dc_yl = dc_yh + 1; dc_colormap = dc_lightlist[i].rcolormap; + dc_fullbright = colormaps; if (encoremap) + { dc_colormap += COLORMAP_REMAPOFFSET; + dc_fullbright += COLORMAP_REMAPOFFSET; + } } dc_yh = realyh; if (dc_yl <= realyh) diff --git a/src/r_plane.c b/src/r_plane.c index 8ec7e2b99..58e6ce5ea 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -651,8 +651,12 @@ static void R_DrawSkyPlane(visplane_t *pl) // Because of this hack, sky is not affected // by sector colormaps (INVUL inverse mapping is not implemented in SRB2 so is irrelevant). dc_colormap = colormaps; + dc_fullbright = colormaps; if (encoremap) + { dc_colormap += COLORMAP_REMAPOFFSET; + dc_fullbright += COLORMAP_REMAPOFFSET; + } dc_texturemid = skytexturemid; dc_texheight = textureheight[skytexture] >>FRACBITS; @@ -669,6 +673,7 @@ static void R_DrawSkyPlane(visplane_t *pl) dc_source = R_GetColumn(texturetranslation[skytexture], -angle); // get negative of angle for each column to display sky correct way round! --Monster Iestyn 27/01/18 + dc_brightmap = NULL; colfunc(); } } diff --git a/src/r_segs.c b/src/r_segs.c index 5c9538e34..033bcca73 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -36,6 +36,7 @@ static boolean markceiling; static boolean maskedtexture; static INT32 toptexture, bottomtexture, midtexture; +static INT32 topbrightmap, bottombrightmap, midbrightmap; static INT32 numthicksides, numbackffloors; angle_t rw_normalangle; @@ -83,7 +84,7 @@ static fixed_t *maskedtextureheight = NULL; // multi-patch textures. They are not normally needed as multi-patch // textures don't have holes in it. At least not for now. -static void R_Render2sidedMultiPatchColumn(column_t *column) +static void R_Render2sidedMultiPatchColumn(column_t *column, column_t *brightmap) { INT32 topscreen, bottomscreen; @@ -93,6 +94,8 @@ static void R_Render2sidedMultiPatchColumn(column_t *column) dc_yl = (sprtopscreen+FRACUNIT-1)>>FRACBITS; dc_yh = (bottomscreen-1)>>FRACBITS; + dc_brightmap = NULL; + if (windowtop != INT32_MAX && windowbottom != INT32_MAX) { dc_yl = ((windowtop + FRACUNIT)>>FRACBITS); @@ -110,6 +113,10 @@ static void R_Render2sidedMultiPatchColumn(column_t *column) if (dc_yl <= dc_yh && dc_yh < vid.height && dc_yh > 0) { dc_source = (UINT8 *)column + 3; + if (brightmap != NULL) + { + dc_brightmap = (UINT8 *)brightmap + 3; + } if (colfunc == colfuncs[BASEDRAWFUNC]) (colfuncs[COLDRAWFUNC_TWOSMULTIPATCH])(); @@ -132,12 +139,12 @@ transnum_t R_GetLinedefTransTable(line_t *ldef) void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) { size_t pindex; - column_t *col; - INT32 lightnum, texnum, i; + column_t *col, *bmCol = NULL; + INT32 lightnum, texnum, bmnum, i; fixed_t height, realbot; lightlist_t *light; r_lightlist_t *rlight; - void (*colfunc_2s)(column_t *); + void (*colfunc_2s)(column_t *, column_t *); line_t *ldef; sector_t *front, *back; INT32 times, repeats; @@ -155,6 +162,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) frontsector = curline->frontsector; backsector = curline->backsector; texnum = R_GetTextureNum(curline->sidedef->midtexture); + bmnum = R_GetTextureBrightmap(texnum); windowbottom = windowtop = sprbotscreen = INT32_MAX; ldef = curline->linedef; @@ -215,6 +223,8 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) // Texture must be cached before setting colfunc_2s, // otherwise texture[texnum]->holes may be false when it shouldn't be R_CheckTextureCache(texnum); + if (bmnum) { R_CheckTextureCache(bmnum); } + // handle case where multipatch texture is drawn on a 2sided wall, multi-patch textures // are not stored per-column with post info in SRB2 if (textures[texnum]->holes) @@ -400,6 +410,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) // draw the texture col = (column_t *)((UINT8 *)R_GetColumn(texnum, maskedtexturecol[dc_x]) - 3); + if (bmnum) { bmCol = (column_t *)((UINT8 *)R_GetColumn(bmnum, maskedtexturecol[dc_x]) - 3); } for (i = 0; i < dc_numlights; i++) { @@ -431,8 +442,12 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) if (height <= windowtop) { dc_colormap = rlight->rcolormap; + dc_fullbright = colormaps; if (encoremap && !(ldef->flags & ML_TFERLINE)) + { dc_colormap += COLORMAP_REMAPOFFSET; + dc_fullbright += COLORMAP_REMAPOFFSET; + } continue; } @@ -440,7 +455,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) if (windowbottom >= realbot) { windowbottom = realbot; - colfunc_2s(col); + colfunc_2s(col, bmCol); for (i++; i < dc_numlights; i++) { rlight = &dc_lightlist[i]; @@ -449,15 +464,19 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) continue; } - colfunc_2s(col); + colfunc_2s(col, bmCol); windowtop = windowbottom + 1; dc_colormap = rlight->rcolormap; + dc_fullbright = colormaps; if (encoremap && !(ldef->flags & ML_TFERLINE)) + { dc_colormap += COLORMAP_REMAPOFFSET; + dc_fullbright += COLORMAP_REMAPOFFSET; + } } windowbottom = realbot; if (windowtop < windowbottom) - colfunc_2s(col); + colfunc_2s(col, bmCol); spryscale += rw_scalestep; continue; @@ -470,8 +489,12 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) pindex = MAXLIGHTSCALE - 1; dc_colormap = walllights[pindex]; + dc_fullbright = colormaps; if (encoremap && !(ldef->flags & ML_TFERLINE)) + { dc_colormap += COLORMAP_REMAPOFFSET; + dc_fullbright += COLORMAP_REMAPOFFSET; + } if (frontsector->extra_colormap) dc_colormap = frontsector->extra_colormap->colormap + (dc_colormap - colormaps); @@ -481,6 +504,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) // draw the texture col = (column_t *)((UINT8 *)R_GetColumn(texnum, maskedtexturecol[dc_x]) - 3); + if (bmnum) { bmCol = (column_t *)((UINT8 *)R_GetColumn(bmnum, maskedtexturecol[dc_x]) - 3); } #if 0 // Disabling this allows inside edges to render below the planes, for until the clipping is fixed to work right when POs are near the camera. -Red if (curline->dontrenderme && curline->polyseg && (curline->polyseg->flags & POF_RENDERPLANES)) @@ -535,7 +559,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) } else #endif - colfunc_2s(col); + colfunc_2s(col, bmCol); } spryscale += rw_scalestep; } @@ -544,10 +568,10 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) } // Loop through R_DrawMaskedColumn calls -static void R_DrawRepeatMaskedColumn(column_t *col) +static void R_DrawRepeatMaskedColumn(column_t *col, column_t *bm) { while (sprtopscreen < sprbotscreen) { - R_DrawMaskedColumn(col); + R_DrawMaskedColumn(col, bm); if ((INT64)sprtopscreen + dc_texheight*spryscale > (INT64)INT32_MAX) // prevent overflow sprtopscreen = INT32_MAX; else @@ -555,10 +579,10 @@ static void R_DrawRepeatMaskedColumn(column_t *col) } } -static void R_DrawRepeatFlippedMaskedColumn(column_t *col) +static void R_DrawRepeatFlippedMaskedColumn(column_t *col, column_t *bm) { do { - R_DrawFlippedMaskedColumn(col); + R_DrawFlippedMaskedColumn(col, bm); sprtopscreen += dc_texheight*spryscale; } while (sprtopscreen < sprbotscreen); } @@ -582,9 +606,9 @@ static boolean R_IsFFloorTranslucent(visffloor_t *pfloor) void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) { size_t pindex; - column_t * col; + column_t * col, *bmCol = NULL; INT32 lightnum; - INT32 texnum; + INT32 texnum, bmnum; sector_t tempsec; INT32 templight; INT32 i, p; @@ -605,7 +629,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) fixed_t left_top, left_bottom; // needed here for slope skewing pslope_t *skewslope = NULL; - void (*colfunc_2s) (column_t *); + void (*colfunc_2s) (column_t *, column_t *); // Calculate light table. // Use different light tables @@ -616,6 +640,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) backsector = pfloor->target; frontsector = curline->frontsector == pfloor->target ? curline->backsector : curline->frontsector; texnum = R_GetTextureNum(sides[pfloor->master->sidenum[0]].midtexture); + bmnum = R_GetTextureBrightmap(texnum); colfunc = colfuncs[BASEDRAWFUNC]; @@ -624,6 +649,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) size_t linenum = curline->linedef-backsector->lines[0]; newline = pfloor->master->frontsector->lines[0] + linenum; texnum = R_GetTextureNum(sides[newline->sidenum[0]].midtexture); + bmnum = R_GetTextureBrightmap(texnum); } if (pfloor->flags & FF_TRANSLUCENT) @@ -833,6 +859,8 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) // Texture must be cached before setting colfunc_2s, // otherwise texture[texnum]->holes may be false when it shouldn't be R_CheckTextureCache(texnum); + if (bmnum) { R_CheckTextureCache(bmnum); } + //faB: handle case where multipatch texture is drawn on a 2sided wall, multi-patch textures // are not stored per-column with post info anymore in Doom Legacy if (textures[texnum]->holes) @@ -916,6 +944,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) // Get data for the column col = (column_t *)((UINT8 *)R_GetColumn(texnum,maskedtexturecol[dc_x]) - 3); + if (bmnum) { bmCol = (column_t *)((UINT8 *)R_GetColumn(bmnum, maskedtexturecol[dc_x]) - 3); } // SoM: New code does not rely on R_DrawColumnShadowed_8 which // will (hopefully) put less strain on the stack. @@ -998,8 +1027,12 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) if (lighteffect) { dc_colormap = rlight->rcolormap; + dc_fullbright = colormaps; if (encoremap && !(curline->linedef->flags & ML_TFERLINE)) + { dc_colormap += COLORMAP_REMAPOFFSET; + dc_fullbright += COLORMAP_REMAPOFFSET; + } } if (solid && windowtop < bheight) windowtop = bheight; @@ -1011,7 +1044,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) { windowbottom = sprbotscreen; // draw the texture - colfunc_2s (col); + colfunc_2s (col, bmCol); for (i++; i < dc_numlights; i++) { rlight = &dc_lightlist[i]; @@ -1022,7 +1055,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) continue; } // draw the texture - colfunc_2s (col); + colfunc_2s (col, bmCol); if (solid) windowtop = bheight; else @@ -1030,14 +1063,18 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) if (lighteffect) { dc_colormap = rlight->rcolormap; + dc_fullbright = colormaps; if (encoremap && !(curline->linedef->flags & ML_TFERLINE)) + { dc_colormap += COLORMAP_REMAPOFFSET; + dc_fullbright += COLORMAP_REMAPOFFSET; + } } } windowbottom = sprbotscreen; // draw the texture, if there is any space left if (windowtop < windowbottom) - colfunc_2s (col); + colfunc_2s (col, bmCol); spryscale += rw_scalestep; continue; @@ -1050,9 +1087,13 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) pindex = MAXLIGHTSCALE - 1; dc_colormap = walllights[pindex]; + dc_fullbright = colormaps; if (encoremap && !(curline->linedef->flags & ML_TFERLINE)) + { dc_colormap += COLORMAP_REMAPOFFSET; + dc_fullbright += COLORMAP_REMAPOFFSET; + } if (pfloor->flags & FF_FOG && pfloor->master->frontsector->extra_colormap) dc_colormap = pfloor->master->frontsector->extra_colormap->colormap + (dc_colormap - colormaps); @@ -1060,7 +1101,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor) dc_colormap = frontsector->extra_colormap->colormap + (dc_colormap - colormaps); // draw the texture - colfunc_2s (col); + colfunc_2s (col, bmCol); spryscale += rw_scalestep; } } @@ -1311,8 +1352,12 @@ static void R_RenderSegLoop (void) pindex = MAXLIGHTSCALE-1; dc_colormap = walllights[pindex]; + dc_fullbright = colormaps; if (encoremap && !(curline->linedef->flags & ML_TFERLINE)) + { dc_colormap += COLORMAP_REMAPOFFSET; + dc_fullbright += COLORMAP_REMAPOFFSET; + } dc_x = rw_x; dc_iscale = 0xffffffffu / (unsigned)rw_scale; @@ -1366,6 +1411,7 @@ static void R_RenderSegLoop (void) dc_yh = yh; dc_texturemid = rw_midtexturemid; dc_source = R_GetColumn(midtexture,texturecolumn); + dc_brightmap = (midbrightmap ? R_GetColumn(midbrightmap, texturecolumn) : NULL); dc_texheight = textureheight[midtexture]>>FRACBITS; //profile stuff --------------------------------------------------------- @@ -1427,6 +1473,7 @@ static void R_RenderSegLoop (void) dc_yh = mid; dc_texturemid = rw_toptexturemid; dc_source = R_GetColumn(toptexture,texturecolumn); + dc_brightmap = (topbrightmap ? R_GetColumn(topbrightmap, texturecolumn) : NULL); dc_texheight = textureheight[toptexture]>>FRACBITS; colfunc(); ceilingclip[rw_x] = (INT16)mid; @@ -1462,8 +1509,8 @@ static void R_RenderSegLoop (void) dc_yl = mid; dc_yh = yh; dc_texturemid = rw_bottomtexturemid; - dc_source = R_GetColumn(bottomtexture, - texturecolumn); + dc_source = R_GetColumn(bottomtexture,texturecolumn); + dc_brightmap = (bottombrightmap ? R_GetColumn(bottombrightmap, texturecolumn) : NULL); dc_texheight = textureheight[bottomtexture]>>FRACBITS; colfunc(); floorclip[rw_x] = (INT16)mid; @@ -1738,6 +1785,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) worldbottomslope -= viewz; midtexture = toptexture = bottomtexture = maskedtexture = 0; + midbrightmap = topbrightmap = bottombrightmap = 0; ds_p->maskedtexturecol = NULL; ds_p->numthicksides = numthicksides = 0; ds_p->thicksidecol = NULL; @@ -1785,6 +1833,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) fixed_t texheight; // single sided line midtexture = R_GetTextureNum(sidedef->midtexture); + midbrightmap = R_GetTextureBrightmap(midtexture); texheight = textureheight[midtexture]; // a single sided line is terminal, so it must mark ends markfloor = markceiling = true; @@ -2021,11 +2070,14 @@ void R_StoreWallRange(INT32 start, INT32 stop) if (!toptexture) //Second side has no texture, use the first side's instead. toptexture = R_GetTextureNum(sidedef->toptexture); + + topbrightmap = R_GetTextureBrightmap(toptexture); texheight = textureheight[toptexture]; } else { toptexture = R_GetTextureNum(sidedef->toptexture); + topbrightmap = R_GetTextureBrightmap(toptexture); texheight = textureheight[toptexture]; } if (!(linedef->flags & ML_EFFECT1)) { // Ignore slopes for lower/upper textures unless flag is checked @@ -2052,6 +2104,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) { // bottom texture bottomtexture = R_GetTextureNum(sidedef->bottomtexture); + bottombrightmap = R_GetTextureBrightmap(bottomtexture); if (!(linedef->flags & ML_EFFECT1)) { // Ignore slopes for lower/upper textures unless flag is checked if (linedef->flags & ML_DONTPEGBOTTOM) diff --git a/src/r_state.h b/src/r_state.h index 6f9008cc7..dc577448e 100644 --- a/src/r_state.h +++ b/src/r_state.h @@ -54,6 +54,9 @@ extern extracolormap_t *extra_colormaps; // for global animation extern INT32 *texturetranslation; +// for brightmaps +extern INT32 *texturebrightmaps; + // Sprites extern size_t numspritelumps, max_spritelumps; diff --git a/src/r_textures.c b/src/r_textures.c index df7709374..c08feeece 100644 --- a/src/r_textures.c +++ b/src/r_textures.c @@ -55,6 +55,7 @@ INT32 *texturewidth; fixed_t *textureheight; // needed for texture pegging INT32 *texturetranslation; +INT32 *texturebrightmaps; // Painfully simple texture id cacheing to make maps load faster. :3 static struct { @@ -500,6 +501,20 @@ INT32 R_GetTextureNum(INT32 texnum) return texturetranslation[texnum]; } +// +// R_GetTextureBrightmap +// +// Returns the actual texture id that we should use. +// This can either be the texture's brightmap, +// or 0 if not valid. +// +INT32 R_GetTextureBrightmap(INT32 texnum) +{ + if (texnum < 0 || texnum >= numtextures) + return 0; + return texturebrightmaps[texnum]; +} + // // R_CheckTextureCache // @@ -944,6 +959,7 @@ void R_LoadTextures(void) Z_Free(textures[i]); Z_Free(texturecache[i]); } + Z_Free(texturebrightmaps); Z_Free(texturetranslation); Z_Free(textures); } @@ -1044,9 +1060,14 @@ void R_LoadTextures(void) textureheight = (void *)((UINT8 *)textures + ((numtextures * sizeof(void *)) * 4)); // Create translation table for global animation. texturetranslation = Z_Malloc((numtextures + 1) * sizeof(*texturetranslation), PU_STATIC, NULL); + // Create brightmap texture table. + texturebrightmaps = Z_Malloc((numtextures + 1) * sizeof(*texturebrightmaps), PU_STATIC, NULL); for (i = 0; i < numtextures; i++) + { texturetranslation[i] = i; + texturebrightmaps[i] = 0; + } for (i = 0, w = 0; w < numwadfiles; w++) { diff --git a/src/r_textures.h b/src/r_textures.h index 6e0cc168a..dada043a6 100644 --- a/src/r_textures.h +++ b/src/r_textures.h @@ -82,6 +82,7 @@ void R_FlushTextureCache(void); UINT8 *R_GenerateTexture(size_t texnum); UINT8 *R_GenerateTextureAsFlat(size_t texnum); INT32 R_GetTextureNum(INT32 texnum); +INT32 R_GetTextureBrightmap(INT32 texnum); void R_CheckTextureCache(INT32 tex); void R_ClearTextureNumCache(boolean btell); diff --git a/src/r_things.c b/src/r_things.c index eccbe7e23..134c21dae 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -602,7 +602,7 @@ INT16 *mceilingclip; fixed_t spryscale = 0, sprtopscreen = 0, sprbotscreen = 0; fixed_t windowtop = 0, windowbottom = 0; -void R_DrawMaskedColumn(column_t *column) +void R_DrawMaskedColumn(column_t *column, column_t *brightmap) { INT32 topscreen; INT32 bottomscreen; @@ -610,6 +610,7 @@ void R_DrawMaskedColumn(column_t *column) INT32 topdelta, prevdelta = 0; basetexturemid = dc_texturemid; + dc_brightmap = NULL; for (; column->topdelta != 0xff ;) { @@ -645,6 +646,11 @@ void R_DrawMaskedColumn(column_t *column) if (dc_yl <= dc_yh && dc_yh > 0) { dc_source = (UINT8 *)column + 3; + if (brightmap != NULL) + { + dc_brightmap = (UINT8 *)brightmap + 3; + } + dc_texturemid = basetexturemid - (topdelta<length + 4); + if (brightmap != NULL) + { + brightmap = (column_t *)((UINT8 *)brightmap + brightmap->length + 4); + } } dc_texturemid = basetexturemid; @@ -666,7 +676,7 @@ void R_DrawMaskedColumn(column_t *column) INT32 lengthcol; // column->length : for flipped column function pointers and multi-patch on 2sided wall = texture->height -void R_DrawFlippedMaskedColumn(column_t *column) +void R_DrawFlippedMaskedColumn(column_t *column, column_t *brightmap) { INT32 topscreen; INT32 bottomscreen; @@ -674,6 +684,8 @@ void R_DrawFlippedMaskedColumn(column_t *column) INT32 topdelta, prevdelta = -1; UINT8 *d,*s; + dc_brightmap = NULL; + for (; column->topdelta != 0xff ;) { // calculate unclipped screen coordinates @@ -712,6 +724,14 @@ void R_DrawFlippedMaskedColumn(column_t *column) dc_source = ZZ_Alloc(column->length); for (s = (UINT8 *)column+2+column->length, d = dc_source; d < dc_source+column->length; --s) *d++ = *s; + + if (brightmap != NULL) + { + dc_brightmap = ZZ_Alloc(brightmap->length); + for (s = (UINT8 *)brightmap+2+brightmap->length, d = dc_brightmap; d < dc_brightmap+brightmap->length; --s) + *d++ = *s; + } + dc_texturemid = basetexturemid - (topdelta<length + 4); + if (brightmap != NULL) + { + brightmap = (column_t *)((UINT8 *)brightmap + brightmap->length + 4); + } } dc_texturemid = basetexturemid; @@ -779,7 +803,7 @@ UINT8 *R_GetSpriteTranslation(vissprite_t *vis) static void R_DrawVisSprite(vissprite_t *vis) { column_t *column; - void (*localcolfunc)(column_t *); + void (*localcolfunc)(column_t *, column_t *); INT32 texturecolumn; INT32 pwidth; fixed_t frac; @@ -805,6 +829,7 @@ static void R_DrawVisSprite(vissprite_t *vis) colfunc = colfuncs[BASEDRAWFUNC]; // hack: this isn't resetting properly somewhere. dc_colormap = vis->colormap; + dc_fullbright = colormaps; dc_translation = R_GetSpriteTranslation(vis); if (R_SpriteIsFlashing(vis)) // Bosses "flash" @@ -834,8 +859,13 @@ static void R_DrawVisSprite(vissprite_t *vis) if (!dc_colormap) dc_colormap = colormaps; + dc_fullbright = colormaps; + if (encoremap && !vis->mobj->color && !(vis->mobj->flags & MF_DONTENCOREMAP)) - dc_colormap += COLORMAP_REMAPOFFSET; + { + dc_colormap += COLORMAP_REMAPOFFSET; + dc_fullbright += COLORMAP_REMAPOFFSET; + } dc_texturemid = vis->texturemid; dc_texheight = 0; @@ -908,7 +938,7 @@ static void R_DrawVisSprite(vissprite_t *vis) column = (column_t *)((UINT8 *)patch->columns + (patch->columnofs[texturecolumn])); - localcolfunc (column); + localcolfunc (column, NULL); } } else if (vis->cut & SC_SHEAR) @@ -930,7 +960,7 @@ static void R_DrawVisSprite(vissprite_t *vis) #endif sprtopscreen = (centeryfrac - FixedMul(dc_texturemid, spryscale)); - localcolfunc (column); + localcolfunc (column, NULL); } } else @@ -950,7 +980,7 @@ static void R_DrawVisSprite(vissprite_t *vis) #else column = (column_t *)((UINT8 *)patch->columns + (patch->columnofs[frac>>FRACBITS])); #endif - localcolfunc (column); + localcolfunc (column, NULL); } } @@ -989,8 +1019,12 @@ static void R_DrawPrecipitationVisSprite(vissprite_t *vis) } dc_colormap = colormaps; + dc_fullbright = colormaps; if (encoremap) + { dc_colormap += COLORMAP_REMAPOFFSET; + dc_fullbright += COLORMAP_REMAPOFFSET; + } dc_iscale = FixedDiv(FRACUNIT, vis->scale); dc_texturemid = vis->texturemid; @@ -1019,7 +1053,7 @@ static void R_DrawPrecipitationVisSprite(vissprite_t *vis) #else column = (column_t *)((UINT8 *)patch->columns + (patch->columnofs[frac>>FRACBITS])); #endif - R_DrawMaskedColumn(column); + R_DrawMaskedColumn(column, NULL); } colfunc = colfuncs[BASEDRAWFUNC]; diff --git a/src/r_things.h b/src/r_things.h index cbbb0f2d8..7ff1bd4c7 100644 --- a/src/r_things.h +++ b/src/r_things.h @@ -47,8 +47,8 @@ extern fixed_t windowtop; extern fixed_t windowbottom; extern INT32 lengthcol; -void R_DrawMaskedColumn(column_t *column); -void R_DrawFlippedMaskedColumn(column_t *column); +void R_DrawMaskedColumn(column_t *column, column_t *brightmap); +void R_DrawFlippedMaskedColumn(column_t *column, column_t *brightmap); // ---------------- // SPRITE RENDERING