Merge branch 'brightmap-conversion' into 'master'

Convert BRIGHTMAP texture columns to match associated texture

See merge request KartKrew/Kart!1473
This commit is contained in:
Oni 2023-09-10 19:50:25 +00:00
commit 87d7cae5d3
8 changed files with 351 additions and 57 deletions

View file

@ -551,6 +551,7 @@ void D_RegisterClientCommands(void)
COM_AddDebugCommand("goto", Command_Goto_f);
COM_AddDebugCommand("angle", Command_Angle_f);
COM_AddDebugCommand("respawnat", Command_RespawnAt_f);
COM_AddDebugCommand("goto_skybox", Command_GotoSkybox_f);
{
extern struct CVarList *cvlist_player;

View file

@ -640,6 +640,23 @@ void Command_RespawnAt_f(void)
D_Cheat(consoleplayer, CHEAT_RESPAWNAT, atoi(COM_Argv(1)));
}
void Command_GotoSkybox_f(void)
{
REQUIRE_CHEATS;
REQUIRE_INLEVEL;
mobj_t *skybox = players[consoleplayer].skybox.viewpoint;
if (P_MobjWasRemoved(skybox))
{
CONS_Printf("There is no visible skybox for local Player 1.\n");
return;
}
D_Cheat(consoleplayer, CHEAT_TELEPORT, skybox->x, skybox->y, skybox->z);
D_Cheat(consoleplayer, CHEAT_ANGLE, skybox->angle);
}
//
// OBJECTPLACE (and related variables)
//

View file

@ -91,6 +91,7 @@ void Command_Grayscale_f(void);
void Command_Goto_f(void);
void Command_Angle_f(void);
void Command_RespawnAt_f(void);
void Command_GotoSkybox_f(void);
#ifdef _DEBUG
void Command_CauseCfail_f(void);
#endif

View file

@ -1029,6 +1029,9 @@ void R_DrawSinglePlane(visplane_t *pl)
INT32 bmNum = R_GetTextureBrightmap(levelflat->u.texture.num);
if (bmNum != 0)
{
// FIXME: This has the potential to read out of
// bounds if the brightmap texture is not as
// large as the flat.
ds_brightmap = (UINT8 *)R_GenerateTextureAsFlat(bmNum);
}
}

View file

