Implement sloped floor sprites

This commit is contained in:
Jaime Passos 2020-10-13 22:42:07 -03:00
parent fccbc00cac
commit 4b7bfce95e
10 changed files with 757 additions and 174 deletions

View File

@ -150,42 +150,53 @@ void R_Draw2sMultiPatchTranslucentColumn_8(void);
void R_DrawFogColumn_8(void);
void R_DrawColumnShadowed_8(void);
#define PLANELIGHTFLOAT (BASEVIDWIDTH * BASEVIDWIDTH / vid.width / (zeroheight - FIXED_TO_FLOAT(viewz)) / 21.0f * FIXED_TO_FLOAT(fovtan))
void R_DrawSpan_8(void);
void R_DrawSplat_8(void);
void R_DrawFloorSprite_8(void);
void R_DrawTranslucentSpan_8(void);
void R_DrawTranslucentSplat_8(void);
void R_DrawTranslucentFloorSprite_8(void);
void R_DrawTiltedSpan_8(void);
void R_DrawTiltedTranslucentSpan_8(void);
#ifndef NOWATER
void R_DrawTiltedTranslucentWaterSpan_8(void);
#endif
void R_DrawSplat_8(void);
void R_DrawTranslucentSplat_8(void);
void R_DrawTiltedSplat_8(void);
void R_DrawFloorSprite_8(void);
void R_DrawTranslucentFloorSprite_8(void);
void R_DrawTiltedFloorSprite_8(void);
void R_DrawTiltedTranslucentFloorSprite_8(void);
void R_CalcTiltedLighting(fixed_t start, fixed_t end);
extern INT32 tiltlighting[MAXVIDWIDTH];
#ifndef NOWATER
void R_DrawTranslucentWaterSpan_8(void);
void R_DrawTiltedTranslucentWaterSpan_8(void);
extern INT32 ds_bgofs;
extern INT32 ds_waterofs;
#endif
void R_DrawFogSpan_8(void);
// Lactozilla: Non-powers-of-two
void R_DrawSpan_NPO2_8(void);
void R_DrawTranslucentSpan_NPO2_8(void);
void R_DrawFloorSprite_NPO2_8(void);
void R_DrawSplat_NPO2_8(void);
void R_DrawTranslucentSplat_NPO2_8(void);
void R_DrawTranslucentFloorSprite_NPO2_8(void);
void R_DrawTiltedSpan_NPO2_8(void);
void R_DrawTiltedTranslucentSpan_NPO2_8(void);
#ifndef NOWATER
void R_DrawTiltedTranslucentWaterSpan_NPO2_8(void);
#endif
void R_DrawSplat_NPO2_8(void);
void R_DrawTranslucentSplat_NPO2_8(void);
void R_DrawTiltedSplat_NPO2_8(void);
void R_DrawFloorSprite_NPO2_8(void);
void R_DrawTranslucentFloorSprite_NPO2_8(void);
void R_DrawTiltedFloorSprite_NPO2_8(void);
void R_DrawTiltedTranslucentFloorSprite_NPO2_8(void);
#ifndef NOWATER
void R_DrawTranslucentWaterSpan_NPO2_8(void);
void R_DrawTiltedTranslucentWaterSpan_NPO2_8(void);
#endif
#ifdef USEASM

View File

