diff --git a/src/p_saveg.c b/src/p_saveg.c index eec3dbf3e..621abcb48 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -30,6 +30,9 @@ #include "r_sky.h" #include "p_polyobj.h" #include "lua_script.h" +#ifdef ESLOPE +#include "p_slopes.h" +#endif savedata_t savedata; UINT8 *save_p; @@ -921,7 +924,8 @@ typedef enum MD2_EXTVAL1 = 1<<5, MD2_EXTVAL2 = 1<<6, MD2_HNEXT = 1<<7, - MD2_HPREV = 1<<8 + MD2_HPREV = 1<<8, + MD2_SLOPE = 1<<9 } mobj_diff2_t; typedef enum @@ -1109,6 +1113,8 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type) diff2 |= MD2_HNEXT; if (mobj->hprev) diff2 |= MD2_HPREV; + if (mobj->standingslope) + diff2 |= MD2_SLOPE; if (diff2 != 0) diff |= MD_MORE; @@ -1221,6 +1227,8 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type) WRITEUINT32(save_p, mobj->hnext->mobjnum); if (diff2 & MD2_HPREV) WRITEUINT32(save_p, mobj->hprev->mobjnum); + if (diff2 & MD2_SLOPE) + WRITEUINT16(save_p, mobj->standingslope->id); WRITEUINT32(save_p, mobj->mobjnum); } @@ -2068,6 +2076,9 @@ static void LoadMobjThinker(actionf_p1 thinker) mobj->hnext = (mobj_t *)(size_t)READUINT32(save_p); if (diff2 & MD2_HPREV) mobj->hprev = (mobj_t *)(size_t)READUINT32(save_p); + if (diff2 & MD2_SLOPE) + mobj->standingslope = P_SlopeById(READUINT16(save_p)); + if (diff & MD_REDFLAG) { diff --git a/src/p_setup.c b/src/p_setup.c index c836d601c..3491669c7 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -850,7 +850,7 @@ void P_ScanThings(INT16 mapnum, INT16 wadnum, INT16 lumpnum) // // P_LoadThings // -static void P_LoadThings(lumpnum_t lumpnum) +static void P_PrepareThings(lumpnum_t lumpnum) { size_t i; mapthing_t *mt; @@ -888,6 +888,15 @@ static void P_LoadThings(lumpnum_t lumpnum) } Z_Free(datastart); +} + +static void P_LoadThings(void) +{ + size_t i; + mapthing_t *mt; + + // Loading the things lump itself into memory is now handled in P_PrepareThings, above + mt = mapthings; numhuntemeralds = 0; for (i = 0; i < nummapthings; i++, mt++) @@ -2123,7 +2132,8 @@ void P_LoadThingsOnly(void) P_LevelInitStuff(); - P_LoadThings(lastloadedmaplumpnum + ML_THINGS); + P_PrepareThings(lastloadedmaplumpnum + ML_THINGS); + P_LoadThings(); P_SpawnSecretItems(true); } @@ -2540,11 +2550,13 @@ boolean P_SetupLevel(boolean skipprecip) P_MapStart(); + P_PrepareThings(lastloadedmaplumpnum + ML_THINGS); + #ifdef ESLOPE P_ResetDynamicSlopes(); #endif - P_LoadThings(lastloadedmaplumpnum + ML_THINGS); + P_LoadThings(); P_SpawnSecretItems(loademblems); diff --git a/src/p_slopes.c b/src/p_slopes.c index d0b202168..baec5e1ef 100644 --- a/src/p_slopes.c +++ b/src/p_slopes.c @@ -34,13 +34,15 @@ #include "z_zone.h" #include "p_spec.h" #include "p_slopes.h" +#include "p_setup.h" #include "r_main.h" #include "p_maputl.h" #include "w_wad.h" #ifdef ESLOPE -static pslope_t *dynslopes = NULL; +static pslope_t *slopelist = NULL; +static UINT16 slopecount = 0; // Calculate line normal void P_CalculateSlopeNormal(pslope_t *slope) { @@ -49,13 +51,75 @@ void P_CalculateSlopeNormal(pslope_t *slope) { slope->normal.y = -FixedMul(FINESINE(slope->zangle>>ANGLETOFINESHIFT), slope->d.y); } +// With a vertex slope that has its vertices set, configure relevant slope info +void P_ReconfigureVertexSlope(pslope_t *slope) +{ + vector3_t vec1, vec2; + + // Set slope normal + vec1.x = (slope->vertices[1]->x - slope->vertices[0]->x) << FRACBITS; + vec1.y = (slope->vertices[1]->y - slope->vertices[0]->y) << FRACBITS; + vec1.z = (slope->vertices[1]->z - slope->vertices[0]->z) << FRACBITS; + + vec2.x = (slope->vertices[2]->x - slope->vertices[0]->x) << FRACBITS; + vec2.y = (slope->vertices[2]->y - slope->vertices[0]->y) << FRACBITS; + vec2.z = (slope->vertices[2]->z - slope->vertices[0]->z) << FRACBITS; + + // ugggggggh fixed-point maaaaaaath + slope->extent = max( + max(max(abs(vec1.x), abs(vec1.y)), abs(vec1.z)), + max(max(abs(vec2.x), abs(vec2.y)), abs(vec2.z)) + ) >> (FRACBITS+5); + vec1.x /= slope->extent; + vec1.y /= slope->extent; + vec1.z /= slope->extent; + vec2.x /= slope->extent; + vec2.y /= slope->extent; + vec2.z /= slope->extent; + + FV3_Cross(&vec1, &vec2, &slope->normal); + + slope->extent = R_PointToDist2(0, 0, R_PointToDist2(0, 0, slope->normal.x, slope->normal.y), slope->normal.z); + if (slope->normal.z < 0) + slope->extent = -slope->extent; + + slope->normal.x = FixedDiv(slope->normal.x, slope->extent); + slope->normal.y = FixedDiv(slope->normal.y, slope->extent); + slope->normal.z = FixedDiv(slope->normal.z, slope->extent); + + // Set origin + slope->o.x = slope->vertices[0]->x << FRACBITS; + slope->o.y = slope->vertices[0]->y << FRACBITS; + slope->o.z = slope->vertices[0]->z << FRACBITS; + + if (slope->normal.x == 0 && slope->normal.y == 0) { // Set some defaults for a non-sloped "slope" + slope->zangle = slope->xydirection = 0; + slope->zdelta = slope->d.x = slope->d.y = 0; + } else { + // Get direction vector + slope->extent = R_PointToDist2(0, 0, slope->normal.x, slope->normal.y); + slope->d.x = -FixedDiv(slope->normal.x, slope->extent); + slope->d.y = -FixedDiv(slope->normal.y, slope->extent); + + // Z delta + slope->zdelta = FixedDiv(slope->extent, slope->normal.z); + + // Get angles + slope->xydirection = R_PointToAngle2(0, 0, slope->d.x, slope->d.y)+ANGLE_180; + slope->zangle = -R_PointToAngle2(0, 0, FRACUNIT, slope->zdelta); + } +} + // Recalculate dynamic slopes void P_RunDynamicSlopes(void) { pslope_t *slope; - for (slope = dynslopes; slope; slope = slope->next) { + for (slope = slopelist; slope; slope = slope->next) { fixed_t zdelta; + if (slope->flags & SL_NODYNAMIC) + continue; + switch(slope->refpos) { case 1: // front floor zdelta = slope->sourceline->backsector->floorheight - slope->sourceline->frontsector->floorheight; @@ -73,6 +137,24 @@ void P_RunDynamicSlopes(void) { zdelta = slope->sourceline->frontsector->ceilingheight - slope->sourceline->backsector->ceilingheight; slope->o.z = slope->sourceline->backsector->ceilingheight; break; + case 5: // vertices + { + mapthing_t *mt; + size_t i, l; + line_t *line; + + for (i = 0; i < 3; i++) { + mt = slope->vertices[i]; + l = P_FindSpecialLineFromTag(799, mt->angle, -1); + if (l != -1) { + line = &lines[l]; + mt->z = line->frontsector->floorheight >> FRACBITS; + } + } + + P_ReconfigureVertexSlope(slope); + } + continue; // TODO default: I_Error("P_RunDynamicSlopes: slope has invalid type!"); @@ -92,7 +174,7 @@ void P_RunDynamicSlopes(void) { // Alocates and fill the contents of a slope structure. // static pslope_t *P_MakeSlope(const vector3_t *o, const vector2_t *d, - const fixed_t zdelta, boolean dynamic) + const fixed_t zdelta, UINT8 flags) { pslope_t *ret = Z_Malloc(sizeof(pslope_t), PU_LEVEL, NULL); memset(ret, 0, sizeof(*ret)); @@ -106,10 +188,14 @@ static pslope_t *P_MakeSlope(const vector3_t *o, const vector2_t *d, ret->zdelta = zdelta; - if (dynamic) { // Add to the dynamic slopes list - ret->next = dynslopes; - dynslopes = ret; - } + ret->flags = flags; + + // Add to the slope list + ret->next = slopelist; + slopelist = ret; + + slopecount++; + ret->id = slopecount; return ret; } @@ -179,6 +265,14 @@ void P_SpawnSlope_Line(int linenum) boolean frontceil = (special == 701 || special == 702 || special == 713); boolean backceil = (special == 711 || special == 712 || special == 703); + UINT8 flags = 0; // Slope flags + if (line->flags & ML_NOSONIC) + flags |= SL_NOPHYSICS; + if (line->flags & ML_NOTAILS) + flags |= SL_NODYNAMIC; + if (line->flags & ML_NOKNUX) + flags |= SL_ANCHORVERTEX; + if(!frontfloor && !backfloor && !frontceil && !backceil) { CONS_Printf("P_SpawnSlope_Line called with non-slope line special.\n"); @@ -235,7 +329,7 @@ void P_SpawnSlope_Line(int linenum) // In P_SpawnSlopeLine the origin is the centerpoint of the sourcelinedef fslope = line->frontsector->f_slope = - P_MakeSlope(&point, &direction, dz, !(line->flags & ML_NOTAILS)); + P_MakeSlope(&point, &direction, dz, flags); // Set up some shit fslope->extent = extent; @@ -291,7 +385,7 @@ void P_SpawnSlope_Line(int linenum) dz = FixedDiv(origin.z - point.z, extent); cslope = line->frontsector->c_slope = - P_MakeSlope(&point, &direction, dz, !(line->flags & ML_NOTAILS)); + P_MakeSlope(&point, &direction, dz, flags); // Set up some shit cslope->extent = extent; @@ -356,7 +450,7 @@ void P_SpawnSlope_Line(int linenum) dz = FixedDiv(origin.z - point.z, extent); fslope = line->backsector->f_slope = - P_MakeSlope(&point, &direction, dz, !(line->flags & ML_NOTAILS)); + P_MakeSlope(&point, &direction, dz, flags); // Set up some shit fslope->extent = extent; @@ -398,7 +492,7 @@ void P_SpawnSlope_Line(int linenum) dz = FixedDiv(origin.z - point.z, extent); cslope = line->backsector->c_slope = - P_MakeSlope(&point, &direction, dz, !(line->flags & ML_NOTAILS)); + P_MakeSlope(&point, &direction, dz, flags); // Set up some shit cslope->extent = extent; @@ -440,6 +534,68 @@ void P_SpawnSlope_Line(int linenum) return; } +// +// P_NewVertexSlope +// +// Creates a new slope from three vertices with the specified IDs +// +pslope_t *P_NewVertexSlope(INT16 tag1, INT16 tag2, INT16 tag3, UINT8 flags) +{ + size_t i; + mapthing_t *mt = mapthings; + + pslope_t *ret = Z_Malloc(sizeof(pslope_t), PU_LEVEL, NULL); + memset(ret, 0, sizeof(*ret)); + + // Start by setting flags + ret->flags = flags; + + // Now set up the vertex list + ret->vertices = Z_Malloc(3*sizeof(mapthing_t), PU_LEVEL, NULL); + memset(ret->vertices, 0, 3*sizeof(mapthing_t)); + + // And... look for the vertices in question. + for (i = 0; i < nummapthings; i++, mt++) { + if (mt->type != 750) // Haha, I'm hijacking the old Chaos Spawn thingtype for something! + continue; + + if (!ret->vertices[0] && mt->angle == tag1) + ret->vertices[0] = mt; + else if (!ret->vertices[1] && mt->angle == tag2) + ret->vertices[1] = mt; + else if (!ret->vertices[2] && mt->angle == tag3) + ret->vertices[2] = mt; + } + + if (!ret->vertices[0]) + CONS_Printf("PANIC 0\n"); + if (!ret->vertices[1]) + CONS_Printf("PANIC 1\n"); + if (!ret->vertices[2]) + CONS_Printf("PANIC 2\n"); + + // Now set heights for each vertex, because they haven't been set yet + for (i = 0; i < 3; i++) { + mt = ret->vertices[i]; + if (mt->extrainfo) + mt->z = mt->options; + else + mt->z = (R_PointInSubsector(mt->x << FRACBITS, mt->y << FRACBITS)->sector->floorheight >> FRACBITS) + (mt->options >> ZSHIFT); + } + + P_ReconfigureVertexSlope(ret); + ret->refpos = 5; + + // Add to the slope list + ret->next = slopelist; + slopelist = ret; + + slopecount++; + ret->id = slopecount; + + return ret; +} + // @@ -468,6 +624,18 @@ void P_CopySectorSlope(line_t *line) line->special = 0; // Linedef was use to set slopes, it finished its job, so now make it a normal linedef } +// +// P_SlopeById +// +// Looks in the slope list for a slope with a specified ID. Mostly useful for netgame sync +// +pslope_t *P_SlopeById(UINT16 id) +{ + pslope_t *ret; + for (ret = slopelist; ret && ret->id != id; ret = ret->next); + return ret; +} + #ifdef SPRINGCLEAN #include "byteptr.h" @@ -730,7 +898,8 @@ void P_ResetDynamicSlopes(void) { boolean warned = false; #endif - dynslopes = NULL; + slopelist = NULL; + slopecount = 0; // We'll handle copy slopes later, after all the tag lists have been made. // Yes, this means copied slopes won't affect things' spawning heights. Too bad for you. @@ -783,6 +952,51 @@ void P_ResetDynamicSlopes(void) { P_SpawnSlope_Line(i); break; + case 704: + case 705: + case 714: + case 715: + { + pslope_t **slopetoset; + size_t which = lines[i].special; + + UINT8 flags = SL_VERTEXSLOPE; + if (lines[i].flags & ML_NOSONIC) + flags |= SL_NOPHYSICS; + if (!(lines[i].flags & ML_NOTAILS)) + flags |= SL_NODYNAMIC; + + if (which == 704) + { + slopetoset = &lines[i].frontsector->f_slope; + which = 0; + } + else if (which == 705) + { + slopetoset = &lines[i].frontsector->c_slope; + which = 0; + } + else if (which == 714) + { + slopetoset = &lines[i].backsector->f_slope; + which = 1; + } + else // 715 + { + slopetoset = &lines[i].backsector->c_slope; + which = 1; + } + + if (lines[i].flags & ML_NOKNUX) + *slopetoset = P_NewVertexSlope(lines[i].tag, sides[lines[i].sidenum[which]].textureoffset >> FRACBITS, + sides[lines[i].sidenum[which]].rowoffset >> FRACBITS, flags); + else + *slopetoset = P_NewVertexSlope(lines[i].tag, lines[i].tag, lines[i].tag, flags); + + sides[lines[i].sidenum[which]].sector->hasslope = true; + } + break; + default: break; } diff --git a/src/p_slopes.h b/src/p_slopes.h index 52988c18f..e92198675 100644 --- a/src/p_slopes.h +++ b/src/p_slopes.h @@ -63,6 +63,8 @@ typedef enum // void P_CopySectorSlope(line_t *line); +pslope_t *P_SlopeById(UINT16 id); + // Returns the height of the sloped plane at (x, y) as a fixed_t fixed_t P_GetZAt(pslope_t *slope, fixed_t x, fixed_t y); diff --git a/src/r_defs.h b/src/r_defs.h index 9f35af7e5..f18410fe8 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -233,11 +233,19 @@ typedef struct secplane_t fixed_t a, b, c, d, ic; } secplane_t; -// Kalaron Slopes +// Slopes #ifdef ESLOPE +typedef enum { + SL_NOPHYSICS = 1, // Don't do momentum adjustment with this slope + SL_NODYNAMIC = 1<<1, // Slope will never need to move during the level, so don't fuss with recalculating it + SL_ANCHORVERTEX = 1<<2, // Slope is using a Slope Vertex Thing to anchor its position + SL_VERTEXSLOPE = 1<<3, // Slope is built from three Slope Vertex Things +} slopeflags_t; typedef struct pslope_s { + UINT16 id; // The number of the slope, mostly used for netgame syncing purposes + // --- Information used in clipping/projection --- // Origin vector for the plane vector3_t o; @@ -262,7 +270,10 @@ typedef struct pslope_s struct line_s *sourceline; // The line that generated the slope fixed_t extent; // Distance value used for recalculating zdelta - UINT8 refpos; // 1=front floor 2=front ceiling 3=back floor 4=back ceiling (used for dynamic sloping) 0=disabled + UINT8 refpos; // 1=front floor 2=front ceiling 3=back floor 4=back ceiling (used for dynamic sloping) + + UINT8 flags; // Slope options + mapthing_t **vertices; // List should be three long for slopes made by vertex things, or one long for slopes using one vertex thing to anchor struct pslope_s *next; // Make a linked list of dynamic slopes, for easy reference later } pslope_t; diff --git a/src/r_draw.h b/src/r_draw.h index e1818545b..63fecc046 100644 --- a/src/r_draw.h +++ b/src/r_draw.h @@ -154,6 +154,7 @@ void R_DrawSpan_8(void); #ifdef ESLOPE void R_DrawTiltedSpan_8(void); void R_DrawTiltedTranslucentSpan_8(void); +void R_DrawTiltedSplat_8(void); #endif void R_DrawSplat_8(void); void R_DrawTranslucentSplat_8(void); diff --git a/src/r_draw8.c b/src/r_draw8.c index 279690492..f78f1494b 100644 --- a/src/r_draw8.c +++ b/src/r_draw8.c @@ -593,8 +593,8 @@ void R_DrawTiltedSpan_8(void) do { double z = 1.f/iz; - u = (UINT32)(uz*z) + viewx; - v = (UINT32)(vz*z) + viewy; + u = (INT64)(uz*z) + viewx; + v = (INT64)(vz*z) + viewy; colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); @@ -630,8 +630,8 @@ void R_DrawTiltedSpan_8(void) double endv = vz*endz; UINT32 stepu = (INT64)((endu - startu) * INVSPAN); UINT32 stepv = (INT64)((endv - startv) * INVSPAN); - u = (UINT32)(startu) + viewx; - v = (UINT32)(startv) + viewy; + u = (INT64)(startu) + viewx; + v = (INT64)(startv) + viewy; for (i = SPANSIZE-1; i >= 0; i--) { @@ -649,8 +649,8 @@ void R_DrawTiltedSpan_8(void) { if (width == 1) { - u = (UINT32)(startu); - v = (UINT32)(startv); + u = (INT64)(startu); + v = (INT64)(startv); colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); *dest = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]]; } @@ -667,8 +667,8 @@ void R_DrawTiltedSpan_8(void) left = 1.f/left; UINT32 stepu = (INT64)((endu - startu) * left); UINT32 stepv = (INT64)((endv - startv) * left); - u = (UINT32)(startu) + viewx; - v = (UINT32)(startv) + viewy; + u = (INT64)(startu) + viewx; + v = (INT64)(startv) + viewy; for (; width != 0; width--) { @@ -726,8 +726,8 @@ void R_DrawTiltedTranslucentSpan_8(void) do { double z = 1.f/iz; - u = (UINT32)(uz*z) + viewx; - v = (UINT32)(vz*z) + viewy; + u = (INT64)(uz*z) + viewx; + v = (INT64)(vz*z) + viewy; colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); @@ -763,8 +763,8 @@ void R_DrawTiltedTranslucentSpan_8(void) double endv = vz*endz; UINT32 stepu = (INT64)((endu - startu) * INVSPAN); UINT32 stepv = (INT64)((endv - startv) * INVSPAN); - u = (UINT32)(startu) + viewx; - v = (UINT32)(startv) + viewy; + u = (INT64)(startu) + viewx; + v = (INT64)(startv) + viewy; for (i = SPANSIZE-1; i >= 0; i--) { @@ -782,8 +782,8 @@ void R_DrawTiltedTranslucentSpan_8(void) { if (width == 1) { - u = (UINT32)(startu); - v = (UINT32)(startv); + u = (INT64)(startu); + v = (INT64)(startv); colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); *dest = colormap[*(ds_transmap + (source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)] << 8) + dest[0])]; } @@ -800,8 +800,8 @@ void R_DrawTiltedTranslucentSpan_8(void) left = 1.f/left; UINT32 stepu = (INT64)((endu - startu) * left); UINT32 stepv = (INT64)((endv - startv) * left); - u = (UINT32)(startu) + viewx; - v = (UINT32)(startv) + viewy; + u = (INT64)(startu) + viewx; + v = (INT64)(startv) + viewy; for (; width != 0; width--) { @@ -815,6 +815,145 @@ void R_DrawTiltedTranslucentSpan_8(void) } #endif } + +void R_DrawTiltedSplat_8(void) +{ + // x1, x2 = ds_x1, ds_x2 + int width = ds_x2 - ds_x1; + double iz, uz, vz; + UINT32 u, v; + int i; + + UINT8 *source; + UINT8 *colormap; + UINT8 *dest; + + UINT8 val; + + iz = ds_sz.z + ds_sz.y*(centery-ds_y) + ds_sz.x*(ds_x1-centerx); + + // Lighting is simple. It's just linear interpolation from start to end + { + float planelightfloat = BASEVIDWIDTH*BASEVIDWIDTH/vid.width / (zeroheight - FIXED_TO_FLOAT(viewz)) / 21.0f; + float lightstart, lightend; + + lightend = (iz + ds_sz.x*width) * planelightfloat; + lightstart = iz * planelightfloat; + + R_CalcTiltedLighting(FLOAT_TO_FIXED(lightstart), FLOAT_TO_FIXED(lightend)); + //CONS_Printf("tilted lighting %f to %f (foc %f)\n", lightstart, lightend, focallengthf); + } + + uz = ds_su.z + ds_su.y*(centery-ds_y) + ds_su.x*(ds_x1-centerx); + vz = ds_sv.z + ds_sv.y*(centery-ds_y) + ds_sv.x*(ds_x1-centerx); + + dest = ylookup[ds_y] + columnofs[ds_x1]; + source = ds_source; + //colormap = ds_colormap; + +#if 0 // The "perfect" reference version of this routine. Pretty slow. + // Use it only to see how things are supposed to look. + i = 0; + do + { + double z = 1.f/iz; + u = (INT64)(uz*z) + viewx; + v = (INT64)(vz*z) + viewy; + + colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); + + val = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]]; + if (val != TRANSPARENTPIXEL) + *dest = val; + dest++; + iz += ds_sz.x; + uz += ds_su.x; + vz += ds_sv.x; + } while (--width >= 0); +#else +#define SPANSIZE 16 +#define INVSPAN 0.0625f + + double startz = 1.f/iz; + double startu = uz*startz; + double startv = vz*startz; + double izstep, uzstep, vzstep; + + izstep = ds_sz.x * SPANSIZE; + uzstep = ds_su.x * SPANSIZE; + vzstep = ds_sv.x * SPANSIZE; + //x1 = 0; + width++; + + while (width >= SPANSIZE) + { + iz += izstep; + uz += uzstep; + vz += vzstep; + + double endz = 1.f/iz; + double endu = uz*endz; + double endv = vz*endz; + UINT32 stepu = (INT64)((endu - startu) * INVSPAN); + UINT32 stepv = (INT64)((endv - startv) * INVSPAN); + u = (INT64)(startu) + viewx; + v = (INT64)(startv) + viewy; + + for (i = SPANSIZE-1; i >= 0; i--) + { + colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); + val = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]]; + if (val != TRANSPARENTPIXEL) + *dest = val; + dest++; + u += stepu; + v += stepv; + } + startu = endu; + startv = endv; + width -= SPANSIZE; + } + if (width > 0) + { + if (width == 1) + { + u = (INT64)(startu); + v = (INT64)(startv); + colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); + val = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]]; + if (val != TRANSPARENTPIXEL) + *dest = val; + } + else + { + double left = width; + iz += ds_sz.x * left; + uz += ds_su.x * left; + vz += ds_sv.x * left; + + double endz = 1.f/iz; + double endu = uz*endz; + double endv = vz*endz; + left = 1.f/left; + UINT32 stepu = (INT64)((endu - startu) * left); + UINT32 stepv = (INT64)((endv - startv) * left); + u = (INT64)(startu) + viewx; + v = (INT64)(startv) + viewy; + + for (; width != 0; width--) + { + colormap = planezlight[tiltlighting[ds_x1++]] + (ds_colormap - colormaps); + val = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]]; + if (val != TRANSPARENTPIXEL) + *dest = val; + dest++; + u += stepu; + v += stepv; + } + } + } +#endif +} #endif // ESLOPE /** \brief The R_DrawSplat_8 function diff --git a/src/r_plane.c b/src/r_plane.c index 6aae1e250..406a38d7b 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -836,7 +836,11 @@ void R_DrawSinglePlane(visplane_t *pl) else light = (pl->lightlevel >> LIGHTSEGSHIFT); #ifndef NOWATER - if (pl->ffloor->flags & FF_RIPPLE) + if (pl->ffloor->flags & FF_RIPPLE +#ifdef ESLOPE + && !pl->slope +#endif + ) { INT32 top, bottom; @@ -1024,6 +1028,8 @@ void R_DrawSinglePlane(visplane_t *pl) if (spanfunc == R_DrawTranslucentSpan_8) spanfunc = R_DrawTiltedTranslucentSpan_8; + else if (spanfunc == splatfunc) + spanfunc = R_DrawTiltedSplat_8; else spanfunc = R_DrawTiltedSpan_8;