@ -40,7 +40,7 @@ static boolean markceiling;
static boolean maskedtexture;
static INT32 toptexture, bottomtexture, midtexture;
static INT32 topbrightmap, bottombrightmap, midbrightmap;
static bool topbrightmapped, bottombrightmapped, midbrightmapped;
static INT32 numthicksides, numbackffloors;
angle_t rw_normalangle;
@ -160,7 +160,7 @@ static inline boolean R_OverflowTest(void)
return false;
}
static void R_RenderMaskedSegLoop(drawseg_t *ds, INT32 x1, INT32 x2, INT32 texnum, INT32 bmnum, void (*colfunc_2s)(column_t *, column_t *, INT32))
static void R_RenderMaskedSegLoop(drawseg_t *ds, INT32 x1, INT32 x2, INT32 texnum, void (*colfunc_2s)(column_t *, column_t *, INT32))
{
size_t pindex;
column_t *col, *bmCol = NULL;
@ -173,6 +173,7 @@ static void R_RenderMaskedSegLoop(drawseg_t *ds, INT32 x1, INT32 x2, INT32 texnu
sector_t *front, *back;
INT32 times, repeats;
boolean tripwire;
boolean brightmapped = R_TextureHasBrightmap(texnum);
ldef = curline->linedef;
tripwire = P_IsLineTripWire(ldef);
@ -350,7 +351,11 @@ static void R_RenderMaskedSegLoop(drawseg_t *ds, INT32 x1, INT32 x2, INT32 texnu
// 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 (brightmapped)
{
bmCol = (column_t *)((UINT8 *)R_GetBrightmapColumn(texnum, maskedtexturecol[dc_x]) - 3);
}
for (i = 0; i < dc_numlights; i++)
{
@ -449,7 +454,11 @@ static void R_RenderMaskedSegLoop(drawseg_t *ds, INT32 x1, INT32 x2, INT32 texnu
// 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 (brightmapped)
{
bmCol = (column_t *)((UINT8 *)R_GetBrightmapColumn(texnum, 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))
@ -557,7 +566,7 @@ static INT32 R_GetTwoSidedMidTexture(seg_t *line)
return R_GetTextureNum(texture);
}
static boolean R_CheckBlendMode(const line_t *ldef, INT32 bmnum)
static boolean R_CheckBlendMode(const line_t *ldef, boolean brightmapped)
{
transnum_t transtable = NUMTRANSMAPS;
patchalphastyle_t blendmode = AST_COPY;
@ -578,18 +587,18 @@ static boolean R_CheckBlendMode(const line_t *ldef, INT32 bmnum)
if (blendmode == AST_FOG)
{
R_SetColumnFunc(COLDRAWFUNC_FOG, bmnum != 0);
R_SetColumnFunc(COLDRAWFUNC_FOG, brightmapped);
windowtop = frontsector->ceilingheight;
windowbottom = frontsector->floorheight;
}
else if (transtable != NUMTRANSMAPS && (blendmode || transtable))
{
dc_transmap = R_GetBlendTable(blendmode, transtable);
R_SetColumnFunc(COLDRAWFUNC_FUZZY, bmnum != 0);
R_SetColumnFunc(COLDRAWFUNC_FUZZY, brightmapped);
}
else
{
R_SetColumnFunc(BASEDRAWFUNC, bmnum != 0);
R_SetColumnFunc(BASEDRAWFUNC, brightmapped);
}
if (curline->polyseg && curline->polyseg->translucency > 0)
@ -598,7 +607,7 @@ static boolean R_CheckBlendMode(const line_t *ldef, INT32 bmnum)
return false;
dc_transmap = R_GetTranslucencyTable(curline->polyseg->translucency);
R_SetColumnFunc(COLDRAWFUNC_FUZZY, bmnum != 0);
R_SetColumnFunc(COLDRAWFUNC_FUZZY, brightmapped);
}
return true;
@ -606,7 +615,7 @@ static boolean R_CheckBlendMode(const line_t *ldef, INT32 bmnum)
void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
{
INT32 texnum, bmnum;
INT32 texnum;
void (*colfunc_2s)(column_t *, column_t *, INT32);
line_t *ldef;
const boolean debug = R_IsDebugLine(ds->curline);
@ -620,14 +629,13 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
frontsector = curline->frontsector;
backsector = curline->backsector;
texnum = R_GetTwoSidedMidTexture(curline);
bmnum = R_GetTextureBrightmap(texnum);
windowbottom = windowtop = sprbotscreen = INT32_MAX;
ldef = curline->linedef;
R_CheckDebugHighlight(SW_HI_MIDTEXTURES);
if (debug == false && R_CheckBlendMode(ldef, bmnum) == false)
if (debug == false && R_CheckBlendMode(ldef, R_TextureHasBrightmap(texnum)) == false)
{
return; // does not render
}
@ -638,7 +646,6 @@ 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
@ -671,7 +678,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
}
else
{
R_RenderMaskedSegLoop(ds, x1, x2, texnum, bmnum, colfunc_2s);
R_RenderMaskedSegLoop(ds, x1, x2, texnum, colfunc_2s);
}
R_SetColumnFunc(BASEDRAWFUNC, false);
@ -719,7 +726,7 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
size_t pindex = 0;
column_t * col, *bmCol = NULL;
INT32 lightnum;
INT32 texnum, bmnum;
INT32 texnum;
sector_t tempsec;
INT32 templight;
INT32 i, p;
@ -751,20 +758,20 @@ 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);
R_CheckDebugHighlight(SW_HI_FOFSIDES);
R_SetColumnFunc(BASEDRAWFUNC, bmnum != 0);
if (pfloor->master->flags & ML_TFERLINE)
{
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);
}
boolean brightmapped = R_TextureHasBrightmap(texnum);
R_SetColumnFunc(BASEDRAWFUNC, brightmapped);
if (pfloor->fofflags & FOF_TRANSLUCENT)
{
boolean fuzzy = true;
@ -781,12 +788,12 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
if (fuzzy)
{
R_SetColumnFunc(COLDRAWFUNC_FUZZY, bmnum != 0);
R_SetColumnFunc(COLDRAWFUNC_FUZZY, brightmapped);
}
}
else if (pfloor->fofflags & FOF_FOG)
{
R_SetColumnFunc(COLDRAWFUNC_FOG, bmnum != 0);
R_SetColumnFunc(COLDRAWFUNC_FOG, brightmapped);
}
range = std::max(ds->x2-ds->x1, 1);
@ -980,7 +987,6 @@ 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
@ -1065,7 +1071,11 @@ 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); }
if (brightmapped)
{
bmCol = (column_t *)((UINT8 *)R_GetBrightmapColumn(texnum, maskedtexturecol[dc_x]) - 3);
}
// SoM: New code does not rely on R_DrawColumnShadowed_8 which
// will (hopefully) put less strain on the stack.
@ -1276,13 +1286,13 @@ UINT32 nombre = 100000;
#endif
//profile stuff ---------------------------------------------------------
static void R_DrawWallColumn(INT32 yl, INT32 yh, fixed_t mid, fixed_t texturecolumn, INT32 texture, INT32 brightmap)
static void R_DrawWallColumn(INT32 yl, INT32 yh, fixed_t mid, fixed_t texturecolumn, INT32 texture, boolean brightmapped)
{
dc_yl = yl;
dc_yh = yh;
dc_texturemid = mid;
dc_source = R_GetColumn(texture, texturecolumn);
dc_brightmap = (brightmap ? R_GetColumn(brightmap, texturecolumn) : NULL);
dc_brightmap = (brightmapped ? R_GetBrightmapColumn(texture, texturecolumn) : NULL);
dc_texheight = textureheight[texture] >> FRACBITS;
R_SetColumnFunc(colfunctype, dc_brightmap != NULL);
colfunc();
@ -1560,7 +1570,7 @@ static void R_RenderSegLoop (void)
// single sided line
if (yl <= yh && yh >= 0 && yl < viewheight)
{
R_DrawWallColumn(yl, yh, rw_midtexturemid, texturecolumn, midtexture, midbrightmap);
R_DrawWallColumn(yl, yh, rw_midtexturemid, texturecolumn, midtexture, midbrightmapped);
// dont draw anything more for this column, since
// a midtexture blocks the view
@ -1599,7 +1609,7 @@ static void R_RenderSegLoop (void)
}
else if (mid >= 0) // safe to draw top texture
{
R_DrawWallColumn(yl, mid, rw_toptexturemid, texturecolumn, toptexture, topbrightmap);
R_DrawWallColumn(yl, mid, rw_toptexturemid, texturecolumn, toptexture, topbrightmapped);
ceilingclip[rw_x] = (INT16)mid;
}
else if (!rw_ceilingmarked) // entirely off top of screen
@ -1630,7 +1640,7 @@ static void R_RenderSegLoop (void)
}
else if (mid < viewheight) // safe to draw bottom texture
{
R_DrawWallColumn(mid, yh, rw_bottomtexturemid, texturecolumn, bottomtexture, bottombrightmap);
R_DrawWallColumn(mid, yh, rw_bottomtexturemid, texturecolumn, bottomtexture, bottombrightmapped);
floorclip[rw_x] = (INT16)mid;
}
else if (!rw_floormarked) // entirely off bottom of screen
@ -1914,7 +1924,7 @@ void R_StoreWallRange(INT32 start, INT32 stop)
worldbottomslope -= viewz;
midtexture = toptexture = bottomtexture = maskedtexture = 0;
midbrightmap = topbrightmap = bottombrightmap = 0;
midbrightmapped = topbrightmapped = bottombrightmapped = false;
ds_p->maskedtexturecol = NULL;
ds_p->numthicksides = numthicksides = 0;
ds_p->thicksidecol = NULL;
@ -1962,7 +1972,7 @@ void R_StoreWallRange(INT32 start, INT32 stop)
fixed_t texheight;
// single sided line
midtexture = R_GetTextureNum(sidedef->midtexture);
midbrightmap = R_GetTextureBrightmap(midtexture);
midbrightmapped = R_TextureHasBrightmap(midtexture);
texheight = textureheight[midtexture];
// a single sided line is terminal, so it must mark ends
markfloor = markceiling = true;
@ -2150,7 +2160,7 @@ void R_StoreWallRange(INT32 start, INT32 stop)
fixed_t texheight;
// top texture
toptexture = R_GetTextureNum(sidedef->toptexture);
topbrightmap = R_GetTextureBrightmap(toptexture);
topbrightmapped = R_TextureHasBrightmap(toptexture);
texheight = textureheight[toptexture];
if (!(linedef->flags & ML_SKEWTD))
@ -2179,7 +2189,7 @@ void R_StoreWallRange(INT32 start, INT32 stop)
{
// bottom texture
bottomtexture = R_GetTextureNum(sidedef->bottomtexture);
bottombrightmap = R_GetTextureBrightmap(bottomtexture);
bottombrightmapped = R_TextureHasBrightmap(bottomtexture);
if (!(linedef->flags & ML_SKEWTD))
{

View file

@ -50,6 +50,7 @@ INT32 numtextures = 0; // total number of textures found,
texture_t **textures = NULL;
UINT32 **texturecolumnofs; // column offset lookup table for each texture
UINT8 **texturecache; // graphics data for each generated full-size texture
UINT8 **texturebrightmapcache; // graphics data for brightmap converted for use with a specific texture
INT32 *texturewidth;
fixed_t *textureheight; // needed for texture pegging
@ -249,6 +250,50 @@ static inline void R_DrawBlendFlippedColumnInCache(column_t *patch, UINT8 *cache
}
}
static UINT8 *R_AllocateTextureBlock(size_t blocksize, UINT8 **user)
{
texturememory += blocksize;
return Z_Malloc(blocksize, PU_CACHE, user);
}
static UINT8 *R_AllocateDummyTextureBlock(size_t width, UINT8 **user)
{
// Allocate dummy data. Keep 4-bytes aligned.
// Column offsets will be initialized to 0, which points to the 0xff byte (empty column flag).
size_t blocksize = 4 + (width * 4);
UINT8 *block = R_AllocateTextureBlock(blocksize, user);
memset(block, 0, blocksize);
block[0] = 0xff;
return block;
}
static boolean R_CheckTextureLumpLength(texture_t *texture, size_t patch)
{
UINT16 wadnum = texture->patches[patch].wad;
UINT16 lumpnum = texture->patches[patch].lump;
size_t lumplength = W_LumpLengthPwad(wadnum, lumpnum);
// The header does not exist
if (lumplength < offsetof(softwarepatch_t, columnofs))
{
CONS_Alert(
CONS_ERROR,
"%.8s: texture lump data is too small. Expected %s bytes, got %s. (%s)\n",
texture->name,
sizeu1(offsetof(softwarepatch_t, columnofs)),
sizeu2(lumplength),
wadfiles[wadnum]->lumpinfo[lumpnum].fullname
);
return false;
}
return true;
}
//
// R_GenerateTexture
//
@ -297,22 +342,11 @@ UINT8 *R_GenerateTexture(size_t texnum)
lumplength = W_LumpLengthPwad(wadnum, lumpnum);
// The header does not exist
if (lumplength < offsetof(softwarepatch_t, columnofs))
if (R_CheckTextureLumpLength(texture, 0) == false)
{
CONS_Alert(
CONS_ERROR,
"%.8s: texture lump data is too small. Expected %s bytes, got %s. (%s)\n",
texture->name,
sizeu1(offsetof(softwarepatch_t, columnofs)),
sizeu2(lumplength),
wadfiles[wadnum]->lumpinfo[lumpnum].fullname
);
// Allocate dummy data. Keep 4-bytes aligned.
// Column offsets will be initialized to 0, which points to the 0xff byte (empty column flag).
block = Z_Calloc(4 + (texture->width * 4), PU_CACHE, &texturecache[texnum]);
block[0] = 0xff;
block = R_AllocateDummyTextureBlock(texture->width, &texturecache[texnum]);
texturecolumnofs[texnum] = (UINT32*)&block[4];
textures[texnum]->holes = true;
return block;
}
@ -511,6 +545,202 @@ UINT8 *R_GenerateTextureAsFlat(size_t texnum)
return texture->flat;
}
// This function writes a column to p, using the posts from
// tcol, but the pixel values from bcol. If bcol is larger
// than tcol, the pixels are cropped. If bcol is smaller than
// tcol, the empty space is filled with TRANSPARENTPIXEL.
static void R_ConvertBrightmapColumn(UINT8 *p, const column_t *tcol, const column_t *bcol)
{
/*
___t1
|
| ___b1
| |
| |
|__t2 |
| |__b2
|
| ___b3
|__t3 |
|
___t4 |
| |__b4
|__t5
___t6
|__t7
*/
// copy post header
memcpy(&p[-3], tcol, 3);
INT32 ttop = tcol->topdelta;
INT32 btop = bcol->topdelta;
INT32 y = ttop;
while (tcol->topdelta != 0xff && bcol->topdelta != 0xff)
{
INT32 tbot = ttop + tcol->length;
INT32 bbot = btop + bcol->length;
INT32 n;
// t1 to b1
// b2 to b3
// --------
// The brightmap column starts below the
// texture column, so pad it with black
// pixels.
n = max(0, min(btop, tbot) - y);
memset(&p[y - ttop], TRANSPARENTPIXEL, n);
y += n;
// b1 to t2
// t2 to b2
// b3 to t3
// t4 to b4
// --------
// Copy parts of the brightmap column which
// line up with the texture column.
n = max(0, min(bbot, tbot) - y);
memcpy(&p[y - ttop], (const UINT8*)bcol + 3 + (y - btop), n);
y += n;
if (y == tbot)
{
p += 4 + tcol->length;
tcol = (const column_t*)((const UINT8*)tcol + 4 + tcol->length);
memcpy(&p[-3], tcol, 3); // copy post header
// Tall patches add the topdelta if it is less
// than the running topdelta.
ttop = tcol->topdelta <= ttop ? ttop + tcol->topdelta : tcol->topdelta;
y = ttop;
}
if (y >= bbot)
{
bcol = (const column_t*)((const UINT8*)bcol + 4 + bcol->length);
btop = bcol->topdelta <= btop ? btop + bcol->topdelta : bcol->topdelta; // tall patches
}
}
if (tcol->topdelta != 0xff)
{
// b4 to t5
// t6 to t7
// --------
// The texture column continues past the end
// of the brightmap column, so pad it with
// black pixels.
y -= ttop;
memset(&p[y], TRANSPARENTPIXEL, tcol->length - y);
while
(
(
p += 4 + tcol->length,
tcol = (const column_t*)((const UINT8*)tcol + 4 + tcol->length)
)->topdelta != 0xff
)
{
memcpy(&p[-3], tcol, 3); // copy post header
memset(p, TRANSPARENTPIXEL, tcol->length);
}
}
p[-3] = 0xff;
}
// Remember, this function must generate a texture that
// matches the layout of texnum. It must have the same width
// and same columns. Only the pixels that overlap are copied
// from the brightmap texture.
UINT8 *R_GenerateTextureBrightmap(size_t texnum)
{
texture_t *texture = textures[texnum];
texture_t *bright = textures[R_GetTextureBrightmap(texnum)];
if (R_TextureHasBrightmap(texnum) && bright->patchcount > 1)
{
CONS_Alert(
CONS_WARNING,
"%.8s: BRIGHTMAP should not be a composite texture. Only using the first patch.\n",
bright->name
);
}
if (R_CheckTextureLumpLength(texture, 0) == false)
{
return R_AllocateDummyTextureBlock(texture->width, &texturebrightmapcache[texnum]);
}
R_CheckTextureCache(texnum);
softwarepatch_t *patch = NULL;
INT32 bmap_width = 0;
column_t empty = {0xff, 0};
if (R_TextureHasBrightmap(texnum) && R_CheckTextureLumpLength(bright, 0))
{
patch = W_CacheLumpNumPwad(bright->patches[0].wad, bright->patches[0].lump, PU_STATIC);
bmap_width = SHORT(patch->width);
}
UINT8 *block;
if (texture->holes)
{
block = R_AllocateTextureBlock(
W_LumpLengthPwad(texture->patches[0].wad, texture->patches[0].lump),
&texturebrightmapcache[texnum]
);
INT32 x;
for (x = 0; x < texture->width; ++x)
{
const column_t *tcol = (column_t*)(R_GetColumn(texnum, x) - 3);
const column_t *bcol = x < bmap_width ? (column_t*)((UINT8*)patch + LONG(patch->columnofs[x])) : &empty;
R_ConvertBrightmapColumn(block + LONG(texturecolumnofs[texnum][x]), tcol, bcol);
}
}
else
{
// Allocate the same size as composite textures.
size_t blocksize = (texture->width * 4) + (texture->width * texture->height) + 1;
block = R_AllocateTextureBlock(blocksize, &texturebrightmapcache[texnum]);
memset(block, TRANSPARENTPIXEL, blocksize); // Transparency hack
texpatch_t origin = {0};
INT32 x;
for (x = 0; x < texture->width; ++x)
{
R_DrawColumnInCache(
x < bmap_width ? (column_t*)((UINT8*)patch + LONG(patch->columnofs[x])) : &empty,
block + LONG(texturecolumnofs[texnum][x]),
&origin,
texture->height,
patch->height
);
}
}
Z_Free(patch);
return block;
}
//
// R_GetTextureNum
//
@ -539,6 +769,11 @@ INT32 R_GetTextureBrightmap(INT32 texnum)
return texturebrightmaps[texnum];
}
boolean R_TextureHasBrightmap(INT32 texnum)
{
return R_GetTextureBrightmap(texnum) != 0;
}
//
// R_CheckTextureCache
//
@ -551,12 +786,8 @@ void R_CheckTextureCache(INT32 tex)
R_GenerateTexture(tex);
}
//
// R_GetColumn
//
UINT8 *R_GetColumn(fixed_t tex, INT32 col)
static inline INT32 wrap_column(fixed_t tex, INT32 col)
{
UINT8 *data;
INT32 width = texturewidth[tex];
if (width & (width - 1))
@ -564,11 +795,29 @@ UINT8 *R_GetColumn(fixed_t tex, INT32 col)
else
col &= (width - 1);
data = texturecache[tex];
if (!data)
data = R_GenerateTexture(tex);
return col;
}
return data + LONG(texturecolumnofs[tex][col]);
//
// R_GetColumn
//
UINT8 *R_GetColumn(fixed_t tex, INT32 col)
{
if (!texturecache[tex])
R_GenerateTexture(tex);
return texturecache[tex] + LONG(texturecolumnofs[tex][wrap_column(tex, col)]);
}
//
// R_GetBrightmapColumn
//
UINT8 *R_GetBrightmapColumn(fixed_t tex, INT32 col)
{
if (!texturebrightmapcache[tex])
R_GenerateTextureBrightmap(tex);
return texturebrightmapcache[tex] + LONG(texturecolumnofs[tex][wrap_column(tex, col)]);
}
void *R_GetFlat(lumpnum_t flatlumpnum)
@ -1099,6 +1348,7 @@ static void R_AllocateTextures(INT32 add)
recallocuser(&texturecolumnofs, oldsize, newsize);
// Allocate texture referencing cache.
recallocuser(&texturecache, oldsize, newsize);
recallocuser(&texturebrightmapcache, oldsize, newsize);
// Allocate texture width table.
recallocuser(&texturewidth, oldsize, newsize);
// Allocate texture height table.
@ -1113,8 +1363,8 @@ static void R_AllocateTextures(INT32 add)
// R_FlushTextureCache relies on the user for
// Z_Free, texturecache has been reallocated so the
// user is now garbage memory.
Z_SetUser(texturecache[i],
(void**)&texturecache[i]);
Z_SetUser(texturecache[i], (void**)&texturecache[i]);
Z_SetUser(texturebrightmapcache[i], (void**)&texturebrightmapcache[i]);
}
while (i < newtextures)