@ -536,6 +536,9 @@ void R_DrawTranslatedColumn_8(void)
// SPANS
// ==========================================================================
#define SPANSIZE 16
#define INVSPAN 0.0625f
/** \brief The R_DrawSpan_8 function
Draws the actual span.
*/
@ -643,8 +646,6 @@ void R_CalcTiltedLighting(fixed_t start, fixed_t end)
}
}
#define PLANELIGHTFLOAT (BASEVIDWIDTH * BASEVIDWIDTH / vid.width / (zeroheight - FIXED_TO_FLOAT(viewz)) / 21.0f * FIXED_TO_FLOAT(fovtan))
/** \brief The R_DrawTiltedSpan_8 function
Draw slopes! Holy sheit!
*/
@ -704,9 +705,6 @@ void R_DrawTiltedSpan_8(void)
vz += ds_svp->x;
} while (--width >= 0);
#else
#define SPANSIZE 16
#define INVSPAN 0.0625f
startz = 1.f/iz;
startu = uz*startz;
startv = vz*startz;
@ -839,9 +837,6 @@ void R_DrawTiltedTranslucentSpan_8(void)
vz += ds_svp->x;
} while (--width >= 0);
#else
#define SPANSIZE 16
#define INVSPAN 0.0625f
startz = 1.f/iz;
startu = uz*startz;
startv = vz*startz;
@ -977,9 +972,6 @@ void R_DrawTiltedTranslucentWaterSpan_8(void)
vz += ds_svp->x;
} while (--width >= 0);
#else
#define SPANSIZE 16
#define INVSPAN 0.0625f
startz = 1.f/iz;
startu = uz*startz;
startv = vz*startz;
@ -1116,9 +1108,6 @@ void R_DrawTiltedSplat_8(void)
vz += ds_svp->x;
} while (--width >= 0);
#else
#define SPANSIZE 16
#define INVSPAN 0.0625f
startz = 1.f/iz;
startu = uz*startz;
startv = vz*startz;
@ -1643,6 +1632,224 @@ void R_DrawTranslucentFloorSprite_8 (void)
}
}
/** \brief The R_DrawTiltedFloorSprite_8 function
Draws a tilted floor sprite.
*/
void R_DrawTiltedFloorSprite_8(void)
{
// x1, x2 = ds_x1, ds_x2
int width = ds_x2 - ds_x1;
double iz, uz, vz;
UINT32 u, v;
int i;
UINT16 *source;
UINT8 *colormap;
UINT8 *translation;
UINT8 *dest;
UINT16 val;
double startz, startu, startv;
double izstep, uzstep, vzstep;
double endz, endu, endv;
UINT32 stepu, stepv;
iz = ds_szp->z + ds_szp->y*(centery-ds_y) + ds_szp->x*(ds_x1-centerx);
uz = ds_sup->z + ds_sup->y*(centery-ds_y) + ds_sup->x*(ds_x1-centerx);
vz = ds_svp->z + ds_svp->y*(centery-ds_y) + ds_svp->x*(ds_x1-centerx);
dest = ylookup[ds_y] + columnofs[ds_x1];
source = (UINT16 *)ds_source;
colormap = ds_colormap;
translation = ds_translation;
startz = 1.f/iz;
startu = uz*startz;
startv = vz*startz;
izstep = ds_szp->x * SPANSIZE;
uzstep = ds_sup->x * SPANSIZE;
vzstep = ds_svp->x * SPANSIZE;
//x1 = 0;
width++;
while (width >= SPANSIZE)
{
iz += izstep;
uz += uzstep;
vz += vzstep;
endz = 1.f/iz;
endu = uz*endz;
endv = vz*endz;
stepu = (INT64)((endu - startu) * INVSPAN);
stepv = (INT64)((endv - startv) * INVSPAN);
u = (INT64)(startu) + viewx;
v = (INT64)(startv) + viewy;
for (i = SPANSIZE-1; i >= 0; i--)
{
val = source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)];
if (val & 0xFF00)
*dest = colormap[translation[val & 0xFF]];
dest++;
u += stepu;
v += stepv;
}
startu = endu;
startv = endv;
width -= SPANSIZE;
}
if (width > 0)
{
if (width == 1)
{
u = (INT64)(startu);
v = (INT64)(startv);
val = source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)];
if (val & 0xFF00)
*dest = colormap[translation[val & 0xFF]];
}
else
{
double left = width;
iz += ds_szp->x * left;
uz += ds_sup->x * left;
vz += ds_svp->x * left;
endz = 1.f/iz;
endu = uz*endz;
endv = vz*endz;
left = 1.f/left;
stepu = (INT64)((endu - startu) * left);
stepv = (INT64)((endv - startv) * left);
u = (INT64)(startu) + viewx;
v = (INT64)(startv) + viewy;
for (; width != 0; width--)
{
val = source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)];
if (val & 0xFF00)
*dest = colormap[translation[val & 0xFF]];
dest++;
u += stepu;
v += stepv;
}
}
}
}
/** \brief The R_DrawTiltedTranslucentFloorSprite_8 function
Draws a tilted, translucent, floor sprite.
*/
void R_DrawTiltedTranslucentFloorSprite_8(void)
{
// x1, x2 = ds_x1, ds_x2
int width = ds_x2 - ds_x1;
double iz, uz, vz;
UINT32 u, v;
int i;
UINT16 *source;
UINT8 *colormap;
UINT8 *translation;
UINT8 *dest;
UINT16 val;
double startz, startu, startv;
double izstep, uzstep, vzstep;
double endz, endu, endv;
UINT32 stepu, stepv;
iz = ds_szp->z + ds_szp->y*(centery-ds_y) + ds_szp->x*(ds_x1-centerx);
uz = ds_sup->z + ds_sup->y*(centery-ds_y) + ds_sup->x*(ds_x1-centerx);
vz = ds_svp->z + ds_svp->y*(centery-ds_y) + ds_svp->x*(ds_x1-centerx);
dest = ylookup[ds_y] + columnofs[ds_x1];
source = (UINT16 *)ds_source;
colormap = ds_colormap;
translation = ds_translation;
startz = 1.f/iz;
startu = uz*startz;
startv = vz*startz;
izstep = ds_szp->x * SPANSIZE;
uzstep = ds_sup->x * SPANSIZE;
vzstep = ds_svp->x * SPANSIZE;
//x1 = 0;
width++;
while (width >= SPANSIZE)
{
iz += izstep;
uz += uzstep;
vz += vzstep;
endz = 1.f/iz;
endu = uz*endz;
endv = vz*endz;
stepu = (INT64)((endu - startu) * INVSPAN);
stepv = (INT64)((endv - startv) * INVSPAN);
u = (INT64)(startu) + viewx;
v = (INT64)(startv) + viewy;
for (i = SPANSIZE-1; i >= 0; i--)
{
val = source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)];
if (val & 0xFF00)
*dest = *(ds_transmap + (colormap[translation[val & 0xFF]] << 8) + *dest);
dest++;
u += stepu;
v += stepv;
}
startu = endu;
startv = endv;
width -= SPANSIZE;
}
if (width > 0)
{
if (width == 1)
{
u = (INT64)(startu);
v = (INT64)(startv);
val = source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)];
if (val & 0xFF00)
*dest = *(ds_transmap + (colormap[translation[val & 0xFF]] << 8) + *dest);
}
else
{
double left = width;
iz += ds_szp->x * left;
uz += ds_sup->x * left;
vz += ds_svp->x * left;
endz = 1.f/iz;
endu = uz*endz;
endv = vz*endz;
left = 1.f/left;
stepu = (INT64)((endu - startu) * left);
stepv = (INT64)((endv - startv) * left);
u = (INT64)(startu) + viewx;
v = (INT64)(startv) + viewy;
for (; width != 0; width--)
{
val = source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)];
if (val & 0xFF00)
*dest = *(ds_transmap + (colormap[translation[val & 0xFF]] << 8) + *dest);
dest++;
u += stepu;
v += stepv;
}
}
}
}
/** \brief The R_DrawTranslucentSpan_8 function
Draws the actual span with translucency.
*/

View File

