From 779faaa93f480035e46ee4082c12a6ac3b44c780 Mon Sep 17 00:00:00 2001 From: RedEnchilada Date: Mon, 20 Apr 2015 02:10:14 -0500 Subject: [PATCH] SLOPES IN SOFTWARE MOD EHOLY SHIT --- src/r_bsp.c | 40 +++++++++++++++++++---- src/r_draw.c | 6 ++++ src/r_draw.h | 9 ++++++ src/r_draw8.c | 43 ++++++++++++++++++++++++ src/r_main.c | 2 ++ src/r_plane.c | 90 +++++++++++++++++++++++++++++++++++++++++++++++++-- src/r_plane.h | 9 +++++- src/r_segs.c | 14 ++++++-- 8 files changed, 202 insertions(+), 11 deletions(-) diff --git a/src/r_bsp.c b/src/r_bsp.c index d4f769433..01d2be671 100644 --- a/src/r_bsp.c +++ b/src/r_bsp.c @@ -487,6 +487,10 @@ static void R_AddLine(seg_t *line) #endif backsector->ceilingpic == frontsector->ceilingpic && backsector->floorpic == frontsector->floorpic +#ifdef ESLOPE + && backsector->f_slope == frontsector->f_slope + && backsector->c_slope == frontsector->c_slope +#endif && backsector->lightlevel == frontsector->lightlevel && !curline->sidedef->midtexture // Check offsets too! @@ -862,7 +866,11 @@ static void R_Subsector(size_t num) && sectors[frontsector->heightsec].ceilingpic == skyflatnum))) { floorplane = R_FindPlane(frontsector->floorheight, frontsector->floorpic, floorlightlevel, - frontsector->floor_xoffs, frontsector->floor_yoffs, frontsector->floorpic_angle, floorcolormap, NULL); + frontsector->floor_xoffs, frontsector->floor_yoffs, frontsector->floorpic_angle, floorcolormap, NULL +#ifdef ESLOPE + , frontsector->f_slope +#endif + ); } else floorplane = NULL; @@ -877,7 +885,11 @@ static void R_Subsector(size_t num) { ceilingplane = R_FindPlane(frontsector->ceilingheight, frontsector->ceilingpic, ceilinglightlevel, frontsector->ceiling_xoffs, frontsector->ceiling_yoffs, frontsector->ceilingpic_angle, - ceilingcolormap, NULL); + ceilingcolormap, NULL +#ifdef ESLOPE + , frontsector->c_slope +#endif + ); } else ceilingplane = NULL; @@ -914,7 +926,11 @@ static void R_Subsector(size_t num) viewz < *rover->bottomheight); ffloor[numffloors].plane = R_FindPlane(*rover->bottomheight, *rover->bottompic, *frontsector->lightlist[light].lightlevel, *rover->bottomxoffs, - *rover->bottomyoffs, *rover->bottomangle, frontsector->lightlist[light].extra_colormap, rover); + *rover->bottomyoffs, *rover->bottomangle, frontsector->lightlist[light].extra_colormap, rover +#ifdef ESLOPE + , NULL // will ffloors be slopable eventually? +#endif + ); ffloor[numffloors].height = *rover->bottomheight; ffloor[numffloors].ffloor = rover; @@ -932,7 +948,11 @@ static void R_Subsector(size_t num) light = R_GetPlaneLight(frontsector, *rover->topheight, viewz < *rover->topheight); ffloor[numffloors].plane = R_FindPlane(*rover->topheight, *rover->toppic, *frontsector->lightlist[light].lightlevel, *rover->topxoffs, *rover->topyoffs, *rover->topangle, - frontsector->lightlist[light].extra_colormap, rover); + frontsector->lightlist[light].extra_colormap, rover +#ifdef ESLOPE + , NULL // will ffloors be slopable eventually? +#endif + ); ffloor[numffloors].height = *rover->topheight; ffloor[numffloors].ffloor = rover; numffloors++; @@ -985,7 +1005,11 @@ static void R_Subsector(size_t num) polysec->lightlevel, xoff, yoff, polysec->floorpic_angle-po->angle, NULL, - NULL); + NULL +#ifdef ESLOPE + , NULL // will ffloors be slopable eventually? +#endif + ); //ffloor[numffloors].plane->polyobj = po; ffloor[numffloors].height = polysec->floorheight; @@ -1022,7 +1046,11 @@ static void R_Subsector(size_t num) light = 0; ffloor[numffloors].plane = R_FindPlane(polysec->ceilingheight, polysec->ceilingpic, polysec->lightlevel, xoff, yoff, polysec->ceilingpic_angle-po->angle, - NULL, NULL); + NULL, NULL +#ifdef ESLOPE + , NULL // will ffloors be slopable eventually? +#endif + ); //ffloor[numffloors].plane->polyobj = po; ffloor[numffloors].polyobj = po; diff --git a/src/r_draw.c b/src/r_draw.c index cd219c15f..f4886d262 100644 --- a/src/r_draw.c +++ b/src/r_draw.c @@ -103,6 +103,12 @@ fixed_t ds_xfrac, ds_yfrac, ds_xstep, ds_ystep; UINT8 *ds_source; // start of a 64*64 tile image UINT8 *ds_transmap; // one of the translucency tables +#ifdef ESLOPE +pslope_t *ds_slope; // Current slope being used +v3float_t ds_su, ds_sv, ds_sz; // Vectors for... stuff? +float focallengthf; +#endif + /** \brief Variable flat sizes */ diff --git a/src/r_draw.h b/src/r_draw.h index 061a271b1..179887536 100644 --- a/src/r_draw.h +++ b/src/r_draw.h @@ -60,6 +60,12 @@ extern fixed_t ds_xfrac, ds_yfrac, ds_xstep, ds_ystep; extern UINT8 *ds_source; // start of a 64*64 tile image extern UINT8 *ds_transmap; +#ifdef ESLOPE +pslope_t *ds_slope; // Current slope being used +v3float_t ds_su, ds_sv, ds_sz; // Vectors for... stuff? +float focallengthf; +#endif + // Variable flat sizes extern UINT32 nflatxshift; extern UINT32 nflatyshift; @@ -141,6 +147,9 @@ void ASMCALL R_DrawSpan_8_MMX(void); void R_DrawTranslatedColumn_8(void); void R_DrawTranslatedTranslucentColumn_8(void); void R_DrawSpan_8(void); +#ifdef ESLOPE +void R_DrawTiltedSpan_8(void); +#endif void R_DrawSplat_8(void); void R_DrawTranslucentSplat_8(void); void R_DrawTranslucentSpan_8(void); diff --git a/src/r_draw8.c b/src/r_draw8.c index e0264ba92..6a240c349 100644 --- a/src/r_draw8.c +++ b/src/r_draw8.c @@ -526,6 +526,49 @@ void R_DrawSpan_8 (void) } } +#ifdef ESLOPE +/** \brief The R_DrawTiltedSpan_8 function + Draw slopes! Holy sheit! +*/ +void R_DrawTiltedSpan_8(void) +{ + // x1, x2 = ds_x1, ds_x2 + int width = ds_x2 - ds_x1; + double iz, uz, vz; + BYTE *fb; + DWORD u, v; + int i; + + UINT8 *source; + UINT8 *colormap; + UINT8 *dest; + + iz = ds_sz.z + ds_sz.y*(centery-ds_y) + ds_sz.x*(ds_x1-centerx); + + 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; + + // 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; + *dest = colormap[source[((v >> nflatyshift) & nflatmask) | (u >> nflatxshift)]]; + dest++; + iz += ds_sz.x; + uz += ds_su.x; + vz += ds_sv.x; + } while (--width >= 0); +} +#endif // ESLOPE + /** \brief The R_DrawSplat_8 function Just like R_DrawSpan_8, but skips transparent pixels. */ diff --git a/src/r_main.c b/src/r_main.c index 1edcb815b..127801598 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -527,6 +527,8 @@ static void R_InitTextureMapping(void) focallength = FixedDiv(centerxfrac, FINETANGENT(FINEANGLES/4+/*cv_fov.value*/ FIELDOFVIEW/2)); + focallengthf = FIXED_TO_FLOAT(focallength); + for (i = 0; i < FINEANGLES/2; i++) { if (FINETANGENT(i) > FRACUNIT*2) diff --git a/src/r_plane.c b/src/r_plane.c index dcff25c13..44b65ad10 100644 --- a/src/r_plane.c +++ b/src/r_plane.c @@ -423,7 +423,11 @@ static visplane_t *new_visplane(unsigned hash) // visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel, fixed_t xoff, fixed_t yoff, angle_t plangle, extracolormap_t *planecolormap, - ffloor_t *pfloor) + ffloor_t *pfloor +#ifdef ESLOPE + , pslope_t *slope +#endif + ) { visplane_t *check; unsigned hash; @@ -462,7 +466,11 @@ visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel, && xoff == check->xoffs && yoff == check->yoffs && planecolormap == check->extra_colormap && !pfloor && !check->ffloor && check->viewz == viewz - && check->viewangle == viewangle) + && check->viewangle == viewangle +#ifdef ESLOPE + && check->slope == slope +#endif + ) { return check; } @@ -485,6 +493,9 @@ visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel, #ifdef POLYOBJECTS_PLANES check->polyobj = NULL; #endif +#ifdef ESLOPE + check->slope = slope; +#endif memset(check->top, 0xff, sizeof (check->top)); memset(check->bottom, 0x00, sizeof (check->bottom)); @@ -551,6 +562,9 @@ visplane_t *R_CheckPlane(visplane_t *pl, INT32 start, INT32 stop) new_pl->plangle = pl->plangle; #ifdef POLYOBJECTS_PLANES new_pl->polyobj = pl->polyobj; +#endif +#ifdef ESLOPE + new_pl->slope = pl->slope; #endif pl = new_pl; pl->minx = start; @@ -905,6 +919,78 @@ void R_DrawSinglePlane(visplane_t *pl) break; } +#ifdef ESLOPE + if (pl->slope) { + // 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 + static const float ifloatpow2[16] = + { + // ifloatpow2[i] = 1 / (1 << i) + 64.f, 32.f, 16.f, 8.f, 4.f, 2.f, 1.f, 0.5f, + 0.25f, 0.125f, 0.0625f, 0.03125f, 0.015625f, 0.0078125f, + 0.00390625f, 0.001953125f + /*, 0.0009765625f, 0.00048828125f, 0.000244140625f, + 1.220703125e-4f, 6.103515625e-5, 3.0517578125e-5*/ + }; + double lxscale, lyscale; + double xscale, yscale; + v3float_t p, m, n; + angle_t ang; + double zeroheight; + + double vx = FIXED_TO_FLOAT(viewx); + double vy = FIXED_TO_FLOAT(viewy); + double vz = FIXED_TO_FLOAT(viewz); + + zeroheight = FIXED_TO_FLOAT(P_GetZAt(pl->slope, viewx, viewy)); + + // 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 = (ANGLE_270 - viewangle)>>ANGLETOFINESHIFT; + p.x = vx * FIXED_TO_FLOAT(FINECOSINE(ang)) - vy * FIXED_TO_FLOAT(FINESINE(ang)); + p.z = vx * FIXED_TO_FLOAT(FINESINE(ang)) + vy * FIXED_TO_FLOAT(FINECOSINE(ang)); + p.y = FIXED_TO_FLOAT(P_GetZAt(pl->slope, 0, 0)) - vz; + + // m is the v direction vector in view space + ang = (ANGLE_180 - viewangle - pl->plangle) >> ANGLETOFINESHIFT; + m.x = FIXED_TO_FLOAT(FINECOSINE(ang)); + m.z = FIXED_TO_FLOAT(FINESINE(ang)); + + // n is the u direction vector in view space + ang += ANGLE_90>>ANGLETOFINESHIFT; + ang &= FINEMASK; + n.x = -FIXED_TO_FLOAT(FINECOSINE(ang)); + n.z = -FIXED_TO_FLOAT(FINESINE(ang)); + + ang = pl->plangle>>ANGLETOFINESHIFT; + m.y = FIXED_TO_FLOAT(P_GetZAt(pl->slope, viewx + FINESINE(ang), viewy + FINECOSINE(ang))) - zeroheight; + ang += ANGLE_90>>ANGLETOFINESHIFT; + ang &= FINEMASK; + n.y = FIXED_TO_FLOAT(P_GetZAt(pl->slope, viewx + FINESINE(ang), viewy + FINECOSINE(ang))) - zeroheight; + + M_CrossProduct3f(&ds_su, &p, &m); + M_CrossProduct3f(&ds_sv, &p, &n); + M_CrossProduct3f(&ds_sz, &m, &n); + + ds_su.z *= focallengthf; + ds_sv.z *= focallengthf; + ds_sz.z *= focallengthf; + + // Premultiply the texture vectors with the scale factors +#define SFMULT 65536.f*(1<xoffs; yoffs = pl->yoffs; planeheight = abs(pl->height - pl->viewz); diff --git a/src/r_plane.h b/src/r_plane.h index f3a7f573f..b2346636b 100644 --- a/src/r_plane.h +++ b/src/r_plane.h @@ -61,6 +61,9 @@ typedef struct visplane_s #ifdef POLYOBJECTS_PLANES polyobj_t *polyobj; #endif +#ifdef ESLOPE + pslope_t *slope; +#endif } visplane_t; extern visplane_t *floorplane; @@ -91,7 +94,11 @@ void R_MapPlane(INT32 y, INT32 x1, INT32 x2); void R_MakeSpans(INT32 x, INT32 t1, INT32 b1, INT32 t2, INT32 b2); void R_DrawPlanes(void); visplane_t *R_FindPlane(fixed_t height, INT32 picnum, INT32 lightlevel, fixed_t xoff, fixed_t yoff, angle_t plangle, - extracolormap_t *planecolormap, ffloor_t *ffloor); + extracolormap_t *planecolormap, ffloor_t *ffloor +#ifdef ESLOPE + , pslope_t *slope +#endif + ); 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); diff --git a/src/r_segs.c b/src/r_segs.c index d582f13fe..2cb04b25e 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -1757,6 +1757,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) if (worldlow != worldbottom #ifdef ESLOPE || worldlowslope != worldbottomslope + || backsector->f_slope != frontsector->f_slope #endif || backsector->floorpic != frontsector->floorpic || backsector->lightlevel != frontsector->lightlevel @@ -1782,6 +1783,7 @@ void R_StoreWallRange(INT32 start, INT32 stop) if (worldhigh != worldtop #ifdef ESLOPE || worldhighslope != worldtopslope + || backsector->c_slope != frontsector->c_slope #endif || backsector->ceilingpic != frontsector->ceilingpic || backsector->lightlevel != frontsector->lightlevel @@ -2092,13 +2094,21 @@ void R_StoreWallRange(INT32 start, INT32 stop) // and doesn't need to be marked. if (frontsector->heightsec == -1) { - if (frontsector->floorheight >= viewz) + if (( +#ifdef ESLOPE + frontsector->f_slope ? P_GetZAt(frontsector->f_slope, viewx, viewy) : +#endif + frontsector->floorheight) >= viewz) { // above view plane markfloor = false; } - if (frontsector->ceilingheight <= viewz && + if (( +#ifdef ESLOPE + frontsector->c_slope ? P_GetZAt(frontsector->c_slope, viewx, viewy) : +#endif + frontsector->ceilingheight) <= viewz && frontsector->ceilingpic != skyflatnum) { // below view plane