From 413d68f1f85b0eb6e7ae4cf9d668a80a5977d8d8 Mon Sep 17 00:00:00 2001 From: terminx Date: Thu, 18 Apr 2019 17:24:30 +0000 Subject: [PATCH] Replace yax_getclosestpointonwall() with getclosestpointonwall_internal() and use it in both yax_walldist() and getwalldist() This commit also adds a getsectordist() but we aren't using it anywhere yet. git-svn-id: https://svn.eduke32.com/eduke32@7591 1a8010ca-5511-0410-912e-c29ae57300e0 --- source/build/include/build.h | 4 +- source/build/src/engine.cpp | 91 +++++++++++++++++++++++------------- 2 files changed, 60 insertions(+), 35 deletions(-) diff --git a/source/build/include/build.h b/source/build/include/build.h index 25bfcc81c..66be2f341 100644 --- a/source/build/include/build.h +++ b/source/build/include/build.h @@ -208,7 +208,6 @@ void yax_setbunches(int16_t i, int16_t cb, int16_t fb); int16_t yax_vnextsec(int16_t line, int16_t cf); void yax_update(int32_t resetstat); int32_t yax_getneighborsect(int32_t x, int32_t y, int32_t sectnum, int32_t cf); -void yax_getclosestpointonwall(int32_t dawall, int32_t *closestx, int32_t *closesty); static FORCE_INLINE CONSTEXPR int32_t yax_waltosecmask(int32_t const walclipmask) { @@ -1170,7 +1169,8 @@ int32_t try_facespr_intersect(uspritetype const * const spr, const vec3_t *refpo vec3_t *intp, int32_t strictly_smaller_than_p); bool sectoradjacent(int sect1, int sect2); -int32_t getwalldist(vec2_t const &p, int const w); +int32_t getwalldist(vec2_t const &p, int const wallnum); +int32_t getsectordist(vec2_t const &p, int const sectnum); extern const int16_t *chsecptr_onextwall; int32_t checksectorpointer(int16_t i, int16_t sectnum); diff --git a/source/build/src/engine.cpp b/source/build/src/engine.cpp index a15c4124c..7d0237fa6 100644 --- a/source/build/src/engine.cpp +++ b/source/build/src/engine.cpp @@ -189,6 +189,33 @@ static void draw_rainbow_background(void); int16_t editstatus = 0; static fix16_t global100horiz; // (-100..300)-scale horiz (the one passed to drawrooms) +// adapted from build.c +static void getclosestpointonwall_internal(vec2_t const &p, int32_t const dawall, vec2_t *const closest) +{ + vec2_t const w = *(vec2_t *)&wall[dawall]; + vec2_t const w2 = *(vec2_t *)&wall[wall[dawall].point2]; + vec2_t const d = { w2.x - w.x, w2.y - w.y }; + + int64_t i = d.x * ((int64_t)p.x - w.x) + d.y * ((int64_t)p.y - w.y); + + if (i <= 0) + { + *closest = w; + return; + } + + int64_t const j = (int64_t)d.x * d.x + (int64_t)d.y * d.y; + + if (i >= j) + { + *closest = w2; + return; + } + + i = tabledivide64((i << 15), j) << 15; + + *closest = { (int32_t)(w.x + ((d.x * i) >> 30)), (int32_t)(w.y + ((d.y * i) >> 30)) }; +} ////////// YAX ////////// @@ -607,35 +634,11 @@ static int32_t ymostallocsize = 0; // numyaxbunches*xdimen (no sizeof(int16_t) static int16_t *yumost=NULL, *ydmost=NULL; // used as if [numyaxbunches][xdimen] uint8_t haveymost[YAX_MAXBUNCHES>>3]; -// adapted from build.c -void yax_getclosestpointonwall(int32_t dawall, int32_t *closestx, int32_t *closesty) -{ - int64_t i, j, wx,wy, wx2,wy2, dx, dy; - - wx = wall[dawall].x; - wy = wall[dawall].y; - wx2 = wall[wall[dawall].point2].x; - wy2 = wall[wall[dawall].point2].y; - - dx = wx2 - wx; - dy = wy2 - wy; - i = dx*(globalposx-wx) + dy*(globalposy-wy); - if (i <= 0) { *closestx = wx; *closesty = wy; return; } - j = dx*dx + dy*dy; - if (i >= j) { *closestx = wx2; *closesty = wy2; return; } - i=((i<<15)/j)<<15; - *closestx = wx + ((dx*i)>>30); - *closesty = wy + ((dy*i)>>30); -} - static inline int32_t yax_walldist(int32_t w) { - int32_t closestx, closesty; - - yax_getclosestpointonwall(w, &closestx, &closesty); - return klabs(closestx-globalposx) + klabs(closesty-globalposy); - -// return klabs(wall[w].x-globalposx) + klabs(wall[w].y-globalposy); + vec2_t closest; + getclosestpointonwall_internal({ globalposx, globalposy }, w, &closest); + return klabs(closest.x-globalposx) + klabs(closest.y-globalposy); } // calculate distances to bunches and best start-drawing sectors @@ -10974,6 +10977,34 @@ static inline bool inside_z_p(int32_t const x, int32_t const y, int32_t const z, return (z >= cz && z <= fz && inside_p(x, y, sectnum)); } +int32_t getwalldist(vec2_t const &p, int const wallnum) +{ + vec2_t closest; + getclosestpointonwall_internal(p, wallnum, &closest); + return klabs(closest.x - p.x) + klabs(closest.y - p.y); +} + +int32_t getsectordist(vec2_t const &p, int const sectnum) +{ + if (inside_p(p.x, p.y, sectnum)) + return 0; + + int32_t distance = INT32_MAX; + + auto const sec = (usectortype *)§or[sectnum]; + int const startwall = sec->wallptr; + int const endwall = sec->wallptr + sec->wallnum; + auto uwal = (uwalltype *)&wall[startwall]; + + for (int j = startwall; j < endwall; j++, uwal++) + { + int32_t const walldist = getwalldist(p, j); + distance = min(walldist, distance); + } + + return distance; +} + bool sectoradjacent(int sect1, int sect2) { if (sector[sect1].wallnum > sector[sect2].wallnum) @@ -10986,12 +11017,6 @@ bool sectoradjacent(int sect1, int sect2) return 0; } -int32_t getwalldist(vec2_t const &p, int const w) -{ - int32_t closestx, closesty; - yax_getclosestpointonwall(w, &closestx, &closesty); - return klabs(closestx - p.x) + klabs(closesty - p.y); -} // // updatesector[z]