mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2025-02-28 06:22:05 +00:00
Border textures WIP
This commit is contained in:
parent
36e64cb683
commit
77f9d476de
5 changed files with 700 additions and 123 deletions
|
@ -103,48 +103,51 @@ typedef struct
|
|||
// LineDef attributes.
|
||||
//
|
||||
|
||||
// Solid, is an obstacle.
|
||||
#define ML_IMPASSIBLE 1
|
||||
enum
|
||||
{
|
||||
// Solid, is an obstacle.
|
||||
ML_IMPASSIBLE = 1<<0,
|
||||
|
||||
// Blocks monsters only.
|
||||
#define ML_BLOCKMONSTERS 2
|
||||
// Blocks monsters only.
|
||||
ML_BLOCKMONSTERS = 1<<1,
|
||||
|
||||
// Backside will not be present at all if not two sided.
|
||||
#define ML_TWOSIDED 4
|
||||
// Backside will not be present at all if not two sided.
|
||||
ML_TWOSIDED = 1<<2,
|
||||
|
||||
// If a texture is pegged, the texture will have
|
||||
// the end exposed to air held constant at the
|
||||
// top or bottom of the texture (stairs or pulled
|
||||
// down things) and will move with a height change
|
||||
// of one of the neighbor sectors.
|
||||
// Unpegged textures allways have the first row of
|
||||
// the texture at the top pixel of the line for both
|
||||
// top and bottom textures (use next to windows).
|
||||
// If a texture is pegged, the texture will have
|
||||
// the end exposed to air held constant at the
|
||||
// top or bottom of the texture (stairs or pulled
|
||||
// down things) and will move with a height change
|
||||
// of one of the neighbor sectors.
|
||||
// Unpegged textures allways have the first row of
|
||||
// the texture at the top pixel of the line for both
|
||||
// top and bottom textures (use next to windows).
|
||||
|
||||
// upper texture unpegged
|
||||
#define ML_DONTPEGTOP 8
|
||||
// upper texture unpegged
|
||||
ML_DONTPEGTOP = 1<<3,
|
||||
|
||||
// lower texture unpegged
|
||||
#define ML_DONTPEGBOTTOM 16
|
||||
// lower texture unpegged
|
||||
ML_DONTPEGBOTTOM = 1<<4,
|
||||
|
||||
#define ML_SKEWTD 32
|
||||
ML_SKEWTD = 1<<5,
|
||||
|
||||
// Don't let Knuckles climb on this line
|
||||
#define ML_NOCLIMB 64
|
||||
// Don't let Knuckles climb on this line
|
||||
ML_NOCLIMB = 1<<6,
|
||||
|
||||
#define ML_NOSKEW 128
|
||||
#define ML_MIDPEG 256
|
||||
#define ML_MIDSOLID 512
|
||||
#define ML_WRAPMIDTEX 1024
|
||||
ML_NOSKEW = 1<<7,
|
||||
ML_MIDPEG = 1<<8,
|
||||
ML_MIDSOLID = 1<<9,
|
||||
ML_WRAPMIDTEX = 1<<10,
|
||||
|
||||
#define ML_NETONLY 2048 // Apply effect only in netgames
|
||||
#define ML_NONET 4096 // Apply effect only in single player games
|
||||
#define ML_EFFECT6 8192
|
||||
ML_NETONLY = 1<<11, // Apply effect only in netgames
|
||||
ML_NONET = 1<<12, // Apply effect only in single player games
|
||||
ML_EFFECT6 = 1<<13,
|
||||
|
||||
// Bounce off walls!
|
||||
#define ML_BOUNCY 16384
|
||||
// Bounce off walls!
|
||||
ML_BOUNCY = 1<<14,
|
||||
|
||||
#define ML_TFERLINE 32768
|
||||
ML_TFERLINE = 1<<15
|
||||
};
|
||||
|
||||
// Sector definition, from editing.
|
||||
typedef struct
|
||||
|
|
|
@ -1366,6 +1366,15 @@ static void P_LoadSidedefs(UINT8 *data)
|
|||
sd->scalex_top = sd->scalex_mid = sd->scalex_bottom = FRACUNIT;
|
||||
sd->scaley_top = sd->scaley_mid = sd->scaley_bottom = FRACUNIT;
|
||||
|
||||
sd->flags = 0;
|
||||
|
||||
for (unsigned j = 0; j < NUM_WALL_OVERLAYS; j++)
|
||||
{
|
||||
sd->overlays[j].texture = R_TextureNumForName("-");
|
||||
sd->overlays[j].offsetx = sd->overlays[j].offsety = 0;
|
||||
sd->overlays[j].scalex = sd->overlays[j].scaley = FRACUNIT;
|
||||
}
|
||||
|
||||
P_SetSidedefSector(i, (UINT16)SHORT(msd->sector));
|
||||
|
||||
// Special info stored in texture fields!
|
||||
|
@ -1896,6 +1905,24 @@ static void ParseTextmapSectorParameter(UINT32 i, const char *param, const char
|
|||
}
|
||||
}
|
||||
|
||||
static void ParseTextmapSidedefOverlay(unsigned which, UINT32 i, const char *param, const char *val)
|
||||
{
|
||||
if (fastcmp(param, "texture"))
|
||||
sides[i].overlays[which].texture = R_TextureNumForName(val);
|
||||
else if (fastcmp(param, "offsetx"))
|
||||
sides[i].overlays[which].offsetx = FLOAT_TO_FIXED(atof(val));
|
||||
else if (fastcmp(param, "offsety"))
|
||||
sides[i].overlays[which].offsety = FLOAT_TO_FIXED(atof(val));
|
||||
else if (fastcmp(param, "scalex"))
|
||||
sides[i].overlays[which].scalex = FLOAT_TO_FIXED(atof(val));
|
||||
else if (fastcmp(param, "scaley"))
|
||||
sides[i].overlays[which].scaley = FLOAT_TO_FIXED(atof(val));
|
||||
else if (fastcmp(param, "noskew") && fastcmp("true", val))
|
||||
sides[i].flags |= GET_SIDEFLAG_EDGENOSKEW(which);
|
||||
else if (fastcmp(param, "wrap") && fastcmp("true", val))
|
||||
sides[i].flags |= GET_SIDEFLAG_EDGEWRAP(which);
|
||||
}
|
||||
|
||||
static void ParseTextmapSidedefParameter(UINT32 i, const char *param, const char *val)
|
||||
{
|
||||
if (fastcmp(param, "offsetx"))
|
||||
|
@ -1936,6 +1963,19 @@ static void ParseTextmapSidedefParameter(UINT32 i, const char *param, const char
|
|||
P_SetSidedefSector(i, atol(val));
|
||||
else if (fastcmp(param, "repeatcnt"))
|
||||
sides[i].repeatcnt = atol(val);
|
||||
// Oh God there's a total of 28 fields to read. Uhhh
|
||||
// Okay, so ParseTextmapSidedefOverlay handles the parsing of all the parameters edges have.
|
||||
else if (fastncmp(param, "edge_", 5) && strlen(param) > 5)
|
||||
{
|
||||
if (fastncmp(param, "edge_top_upper_", 15) && strlen(param) > 15)
|
||||
ParseTextmapSidedefOverlay(EDGE_TEXTURE_TOP_UPPER, i, param + 15, val);
|
||||
else if (fastncmp(param, "edge_top_lower_", 15) && strlen(param) > 15)
|
||||
ParseTextmapSidedefOverlay(EDGE_TEXTURE_TOP_LOWER, i, param + 15, val);
|
||||
else if (fastncmp(param, "edge_bottom_upper_", 18) && strlen(param) > 18)
|
||||
ParseTextmapSidedefOverlay(EDGE_TEXTURE_BOTTOM_UPPER, i, param + 18, val);
|
||||
else if (fastncmp(param, "edge_bottom_lower_", 18) && strlen(param) > 18)
|
||||
ParseTextmapSidedefOverlay(EDGE_TEXTURE_BOTTOM_LOWER, i, param + 18, val);
|
||||
}
|
||||
}
|
||||
|
||||
static void ParseTextmapLinedefParameter(UINT32 i, const char *param, const char *val)
|
||||
|
@ -2020,8 +2060,6 @@ static void ParseTextmapLinedefParameter(UINT32 i, const char *param, const char
|
|||
lines[i].flags |= ML_MIDSOLID;
|
||||
else if (fastcmp(param, "wrapmidtex") && fastcmp("true", val))
|
||||
lines[i].flags |= ML_WRAPMIDTEX;
|
||||
/*else if (fastcmp(param, "effect6") && fastcmp("true", val))
|
||||
lines[i].flags |= ML_EFFECT6;*/
|
||||
else if (fastcmp(param, "nonet") && fastcmp("true", val))
|
||||
lines[i].flags |= ML_NONET;
|
||||
else if (fastcmp(param, "netonly") && fastcmp("true", val))
|
||||
|
@ -2190,6 +2228,24 @@ typedef struct
|
|||
mapthing_t *angleanchor;
|
||||
} sectorspecialthings_t;
|
||||
|
||||
static void WriteTextmapEdgeTexture(const char *prefix, unsigned i, side_t *side, FILE *f)
|
||||
{
|
||||
if (side->overlays[i].texture > 0 && side->overlays[i].texture < numtextures)
|
||||
fprintf(f, "%s""texture = \"%.*s\";\n", prefix, 8, textures[side->overlays[i].texture]->name);
|
||||
if (side->overlays[i].offsetx != 0)
|
||||
fprintf(f, "%s""offsetx = %f;\n", prefix, FIXED_TO_FLOAT(side->overlays[i].offsetx));
|
||||
if (side->overlays[i].offsety != 0)
|
||||
fprintf(f, "%s""offsety = %f;\n", prefix, FIXED_TO_FLOAT(side->overlays[i].offsety));
|
||||
if (side->overlays[i].scalex != FRACUNIT)
|
||||
fprintf(f, "%s""scalex = %f;\n", prefix, FIXED_TO_FLOAT(side->overlays[i].scalex));
|
||||
if (side->overlays[i].scaley != FRACUNIT)
|
||||
fprintf(f, "%s""scaley = %f;\n", prefix, FIXED_TO_FLOAT(side->overlays[i].scaley));
|
||||
if (side->flags & GET_SIDEFLAG_EDGENOSKEW(i))
|
||||
fprintf(f, "%s""noskew = true;\n", prefix);
|
||||
if (side->flags & GET_SIDEFLAG_EDGEWRAP(i))
|
||||
fprintf(f, "%s""wrap = true;\n", prefix);
|
||||
}
|
||||
|
||||
static void P_WriteTextmap(void)
|
||||
{
|
||||
size_t i, j;
|
||||
|
@ -2654,6 +2710,10 @@ static void P_WriteTextmap(void)
|
|||
fprintf(f, "texturemiddle = \"%.*s\";\n", 8, textures[wsides[i].midtexture]->name);
|
||||
if (wsides[i].repeatcnt != 0)
|
||||
fprintf(f, "repeatcnt = %d;\n", wsides[i].repeatcnt);
|
||||
WriteTextmapEdgeTexture("edge_top_upper_", EDGE_TEXTURE_TOP_UPPER, &wsides[i], f);
|
||||
WriteTextmapEdgeTexture("edge_top_lower_", EDGE_TEXTURE_TOP_LOWER, &wsides[i], f);
|
||||
WriteTextmapEdgeTexture("edge_bottom_upper_", EDGE_TEXTURE_BOTTOM_UPPER, &wsides[i], f);
|
||||
WriteTextmapEdgeTexture("edge_bottom_lower_", EDGE_TEXTURE_BOTTOM_LOWER, &wsides[i], f);
|
||||
fprintf(f, "}\n");
|
||||
fprintf(f, "\n");
|
||||
}
|
||||
|
@ -3041,9 +3101,16 @@ static void P_LoadTextmap(void)
|
|||
sd->offsety_top = sd->offsety_mid = sd->offsety_bottom = 0;
|
||||
sd->scalex_top = sd->scalex_mid = sd->scalex_bottom = FRACUNIT;
|
||||
sd->scaley_top = sd->scaley_mid = sd->scaley_bottom = FRACUNIT;
|
||||
sd->flags = 0;
|
||||
sd->toptexture = R_TextureNumForName("-");
|
||||
sd->midtexture = R_TextureNumForName("-");
|
||||
sd->bottomtexture = R_TextureNumForName("-");
|
||||
for (unsigned j = 0; j < NUM_WALL_OVERLAYS; j++)
|
||||
{
|
||||
sd->overlays[j].texture = R_TextureNumForName("-");
|
||||
sd->overlays[j].offsetx = sd->overlays[j].offsety = 0;
|
||||
sd->overlays[j].scalex = sd->overlays[j].scaley = FRACUNIT;
|
||||
}
|
||||
sd->sector = NULL;
|
||||
sd->repeatcnt = 0;
|
||||
|
||||
|
|
44
src/r_defs.h
44
src/r_defs.h
|
@ -555,6 +555,21 @@ typedef enum
|
|||
|
||||
#define NO_SIDEDEF 0xFFFFFFFF
|
||||
|
||||
enum
|
||||
{
|
||||
EDGE_TEXTURE_TOP_UPPER,
|
||||
EDGE_TEXTURE_TOP_LOWER,
|
||||
EDGE_TEXTURE_BOTTOM_UPPER,
|
||||
EDGE_TEXTURE_BOTTOM_LOWER,
|
||||
|
||||
NUM_WALL_OVERLAYS
|
||||
};
|
||||
|
||||
#define IS_TOP_EDGE_TEXTURE(i) ((i) == EDGE_TEXTURE_TOP_UPPER || (i) == EDGE_TEXTURE_TOP_LOWER)
|
||||
#define IS_BOTTOM_EDGE_TEXTURE(i) (!IS_TOP_EDGE_TEXTURE(i))
|
||||
#define IS_UPPER_EDGE_TEXTURE(i) ((i) == EDGE_TEXTURE_TOP_UPPER || (i) == EDGE_TEXTURE_BOTTOM_UPPER)
|
||||
#define IS_LOWER_EDGE_TEXTURE(i) (!IS_UPPER_EDGE_TEXTURE(i))
|
||||
|
||||
typedef struct line_s
|
||||
{
|
||||
// Vertices, from v1 to v2.
|
||||
|
@ -595,6 +610,23 @@ typedef struct line_s
|
|||
UINT32 secportal; // transferred sector portal
|
||||
} line_t;
|
||||
|
||||
// Don't make available to Lua or I will find where you live
|
||||
enum
|
||||
{
|
||||
SIDEFLAG_EDGENOSKEW1 = 1<<7,
|
||||
SIDEFLAG_EDGENOSKEW2 = 1<<8,
|
||||
SIDEFLAG_EDGENOSKEW3 = 1<<9,
|
||||
SIDEFLAG_EDGENOSKEW4 = 1<<10,
|
||||
|
||||
SIDEFLAG_EDGEWRAP1 = 1<<11,
|
||||
SIDEFLAG_EDGEWRAP2 = 1<<12,
|
||||
SIDEFLAG_EDGEWRAP3 = 1<<13,
|
||||
SIDEFLAG_EDGEWRAP4 = 1<<14
|
||||
};
|
||||
|
||||
#define GET_SIDEFLAG_EDGENOSKEW(which) (SIDEFLAG_EDGENOSKEW1<<(which))
|
||||
#define GET_SIDEFLAG_EDGEWRAP(which) (SIDEFLAG_EDGEWRAP1<<(which))
|
||||
|
||||
typedef struct
|
||||
{
|
||||
// add this to the calculated texture column
|
||||
|
@ -610,10 +642,19 @@ typedef struct
|
|||
fixed_t scalex_top, scalex_mid, scalex_bottom;
|
||||
fixed_t scaley_top, scaley_mid, scaley_bottom;
|
||||
|
||||
UINT16 flags;
|
||||
|
||||
// Texture indices.
|
||||
// We do not maintain names here.
|
||||
INT32 toptexture, bottomtexture, midtexture;
|
||||
|
||||
// Upper and lower overlays for top and bottom textures
|
||||
struct {
|
||||
INT32 texture;
|
||||
fixed_t offsetx, offsety;
|
||||
fixed_t scalex, scaley;
|
||||
} overlays[NUM_WALL_OVERLAYS];
|
||||
|
||||
// Linedef the sidedef belongs to
|
||||
line_t *line;
|
||||
|
||||
|
@ -808,6 +849,7 @@ typedef struct drawseg_s
|
|||
INT16 *sprtopclip;
|
||||
INT16 *sprbottomclip;
|
||||
fixed_t *maskedtexturecol;
|
||||
fixed_t *maskedtextureheight; // For handling sloped midtextures
|
||||
fixed_t *invscale;
|
||||
|
||||
struct visplane_s *ffloorplanes[MAXFFLOORS];
|
||||
|
@ -819,8 +861,6 @@ typedef struct drawseg_s
|
|||
|
||||
UINT8 portalpass; // if > 0 and <= portalrender, do not affect sprite clipping
|
||||
|
||||
fixed_t maskedtextureheight[MAXVIDWIDTH]; // For handling sloped midtextures
|
||||
|
||||
vertex_t leftpos, rightpos; // Used for rendering FOF walls with slopes
|
||||
} drawseg_t;
|
||||
|
||||
|
|
641
src/r_segs.c
641
src/r_segs.c
|
@ -38,6 +38,9 @@ static boolean maskedtexture;
|
|||
static INT32 toptexture, bottomtexture, midtexture;
|
||||
static INT32 numthicksides, numbackffloors;
|
||||
|
||||
static boolean hasoverlaytexture;
|
||||
static INT32 overlaytexture[NUM_WALL_OVERLAYS];
|
||||
|
||||
angle_t rw_normalangle;
|
||||
// angle to line origin
|
||||
angle_t rw_angle1;
|
||||
|
@ -61,6 +64,14 @@ static fixed_t rw_toptexturescalex, rw_toptexturescaley;
|
|||
static fixed_t rw_bottomtexturescalex, rw_bottomtexturescaley;
|
||||
static fixed_t rw_invmidtexturescalex, rw_invtoptexturescalex, rw_invbottomtexturescalex;
|
||||
|
||||
static struct
|
||||
{
|
||||
fixed_t mid, slide;
|
||||
fixed_t back, backslide;
|
||||
fixed_t scalex, scaley, invscalex;
|
||||
fixed_t offsetx, offsety;
|
||||
} rw_overlay[NUM_WALL_OVERLAYS];
|
||||
|
||||
// Lactozilla: 3D floor clipping
|
||||
static boolean rw_floormarked = false;
|
||||
static boolean rw_ceilingmarked = false;
|
||||
|
@ -79,6 +90,13 @@ static fixed_t *maskedtextureheight = NULL;
|
|||
static fixed_t *thicksidecol = NULL;
|
||||
static fixed_t *invscale = NULL;
|
||||
|
||||
static boolean texcoltables;
|
||||
|
||||
// TODO: Allocate dynamically
|
||||
static fixed_t overlaytextureheight[NUM_WALL_OVERLAYS][MAXVIDWIDTH];
|
||||
static fixed_t overlaytexturecol[NUM_WALL_OVERLAYS][MAXVIDWIDTH];
|
||||
static INT16 overlayopening[2][MAXVIDWIDTH];
|
||||
|
||||
//SoM: 3/23/2000: Use boom opening limit removal
|
||||
static size_t numopenings;
|
||||
static INT16 *openings, *lastopening;
|
||||
|
@ -144,13 +162,93 @@ transnum_t R_GetLinedefTransTable(fixed_t alpha)
|
|||
return (20*(FRACUNIT - alpha - 1) + FRACUNIT) >> (FRACBITS+1);
|
||||
}
|
||||
|
||||
// Setup lighting based on the presence/lack-of 3D floors.
|
||||
static void R_PrepareMaskedSegLightlist(drawseg_t *ds, INT32 range)
|
||||
{
|
||||
lightlist_t *light;
|
||||
r_lightlist_t *rlight;
|
||||
INT32 lightnum;
|
||||
|
||||
dc_numlights = 0;
|
||||
|
||||
if (frontsector->numlights)
|
||||
{
|
||||
dc_numlights = frontsector->numlights;
|
||||
if (dc_numlights >= dc_maxlights)
|
||||
{
|
||||
dc_maxlights = dc_numlights;
|
||||
dc_lightlist = Z_Realloc(dc_lightlist, sizeof (*dc_lightlist) * dc_maxlights, PU_STATIC, NULL);
|
||||
}
|
||||
|
||||
for (INT32 i = 0; i < dc_numlights; i++)
|
||||
{
|
||||
fixed_t leftheight, rightheight;
|
||||
light = &frontsector->lightlist[i];
|
||||
rlight = &dc_lightlist[i];
|
||||
leftheight = P_GetLightZAt(light, ds-> leftpos.x, ds-> leftpos.y);
|
||||
rightheight = P_GetLightZAt(light, ds->rightpos.x, ds->rightpos.y);
|
||||
|
||||
leftheight -= viewz;
|
||||
rightheight -= viewz;
|
||||
|
||||
rlight->height = (centeryfrac) - FixedMul(leftheight , ds->scale1);
|
||||
rlight->heightstep = (centeryfrac) - FixedMul(rightheight, ds->scale2);
|
||||
rlight->heightstep = (rlight->heightstep-rlight->height)/(range);
|
||||
//if (x1 > ds->x1)
|
||||
//rlight->height -= (x1 - ds->x1)*rlight->heightstep;
|
||||
rlight->startheight = rlight->height; // keep starting value here to reset for each repeat
|
||||
rlight->lightlevel = *light->lightlevel;
|
||||
rlight->extra_colormap = *light->extra_colormap;
|
||||
rlight->flags = light->flags;
|
||||
|
||||
if ((colfunc != colfuncs[COLDRAWFUNC_FUZZY])
|
||||
|| (rlight->flags & FOF_FOG)
|
||||
|| (rlight->extra_colormap && (rlight->extra_colormap->flags & CMF_FOG)))
|
||||
lightnum = (rlight->lightlevel >> LIGHTSEGSHIFT);
|
||||
else
|
||||
lightnum = LIGHTLEVELS - 1;
|
||||
|
||||
if (rlight->extra_colormap && (rlight->extra_colormap->flags & CMF_FOG))
|
||||
;
|
||||
else if (curline->v1->y == curline->v2->y)
|
||||
lightnum--;
|
||||
else if (curline->v1->x == curline->v2->x)
|
||||
lightnum++;
|
||||
|
||||
rlight->lightnum = lightnum;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((colfunc != colfuncs[COLDRAWFUNC_FUZZY])
|
||||
|| (frontsector->extra_colormap && (frontsector->extra_colormap->flags & CMF_FOG)))
|
||||
lightnum = (frontsector->lightlevel >> LIGHTSEGSHIFT);
|
||||
else
|
||||
lightnum = LIGHTLEVELS - 1;
|
||||
|
||||
if (colfunc == colfuncs[COLDRAWFUNC_FOG]
|
||||
|| (frontsector->extra_colormap && (frontsector->extra_colormap->flags & CMF_FOG)))
|
||||
;
|
||||
else if (curline->v1->y == curline->v2->y)
|
||||
lightnum--;
|
||||
else if (curline->v1->x == curline->v2->x)
|
||||
lightnum++;
|
||||
|
||||
if (lightnum < 0)
|
||||
walllights = scalelight[0];
|
||||
else if (lightnum >= LIGHTLEVELS)
|
||||
walllights = scalelight[LIGHTLEVELS - 1];
|
||||
else
|
||||
walllights = scalelight[lightnum];
|
||||
}
|
||||
}
|
||||
|
||||
void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
|
||||
{
|
||||
size_t pindex;
|
||||
column_t *col;
|
||||
INT32 lightnum, texnum, i;
|
||||
INT32 texnum, i;
|
||||
fixed_t height, realbot;
|
||||
lightlist_t *light;
|
||||
r_lightlist_t *rlight;
|
||||
void (*colfunc_2s)(column_t *);
|
||||
line_t *ldef;
|
||||
|
@ -236,77 +334,7 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
|
|||
}
|
||||
|
||||
// Setup lighting based on the presence/lack-of 3D floors.
|
||||
dc_numlights = 0;
|
||||
if (frontsector->numlights)
|
||||
{
|
||||
dc_numlights = frontsector->numlights;
|
||||
if (dc_numlights >= dc_maxlights)
|
||||
{
|
||||
dc_maxlights = dc_numlights;
|
||||
dc_lightlist = Z_Realloc(dc_lightlist, sizeof (*dc_lightlist) * dc_maxlights, PU_STATIC, NULL);
|
||||
}
|
||||
|
||||
for (i = 0; i < dc_numlights; i++)
|
||||
{
|
||||
fixed_t leftheight, rightheight;
|
||||
light = &frontsector->lightlist[i];
|
||||
rlight = &dc_lightlist[i];
|
||||
leftheight = P_GetLightZAt(light, ds-> leftpos.x, ds-> leftpos.y);
|
||||
rightheight = P_GetLightZAt(light, ds->rightpos.x, ds->rightpos.y);
|
||||
|
||||
leftheight -= viewz;
|
||||
rightheight -= viewz;
|
||||
|
||||
rlight->height = (centeryfrac) - FixedMul(leftheight , ds->scale1);
|
||||
rlight->heightstep = (centeryfrac) - FixedMul(rightheight, ds->scale2);
|
||||
rlight->heightstep = (rlight->heightstep-rlight->height)/(range);
|
||||
//if (x1 > ds->x1)
|
||||
//rlight->height -= (x1 - ds->x1)*rlight->heightstep;
|
||||
rlight->startheight = rlight->height; // keep starting value here to reset for each repeat
|
||||
rlight->lightlevel = *light->lightlevel;
|
||||
rlight->extra_colormap = *light->extra_colormap;
|
||||
rlight->flags = light->flags;
|
||||
|
||||
if ((colfunc != colfuncs[COLDRAWFUNC_FUZZY])
|
||||
|| (rlight->flags & FOF_FOG)
|
||||
|| (rlight->extra_colormap && (rlight->extra_colormap->flags & CMF_FOG)))
|
||||
lightnum = (rlight->lightlevel >> LIGHTSEGSHIFT);
|
||||
else
|
||||
lightnum = LIGHTLEVELS - 1;
|
||||
|
||||
if (rlight->extra_colormap && (rlight->extra_colormap->flags & CMF_FOG))
|
||||
;
|
||||
else if (curline->v1->y == curline->v2->y)
|
||||
lightnum--;
|
||||
else if (curline->v1->x == curline->v2->x)
|
||||
lightnum++;
|
||||
|
||||
rlight->lightnum = lightnum;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((colfunc != colfuncs[COLDRAWFUNC_FUZZY])
|
||||
|| (frontsector->extra_colormap && (frontsector->extra_colormap->flags & CMF_FOG)))
|
||||
lightnum = (frontsector->lightlevel >> LIGHTSEGSHIFT);
|
||||
else
|
||||
lightnum = LIGHTLEVELS - 1;
|
||||
|
||||
if (colfunc == colfuncs[COLDRAWFUNC_FOG]
|
||||
|| (frontsector->extra_colormap && (frontsector->extra_colormap->flags & CMF_FOG)))
|
||||
;
|
||||
else if (curline->v1->y == curline->v2->y)
|
||||
lightnum--;
|
||||
else if (curline->v1->x == curline->v2->x)
|
||||
lightnum++;
|
||||
|
||||
if (lightnum < 0)
|
||||
walllights = scalelight[0];
|
||||
else if (lightnum >= LIGHTLEVELS)
|
||||
walllights = scalelight[LIGHTLEVELS - 1];
|
||||
else
|
||||
walllights = scalelight[lightnum];
|
||||
}
|
||||
R_PrepareMaskedSegLightlist(ds, range);
|
||||
|
||||
maskedtexturecol = ds->maskedtexturecol;
|
||||
|
||||
|
@ -489,6 +517,268 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
|
|||
colfunc = colfuncs[BASEDRAWFUNC];
|
||||
}
|
||||
|
||||
// Renders a texture right on top of the wall texture
|
||||
static void R_RenderExtraTexture(drawseg_t *ds, unsigned which, INT32 x1, INT32 x2)
|
||||
{
|
||||
size_t pindex;
|
||||
column_t *col;
|
||||
INT32 i;
|
||||
fixed_t height, realbot;
|
||||
r_lightlist_t *rlight;
|
||||
void (*colfunc_2s)(column_t *);
|
||||
INT32 times, repeats;
|
||||
INT64 overflow_test;
|
||||
INT32 range;
|
||||
|
||||
fixed_t wall_scaley;
|
||||
fixed_t scalestep;
|
||||
fixed_t scale1;
|
||||
|
||||
fixed_t *extraheight = overlaytextureheight[which];
|
||||
fixed_t *texturecol = overlaytexturecol[which];
|
||||
INT32 texnum = overlaytexture[which];
|
||||
|
||||
UINT8 vertflip = textures[texnum]->flip & 2;
|
||||
|
||||
// Calculate light table.
|
||||
// Use different light tables
|
||||
// for horizontal / vertical / diagonal. Diagonal?
|
||||
// OPTIMIZE: get rid of LIGHTSEGSHIFT globally
|
||||
windowbottom = windowtop = sprbotscreen = INT32_MAX;
|
||||
|
||||
wall_scaley = rw_overlay[which].scaley;
|
||||
if (wall_scaley < 0)
|
||||
{
|
||||
wall_scaley = -wall_scaley;
|
||||
vertflip = !vertflip;
|
||||
}
|
||||
|
||||
scalestep = FixedDiv(ds->scalestep, wall_scaley);
|
||||
scale1 = FixedDiv(ds->scale1, wall_scaley);
|
||||
|
||||
range = max(ds->x2-ds->x1, 1);
|
||||
rw_scalestep = scalestep;
|
||||
spryscale = scale1 + (x1 - ds->x1)*rw_scalestep;
|
||||
|
||||
// Texture must be cached before setting colfunc_2s,
|
||||
// otherwise texture[texnum]->holes may be false when it shouldn't be
|
||||
R_CheckTextureCache(texnum);
|
||||
|
||||
// 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)
|
||||
{
|
||||
if (vertflip) // vertically flipped?
|
||||
{
|
||||
colfunc_2s = R_DrawFlippedMaskedColumn;
|
||||
lengthcol = textures[texnum]->height;
|
||||
}
|
||||
else
|
||||
colfunc_2s = R_DrawMaskedColumn; // render the usual 2sided single-patch packed texture
|
||||
}
|
||||
else
|
||||
{
|
||||
// FIXME: Composite textures don't get flipped vertically
|
||||
colfunc_2s = R_Render2sidedMultiPatchColumn; // render multipatch with no holes (no post_t info)
|
||||
lengthcol = textures[texnum]->height;
|
||||
}
|
||||
|
||||
// Setup lighting based on the presence/lack-of 3D floors.
|
||||
R_PrepareMaskedSegLightlist(ds, range);
|
||||
|
||||
mfloorclip = overlayopening[1];
|
||||
mceilingclip = overlayopening[0];
|
||||
|
||||
if (sidedef->flags & GET_SIDEFLAG_EDGEWRAP(which))
|
||||
{
|
||||
fixed_t high, low;
|
||||
|
||||
if (backsector)
|
||||
{
|
||||
if (IS_TOP_EDGE_TEXTURE(which))
|
||||
{
|
||||
high = max(
|
||||
P_GetSectorCeilingZAt(frontsector, ds_p->leftpos.x, ds_p->leftpos.y),
|
||||
P_GetSectorCeilingZAt(frontsector, ds_p->rightpos.x, ds_p->rightpos.y)
|
||||
);
|
||||
low = min(
|
||||
P_GetSectorCeilingZAt(backsector, ds_p->leftpos.x, ds_p->leftpos.y),
|
||||
P_GetSectorCeilingZAt(backsector, ds_p->rightpos.x, ds_p->rightpos.y)
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
high = max(
|
||||
P_GetSectorFloorZAt(frontsector, ds_p->leftpos.x, ds_p->leftpos.y),
|
||||
P_GetSectorFloorZAt(frontsector, ds_p->rightpos.x, ds_p->rightpos.y)
|
||||
);
|
||||
low = min(
|
||||
P_GetSectorFloorZAt(backsector, ds_p->leftpos.x, ds_p->leftpos.y),
|
||||
P_GetSectorFloorZAt(backsector, ds_p->rightpos.x, ds_p->rightpos.y)
|
||||
);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
high = max(
|
||||
P_GetSectorCeilingZAt(frontsector, ds_p->leftpos.x, ds_p->leftpos.y),
|
||||
P_GetSectorCeilingZAt(frontsector, ds_p->rightpos.x, ds_p->rightpos.y)
|
||||
);
|
||||
low = min(
|
||||
P_GetSectorFloorZAt(backsector, ds_p->leftpos.x, ds_p->leftpos.y),
|
||||
P_GetSectorFloorZAt(backsector, ds_p->rightpos.x, ds_p->rightpos.y)
|
||||
);
|
||||
}
|
||||
|
||||
repeats = (high - low)/textureheight[texnum];
|
||||
if ((high-low)%textureheight[texnum])
|
||||
repeats++; // tile an extra time to fill the gap -- Monster Iestyn
|
||||
}
|
||||
else
|
||||
repeats = 1;
|
||||
|
||||
for (times = 0; times < repeats; times++)
|
||||
{
|
||||
if (times > 0)
|
||||
{
|
||||
rw_scalestep = scalestep;
|
||||
spryscale = scale1 + (x1 - ds->x1)*rw_scalestep;
|
||||
|
||||
// reset all lights to their starting heights
|
||||
for (i = 0; i < dc_numlights; i++)
|
||||
{
|
||||
rlight = &dc_lightlist[i];
|
||||
rlight->height = rlight->startheight;
|
||||
}
|
||||
}
|
||||
|
||||
dc_texheight = textureheight[texnum]>>FRACBITS;
|
||||
|
||||
// draw the columns
|
||||
for (dc_x = x1; dc_x <= x2; dc_x++)
|
||||
{
|
||||
dc_texturemid = extraheight[dc_x];
|
||||
|
||||
if (IS_LOWER_EDGE_TEXTURE(which))
|
||||
dc_texturemid += (textureheight[texnum])*times + textureheight[texnum];
|
||||
else
|
||||
dc_texturemid -= (textureheight[texnum])*times;
|
||||
|
||||
// Check for overflows first
|
||||
overflow_test = (INT64)centeryfrac - (((INT64)dc_texturemid*spryscale)>>FRACBITS);
|
||||
if (overflow_test < 0) overflow_test = -overflow_test;
|
||||
if ((UINT64)overflow_test&0xFFFFFFFF80000000ULL)
|
||||
{
|
||||
// Eh, no, go away, don't waste our time
|
||||
if (dc_numlights)
|
||||
{
|
||||
for (i = 0; i < dc_numlights; i++)
|
||||
{
|
||||
rlight = &dc_lightlist[i];
|
||||
rlight->height += rlight->heightstep;
|
||||
}
|
||||
}
|
||||
spryscale += rw_scalestep;
|
||||
continue;
|
||||
}
|
||||
|
||||
// calculate lighting
|
||||
if (dc_numlights)
|
||||
{
|
||||
lighttable_t **xwalllights;
|
||||
|
||||
sprbotscreen = INT32_MAX;
|
||||
sprtopscreen = windowtop = (centeryfrac - FixedMul(dc_texturemid, spryscale));
|
||||
|
||||
realbot = FixedMul(textureheight[texnum], spryscale) + sprtopscreen;
|
||||
dc_iscale = FixedMul(ds->invscale[dc_x], wall_scaley);
|
||||
|
||||
windowbottom = realbot;
|
||||
|
||||
// draw the texture
|
||||
col = (column_t *)((UINT8 *)R_GetColumn(texnum, (texturecol[dc_x] >> FRACBITS)) - 3);
|
||||
|
||||
for (i = 0; i < dc_numlights; i++)
|
||||
{
|
||||
rlight = &dc_lightlist[i];
|
||||
|
||||
if ((rlight->flags & FOF_NOSHADE))
|
||||
continue;
|
||||
|
||||
if (rlight->lightnum < 0)
|
||||
xwalllights = scalelight[0];
|
||||
else if (rlight->lightnum >= LIGHTLEVELS)
|
||||
xwalllights = scalelight[LIGHTLEVELS-1];
|
||||
else
|
||||
xwalllights = scalelight[rlight->lightnum];
|
||||
|
||||
pindex = FixedMul(spryscale, LIGHTRESOLUTIONFIX)>>LIGHTSCALESHIFT;
|
||||
|
||||
if (pindex >= MAXLIGHTSCALE)
|
||||
pindex = MAXLIGHTSCALE - 1;
|
||||
|
||||
if (rlight->extra_colormap)
|
||||
rlight->rcolormap = rlight->extra_colormap->colormap + (xwalllights[pindex] - colormaps);
|
||||
else
|
||||
rlight->rcolormap = xwalllights[pindex];
|
||||
|
||||
height = rlight->height;
|
||||
rlight->height += rlight->heightstep;
|
||||
|
||||
if (height <= windowtop)
|
||||
{
|
||||
dc_colormap = rlight->rcolormap;
|
||||
continue;
|
||||
}
|
||||
|
||||
windowbottom = height;
|
||||
if (windowbottom >= realbot)
|
||||
{
|
||||
windowbottom = realbot;
|
||||
colfunc_2s(col);
|
||||
for (i++; i < dc_numlights; i++)
|
||||
{
|
||||
rlight = &dc_lightlist[i];
|
||||
rlight->height += rlight->heightstep;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
colfunc_2s(col);
|
||||
windowtop = windowbottom + 1;
|
||||
dc_colormap = rlight->rcolormap;
|
||||
}
|
||||
windowbottom = realbot;
|
||||
if (windowtop < windowbottom)
|
||||
colfunc_2s(col);
|
||||
|
||||
spryscale += rw_scalestep;
|
||||
continue;
|
||||
}
|
||||
|
||||
// calculate lighting
|
||||
pindex = FixedMul(spryscale, LIGHTRESOLUTIONFIX)>>LIGHTSCALESHIFT;
|
||||
|
||||
if (pindex >= MAXLIGHTSCALE)
|
||||
pindex = MAXLIGHTSCALE - 1;
|
||||
|
||||
dc_colormap = walllights[pindex];
|
||||
|
||||
if (frontsector->extra_colormap)
|
||||
dc_colormap = frontsector->extra_colormap->colormap + (dc_colormap - colormaps);
|
||||
|
||||
sprtopscreen = centeryfrac - FixedMul(dc_texturemid, spryscale);
|
||||
dc_iscale = FixedMul(ds->invscale[dc_x], wall_scaley);
|
||||
|
||||
// draw the texture
|
||||
col = (column_t *)((UINT8 *)R_GetColumn(texnum, (texturecol[dc_x] >> FRACBITS)) - 3);
|
||||
colfunc_2s(col);
|
||||
|
||||
spryscale += rw_scalestep;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Loop through R_DrawMaskedColumn calls
|
||||
static void R_DrawRepeatMaskedColumn(column_t *col)
|
||||
{
|
||||
|
@ -790,8 +1080,9 @@ 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);
|
||||
//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
|
||||
|
||||
// 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)
|
||||
{
|
||||
if (textures[texnum]->flip & 2) // vertically flipped?
|
||||
|
@ -1077,6 +1368,15 @@ static void R_RenderSegLoop (void)
|
|||
INT32 bottom;
|
||||
INT32 i;
|
||||
|
||||
fixed_t oldoverlaycolumn[NUM_WALL_OVERLAYS];
|
||||
fixed_t overlaycolumn[NUM_WALL_OVERLAYS];
|
||||
|
||||
if (hasoverlaytexture)
|
||||
{
|
||||
for (i = 0; i < NUM_WALL_OVERLAYS; i++)
|
||||
oldoverlaycolumn[i] = -1;
|
||||
}
|
||||
|
||||
for (; rw_x < rw_stopx; rw_x++)
|
||||
{
|
||||
// mark floor / ceiling areas
|
||||
|
@ -1469,6 +1769,47 @@ static void R_RenderSegLoop (void)
|
|||
oldtexturecolumn = texturecolumn;
|
||||
}
|
||||
|
||||
if (hasoverlaytexture)
|
||||
{
|
||||
#define ALIGN_UPPER(which) \
|
||||
if (overlaytexture[which]) \
|
||||
overlaytextureheight[which][rw_x] = max(rw_overlay[which].mid, rw_overlay[which].back)
|
||||
#define ALIGN_LOWER(which) \
|
||||
if (overlaytexture[which]) \
|
||||
overlaytextureheight[which][rw_x] = min(rw_overlay[which].mid, rw_overlay[which].back)
|
||||
|
||||
ALIGN_UPPER(EDGE_TEXTURE_TOP_UPPER);
|
||||
ALIGN_LOWER(EDGE_TEXTURE_TOP_LOWER);
|
||||
ALIGN_UPPER(EDGE_TEXTURE_BOTTOM_UPPER);
|
||||
ALIGN_LOWER(EDGE_TEXTURE_BOTTOM_LOWER);
|
||||
|
||||
#undef ALIGN_UPPER
|
||||
#undef ALIGN_LOWER
|
||||
|
||||
for (i = 0; i < NUM_WALL_OVERLAYS; i++)
|
||||
{
|
||||
fixed_t offset;
|
||||
|
||||
if (!overlaytexture[i])
|
||||
continue;
|
||||
|
||||
offset = sidedef->textureoffset + rw_overlay[i].offsetx;
|
||||
if (rw_overlay[i].scalex < 0)
|
||||
offset = -offset;
|
||||
|
||||
overlaycolumn[i] = FixedDiv(textureoffset, rw_overlay[i].invscalex);
|
||||
overlaytexturecol[i][rw_x] = overlaycolumn[i] + offset;
|
||||
|
||||
if (oldoverlaycolumn[i] != -1)
|
||||
{
|
||||
rw_overlay[i].mid += FixedMul(rw_overlay[i].slide, oldoverlaycolumn[i]-overlaycolumn[i]);
|
||||
rw_overlay[i].back += FixedMul(rw_overlay[i].backslide, oldoverlaycolumn[i]-overlaycolumn[i]);
|
||||
}
|
||||
|
||||
oldoverlaycolumn[i] = overlaycolumn[i];
|
||||
}
|
||||
}
|
||||
|
||||
if (invscale)
|
||||
invscale[rw_x] = 0xffffffffu / (unsigned)rw_scale;
|
||||
|
||||
|
@ -1560,7 +1901,7 @@ static void R_AllocClippingTables(size_t range)
|
|||
static void R_AllocTextureColumnTables(size_t range)
|
||||
{
|
||||
size_t pos = curtexturecolumntable - texturecolumntable;
|
||||
size_t need = range * 3;
|
||||
size_t need = range * 4;
|
||||
|
||||
if (pos + need < texturecolumntablesize)
|
||||
return;
|
||||
|
@ -1581,12 +1922,109 @@ static void R_AllocTextureColumnTables(size_t range)
|
|||
for (drawseg_t *ds = drawsegs; ds < ds_p; ds++)
|
||||
{
|
||||
// Check if it's in range of the tables
|
||||
if (ds->maskedtexturecol + ds->x1 >= oldtable && ds->maskedtexturecol + ds->x1 <= oldlast)
|
||||
ds->maskedtexturecol = (ds->maskedtexturecol - oldtable) + texturecolumntable;
|
||||
if (ds->thicksidecol + ds->x1 >= oldtable && ds->thicksidecol + ds->x1 <= oldlast)
|
||||
ds->thicksidecol = (ds->thicksidecol - oldtable) + texturecolumntable;
|
||||
if (ds->invscale + ds->x1 >= oldtable && ds->invscale + ds->x1 <= oldlast)
|
||||
ds->invscale = (ds->invscale - oldtable) + texturecolumntable;
|
||||
#define CHECK(which) \
|
||||
if (which + ds->x1 >= oldtable && which + ds->x1 <= oldlast) \
|
||||
which = (which - oldtable) + texturecolumntable
|
||||
|
||||
CHECK(ds->maskedtexturecol);
|
||||
CHECK(ds->maskedtextureheight);
|
||||
CHECK(ds->thicksidecol);
|
||||
CHECK(ds->invscale);
|
||||
|
||||
#undef CHECK
|
||||
}
|
||||
}
|
||||
|
||||
static void R_AddOverlayTextures(fixed_t ceilingfrontslide, fixed_t floorfrontslide, fixed_t ceilingbackslide, fixed_t floorbackslide)
|
||||
{
|
||||
INT32 texnums[4] = {
|
||||
R_GetTextureNum(sidedef->overlays[0].texture),
|
||||
R_GetTextureNum(sidedef->overlays[1].texture),
|
||||
R_GetTextureNum(sidedef->overlays[2].texture),
|
||||
R_GetTextureNum(sidedef->overlays[3].texture)
|
||||
};
|
||||
|
||||
if (!backsector)
|
||||
{
|
||||
// If one-sided, render just the upper top and the lower bottom overlays
|
||||
overlaytexture[0] = texnums[0] ? texnums[0] : texnums[2];
|
||||
overlaytexture[3] = texnums[1] ? texnums[1] : texnums[3];
|
||||
}
|
||||
else
|
||||
{
|
||||
overlaytexture[0] = texnums[0];
|
||||
overlaytexture[1] = texnums[1];
|
||||
overlaytexture[2] = texnums[2];
|
||||
overlaytexture[3] = texnums[3];
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < NUM_WALL_OVERLAYS; i++)
|
||||
{
|
||||
if (overlaytexture[i] > 0 && overlaytexture[i] < numtextures)
|
||||
{
|
||||
if (!texcoltables)
|
||||
{
|
||||
// allocate space for masked texture tables
|
||||
R_AllocTextureColumnTables(rw_stopx - rw_x);
|
||||
|
||||
texcoltables = true;
|
||||
}
|
||||
|
||||
if (!maskedtexturecol)
|
||||
{
|
||||
ds_p->maskedtexturecol = maskedtexturecol = curtexturecolumntable - rw_x;
|
||||
curtexturecolumntable += rw_stopx - rw_x;
|
||||
}
|
||||
|
||||
maskedtexture = hasoverlaytexture = true;
|
||||
|
||||
rw_overlay[i].scalex = sidedef->overlays[i].scalex;
|
||||
rw_overlay[i].scaley = sidedef->overlays[i].scaley;
|
||||
rw_overlay[i].offsetx = sidedef->overlays[i].offsetx;
|
||||
rw_overlay[i].offsety = sidedef->overlays[i].offsety;
|
||||
|
||||
rw_overlay[i].invscalex = FixedDiv(FRACUNIT, rw_overlay[i].scalex);
|
||||
|
||||
if (sidedef->flags & GET_SIDEFLAG_EDGENOSKEW(i))
|
||||
{
|
||||
if (IS_BOTTOM_EDGE_TEXTURE(i))
|
||||
{
|
||||
rw_overlay[i].mid = frontsector->floorheight;
|
||||
rw_overlay[i].back = backsector ? backsector->floorheight : rw_overlay[i].mid;
|
||||
}
|
||||
else
|
||||
{
|
||||
rw_overlay[i].mid = frontsector->ceilingheight;
|
||||
rw_overlay[i].back = backsector ? backsector->ceilingheight : rw_overlay[i].mid;
|
||||
}
|
||||
|
||||
rw_overlay[i].slide = 0;
|
||||
rw_overlay[i].backslide = 0;
|
||||
|
||||
rw_overlay[i].mid -= viewz;
|
||||
rw_overlay[i].back -= viewz;
|
||||
}
|
||||
else if (IS_BOTTOM_EDGE_TEXTURE(i))
|
||||
{
|
||||
rw_overlay[i].mid = worldbottom;
|
||||
rw_overlay[i].slide = floorfrontslide;
|
||||
rw_overlay[i].back = backsector ? worldlow : rw_overlay[i].mid;
|
||||
rw_overlay[i].backslide = backsector ? floorbackslide : rw_overlay[i].slide;
|
||||
}
|
||||
else
|
||||
{
|
||||
rw_overlay[i].mid = worldtop;
|
||||
rw_overlay[i].slide = ceilingfrontslide;
|
||||
rw_overlay[i].back = backsector ? worldhigh : rw_overlay[i].mid;
|
||||
rw_overlay[i].backslide = backsector ? ceilingbackslide : rw_overlay[i].slide;
|
||||
}
|
||||
|
||||
rw_overlay[i].mid = FixedMul(rw_overlay[i].mid, abs(rw_overlay[i].scaley));
|
||||
rw_overlay[i].back = FixedMul(rw_overlay[i].back, abs(rw_overlay[i].scaley));
|
||||
|
||||
rw_overlay[i].mid += sidedef->rowoffset + rw_overlay[i].offsety;
|
||||
rw_overlay[i].back += sidedef->rowoffset + rw_overlay[i].offsety;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1768,12 +2206,18 @@ void R_StoreWallRange(INT32 start, INT32 stop)
|
|||
worldbottomslope -= viewz;
|
||||
|
||||
midtexture = toptexture = bottomtexture = maskedtexture = 0;
|
||||
hasoverlaytexture = false;
|
||||
memset(overlaytexture, 0, sizeof(overlaytexture));
|
||||
|
||||
ds_p->maskedtexturecol = NULL;
|
||||
ds_p->maskedtextureheight = NULL;
|
||||
ds_p->numthicksides = numthicksides = 0;
|
||||
ds_p->thicksidecol = NULL;
|
||||
ds_p->invscale = NULL;
|
||||
ds_p->tsilheight = 0;
|
||||
|
||||
texcoltables = false;
|
||||
|
||||
numbackffloors = 0;
|
||||
|
||||
for (i = 0; i < MAXFFLOORS; i++)
|
||||
|
@ -2133,6 +2577,8 @@ void R_StoreWallRange(INT32 start, INT32 stop)
|
|||
// allocate space for masked texture tables
|
||||
R_AllocTextureColumnTables(rw_stopx - start);
|
||||
|
||||
texcoltables = true;
|
||||
|
||||
if (frontsector && backsector && !Tag_Compare(&frontsector->tags, &backsector->tags) && (backsector->ffloors || frontsector->ffloors))
|
||||
{
|
||||
ffloor_t *rover;
|
||||
|
@ -2331,7 +2777,8 @@ void R_StoreWallRange(INT32 start, INT32 stop)
|
|||
ds_p->maskedtexturecol = maskedtexturecol = curtexturecolumntable - rw_x;
|
||||
curtexturecolumntable += rw_stopx - rw_x;
|
||||
|
||||
maskedtextureheight = ds_p->maskedtextureheight; // note to red, this == &(ds_p->maskedtextureheight[0])
|
||||
ds_p->maskedtextureheight = maskedtextureheight = curtexturecolumntable - rw_x;
|
||||
curtexturecolumntable += rw_stopx - rw_x;
|
||||
|
||||
maskedtexture = true;
|
||||
|
||||
|
@ -2355,7 +2802,6 @@ void R_StoreWallRange(INT32 start, INT32 stop)
|
|||
rw_midtexturemid = rw_midtextureback = max(frontsector->floorheight, backsector->floorheight) - viewz;
|
||||
else
|
||||
rw_midtexturemid = rw_midtextureback = min(frontsector->ceilingheight, backsector->ceilingheight) - viewz;
|
||||
|
||||
}
|
||||
else if (linedef->flags & ML_MIDPEG)
|
||||
{
|
||||
|
@ -2378,14 +2824,16 @@ void R_StoreWallRange(INT32 start, INT32 stop)
|
|||
|
||||
rw_midtexturemid += sidedef->rowoffset + sidedef->offsety_mid;
|
||||
rw_midtextureback += sidedef->rowoffset + sidedef->offsety_mid;
|
||||
|
||||
maskedtexture = true;
|
||||
}
|
||||
}
|
||||
|
||||
// calculate rw_offset (only needed for textured lines)
|
||||
segtextured = midtexture || toptexture || bottomtexture || maskedtexture || (numthicksides > 0);
|
||||
|
||||
// check if extra textures need to be rendered
|
||||
if (segtextured)
|
||||
R_AddOverlayTextures(ceilingfrontslide, floorfrontslide, ceilingbackslide, floorbackslide);
|
||||
|
||||
// calculate rw_offset (only needed for textured lines)
|
||||
if (segtextured)
|
||||
{
|
||||
fixed_t sideoffset = sidedef->textureoffset;
|
||||
|
@ -2851,6 +3299,14 @@ void R_StoreWallRange(INT32 start, INT32 stop)
|
|||
rw_tsilheight = &(ds_p->tsilheight);
|
||||
rw_bsilheight = &(ds_p->bsilheight);
|
||||
|
||||
// Overlay rendering needs to use the floor/ceiling clip from before the wall is rendered
|
||||
// (otherwise it would be clipped and therefore wouldn't be visible)
|
||||
if (hasoverlaytexture)
|
||||
{
|
||||
M_Memcpy(&overlayopening[0][start], ceilingclip + start, 2*(rw_stopx - start));
|
||||
M_Memcpy(&overlayopening[1][start], floorclip + start, 2*(rw_stopx - start));
|
||||
}
|
||||
|
||||
R_RenderSegLoop();
|
||||
colfunc = colfuncs[BASEDRAWFUNC];
|
||||
|
||||
|
@ -2889,5 +3345,16 @@ void R_StoreWallRange(INT32 start, INT32 stop)
|
|||
ds_p->silhouette |= SIL_BOTTOM;
|
||||
ds_p->bsilheight = (sidedef->midtexture > 0 && sidedef->midtexture < numtextures) ? INT32_MAX : INT32_MIN;
|
||||
}
|
||||
|
||||
// Render up to four extra textures when everything is done
|
||||
if (hasoverlaytexture)
|
||||
{
|
||||
for (i = 0; i < NUM_WALL_OVERLAYS; i++)
|
||||
{
|
||||
if (overlaytexture[i])
|
||||
R_RenderExtraTexture(ds_p, i, ds_p->x1, ds_p->x2);
|
||||
}
|
||||
}
|
||||
|
||||
ds_p++;
|
||||
}
|
||||
|
|
|
@ -3642,7 +3642,7 @@ static void R_DrawMaskedList (drawnode_t* head)
|
|||
R_DoneWithNode(r2);
|
||||
r2 = next;
|
||||
}
|
||||
else if (r2->seg && r2->seg->maskedtexturecol != NULL)
|
||||
else if (r2->seg && r2->seg->maskedtexturecol != NULL && r2->seg->maskedtextureheight != NULL)
|
||||
{
|
||||
next = r2->prev;
|
||||
R_RenderMaskedSegRange(r2->seg, r2->seg->x1, r2->seg->x2);
|
||||
|
|
Loading…
Reference in a new issue