View file

@ -80,6 +80,7 @@ extern fixed_t *textureheight; // needed for texture pegging
extern UINT32 **texturecolumnofs; // column offset lookup table for each texture
extern UINT8 **texturecache; // graphics data for each generated full-size texture
extern UINT8 **texturebrightmapcache; // graphics data for brightmap converted for use with a specific texture
// Load TEXTURES definitions, create lookup tables
void R_LoadTextures(void);
@ -89,14 +90,17 @@ void R_FlushTextureCache(void);
// Texture generation
UINT8 *R_GenerateTexture(size_t texnum);
UINT8 *R_GenerateTextureAsFlat(size_t texnum);
UINT8 *R_GenerateTextureBrightmap(size_t texnum);
INT32 R_GetTextureNum(INT32 texnum);
INT32 R_GetTextureBrightmap(INT32 texnum);
boolean R_TextureHasBrightmap(INT32 texnum);
void R_CheckTextureCache(INT32 tex);
void R_ClearTextureNumCache(boolean btell);
// Retrieve texture data.
void *R_GetLevelFlat(levelflat_t *levelflat);
UINT8 *R_GetColumn(fixed_t tex, INT32 col);
UINT8 *R_GetBrightmapColumn(fixed_t tex, INT32 col);
void *R_GetFlat(lumpnum_t flatnum);
boolean R_CheckPowersOfTwo(void);

View file

@ -900,6 +900,14 @@ static void R_DrawVisSprite(vissprite_t *vis)
}
// Prevent an out of bounds error
//
// FIXME: The following check doesn't account for
// differences in transparency between the patches.
//
// Sprite BRIGHTMAPs should be converted on load,
// as like textures. I'm too tired to bother with it
// right now, though.
//
if (bmpatch && (bmpatch->width != patch->width ||
bmpatch->height != patch->height))
{