@ -15,6 +15,9 @@
// SPANS
// ==========================================================================
#define SPANSIZE 16
#define INVSPAN 0.0625f
/** \brief The R_DrawSpan_NPO2_8 function
Draws the actual span.
*/
@ -61,8 +64,6 @@ void R_DrawSpan_NPO2_8 (void)
}
}
#define PLANELIGHTFLOAT (BASEVIDWIDTH * BASEVIDWIDTH / vid.width / (zeroheight - FIXED_TO_FLOAT(viewz)) / 21.0f * FIXED_TO_FLOAT(fovtan))
/** \brief The R_DrawTiltedSpan_NPO2_8 function
Draw slopes! Holy sheit!
*/
@ -137,9 +138,6 @@ void R_DrawTiltedSpan_NPO2_8(void)
vz += ds_svp->x;
} while (--width >= 0);
#else
#define SPANSIZE 16
#define INVSPAN 0.0625f
startz = 1.f/iz;
startu = uz*startz;
startv = vz*startz;
@ -332,9 +330,6 @@ void R_DrawTiltedTranslucentSpan_NPO2_8(void)
vz += ds_svp->x;
} while (--width >= 0);
#else
#define SPANSIZE 16
#define INVSPAN 0.0625f
startz = 1.f/iz;
startu = uz*startz;
startv = vz*startz;
@ -531,9 +526,6 @@ void R_DrawTiltedSplat_NPO2_8(void)
vz += ds_svp->x;
} while (--width >= 0);
#else
#define SPANSIZE 16
#define INVSPAN 0.0625f
startz = 1.f/iz;
startu = uz*startz;
startv = vz*startz;
@ -852,6 +844,306 @@ void R_DrawTranslucentFloorSprite_NPO2_8 (void)
}
}
/** \brief The R_DrawTiltedFloorSprite_NPO2_8 function
Draws a tilted floor sprite.
*/
void R_DrawTiltedFloorSprite_NPO2_8(void)
{
// x1, x2 = ds_x1, ds_x2
int width = ds_x2 - ds_x1;
double iz, uz, vz;
UINT32 u, v;
int i;
UINT16 *source;
UINT8 *colormap;
UINT8 *translation;
UINT8 *dest;
UINT16 val;
double startz, startu, startv;
double izstep, uzstep, vzstep;
double endz, endu, endv;
UINT32 stepu, stepv;
iz = ds_szp->z + ds_szp->y*(centery-ds_y) + ds_szp->x*(ds_x1-centerx);
uz = ds_sup->z + ds_sup->y*(centery-ds_y) + ds_sup->x*(ds_x1-centerx);
vz = ds_svp->z + ds_svp->y*(centery-ds_y) + ds_svp->x*(ds_x1-centerx);
dest = ylookup[ds_y] + columnofs[ds_x1];
source = (UINT16 *)ds_source;
colormap = ds_colormap;
translation = ds_translation;
startz = 1.f/iz;
startu = uz*startz;
startv = vz*startz;
izstep = ds_szp->x * SPANSIZE;
uzstep = ds_sup->x * SPANSIZE;
vzstep = ds_svp->x * SPANSIZE;
//x1 = 0;
width++;
while (width >= SPANSIZE)
{
iz += izstep;
uz += uzstep;
vz += vzstep;
endz = 1.f/iz;
endu = uz*endz;
endv = vz*endz;
stepu = (INT64)((endu - startu) * INVSPAN);
stepv = (INT64)((endv - startv) * INVSPAN);
u = (INT64)(startu) + viewx;
v = (INT64)(startv) + viewy;
for (i = SPANSIZE-1; i >= 0; i--)
{
// Lactozilla: Non-powers-of-two
fixed_t x = (((fixed_t)u-viewx) >> FRACBITS);
fixed_t y = (((fixed_t)v-viewy) >> FRACBITS);
// Carefully align all of my Friends.
if (x < 0)
x = ds_flatwidth - ((UINT32)(ds_flatwidth - x) % ds_flatwidth);
if (y < 0)
y = ds_flatheight - ((UINT32)(ds_flatheight - y) % ds_flatheight);
x %= ds_flatwidth;
y %= ds_flatheight;
val = source[((y * ds_flatwidth) + x)];
if (val & 0xFF00)
*dest = colormap[translation[val & 0xFF]];
dest++;
u += stepu;
v += stepv;
}
startu = endu;
startv = endv;
width -= SPANSIZE;
}
if (width > 0)
{
if (width == 1)
{
u = (INT64)(startu);
v = (INT64)(startv);
// Lactozilla: Non-powers-of-two
{
fixed_t x = (((fixed_t)u-viewx) >> FRACBITS);
fixed_t y = (((fixed_t)v-viewy) >> FRACBITS);
// Carefully align all of my Friends.
if (x < 0)
x = ds_flatwidth - ((UINT32)(ds_flatwidth - x) % ds_flatwidth);
if (y < 0)
y = ds_flatheight - ((UINT32)(ds_flatheight - y) % ds_flatheight);
x %= ds_flatwidth;
y %= ds_flatheight;
val = source[((y * ds_flatwidth) + x)];
if (val & 0xFF00)
*dest = colormap[translation[val & 0xFF]];
}
}
else
{
double left = width;
iz += ds_szp->x * left;
uz += ds_sup->x * left;
vz += ds_svp->x * left;
endz = 1.f/iz;
endu = uz*endz;
endv = vz*endz;
left = 1.f/left;
stepu = (INT64)((endu - startu) * left);
stepv = (INT64)((endv - startv) * left);
u = (INT64)(startu) + viewx;
v = (INT64)(startv) + viewy;
for (; width != 0; width--)
{
// Lactozilla: Non-powers-of-two
fixed_t x = (((fixed_t)u-viewx) >> FRACBITS);
fixed_t y = (((fixed_t)v-viewy) >> FRACBITS);
// Carefully align all of my Friends.
if (x < 0)
x = ds_flatwidth - ((UINT32)(ds_flatwidth - x) % ds_flatwidth);
if (y < 0)
y = ds_flatheight - ((UINT32)(ds_flatheight - y) % ds_flatheight);
x %= ds_flatwidth;
y %= ds_flatheight;
val = source[((y * ds_flatwidth) + x)];
if (val & 0xFF00)
*dest = colormap[translation[val & 0xFF]];
dest++;
u += stepu;
v += stepv;
}
}
}
}
/** \brief The R_DrawTiltedTranslucentFloorSprite_NPO2_8 function
Draws a tilted, translucent, floor sprite.
*/
void R_DrawTiltedTranslucentFloorSprite_NPO2_8(void)
{
// x1, x2 = ds_x1, ds_x2
int width = ds_x2 - ds_x1;
double iz, uz, vz;
UINT32 u, v;
int i;
UINT16 *source;
UINT8 *colormap;
UINT8 *translation;
UINT8 *dest;
UINT16 val;
double startz, startu, startv;
double izstep, uzstep, vzstep;
double endz, endu, endv;
UINT32 stepu, stepv;
iz = ds_szp->z + ds_szp->y*(centery-ds_y) + ds_szp->x*(ds_x1-centerx);
uz = ds_sup->z + ds_sup->y*(centery-ds_y) + ds_sup->x*(ds_x1-centerx);
vz = ds_svp->z + ds_svp->y*(centery-ds_y) + ds_svp->x*(ds_x1-centerx);
dest = ylookup[ds_y] + columnofs[ds_x1];
source = (UINT16 *)ds_source;
colormap = ds_colormap;
translation = ds_translation;
startz = 1.f/iz;
startu = uz*startz;
startv = vz*startz;
izstep = ds_szp->x * SPANSIZE;
uzstep = ds_sup->x * SPANSIZE;
vzstep = ds_svp->x * SPANSIZE;
//x1 = 0;
width++;
while (width >= SPANSIZE)
{
iz += izstep;
uz += uzstep;
vz += vzstep;
endz = 1.f/iz;
endu = uz*endz;
endv = vz*endz;
stepu = (INT64)((endu - startu) * INVSPAN);
stepv = (INT64)((endv - startv) * INVSPAN);
u = (INT64)(startu) + viewx;
v = (INT64)(startv) + viewy;
for (i = SPANSIZE-1; i >= 0; i--)
{
// Lactozilla: Non-powers-of-two
fixed_t x = (((fixed_t)u-viewx) >> FRACBITS);
fixed_t y = (((fixed_t)v-viewy) >> FRACBITS);
// Carefully align all of my Friends.
if (x < 0)
x = ds_flatwidth - ((UINT32)(ds_flatwidth - x) % ds_flatwidth);
if (y < 0)
y = ds_flatheight - ((UINT32)(ds_flatheight - y) % ds_flatheight);
x %= ds_flatwidth;
y %= ds_flatheight;
val = source[((y * ds_flatwidth) + x)];
if (val & 0xFF00)
*dest = *(ds_transmap + (colormap[translation[val & 0xFF]] << 8) + *dest);
dest++;
u += stepu;
v += stepv;
}
startu = endu;
startv = endv;
width -= SPANSIZE;
}
if (width > 0)
{
if (width == 1)
{
u = (INT64)(startu);
v = (INT64)(startv);
// Lactozilla: Non-powers-of-two
{
fixed_t x = (((fixed_t)u-viewx) >> FRACBITS);
fixed_t y = (((fixed_t)v-viewy) >> FRACBITS);
// Carefully align all of my Friends.
if (x < 0)
x = ds_flatwidth - ((UINT32)(ds_flatwidth - x) % ds_flatwidth);
if (y < 0)
y = ds_flatheight - ((UINT32)(ds_flatheight - y) % ds_flatheight);
x %= ds_flatwidth;
y %= ds_flatheight;
val = source[((y * ds_flatwidth) + x)];
if (val & 0xFF00)
*dest = *(ds_transmap + (colormap[translation[val & 0xFF]] << 8) + *dest);
}
}
else
{
double left = width;
iz += ds_szp->x * left;
uz += ds_sup->x * left;
vz += ds_svp->x * left;
endz = 1.f/iz;
endu = uz*endz;
endv = vz*endz;
left = 1.f/left;
stepu = (INT64)((endu - startu) * left);
stepv = (INT64)((endv - startv) * left);
u = (INT64)(startu) + viewx;
v = (INT64)(startv) + viewy;
for (; width != 0; width--)
{
// Lactozilla: Non-powers-of-two
fixed_t x = (((fixed_t)u-viewx) >> FRACBITS);
fixed_t y = (((fixed_t)v-viewy) >> FRACBITS);
// Carefully align all of my Friends.
if (x < 0)
x = ds_flatwidth - ((UINT32)(ds_flatwidth - x) % ds_flatwidth);
if (y < 0)
y = ds_flatheight - ((UINT32)(ds_flatheight - y) % ds_flatheight);
x %= ds_flatwidth;
y %= ds_flatheight;
val = source[((y * ds_flatwidth) + x)];
if (val & 0xFF00)
*dest = *(ds_transmap + (colormap[translation[val & 0xFF]] << 8) + *dest);
dest++;
u += stepu;
v += stepv;
}
}
}
}
/** \brief The R_DrawTranslucentSpan_NPO2_8 function
Draws the actual span with translucency.
*/
@ -1016,9 +1308,6 @@ void R_DrawTiltedTranslucentWaterSpan_NPO2_8(void)
vz += ds_svp->x;
} while (--width >= 0);
#else
#define SPANSIZE 16
#define INVSPAN 0.0625f
startz = 1.f/iz;
startu = uz*startz;
startv = vz*startz;

