From 649455c2d0890770e02922776368749c70e18063 Mon Sep 17 00:00:00 2001 From: Jaime Passos Date: Thu, 26 Dec 2019 01:58:38 -0300 Subject: [PATCH] R_CalculateSegDistance stuff... --- src/p_setup.c | 5 +--- src/r_defs.h | 3 +- src/r_segs.c | 77 +++++++++++++++++++++++++++++++++++++++++++++------ 3 files changed, 72 insertions(+), 13 deletions(-) diff --git a/src/p_setup.c b/src/p_setup.c index bf3493d8c..06344a0e3 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -416,9 +416,7 @@ fixed_t P_SegLength(seg_t *seg) return FixedHypot(dx, dy)<<1; } -#ifdef HWRENDER /** Computes the length of a seg as a float. - * This is needed for OpenGL. * * \param seg Seg to compute length for. * \return Length as a float. @@ -433,7 +431,6 @@ static inline float P_SegLengthFloat(seg_t *seg) return (float)hypot(dx, dy); } -#endif /** Loads the SEGS resource from a level. * @@ -460,10 +457,10 @@ static void P_LoadRawSegs(UINT8 *data, size_t i) li->v2 = &vertexes[SHORT(ml->v2)]; li->length = P_SegLength(li); + li->flength = P_SegLengthFloat(li); #ifdef HWRENDER if (rendermode == render_opengl) { - li->flength = P_SegLengthFloat(li); //Hurdler: 04/12/2000: for now, only used in hardware mode li->lightmaps = NULL; // list of static lightmap for this seg } diff --git a/src/r_defs.h b/src/r_defs.h index 3cc780545..bc0343730 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -582,11 +582,12 @@ typedef struct seg_s sector_t *backsector; fixed_t length; // precalculated seg length + float flength; // ditto but float + #ifdef HWRENDER // new pointers so that AdjustSegs doesn't mess with v1/v2 void *pv1; // polyvertex_t void *pv2; // polyvertex_t - float flength; // length of the seg, used by hardware renderer lightmap_t *lightmaps; // for static lightmap #endif diff --git a/src/r_segs.c b/src/r_segs.c index bc2996011..241402d44 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -50,6 +50,9 @@ angle_t rw_normalangle; angle_t rw_angle1; fixed_t rw_distance; +// for R_CalculateSegDistance +#define SOFTWARE_USE_FLOATS + // // regular wall // @@ -1706,22 +1709,73 @@ static void R_RenderSegLoop (void) // // R_CalculateSegDistance // Calculate the distance from a seg. -// Uses precalculated seg->length. +// Uses precalculated seg length. // -static INT64 R_CalculateSegDistance(seg_t* seg, INT64 x2, INT64 y2) +static void R_CalculateSegDistance(seg_t *seg, INT64 x2, INT64 y2, boolean longboi) { +#ifdef SOFTWARE_USE_FLOATS + float v1x = FIXED_TO_FLOAT(seg->v1->x); + float v1y = FIXED_TO_FLOAT(seg->v1->y); + float v2x = FIXED_TO_FLOAT(seg->v2->x); + float v2y = FIXED_TO_FLOAT(seg->v2->y); + float dx, dy, vdx, vdy; + float distance = 0.0f; + + // The seg is vertical. if (!seg->linedef->dy) - return llabs(y2 - seg->v1->y); + distance = fabsf(y2 - v1y); + // The seg is horizontal. else if (!seg->linedef->dx) - return llabs(x2 - seg->v1->x); + distance = fabsf(x2 - v1x); + // Uses precalculated seg->flength + else if (longboi) + { + dx = v2x-v1x; + dy = v2y-v1y; + vdx = x2-v1x; + vdy = y2-v1y; + distance = ((dy*vdx)-(dx*vdy))/(seg->flength); + } + // Linguica's fix converted to floating-point math + else + { + fixed_t x, y; + float a, c, ac; + + v1x -= FIXED_TO_FLOAT(viewx); + v1y -= FIXED_TO_FLOAT(viewy); + v2x -= FIXED_TO_FLOAT(viewx); + v2y -= FIXED_TO_FLOAT(viewy); + dx = v2x - v1x; + dy = v2y - v1y; + + a = (v1x*v2y) - (v1y*v2x); + c = (dx*dx) + (dy*dy); + ac = (a/c); + + x = FLOAT_TO_FIXED(ac*(-dy)); + y = FLOAT_TO_FIXED(ac*dx); + + rw_distance = R_PointToDist(viewx + x, viewy + y); + return; + } + + rw_distance = FLOAT_TO_FIXED(distance); +#else + (void)longboi; + if (!seg->linedef->dy) + rw_distance = (fixed_t)(llabs(y2 - seg->v1->y)); + else if (!seg->linedef->dx) + rw_distance = (fixed_t)(llabs(x2 - seg->v1->x)); else { INT64 dx = (seg->v2->x)-(seg->v1->x); INT64 dy = (seg->v2->y)-(seg->v1->y); INT64 vdx = x2-(seg->v1->x); INT64 vdy = y2-(seg->v1->y); - return ((dy*vdx)-(dx*vdy))/(seg->length); + rw_distance = (fixed_t)(((dy*vdx)-(dx*vdy))/(seg->length)); } +#endif } // @@ -3187,12 +3241,19 @@ void R_StoreWallRange(INT32 start, INT32 stop) sineval = FINESINE(distangle>>ANGLETOFINESHIFT); hyp = R_PointToDist(curline->v1->x, curline->v1->y); - rw_distance = FixedMul(hyp, sineval); longboi = (hyp >= INT32_MAX); + // The seg is vertical. + if (curline->v1->y == curline->v2->y) + rw_distance = (fixed_t)(llabs(viewy - curline->v1->y)); + // The seg is horizontal. + else if (curline->v1->x == curline->v2->x) + rw_distance = (fixed_t)(llabs(viewx - curline->v1->x)); // big room fix - if (longboi) - rw_distance = (fixed_t)R_CalculateSegDistance(curline,viewx,viewy); + else if ((curline->length >= 1024<x1 = rw_x = start; ds_p->x2 = stop;