View File

@ -645,46 +645,48 @@ static void R_DrawSkyPlane(visplane_t *pl)
}
}
static void R_SlopeVectors(visplane_t *pl, INT32 i, float fudge)
// Potentially override other stuff for now cus we're mean. :< But draw a slope plane!
// I copied ZDoom's code and adapted it to SRB2... -Red
void R_CalculateSlopeVectors(pslope_t *slope, fixed_t planeviewx, fixed_t planeviewy, fixed_t planeviewz, fixed_t planexscale, fixed_t planeyscale, fixed_t planexoffset, fixed_t planeyoffset, angle_t planeviewangle, angle_t planeangle, float fudge)
{
// Potentially override other stuff for now cus we're mean. :< But draw a slope plane!
// I copied ZDoom's code and adapted it to SRB2... -Red
floatv3_t p, m, n;
float ang;
float vx, vy, vz;
float xscale = FIXED_TO_FLOAT(planexscale);
float yscale = FIXED_TO_FLOAT(planeyscale);
// compiler complains when P_GetSlopeZAt is used in FLOAT_TO_FIXED directly
// use this as a temp var to store P_GetSlopeZAt's return value each time
fixed_t temp;
vx = FIXED_TO_FLOAT(pl->viewx+xoffs);
vy = FIXED_TO_FLOAT(pl->viewy-yoffs);
vz = FIXED_TO_FLOAT(pl->viewz);
vx = FIXED_TO_FLOAT(planeviewx+planexoffset);
vy = FIXED_TO_FLOAT(planeviewy-planeyoffset);
vz = FIXED_TO_FLOAT(planeviewz);
temp = P_GetSlopeZAt(pl->slope, pl->viewx, pl->viewy);
temp = P_GetSlopeZAt(slope, planeviewx, planeviewy);
zeroheight = FIXED_TO_FLOAT(temp);
// p is the texture origin in view space
// Don't add in the offsets at this stage, because doing so can result in
// errors if the flat is rotated.
ang = ANG2RAD(ANGLE_270 - pl->viewangle);
ang = ANG2RAD(ANGLE_270 - planeviewangle);
p.x = vx * cos(ang) - vy * sin(ang);
p.z = vx * sin(ang) + vy * cos(ang);
temp = P_GetSlopeZAt(pl->slope, -xoffs, yoffs);
temp = P_GetSlopeZAt(slope, -planexoffset, planeyoffset);
p.y = FIXED_TO_FLOAT(temp) - vz;
// m is the v direction vector in view space
ang = ANG2RAD(ANGLE_180 - (pl->viewangle + pl->plangle));
m.x = cos(ang);
m.z = sin(ang);
ang = ANG2RAD(ANGLE_180 - (planeviewangle + planeangle));
m.x = yscale * cos(ang);
m.z = yscale * sin(ang);
// n is the u direction vector in view space
n.x = sin(ang);
n.z = -cos(ang);
n.x = xscale * sin(ang);
n.z = -xscale * cos(ang);
ang = ANG2RAD(pl->plangle);
temp = P_GetSlopeZAt(pl->slope, pl->viewx + FLOAT_TO_FIXED(sin(ang)), pl->viewy + FLOAT_TO_FIXED(cos(ang)));
ang = ANG2RAD(planeangle);
temp = P_GetSlopeZAt(slope, planeviewx + yscale * FLOAT_TO_FIXED(sin(ang)), planeviewy + yscale * FLOAT_TO_FIXED(cos(ang)));
m.y = FIXED_TO_FLOAT(temp) - zeroheight;
temp = P_GetSlopeZAt(pl->slope, pl->viewx + FLOAT_TO_FIXED(cos(ang)), pl->viewy - FLOAT_TO_FIXED(sin(ang)));
temp = P_GetSlopeZAt(slope, planeviewx + xscale * FLOAT_TO_FIXED(cos(ang)), planeviewy - xscale * FLOAT_TO_FIXED(sin(ang)));
n.y = FIXED_TO_FLOAT(temp) - zeroheight;
if (ds_powersoftwo)
@ -700,42 +702,50 @@ static void R_SlopeVectors(visplane_t *pl, INT32 i, float fudge)
// Eh. I tried making this stuff fixed-point and it exploded on me. Here's a macro for the only floating-point vector function I recall using.
#define CROSS(d, v1, v2) \
d.x = (v1.y * v2.z) - (v1.z * v2.y);\
d.y = (v1.z * v2.x) - (v1.x * v2.z);\
d.z = (v1.x * v2.y) - (v1.y * v2.x)
CROSS(ds_su[i], p, m);
CROSS(ds_sv[i], p, n);
CROSS(ds_sz[i], m, n);
d->x = (v1.y * v2.z) - (v1.z * v2.y);\
d->y = (v1.z * v2.x) - (v1.x * v2.z);\
d->z = (v1.x * v2.y) - (v1.y * v2.x)
CROSS(ds_sup, p, m);
CROSS(ds_svp, p, n);
CROSS(ds_szp, m, n);
#undef CROSS
ds_su[i].z *= focallengthf;
ds_sv[i].z *= focallengthf;
ds_sz[i].z *= focallengthf;
ds_sup->z *= focallengthf;
ds_svp->z *= focallengthf;
ds_szp->z *= focallengthf;
// Premultiply the texture vectors with the scale factors
#define SFMULT 65536.f
if (ds_powersoftwo)
{
ds_su[i].x *= (SFMULT * (1<<nflatshiftup));
ds_su[i].y *= (SFMULT * (1<<nflatshiftup));
ds_su[i].z *= (SFMULT * (1<<nflatshiftup));
ds_sv[i].x *= (SFMULT * (1<<nflatshiftup));
ds_sv[i].y *= (SFMULT * (1<<nflatshiftup));
ds_sv[i].z *= (SFMULT * (1<<nflatshiftup));
ds_sup->x *= (SFMULT * (1<<nflatshiftup));
ds_sup->y *= (SFMULT * (1<<nflatshiftup));
ds_sup->z *= (SFMULT * (1<<nflatshiftup));
ds_svp->x *= (SFMULT * (1<<nflatshiftup));
ds_svp->y *= (SFMULT * (1<<nflatshiftup));
ds_svp->z *= (SFMULT * (1<<nflatshiftup));
}
else
{
// Lactozilla: I'm essentially multiplying the vectors by FRACUNIT...
ds_su[i].x *= SFMULT;
ds_su[i].y *= SFMULT;
ds_su[i].z *= SFMULT;
ds_sv[i].x *= SFMULT;
ds_sv[i].y *= SFMULT;
ds_sv[i].z *= SFMULT;
ds_sup->x *= SFMULT;
ds_sup->y *= SFMULT;
ds_sup->z *= SFMULT;
ds_svp->x *= SFMULT;
ds_svp->y *= SFMULT;
ds_svp->z *= SFMULT;
}
#undef SFMULT
}
static void R_SlopePlaneVectors(visplane_t *pl, INT32 i, float fudge)
{
ds_sup = &ds_su[i];
ds_svp = &ds_sv[i];
ds_szp = &ds_sz[i];
R_CalculateSlopeVectors(pl->slope, pl->viewx, pl->viewy, pl->viewz, FRACUNIT, FRACUNIT, xoffs, yoffs, pl->viewangle, pl->plangle, fudge);
}
void R_DrawSinglePlane(visplane_t *pl)
{
levelflat_t *levelflat;
@ -992,7 +1002,7 @@ void R_DrawSinglePlane(visplane_t *pl)
R_PlaneRipple(pl, i, plheight);
xoffs = rxoffs + ripple_xfrac;
yoffs = ryoffs + ripple_yfrac;
R_SlopeVectors(pl, i, fudgecanyon);
R_SlopePlaneVectors(pl, i, fudgecanyon);
}
xoffs = rxoffs;
@ -1000,7 +1010,7 @@ void R_DrawSinglePlane(visplane_t *pl)
}
else
#endif
R_SlopeVectors(pl, 0, fudgecanyon);
R_SlopePlaneVectors(pl, 0, fudgecanyon);
#ifndef NOWATER
if (itswater && (spanfunctype == SPANDRAWFUNC_WATER))

View File

@ -84,11 +84,15 @@ visplane_t *R_CheckPlane(visplane_t *pl, INT32 start, INT32 stop);
void R_ExpandPlane(visplane_t *pl, INT32 start, INT32 stop);
void R_PlaneBounds(visplane_t *plane);
// Draws a single visplane.
void R_DrawSinglePlane(visplane_t *pl);
void R_CheckFlatLength(size_t size);
boolean R_CheckPowersOfTwo(void);
// Draws a single visplane.
void R_DrawSinglePlane(visplane_t *pl);
// Calculates the slope vectors needed for tilted span drawing.
void R_CalculateSlopeVectors(pslope_t *slope, fixed_t planeviewx, fixed_t planeviewy, fixed_t planeviewz, fixed_t planexscale, fixed_t planeyscale, fixed_t planexoffset, fixed_t planeyoffset, angle_t planeviewangle, angle_t planeangle, float fudge);
typedef struct planemgr_s
{
visplane_t *plane;

View File

@ -14,6 +14,7 @@
#include "r_main.h"
#include "r_splats.h"
#include "r_bsp.h"
#include "p_slopes.h"
#include "w_wad.h"
#include "z_zone.h"
@ -143,10 +144,10 @@ static void rasterize_segment_tex(INT32 x1, INT32 y1, INT32 x2, INT32 y2, INT32
// fill the polygon with linear interpolation, call span drawer for each
// scan line
// --------------------------------------------------------------------------
void R_RenderFloorSplat(floorsplat_t *pSplat, vertex_t *verts, vissprite_t *vis)
void R_RenderFloorSplat(floorsplat_t *pSplat, vector2_t *verts, vissprite_t *vis)
{
// rasterizing
INT32 miny = viewheight + 1, maxy = 0, y, x1, ry1, x2, y2, i;
INT32 miny = viewheight + 1, maxy = 0, y, x1, ry1, x2, y2, i, xclip;
fixed_t offsetx = 0, offsety = 0;
fixed_t step;
@ -217,19 +218,47 @@ void R_RenderFloorSplat(floorsplat_t *pSplat, vertex_t *verts, vissprite_t *vis)
// do segment d -> left side of texture
RASTERPARAMS(0,3,pSplat->width-1,0,0,1);
ds_source = pSplat->pic;
ds_source = (UINT8 *)pSplat->pic;
ds_flatwidth = pSplat->width;
ds_flatheight = pSplat->height;
if (R_CheckPowersOfTwo())
R_CheckFlatLength(ds_flatwidth * ds_flatheight);
// Lactozilla: I don't know what I'm doing
if (pSplat->tilted)
{
R_CalculateSlopeVectors(&pSplat->slope, viewx, viewy, viewz, pSplat->xscale, pSplat->yscale, -pSplat->verts[0].x, pSplat->verts[0].y, viewangle, pSplat->angle, 1.0f);
spanfunctype = SPANDRAWFUNC_TILTEDSPRITE;
}
else
{
if (pSplat->angle)
{
// Add the view offset, rotated by the plane angle.
fixed_t a = -pSplat->verts[0].x + viewx;
fixed_t b = -pSplat->verts[0].y + viewy;
angle = (pSplat->angle >> ANGLETOFINESHIFT);
offsetx = FixedMul(a, FINECOSINE(angle)) - FixedMul(b,FINESINE(angle));
offsety = -FixedMul(a, FINESINE(angle)) - FixedMul(b,FINECOSINE(angle));
}
else
{
offsetx = viewx - pSplat->verts[0].x;
offsety = pSplat->verts[0].y - viewy;
}
}
ds_transmap = NULL;
if (vis->transmap)
{
ds_transmap = vis->transmap;
spanfunctype = SPANDRAWFUNC_TRANSSPRITE;
if (pSplat->tilted)
spanfunctype = SPANDRAWFUNC_TILTEDTRANSSPRITE;
else
spanfunctype = SPANDRAWFUNC_TRANSSPRITE;
}
if (ds_powersoftwo)
@ -237,7 +266,7 @@ void R_RenderFloorSplat(floorsplat_t *pSplat, vertex_t *verts, vissprite_t *vis)
else
spanfunc = spanfuncs_npo2[spanfunctype];
if (pSplat->angle)
if (pSplat->angle && !pSplat->tilted)
{
memset(cachedheight, 0, sizeof(cachedheight));
angle = (viewangle + pSplat->angle - ANGLE_90) >> ANGLETOFINESHIFT;
@ -252,7 +281,6 @@ void R_RenderFloorSplat(floorsplat_t *pSplat, vertex_t *verts, vissprite_t *vis)
}
planeheight = abs(pSplat->z - viewz);
if (maxy >= vid.height)
maxy = vid.height-1;
@ -276,33 +304,6 @@ void R_RenderFloorSplat(floorsplat_t *pSplat, vertex_t *verts, vissprite_t *vis)
if (x2 >= vid.width)
x2 = vid.width - 1;
angle = (viewangle + pSplat->angle)>>ANGLETOFINESHIFT;
planecos = FINECOSINE(angle);
planesin = FINESINE(angle);
if (planeheight != cachedheight[y])
{
cachedheight[y] = planeheight;
distance = cacheddistance[y] = FixedMul(planeheight, yslope[y]);
xstep = cachedxstep[y] = FixedMul(distance, basexscale);
ystep = cachedystep[y] = FixedMul(distance, baseyscale);
// don't divide by zero
if ((span = abs(centery-y)))
{
xstep = cachedxstep[y] = FixedMul(planesin, planeheight) / span;
ystep = cachedystep[y] = FixedMul(planecos, planeheight) / span;
}
}
else
{
distance = cacheddistance[y];
xstep = cachedxstep[y];
ystep = cachedystep[y];
}
ds_xstep = FixedDiv(xstep, pSplat->xscale);
ds_ystep = FixedDiv(ystep, pSplat->yscale);
ds_colormap = vis->colormap;
ds_translation = R_GetSpriteTranslation(vis);
if (ds_translation == NULL)
@ -316,53 +317,61 @@ void R_RenderFloorSplat(floorsplat_t *pSplat, vertex_t *verts, vissprite_t *vis)
ds_colormap = &vis->extra_colormap->colormap[ds_colormap - colormaps];
}
if (pSplat->angle)
R_ClipVisSprite(vis, x1-1, x2+1, drawsegs, NULL);
memset(ds_splatclip, 0, sizeof(ds_splatclip));
if (x2 >= x1 && x1 < viewwidth && x1 >= 0)
{
// Add the view offset, rotated by the plane angle.
fixed_t a = -pSplat->verts[0].x + viewx;
fixed_t b = -pSplat->verts[0].y + viewy;
angle = (pSplat->angle >> ANGLETOFINESHIFT);
offsetx = FixedMul(a, FINECOSINE(angle)) - FixedMul(b,FINESINE(angle));
offsety = -FixedMul(a, FINESINE(angle)) - FixedMul(b,FINECOSINE(angle));
}
else
{
offsetx = viewx - pSplat->verts[0].x;
offsety = pSplat->verts[0].y - viewy;
}
if (vis != NULL)
{
INT32 xclip;
mfloorclip = vis->clipbot;
mceilingclip = vis->cliptop;
R_ClipVisSprite(vis, x1-1, x2+1, drawsegs, NULL);
memset(ds_splatclip, 0, sizeof(ds_splatclip));
if (x2 >= x1 && x1 < viewwidth && x1 >= 0)
for (xclip = x1; xclip <= x2; xclip++)
{
for (xclip = x1; xclip <= x2; xclip++)
if (y >= mfloorclip[xclip])
ds_splatclip[xclip] = 1;
}
}
while (ds_splatclip[x1])
x1++;
i = x2;
while (i > x1)
{
if (ds_splatclip[i])
x2 = i-1;
i--;
}
if (!pSplat->tilted)
{
angle = (viewangle + pSplat->angle)>>ANGLETOFINESHIFT;
planecos = FINECOSINE(angle);
planesin = FINESINE(angle);
if (planeheight != cachedheight[y])
{
cachedheight[y] = planeheight;
distance = cacheddistance[y] = FixedMul(planeheight, yslope[y]);
xstep = cachedxstep[y] = FixedMul(distance, basexscale);
ystep = cachedystep[y] = FixedMul(distance, baseyscale);
// don't divide by zero
if ((span = abs(centery-y)))
{
if (y >= mfloorclip[xclip])
ds_splatclip[xclip] = 1;
xstep = cachedxstep[y] = FixedMul(planesin, planeheight) / span;
ystep = cachedystep[y] = FixedMul(planecos, planeheight) / span;
}
}
while (ds_splatclip[x1])
x1++;
i = x2;
while (i > x1)
else
{
if (ds_splatclip[i])
x2 = i-1;
i--;
distance = cacheddistance[y];
xstep = cachedxstep[y];
ystep = cachedystep[y];
}
}
ds_xfrac = FixedDiv(offsetx + FixedMul(planecos, distance) + (x1 - centerx) * xstep, pSplat->xscale);
ds_yfrac = FixedDiv(offsety - FixedMul(planesin, distance) + (x1 - centerx) * ystep, pSplat->yscale);
ds_xstep = FixedDiv(xstep, pSplat->xscale);
ds_ystep = FixedDiv(ystep, pSplat->yscale);
ds_xfrac = FixedDiv(offsetx + FixedMul(planecos, distance) + (x1 - centerx) * xstep, pSplat->xscale);
ds_yfrac = FixedDiv(offsety - FixedMul(planesin, distance) + (x1 - centerx) * ystep, pSplat->yscale);
}
if (x2 >= x1)
{
@ -376,7 +385,7 @@ void R_RenderFloorSplat(floorsplat_t *pSplat, vertex_t *verts, vissprite_t *vis)
rastertab[y].maxx = INT32_MIN;
}
if (pSplat->angle)
if (pSplat->angle && !pSplat->tilted)
{
memset(cachedheight, 0, sizeof(cachedheight));
angle = (viewangle - ANGLE_90) >> ANGLETOFINESHIFT;

View File

@ -31,17 +31,19 @@ extern struct rastery_s *prastertab; // for ASM code
#ifdef FLOORSPLATS
typedef struct floorsplat_s
{
UINT8 *pic;
UINT16 *pic;
INT32 width, height;
fixed_t scale, xscale, yscale;
angle_t angle;
boolean tilted; // Uses the tilted drawer
pslope_t slope;
vertex_t verts[4]; // (x,y) as viewed from above on map
vector3_t verts[4]; // (x,y,z) as viewed from above on map
fixed_t x, y, z; // position
mobj_t *mobj; // Mobj it is tied to
} floorsplat_t;
void R_RenderFloorSplat(floorsplat_t *pSplat, vertex_t *verts, vissprite_t *vis);
void R_RenderFloorSplat(floorsplat_t *pSplat, vector2_t *verts, vissprite_t *vis);
extern UINT8 ds_splatclip[MAXVIDWIDTH];
#endif

View File

@ -1415,7 +1415,7 @@ static void R_ProjectSprite(mobj_t *thing)
fixed_t tx, tz;
fixed_t xscale, yscale; //added : 02-02-98 : aaargll..if I were a math-guy!!!
fixed_t sortscale, sortsplat = 0;
fixed_t sort_x = 0, sort_y = 0;
fixed_t sort_x = 0, sort_y = 0, sort_z;
INT32 x1, x2;
@ -1764,10 +1764,10 @@ static void R_ProjectSprite(mobj_t *thing)
// Adjust the sort scale if needed
if (splat)
{
tz = (patch->height - patch->topoffset) * FRACUNIT;
sort_z = (patch->height - patch->topoffset) * FRACUNIT;
ang = (viewangle >> ANGLETOFINESHIFT);
sort_x = FixedMul(FixedMul(FixedMul(spritexscale, this_scale), tz), FINECOSINE(ang));
sort_y = FixedMul(FixedMul(FixedMul(spriteyscale, this_scale), tz), FINESINE(ang));
sort_x = FixedMul(FixedMul(FixedMul(spritexscale, this_scale), sort_z), FINECOSINE(ang));
sort_y = FixedMul(FixedMul(FixedMul(spriteyscale, this_scale), sort_z), FINESINE(ang));
}
if ((thing->flags2 & MF2_LINKDRAW) && thing->tracer) // toast 16/09/16 (SYMMETRY)
@ -1797,8 +1797,8 @@ static void R_ProjectSprite(mobj_t *thing)
{
tr_x = (thing->x + sort_x) - viewx;
tr_y = (thing->y + sort_y) - viewy;
tz = FixedMul(tr_x, viewcos) + FixedMul(tr_y, viewsin);
sortscale = FixedDiv(projectiony, tz);
sort_z = FixedMul(tr_x, viewcos) + FixedMul(tr_y, viewsin);
sortscale = FixedDiv(projectiony, sort_z);
}
// Calculate the splat's sortscale
@ -1806,8 +1806,8 @@ static void R_ProjectSprite(mobj_t *thing)
{
tr_x = (thing->x - sort_x) - viewx;
tr_y = (thing->y - sort_y) - viewy;
tz = FixedMul(tr_x, viewcos) + FixedMul(tr_y, viewsin);
sortsplat = FixedDiv(projectiony, tz);
sort_z = FixedMul(tr_x, viewcos) + FixedMul(tr_y, viewsin);
sortsplat = FixedDiv(projectiony, sort_z);
}
// PORTAL SPRITE CLIPPING
@ -2796,8 +2796,8 @@ static void R_DrawVisSplat(vissprite_t *spr)
#ifdef FLOORSPLATS
floorsplat_t splat;
fixed_t tr_x, tr_y, rot_x, rot_y, rot_z;
vertex_t *v3d;
vertex_t v2d[4];
vector3_t *v3d;
vector2_t v2d[4];
fixed_t x, y;
fixed_t w, h;
angle_t splatangle, angle;
@ -2809,6 +2809,7 @@ static void R_DrawVisSplat(vissprite_t *spr)
boolean vflip = (spr->cut & SC_VFLIP);
UINT8 flipflags = 0;
vector2_t rotated[4];
pslope_t *slope = NULL;
INT32 i;
if (hflip)
@ -2826,6 +2827,9 @@ static void R_DrawVisSplat(vissprite_t *spr)
splat.height = spr->patch->height;
splat.scale = spr->mobj->scale;
if (spr->mobj->skin && ((skin_t *)spr->mobj->skin)->flags & SF_HIRES)
splat.scale = FixedMul(splat.scale, ((skin_t *)spr->mobj->skin)->highresscale);
if (spr->rotateflags & SRF_3D || spr->renderflags & RF_NOSPLATBILLBOARD)
splatangle = spr->mobj->angle;
else
@ -2859,6 +2863,7 @@ static void R_DrawVisSplat(vissprite_t *spr)
splat.x = x;
splat.y = y;
splat.z = spr->mobj->z;
splat.tilted = false;
// Set positions
@ -2889,14 +2894,53 @@ static void R_DrawVisSplat(vissprite_t *spr)
rotated[i].y = FixedMul(splat.verts[i].x, sa) + FixedMul(splat.verts[i].y, ca);
}
if (spr->renderflags & RF_SLOPESPLAT)
{
slope = spr->mobj->standingslope;
splat.tilted = (slope != NULL);
}
if (splat.tilted)
{
// Lactozilla: Just copy the entire slope LMFAOOOO
pslope_t *s = &splat.slope;
s->o.x = slope->o.x;
s->o.y = slope->o.y;
s->o.z = slope->o.z;
s->d.x = slope->d.x;
s->d.y = slope->d.y;
s->normal.x = slope->normal.x;
s->normal.y = slope->normal.y;
s->normal.z = slope->normal.z;
s->zdelta = slope->zdelta;
s->zangle = slope->zangle;
s->xydirection = slope->xydirection;
s->next = NULL;
s->flags = 0;
}
// Translate
for (i = 0; i < 4; i++)
{
splat.verts[i].x = rotated[i].x + x;
splat.verts[i].y = rotated[i].y + y;
}
tr_x = rotated[i].x + x;
tr_y = rotated[i].y + y;
rot_z = splat.z - viewz;
if (slope)
{
rot_z = P_GetSlopeZAt(slope, tr_x, tr_y);
splat.verts[i].z = rot_z;
}
else
splat.verts[i].z = splat.z;
splat.verts[i].x = tr_x;
splat.verts[i].y = tr_y;
}
for (i = 0; i < 4; i++)
{
@ -2909,6 +2953,7 @@ static void R_DrawVisSplat(vissprite_t *spr)
// rotation around vertical y axis
rot_x = FixedMul(tr_x, viewsin) - FixedMul(tr_y, viewcos);
rot_y = FixedMul(tr_x, viewcos) + FixedMul(tr_y, viewsin);
rot_z = v3d->z - viewz;
if (!rot_y || rot_y < FixedDiv(4*FRACUNIT, splat.scale))
return;

View File

@ -126,6 +126,8 @@ void SCR_SetDrawFuncs(void)
spanfuncs[SPANDRAWFUNC_TRANSSPLAT] = R_DrawTranslucentSplat_8;
spanfuncs[SPANDRAWFUNC_SPRITE] = R_DrawFloorSprite_8;
spanfuncs[SPANDRAWFUNC_TRANSSPRITE] = R_DrawTranslucentFloorSprite_8;
spanfuncs[SPANDRAWFUNC_TILTEDSPRITE] = R_DrawTiltedFloorSprite_8;
spanfuncs[SPANDRAWFUNC_TILTEDTRANSSPRITE] = R_DrawTiltedTranslucentFloorSprite_8;
spanfuncs[SPANDRAWFUNC_FOG] = R_DrawFogSpan_8;
#ifndef NOWATER
spanfuncs[SPANDRAWFUNC_WATER] = R_DrawTranslucentWaterSpan_8;
@ -144,6 +146,8 @@ void SCR_SetDrawFuncs(void)
spanfuncs_npo2[SPANDRAWFUNC_TRANSSPLAT] = R_DrawTranslucentSplat_NPO2_8;
spanfuncs_npo2[SPANDRAWFUNC_SPRITE] = R_DrawFloorSprite_NPO2_8;
spanfuncs_npo2[SPANDRAWFUNC_TRANSSPRITE] = R_DrawTranslucentFloorSprite_NPO2_8;
spanfuncs_npo2[SPANDRAWFUNC_TILTEDSPRITE] = R_DrawTiltedFloorSprite_NPO2_8;
spanfuncs_npo2[SPANDRAWFUNC_TILTEDTRANSSPRITE] = R_DrawTiltedTranslucentFloorSprite_NPO2_8;
spanfuncs_npo2[SPANDRAWFUNC_FOG] = NULL; // Not needed
#ifndef NOWATER
spanfuncs_npo2[SPANDRAWFUNC_WATER] = R_DrawTranslucentWaterSpan_NPO2_8;

View File

@ -144,6 +144,8 @@ enum
SPANDRAWFUNC_TRANSSPLAT,
SPANDRAWFUNC_SPRITE,
SPANDRAWFUNC_TRANSSPRITE,
SPANDRAWFUNC_TILTEDSPRITE,
SPANDRAWFUNC_TILTEDTRANSSPRITE,
SPANDRAWFUNC_FOG,
#ifndef NOWATER
SPANDRAWFUNC_WATER,