From 32450bdd687bb92bfa6079bd8a61374e026b2591 Mon Sep 17 00:00:00 2001
From: terminx <terminx@1a8010ca-5511-0410-912e-c29ae57300e0>
Date: Tue, 21 Jun 2016 00:33:30 +0000
Subject: [PATCH] Relocate maphack related code into mhk.c.

This commit also relocates clipping related code into clip.c and makes a few other minor changes, because I fucked up and merged the commits together. God damn it.

git-svn-id: https://svn.eduke32.com/eduke32@5792 1a8010ca-5511-0410-912e-c29ae57300e0
---
 polymer/eduke32/Makefile                |    4 +-
 polymer/eduke32/Makefile.msvc           |    4 +-
 polymer/eduke32/build/Makefile.deps     |    3 +
 polymer/eduke32/build/include/build.h   |   19 +-
 polymer/eduke32/build/include/clip.h    |   88 +
 polymer/eduke32/build/src/2d.c          |    2 -
 polymer/eduke32/build/src/clip.c        | 1420 +++++++++++++
 polymer/eduke32/build/src/engine.c      | 2464 ++---------------------
 polymer/eduke32/build/src/engine_priv.h |  249 ++-
 polymer/eduke32/build/src/mhk.c         |  338 ++++
 polymer/eduke32/build/src/screenshot.c  |    1 -
 polymer/eduke32/eduke32.vcxproj         |    3 +
 polymer/eduke32/eduke32.vcxproj.filters |    9 +
 13 files changed, 2306 insertions(+), 2298 deletions(-)
 create mode 100644 polymer/eduke32/build/include/clip.h
 create mode 100644 polymer/eduke32/build/src/clip.c
 create mode 100644 polymer/eduke32/build/src/mhk.c

diff --git a/polymer/eduke32/Makefile b/polymer/eduke32/Makefile
index dc855bb15..d526b991d 100644
--- a/polymer/eduke32/Makefile
+++ b/polymer/eduke32/Makefile
@@ -43,6 +43,7 @@ ENGINE_OBJS = \
     crc32 \
     defs \
     engine \
+    clip \
     2d \
     hash \
     palette \
@@ -62,7 +63,8 @@ ENGINE_OBJS = \
     xxhash \
     md4 \
     colmatch \
-    screenshot
+    screenshot \
+    mhk
 
 ENGINE_EDITOR_OBJS = \
     build \
diff --git a/polymer/eduke32/Makefile.msvc b/polymer/eduke32/Makefile.msvc
index 729411076..b2129a245 100644
--- a/polymer/eduke32/Makefile.msvc
+++ b/polymer/eduke32/Makefile.msvc
@@ -137,6 +137,7 @@ ENGINE_OBJS= \
 	$(ENGINE_OBJ)\defs.$o \
 	$(ENGINE_OBJ)\colmatch.$o \
 	$(ENGINE_OBJ)\engine.$o \
+	$(ENGINE_OBJ)\clip.$o \
 	$(ENGINE_OBJ)\2d.$o \
 	$(ENGINE_OBJ)\hash.$o \
 	$(ENGINE_OBJ)\palette.$o \
@@ -160,7 +161,8 @@ ENGINE_OBJS= \
 	$(ENGINE_OBJ)\mutex.$o \
 	$(ENGINE_OBJ)\winbits.$o \
 	$(ENGINE_OBJ)\xxhash.$o \
-	$(ENGINE_OBJ)\screenshot.$o
+	$(ENGINE_OBJ)\screenshot.$o \
+	$(ENGINE_OBJ)\mhk.$o
 
 ENGINE_EDITOR_OBJS=$(ENGINE_OBJ)\build.$o \
 	$(ENGINE_OBJ)\startwin.editor.$o \
diff --git a/polymer/eduke32/build/Makefile.deps b/polymer/eduke32/build/Makefile.deps
index c94b85b3d..d6ec0e648 100644
--- a/polymer/eduke32/build/Makefile.deps
+++ b/polymer/eduke32/build/Makefile.deps
@@ -11,8 +11,11 @@ $(ENGINE_OBJ)/crc32.$o: $(ENGINE_SRC)/crc32.c $(ENGINE_INC)/crc32.h
 $(ENGINE_OBJ)/defs.$o: $(ENGINE_SRC)/defs.c $(ENGINE_INC)/build.h $(ENGINE_INC)/buildtypes.h $(ENGINE_INC)/baselayer.h $(ENGINE_INC)/scriptfile.h $(ENGINE_INC)/compat.h
 $(ENGINE_OBJ)/engine.$o: $(ENGINE_SRC)/engine.c $(ENGINE_INC)/compat.h $(ENGINE_INC)/build.h $(ENGINE_INC)/buildtypes.h $(ENGINE_INC)/pragmas.h $(ENGINE_INC)/cache1d.h $(ENGINE_INC)/a.h $(ENGINE_INC)/osd.h $(ENGINE_INC)/baselayer.h $(ENGINE_SRC)/engine_priv.h $(ENGINE_SRC)/engine_oldmap.h $(ENGINE_INC)/polymost.h $(ENGINE_INC)/hightile.h $(ENGINE_INC)/mdsprite.h $(ENGINE_INC)/polymer.h
 $(ENGINE_OBJ)/2d.$o: $(ENGINE_SRC)/2d.c
+$(ENGINE_OBJ)/clip.$o: $(ENGINE_SRC)/clip.c
 $(ENGINE_OBJ)/screenshot.$o: $(ENGINE_SRC)/screenshot.c
 $(ENGINE_OBJ)/hash.$o: $(ENGINE_SRC)/hash.c $(ENGINE_INC)/hash.h
+$(ENGINE_OBJ)/colmatch.$o: $(ENGINE_SRC)/colmatch.c
+$(ENGINE_OBJ)/mhk.$o: $(ENGINE_SRC)/mhk.c
 $(ENGINE_OBJ)/palette.$o: $(ENGINE_SRC)/palette.c $(ENGINE_INC)/palette.h
 $(ENGINE_OBJ)/polymost.$o: $(ENGINE_SRC)/polymost.c $(ENGINE_INC)/lz4.h $(ENGINE_INC)/compat.h $(ENGINE_INC)/build.h $(ENGINE_INC)/buildtypes.h $(ENGINE_SRC)/engine_priv.h $(ENGINE_INC)/polymost.h $(ENGINE_INC)/hightile.h $(ENGINE_INC)/mdsprite.h $(ENGINE_INC)/texcache.h
 $(ENGINE_OBJ)/texcache.$o: $(ENGINE_SRC)/texcache.c $(ENGINE_INC)/texcache.h $(ENGINE_INC)/polymost.h $(ENGINE_INC)/dxtfilter.h $(ENGINE_INC)/kplib.h
diff --git a/polymer/eduke32/build/include/build.h b/polymer/eduke32/build/include/build.h
index 922641c3e..6d2e871c2 100644
--- a/polymer/eduke32/build/include/build.h
+++ b/polymer/eduke32/build/include/build.h
@@ -307,6 +307,8 @@ enum {
 #undef UNTRACKED_STRUCTS
 #endif
 
+#include "clip.h"
+
 #ifdef NEW_MAP_FORMAT
 //////////////////// Lunatic new-generation map format ////////////////////
 
@@ -1102,18 +1104,6 @@ FORCE_INLINE void rotatesprite_win(int32_t sx, int32_t sy, int32_t z, int16_t a,
 void bfirst_search_init(int16_t *list, uint8_t *bitmap, int32_t *eltnumptr, int32_t maxnum, int16_t firstelt);
 void bfirst_search_try(int16_t *list, uint8_t *bitmap, int32_t *eltnumptr, int16_t elt);
 
-extern int32_t clipmoveboxtracenum;
-
-int32_t   clipmove(vec3_t *vect, int16_t *sectnum, int32_t xvect, int32_t yvect, int32_t walldist,
-                   int32_t ceildist, int32_t flordist, uint32_t cliptype) ATTRIBUTE((nonnull(1,2)));
-int32_t clipmovex(vec3_t *pos, int16_t *sectnum, int32_t xvect, int32_t yvect,
-                  int32_t walldist, int32_t ceildist, int32_t flordist, uint32_t cliptype,
-                  uint8_t noslidep) ATTRIBUTE((nonnull(1,2)));
-int32_t   clipinsidebox(int32_t x, int32_t y, int16_t wallnum, int32_t walldist);
-int32_t   clipinsideboxline(int32_t x, int32_t y, int32_t x1, int32_t y1,
-                            int32_t x2, int32_t y2, int32_t walldist);
-int32_t   pushmove(vec3_t *vect, int16_t *sectnum, int32_t walldist,
-                   int32_t ceildist, int32_t flordist, uint32_t cliptype) ATTRIBUTE((nonnull(1,2)));
 void   getzrange(const vec3_t *vect, int16_t sectnum, int32_t *ceilz, int32_t *ceilhit, int32_t *florz,
                  int32_t *florhit, int32_t walldist, uint32_t cliptype) ATTRIBUTE((nonnull(1,3,4,5,6)));
 int32_t   hitscan(const vec3_t *sv, int16_t sectnum, int32_t vx, int32_t vy, int32_t vz,
@@ -1475,6 +1465,11 @@ static inline int32_t setspritez_old(int16_t spritenum, int32_t x, int32_t y, in
     return setspritez(spritenum, &vector);
 }
 
+extern int32_t rintersect(int32_t x1, int32_t y1, int32_t z1,
+    int32_t vx_, int32_t vy_, int32_t vz,
+    int32_t x3, int32_t y3, int32_t x4, int32_t y4,
+    int32_t *intx, int32_t *inty, int32_t *intz);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/polymer/eduke32/build/include/clip.h b/polymer/eduke32/build/include/clip.h
new file mode 100644
index 000000000..a5f55876f
--- /dev/null
+++ b/polymer/eduke32/build/include/clip.h
@@ -0,0 +1,88 @@
+#pragma once
+
+#ifndef clip_h_
+#define clip_h_
+
+#ifdef HAVE_CLIPSHAPE_FEATURE
+
+#define CM_MAX 256  // must be a power of 2
+
+// sectoidx bits
+#undef CM_NONE
+#define CM_NONE (CM_MAX<<1)
+#define CM_SOME (CM_NONE-1)
+#define CM_OUTER (CM_MAX)   // sector surrounds clipping sector
+
+// sprite -> sector tag mappings
+#define CM_XREPEAT floorpal
+#define CM_YREPEAT floorxpanning
+#define CM_XOFFSET ceilingshade
+#define CM_YOFFSET floorshade
+#define CM_CSTAT hitag
+#define CM_ANG extra
+#define CM_FLOORZ(Sec) (*(int32_t *)&sector[Sec].ceilingxpanning)  // ceilingxpanning,ceilingypanning,floorpicnum
+#define CM_CEILINGZ(Sec) (*(int32_t *)&sector[Sec].visibility)  // visibility,fogpal,lotag
+
+// backup of original normalized coordinates
+#define CM_WALL_X(Wal) (*(int32_t *)&wall[Wal].picnum)  // picnum, overpicnum
+#define CM_WALL_Y(Wal) (*(int32_t *)&wall[Wal].lotag)  // lotag, hitag
+
+// don't rotate when applying clipping, for models with rotational symmetry
+#define CM_NOROT(Spri) (sprite[Spri].cstat&2)
+#define CM_NOROTS(Sect) (sector[Sect].CM_CSTAT&2)
+
+#define MAXCLIPNUM 1024
+
+typedef struct
+{
+    int16_t qbeg, qend;  // indices into sectq
+    int16_t picnum, next;
+    int32_t maxdist;
+} clipinfo_t;
+
+extern clipinfo_t clipinfo[CM_MAX];
+
+typedef struct
+{
+    int16_t numsectors, numwalls;
+    tsectortype *sector;
+    twalltype *wall;
+} mapinfo_t;
+
+extern mapinfo_t origmapinfo, clipmapinfo;
+
+typedef struct
+{
+    int32_t x1, y1, x2, y2;
+} linetype;
+
+extern linetype clipit[MAXCLIPNUM];
+
+extern void clipmapinfo_init();
+extern int32_t quickloadboard;
+extern int16_t *sectq;
+extern int16_t pictoidx[MAXTILES];  // maps tile num to clipinfo[] index
+extern int16_t clipnum;
+extern int32_t clipsectnum, origclipsectnum, clipspritenum;
+extern int16_t clipsectorlist[MAXCLIPNUM], origclipsectorlist[MAXCLIPNUM];
+extern int16_t clipspritelist[MAXCLIPNUM];
+extern void mapinfo_set(mapinfo_t *bak, mapinfo_t *newmap);
+extern int32_t clipsprite_try(const spritetype *spr, int32_t xmin, int32_t ymin, int32_t xmax, int32_t ymax);
+extern int32_t clipsprite_initindex(int32_t curidx, spritetype *curspr, int32_t *clipsectcnt, const vec3_t *vect);
+
+int32_t   clipinsidebox(int32_t x, int32_t y, int16_t wallnum, int32_t walldist);
+int32_t   clipinsideboxline(int32_t x, int32_t y, int32_t x1, int32_t y1,
+    int32_t x2, int32_t y2, int32_t walldist);
+
+extern int32_t clipmoveboxtracenum;
+
+int32_t   clipmove(vec3_t *vect, int16_t *sectnum, int32_t xvect, int32_t yvect, int32_t walldist,
+    int32_t ceildist, int32_t flordist, uint32_t cliptype) ATTRIBUTE((nonnull(1, 2)));
+int32_t clipmovex(vec3_t *pos, int16_t *sectnum, int32_t xvect, int32_t yvect,
+    int32_t walldist, int32_t ceildist, int32_t flordist, uint32_t cliptype,
+    uint8_t noslidep) ATTRIBUTE((nonnull(1, 2)));
+int32_t   pushmove(vec3_t *vect, int16_t *sectnum, int32_t walldist,
+    int32_t ceildist, int32_t flordist, uint32_t cliptype) ATTRIBUTE((nonnull(1, 2)));
+
+#endif
+#endif
\ No newline at end of file
diff --git a/polymer/eduke32/build/src/2d.c b/polymer/eduke32/build/src/2d.c
index 54b6665d5..76919c489 100644
--- a/polymer/eduke32/build/src/2d.c
+++ b/polymer/eduke32/build/src/2d.c
@@ -1,4 +1,3 @@
-#include "compat.h"
 #include "build.h"
 #include "editor.h"
 
@@ -119,7 +118,6 @@ char getpixel(int32_t x, int32_t y)
 }
 
 
-
 //
 // drawline256
 //
diff --git a/polymer/eduke32/build/src/clip.c b/polymer/eduke32/build/src/clip.c
new file mode 100644
index 000000000..62e56bdb4
--- /dev/null
+++ b/polymer/eduke32/build/src/clip.c
@@ -0,0 +1,1420 @@
+#include "build.h"
+#include "engine_priv.h"
+
+////// sector-like clipping for sprites //////
+#ifdef HAVE_CLIPSHAPE_FEATURE
+void mapinfo_set(mapinfo_t *bak, mapinfo_t *newmap)
+{
+    if (bak)
+    {
+        bak->numsectors = numsectors;
+        bak->numwalls = numwalls;
+        bak->sector = (tsectortype *) sector;
+        bak->wall = (twalltype *) wall;
+    }
+
+    if (newmap)
+    {
+        numsectors = newmap->numsectors;
+        numwalls = newmap->numwalls;
+        sector = (sectortype *) newmap->sector;
+        wall = (walltype *) newmap->wall;
+    }
+}
+
+mapinfo_t origmapinfo, clipmapinfo;
+int32_t quickloadboard=0;
+
+clipinfo_t clipinfo[CM_MAX];
+static int32_t numclipmaps;
+
+static int32_t numclipsects;  // number in sectq[]
+static int16_t *sectoidx;
+int16_t *sectq;  // [numsectors]
+int16_t pictoidx[MAXTILES];  // maps tile num to clipinfo[] index
+static int16_t *tempictoidx;
+
+static tsectortype *loadsector;
+static twalltype *loadwall, *loadwallinv;
+static tspritetype *loadsprite;
+
+int16_t clipnum;
+linetype clipit[MAXCLIPNUM];
+int32_t clipsectnum, origclipsectnum, clipspritenum;
+int16_t clipsectorlist[MAXCLIPNUM], origclipsectorlist[MAXCLIPNUM];
+#ifdef HAVE_CLIPSHAPE_FEATURE
+int16_t clipspritelist[MAXCLIPNUM];  // sector-like sprite clipping
+#endif
+static int16_t clipobjectval[MAXCLIPNUM];
+
+void clipmapinfo_init()
+{
+    numclipmaps = 0;
+    numclipsects = 0;
+
+    DO_FREE_AND_NULL(sectq);
+    DO_FREE_AND_NULL(sectoidx);
+    DO_FREE_AND_NULL(tempictoidx);
+    DO_FREE_AND_NULL(loadsector);
+    DO_FREE_AND_NULL(loadwall);
+    DO_FREE_AND_NULL(loadwallinv);
+    DO_FREE_AND_NULL(loadsprite);
+
+    // two's complement trick, -1 = 0xff
+    Bmemset(&pictoidx, -1, sizeof(pictoidx));
+    Bmemset(&clipmapinfo, 0, sizeof(mapinfo_t));
+
+    numsectors = 0;
+    numwalls = 0;
+}
+
+// loads the clip maps.
+// this should be called before any real map is loaded.
+int32_t clipmapinfo_load(void)
+{
+    int32_t i, k, w;
+
+    int32_t lwcp = 0;
+    int32_t fi;
+
+    int32_t *fisec = NULL;
+    int32_t *fispr = NULL;
+
+    int32_t ournumsectors=0, ournumwalls=0, ournumsprites=0;
+
+    clipmapinfo_init();
+
+    loadsector = (tsectortype *) Xmalloc(MAXSECTORS * sizeof(sectortype));
+    loadwall = (twalltype *) Xmalloc(MAXWALLS * sizeof(walltype));
+    loadsprite = (tspritetype *) Xmalloc(MAXSPRITES * sizeof(spritetype));
+
+    if (g_clipMapFilesNum)
+        fisec = (int32_t *) Xcalloc(g_clipMapFilesNum, sizeof(int32_t));
+    if (g_clipMapFilesNum)
+        fispr = (int32_t *) Xcalloc(g_clipMapFilesNum, sizeof(int32_t));
+
+    quickloadboard = 1;
+    for (fi = 0; fi < g_clipMapFilesNum; ++fi)
+    {
+        int16_t ang, cs;
+        vec3_t tmppos;
+
+        fisec[fi] = ournumsectors;
+        fispr[fi] = ournumsprites;
+
+        i = loadboard(g_clipMapFiles[fi], 8, &tmppos, &ang, &cs);
+        if (i<0)
+            continue;
+        // Numsprites will now be set!
+
+        initprintf("Loading clip map: %s\n", g_clipMapFiles[fi]);
+
+        if (ournumsectors+numsectors>MAXSECTORS ||
+            ournumwalls+numwalls>MAXWALLS ||
+            ournumsprites+Numsprites>MAXSPRITES)
+        {
+            initprintf("clip map: warning: exceeded limits when loading %s, aborting.\n", g_clipMapFiles[fi]);
+            break;
+        }
+
+        Bmemcpy(loadsector+ournumsectors, sector, numsectors*sizeof(sectortype));
+        Bmemcpy(loadwall+ournumwalls, wall, numwalls*sizeof(walltype));
+        Bmemcpy(loadsprite+ournumsprites, sprite, Numsprites*sizeof(spritetype));
+        for (i=ournumsectors; i<ournumsectors+numsectors; i++)
+            loadsector[i].wallptr += ournumwalls;
+        for (i=ournumwalls; i<ournumwalls+numwalls; i++)
+        {
+            if (loadwall[i].point2>=0)
+                loadwall[i].point2 += ournumwalls;
+            if (loadwall[i].nextwall>=0)
+            {
+                loadwall[i].nextwall += ournumwalls;
+                loadwall[i].nextsector += ournumsectors;
+            }
+        }
+        for (i=ournumsprites; i<ournumsprites+Numsprites; i++)
+            if (loadsprite[i].sectnum>=0)
+                loadsprite[i].sectnum += ournumsectors;
+        ournumsectors += numsectors;
+        ournumwalls += numwalls;
+        ournumsprites += Numsprites;
+
+        ++lwcp;
+    }
+    quickloadboard = 0;
+
+    if (ournumsectors==0 || ournumwalls==0 || ournumsprites==0)  // nothing loaded
+    {
+        clipmapinfo_init();
+
+        Bfree(fisec);
+        Bfree(fispr);
+
+        return -1;
+    }
+
+    // shrink
+    loadsector = (tsectortype *) Xrealloc(loadsector, ournumsectors*sizeof(sectortype));
+    loadwall = (twalltype *) Xrealloc(loadwall, ournumwalls*sizeof(walltype));
+
+    Bmemcpy(sector, loadsector, ournumsectors*sizeof(sectortype));
+    Bmemcpy(wall, loadwall, ournumwalls*sizeof(walltype));
+    Bmemcpy(sprite, loadsprite, ournumsprites*sizeof(spritetype));
+    numsectors = ournumsectors;
+    numwalls = ournumwalls;
+
+    //  vvvv    don't use headsprite[sect,stat]!   vvvv
+
+    sectoidx = (int16_t *) Xmalloc(numsectors*sizeof(sectoidx[0]));
+
+    for (i=0; i<numsectors; i++)
+        sectoidx[i] = CM_NONE;
+
+    // determine outer sectors
+    for (i=0; i<numsectors; i++)
+    {
+        for (w=sector[i].wallptr; w<sector[i].wallptr+sector[i].wallnum; w++)
+            if (wall[w].nextsector<0)
+            {
+                sectoidx[i] = CM_OUTER;
+                break;
+            }
+    }
+    // break connections between outer sectors
+    for (i=0; i<numsectors; i++)
+    {
+        if (sectoidx[i] == CM_OUTER)
+            for (w=sector[i].wallptr; w<sector[i].wallptr+sector[i].wallnum; w++)
+            {
+                k = wall[w].nextwall;
+                if (k>=0 && sectoidx[wall[w].nextsector]==CM_OUTER)
+                {
+                    wall[k].nextwall = wall[k].nextsector = -1;
+                    wall[w].nextwall = wall[w].nextsector = -1;
+                }
+            }
+    }
+
+    {
+        int16_t ns, outersect;
+        int32_t pn, scnt, x, y, z, maxdist;
+
+        sectq = (int16_t *) Xmalloc(numsectors*sizeof(sectq[0]));
+        tempictoidx = (int16_t *) Xmalloc(MAXTILES*sizeof(tempictoidx[0]));
+
+        for (i=0; i<MAXTILES; i++)
+            tempictoidx[i]=-1;
+
+        // collect sprite picnums
+        for (i=0; i<MAXSPRITES && sprite[i].statnum<MAXSTATUS; i++)
+        {
+            pn = sprite[i].picnum;
+            k = sprite[i].sectnum;
+            //    -v-  note the <=                         ignore sprites in outer sectors
+            if (pn<=0 || pn>=MAXTILES || k<0 || k>=numsectors || (sectoidx[k]&CM_OUTER))
+                continue;
+
+            if (numclipmaps >= CM_MAX)
+            {
+                initprintf("warning: reached max clip map number %d, not processing any more\n", CM_MAX);
+                break;
+            }
+
+            // chain
+            if (pictoidx[pn]>=0)
+            {
+                if (sectoidx[k]&CM_SOME)
+                {
+                    for (fi = 0; fi < g_clipMapFilesNum; ++fi)
+                        if (k>=fisec[fi])
+                            break;
+                    initprintf("clip map \"%s\": error: tried to chain picnum %d (sprite %d) in sector %d which"
+                        " already belongs to picnum %d.\n", g_clipMapFiles[fi], pn, i-fispr[fi], k-fisec[fi],
+                        clipinfo[sectoidx[k]].picnum);
+                    clipmapinfo_init();
+
+                    Bfree(fisec);
+                    Bfree(fispr);
+
+                    return 2;
+                }
+
+                // new one is front
+                clipinfo[numclipmaps].next = pictoidx[pn];
+                pictoidx[pn] = numclipmaps;
+            }
+            else
+            {
+                clipinfo[numclipmaps].next = -1;
+                pictoidx[pn] = numclipmaps;
+            }
+
+            if (!CM_NOROT(i))
+            {
+                if (sprite[i].ang!=1536 && sprite[i].ang!=512)
+                {
+                    for (fi = 0; fi < g_clipMapFilesNum; ++fi)
+                        if (i>=fispr[fi])
+                            break;
+                    initprintf("clip map \"%s\": warning: sprite %d pointing neither northward nor southward. %s will be wrong.\n",
+                        g_clipMapFiles[fi], i-fispr[fi], (sprite[i].cstat&48)==32 ? "Scaling and flipping" : "X-flipping");
+                }
+            }
+
+            clipinfo[numclipmaps].picnum = pn;
+
+            // collect sectors
+            scnt = numclipsects;
+            sectq[numclipsects++] = k;
+            sectoidx[k] = numclipmaps;
+
+            clipinfo[numclipmaps].qbeg = scnt;
+
+            outersect = -1;
+
+            do
+            {
+                k = sectq[scnt];
+
+                for (w=sector[k].wallptr; w<sector[k].wallptr+sector[k].wallnum; w++)
+                {
+                    ns = wall[w].nextsector;
+                    if (ns>=0)
+                    {
+                        if (sectoidx[ns]==CM_NONE)
+                        {
+                            sectoidx[ns] = numclipmaps;
+                            sectq[numclipsects++] = ns;
+                        }
+                        else if (sectoidx[ns]&CM_OUTER)
+                        {
+                            if (outersect>=0 && ns!=outersect)
+                            {
+                                for (fi = 0; fi < g_clipMapFilesNum; ++fi)
+                                    if (ns>=fisec[fi])
+                                        break;
+                                initprintf("clip map \"%s\": error: encountered more than one outer sector (%d and %d)"
+                                    " for sprite %d.\n", g_clipMapFiles[fi], outersect-fisec[fi], ns-fisec[fi], i-fispr[fi]);
+                                clipmapinfo_init();
+
+                                Bfree(fisec);
+                                Bfree(fispr);
+
+                                return 3;
+                            }
+
+                            outersect = ns;
+                            sectoidx[outersect] |= numclipmaps;
+                        }
+                        else if (sectoidx[ns]!=numclipmaps)
+                        {
+                            for (fi = 0; fi < g_clipMapFilesNum; ++fi)
+                                if (ns>=fisec[fi])
+                                    break;
+                            initprintf("clip map \"%s\": error: encountered sector %d belonging to index %d"
+                                " while collecting sectors for sprite %d (index %d).\n",
+                                g_clipMapFiles[fi], ns-fisec[fi], sectoidx[ns], i-fispr[fi], numclipmaps);
+                            clipmapinfo_init();
+
+                            Bfree(fisec);
+                            Bfree(fispr);
+
+                            return 4;
+                        }
+                    }
+                }
+            } while (++scnt < numclipsects);
+
+            if (outersect==-1)
+            {
+                initprintf("clip map: INTERNAL ERROR: outersect==-1!\n");
+                clipmapinfo_init();
+
+                Bfree(fisec);
+                Bfree(fispr);
+
+                return 5;
+            }
+
+            sectq[numclipsects++] = outersect;  // last is outer
+            clipinfo[numclipmaps].qend = numclipsects-1;
+
+            // normalize
+            maxdist = 0;
+
+            for (scnt=clipinfo[numclipmaps].qbeg; scnt<=clipinfo[numclipmaps].qend; scnt++)
+            {
+                k = sectq[scnt];
+
+                x = sprite[i].x;
+                y = sprite[i].y;
+                z = sprite[i].z;
+
+                sector[k].floorz -= z;
+                sector[k].ceilingz -= z;
+
+                if (scnt==clipinfo[numclipmaps].qbeg)
+                {
+                    // backup sprite tags since we'll discard sprites later
+                    sector[k].CM_XREPEAT = sprite[i].xrepeat;
+                    sector[k].CM_YREPEAT = sprite[i].yrepeat;
+                    sector[k].CM_XOFFSET = sprite[i].xoffset;
+                    sector[k].CM_YOFFSET = sprite[i].yoffset;
+                    sector[k].CM_CSTAT = sprite[i].cstat;
+                    sector[k].CM_ANG = sprite[i].ang;
+                }
+
+                // backup floor and ceiling z
+                CM_FLOORZ(k) = sector[k].floorz;
+                CM_CEILINGZ(k) = sector[k].ceilingz;
+
+                for (w=sector[k].wallptr; w<sector[k].wallptr+sector[k].wallnum; w++)
+                {
+                    wall[w].x -= x;
+                    wall[w].y -= y;
+
+                    if (scnt!=clipinfo[numclipmaps].qend)
+                    {
+                        if (CM_NOROT(i))
+                        {
+                            if (klabs(wall[w].x) > maxdist)
+                                maxdist = klabs(wall[w].x);
+                            if (klabs(wall[w].y) > maxdist)
+                                maxdist = klabs(wall[w].y);
+                        }
+                        else
+                        {
+                            int32_t tmp = ksqrt(uhypsq(wall[w].x, wall[w].y));
+                            if (tmp > maxdist)
+                                maxdist = tmp;
+                        }
+                    }
+
+                    // aliasing
+                    if (wall[w].lotag>0 || wall[w].hitag>0)
+                    {
+                        int32_t ii;
+
+                        if (wall[w].lotag>0 && wall[w].hitag>0)
+                        {
+                            if (wall[w].lotag > wall[w].hitag)
+                                swapshort(&wall[w].lotag, &wall[w].hitag);
+
+                            for (ii=wall[w].lotag; ii<wall[w].hitag; ii++)
+                                tempictoidx[ii] = numclipmaps;
+                        }
+                        else if (wall[w].lotag>0)
+                        {
+                            if (wall[w].lotag<MAXTILES)
+                                tempictoidx[wall[w].lotag] = numclipmaps;
+                        }
+                        else
+                        {
+                            if (wall[w].hitag<MAXTILES)
+                                tempictoidx[wall[w].hitag] = numclipmaps;
+                        }
+                    }
+
+                    CM_WALL_X(w) = wall[w].x;
+                    CM_WALL_Y(w) = wall[w].y;
+                }
+            }
+
+            clipinfo[numclipmaps].maxdist = maxdist;
+            numclipmaps++;
+        }
+    }
+
+    // yes, too much copying, but better than ugly code
+    Bmemcpy(loadsector, sector, ournumsectors*sizeof(sectortype));
+    Bmemcpy(loadwall, wall, ournumwalls*sizeof(walltype));
+
+    // loadwallinv will contain all walls with inverted orientation for x/y-flip handling
+    loadwallinv = (twalltype *) Xmalloc(ournumwalls*sizeof(walltype));
+
+    {
+        int32_t j, loopstart, loopend, numloopwalls;
+
+        // invert walls!
+        loopstart = 0;
+        for (j=0; j<ournumwalls; j++)
+        {
+            wall[j].nextsector = wall[j].nextwall = -1;
+
+            if (wall[j].point2 < j)
+            {
+                loopend = j+1;
+                numloopwalls = loopend-loopstart;
+
+                if (numloopwalls<3)
+                {
+                    loopstart = loopend;
+                    continue;
+                }
+
+                for (k=0; k<numloopwalls; k++)
+                {
+                    wall[loopstart+k].x = loadwall[loopstart + (numloopwalls+1-k)%numloopwalls].x;
+                    wall[loopstart+k].y = loadwall[loopstart + (numloopwalls+1-k)%numloopwalls].y;
+
+                    CM_WALL_X(loopstart+k) = wall[loopstart+k].x;
+                    CM_WALL_Y(loopstart+k) = wall[loopstart+k].y;
+                }
+
+                loopstart = loopend;
+            }
+        }
+
+        // reconstruct wall connections
+        for (i=0; i<ournumsectors; i++)
+        {
+            for (j=sector[i].wallptr; j<sector[i].wallptr+sector[i].wallnum; j++)
+                checksectorpointer(j, i);
+        }
+    }
+    Bmemcpy(loadwallinv, wall, ournumwalls*sizeof(walltype));
+
+    clipmapinfo.numsectors = numsectors;
+    clipmapinfo.sector = loadsector;
+    clipmapinfo.numwalls = numwalls;
+    clipmapinfo.wall = loadwall;
+
+    for (i=0; i<MAXTILES; i++)
+    {
+        if (pictoidx[i]==-1 && tempictoidx[i]>=0)
+            pictoidx[i]=tempictoidx[i];
+    }
+
+    DO_FREE_AND_NULL(loadsprite);
+    DO_FREE_AND_NULL(tempictoidx);
+
+    // don't let other code be distracted by the temporary map we constructed
+    numsectors = 0;
+    numwalls = 0;
+    initspritelists();
+
+    if (lwcp > 0)
+        initprintf("Loaded clip map%s.\n", lwcp==1 ? "" : "s");
+
+    Bfree(fisec);
+    Bfree(fispr);
+
+    return 0;
+}
+
+
+int32_t clipshape_idx_for_sprite(spritetype *curspr, int32_t curidx)
+{
+    if (curidx < 0)  // per-sprite init
+        curidx = pictoidx[curspr->picnum];
+    else
+        curidx = clipinfo[curidx].next;
+
+    while (curidx>=0 && (curspr->cstat&32) != (sector[sectq[clipinfo[curidx].qbeg]].CM_CSTAT&32))
+        curidx = clipinfo[curidx].next;
+
+    return curidx;
+}
+#else
+int32_t clipshape_idx_for_sprite(spritetype *curspr, int32_t curidx)
+{
+    UNREFERENCED_PARAMETER(curspr);
+    UNREFERENCED_PARAMETER(curidx);
+    return -1;
+}
+#endif  // HAVE_CLIPSHAPE_FEATURE
+////// //////
+
+////////// CLIPMOVE //////////
+
+int32_t clipmoveboxtracenum = 3;
+
+//
+// clipinsidebox
+//
+int32_t clipinsidebox(int32_t x, int32_t y, int16_t wallnum, int32_t walldist)
+{
+    int32_t const r = walldist<<1;
+    twalltype const *wal = (twalltype *) &wall[wallnum];
+    vec2_t const v1 ={ wal->x + walldist - x, wal->y + walldist - y };
+    wal = (twalltype *) &wall[wal->point2];
+    vec2_t v2 ={ wal->x + walldist - x, wal->y + walldist - y };
+
+    if (((v1.x < 0) && (v2.x < 0)) || ((v1.y < 0) && (v2.y < 0)) ||
+        ((v1.x >= r) && (v2.x >= r)) || ((v1.y >= r) && (v2.y >= r)))
+        return (0);
+
+    v2.x -= v1.x; v2.y -= v1.y;
+
+    if (v2.x*(walldist-v1.y) >= v2.y*(walldist-v1.x))  //Front
+    {
+        v2.x *= ((v2.x > 0) ? (0 - v1.y) : (r - v1.y));
+        v2.y *= ((v2.y > 0) ? (r-v1.x) : (0-v1.x));
+        return v2.x < v2.y;
+    }
+
+    v2.x *= ((v2.x > 0) ? (r-v1.y) : (0-v1.y));
+    v2.y *= ((v2.y > 0) ? (0-v1.x) : (r-v1.x));
+    return (v2.x >= v2.y)<<1;
+}
+
+
+//
+// clipinsideboxline
+//
+int32_t clipinsideboxline(int32_t x, int32_t y, int32_t x1, int32_t y1, int32_t x2, int32_t y2, int32_t walldist)
+{
+    int32_t const r = walldist<<1;
+
+    x1 += walldist-x; x2 += walldist-x;
+
+    if (((x1 < 0) && (x2 < 0)) || ((x1 >= r) && (x2 >= r)))
+        return (0);
+
+    y1 += walldist-y; y2 += walldist-y;
+
+    if (((y1 < 0) && (y2 < 0)) || ((y1 >= r) && (y2 >= r)))
+        return (0);
+
+    x2 -= x1; y2 -= y1;
+
+    if (x2*(walldist-y1) >= y2*(walldist-x1))  //Front
+    {
+        x2 *= ((x2 > 0) ? (0-y1) : (r-y1));
+        y2 *= ((y2 > 0) ? (r-x1) : (0-x1));
+        return x2 < y2;
+    }
+
+    x2 *= ((x2 > 0) ? (r-y1) : (0-y1));
+    y2 *= ((y2 > 0) ? (0-x1) : (r-x1));
+    return (x2 >= y2)<<1;
+}
+
+
+#ifdef HAVE_CLIPSHAPE_FEATURE
+int32_t clipsprite_try(const spritetype *spr, int32_t xmin, int32_t ymin, int32_t xmax, int32_t ymax)
+{
+    // try and see whether this sprite's picnum has sector-like clipping data
+    int32_t i = pictoidx[spr->picnum];
+    // handle sector-like floor sprites separately
+    while (i>=0 && (spr->cstat&32) != (clipmapinfo.sector[sectq[clipinfo[i].qbeg]].CM_CSTAT&32))
+        i = clipinfo[i].next;
+
+    if (i>=0)
+    {
+        int32_t maxcorrection = clipinfo[i].maxdist;
+        const int32_t k = sectq[clipinfo[i].qbeg];
+
+        if ((spr->cstat&48)!=32)  // face/wall sprite
+        {
+            int32_t tempint1 = clipmapinfo.sector[k].CM_XREPEAT;
+            maxcorrection = divideu32_noinline(maxcorrection * (int32_t) spr->xrepeat, tempint1);
+        }
+        else  // floor sprite
+        {
+            int32_t tempint1 = clipmapinfo.sector[k].CM_XREPEAT;
+            int32_t tempint2 = clipmapinfo.sector[k].CM_YREPEAT;
+            maxcorrection = max(divideu32_noinline(maxcorrection * (int32_t) spr->xrepeat, tempint1),
+                divideu32_noinline(maxcorrection * (int32_t) spr->yrepeat, tempint2));
+        }
+
+        maxcorrection -= MAXCLIPDIST;
+
+        if (spr->x < xmin - maxcorrection) return 1;
+        if (spr->y < ymin - maxcorrection) return 1;
+        if (spr->x > xmax + maxcorrection) return 1;
+        if (spr->y > ymax + maxcorrection) return 1;
+
+        if (clipspritenum < MAXCLIPNUM)
+            clipspritelist[clipspritenum++] = spr-sprite;
+        //initprintf("%d: clip sprite[%d]\n",clipspritenum,j);
+        return 1;
+    }
+
+    return 0;
+}
+
+// return: -1 if curspr has x-flip xor y-flip (in the horizontal map plane!), 1 else
+int32_t clipsprite_initindex(int32_t curidx, spritetype *curspr, int32_t *clipsectcnt, const vec3_t *vect)
+{
+    int32_t k, daz = curspr->z;
+    int32_t scalex, scaley, scalez, flipx, flipy;
+    int32_t flipmul=1;
+
+    const int32_t j = sectq[clipinfo[curidx].qbeg];
+    const int32_t tempint1 = sector[j].CM_XREPEAT;
+    const int32_t tempint2 = sector[j].CM_YREPEAT;
+
+    const int32_t rotang = (curspr->ang - sector[j].CM_ANG)&2047;
+    const int32_t dorot = !CM_NOROTS(j);
+
+    if ((curspr->cstat&48)!=32)  // face/wall sprite
+    {
+        scalex = scaley = divscale22(curspr->xrepeat, tempint1);
+        scalez = divscale22(curspr->yrepeat, tempint2);
+
+        flipx = 1-((curspr->cstat&4)>>1);
+        flipy = 1;
+    }
+    else
+    {
+        scalex = divscale22(curspr->xrepeat, tempint1);
+        scaley = divscale22(curspr->yrepeat, tempint2);
+        scalez = scalex;
+
+        flipx = 1-((curspr->cstat&4)>>1);
+        flipy = 1-((curspr->cstat&8)>>2);
+    }
+
+    if (dorot)
+    {
+        flipmul = flipx*flipy;
+        if (flipmul==-1)
+            wall = (walltype *) loadwallinv;
+    }
+
+    if ((curspr->cstat&128) != (sector[j].CM_CSTAT&128))
+        daz += (((curspr->cstat&128)>>6)-1)*((tilesiz[curspr->picnum].y*curspr->yrepeat)<<1);
+
+    *clipsectcnt = clipsectnum = 0;
+    // init sectors for this index
+    for (k=clipinfo[curidx].qbeg; k<=clipinfo[curidx].qend; k++)
+    {
+        const int32_t j = sectq[k];
+        sectortype *const sec = &sector[j];
+        const int32_t startwall = sec->wallptr, endwall = startwall+sec->wallnum;
+
+        int32_t w;
+        walltype *wal;
+
+        sec->floorz = daz + mulscale22(scalez, CM_FLOORZ(j));
+        sec->ceilingz = daz + mulscale22(scalez, CM_CEILINGZ(j));
+        //initprintf("sec %d: f=%d, c=%d\n", j, sec->floorz, sec->ceilingz);
+
+        for (w=startwall, wal=&wall[startwall]; w<endwall; w++, wal++)
+        {
+            wal->x = mulscale22(scalex, CM_WALL_X(w));
+            wal->y = mulscale22(scaley, CM_WALL_Y(w));
+
+            if (dorot)
+            {
+                wal->x *= flipx;
+                wal->y *= flipy;
+                rotatepoint(zerovec, *(vec2_t *) wal, rotang, (vec2_t *) wal);
+            }
+
+            wal->x += curspr->x;
+            wal->y += curspr->y;
+        }
+
+        if (inside(vect->x, vect->y, j)==1)
+            clipsectorlist[clipsectnum++] = j;
+    }
+
+    // add outer sector if not inside inner ones
+    if (clipsectnum==0)
+        clipsectorlist[clipsectnum++] = sectq[k-1];
+
+    return flipmul;
+}
+#endif
+
+static int32_t clipmove_warned=0;
+
+static void addclipline(int32_t dax1, int32_t day1, int32_t dax2, int32_t day2, int32_t daoval)
+{
+    if (clipnum < MAXCLIPNUM)
+    {
+        clipit[clipnum].x1 = dax1; clipit[clipnum].y1 = day1;
+        clipit[clipnum].x2 = dax2; clipit[clipnum].y2 = day2;
+        clipobjectval[clipnum] = daoval;
+        clipnum++;
+    }
+    else if (!clipmove_warned)
+    {
+        initprintf("!!clipnum\n");
+        clipmove_warned = 1;
+    }
+}
+
+static inline void clipmove_tweak_pos(const vec3_t *pos, int32_t gx, int32_t gy,
+    int32_t x1, int32_t y1, int32_t x2, int32_t y2,
+    int32_t *daxptr, int32_t *dayptr)
+{
+    int32_t daz;
+
+    if (rintersect(pos->x, pos->y, 0, gx, gy, 0, x1, y1, x2, y2, daxptr, dayptr, &daz) == -1)
+    {
+        *daxptr = pos->x;
+        *dayptr = pos->y;
+    }
+}
+
+// Returns: should clip?
+static int32_t check_floor_curb(int32_t dasect, int32_t nextsect, int32_t flordist,
+    int32_t posz, int32_t dax, int32_t day)
+{
+    const sectortype *sec2 = &sector[nextsect];
+    int32_t daz2 = getflorzofslope(nextsect, dax, day);
+
+    return ((sec2->floorstat&1) == 0 &&  // parallaxed floor curbs don't clip
+        posz >= daz2-(flordist-1) &&  // also account for desired z distance tolerance
+        daz2 < getflorzofslope(dasect, dax, day)-(1<<8));  // curbs less tall than 256 z units don't clip
+}
+
+int32_t clipmovex(vec3_t *pos, int16_t *sectnum,
+    int32_t xvect, int32_t yvect,
+    int32_t walldist, int32_t ceildist, int32_t flordist, uint32_t cliptype,
+    uint8_t noslidep)
+{
+    const int32_t oboxtracenum = clipmoveboxtracenum;
+
+    if (noslidep)
+        clipmoveboxtracenum = 1;
+    int32_t ret = clipmove(pos, sectnum, xvect, yvect,
+        walldist, ceildist, flordist, cliptype);
+    clipmoveboxtracenum = oboxtracenum;
+
+    return ret;
+}
+
+//
+// raytrace (internal)
+//
+static inline int32_t raytrace(int32_t x3, int32_t y3, int32_t *x4, int32_t *y4)
+{
+    int32_t hitwall = -1;
+
+    for (int32_t z=clipnum-1; z>=0; z--)
+    {
+        const int32_t x1 = clipit[z].x1, x2 = clipit[z].x2, x21 = x2-x1;
+        const int32_t y1 = clipit[z].y1, y2 = clipit[z].y2, y21 = y2-y1;
+
+        int32_t topu = x21*(y3-y1) - (x3-x1)*y21;
+        if (topu <= 0)
+            continue;
+
+        if (x21*(*y4-y1) > (*x4-x1)*y21)
+            continue;
+
+        const int32_t x43 = *x4-x3;
+        const int32_t y43 = *y4-y3;
+
+        if (x43*(y1-y3) > (x1-x3)*y43)
+            continue;
+
+        if (x43*(y2-y3) <= (x2-x3)*y43)
+            continue;
+
+        const int32_t bot = x43*y21 - x21*y43;
+        if (bot == 0)
+            continue;
+
+        int32_t cnt = 256, nintx, ninty;
+
+        do
+        {
+            cnt--; if (cnt < 0) { *x4 = x3; *y4 = y3; return z; }
+            nintx = x3 + scale(x43, topu, bot);
+            ninty = y3 + scale(y43, topu, bot);
+            topu--;
+        } while (x21*(ninty-y1) <= (nintx-x1)*y21);
+
+        if (klabs(x3-nintx)+klabs(y3-ninty) < klabs(x3-*x4)+klabs(y3-*y4))
+        {
+            *x4 = nintx; *y4 = ninty; hitwall = z;
+        }
+    }
+
+    return hitwall;
+}
+
+//
+// keepaway (internal)
+//
+static inline void keepaway(int32_t *x, int32_t *y, int32_t w)
+{
+    const int32_t x1 = clipit[w].x1, dx = clipit[w].x2-x1;
+    const int32_t y1 = clipit[w].y1, dy = clipit[w].y2-y1;
+    const int32_t ox = ksgn(-dy), oy = ksgn(dx);
+    char first = (klabs(dx) <= klabs(dy));
+
+    while (1)
+    {
+        if (dx*(*y-y1) > (*x-x1)*dy)
+            return;
+
+        if (first == 0)
+            *x += ox;
+        else
+            *y += oy;
+
+        first ^= 1;
+    }
+}
+
+//
+// clipmove
+//
+int32_t clipmove(vec3_t *pos, int16_t *sectnum,
+    int32_t xvect, int32_t yvect,
+    int32_t walldist, int32_t ceildist, int32_t flordist, uint32_t cliptype)
+{
+    int32_t i, j, k, tempint1, tempint2;
+    int32_t x1, y1, x2, y2;
+    int32_t dax, day;
+    int32_t retval=0;
+
+    spritetype *curspr=NULL;  // non-NULL when handling sprite with sector-like clipping
+    int32_t curidx=-1, clipsectcnt, clipspritecnt;
+
+    const int32_t dawalclipmask = (cliptype&65535);        //CLIPMASK0 = 0x00010001
+    const int32_t dasprclipmask = (cliptype>>16);          //CLIPMASK1 = 0x01000040
+
+    const int32_t oxvect=xvect, oyvect=yvect;
+
+    int32_t goalx = pos->x + (xvect>>14);
+    int32_t goaly = pos->y + (yvect>>14);
+    const int32_t cx = (pos->x+goalx)>>1;
+    const int32_t cy = (pos->y+goaly)>>1;
+
+    //Extra walldist for sprites on sector lines
+    const int32_t gx=goalx-(pos->x), gy=goaly-(pos->y);
+    const int32_t rad = nsqrtasm(uhypsq(gx, gy)) + MAXCLIPDIST+walldist + 8;
+    const int32_t xmin = cx-rad, ymin = cy-rad;
+    const int32_t xmax = cx+rad, ymax = cy+rad;
+
+    if ((xvect|yvect) == 0 || *sectnum < 0)
+        return 0;
+
+    clipmove_warned = 0;
+    clipnum = 0;
+
+    clipsectorlist[0] = (*sectnum);
+    clipsectcnt = 0; clipsectnum = 1;
+    clipspritecnt = 0; clipspritenum = 0;
+    do
+    {
+        const walltype *wal;
+        const sectortype *sec;
+        int32_t dasect, startwall, endwall;
+
+#ifdef HAVE_CLIPSHAPE_FEATURE
+        if (clipsectcnt>=clipsectnum)
+        {
+            // one bunch of sectors completed (either the very first
+            // one or a sector-like sprite one), prepare the next
+
+            //initprintf("init sprite %d\n", clipspritecnt);
+            if (!curspr)
+            {
+                // init sector-like sprites for clipping
+                origclipsectnum = clipsectnum;
+                Bmemcpy(origclipsectorlist, clipsectorlist, clipsectnum*sizeof(clipsectorlist[0]));
+
+                // replace sector and wall with clip map
+                mapinfo_set(&origmapinfo, &clipmapinfo);
+            }
+
+            curspr = &sprite[clipspritelist[clipspritecnt]];
+            curidx = clipshape_idx_for_sprite(curspr, curidx);
+
+            if (curidx < 0)
+            {
+                clipspritecnt++;
+                continue;
+            }
+
+            clipsprite_initindex(curidx, curspr, &clipsectcnt, pos);
+        }
+#endif
+
+        dasect = clipsectorlist[clipsectcnt++];
+        //if (curspr)
+        //    initprintf("sprite %d/%d: sect %d/%d (%d)\n", clipspritecnt,clipspritenum, clipsectcnt,clipsectnum,dasect);
+
+        ////////// Walls //////////
+
+        sec = &sector[dasect];
+        startwall = sec->wallptr; endwall = startwall + sec->wallnum;
+        for (j=startwall, wal=&wall[startwall]; j<endwall; j++, wal++)
+        {
+            int32_t clipyou = 0, dx, dy;
+            const walltype *const wal2 = &wall[wal->point2];
+
+            if (wal->x < xmin && wal2->x < xmin) continue;
+            if (wal->x > xmax && wal2->x > xmax) continue;
+            if (wal->y < ymin && wal2->y < ymin) continue;
+            if (wal->y > ymax && wal2->y > ymax) continue;
+
+            x1 = wal->x; y1 = wal->y; x2 = wal2->x; y2 = wal2->y;
+
+            dx = x2-x1; dy = y2-y1;
+            if (dx*((pos->y)-y1) < ((pos->x)-x1)*dy) continue;  //If wall's not facing you
+
+            if (dx > 0) dax = dx*(ymin-y1); else dax = dx*(ymax-y1);
+            if (dy > 0) day = dy*(xmax-x1); else day = dy*(xmin-x1);
+            if (dax >= day) continue;
+
+#ifdef HAVE_CLIPSHAPE_FEATURE
+            if (curspr)
+            {
+                if (wal->nextsector>=0)
+                {
+                    const sectortype *sec2 = &sector[wal->nextsector];
+
+                    clipmove_tweak_pos(pos, gx, gy, x1, y1, x2, y2, &dax, &day);
+
+#define CLIPMV_SPR_F_DAZ2 getflorzofslope(wal->nextsector, dax,day)
+#define CLIPMV_SPR_F_BASEZ getflorzofslope(sectq[clipinfo[curidx].qend], dax,day)
+
+                    if ((sec2->floorstat&1) == 0)
+                        if (CLIPMV_SPR_F_DAZ2-(flordist-1) <= pos->z)
+                            if (pos->z <= CLIPMV_SPR_F_BASEZ+(flordist-1))
+                                clipyou = 1;
+
+                    if (clipyou == 0)
+                    {
+#define CLIPMV_SPR_C_DAZ2 getceilzofslope(wal->nextsector, dax,day)
+#define CLIPMV_SPR_C_BASEZ getceilzofslope(sectq[clipinfo[curidx].qend], dax,day)
+
+                        if ((sec2->ceilingstat&1) == 0)
+                            if (CLIPMV_SPR_C_BASEZ-(ceildist-1) <= pos->z)
+                                if (pos->z <= CLIPMV_SPR_C_DAZ2+(ceildist-1))
+                                    clipyou = 1;
+                    }
+                }
+            }
+            else
+#endif
+                if (wal->nextsector < 0 || (wal->cstat&dawalclipmask))
+                {
+                    clipyou = 1;
+#ifdef YAX_ENABLE
+                    int16_t cb = yax_getbunch(dasect, YAX_CEILING);
+
+                    if (cb >= 0 && (sec->ceilingstat & yax_waltosecmask(dawalclipmask)) == 0)
+                    {
+                        int32_t ynw = yax_getnextwall(j, YAX_CEILING);
+
+                        if (ynw >= 0 && wall[ynw].nextsector >= 0 && (wall[ynw].cstat & dawalclipmask) == 0)
+                        {
+                            clipmove_tweak_pos(pos, gx, gy, x1, y1, x2, y2, &dax, &day);
+                            clipyou = check_floor_curb(dasect, wall[ynw].nextsector, flordist, pos->z, dax, day);
+                        }
+                    }
+#endif
+                }
+                else if (editstatus == 0)
+                {
+                    clipmove_tweak_pos(pos, gx, gy, x1, y1, x2, y2, &dax, &day);
+                    clipyou = check_floor_curb(dasect, wal->nextsector, flordist, pos->z, dax, day);
+
+                    if (clipyou == 0)
+                    {
+                        const sectortype *sec2 = &sector[wal->nextsector];
+                        int32_t daz2 = getceilzofslope(wal->nextsector, dax, day);
+
+                        clipyou = ((sec2->ceilingstat&1) == 0 &&
+                            pos->z <= daz2+(ceildist-1) &&
+                            daz2 > getceilzofslope(dasect, dax, day)+(1<<8));
+                    }
+                }
+
+            if (clipyou)
+            {
+                int16_t objtype;
+                int32_t bsz;
+
+                if (!curspr)
+                    objtype = (int16_t) j+32768;
+                else
+                    objtype = (int16_t) (curspr-sprite)+49152;
+
+                //Add 2 boxes at endpoints
+                bsz = walldist; if (gx < 0) bsz = -bsz;
+                addclipline(x1-bsz, y1-bsz, x1-bsz, y1+bsz, objtype);
+                addclipline(x2-bsz, y2-bsz, x2-bsz, y2+bsz, objtype);
+                bsz = walldist; if (gy < 0) bsz = -bsz;
+                addclipline(x1+bsz, y1-bsz, x1-bsz, y1-bsz, objtype);
+                addclipline(x2+bsz, y2-bsz, x2-bsz, y2-bsz, objtype);
+
+                dax = walldist; if (dy > 0) dax = -dax;
+                day = walldist; if (dx < 0) day = -day;
+                addclipline(x1+dax, y1+day, x2+dax, y2+day, objtype);
+            }
+            else if (wal->nextsector>=0)
+            {
+                for (i=clipsectnum-1; i>=0; i--)
+                    if (wal->nextsector == clipsectorlist[i]) break;
+                if (i < 0) clipsectorlist[clipsectnum++] = wal->nextsector;
+            }
+        }
+
+        ////////// Sprites //////////
+
+        if (dasprclipmask==0)
+            continue;
+
+#ifdef HAVE_CLIPSHAPE_FEATURE
+        if (curspr)
+            continue;  // next sector of this index
+#endif
+        for (j=headspritesect[dasect]; j>=0; j=nextspritesect[j])
+        {
+            const spritetype *const spr = &sprite[j];
+            const int32_t cstat = spr->cstat;
+
+            if ((cstat&dasprclipmask) == 0)
+                continue;
+
+#ifdef HAVE_CLIPSHAPE_FEATURE
+            if (clipsprite_try(spr, xmin, ymin, xmax, ymax))
+                continue;
+#endif
+            x1 = spr->x; y1 = spr->y;
+
+            switch (cstat&48)
+            {
+            case 0:
+                if (x1 >= xmin && x1 <= xmax && y1 >= ymin && y1 <= ymax)
+                {
+                    const int32_t daz = spr->z + spriteheightofs(j, &k, 1);
+
+                    if (pos->z > daz-k-flordist && pos->z < daz+ceildist)
+                    {
+                        int32_t bsz;
+                        bsz = (spr->clipdist<<2)+walldist; if (gx < 0) bsz = -bsz;
+                        addclipline(x1-bsz, y1-bsz, x1-bsz, y1+bsz, (int16_t) j+49152);
+                        bsz = (spr->clipdist<<2)+walldist; if (gy < 0) bsz = -bsz;
+                        addclipline(x1+bsz, y1-bsz, x1-bsz, y1-bsz, (int16_t) j+49152);
+                    }
+                }
+                break;
+
+            case 16:
+            {
+                const int32_t daz = spr->z + spriteheightofs(j, &k, 1);
+
+                if (pos->z > daz-k-flordist && pos->z < daz+ceildist)
+                {
+                    get_wallspr_points(spr, &x1, &x2, &y1, &y2);
+
+                    if (clipinsideboxline(cx, cy, x1, y1, x2, y2, rad) != 0)
+                    {
+                        dax = mulscale14(sintable[(spr->ang+256+512)&2047], walldist);
+                        day = mulscale14(sintable[(spr->ang+256)&2047], walldist);
+
+                        if ((x1-(pos->x))*(y2-(pos->y)) >= (x2-(pos->x))*(y1-(pos->y)))   //Front
+                        {
+                            addclipline(x1+dax, y1+day, x2+day, y2-dax, (int16_t) j+49152);
+                        }
+                        else
+                        {
+                            if ((cstat&64) != 0) continue;
+                            addclipline(x2-dax, y2-day, x1-day, y1+dax, (int16_t) j+49152);
+                        }
+
+                        //Side blocker
+                        if ((x2-x1)*((pos->x)-x1) + (y2-y1)*((pos->y)-y1) < 0)
+                            addclipline(x1-day, y1+dax, x1+dax, y1+day, (int16_t) j+49152);
+                        else if ((x1-x2)*((pos->x)-x2) + (y1-y2)*((pos->y)-y2) < 0)
+                            addclipline(x2+day, y2-dax, x2-dax, y2-day, (int16_t) j+49152);
+                    }
+                }
+                break;
+            }
+
+            case 32:
+            {
+                if (pos->z > spr->z - flordist && pos->z < spr->z + ceildist)
+                {
+                    if ((cstat&64) != 0)
+                        if ((pos->z > spr->z) == ((cstat&8)==0))
+                            continue;
+
+                    rxi[0] = x1;
+                    ryi[0] = y1;
+                    get_floorspr_points((tspritetype const *) spr, 0, 0, &rxi[0], &rxi[1], &rxi[2], &rxi[3],
+                        &ryi[0], &ryi[1], &ryi[2], &ryi[3]);
+
+                    dax = mulscale14(sintable[(spr->ang-256+512)&2047], walldist);
+                    day = mulscale14(sintable[(spr->ang-256)&2047], walldist);
+
+                    if ((rxi[0]-(pos->x))*(ryi[1]-(pos->y)) < (rxi[1]-(pos->x))*(ryi[0]-(pos->y)))
+                    {
+                        if (clipinsideboxline(cx, cy, rxi[1], ryi[1], rxi[0], ryi[0], rad) != 0)
+                            addclipline(rxi[1]-day, ryi[1]+dax, rxi[0]+dax, ryi[0]+day, (int16_t) j+49152);
+                    }
+                    else if ((rxi[2]-(pos->x))*(ryi[3]-(pos->y)) < (rxi[3]-(pos->x))*(ryi[2]-(pos->y)))
+                    {
+                        if (clipinsideboxline(cx, cy, rxi[3], ryi[3], rxi[2], ryi[2], rad) != 0)
+                            addclipline(rxi[3]+day, ryi[3]-dax, rxi[2]-dax, ryi[2]-day, (int16_t) j+49152);
+                    }
+
+                    if ((rxi[1]-(pos->x))*(ryi[2]-(pos->y)) < (rxi[2]-(pos->x))*(ryi[1]-(pos->y)))
+                    {
+                        if (clipinsideboxline(cx, cy, rxi[2], ryi[2], rxi[1], ryi[1], rad) != 0)
+                            addclipline(rxi[2]-dax, ryi[2]-day, rxi[1]-day, ryi[1]+dax, (int16_t) j+49152);
+                    }
+                    else if ((rxi[3]-(pos->x))*(ryi[0]-(pos->y)) < (rxi[0]-(pos->x))*(ryi[3]-(pos->y)))
+                    {
+                        if (clipinsideboxline(cx, cy, rxi[0], ryi[0], rxi[3], ryi[3], rad) != 0)
+                            addclipline(rxi[0]+dax, ryi[0]+day, rxi[3]+day, ryi[3]-dax, (int16_t) j+49152);
+                    }
+                }
+                break;
+            }
+            }
+        }
+    } while (clipsectcnt < clipsectnum || clipspritecnt < clipspritenum);
+
+#ifdef HAVE_CLIPSHAPE_FEATURE
+    if (curspr)
+    {
+        // restore original map
+        mapinfo_set(NULL, &origmapinfo);
+
+        clipsectnum = origclipsectnum;
+        Bmemcpy(clipsectorlist, origclipsectorlist, clipsectnum*sizeof(clipsectorlist[0]));
+    }
+#endif
+
+    int32_t hitwalls[4], hitwall;
+    int32_t cnt = clipmoveboxtracenum;
+
+    do
+    {
+        int32_t intx=goalx, inty=goaly;
+
+        hitwall = raytrace(pos->x, pos->y, &intx, &inty);
+        if (hitwall >= 0)
+        {
+            const int32_t lx = clipit[hitwall].x2-clipit[hitwall].x1;
+            const int32_t ly = clipit[hitwall].y2-clipit[hitwall].y1;
+            const uint64_t tempull = (int64_t) lx*(int64_t) lx + (int64_t) ly*(int64_t) ly;
+
+            if (tempull > 0 && tempull < INT32_MAX)
+            {
+                tempint2 = (int32_t) tempull;
+
+                tempint1 = (goalx-intx)*lx + (goaly-inty)*ly;
+
+                if ((klabs(tempint1)>>11) < tempint2)
+                    i = divscale20(tempint1, tempint2);
+                else
+                    i = 0;
+                goalx = mulscale20(lx, i)+intx;
+                goaly = mulscale20(ly, i)+inty;
+            }
+
+            tempint1 = dmulscale6(lx, oxvect, ly, oyvect);
+            for (i=cnt+1; i<=clipmoveboxtracenum; i++)
+            {
+                j = hitwalls[i];
+                tempint2 = dmulscale6(clipit[j].x2-clipit[j].x1, oxvect,
+                    clipit[j].y2-clipit[j].y1, oyvect);
+                if ((tempint1^tempint2) < 0)
+                {
+                    updatesector(pos->x, pos->y, sectnum);
+                    return retval;
+                }
+            }
+
+            keepaway(&goalx, &goaly, hitwall);
+            xvect = (goalx-intx)<<14;
+            yvect = (goaly-inty)<<14;
+
+            if (cnt == clipmoveboxtracenum)
+                retval = (uint16_t) clipobjectval[hitwall];
+            hitwalls[cnt] = hitwall;
+        }
+        cnt--;
+
+        pos->x = intx;
+        pos->y = inty;
+    } while ((xvect|yvect) != 0 && hitwall >= 0 && cnt > 0);
+
+    for (j=0; j<clipsectnum; j++)
+        if (inside(pos->x, pos->y, clipsectorlist[j]) == 1)
+        {
+            *sectnum = clipsectorlist[j];
+            return retval;
+        }
+
+    *sectnum = -1; tempint1 = INT32_MAX;
+    for (j=numsectors-1; j>=0; j--)
+        if (inside(pos->x, pos->y, j) == 1)
+        {
+            if (sector[j].ceilingstat&2)
+                tempint2 = getceilzofslope(j, pos->x, pos->y) - pos->z;
+            else
+                tempint2 = sector[j].ceilingz - pos->z;
+
+            if (tempint2 > 0)
+            {
+                if (tempint2 < tempint1)
+                {
+                    *sectnum = j; tempint1 = tempint2;
+                }
+            }
+            else
+            {
+                if (sector[j].floorstat&2)
+                    tempint2 = pos->z - getflorzofslope(j, pos->x, pos->y);
+                else
+                    tempint2 = pos->z - sector[j].floorz;
+
+                if (tempint2 <= 0)
+                {
+                    *sectnum = j;
+                    return retval;
+                }
+                if (tempint2 < tempint1)
+                {
+                    *sectnum = j; tempint1 = tempint2;
+                }
+            }
+        }
+
+    return retval;
+}
+
+
+//
+// pushmove
+//
+int32_t pushmove(vec3_t *vect, int16_t *sectnum,
+    int32_t walldist, int32_t ceildist, int32_t flordist, uint32_t cliptype)
+{
+    int32_t i, j, k, t, dx, dy, dax, day, daz;
+    int32_t dir, bad, bad2;
+
+    const int32_t dawalclipmask = (cliptype&65535);
+    //    const int32_t dasprclipmask = (cliptype>>16);
+
+    if (*sectnum < 0)
+        return -1;
+
+    k = 32;
+    dir = 1;
+    do
+    {
+        int32_t clipsectcnt;
+
+        bad = 0;
+
+        clipsectorlist[0] = *sectnum;
+        clipsectcnt = 0; clipsectnum = 1;
+        do
+        {
+            const walltype *wal;
+            const sectortype *sec;
+            int32_t startwall, endwall;
+#if 0
+            // Push FACE sprites
+            for (i=headspritesect[clipsectorlist[clipsectcnt]]; i>=0; i=nextspritesect[i])
+            {
+                spr = &sprite[i];
+                if (((spr->cstat&48) != 0) && ((spr->cstat&48) != 48)) continue;
+                if ((spr->cstat&dasprclipmask) == 0) continue;
+
+                dax = (vect->x)-spr->x; day = (vect->y)-spr->y;
+                t = (spr->clipdist<<2)+walldist;
+                if ((klabs(dax) < t) && (klabs(day) < t))
+                {
+                    daz = spr->z + spriteheightofs(i, &t, 1);
+                    if (((vect->z) < daz+ceildist) && ((vect->z) > daz-t-flordist))
+                    {
+                        t = (spr->clipdist<<2)+walldist;
+
+                        j = getangle(dax, day);
+                        dx = (sintable[(j+512)&2047]>>11);
+                        dy = (sintable[(j)&2047]>>11);
+                        bad2 = 16;
+                        do
+                        {
+                            vect->x = (vect->x) + dx; vect->y = (vect->y) + dy;
+                            bad2--; if (bad2 == 0) break;
+                        } while ((klabs((vect->x)-spr->x) < t) && (klabs((vect->y)-spr->y) < t));
+                        bad = -1;
+                        k--; if (k <= 0) return(bad);
+                        updatesector(vect->x, vect->y, sectnum);
+                    }
+                }
+            }
+#endif
+            sec = &sector[clipsectorlist[clipsectcnt]];
+            if (dir > 0)
+                startwall = sec->wallptr, endwall = startwall + sec->wallnum;
+            else
+                endwall = sec->wallptr, startwall = endwall + sec->wallnum;
+
+            for (i=startwall, wal=&wall[startwall]; i!=endwall; i+=dir, wal+=dir)
+                if (clipinsidebox(vect->x, vect->y, i, walldist-4) == 1)
+                {
+                    j = 0;
+                    if (wal->nextsector < 0) j = 1;
+                    if (wal->cstat&dawalclipmask) j = 1;
+                    if (j == 0)
+                    {
+                        const sectortype *const sec2 = &sector[wal->nextsector];
+                        int32_t daz2;
+
+                        //Find closest point on wall (dax, day) to (vect->x, vect->y)
+                        dax = wall[wal->point2].x-wal->x;
+                        day = wall[wal->point2].y-wal->y;
+                        daz = dax*((vect->x)-wal->x) + day*((vect->y)-wal->y);
+                        if (daz <= 0)
+                            t = 0;
+                        else
+                        {
+                            daz2 = dax*dax+day*day;
+                            if (daz >= daz2) t = (1<<30); else t = divscale30(daz, daz2);
+                        }
+                        dax = wal->x + mulscale30(dax, t);
+                        day = wal->y + mulscale30(day, t);
+
+
+                        daz = getflorzofslope(clipsectorlist[clipsectcnt], dax, day);
+                        daz2 = getflorzofslope(wal->nextsector, dax, day);
+                        if ((daz2 < daz-(1<<8)) && ((sec2->floorstat&1) == 0))
+                            if (vect->z >= daz2-(flordist-1)) j = 1;
+
+                        daz = getceilzofslope(clipsectorlist[clipsectcnt], dax, day);
+                        daz2 = getceilzofslope(wal->nextsector, dax, day);
+                        if ((daz2 > daz+(1<<8)) && ((sec2->ceilingstat&1) == 0))
+                            if (vect->z <= daz2+(ceildist-1)) j = 1;
+                    }
+
+                    if (j != 0)
+                    {
+                        j = getangle(wall[wal->point2].x-wal->x, wall[wal->point2].y-wal->y);
+                        dx = (sintable[(j+1024)&2047]>>11);
+                        dy = (sintable[(j+512)&2047]>>11);
+                        bad2 = 16;
+                        do
+                        {
+                            vect->x = (vect->x) + dx; vect->y = (vect->y) + dy;
+                            bad2--; if (bad2 == 0) break;
+                        } while (clipinsidebox(vect->x, vect->y, i, walldist-4) != 0);
+                        bad = -1;
+                        k--; if (k <= 0) return(bad);
+                        updatesector(vect->x, vect->y, sectnum);
+                        if (*sectnum < 0) return -1;
+                    }
+                    else
+                    {
+                        for (j=clipsectnum-1; j>=0; j--)
+                            if (wal->nextsector == clipsectorlist[j]) break;
+                        if (j < 0) clipsectorlist[clipsectnum++] = wal->nextsector;
+                    }
+                }
+
+            clipsectcnt++;
+        } while (clipsectcnt < clipsectnum);
+        dir = -dir;
+    } while (bad != 0);
+
+    return(bad);
+}
diff --git a/polymer/eduke32/build/src/engine.c b/polymer/eduke32/build/src/engine.c
index 7f67eee6d..4d92fb0fb 100644
--- a/polymer/eduke32/build/src/engine.c
+++ b/polymer/eduke32/build/src/engine.c
@@ -5,7 +5,6 @@
 // This file has been modified from Ken Silverman's original release
 // by Jonathon Fowler (jf@jonof.id.au)
 
-
 #define ENGINE
 
 #if (PNG_LIBPNG_VER > 10599)
@@ -94,14 +93,6 @@ float debug1, debug2;
 
 int32_t mapversion=7; // JBF 20040211: default mapversion to 7
 int32_t g_loadedMapVersion = -1;  // -1: none (e.g. started new)
-usermaphack_t g_loadedMapHack;  // used only for the MD4 part
-
-int32_t compare_usermaphacks(const void *a, const void *b)
-{
-    return Bmemcmp(((usermaphack_t const *) a)->md4, ((usermaphack_t const *) b)->md4, 16);
-}
-usermaphack_t *usermaphacks;
-int32_t num_usermaphacks;
 
 static int32_t get_mapversion(void);
 
@@ -236,11 +227,6 @@ int32_t showfirstwall=0;
 int32_t showheightindicators=1;
 int32_t circlewall=-1;
 
-#ifdef POLYMER
-static int16_t maphacklightcnt=0;
-static int16_t maphacklight[PR_MAXLIGHTS];
-#endif
-
 // forward refs
 #ifdef __cplusplus
 extern "C" {
@@ -1246,562 +1232,6 @@ void setslope(int32_t sectnum, int32_t cf, int16_t slope)
     }
 }
 
-////// sector-like clipping for sprites //////
-#ifdef HAVE_CLIPSHAPE_FEATURE
-typedef struct
-{
-    int16_t numsectors, numwalls;
-    tsectortype *sector;
-    twalltype *wall;
-} mapinfo_t;
-
-static void mapinfo_set(mapinfo_t *bak, mapinfo_t *newmap)
-{
-    if (bak)
-    {
-        bak->numsectors = numsectors;
-        bak->numwalls = numwalls;
-        bak->sector = (tsectortype *)sector;
-        bak->wall = (twalltype *)wall;
-    }
-
-    if (newmap)
-    {
-        numsectors = newmap->numsectors;
-        numwalls = newmap->numwalls;
-        sector = (sectortype *)newmap->sector;
-        wall = (walltype *)newmap->wall;
-    }
-}
-
-static mapinfo_t origmapinfo, clipmapinfo;
-static int32_t quickloadboard=0;
-
-#define CM_MAX 256  // must be a power of 2
-
-typedef struct
-{
-    int16_t qbeg, qend;  // indices into sectq
-    int16_t picnum, next;
-    int32_t maxdist;
-} clipinfo_t;
-
-static int32_t numclipmaps;
-static clipinfo_t clipinfo[CM_MAX];
-
-static int32_t numclipsects;  // number in sectq[]
-static int16_t *sectoidx, *sectq;  // [numsectors]
-static int16_t pictoidx[MAXTILES];  // maps tile num to clipinfo[] index
-static int16_t *tempictoidx;
-
-static tsectortype *loadsector;
-static twalltype *loadwall, *loadwallinv;
-static tspritetype *loadsprite;
-
-// sectoidx bits
-#undef CM_NONE
-#define CM_NONE (CM_MAX<<1)
-#define CM_SOME (CM_NONE-1)
-#define CM_OUTER (CM_MAX)   // sector surrounds clipping sector
-
-// sprite -> sector tag mappings
-#define CM_XREPEAT floorpal
-#define CM_YREPEAT floorxpanning
-#define CM_XOFFSET ceilingshade
-#define CM_YOFFSET floorshade
-#define CM_CSTAT hitag
-#define CM_ANG extra
-#define CM_FLOORZ(Sec) (*(int32_t *)&sector[Sec].ceilingxpanning)  // ceilingxpanning,ceilingypanning,floorpicnum
-#define CM_CEILINGZ(Sec) (*(int32_t *)&sector[Sec].visibility)  // visibility,fogpal,lotag
-
-// backup of original normalized coordinates
-#define CM_WALL_X(Wal) (*(int32_t *)&wall[Wal].picnum)  // picnum, overpicnum
-#define CM_WALL_Y(Wal) (*(int32_t *)&wall[Wal].lotag)  // lotag, hitag
-
-// don't rotate when applying clipping, for models with rotational symmetry
-#define CM_NOROT(Spri) (sprite[Spri].cstat&2)
-#define CM_NOROTS(Sect) (sector[Sect].CM_CSTAT&2)
-
-
-static void clipmapinfo_init()
-{
-    numclipmaps = 0;
-    numclipsects = 0;
-
-    DO_FREE_AND_NULL(sectq);
-    DO_FREE_AND_NULL(sectoidx);
-    DO_FREE_AND_NULL(tempictoidx);
-    DO_FREE_AND_NULL(loadsector);
-    DO_FREE_AND_NULL(loadwall);
-    DO_FREE_AND_NULL(loadwallinv);
-    DO_FREE_AND_NULL(loadsprite);
-
-    // two's complement trick, -1 = 0xff
-    Bmemset(&pictoidx, -1, sizeof(pictoidx));
-    Bmemset(&clipmapinfo, 0, sizeof(mapinfo_t));
-
-    numsectors = 0;
-    numwalls = 0;
-}
-
-// loads the clip maps.
-// this should be called before any real map is loaded.
-int32_t clipmapinfo_load(void)
-{
-    int32_t i,k,w;
-
-    int32_t lwcp = 0;
-    int32_t fi;
-
-    int32_t *fisec = NULL;
-    int32_t *fispr = NULL;
-
-    int32_t ournumsectors=0, ournumwalls=0, ournumsprites=0;
-
-    clipmapinfo_init();
-
-    loadsector = (tsectortype *)Xmalloc(MAXSECTORS * sizeof(sectortype));
-    loadwall = (twalltype *)Xmalloc(MAXWALLS * sizeof(walltype));
-    loadsprite = (tspritetype *)Xmalloc(MAXSPRITES * sizeof(spritetype));
-
-    if (g_clipMapFilesNum)
-        fisec = (int32_t *)Xcalloc(g_clipMapFilesNum, sizeof (int32_t));
-    if (g_clipMapFilesNum)
-        fispr = (int32_t *)Xcalloc(g_clipMapFilesNum, sizeof (int32_t));
-
-    quickloadboard = 1;
-    for (fi = 0; fi < g_clipMapFilesNum; ++fi)
-    {
-        int16_t ang,cs;
-        vec3_t tmppos;
-
-        fisec[fi] = ournumsectors;
-        fispr[fi] = ournumsprites;
-
-        i = loadboard(g_clipMapFiles[fi], 8, &tmppos, &ang, &cs);
-        if (i<0)
-            continue;
-        // Numsprites will now be set!
-
-        initprintf("Loading clip map: %s\n", g_clipMapFiles[fi]);
-
-        if (ournumsectors+numsectors>MAXSECTORS ||
-                ournumwalls+numwalls>MAXWALLS ||
-                ournumsprites+Numsprites>MAXSPRITES)
-        {
-            initprintf("clip map: warning: exceeded limits when loading %s, aborting.\n", g_clipMapFiles[fi]);
-            break;
-        }
-
-        Bmemcpy(loadsector+ournumsectors, sector, numsectors*sizeof(sectortype));
-        Bmemcpy(loadwall+ournumwalls, wall, numwalls*sizeof(walltype));
-        Bmemcpy(loadsprite+ournumsprites, sprite, Numsprites*sizeof(spritetype));
-        for (i=ournumsectors; i<ournumsectors+numsectors; i++)
-            loadsector[i].wallptr += ournumwalls;
-        for (i=ournumwalls; i<ournumwalls+numwalls; i++)
-        {
-            if (loadwall[i].point2>=0)
-                loadwall[i].point2 += ournumwalls;
-            if (loadwall[i].nextwall>=0)
-            {
-                loadwall[i].nextwall += ournumwalls;
-                loadwall[i].nextsector += ournumsectors;
-            }
-        }
-        for (i=ournumsprites; i<ournumsprites+Numsprites; i++)
-            if (loadsprite[i].sectnum>=0)
-                loadsprite[i].sectnum += ournumsectors;
-        ournumsectors += numsectors;
-        ournumwalls += numwalls;
-        ournumsprites += Numsprites;
-
-        ++lwcp;
-    }
-    quickloadboard = 0;
-
-    if (ournumsectors==0 || ournumwalls==0 || ournumsprites==0)  // nothing loaded
-    {
-        clipmapinfo_init();
-
-        Bfree(fisec);
-        Bfree(fispr);
-
-        return -1;
-    }
-
-    // shrink
-    loadsector = (tsectortype *)Xrealloc(loadsector, ournumsectors*sizeof(sectortype));
-    loadwall = (twalltype *)Xrealloc(loadwall, ournumwalls*sizeof(walltype));
-
-    Bmemcpy(sector, loadsector, ournumsectors*sizeof(sectortype));
-    Bmemcpy(wall, loadwall, ournumwalls*sizeof(walltype));
-    Bmemcpy(sprite, loadsprite, ournumsprites*sizeof(spritetype));
-    numsectors = ournumsectors;
-    numwalls = ournumwalls;
-
-    //  vvvv    don't use headsprite[sect,stat]!   vvvv
-
-    sectoidx = (int16_t *)Xmalloc(numsectors*sizeof(sectoidx[0]));
-
-    for (i=0; i<numsectors; i++)
-        sectoidx[i] = CM_NONE;
-
-    // determine outer sectors
-    for (i=0; i<numsectors; i++)
-    {
-        for (w=sector[i].wallptr; w<sector[i].wallptr+sector[i].wallnum; w++)
-            if (wall[w].nextsector<0)
-            {
-                sectoidx[i] = CM_OUTER;
-                break;
-            }
-    }
-    // break connections between outer sectors
-    for (i=0; i<numsectors; i++)
-    {
-        if (sectoidx[i] == CM_OUTER)
-            for (w=sector[i].wallptr; w<sector[i].wallptr+sector[i].wallnum; w++)
-            {
-                k = wall[w].nextwall;
-                if (k>=0 && sectoidx[wall[w].nextsector]==CM_OUTER)
-                {
-                    wall[k].nextwall = wall[k].nextsector = -1;
-                    wall[w].nextwall = wall[w].nextsector = -1;
-                }
-            }
-    }
-
-    {
-        int16_t ns, outersect;
-        int32_t pn,scnt, x,y,z, maxdist;
-
-        sectq = (int16_t *)Xmalloc(numsectors*sizeof(sectq[0]));
-        tempictoidx = (int16_t *)Xmalloc(MAXTILES*sizeof(tempictoidx[0]));
-
-        for (i=0; i<MAXTILES; i++)
-            tempictoidx[i]=-1;
-
-        // collect sprite picnums
-        for (i=0; i<MAXSPRITES && sprite[i].statnum<MAXSTATUS; i++)
-        {
-            pn = sprite[i].picnum;
-            k = sprite[i].sectnum;
-            //    -v-  note the <=                         ignore sprites in outer sectors
-            if (pn<=0 || pn>=MAXTILES || k<0 || k>=numsectors || (sectoidx[k]&CM_OUTER))
-                continue;
-
-            if (numclipmaps >= CM_MAX)
-            {
-                initprintf("warning: reached max clip map number %d, not processing any more\n", CM_MAX);
-                break;
-            }
-
-            // chain
-            if (pictoidx[pn]>=0)
-            {
-                if (sectoidx[k]&CM_SOME)
-                {
-                    for (fi = 0; fi < g_clipMapFilesNum; ++fi)
-                        if (k>=fisec[fi])
-                            break;
-                    initprintf("clip map \"%s\": error: tried to chain picnum %d (sprite %d) in sector %d which"
-                               " already belongs to picnum %d.\n", g_clipMapFiles[fi], pn, i-fispr[fi], k-fisec[fi],
-                               clipinfo[sectoidx[k]].picnum);
-                    clipmapinfo_init();
-
-                    Bfree(fisec);
-                    Bfree(fispr);
-
-                    return 2;
-                }
-
-                // new one is front
-                clipinfo[numclipmaps].next = pictoidx[pn];
-                pictoidx[pn] = numclipmaps;
-            }
-            else
-            {
-                clipinfo[numclipmaps].next = -1;
-                pictoidx[pn] = numclipmaps;
-            }
-
-            if (!CM_NOROT(i))
-            {
-                if (sprite[i].ang!=1536 && sprite[i].ang!=512)
-                {
-                    for (fi = 0; fi < g_clipMapFilesNum; ++fi)
-                        if (i>=fispr[fi])
-                            break;
-                    initprintf("clip map \"%s\": warning: sprite %d pointing neither northward nor southward. %s will be wrong.\n",
-                               g_clipMapFiles[fi], i-fispr[fi], (sprite[i].cstat&48)==32 ? "Scaling and flipping" : "X-flipping");
-                }
-            }
-
-            clipinfo[numclipmaps].picnum = pn;
-
-            // collect sectors
-            scnt = numclipsects;
-            sectq[numclipsects++] = k;
-            sectoidx[k] = numclipmaps;
-
-            clipinfo[numclipmaps].qbeg = scnt;
-
-            outersect = -1;
-
-            do
-            {
-                k = sectq[scnt];
-
-                for (w=sector[k].wallptr; w<sector[k].wallptr+sector[k].wallnum; w++)
-                {
-                    ns = wall[w].nextsector;
-                    if (ns>=0)
-                    {
-                        if (sectoidx[ns]==CM_NONE)
-                        {
-                            sectoidx[ns] = numclipmaps;
-                            sectq[numclipsects++] = ns;
-                        }
-                        else if (sectoidx[ns]&CM_OUTER)
-                        {
-                            if (outersect>=0 && ns!=outersect)
-                            {
-                                for (fi = 0; fi < g_clipMapFilesNum; ++fi)
-                                    if (ns>=fisec[fi])
-                                        break;
-                                initprintf("clip map \"%s\": error: encountered more than one outer sector (%d and %d)"
-                                           " for sprite %d.\n", g_clipMapFiles[fi], outersect-fisec[fi], ns-fisec[fi], i-fispr[fi]);
-                                clipmapinfo_init();
-
-                                Bfree(fisec);
-                                Bfree(fispr);
-
-                                return 3;
-                            }
-
-                            outersect = ns;
-                            sectoidx[outersect] |= numclipmaps;
-                        }
-                        else if (sectoidx[ns]!=numclipmaps)
-                        {
-                            for (fi = 0; fi < g_clipMapFilesNum; ++fi)
-                                if (ns>=fisec[fi])
-                                    break;
-                            initprintf("clip map \"%s\": error: encountered sector %d belonging to index %d"
-                                       " while collecting sectors for sprite %d (index %d).\n",
-                                       g_clipMapFiles[fi], ns-fisec[fi], sectoidx[ns], i-fispr[fi], numclipmaps);
-                            clipmapinfo_init();
-
-                            Bfree(fisec);
-                            Bfree(fispr);
-
-                            return 4;
-                        }
-                    }
-                }
-            }
-            while (++scnt < numclipsects);
-
-            if (outersect==-1)
-            {
-                initprintf("clip map: INTERNAL ERROR: outersect==-1!\n");
-                clipmapinfo_init();
-
-                Bfree(fisec);
-                Bfree(fispr);
-
-                return 5;
-            }
-
-            sectq[numclipsects++] = outersect;  // last is outer
-            clipinfo[numclipmaps].qend = numclipsects-1;
-
-            // normalize
-            maxdist = 0;
-
-            for (scnt=clipinfo[numclipmaps].qbeg; scnt<=clipinfo[numclipmaps].qend; scnt++)
-            {
-                k = sectq[scnt];
-
-                x = sprite[i].x;
-                y = sprite[i].y;
-                z = sprite[i].z;
-
-                sector[k].floorz -= z;
-                sector[k].ceilingz -= z;
-
-                if (scnt==clipinfo[numclipmaps].qbeg)
-                {
-                    // backup sprite tags since we'll discard sprites later
-                    sector[k].CM_XREPEAT = sprite[i].xrepeat;
-                    sector[k].CM_YREPEAT = sprite[i].yrepeat;
-                    sector[k].CM_XOFFSET = sprite[i].xoffset;
-                    sector[k].CM_YOFFSET = sprite[i].yoffset;
-                    sector[k].CM_CSTAT = sprite[i].cstat;
-                    sector[k].CM_ANG = sprite[i].ang;
-                }
-
-                // backup floor and ceiling z
-                CM_FLOORZ(k) = sector[k].floorz;
-                CM_CEILINGZ(k) = sector[k].ceilingz;
-
-                for (w=sector[k].wallptr; w<sector[k].wallptr+sector[k].wallnum; w++)
-                {
-                    wall[w].x -= x;
-                    wall[w].y -= y;
-
-                    if (scnt!=clipinfo[numclipmaps].qend)
-                    {
-                        if (CM_NOROT(i))
-                        {
-                            if (klabs(wall[w].x) > maxdist)
-                                maxdist = klabs(wall[w].x);
-                            if (klabs(wall[w].y) > maxdist)
-                                maxdist = klabs(wall[w].y);
-                        }
-                        else
-                        {
-                            int32_t tmp = ksqrt(uhypsq(wall[w].x, wall[w].y));
-                            if (tmp > maxdist)
-                                maxdist = tmp;
-                        }
-                    }
-
-                    // aliasing
-                    if (wall[w].lotag>0 || wall[w].hitag>0)
-                    {
-                        int32_t ii;
-
-                        if (wall[w].lotag>0 && wall[w].hitag>0)
-                        {
-                            if (wall[w].lotag > wall[w].hitag)
-                                swapshort(&wall[w].lotag, &wall[w].hitag);
-
-                            for (ii=wall[w].lotag; ii<wall[w].hitag; ii++)
-                                tempictoidx[ii] = numclipmaps;
-                        }
-                        else if (wall[w].lotag>0)
-                        {
-                            if (wall[w].lotag<MAXTILES)
-                                tempictoidx[wall[w].lotag] = numclipmaps;
-                        }
-                        else
-                        {
-                            if (wall[w].hitag<MAXTILES)
-                                tempictoidx[wall[w].hitag] = numclipmaps;
-                        }
-                    }
-
-                    CM_WALL_X(w) = wall[w].x;
-                    CM_WALL_Y(w) = wall[w].y;
-                }
-            }
-
-            clipinfo[numclipmaps].maxdist = maxdist;
-            numclipmaps++;
-        }
-    }
-
-    // yes, too much copying, but better than ugly code
-    Bmemcpy(loadsector, sector, ournumsectors*sizeof(sectortype));
-    Bmemcpy(loadwall, wall, ournumwalls*sizeof(walltype));
-
-    // loadwallinv will contain all walls with inverted orientation for x/y-flip handling
-    loadwallinv = (twalltype *)Xmalloc(ournumwalls*sizeof(walltype));
-
-    {
-        int32_t j, loopstart, loopend, numloopwalls;
-
-        // invert walls!
-        loopstart = 0;
-        for (j=0; j<ournumwalls; j++)
-        {
-            wall[j].nextsector = wall[j].nextwall = -1;
-
-            if (wall[j].point2 < j)
-            {
-                loopend = j+1;
-                numloopwalls = loopend-loopstart;
-
-                if (numloopwalls<3)
-                {
-                    loopstart = loopend;
-                    continue;
-                }
-
-                for (k=0; k<numloopwalls; k++)
-                {
-                    wall[loopstart+k].x = loadwall[loopstart + (numloopwalls+1-k)%numloopwalls].x;
-                    wall[loopstart+k].y = loadwall[loopstart + (numloopwalls+1-k)%numloopwalls].y;
-
-                    CM_WALL_X(loopstart+k) = wall[loopstart+k].x;
-                    CM_WALL_Y(loopstart+k) = wall[loopstart+k].y;
-                }
-
-                loopstart = loopend;
-            }
-        }
-
-        // reconstruct wall connections
-        for (i=0; i<ournumsectors; i++)
-        {
-            for (j=sector[i].wallptr; j<sector[i].wallptr+sector[i].wallnum; j++)
-                checksectorpointer(j, i);
-        }
-    }
-    Bmemcpy(loadwallinv, wall, ournumwalls*sizeof(walltype));
-
-    clipmapinfo.numsectors = numsectors;
-    clipmapinfo.sector = loadsector;
-    clipmapinfo.numwalls = numwalls;
-    clipmapinfo.wall = loadwall;
-
-    for (i=0; i<MAXTILES; i++)
-    {
-        if (pictoidx[i]==-1 && tempictoidx[i]>=0)
-            pictoidx[i]=tempictoidx[i];
-    }
-
-    DO_FREE_AND_NULL(loadsprite);
-    DO_FREE_AND_NULL(tempictoidx);
-
-    // don't let other code be distracted by the temporary map we constructed
-    numsectors = 0;
-    numwalls = 0;
-    initspritelists();
-
-    if (lwcp > 0)
-        initprintf("Loaded clip map%s.\n", lwcp==1?"":"s");
-
-    Bfree(fisec);
-    Bfree(fispr);
-
-    return 0;
-}
-
-
-int32_t clipshape_idx_for_sprite(spritetype *curspr, int32_t curidx)
-{
-    if (curidx < 0)  // per-sprite init
-        curidx = pictoidx[curspr->picnum];
-    else
-        curidx = clipinfo[curidx].next;
-
-    while (curidx>=0 && (curspr->cstat&32) != (sector[sectq[clipinfo[curidx].qbeg]].CM_CSTAT&32))
-        curidx = clipinfo[curidx].next;
-
-    return curidx;
-}
-#else
-int32_t clipshape_idx_for_sprite(spritetype *curspr, int32_t curidx)
-{
-    UNREFERENCED_PARAMETER(curspr);
-    UNREFERENCED_PARAMETER(curidx);
-    return -1;
-}
-#endif  // HAVE_CLIPSHAPE_FEATURE
-////// //////
-
 #define WALLS_ARE_CONSISTENT(k) ((wall[k].x == x2 && wall[k].y == y2)   \
                                  && ((wall[wall[k].point2]).x == x1 && (wall[wall[k].point2]).y == y1))
 
@@ -1963,245 +1393,6 @@ int32_t checksectorpointer(int16_t i, int16_t sectnum)
 
 #undef WALLS_ARE_CONSISTENT
 
-
-#if defined(_MSC_VER) && !defined(NOASM)
-
-//
-// Microsoft C Inline Assembly Routines
-//
-
-static inline int32_t nsqrtasm(int32_t a)
-{
-    _asm
-    {
-        push ebx
-        mov eax, a
-        test eax, 0xff000000
-        mov ebx, eax
-        jnz short over24
-        shr ebx, 12
-        mov cx, word ptr shlookup[ebx*2]
-        jmp short under24
-        over24:
-        shr ebx, 24
-        mov cx, word ptr shlookup[ebx*2+8192]
-        under24:
-        shr eax, cl
-        mov cl, ch
-        mov ax, word ptr sqrtable[eax*2]
-        shr eax, cl
-        pop ebx
-    }
-}
-
-static inline int32_t msqrtasm(int32_t c)
-{
-    _asm
-    {
-        push ebx
-        mov ecx, c
-        mov eax, 0x40000000
-        mov ebx, 0x20000000
-        begit:
-        cmp ecx, eax
-        jl skip
-        sub ecx, eax
-        lea eax, [eax+ebx*4]
-        skip:
-        sub eax, ebx
-        shr eax, 1
-        shr ebx, 2
-        jnz begit
-        cmp ecx, eax
-        sbb eax, -1
-        shr eax, 1
-        pop ebx
-    }
-}
-
-static inline int32_t getclipmask(int32_t a, int32_t b, int32_t c, int32_t d)
-{
-    _asm
-    {
-        push ebx
-        mov eax, a
-        mov ebx, b
-        mov ecx, c
-        mov edx, d
-        sar eax, 31
-        add ebx, ebx
-        adc eax, eax
-        add ecx, ecx
-        adc eax, eax
-        add edx, edx
-        adc eax, eax
-        mov ebx, eax
-        shl ebx, 4
-        or al, 0xf0
-        xor eax, ebx
-        pop ebx
-    }
-}
-
-static inline int32_t getkensmessagecrc(void *b)
-{
-    _asm
-    {
-        push ebx
-        mov ebx, b
-        xor eax, eax
-        mov ecx, 32
-        beg:
-        mov edx, dword ptr [ebx+ecx*4-4]
-        ror edx, cl
-        adc eax, edx
-        bswap eax
-        loop short beg
-        pop ebx
-    }
-}
-
-#elif defined(__GNUC__) && defined(__i386__) && !defined(NOASM)	// _MSC_VER
-
-//
-// GCC "Inline" Assembly Routines
-//
-
-#define nsqrtasm(a) \
-    ({ int32_t __r, __a=(a); \
-       __asm__ __volatile__ ( \
-        "testl $0xff000000, %%eax\n\t" \
-        "movl %%eax, %%ebx\n\t" \
-        "jnz 0f\n\t" \
-        "shrl $12, %%ebx\n\t" \
-        "movw " ASMSYM("shlookup") "(,%%ebx,2), %%cx\n\t" \
-        "jmp 1f\n\t" \
-        "0:\n\t" \
-        "shrl $24, %%ebx\n\t" \
-        "movw (" ASMSYM("shlookup") "+8192)(,%%ebx,2), %%cx\n\t" \
-        "1:\n\t" \
-        "shrl %%cl, %%eax\n\t" \
-        "movb %%ch, %%cl\n\t" \
-        "movw " ASMSYM("sqrtable") "(,%%eax,2), %%ax\n\t" \
-        "shrl %%cl, %%eax" \
-        : "=a" (__r) : "a" (__a) : "ebx", "ecx", "cc"); \
-     __r; })
-
-// edx is blown by this code somehow?!
-#define msqrtasm(c) \
-    ({ int32_t __r, __c=(c); \
-       __asm__ __volatile__ ( \
-        "movl $0x40000000, %%eax\n\t" \
-        "movl $0x20000000, %%ebx\n\t" \
-        "0:\n\t" \
-        "cmpl %%eax, %%ecx\n\t" \
-        "jl 1f\n\t" \
-        "subl %%eax, %%ecx\n\t" \
-        "leal (%%eax,%%ebx,4), %%eax\n\t" \
-        "1:\n\t" \
-        "subl %%ebx, %%eax\n\t" \
-        "shrl $1, %%eax\n\t" \
-        "shrl $2, %%ebx\n\t" \
-        "jnz 0b\n\t" \
-        "cmpl %%eax, %%ecx\n\t" \
-        "sbbl $-1, %%eax\n\t" \
-        "shrl $1, %%eax" \
-        : "=a" (__r) : "c" (__c) : "edx","ebx", "cc"); \
-     __r; })
-
-#define getclipmask(a,b,c,d) \
-    ({ int32_t __a=(a), __b=(b), __c=(c), __d=(d); \
-       __asm__ __volatile__ ("sarl $31, %%eax; addl %%ebx, %%ebx; adcl %%eax, %%eax; " \
-                "addl %%ecx, %%ecx; adcl %%eax, %%eax; addl %%edx, %%edx; " \
-                "adcl %%eax, %%eax; movl %%eax, %%ebx; shl $4, %%ebx; " \
-                "orb $0xf0, %%al; xorl %%ebx, %%eax" \
-        : "=a" (__a), "=b" (__b), "=c" (__c), "=d" (__d) \
-        : "a" (__a), "b" (__b), "c" (__c), "d" (__d) : "cc"); \
-     __a; })
-
-
-#define getkensmessagecrc(b) \
-    ({ int32_t __a, __b=(b); \
-       __asm__ __volatile__ ( \
-        "xorl %%eax, %%eax\n\t" \
-        "movl $32, %%ecx\n\t" \
-        "0:\n\t" \
-        "movl -4(%%ebx,%%ecx,4), %%edx\n\t" \
-        "rorl %%cl, %%edx\n\t" \
-        "adcl %%edx, %%eax\n\t" \
-        "bswapl %%eax\n\t" \
-        "loop 0b" \
-        : "=a" (__a) : "b" (__b) : "ecx", "edx" \
-     __a; })
-
-#else   // __GNUC__ && __i386__
-
-static inline int32_t nsqrtasm(uint32_t a)
-{
-    // JBF 20030901: This was a damn lot simpler to reverse engineer than
-    // msqrtasm was. Really, it was just like simplifying an algebra equation.
-    uint16_t c;
-
-    if (a & 0xff000000)  			// test eax, 0xff000000  /  jnz short over24
-    {
-        c = shlookup[(a >> 24) + 4096];	// mov ebx, eax
-        // over24: shr ebx, 24
-        // mov cx, word ptr shlookup[ebx*2+8192]
-    }
-    else
-    {
-        c = shlookup[a >> 12];		// mov ebx, eax
-        // shr ebx, 12
-        // mov cx, word ptr shlookup[ebx*2]
-        // jmp short under24
-    }
-    a >>= c&0xff;				// under24: shr eax, cl
-    a = (a&0xffff0000)|(sqrtable[a]);	// mov ax, word ptr sqrtable[eax*2]
-    a >>= ((c&0xff00) >> 8);		// mov cl, ch
-    // shr eax, cl
-    return a;
-}
-
-static inline int32_t msqrtasm(uint32_t c)
-{
-    uint32_t a,b;
-
-    a = 0x40000000l;		// mov eax, 0x40000000
-    b = 0x20000000l;		// mov ebx, 0x20000000
-    do  				// begit:
-    {
-        if (c >= a)  		// cmp ecx, eax	 /  jl skip
-        {
-            c -= a;		// sub ecx, eax
-            a += b*4;	// lea eax, [eax+ebx*4]
-        }			// skip:
-        a -= b;			// sub eax, ebx
-        a >>= 1;		// shr eax, 1
-        b >>= 2;		// shr ebx, 2
-    }
-    while (b);			// jnz begit
-    if (c >= a)			// cmp ecx, eax
-        a++;			// sbb eax, -1
-    a >>= 1;			// shr eax, 1
-    return a;
-}
-
-static inline int32_t getclipmask(int32_t a, int32_t b, int32_t c, int32_t d)
-{
-    // Ken did this
-    d = ((a<0)<<3) + ((b<0)<<2) + ((c<0)<<1) + (d<0);
-    return(((d<<4)^0xf0)|d);
-}
-
-inline int32_t getkensmessagecrc(int32_t b)
-{
-    UNREFERENCED_PARAMETER(b);
-    return 0x56c764d4l;
-}
-
-#endif
-
-
 int32_t xb1[MAXWALLSB];  // Polymost uses this as a temp array
 static int32_t yb1[MAXWALLSB], xb2[MAXWALLSB], yb2[MAXWALLSB];
 int32_t rx1[MAXWALLSB], ry1[MAXWALLSB];
@@ -2232,7 +1423,8 @@ intptr_t frameoffset;
 
 static int32_t nrx1[8], nry1[8], nrx2[8], nry2[8]; // JBF 20031206: Thanks Ken
 
-static int32_t rxi[8], ryi[8], rzi[8], rxi2[8], ryi2[8], rzi2[8];
+int32_t rxi[8], ryi[8];
+static int32_t rzi[8], rxi2[8], ryi2[8], rzi2[8];
 static int32_t xsi[8], ysi[8], horizycent;
 static int32_t *horizlookup=0, *horizlookup2=0;
 
@@ -2272,21 +1464,11 @@ static int32_t *lastx;
 
 int32_t halfxdim16, midydim16;
 
-static int16_t clipnum;
 static const int32_t hitscangoalx = (1<<29)-1, hitscangoaly = (1<<29)-1;
 #ifdef USE_OPENGL
 int32_t hitallsprites = 0;
 #endif
 
-typedef struct { int32_t x1, y1, x2, y2; } linetype;
-static linetype clipit[MAXCLIPNUM];
-static int32_t clipsectnum, origclipsectnum, clipspritenum;
-static int16_t clipsectorlist[MAXCLIPNUM], origclipsectorlist[MAXCLIPNUM];
-#ifdef HAVE_CLIPSHAPE_FEATURE
-static int16_t clipspritelist[MAXCLIPNUM];  // sector-like sprite clipping
-#endif
-static int16_t clipobjectval[MAXCLIPNUM];
-
 typedef struct
 {
     int32_t sx, sy, z;
@@ -3071,7 +2253,7 @@ static inline void slowhline(int32_t xr, int32_t yp)
 //
 // prepwall (internal)
 //
-static void prepwall(int32_t z, const walltype *wal)
+static void prepwall(int32_t z, const twalltype *wal)
 {
     int32_t l=0, ol=0, x;
 
@@ -3223,17 +2405,17 @@ static inline void wallmosts_finish(int16_t *mostbuf, int32_t z1, int32_t z2,
 typedef int64_t zint_t;
 
 // For drawvox()
-static inline zint_t mulscale16z(int32_t a, int32_t d)
+FORCE_INLINE zint_t mulscale16z(int32_t a, int32_t d)
 {
     return ((zint_t)a * d)>>16;
 }
 
-static inline zint_t mulscale20z(int32_t a, int32_t d)
+FORCE_INLINE zint_t mulscale20z(int32_t a, int32_t d)
 {
     return ((zint_t)a * d)>>20;
 }
 
-static inline zint_t dmulscale24z(int32_t a, int32_t d, int32_t S, int32_t D)
+FORCE_INLINE zint_t dmulscale24z(int32_t a, int32_t d, int32_t S, int32_t D)
 {
     return (((zint_t)a * d) + ((zint_t)S * D)) >> 24;
 }
@@ -3920,29 +3102,23 @@ do_vlineasm1:
 //
 static void transmaskvline(int32_t x)
 {
-    uint32_t vplc;
-    int32_t vinc;
-    intptr_t palookupoffs;
-    intptr_t bufplc,p;
-    int32_t y1v, y2v;
+    if ((unsigned)x >= xdimen) return;
 
-    vec2_t ntsiz;
+    int32_t const y1v = max(uwall[x],startumost[x+windowx1]-windowy1);
+    int32_t const y2v = min(dwall[x],startdmost[x+windowx1]-windowy1) - 1;
 
-    if ((x < 0) || (x >= xdimen)) return;
-
-    y1v = max(uwall[x],startumost[x+windowx1]-windowy1);
-    y2v = min(dwall[x],startdmost[x+windowx1]-windowy1);
-    y2v--;
     if (y2v < y1v) return;
 
-    palookupoffs = FP_OFF(palookup[globalpal]) + getpalookupsh(mulscale16(swall[x],globvis));
+    intptr_t palookupoffs = FP_OFF(palookup[globalpal]) + getpalookupsh(mulscale16(swall[x],globvis));
 
-    ntsiz.x = -tilesiz[globalpicnum].x;
-    ntsiz.y = -tilesiz[globalpicnum].y;
+    vec2_t ntsiz = { -tilesiz[globalpicnum].x, -tilesiz[globalpicnum].y };
+    intptr_t bufplc;
     calc_bufplc(&bufplc, lwall[x], ntsiz);
+    uint32_t vplc;
+    int32_t vinc;
     calc_vplcinc(&vplc, &vinc, swall, x, y1v);
 
-    p = ylookup[y1v]+x+frameoffset;
+    intptr_t p = ylookup[y1v]+x+frameoffset;
 
 #ifdef NONPOW2_YSIZE_ASM
     if (globalshiftval==0)
@@ -3959,17 +3135,11 @@ static void transmaskvline(int32_t x)
 #ifdef MULTI_COLUMN_VLINE
 static void transmaskvline2(int32_t x)
 {
-    int32_t y1, y2, x2;
-    int32_t y1ve[2], y2ve[2];
-
-    uintptr_t p;
-
-    vec2_t ntsiz;
-
-    if ((x < 0) || (x >= xdimen)) return;
+    if ((unsigned)x >= xdimen) return;
     if (x == xdimen-1) { transmaskvline(x); return; }
 
-    x2 = x+1;
+    int32_t y1ve[2], y2ve[2];
+    int32_t x2 = x+1;
 
     y1ve[0] = max(uwall[x],startumost[x+windowx1]-windowy1);
     y2ve[0] = min(dwall[x],startdmost[x+windowx1]-windowy1)-1;
@@ -3983,18 +3153,17 @@ static void transmaskvline2(int32_t x)
 
     setuptvlineasm2(globalshiftval,palookupoffse[0],palookupoffse[1]);
 
-    ntsiz.x = -tilesiz[globalpicnum].x;
-    ntsiz.y = -tilesiz[globalpicnum].y;
+    vec2_t const ntsiz = { -tilesiz[globalpicnum].x, -tilesiz[globalpicnum].y };
 
     calc_bufplc(&bufplce[0], lwall[x], ntsiz);
     calc_bufplc(&bufplce[1], lwall[x2], ntsiz);
     calc_vplcinc(&vplce[0], &vince[0], swall, x, y1ve[0]);
     calc_vplcinc(&vplce[1], &vince[1], swall, x2, y1ve[1]);
 
-    y1 = max(y1ve[0],y1ve[1]);
-    y2 = min(y2ve[0],y2ve[1]);
+    int32_t const y1 = max(y1ve[0],y1ve[1]);
+    int32_t const y2 = min(y2ve[0],y2ve[1]);
 
-    p = x+frameoffset;
+    uintptr_t p = x+frameoffset;
 
     if (y1ve[0] != y1ve[1])
     {
@@ -4030,8 +3199,6 @@ static void transmaskvline2(int32_t x)
 //
 static void transmaskwallscan(int32_t x1, int32_t x2, int32_t saturatevplc)
 {
-    int32_t x;
-
     setgotpic(globalpicnum);
 
     Bassert(globalshiftval>=0 || ((tilesiz[globalpicnum].x <= 0) || (tilesiz[globalpicnum].y <= 0)));
@@ -4043,23 +3210,23 @@ static void transmaskwallscan(int32_t x1, int32_t x2, int32_t saturatevplc)
 
     setuptvlineasm(globalshiftval, saturatevplc);
 
-    x = x1;
+    int32_t x = x1;
     while ((x <= x2) && (startumost[x+windowx1] > startdmost[x+windowx1]))
-        x++;
+        ++x;
 
 #ifndef ENGINE_USING_A_C
     if (globalshiftval==0)
     {
-        while (x <= x2) transmaskvline(x), x++;
+        while (x <= x2) transmaskvline(x++);
     }
     else
 #endif
     {
 #ifdef MULTI_COLUMN_VLINE
-        if ((x <= x2) && (x&1)) transmaskvline(x), x++;
+        if ((x <= x2) && (x&1)) transmaskvline(x++);
         while (x < x2) transmaskvline2(x), x += 2;
 #endif
-        while (x <= x2) transmaskvline(x), x++;
+        while (x <= x2) transmaskvline(x++);
     }
 
     faketimerhandler();
@@ -4080,7 +3247,7 @@ static void transmaskwallscan(int32_t x1, int32_t x2, int32_t saturatevplc)
 
 // cntup16>>16 iterations
 
-static void nonpow2_mhline(intptr_t bufplc, uint32_t bx, int32_t cntup16, int32_t junk, uint32_t by, char *p)
+static void nonpow2_mhline(intptr_t bufplc, uint32_t bx, int32_t cntup16, uint32_t by, char *p)
 {
     char ch;
 
@@ -4092,8 +3259,6 @@ static void nonpow2_mhline(intptr_t bufplc, uint32_t bx, int32_t cntup16, int32_
     const uint32_t yspan = globalyspan;
     const int32_t xinc = asm1, yinc = asm2;
 
-    UNREFERENCED_PARAMETER(junk);
-
     for (cntup16>>=16; cntup16>0; cntup16--)
     {
         ch = buf[(divideu32(bx, xdiv))*yspan + divideu32(by, ydiv)];
@@ -4106,7 +3271,7 @@ static void nonpow2_mhline(intptr_t bufplc, uint32_t bx, int32_t cntup16, int32_
 }
 
 // cntup16>>16 iterations
-static void nonpow2_thline(intptr_t bufplc, uint32_t bx, int32_t cntup16, int32_t junk, uint32_t by, char *p)
+static void nonpow2_thline(intptr_t bufplc, uint32_t bx, int32_t cntup16, uint32_t by, char *p)
 {
     char ch;
 
@@ -4119,8 +3284,6 @@ static void nonpow2_thline(intptr_t bufplc, uint32_t bx, int32_t cntup16, int32_
     const uint32_t yspan = globalyspan;
     const int32_t xinc = asm1, yinc = asm2;
 
-    UNREFERENCED_PARAMETER(junk);
-
     if (globalorientation&512)
     {
         for (cntup16>>=16; cntup16>0; cntup16--)
@@ -4177,9 +3340,9 @@ static void ceilspritehline(int32_t x2, int32_t y)
     else
     {
         if ((globalorientation&2) == 0)
-            nonpow2_mhline(globalbufplc,bx,(x2-x1)<<16,0L,by,(char *)(ylookup[y]+x1+frameoffset));
+            nonpow2_mhline(globalbufplc,bx,(x2-x1)<<16,by,(char *)(ylookup[y]+x1+frameoffset));
         else
-            nonpow2_thline(globalbufplc,bx,(x2-x1)<<16,0L,by,(char *)(ylookup[y]+x1+frameoffset));
+            nonpow2_thline(globalbufplc,bx,(x2-x1)<<16,by,(char *)(ylookup[y]+x1+frameoffset));
     }
 }
 
@@ -4189,12 +3352,10 @@ static void ceilspritehline(int32_t x2, int32_t y)
 //
 static void ceilspritescan(int32_t x1, int32_t x2)
 {
-    int32_t x;
-
     int32_t y1 = uwall[x1];
     int32_t y2 = y1;
 
-    for (x=x1; x<=x2; x++)
+    for (int x=x1; x<=x2; ++x)
     {
         const int32_t twall = uwall[x]-1;
         const int32_t bwall = dwall[x];
@@ -4247,7 +3408,7 @@ static inline void setupslopevlin_alsotrans(int32_t logylogx, intptr_t bufplc, i
 }
 
 // cnt iterations
-static void tslopevlin(uint8_t *p, int32_t i, const intptr_t *slopalptr, int32_t cnt, int32_t bx, int32_t by)
+static void tslopevlin(uint8_t *p, const intptr_t *slopalptr, int32_t cnt, int32_t bx, int32_t by)
 {
     const char *const A_C_RESTRICT buf = ggbuf;
     const char *const A_C_RESTRICT pal = ggpal;
@@ -4262,13 +3423,10 @@ static void tslopevlin(uint8_t *p, int32_t i, const intptr_t *slopalptr, int32_t
 
     do
     {
-        uint8_t ch;
-        uint32_t u, v;
-
-        i = (sloptable[(bz>>6)+8192]); bz += bzinc;
-        u = bx + xtou*i;
-        v = by + ytov*i;
-        ch = *(uint8_t *)(slopalptr[0] + buf[((u>>(32-logx))<<logy)+(v>>(32-logy))]);
+        int const i = (sloptable[(bz>>6)+8192]); bz += bzinc;
+        uint32_t u = bx + xtou*i;
+        uint32_t v = by + ytov*i;
+        uint8_t ch = *(uint8_t *)(slopalptr[0] + buf[((u>>(32-logx))<<logy)+(v>>(32-logy))]);
 
         if (ch != 255)
             *p = trans[transmode ? *p|(pal[ch]<<8) : (*p<<8)|pal[ch]];
@@ -4444,7 +3602,7 @@ static void grouscan(int32_t dax1, int32_t dax2, int32_t sectnum, char dastat)
             if ((globalorientation&256)==0)
                 slopevlin(ylookup[y2]+x+frameoffset,krecipasm(asm3>>3),(intptr_t)nptr2,y2-y1+1,globalx1,globaly1);
             else
-                tslopevlin((uint8_t *)(ylookup[y2]+x+frameoffset),0,nptr2,y2-y1+1,globalx1,globaly1);
+                tslopevlin((uint8_t *)(ylookup[y2]+x+frameoffset),nptr2,y2-y1+1,globalx1,globaly1);
 
             if ((x&15) == 0) faketimerhandler();
         }
@@ -4648,7 +3806,7 @@ static void parascan(int32_t dax1, int32_t dax2, int32_t sectnum, char dastat, i
 
 
 // set orientation, panning, shade, pal; picnum
-static void setup_globals_wall1(const walltype *wal, int32_t dapicnum)
+static void setup_globals_wall1(const twalltype *wal, int32_t dapicnum)
 {
     globalorientation = wal->cstat;
 
@@ -4664,7 +3822,7 @@ static void setup_globals_wall1(const walltype *wal, int32_t dapicnum)
     if (palookup[globalpal] == NULL) globalpal = 0;    // JBF: fixes crash
 }
 
-static void setup_globals_wall2(const walltype *wal, uint8_t secvisibility, int32_t topzref, int32_t botzref)
+static void setup_globals_wall2(const twalltype *wal, uint8_t secvisibility, int32_t topzref, int32_t botzref)
 {
     const int32_t logtilesizy = (picsiz[globalpicnum]>>4);
     const int32_t tsizy = tilesiz[globalpicnum].y;
@@ -4894,7 +4052,7 @@ static void drawalls(int32_t bunch)
         }
 
         const int32_t wallnum = thewall[z];
-        const walltype *const wal = &wall[wallnum];
+        const twalltype *const wal = (twalltype *)&wall[wallnum];
 
         const int32_t nextsectnum = wal->nextsector;
         const sectortype *const nextsec = nextsectnum>=0 ? &sector[nextsectnum] : NULL;
@@ -5067,10 +4225,8 @@ static void drawalls(int32_t bunch)
                             searchstat = 0; searchit = 1;
                         }
 
-                    {
-                        const walltype *twal = (wal->cstat&2) ? &wall[wal->nextwall] : wal;
-                        setup_globals_wall1(twal, twal->picnum);
-                    }
+                    const twalltype *twal = (wal->cstat&2) ? (twalltype *)&wall[wal->nextwall] : wal;
+                    setup_globals_wall1(twal, twal->picnum);
 
                     setup_globals_wall2(wal, sec->visibility, nextsec->floorz, sec->ceilingz);
 
@@ -5083,12 +4239,11 @@ static void drawalls(int32_t bunch)
                         if (should_clip_fwall(x1, x2))
 #endif
                         for (x=x1; x<=x2; x++)
-                            if (uwall[x] < dmost[x])
-                                if (umost[x] <= dmost[x])
-                                {
-                                    dmost[x] = uwall[x];
-                                    if (umost[x] > dmost[x]) numhits--;
-                                }
+                            if (uwall[x] < dmost[x] && umost[x] <= dmost[x])
+                            {
+                                dmost[x] = uwall[x];
+                                if (umost[x] > dmost[x]) numhits--;
+                            }
                     }
                     else
                     {
@@ -5635,27 +4790,24 @@ static uint8_t falpha_to_blend(float alpha, int32_t *cstatptr, int32_t transbit1
     return blendidx;
 }
 
-static inline int32_t mulscale_triple30(int32_t a, int32_t b, int32_t c)
+FORCE_INLINE int32_t mulscale_triple30(int32_t a, int32_t b, int32_t c)
 {
     return ((int64_t)a * b * c)>>30;
 }
 
 static void drawsprite_classic(int32_t snum)
 {
+    tspritetype *const tspr = tspriteptr[snum];
+    const int32_t sectnum = tspr->sectnum;
+
+    if (sectnum < 0 || bad_tspr(tspr))
+        return;
+
     int32_t x1, y1, x2, y2, i, j, k, x;
     int32_t z, zz, z1, z2, xp1, yp1, xp2, yp2;
     int32_t dax, day, dax1, dax2, y;
     int32_t vtilenum = 0;
 
-    tspritetype *const tspr = tspriteptr[snum];
-
-    const int32_t sectnum = tspr->sectnum;
-
-    if (sectnum < 0)
-        return;
-
-    if (bad_tspr(tspr))
-        return;
 
     uint8_t blendidx = tspr->blend;
     const int32_t xb = spritesxyz[snum].x;
@@ -6004,59 +5156,57 @@ draw_as_face_sprite:
         owallmost(uwall, MAXWALLSB-1, z1-globalposz);
         owallmost(dwall, MAXWALLSB-1, z2-globalposz);
 
+        int32_t hplc = divscale19(xdimenscale,sy1);
+        const int32_t hplc2 = divscale19(xdimenscale,sy2);
+        const int32_t idiv = sx2-sx1;
+        int32_t hinc[4] = { idiv ? tabledivide32(hplc2-hplc, idiv) : 0 };
+
+#ifdef HIGH_PRECISION_SPRITE
+        const float cc = ((1<<19)*fxdimen*(float)yxaspect) * (1.f/320.f);
+        const float loopcc = ((cstat&8) ? -1 : 1)*((float)(1<<30)*(1<<24))
+            / (yspan*tspr->yrepeat);
+        float hplcf = cc/sy1;
+        float hincf[4] = {idiv ? (cc/sy2 - hplcf)/idiv : 0};
+
+#ifdef CLASSIC_SLICE_BY_4
+        hincf[1] = hincf[0] * 2.f;
+        hincf[2] = hincf[0] * 3.f;
+        hincf[3] = hincf[0] * 4.f;
+#endif // CLASSIC_SLICE_BY_4
+#endif // HIGH_PRECISION_SPRITE
+#ifdef CLASSIC_SLICE_BY_4
+        hinc[1] = hinc[0]<<1;
+        hinc[2] = hinc[0]*3;
+        hinc[3] = hinc[0]<<2;
+#endif
+        i = sx1;
+
+#ifdef CLASSIC_SLICE_BY_4
+        for (; i<=sx2-4; i+=4)
         {
-            int32_t hplc = divscale19(xdimenscale,sy1);
-            const int32_t hplc2 = divscale19(xdimenscale,sy2);
-            const int32_t idiv = sx2-sx1;
-            int32_t hinc[4] = { idiv ? tabledivide32(hplc2-hplc, idiv) : 0 };
-
+            swall[i] = (krecipasm(hplc)<<2);
+            swall[i+1] = (krecipasm(hplc+hinc[0])<<2);
+            swall[i+2] = (krecipasm(hplc+hinc[1])<<2);
+            swall[i+3] = (krecipasm(hplc+hinc[2])<<2);
+            hplc += hinc[3];
 #ifdef HIGH_PRECISION_SPRITE
-            const float cc = ((1<<19)*fxdimen*(float)yxaspect) * (1.f/320.f);
-            const float loopcc = ((cstat&8) ? -1 : 1)*((float)(1<<30)*(1<<24))
-                / (yspan*tspr->yrepeat);
-            float hplcf = cc/sy1;
-            float hincf[4] = {idiv ? (cc/sy2 - hplcf)/idiv : 0};
-
-#ifdef CLASSIC_SLICE_BY_4
-            hincf[1] = hincf[0] * 2.f;
-            hincf[2] = hincf[0] * 3.f;
-            hincf[3] = hincf[0] * 4.f;
-#endif // CLASSIC_SLICE_BY_4
+            swallf[i] =   loopcc/hplcf;
+            swallf[i+1] = loopcc/(hplcf+hincf[0]);
+            swallf[i+2] = loopcc/(hplcf+hincf[1]);
+            swallf[i+3] = loopcc/(hplcf+hincf[2]);
+            hplcf += hincf[3];
 #endif // HIGH_PRECISION_SPRITE
-#ifdef CLASSIC_SLICE_BY_4
-            hinc[1] = hinc[0]<<1;
-            hinc[2] = hinc[0]*3;
-            hinc[3] = hinc[0]<<2;
-#endif
-            i = sx1;
-
-#ifdef CLASSIC_SLICE_BY_4
-            for (; i<=sx2-4; i+=4)
-            {
-                swall[i] = (krecipasm(hplc)<<2);
-                swall[i+1] = (krecipasm(hplc+hinc[0])<<2);
-                swall[i+2] = (krecipasm(hplc+hinc[1])<<2);
-                swall[i+3] = (krecipasm(hplc+hinc[2])<<2);
-                hplc += hinc[3];
-#ifdef HIGH_PRECISION_SPRITE
-                swallf[i] =   loopcc/hplcf;
-                swallf[i+1] = loopcc/(hplcf+hincf[0]);
-                swallf[i+2] = loopcc/(hplcf+hincf[1]);
-                swallf[i+3] = loopcc/(hplcf+hincf[2]);
-                hplcf += hincf[3];
-#endif // HIGH_PRECISION_SPRITE
-            }
+        }
 #endif // CLASSIC_SLICE_BY_4
 
-            for (; i<=sx2; i++)
-            {
-                swall[i] = (krecipasm(hplc)<<2);
-                hplc += hinc[0];
+        for (; i<=sx2; i++)
+        {
+            swall[i] = (krecipasm(hplc)<<2);
+            hplc += hinc[0];
 #ifdef HIGH_PRECISION_SPRITE
-                swallf[i] = loopcc/hplcf;
-                hplcf += hincf[0];
+            swallf[i] = loopcc/hplcf;
+            hplcf += hincf[0];
 #endif
-            }
         }
 
         for (i=smostwallcnt-1; i>=0; i--)
@@ -6198,8 +5348,6 @@ draw_as_face_sprite:
     }
     else if ((cstat&48) == 32)
     {
-        int32_t bot, cosang, sinang;
-
         if ((cstat&64) != 0)
             if ((globalposz > tspr->z) == ((cstat&8)==0))
                 return;
@@ -6218,7 +5366,8 @@ draw_as_face_sprite:
 
         //Get top-left corner
         i = ((tspr->ang+2048-globalang)&2047);
-        cosang = sintable[(i+512)&2047]; sinang = sintable[i];
+        int32_t cosang = sintable[(i+512)&2047]; 
+        int32_t sinang = sintable[i];
         dax = ((xspan>>1)+xoff)*tspr->xrepeat;
         day = ((yspan>>1)+yoff)*tspr->yrepeat;
         rzi[0] += dmulscale12(sinang,dax,cosang,day);
@@ -6245,7 +5394,7 @@ draw_as_face_sprite:
             { z = 1; z1 = 0; z2 = 2; }
 
         dax = rzi[z1]-rzi[z]; day = rxi[z1]-rxi[z];
-        bot = dmulscale8(dax,dax,day,day);
+        int32_t bot = dmulscale8(dax,dax,day,day);
         if ((klabs(dax)>>13) >= bot || (klabs(day)>>13) >= bot)
             return;
         globalx1 = divscale18(dax,bot);
@@ -6274,7 +5423,6 @@ draw_as_face_sprite:
             i = rzi[1]; rzi[1] = rzi[3]; rzi[3] = i;
         }
 
-
         //Clip polygon in 3-space
         int32_t npoints = 4;
 
@@ -6644,42 +5792,41 @@ draw_as_face_sprite:
 #endif
         if (searchit >= 1 && yp > (4<<8) && (searchy >= lwall[searchx] && searchy < swall[searchx]))
         {
-            const int32_t siz = divscale19(xdimenscale,yp);
-            const int32_t xv = mulscale16(nxrepeat,xyaspect);
+            int32_t const xdsiz = divscale19(xdimenscale,yp);
+            int32_t const xv = mulscale16(nxrepeat,xyaspect);
 
-            const int32_t xspan = ((B_LITTLE32(longptr[0])+B_LITTLE32(longptr[1]))>>1);
-            const int32_t yspan = B_LITTLE32(longptr[2]);
+            int32_t const xspan = ((B_LITTLE32(longptr[0]) + B_LITTLE32(longptr[1])) >> 1);
+            int32_t const yspan = B_LITTLE32(longptr[2]);
 
-            const int32_t xsiz = mulscale_triple30(siz, xv, xspan);
-            const int32_t ysiz = mulscale_triple30(siz, nyrepeat, yspan);
+            vec2_t const siz ={ mulscale_triple30(xdsiz, xv, xspan), mulscale_triple30(xdsiz, nyrepeat, yspan) };
 
             //Watch out for divscale overflow
-            if (((xspan>>11) < xsiz) && (yspan < (ysiz>>1)))
+            if (((xspan>>11) < siz.x) && (yspan < (siz.y>>1)))
             {
-                x1 = xb-(xsiz>>1);
-                if (xspan&1) x1 += mulscale31(siz,xv);  //Odd xspans
-                i = mulscale30(siz,xv*xoff);
+                x1 = xb-(siz.x>>1);
+                if (xspan&1) x1 += mulscale31(xdsiz,xv);  //Odd xspans
+                i = mulscale30(xdsiz,xv*xoff);
                 if ((cstat&4) == 0) x1 -= i; else x1 += i;
 
-                y1 = mulscale16(tspr->z-globalposz,siz);
-                //y1 -= mulscale30(siz,nyrepeat*yoff);
-                y1 += (globalhoriz<<8)-ysiz;
+                y1 = mulscale16(tspr->z-globalposz,xdsiz);
+                //y1 -= mulscale30(xdsiz,nyrepeat*yoff);
+                y1 += (globalhoriz<<8)-siz.y;
                 //if (cstat&128)  //Already fixed up above
-                y1 += (ysiz>>1);
+                y1 += (siz.y>>1);
 
-                x2 = x1+xsiz-1;
-                y2 = y1+ysiz-1;
+                x2 = x1+siz.x-1;
+                y2 = y1+siz.y-1;
                 if ((y1|255) < (y2|255) && searchx >= (x1>>8)+1 && searchx <= (x2>>8))
                 {
                     int32_t startum, startdm;
 
                     if ((sec->ceilingstat&3) == 0)
-                        startum = globalhoriz+mulscale24(siz,sec->ceilingz-globalposz)-1;
+                        startum = globalhoriz+mulscale24(xdsiz,sec->ceilingz-globalposz)-1;
                     else
                         startum = 0;
 
                     if ((sec->floorstat&3) == 0)
-                        startdm = globalhoriz+mulscale24(siz,sec->floorz-globalposz)+1;
+                        startdm = globalhoriz+mulscale24(xdsiz,sec->floorz-globalposz)+1;
                     else
                         startdm = INT32_MAX;
 
@@ -6732,10 +5879,6 @@ static void drawsprite(int32_t snum)
 //
 static void drawmaskwall(int16_t damaskwallcnt)
 {
-    int32_t i, j, k, x, z, sectnum, z1, z2, lx, rx;
-    sectortype *sec, *nsec;
-    walltype *wal;
-
     //============================================================================= //POLYMOST BEGINS
 #ifdef USE_OPENGL
     if (getrendermode() == REND_POLYMOST) { polymost_drawmaskwall(damaskwallcnt); return; }
@@ -6756,21 +5899,22 @@ static void drawmaskwall(int16_t damaskwallcnt)
 #endif
     //============================================================================= //POLYMOST ENDS
 
-    z = maskwall[damaskwallcnt];
-    wal = &wall[thewall[z]];
-    sectnum = thesector[z]; sec = &sector[sectnum];
-    nsec = &sector[wal->nextsector];
-    z1 = max(nsec->ceilingz,sec->ceilingz);
-    z2 = min(nsec->floorz,sec->floorz);
+    int32_t z = maskwall[damaskwallcnt];
+    twalltype *wal = (twalltype *)&wall[thewall[z]];
+    int32_t sectnum = thesector[z];
+    tsectortype *sec = (tsectortype *)&sector[sectnum];
+    tsectortype *nsec = (tsectortype *)&sector[wal->nextsector];
+    int32_t z1 = max(nsec->ceilingz,sec->ceilingz);
+    int32_t z2 = min(nsec->floorz,sec->floorz);
 
     wallmost(uwall,z,sectnum,(uint8_t)0);
     wallmost(uplc,z,(int32_t)wal->nextsector,(uint8_t)0);
-    for (x=xb1[z]; x<=xb2[z]; x++)
+    for (int x=xb1[z]; x<=xb2[z]; x++)
         if (uplc[x] > uwall[x])
             uwall[x] = uplc[x];
     wallmost(dwall,z,sectnum,(uint8_t)1);
     wallmost(dplc,z,(int32_t)wal->nextsector,(uint8_t)1);
-    for (x=xb1[z]; x<=xb2[z]; x++)
+    for (int x=xb1[z]; x<=xb2[z]; x++)
         if (dplc[x] < dwall[x])
             dwall[x] = dplc[x];
     prepwall(z,wal);
@@ -6778,13 +5922,13 @@ static void drawmaskwall(int16_t damaskwallcnt)
     setup_globals_wall1(wal, wal->overpicnum);
     setup_globals_wall2(wal, sec->visibility, z1, z2);
 
-    for (i=smostwallcnt-1; i>=0; i--)
+    for (int i=smostwallcnt-1, j=smostwall[i]; i>=0; j=smostwall[--i])
     {
-        j = smostwall[i];
         if ((xb1[j] > xb2[z]) || (xb2[j] < xb1[z])) continue;
         if (wallfront(j,z)) continue;
 
-        lx = max(xb1[j],xb1[z]); rx = min(xb2[j],xb2[z]);
+        int lx = max(xb1[j],xb1[z]);
+        int rx = min(xb2[j],xb2[z]);
 
         switch (smostwalltype[i])
         {
@@ -6793,17 +5937,15 @@ static void drawmaskwall(int16_t damaskwallcnt)
             {
                 if ((lx == xb1[z]) && (rx == xb2[z])) return;
                 //clearbufbyte(&dwall[lx],(rx-lx+1)*sizeof(dwall[0]),0L);
-                for (x=lx; x<=rx; x++) dwall[x] = 0;
+                for (int x=lx; x<=rx; x++) dwall[x] = 0;
             }
             break;
         case 1:
-            k = smoststart[i] - xb1[j];
-            for (x=lx; x<=rx; x++)
+            for (int x=lx, k = smoststart[i] - xb1[j]; x<=rx; x++)
                 if (smost[k+x] > uwall[x]) uwall[x] = smost[k+x];
             break;
         case 2:
-            k = smoststart[i] - xb1[j];
-            for (x=lx; x<=rx; x++)
+            for (int x=lx, k = smoststart[i] - xb1[j]; x<=rx; x++)
                 if (smost[k+x] < dwall[x]) dwall[x] = smost[k+x];
             break;
         }
@@ -8349,10 +7491,10 @@ int32_t lintersect(int32_t x1, int32_t y1, int32_t z1,
 // rintersect (internal)
 //
 // returns: -1 if didn't intersect, coefficient (x3--x4 fraction)<<16 else
-static int32_t rintersect(int32_t x1, int32_t y1, int32_t z1,
-                          int32_t vx_, int32_t vy_, int32_t vz,
-                          int32_t x3, int32_t y3, int32_t x4, int32_t y4,
-                          int32_t *intx, int32_t *inty, int32_t *intz)
+int32_t rintersect(int32_t x1, int32_t y1, int32_t z1,
+                   int32_t vx_, int32_t vy_, int32_t vz,
+                   int32_t x3, int32_t y3, int32_t x4, int32_t y4,
+                   int32_t *intx, int32_t *inty, int32_t *intz)
 {
     //p1 towards p2 is a ray
     int64_t topt, topu, t;
@@ -8394,81 +7536,6 @@ int32_t rayintersect(int32_t x1, int32_t y1, int32_t z1, int32_t vx, int32_t vy,
     return (rintersect(x1, y1, z1, vx, vy, vz, x3, y3, x4, y4, intx, inty, intz) != -1);
 }
 
-//
-// keepaway (internal)
-//
-static inline void keepaway(int32_t *x, int32_t *y, int32_t w)
-{
-    const int32_t x1 = clipit[w].x1, dx = clipit[w].x2-x1;
-    const int32_t y1 = clipit[w].y1, dy = clipit[w].y2-y1;
-    const int32_t ox = ksgn(-dy), oy = ksgn(dx);
-    char first = (klabs(dx) <= klabs(dy));
-
-    while (1)
-    {
-        if (dx*(*y-y1) > (*x-x1)*dy)
-            return;
-
-        if (first == 0)
-            *x += ox;
-        else
-            *y += oy;
-
-        first ^= 1;
-    }
-}
-
-
-//
-// raytrace (internal)
-//
-static inline int32_t raytrace(int32_t x3, int32_t y3, int32_t *x4, int32_t *y4)
-{
-    int32_t hitwall = -1;
-
-    for (int32_t z=clipnum-1; z>=0; z--)
-    {
-        const int32_t x1 = clipit[z].x1, x2 = clipit[z].x2, x21 = x2-x1;
-        const int32_t y1 = clipit[z].y1, y2 = clipit[z].y2, y21 = y2-y1;
-
-        int32_t topu = x21*(y3-y1) - (x3-x1)*y21;
-        if (topu <= 0)
-            continue;
-
-        if (x21*(*y4-y1) > (*x4-x1)*y21)
-            continue;
-
-        const int32_t x43 = *x4-x3;
-        const int32_t y43 = *y4-y3;
-
-        if (x43*(y1-y3) > (x1-x3)*y43)
-            continue;
-
-        if (x43*(y2-y3) <= (x2-x3)*y43)
-            continue;
-
-        const int32_t bot = x43*y21 - x21*y43;
-        if (bot == 0)
-            continue;
-
-        int32_t cnt = 256, nintx, ninty;
-
-        do
-        {
-            cnt--; if (cnt < 0) { *x4 = x3; *y4 = y3; return z; }
-            nintx = x3 + scale(x43,topu,bot);
-            ninty = y3 + scale(y43,topu,bot);
-            topu--;
-        }
-        while (x21*(ninty-y1) <= (nintx-x1)*y21);
-
-        if (klabs(x3-nintx)+klabs(y3-ninty) < klabs(x3-*x4)+klabs(y3-*y4))
-            { *x4 = nintx; *y4 = ninty; hitwall = z; }
-    }
-
-    return hitwall;
-}
-
 //
 // multi-pskies
 //
@@ -9218,9 +8285,9 @@ static inline int32_t         sameside(const _equation *eq, const vec2f_t *p1, c
 
 // x1, y1: in/out
 // rest x/y: out
-static void get_wallspr_points(const spritetype *spr, int32_t *x1, int32_t *x2,
+void get_wallspr_points(const spritetype *spr, int32_t *x1, int32_t *x2,
                                int32_t *y1, int32_t *y2);
-static void get_floorspr_points(const tspritetype *spr, int32_t px, int32_t py,
+void get_floorspr_points(const tspritetype *spr, int32_t px, int32_t py,
                                 int32_t *x1, int32_t *x2, int32_t *x3, int32_t *x4,
                                 int32_t *y1, int32_t *y2, int32_t *y3, int32_t *y4);
 
@@ -10584,329 +9651,6 @@ int32_t loadoldboard(const char *filename, char fromwhere, vec3_t *dapos, int16_
 }
 
 
-#ifdef POLYMER
-void delete_maphack_lights()
-{
-    int32_t i;
-    for (i=0; i<maphacklightcnt; i++)
-    {
-        if (maphacklight[i] >= 0)
-            polymer_deletelight(maphacklight[i]);
-        maphacklight[i] = -1;
-    }
-
-    maphacklightcnt = 0;
-}
-#else
-void delete_maphack_lights() {}
-#endif
-
-//
-// loadmaphack
-//
-int32_t loadmaphack(const char *filename)
-{
-    enum
-    {
-        T_SPRITE = 0,
-        T_ANGOFF,
-        T_NOMODEL,
-        T_NOANIM,
-        T_PITCH,
-        T_ROLL,
-        T_MDXOFF,
-        T_MDYOFF,
-        T_MDZOFF,
-        T_AWAY1,
-        T_AWAY2,
-        T_LIGHT,
-    };
-
-    static struct { const char *text; int32_t tokenid; } legaltokens[] =
-    {
-        { "sprite", T_SPRITE },
-        { "angleoff", T_ANGOFF },
-        { "angoff", T_ANGOFF },
-        { "notmd2", T_NOMODEL },
-        { "notmd3", T_NOMODEL },
-        { "notmd", T_NOMODEL },
-        { "nomd2anim", T_NOANIM },
-        { "nomd3anim", T_NOANIM },
-        { "nomdanim", T_NOANIM },
-        { "pitch", T_PITCH },
-        { "roll", T_ROLL },
-        { "mdxoff", T_MDXOFF },
-        { "mdyoff", T_MDYOFF },
-        { "mdzoff", T_MDZOFF },
-        { "away1", T_AWAY1 },
-        { "away2", T_AWAY2 },
-        { "light", T_LIGHT },
-        { NULL, -1 }
-    };
-
-    scriptfile *script = NULL;
-    char *tok, *cmdtokptr;
-    int32_t i;
-    int32_t whichsprite = -1;
-    static char fn[BMAX_PATH];
-
-#ifdef POLYMER
-    int32_t toomanylights = 0;
-
-    delete_maphack_lights();
-#endif
-
-    if (filename)
-    {
-        Bmemset(spriteext, 0, sizeof(spriteext_t) * MAXSPRITES);
-        Bmemset(spritesmooth, 0, sizeof(spritesmooth_t) *(MAXSPRITES+MAXUNIQHUDID));
-        Bstrcpy(fn, filename);
-        script = scriptfile_fromfile(filename);
-    }
-    else if (fn[0])
-    {
-        // re-load
-        // XXX: what if we changed between levels? Could a wrong maphack be loaded?
-        script = scriptfile_fromfile(fn);
-    }
-
-    if (!script)
-    {
-        fn[0] = 0;
-        return -1;
-    }
-
-    while (1)
-    {
-        tok = scriptfile_gettoken(script);
-        if (!tok) break;
-        for (i=0; legaltokens[i].text; i++) if (!Bstrcasecmp(tok,legaltokens[i].text)) break;
-        cmdtokptr = script->ltextptr;
-
-        if (!filename && legaltokens[i].tokenid != T_LIGHT) continue;
-
-        switch (legaltokens[i].tokenid)
-        {
-        case T_SPRITE:     // sprite <xx>
-            if (scriptfile_getnumber(script, &whichsprite)) break;
-
-            if ((unsigned)whichsprite >= (unsigned)MAXSPRITES)
-            {
-                // sprite number out of range
-                initprintf("Sprite number out of range 0-%d on line %s:%d\n",
-                           MAXSPRITES-1,script->filename, scriptfile_getlinum(script,cmdtokptr));
-                whichsprite = -1;
-                break;
-            }
-
-            break;
-        case T_ANGOFF:     // angoff <xx>
-        {
-            int32_t ang;
-            if (scriptfile_getnumber(script, &ang)) break;
-
-            if (whichsprite < 0)
-            {
-                // no sprite directive preceeding
-                initprintf("Ignoring angle offset directive because of absent/invalid sprite number on line %s:%d\n",
-                           script->filename, scriptfile_getlinum(script,cmdtokptr));
-                break;
-            }
-            spriteext[whichsprite].angoff = (int16_t)ang;
-        }
-        break;
-        case T_NOMODEL:      // notmd
-            if (whichsprite < 0)
-            {
-                // no sprite directive preceeding
-                initprintf("Ignoring not-MD2/MD3 directive because of absent/invalid sprite number on line %s:%d\n",
-                           script->filename, scriptfile_getlinum(script,cmdtokptr));
-                break;
-            }
-            spriteext[whichsprite].flags |= SPREXT_NOTMD;
-            break;
-        case T_NOANIM:      // nomdanim
-            if (whichsprite < 0)
-            {
-                // no sprite directive preceeding
-                initprintf("Ignoring no-MD2/MD3-anim directive because of absent/invalid sprite number on line %s:%d\n",
-                           script->filename, scriptfile_getlinum(script,cmdtokptr));
-                break;
-            }
-            spriteext[whichsprite].flags |= SPREXT_NOMDANIM;
-            break;
-        case T_PITCH:     // pitch <xx>
-        {
-            int32_t pitch;
-            if (scriptfile_getnumber(script, &pitch)) break;
-
-            if (whichsprite < 0)
-            {
-                // no sprite directive preceeding
-                initprintf("Ignoring pitch directive because of absent/invalid sprite number on line %s:%d\n",
-                           script->filename, scriptfile_getlinum(script,cmdtokptr));
-                break;
-            }
-            spriteext[whichsprite].pitch = (int16_t)pitch;
-        }
-        break;
-        case T_ROLL:     // roll <xx>
-        {
-            int32_t roll;
-            if (scriptfile_getnumber(script, &roll)) break;
-
-            if (whichsprite < 0)
-            {
-                // no sprite directive preceeding
-                initprintf("Ignoring roll directive because of absent/invalid sprite number on line %s:%d\n",
-                           script->filename, scriptfile_getlinum(script,cmdtokptr));
-                break;
-            }
-            spriteext[whichsprite].roll = (int16_t)roll;
-        }
-        break;
-        case T_MDXOFF:     // mdxoff <xx>
-        {
-            int32_t i;
-            if (scriptfile_getnumber(script, &i)) break;
-
-            if (whichsprite < 0)
-            {
-                // no sprite directive preceeding
-                initprintf("Ignoring mdxoff directive because of absent/invalid sprite number on line %s:%d\n",
-                           script->filename, scriptfile_getlinum(script,cmdtokptr));
-                break;
-            }
-            spriteext[whichsprite].offset.x = i;
-        }
-        break;
-        case T_MDYOFF:     // mdyoff <xx>
-        {
-            int32_t i;
-            if (scriptfile_getnumber(script, &i)) break;
-
-            if (whichsprite < 0)
-            {
-                // no sprite directive preceeding
-                initprintf("Ignoring mdyoff directive because of absent/invalid sprite number on line %s:%d\n",
-                           script->filename, scriptfile_getlinum(script,cmdtokptr));
-                break;
-            }
-            spriteext[whichsprite].offset.y = i;
-        }
-        break;
-        case T_MDZOFF:     // mdzoff <xx>
-        {
-            int32_t i;
-            if (scriptfile_getnumber(script, &i)) break;
-
-            if (whichsprite < 0)
-            {
-                // no sprite directive preceeding
-                initprintf("Ignoring mdzoff directive because of absent/invalid sprite number on line %s:%d\n",
-                           script->filename, scriptfile_getlinum(script,cmdtokptr));
-                break;
-            }
-            spriteext[whichsprite].offset.z = i;
-        }
-        break;
-        case T_AWAY1:      // away1
-            if (whichsprite < 0)
-            {
-                // no sprite directive preceeding
-                initprintf("Ignoring moving away directive because of absent/invalid sprite number on line %s:%d\n",
-                           script->filename, scriptfile_getlinum(script,cmdtokptr));
-                break;
-            }
-            spriteext[whichsprite].flags |= SPREXT_AWAY1;
-            break;
-        case T_AWAY2:      // away2
-            if (whichsprite < 0)
-            {
-                // no sprite directive preceeding
-                initprintf("Ignoring moving away directive because of absent/invalid sprite number on line %s:%d\n",
-                           script->filename, scriptfile_getlinum(script,cmdtokptr));
-                break;
-            }
-            spriteext[whichsprite].flags |= SPREXT_AWAY2;
-            break;
-#ifdef POLYMER
-        case T_LIGHT:      // light sector x y z range r g b radius faderadius angle horiz minshade maxshade priority tilenum
-        {
-            int32_t value;
-            int16_t lightid;
-#pragma pack(push,1)
-            _prlight light;
-#pragma pack(pop)
-            if (toomanylights)
-                break;  // ignore further light defs
-
-            scriptfile_getnumber(script, &value);
-            light.sector = value;
-            scriptfile_getnumber(script, &value);
-            light.x = value;
-            scriptfile_getnumber(script, &value);
-            light.y = value;
-            scriptfile_getnumber(script, &value);
-            light.z = value;
-            scriptfile_getnumber(script, &value);
-            light.range = value;
-            scriptfile_getnumber(script, &value);
-            light.color[0] = value;
-            scriptfile_getnumber(script, &value);
-            light.color[1] = value;
-            scriptfile_getnumber(script, &value);
-            light.color[2] = value;
-            scriptfile_getnumber(script, &value);
-            light.radius = value;
-            scriptfile_getnumber(script, &value);
-            light.faderadius = value;
-            scriptfile_getnumber(script, &value);
-            light.angle = value;
-            scriptfile_getnumber(script, &value);
-            light.horiz = value;
-            scriptfile_getnumber(script, &value);
-            light.minshade = value;
-            scriptfile_getnumber(script, &value);
-            light.maxshade = value;
-            scriptfile_getnumber(script, &value);
-            light.priority = value;
-            scriptfile_getnumber(script, &value);
-            light.tilenum = value;
-
-            light.publicflags.emitshadow = 1;
-            light.publicflags.negative = 0;
-
-            if (getrendermode() == REND_POLYMER)
-            {
-                if (maphacklightcnt == PR_MAXLIGHTS)
-                {
-                    initprintf("warning: max light count %d exceeded, "
-                               "ignoring further light defs\n", PR_MAXLIGHTS);
-                    toomanylights = 1;
-                    break;
-                }
-
-                lightid = polymer_addlight(&light);
-                if (lightid>=0)
-                    maphacklight[maphacklightcnt++] = lightid;
-            }
-
-            break;
-        }
-#endif // POLYMER
-
-        default:
-            // unrecognised token
-            break;
-        }
-    }
-
-    scriptfile_close(script);
-    return 0;
-}
-
-
 #ifdef NEW_MAP_FORMAT
 LUNATIC_CB int32_t (*saveboard_maptext)(const char *filename, const vec3_t *dapos, int16_t daang, int16_t dacursectnum);
 #endif
@@ -11979,65 +10723,6 @@ int32_t qloadkvx(int32_t voxindex, const char *filename)
 }
 
 
-//
-// clipinsidebox
-//
-int32_t clipinsidebox(int32_t x, int32_t y, int16_t wallnum, int32_t walldist)
-{
-    walltype *wal;
-    int32_t x1, y1, x2, y2;
-
-    const int32_t r = walldist<<1;
-
-    wal = &wall[wallnum];     x1 = wal->x+walldist-x; y1 = wal->y+walldist-y;
-    wal = &wall[wal->point2]; x2 = wal->x+walldist-x; y2 = wal->y+walldist-y;
-
-    if ((x1 < 0) && (x2 < 0)) return(0);
-    if ((y1 < 0) && (y2 < 0)) return(0);
-    if ((x1 >= r) && (x2 >= r)) return(0);
-    if ((y1 >= r) && (y2 >= r)) return(0);
-
-    x2 -= x1; y2 -= y1;
-    if (x2*(walldist-y1) >= y2*(walldist-x1))  //Front
-    {
-        if (x2 > 0) x2 *= (0-y1); else x2 *= (r-y1);
-        if (y2 > 0) y2 *= (r-x1); else y2 *= (0-x1);
-        return(x2 < y2);
-    }
-    if (x2 > 0) x2 *= (r-y1); else x2 *= (0-y1);
-    if (y2 > 0) y2 *= (0-x1); else y2 *= (r-x1);
-    return((x2 >= y2)<<1);
-}
-
-
-//
-// clipinsideboxline
-//
-int32_t clipinsideboxline(int32_t x, int32_t y, int32_t x1, int32_t y1, int32_t x2, int32_t y2, int32_t walldist)
-{
-    const int32_t r = walldist<<1;
-
-    x1 += walldist-x; x2 += walldist-x;
-    if ((x1 < 0) && (x2 < 0)) return(0);
-    if ((x1 >= r) && (x2 >= r)) return(0);
-
-    y1 += walldist-y; y2 += walldist-y;
-    if ((y1 < 0) && (y2 < 0)) return(0);
-    if ((y1 >= r) && (y2 >= r)) return(0);
-
-    x2 -= x1; y2 -= y1;
-    if (x2*(walldist-y1) >= y2*(walldist-x1))  //Front
-    {
-        if (x2 > 0) x2 *= (0-y1); else x2 *= (r-y1);
-        if (y2 > 0) y2 *= (r-x1); else y2 *= (0-x1);
-        return(x2 < y2);
-    }
-    if (x2 > 0) x2 *= (r-y1); else x2 *= (0-y1);
-    if (y2 > 0) y2 *= (0-x1); else y2 *= (r-x1);
-    return((x2 >= y2)<<1);
-}
-
-
 //
 // inside
 //
@@ -12048,18 +10733,18 @@ int32_t inside(int32_t x, int32_t y, int16_t sectnum)
     if (sectnum >= 0 && sectnum < numsectors)
     {
         uint32_t cnt1 = 0, cnt2 = 0;
-        walltype *wal = &wall[sector[sectnum].wallptr];
+        twalltype const * wal = (twalltype *) &wall[sector[sectnum].wallptr];
         int32_t i = sector[sectnum].wallnum;
 
         do
         {
             // Get the x and y components of the [tested point]-->[wall
             // point{1,2}] vectors.
-            int32_t x1 = wal->x-x, x2 = wall[wal->point2].x-x;
-            int32_t y1 = wal->y-y, y2 = wall[wal->point2].y-y;
+            vec2_t v1 = { wal->x - x, wal->y - y };
+            vec2_t v2 = { wall[wal->point2].x - x, wall[wal->point2].y - y };
 
             // First, test if the point is EXACTLY_ON_WALL_POINT.
-            if ((x1|y1) == 0 || (x2|y2)==0)
+            if ((v1.x|v1.y) == 0 || (v2.x|v2.y)==0)
                 return 1;
 
             // If their signs differ[*], ...
@@ -12068,16 +10753,11 @@ int32_t inside(int32_t x, int32_t y, int16_t sectnum)
             // Equivalently, the branch is taken iff
             //   y1 != y2 AND y_m <= y < y_M,
             // where y_m := min(y1, y2) and y_M := max(y1, y2).
-            if ((y1^y2) < 0)
-            {
-                if ((x1^x2) >= 0)
-                    cnt1 ^= x1;
-                else
-                    cnt1 ^= (x1*y2-x2*y1)^y2;
-            }
+            if ((v1.y^v2.y) < 0)
+                cnt1 ^= (((v1.x^v2.x) >= 0) ? v1.x : (v1.x*v2.y-v2.x*v1.y)^v2.y);
 
-            y1--;
-            y2--;
+            v1.y--;
+            v2.y--;
 
             // Now, do the same comparisons, but with the interval half-open on
             // the other side! That is, take the branch iff
@@ -12085,15 +10765,12 @@ int32_t inside(int32_t x, int32_t y, int16_t sectnum)
             // For a rectangular sector, without EXACTLY_ON_WALL_POINT, this
             // would still leave the lower left and upper right points
             // "outside" the sector.
-            if ((y1^y2) < 0)
+            if ((v1.y^v2.y) < 0)
             {
-                x1--;
-                x2--;
+                v1.x--;
+                v2.x--;
 
-                if ((x1^x2) >= 0)
-                    cnt2 ^= x1;
-                else
-                    cnt2 ^= (x1*y2-x2*y1)^y2;
+                cnt2 ^= (((v1.x^v2.x) >= 0) ? v1.x : (v1.x*v2.y-v2.x*v1.y)^v2.y);
             }
 
             wal++; i--;
@@ -12522,7 +11199,7 @@ static int32_t hitscan_trysector(const vec3_t *sv, const sectortype *sec, hitdat
 
 // x1, y1: in/out
 // rest x/y: out
-static void get_wallspr_points(const spritetype *spr, int32_t *x1, int32_t *x2,
+void get_wallspr_points(const spritetype *spr, int32_t *x1, int32_t *x2,
                                int32_t *y1, int32_t *y2)
 {
     //These lines get the 2 points of the rotated sprite
@@ -12551,7 +11228,7 @@ static void get_wallspr_points(const spritetype *spr, int32_t *x1, int32_t *x2,
 
 // x1, y1: in/out
 // rest x/y: out
-static void get_floorspr_points(const tspritetype *spr, int32_t px, int32_t py,
+void get_floorspr_points(const tspritetype *spr, int32_t px, int32_t py,
                                 int32_t *x1, int32_t *x2, int32_t *x3, int32_t *x4,
                                 int32_t *y1, int32_t *y2, int32_t *y3, int32_t *y4)
 {
@@ -12669,10 +11346,6 @@ static int32_t try_facespr_intersect(const spritetype *spr, const vec3_t *refpos
 //
 // hitscan
 //
-#ifdef HAVE_CLIPSHAPE_FEATURE
-static int32_t clipsprite_initindex(int32_t curidx, spritetype *curspr, int32_t *clipsectcnt, const vec3_t *vect);
-#endif
-
 int32_t hitscan(const vec3_t *sv, int16_t sectnum, int32_t vx, int32_t vy, int32_t vz,
                 hitdata_t *hit, uint32_t cliptype)
 {
@@ -13275,766 +11948,6 @@ int32_t lastwall(int16_t point)
     return point;
 }
 
-
-////////// CLIPMOVE //////////
-
-int32_t clipmoveboxtracenum = 3;
-
-#ifdef HAVE_CLIPSHAPE_FEATURE
-static int32_t clipsprite_try(const spritetype *spr, int32_t xmin, int32_t ymin, int32_t xmax, int32_t ymax)
-{
-    // try and see whether this sprite's picnum has sector-like clipping data
-    int32_t i = pictoidx[spr->picnum];
-    // handle sector-like floor sprites separately
-    while (i>=0 && (spr->cstat&32) != (clipmapinfo.sector[sectq[clipinfo[i].qbeg]].CM_CSTAT&32))
-        i = clipinfo[i].next;
-
-    if (i>=0)
-    {
-        int32_t maxcorrection = clipinfo[i].maxdist;
-        const int32_t k = sectq[clipinfo[i].qbeg];
-
-        if ((spr->cstat&48)!=32)  // face/wall sprite
-        {
-            int32_t tempint1 = clipmapinfo.sector[k].CM_XREPEAT;
-            maxcorrection = divideu32_noinline(maxcorrection * (int32_t)spr->xrepeat, tempint1);
-        }
-        else  // floor sprite
-        {
-            int32_t tempint1 = clipmapinfo.sector[k].CM_XREPEAT;
-            int32_t tempint2 = clipmapinfo.sector[k].CM_YREPEAT;
-            maxcorrection = max(divideu32_noinline(maxcorrection * (int32_t)spr->xrepeat, tempint1),
-                                divideu32_noinline(maxcorrection * (int32_t)spr->yrepeat, tempint2));
-        }
-
-        maxcorrection -= MAXCLIPDIST;
-
-        if (spr->x < xmin - maxcorrection) return 1;
-        if (spr->y < ymin - maxcorrection) return 1;
-        if (spr->x > xmax + maxcorrection) return 1;
-        if (spr->y > ymax + maxcorrection) return 1;
-
-        if (clipspritenum < MAXCLIPNUM)
-            clipspritelist[clipspritenum++] = spr-sprite;
-//initprintf("%d: clip sprite[%d]\n",clipspritenum,j);
-        return 1;
-    }
-
-    return 0;
-}
-
-// return: -1 if curspr has x-flip xor y-flip (in the horizontal map plane!), 1 else
-static int32_t clipsprite_initindex(int32_t curidx, spritetype *curspr, int32_t *clipsectcnt, const vec3_t *vect)
-{
-    int32_t k, daz = curspr->z;
-    int32_t scalex, scaley, scalez, flipx, flipy;
-    int32_t flipmul=1;
-
-    const int32_t j = sectq[clipinfo[curidx].qbeg];
-    const int32_t tempint1 = sector[j].CM_XREPEAT;
-    const int32_t tempint2 = sector[j].CM_YREPEAT;
-
-    const int32_t rotang = (curspr->ang - sector[j].CM_ANG)&2047;
-    const int32_t dorot = !CM_NOROTS(j);
-
-    if ((curspr->cstat&48)!=32)  // face/wall sprite
-    {
-        scalex = scaley = divscale22(curspr->xrepeat, tempint1);
-        scalez = divscale22(curspr->yrepeat, tempint2);
-
-        flipx = 1-((curspr->cstat&4)>>1);
-        flipy = 1;
-    }
-    else
-    {
-        scalex = divscale22(curspr->xrepeat, tempint1);
-        scaley = divscale22(curspr->yrepeat, tempint2);
-        scalez = scalex;
-
-        flipx = 1-((curspr->cstat&4)>>1);
-        flipy = 1-((curspr->cstat&8)>>2);
-    }
-
-    if (dorot)
-    {
-        flipmul = flipx*flipy;
-        if (flipmul==-1)
-            wall = (walltype *)loadwallinv;
-    }
-
-    if ((curspr->cstat&128) != (sector[j].CM_CSTAT&128))
-        daz += (((curspr->cstat&128)>>6)-1)*((tilesiz[curspr->picnum].y*curspr->yrepeat)<<1);
-
-    *clipsectcnt = clipsectnum = 0;
-    // init sectors for this index
-    for (k=clipinfo[curidx].qbeg; k<=clipinfo[curidx].qend; k++)
-    {
-        const int32_t j = sectq[k];
-        sectortype *const sec = &sector[j];
-        const int32_t startwall = sec->wallptr, endwall = startwall+sec->wallnum;
-
-        int32_t w;
-        walltype *wal;
-
-        sec->floorz = daz + mulscale22(scalez, CM_FLOORZ(j));
-        sec->ceilingz = daz + mulscale22(scalez, CM_CEILINGZ(j));
-//initprintf("sec %d: f=%d, c=%d\n", j, sec->floorz, sec->ceilingz);
-
-        for (w=startwall,wal=&wall[startwall]; w<endwall; w++,wal++)
-        {
-            wal->x = mulscale22(scalex, CM_WALL_X(w));
-            wal->y = mulscale22(scaley, CM_WALL_Y(w));
-
-            if (dorot)
-            {
-                wal->x *= flipx;
-                wal->y *= flipy;
-                rotatepoint(zerovec, *(vec2_t *)wal, rotang, (vec2_t *)wal);
-            }
-
-            wal->x += curspr->x;
-            wal->y += curspr->y;
-        }
-
-        if (inside(vect->x, vect->y, j)==1)
-            clipsectorlist[clipsectnum++] = j;
-    }
-
-    // add outer sector if not inside inner ones
-    if (clipsectnum==0)
-        clipsectorlist[clipsectnum++] = sectq[k-1];
-
-    return flipmul;
-}
-#endif
-
-static int32_t clipmove_warned=0;
-
-static void addclipline(int32_t dax1, int32_t day1, int32_t dax2, int32_t day2, int32_t daoval)
-{
-    if (clipnum < MAXCLIPNUM)
-    {
-        clipit[clipnum].x1 = dax1; clipit[clipnum].y1 = day1;
-        clipit[clipnum].x2 = dax2; clipit[clipnum].y2 = day2;
-        clipobjectval[clipnum] = daoval;
-        clipnum++;
-    }
-    else if (!clipmove_warned)
-    {
-        initprintf("!!clipnum\n");
-        clipmove_warned = 1;
-    }
-}
-
-static inline void clipmove_tweak_pos(const vec3_t *pos, int32_t gx, int32_t gy,
-                                      int32_t x1, int32_t y1, int32_t x2, int32_t y2,
-                                      int32_t *daxptr, int32_t *dayptr)
-{
-    int32_t daz;
-
-    if (rintersect(pos->x,pos->y,0, gx,gy,0, x1,y1, x2,y2, daxptr,dayptr,&daz) == -1)
-    {
-        *daxptr = pos->x;
-        *dayptr = pos->y;
-    }
-}
-
-// Returns: should clip?
-static int32_t check_floor_curb(int32_t dasect, int32_t nextsect, int32_t flordist,
-                                int32_t posz, int32_t dax, int32_t day)
-{
-    const sectortype *sec2 = &sector[nextsect];
-    int32_t daz2 = getflorzofslope(nextsect, dax,day);
-
-    return ((sec2->floorstat&1) == 0 &&  // parallaxed floor curbs don't clip
-                posz >= daz2-(flordist-1) &&  // also account for desired z distance tolerance
-                daz2 < getflorzofslope(dasect, dax,day)-(1<<8));  // curbs less tall than 256 z units don't clip
-}
-
-int32_t clipmovex(vec3_t *pos, int16_t *sectnum,
-                  int32_t xvect, int32_t yvect,
-                  int32_t walldist, int32_t ceildist, int32_t flordist, uint32_t cliptype,
-                  uint8_t noslidep)
-{
-    const int32_t oboxtracenum = clipmoveboxtracenum;
-
-    if (noslidep)
-        clipmoveboxtracenum = 1;
-    int32_t ret = clipmove(pos, sectnum, xvect, yvect,
-                           walldist, ceildist, flordist, cliptype);
-    clipmoveboxtracenum = oboxtracenum;
-
-    return ret;
-}
-
-//
-// clipmove
-//
-int32_t clipmove(vec3_t *pos, int16_t *sectnum,
-                 int32_t xvect, int32_t yvect,
-                 int32_t walldist, int32_t ceildist, int32_t flordist, uint32_t cliptype)
-{
-    int32_t i, j, k, tempint1, tempint2;
-    int32_t x1, y1, x2, y2;
-    int32_t dax, day;
-    int32_t retval=0;
-
-    spritetype *curspr=NULL;  // non-NULL when handling sprite with sector-like clipping
-    int32_t curidx=-1, clipsectcnt, clipspritecnt;
-
-    const int32_t dawalclipmask = (cliptype&65535);        //CLIPMASK0 = 0x00010001
-    const int32_t dasprclipmask = (cliptype>>16);          //CLIPMASK1 = 0x01000040
-
-    const int32_t oxvect=xvect, oyvect=yvect;
-
-    int32_t goalx = pos->x + (xvect>>14);
-    int32_t goaly = pos->y + (yvect>>14);
-    const int32_t cx = (pos->x+goalx)>>1;
-    const int32_t cy = (pos->y+goaly)>>1;
-
-    //Extra walldist for sprites on sector lines
-    const int32_t gx=goalx-(pos->x), gy=goaly-(pos->y);
-    const int32_t rad = nsqrtasm(uhypsq(gx,gy)) + MAXCLIPDIST+walldist + 8;
-    const int32_t xmin = cx-rad, ymin = cy-rad;
-    const int32_t xmax = cx+rad, ymax = cy+rad;
-
-    if ((xvect|yvect) == 0 || *sectnum < 0)
-        return 0;
-
-    clipmove_warned = 0;
-    clipnum = 0;
-
-    clipsectorlist[0] = (*sectnum);
-    clipsectcnt = 0; clipsectnum = 1;
-    clipspritecnt = 0; clipspritenum = 0;
-    do
-    {
-        const walltype *wal;
-        const sectortype *sec;
-        int32_t dasect, startwall, endwall;
-
-#ifdef HAVE_CLIPSHAPE_FEATURE
-        if (clipsectcnt>=clipsectnum)
-        {
-            // one bunch of sectors completed (either the very first
-            // one or a sector-like sprite one), prepare the next
-
-//initprintf("init sprite %d\n", clipspritecnt);
-            if (!curspr)
-            {
-                // init sector-like sprites for clipping
-                origclipsectnum = clipsectnum;
-                Bmemcpy(origclipsectorlist, clipsectorlist, clipsectnum*sizeof(clipsectorlist[0]));
-
-                // replace sector and wall with clip map
-                mapinfo_set(&origmapinfo, &clipmapinfo);
-            }
-
-            curspr = &sprite[clipspritelist[clipspritecnt]];
-            curidx = clipshape_idx_for_sprite(curspr, curidx);
-
-            if (curidx < 0)
-            {
-                clipspritecnt++;
-                continue;
-            }
-
-            clipsprite_initindex(curidx, curspr, &clipsectcnt, pos);
-        }
-#endif
-
-        dasect = clipsectorlist[clipsectcnt++];
-//if (curspr)
-//    initprintf("sprite %d/%d: sect %d/%d (%d)\n", clipspritecnt,clipspritenum, clipsectcnt,clipsectnum,dasect);
-
-        ////////// Walls //////////
-
-        sec = &sector[dasect];
-        startwall = sec->wallptr; endwall = startwall + sec->wallnum;
-        for (j=startwall,wal=&wall[startwall]; j<endwall; j++,wal++)
-        {
-            int32_t clipyou = 0, dx, dy;
-            const walltype *const wal2 = &wall[wal->point2];
-
-            if (wal->x < xmin && wal2->x < xmin) continue;
-            if (wal->x > xmax && wal2->x > xmax) continue;
-            if (wal->y < ymin && wal2->y < ymin) continue;
-            if (wal->y > ymax && wal2->y > ymax) continue;
-
-            x1 = wal->x; y1 = wal->y; x2 = wal2->x; y2 = wal2->y;
-
-            dx = x2-x1; dy = y2-y1;
-            if (dx*((pos->y)-y1) < ((pos->x)-x1)*dy) continue;  //If wall's not facing you
-
-            if (dx > 0) dax = dx*(ymin-y1); else dax = dx*(ymax-y1);
-            if (dy > 0) day = dy*(xmax-x1); else day = dy*(xmin-x1);
-            if (dax >= day) continue;
-
-#ifdef HAVE_CLIPSHAPE_FEATURE
-            if (curspr)
-            {
-                if (wal->nextsector>=0)
-                {
-                    const sectortype *sec2 = &sector[wal->nextsector];
-
-                    clipmove_tweak_pos(pos, gx,gy, x1,y1, x2,y2, &dax,&day);
-
-                    #define CLIPMV_SPR_F_DAZ2 getflorzofslope(wal->nextsector, dax,day)
-                    #define CLIPMV_SPR_F_BASEZ getflorzofslope(sectq[clipinfo[curidx].qend], dax,day)
-
-                    if ((sec2->floorstat&1) == 0)
-                        if (CLIPMV_SPR_F_DAZ2-(flordist-1) <= pos->z)
-                            if (pos->z <= CLIPMV_SPR_F_BASEZ+(flordist-1))
-                                clipyou = 1;
-
-                    if (clipyou == 0)
-                    {
-                        #define CLIPMV_SPR_C_DAZ2 getceilzofslope(wal->nextsector, dax,day)
-                        #define CLIPMV_SPR_C_BASEZ getceilzofslope(sectq[clipinfo[curidx].qend], dax,day)
-
-                        if ((sec2->ceilingstat&1) == 0)
-                            if (CLIPMV_SPR_C_BASEZ-(ceildist-1) <= pos->z)
-                                if (pos->z <= CLIPMV_SPR_C_DAZ2+(ceildist-1))
-                                    clipyou = 1;
-                    }
-                }
-            }
-            else
-#endif
-            if (wal->nextsector < 0 || (wal->cstat&dawalclipmask))
-            {
-                clipyou = 1;
-#ifdef YAX_ENABLE
-                int16_t cb = yax_getbunch(dasect, YAX_CEILING);
-
-                if (cb >= 0 && (sec->ceilingstat & yax_waltosecmask(dawalclipmask)) == 0)
-                {
-                    int32_t ynw = yax_getnextwall(j, YAX_CEILING);
-
-                    if (ynw >= 0 && wall[ynw].nextsector >= 0 && (wall[ynw].cstat & dawalclipmask) == 0)
-                    {
-                        clipmove_tweak_pos(pos, gx,gy, x1,y1, x2,y2, &dax,&day);
-                        clipyou = check_floor_curb(dasect, wall[ynw].nextsector, flordist, pos->z, dax, day);
-                    }
-                }
-#endif
-            }
-            else if (editstatus == 0)
-            {
-                clipmove_tweak_pos(pos, gx,gy, x1,y1, x2,y2, &dax,&day);
-                clipyou = check_floor_curb(dasect, wal->nextsector, flordist, pos->z, dax, day);
-
-                if (clipyou == 0)
-                {
-                    const sectortype *sec2 = &sector[wal->nextsector];
-                    int32_t daz2 = getceilzofslope(wal->nextsector, dax,day);
-
-                    clipyou = ((sec2->ceilingstat&1) == 0 &&
-                                   pos->z <= daz2+(ceildist-1) &&
-                                   daz2 > getceilzofslope(dasect, dax,day)+(1<<8));
-                }
-            }
-
-            if (clipyou)
-            {
-                int16_t objtype;
-                int32_t bsz;
-
-                if (!curspr)
-                    objtype = (int16_t)j+32768;
-                else
-                    objtype = (int16_t)(curspr-sprite)+49152;
-
-                //Add 2 boxes at endpoints
-                bsz = walldist; if (gx < 0) bsz = -bsz;
-                addclipline(x1-bsz,y1-bsz, x1-bsz,y1+bsz, objtype);
-                addclipline(x2-bsz,y2-bsz, x2-bsz,y2+bsz, objtype);
-                bsz = walldist; if (gy < 0) bsz = -bsz;
-                addclipline(x1+bsz,y1-bsz, x1-bsz,y1-bsz, objtype);
-                addclipline(x2+bsz,y2-bsz, x2-bsz,y2-bsz, objtype);
-
-                dax = walldist; if (dy > 0) dax = -dax;
-                day = walldist; if (dx < 0) day = -day;
-                addclipline(x1+dax,y1+day, x2+dax,y2+day, objtype);
-            }
-            else if (wal->nextsector>=0)
-            {
-                for (i=clipsectnum-1; i>=0; i--)
-                    if (wal->nextsector == clipsectorlist[i]) break;
-                if (i < 0) clipsectorlist[clipsectnum++] = wal->nextsector;
-            }
-        }
-
-        ////////// Sprites //////////
-
-        if (dasprclipmask==0)
-            continue;
-
-#ifdef HAVE_CLIPSHAPE_FEATURE
-        if (curspr)
-            continue;  // next sector of this index
-#endif
-        for (j=headspritesect[dasect]; j>=0; j=nextspritesect[j])
-        {
-            const spritetype *const spr = &sprite[j];
-            const int32_t cstat = spr->cstat;
-
-            if ((cstat&dasprclipmask) == 0)
-                continue;
-
-#ifdef HAVE_CLIPSHAPE_FEATURE
-            if (clipsprite_try(spr, xmin,ymin, xmax,ymax))
-                continue;
-#endif
-            x1 = spr->x; y1 = spr->y;
-
-            switch (cstat&48)
-            {
-            case 0:
-                if (x1 >= xmin && x1 <= xmax && y1 >= ymin && y1 <= ymax)
-                {
-                    const int32_t daz = spr->z + spriteheightofs(j, &k, 1);
-
-                    if (pos->z > daz-k-flordist && pos->z < daz+ceildist)
-                    {
-                        int32_t bsz;
-                        bsz = (spr->clipdist<<2)+walldist; if (gx < 0) bsz = -bsz;
-                        addclipline(x1-bsz,y1-bsz,x1-bsz,y1+bsz,(int16_t)j+49152);
-                        bsz = (spr->clipdist<<2)+walldist; if (gy < 0) bsz = -bsz;
-                        addclipline(x1+bsz,y1-bsz,x1-bsz,y1-bsz,(int16_t)j+49152);
-                    }
-                }
-                break;
-
-            case 16:
-            {
-                const int32_t daz = spr->z + spriteheightofs(j, &k, 1);
-
-                if (pos->z > daz-k-flordist && pos->z < daz+ceildist)
-                {
-                    get_wallspr_points(spr, &x1, &x2, &y1, &y2);
-
-                    if (clipinsideboxline(cx,cy,x1,y1,x2,y2,rad) != 0)
-                    {
-                        dax = mulscale14(sintable[(spr->ang+256+512)&2047],walldist);
-                        day = mulscale14(sintable[(spr->ang+256)&2047],walldist);
-
-                        if ((x1-(pos->x))*(y2-(pos->y)) >= (x2-(pos->x))*(y1-(pos->y)))   //Front
-                        {
-                            addclipline(x1+dax,y1+day,x2+day,y2-dax,(int16_t)j+49152);
-                        }
-                        else
-                        {
-                            if ((cstat&64) != 0) continue;
-                            addclipline(x2-dax,y2-day,x1-day,y1+dax,(int16_t)j+49152);
-                        }
-
-                        //Side blocker
-                        if ((x2-x1)*((pos->x)-x1) + (y2-y1)*((pos->y)-y1) < 0)
-                            addclipline(x1-day,y1+dax,x1+dax,y1+day,(int16_t)j+49152);
-                        else if ((x1-x2)*((pos->x)-x2) + (y1-y2)*((pos->y)-y2) < 0)
-                            addclipline(x2+day,y2-dax,x2-dax,y2-day,(int16_t)j+49152);
-                    }
-                }
-                break;
-            }
-
-            case 32:
-            {
-                if (pos->z > spr->z - flordist && pos->z < spr->z + ceildist)
-                {
-                    if ((cstat&64) != 0)
-                        if ((pos->z > spr->z) == ((cstat&8)==0))
-                            continue;
-
-                    rxi[0] = x1;
-                    ryi[0] = y1;
-                    get_floorspr_points((tspritetype const *) spr, 0, 0, &rxi[0], &rxi[1], &rxi[2], &rxi[3],
-                                        &ryi[0], &ryi[1], &ryi[2], &ryi[3]);
-
-                    dax = mulscale14(sintable[(spr->ang-256+512)&2047],walldist);
-                    day = mulscale14(sintable[(spr->ang-256)&2047],walldist);
-
-                    if ((rxi[0]-(pos->x))*(ryi[1]-(pos->y)) < (rxi[1]-(pos->x))*(ryi[0]-(pos->y)))
-                    {
-                        if (clipinsideboxline(cx,cy,rxi[1],ryi[1],rxi[0],ryi[0],rad) != 0)
-                            addclipline(rxi[1]-day,ryi[1]+dax,rxi[0]+dax,ryi[0]+day,(int16_t)j+49152);
-                    }
-                    else if ((rxi[2]-(pos->x))*(ryi[3]-(pos->y)) < (rxi[3]-(pos->x))*(ryi[2]-(pos->y)))
-                    {
-                        if (clipinsideboxline(cx,cy,rxi[3],ryi[3],rxi[2],ryi[2],rad) != 0)
-                            addclipline(rxi[3]+day,ryi[3]-dax,rxi[2]-dax,ryi[2]-day,(int16_t)j+49152);
-                    }
-
-                    if ((rxi[1]-(pos->x))*(ryi[2]-(pos->y)) < (rxi[2]-(pos->x))*(ryi[1]-(pos->y)))
-                    {
-                        if (clipinsideboxline(cx,cy,rxi[2],ryi[2],rxi[1],ryi[1],rad) != 0)
-                            addclipline(rxi[2]-dax,ryi[2]-day,rxi[1]-day,ryi[1]+dax,(int16_t)j+49152);
-                    }
-                    else if ((rxi[3]-(pos->x))*(ryi[0]-(pos->y)) < (rxi[0]-(pos->x))*(ryi[3]-(pos->y)))
-                    {
-                        if (clipinsideboxline(cx,cy,rxi[0],ryi[0],rxi[3],ryi[3],rad) != 0)
-                            addclipline(rxi[0]+dax,ryi[0]+day,rxi[3]+day,ryi[3]-dax,(int16_t)j+49152);
-                    }
-                }
-                break;
-            }
-            }
-        }
-    }
-    while (clipsectcnt < clipsectnum || clipspritecnt < clipspritenum);
-
-#ifdef HAVE_CLIPSHAPE_FEATURE
-    if (curspr)
-    {
-        // restore original map
-        mapinfo_set(NULL, &origmapinfo);
-
-        clipsectnum = origclipsectnum;
-        Bmemcpy(clipsectorlist, origclipsectorlist, clipsectnum*sizeof(clipsectorlist[0]));
-    }
-#endif
-
-    int32_t hitwalls[4], hitwall;
-    int32_t cnt = clipmoveboxtracenum;
-
-    do
-    {
-        int32_t intx=goalx, inty=goaly;
-
-        hitwall = raytrace(pos->x, pos->y, &intx, &inty);
-        if (hitwall >= 0)
-        {
-            const int32_t lx = clipit[hitwall].x2-clipit[hitwall].x1;
-            const int32_t ly = clipit[hitwall].y2-clipit[hitwall].y1;
-            const uint64_t tempull = (int64_t)lx*(int64_t)lx + (int64_t)ly*(int64_t)ly;
-
-            if (tempull > 0 && tempull < INT32_MAX)
-            {
-                tempint2 = (int32_t)tempull;
-
-                tempint1 = (goalx-intx)*lx + (goaly-inty)*ly;
-
-                if ((klabs(tempint1)>>11) < tempint2)
-                    i = divscale20(tempint1,tempint2);
-                else
-                    i = 0;
-                goalx = mulscale20(lx,i)+intx;
-                goaly = mulscale20(ly,i)+inty;
-            }
-
-            tempint1 = dmulscale6(lx,oxvect,ly,oyvect);
-            for (i=cnt+1; i<=clipmoveboxtracenum; i++)
-            {
-                j = hitwalls[i];
-                tempint2 = dmulscale6(clipit[j].x2-clipit[j].x1, oxvect,
-                                      clipit[j].y2-clipit[j].y1, oyvect);
-                if ((tempint1^tempint2) < 0)
-                {
-                    updatesector(pos->x,pos->y,sectnum);
-                    return retval;
-                }
-            }
-
-            keepaway(&goalx, &goaly, hitwall);
-            xvect = (goalx-intx)<<14;
-            yvect = (goaly-inty)<<14;
-
-            if (cnt == clipmoveboxtracenum)
-                retval = (uint16_t)clipobjectval[hitwall];
-            hitwalls[cnt] = hitwall;
-        }
-        cnt--;
-
-        pos->x = intx;
-        pos->y = inty;
-    }
-    while ((xvect|yvect) != 0 && hitwall >= 0 && cnt > 0);
-
-    for (j=0; j<clipsectnum; j++)
-        if (inside(pos->x,pos->y,clipsectorlist[j]) == 1)
-        {
-            *sectnum = clipsectorlist[j];
-            return retval;
-        }
-
-    *sectnum = -1; tempint1 = INT32_MAX;
-    for (j=numsectors-1; j>=0; j--)
-        if (inside(pos->x,pos->y,j) == 1)
-        {
-            if (sector[j].ceilingstat&2)
-                tempint2 = getceilzofslope(j, pos->x, pos->y) - pos->z;
-            else
-                tempint2 = sector[j].ceilingz - pos->z;
-
-            if (tempint2 > 0)
-            {
-                if (tempint2 < tempint1)
-                    { *sectnum = j; tempint1 = tempint2; }
-            }
-            else
-            {
-                if (sector[j].floorstat&2)
-                    tempint2 = pos->z - getflorzofslope(j, pos->x, pos->y);
-                else
-                    tempint2 = pos->z - sector[j].floorz;
-
-                if (tempint2 <= 0)
-                {
-                    *sectnum = j;
-                    return retval;
-                }
-                if (tempint2 < tempint1)
-                    { *sectnum = j; tempint1 = tempint2; }
-            }
-        }
-
-    return retval;
-}
-
-
-//
-// pushmove
-//
-int32_t pushmove(vec3_t *vect, int16_t *sectnum,
-                 int32_t walldist, int32_t ceildist, int32_t flordist, uint32_t cliptype)
-{
-    int32_t i, j, k, t, dx, dy, dax, day, daz;
-    int32_t dir, bad, bad2;
-
-    const int32_t dawalclipmask = (cliptype&65535);
-//    const int32_t dasprclipmask = (cliptype>>16);
-
-    if (*sectnum < 0)
-        return -1;
-
-    k = 32;
-    dir = 1;
-    do
-    {
-        int32_t clipsectcnt;
-
-        bad = 0;
-
-        clipsectorlist[0] = *sectnum;
-        clipsectcnt = 0; clipsectnum = 1;
-        do
-        {
-            const walltype *wal;
-            const sectortype *sec;
-            int32_t startwall, endwall;
-#if 0
-            // Push FACE sprites
-            for(i=headspritesect[clipsectorlist[clipsectcnt]];i>=0;i=nextspritesect[i])
-            {
-                spr = &sprite[i];
-                if (((spr->cstat&48) != 0) && ((spr->cstat&48) != 48)) continue;
-                if ((spr->cstat&dasprclipmask) == 0) continue;
-
-                dax = (vect->x)-spr->x; day = (vect->y)-spr->y;
-                t = (spr->clipdist<<2)+walldist;
-                if ((klabs(dax) < t) && (klabs(day) < t))
-                {
-                    daz = spr->z + spriteheightofs(i, &t, 1);
-                    if (((vect->z) < daz+ceildist) && ((vect->z) > daz-t-flordist))
-                    {
-                        t = (spr->clipdist<<2)+walldist;
-
-                        j = getangle(dax,day);
-                        dx = (sintable[(j+512)&2047]>>11);
-                        dy = (sintable[(j)&2047]>>11);
-                        bad2 = 16;
-                        do
-                        {
-                            vect->x = (vect->x) + dx; vect->y = (vect->y) + dy;
-                            bad2--; if (bad2 == 0) break;
-                        } while ((klabs((vect->x)-spr->x) < t) && (klabs((vect->y)-spr->y) < t));
-                        bad = -1;
-                        k--; if (k <= 0) return(bad);
-                        updatesector(vect->x,vect->y,sectnum);
-                    }
-                }
-            }
-#endif
-            sec = &sector[clipsectorlist[clipsectcnt]];
-            if (dir > 0)
-                startwall = sec->wallptr, endwall = startwall + sec->wallnum;
-            else
-                endwall = sec->wallptr, startwall = endwall + sec->wallnum;
-
-            for (i=startwall,wal=&wall[startwall]; i!=endwall; i+=dir,wal+=dir)
-                if (clipinsidebox(vect->x,vect->y,i,walldist-4) == 1)
-                {
-                    j = 0;
-                    if (wal->nextsector < 0) j = 1;
-                    if (wal->cstat&dawalclipmask) j = 1;
-                    if (j == 0)
-                    {
-                        const sectortype *const sec2 = &sector[wal->nextsector];
-                        int32_t daz2;
-
-                        //Find closest point on wall (dax, day) to (vect->x, vect->y)
-                        dax = wall[wal->point2].x-wal->x;
-                        day = wall[wal->point2].y-wal->y;
-                        daz = dax*((vect->x)-wal->x) + day*((vect->y)-wal->y);
-                        if (daz <= 0)
-                            t = 0;
-                        else
-                        {
-                            daz2 = dax*dax+day*day;
-                            if (daz >= daz2) t = (1<<30); else t = divscale30(daz,daz2);
-                        }
-                        dax = wal->x + mulscale30(dax,t);
-                        day = wal->y + mulscale30(day,t);
-
-
-                        daz = getflorzofslope(clipsectorlist[clipsectcnt],dax,day);
-                        daz2 = getflorzofslope(wal->nextsector,dax,day);
-                        if ((daz2 < daz-(1<<8)) && ((sec2->floorstat&1) == 0))
-                            if (vect->z >= daz2-(flordist-1)) j = 1;
-
-                        daz = getceilzofslope(clipsectorlist[clipsectcnt],dax,day);
-                        daz2 = getceilzofslope(wal->nextsector,dax,day);
-                        if ((daz2 > daz+(1<<8)) && ((sec2->ceilingstat&1) == 0))
-                            if (vect->z <= daz2+(ceildist-1)) j = 1;
-                    }
-
-                    if (j != 0)
-                    {
-                        j = getangle(wall[wal->point2].x-wal->x,wall[wal->point2].y-wal->y);
-                        dx = (sintable[(j+1024)&2047]>>11);
-                        dy = (sintable[(j+512)&2047]>>11);
-                        bad2 = 16;
-                        do
-                        {
-                            vect->x = (vect->x) + dx; vect->y = (vect->y) + dy;
-                            bad2--; if (bad2 == 0) break;
-                        }
-                        while (clipinsidebox(vect->x,vect->y,i,walldist-4) != 0);
-                        bad = -1;
-                        k--; if (k <= 0) return(bad);
-                        updatesector(vect->x,vect->y,sectnum);
-                        if (*sectnum < 0) return -1;
-                    }
-                    else
-                    {
-                        for (j=clipsectnum-1; j>=0; j--)
-                            if (wal->nextsector == clipsectorlist[j]) break;
-                        if (j < 0) clipsectorlist[clipsectnum++] = wal->nextsector;
-                    }
-                }
-
-            clipsectcnt++;
-        }
-        while (clipsectcnt < clipsectnum);
-        dir = -dir;
-    }
-    while (bad != 0);
-
-    return(bad);
-}
-
-
 // breadth-first search helpers
 void bfirst_search_init(int16_t *list, uint8_t *bitmap, int32_t *eltnumptr, int32_t maxnum, int16_t firstelt)
 {
@@ -15249,7 +13162,7 @@ int32_t sectorofwall(int16_t theline)
 
 int32_t sectorofwall_noquick(int16_t theline)
 {
-    if (theline < 0 || theline >= numwalls)
+    if ((unsigned)theline >= numwalls)
         return -1;
 
     return sectorofwall_internal(theline);
@@ -15261,20 +13174,17 @@ int32_t getceilzofslopeptr(const sectortype *sec, int32_t dax, int32_t day)
     if (!(sec->ceilingstat&2))
         return sec->ceilingz;
 
-    {
-        const walltype *wal = &wall[sec->wallptr];
+    twalltype const *wal = (twalltype *)&wall[sec->wallptr];
 
-        // floor(sqrt(2**31-1)) == 46340
-        int32_t i, j, wx=wal->x, wy=wal->y;
-        int32_t dx = wall[wal->point2].x-wx, dy = wall[wal->point2].y-wy;
+    // floor(sqrt(2**31-1)) == 46340
+    vec2_t const w = *(vec2_t *) wal;
+    vec2_t const d ={ wall[wal->point2].x-w.x , wall[wal->point2].y-w.y };
 
-        i = nsqrtasm(uhypsq(dx,dy))<<5;
-        if (i == 0)
-            return sec->ceilingz;
+    int32_t const i = nsqrtasm(uhypsq(d.x,d.y))<<5;
+    if (i == 0) return sec->ceilingz;
 
-        j = dmulscale3(dx, day-wy, -dy, dax-wx);
-        return sec->ceilingz + (scale(sec->ceilingheinum,j>>1,i)<<1);
-    }
+    int32_t const j = dmulscale3(d.x, day-w.y, -d.y, dax-w.x);
+    return sec->ceilingz + (scale(sec->ceilingheinum,j>>1,i)<<1);
 }
 
 int32_t getflorzofslopeptr(const sectortype *sec, int32_t dax, int32_t day)
@@ -15282,41 +13192,37 @@ int32_t getflorzofslopeptr(const sectortype *sec, int32_t dax, int32_t day)
     if (!(sec->floorstat&2))
         return sec->floorz;
 
-    {
-        const walltype *wal = &wall[sec->wallptr];
+    twalltype const *wal = (twalltype *) &wall[sec->wallptr];
 
-        int32_t i, j, wx=wal->x, wy=wal->y;
-        int32_t dx = wall[wal->point2].x-wx, dy = wall[wal->point2].y-wy;
+    vec2_t const w = *(vec2_t *) wal;
+    vec2_t const d ={ wall[wal->point2].x-w.x , wall[wal->point2].y-w.y };
 
-        i = nsqrtasm(uhypsq(dx,dy))<<5;
-        if (i == 0)
-            return sec->floorz;
+    int32_t const i = nsqrtasm(uhypsq(d.x,d.y))<<5;
+    if (i == 0) return sec->floorz;
 
-        j = dmulscale3(dx, day-wy, -dy, dax-wx);
-        return sec->floorz + (scale(sec->floorheinum,j>>1,i)<<1);
-    }
+    int32_t const j = dmulscale3(d.x, day-w.y, -d.y, dax-w.x);
+    return sec->floorz + (scale(sec->floorheinum,j>>1,i)<<1);
 }
 
 void getzsofslopeptr(const sectortype *sec, int32_t dax, int32_t day, int32_t *ceilz, int32_t *florz)
 {
     *ceilz = sec->ceilingz; *florz = sec->floorz;
 
-    if ((sec->ceilingstat|sec->floorstat)&2)
-    {
-        int32_t i, j;
-        const walltype *wal = &wall[sec->wallptr], *wal2 = &wall[wal->point2];
-        const int32_t dx = wal2->x-wal->x, dy = wal2->y-wal->y;
+    if (((sec->ceilingstat|sec->floorstat)&2) != 2)
+        return;
 
-        i = nsqrtasm(uhypsq(dx,dy))<<5;
-        if (i == 0)
-            return;
+    twalltype const *wal = (twalltype *) &wall[sec->wallptr];
+    twalltype const *wal2 = (twalltype *) &wall[wal->point2];
+    const vec2_t d ={ wal2->x-wal->x, wal2->y-wal->y };
 
-        j = dmulscale3(dx,day-wal->y, -dy,dax-wal->x);
-        if (sec->ceilingstat&2)
-            *ceilz += scale(sec->ceilingheinum,j>>1,i)<<1;
-        if (sec->floorstat&2)
-            *florz += scale(sec->floorheinum,j>>1,i)<<1;
-    }
+    int32_t const i = nsqrtasm(uhypsq(d.x,d.y))<<5;
+    if (i == 0) return;
+
+    int32_t const j = dmulscale3(d.x,day-wal->y, -d.y,dax-wal->x);
+    if (sec->ceilingstat&2)
+        *ceilz += scale(sec->ceilingheinum,j>>1,i)<<1;
+    if (sec->floorstat&2)
+        *florz += scale(sec->floorheinum,j>>1,i)<<1;
 }
 
 
@@ -15367,13 +13273,11 @@ void alignflorslope(int16_t dasect, int32_t x, int32_t y, int32_t z)
 //
 int32_t loopnumofsector(int16_t sectnum, int16_t wallnum)
 {
-    int32_t i;
-
     int32_t numloops = 0;
     const int32_t startwall = sector[sectnum].wallptr;
     const int32_t endwall = startwall + sector[sectnum].wallnum;
 
-    for (i=startwall; i<endwall; i++)
+    for (int i=startwall; i<endwall; i++)
     {
         if (i == wallnum)
             return numloops;
diff --git a/polymer/eduke32/build/src/engine_priv.h b/polymer/eduke32/build/src/engine_priv.h
index 5300a5e4c..d9ce65706 100644
--- a/polymer/eduke32/build/src/engine_priv.h
+++ b/polymer/eduke32/build/src/engine_priv.h
@@ -1,7 +1,8 @@
+#pragma once
+
 #ifndef ENGINE_PRIV_H
 #define ENGINE_PRIV_H
 
-#define MAXCLIPNUM 1024
 #define MAXPERMS 512
 #define MAXARTFILES_BASE 200
 #define MAXARTFILES_TOTAL 220
@@ -28,6 +29,244 @@ extern "C" {
 extern "C" {
 #endif
 
+extern uint16_t ATTRIBUTE((used)) sqrtable[4096], ATTRIBUTE((used)) shlookup[4096+256];
+
+#if defined(_MSC_VER) && !defined(NOASM)
+
+    //
+    // Microsoft C Inline Assembly Routines
+    //
+
+    static inline int32_t nsqrtasm(int32_t a)
+    {
+        _asm
+        {
+            push ebx
+            mov eax, a
+            test eax, 0xff000000
+            mov ebx, eax
+            jnz short over24
+            shr ebx, 12
+            mov cx, word ptr shlookup[ebx*2]
+            jmp short under24
+            over24 :
+            shr ebx, 24
+                mov cx, word ptr shlookup[ebx*2+8192]
+                under24 :
+                shr eax, cl
+                mov cl, ch
+                mov ax, word ptr sqrtable[eax*2]
+                shr eax, cl
+                pop ebx
+        }
+    }
+
+    static inline int32_t msqrtasm(int32_t c)
+    {
+        _asm
+        {
+            push ebx
+            mov ecx, c
+            mov eax, 0x40000000
+            mov ebx, 0x20000000
+            begit:
+            cmp ecx, eax
+                jl skip
+                sub ecx, eax
+                lea eax, [eax+ebx*4]
+                skip :
+                sub eax, ebx
+                shr eax, 1
+                shr ebx, 2
+                jnz begit
+                cmp ecx, eax
+                sbb eax, -1
+                shr eax, 1
+                pop ebx
+        }
+    }
+
+    static inline int32_t getclipmask(int32_t a, int32_t b, int32_t c, int32_t d)
+    {
+        _asm
+        {
+            push ebx
+            mov eax, a
+            mov ebx, b
+            mov ecx, c
+            mov edx, d
+            sar eax, 31
+            add ebx, ebx
+            adc eax, eax
+            add ecx, ecx
+            adc eax, eax
+            add edx, edx
+            adc eax, eax
+            mov ebx, eax
+            shl ebx, 4
+            or al, 0xf0
+            xor eax, ebx
+            pop ebx
+        }
+    }
+
+    static inline int32_t getkensmessagecrc(void *b)
+    {
+        _asm
+        {
+            push ebx
+            mov ebx, b
+            xor eax, eax
+            mov ecx, 32
+            beg:
+            mov edx, dword ptr[ebx+ecx*4-4]
+                ror edx, cl
+                adc eax, edx
+                bswap eax
+                loop short beg
+                pop ebx
+        }
+    }
+
+#elif defined(__GNUC__) && defined(__i386__) && !defined(NOASM)	// _MSC_VER
+
+    //
+    // GCC "Inline" Assembly Routines
+    //
+
+#define nsqrtasm(a) \
+    ({ int32_t __r, __a=(a); \
+       __asm__ __volatile__ ( \
+        "testl $0xff000000, %%eax\n\t" \
+        "movl %%eax, %%ebx\n\t" \
+        "jnz 0f\n\t" \
+        "shrl $12, %%ebx\n\t" \
+        "movw " ASMSYM("shlookup") "(,%%ebx,2), %%cx\n\t" \
+        "jmp 1f\n\t" \
+        "0:\n\t" \
+        "shrl $24, %%ebx\n\t" \
+        "movw (" ASMSYM("shlookup") "+8192)(,%%ebx,2), %%cx\n\t" \
+        "1:\n\t" \
+        "shrl %%cl, %%eax\n\t" \
+        "movb %%ch, %%cl\n\t" \
+        "movw " ASMSYM("sqrtable") "(,%%eax,2), %%ax\n\t" \
+        "shrl %%cl, %%eax" \
+        : "=a" (__r) : "a" (__a) : "ebx", "ecx", "cc"); \
+     __r; })
+
+    // edx is blown by this code somehow?!
+#define msqrtasm(c) \
+    ({ int32_t __r, __c=(c); \
+       __asm__ __volatile__ ( \
+        "movl $0x40000000, %%eax\n\t" \
+        "movl $0x20000000, %%ebx\n\t" \
+        "0:\n\t" \
+        "cmpl %%eax, %%ecx\n\t" \
+        "jl 1f\n\t" \
+        "subl %%eax, %%ecx\n\t" \
+        "leal (%%eax,%%ebx,4), %%eax\n\t" \
+        "1:\n\t" \
+        "subl %%ebx, %%eax\n\t" \
+        "shrl $1, %%eax\n\t" \
+        "shrl $2, %%ebx\n\t" \
+        "jnz 0b\n\t" \
+        "cmpl %%eax, %%ecx\n\t" \
+        "sbbl $-1, %%eax\n\t" \
+        "shrl $1, %%eax" \
+        : "=a" (__r) : "c" (__c) : "edx","ebx", "cc"); \
+     __r; })
+
+#define getclipmask(a,b,c,d) \
+    ({ int32_t __a=(a), __b=(b), __c=(c), __d=(d); \
+       __asm__ __volatile__ ("sarl $31, %%eax; addl %%ebx, %%ebx; adcl %%eax, %%eax; " \
+                "addl %%ecx, %%ecx; adcl %%eax, %%eax; addl %%edx, %%edx; " \
+                "adcl %%eax, %%eax; movl %%eax, %%ebx; shl $4, %%ebx; " \
+                "orb $0xf0, %%al; xorl %%ebx, %%eax" \
+        : "=a" (__a), "=b" (__b), "=c" (__c), "=d" (__d) \
+        : "a" (__a), "b" (__b), "c" (__c), "d" (__d) : "cc"); \
+     __a; })
+
+
+#define getkensmessagecrc(b) \
+    ({ int32_t __a, __b=(b); \
+       __asm__ __volatile__ ( \
+        "xorl %%eax, %%eax\n\t" \
+        "movl $32, %%ecx\n\t" \
+        "0:\n\t" \
+        "movl -4(%%ebx,%%ecx,4), %%edx\n\t" \
+        "rorl %%cl, %%edx\n\t" \
+        "adcl %%edx, %%eax\n\t" \
+        "bswapl %%eax\n\t" \
+        "loop 0b" \
+        : "=a" (__a) : "b" (__b) : "ecx", "edx" \
+     __a; })
+
+#else   // __GNUC__ && __i386__
+
+    static inline int32_t nsqrtasm(uint32_t a)
+    {
+        // JBF 20030901: This was a damn lot simpler to reverse engineer than
+        // msqrtasm was. Really, it was just like simplifying an algebra equation.
+        uint16_t c;
+
+        if (a & 0xff000000)  			// test eax, 0xff000000  /  jnz short over24
+        {
+            c = shlookup[(a >> 24) + 4096];	// mov ebx, eax
+                                            // over24: shr ebx, 24
+                                            // mov cx, word ptr shlookup[ebx*2+8192]
+        }
+        else
+        {
+            c = shlookup[a >> 12];		// mov ebx, eax
+                                        // shr ebx, 12
+                                        // mov cx, word ptr shlookup[ebx*2]
+                                        // jmp short under24
+        }
+        a >>= c&0xff;				// under24: shr eax, cl
+        a = (a&0xffff0000)|(sqrtable[a]);	// mov ax, word ptr sqrtable[eax*2]
+        a >>= ((c&0xff00) >> 8);		// mov cl, ch
+                                        // shr eax, cl
+        return a;
+    }
+
+    static inline int32_t msqrtasm(uint32_t c)
+    {
+        uint32_t a, b;
+
+        a = 0x40000000l;		// mov eax, 0x40000000
+        b = 0x20000000l;		// mov ebx, 0x20000000
+        do  				// begit:
+        {
+            if (c >= a)  		// cmp ecx, eax	 /  jl skip
+            {
+                c -= a;		// sub ecx, eax
+                a += b*4;	// lea eax, [eax+ebx*4]
+            }			// skip:
+            a -= b;			// sub eax, ebx
+            a >>= 1;		// shr eax, 1
+            b >>= 2;		// shr ebx, 2
+        } while (b);			// jnz begit
+        if (c >= a)			// cmp ecx, eax
+            a++;			// sbb eax, -1
+        a >>= 1;			// shr eax, 1
+        return a;
+    }
+
+    static inline int32_t getclipmask(int32_t a, int32_t b, int32_t c, int32_t d)
+    {
+        // Ken did this
+        d = ((a<0)<<3) + ((b<0)<<2) + ((c<0)<<1) + (d<0);
+        return(((d<<4)^0xf0)|d);
+    }
+
+    inline int32_t getkensmessagecrc(int32_t b)
+    {
+        UNREFERENCED_PARAMETER(b);
+        return 0x56c764d4l;
+    }
+
+#endif
+
 extern int16_t thesector[MAXWALLSB], thewall[MAXWALLSB];
 extern int16_t bunchfirst[MAXWALLSB], bunchlast[MAXWALLSB];
 extern int16_t maskwall[MAXWALLSB], maskwallcnt;
@@ -66,6 +305,7 @@ extern int32_t xb1[MAXWALLSB];
 extern int32_t rx1[MAXWALLSB], ry1[MAXWALLSB];
 extern int16_t bunchp2[MAXWALLSB];
 extern int16_t numscans, numbunches;
+extern int32_t rxi[8], ryi[8];
 
 #ifdef USE_OPENGL
 
@@ -76,6 +316,13 @@ void calc_and_apply_fog(int32_t tile, int32_t shade, int32_t vis, int32_t pal);
 void calc_and_apply_fog_factor(int32_t tile, int32_t shade, int32_t vis, int32_t pal, float factor);
 #endif
 
+extern void get_wallspr_points(const spritetype *spr, int32_t *x1, int32_t *x2,
+    int32_t *y1, int32_t *y2);
+extern void get_floorspr_points(const tspritetype *spr, int32_t px, int32_t py,
+    int32_t *x1, int32_t *x2, int32_t *x3, int32_t *x4,
+    int32_t *y1, int32_t *y2, int32_t *y3, int32_t *y4);
+
+
 // int32_t wallmost(int16_t *mostbuf, int32_t w, int32_t sectnum, char dastat);
 int32_t wallfront(int32_t l1, int32_t l2);
 
diff --git a/polymer/eduke32/build/src/mhk.c b/polymer/eduke32/build/src/mhk.c
new file mode 100644
index 000000000..45131560f
--- /dev/null
+++ b/polymer/eduke32/build/src/mhk.c
@@ -0,0 +1,338 @@
+
+#include "compat.h"
+#include "build.h"
+#include "scriptfile.h"
+
+usermaphack_t g_loadedMapHack;  // used only for the MD4 part
+
+int32_t compare_usermaphacks(const void *a, const void *b)
+{
+    return Bmemcmp(((usermaphack_t const *) a)->md4, ((usermaphack_t const *) b)->md4, 16);
+}
+usermaphack_t *usermaphacks;
+int32_t num_usermaphacks;
+
+#ifdef POLYMER
+static int16_t maphacklightcnt=0;
+static int16_t maphacklight[PR_MAXLIGHTS];
+
+void delete_maphack_lights()
+{
+    int32_t i;
+    for (i=0; i<maphacklightcnt; i++)
+    {
+        if (maphacklight[i] >= 0)
+            polymer_deletelight(maphacklight[i]);
+        maphacklight[i] = -1;
+    }
+
+    maphacklightcnt = 0;
+}
+#else
+void delete_maphack_lights() {}
+#endif
+
+//
+// loadmaphack
+//
+int32_t loadmaphack(const char *filename)
+{
+    enum
+    {
+        T_SPRITE = 0,
+        T_ANGOFF,
+        T_NOMODEL,
+        T_NOANIM,
+        T_PITCH,
+        T_ROLL,
+        T_MDXOFF,
+        T_MDYOFF,
+        T_MDZOFF,
+        T_AWAY1,
+        T_AWAY2,
+        T_LIGHT,
+    };
+
+    static struct { const char *text; int32_t tokenid; } legaltokens [] =
+    {
+        { "sprite", T_SPRITE },
+        { "angleoff", T_ANGOFF },
+        { "angoff", T_ANGOFF },
+        { "notmd2", T_NOMODEL },
+        { "notmd3", T_NOMODEL },
+        { "notmd", T_NOMODEL },
+        { "nomd2anim", T_NOANIM },
+        { "nomd3anim", T_NOANIM },
+        { "nomdanim", T_NOANIM },
+        { "pitch", T_PITCH },
+        { "roll", T_ROLL },
+        { "mdxoff", T_MDXOFF },
+        { "mdyoff", T_MDYOFF },
+        { "mdzoff", T_MDZOFF },
+        { "away1", T_AWAY1 },
+        { "away2", T_AWAY2 },
+        { "light", T_LIGHT },
+        { NULL, -1 }
+    };
+
+    scriptfile *script = NULL;
+    char *tok, *cmdtokptr;
+    int32_t i;
+    int32_t whichsprite = -1;
+    static char fn[BMAX_PATH];
+
+#ifdef POLYMER
+    int32_t toomanylights = 0;
+
+    delete_maphack_lights();
+#endif
+
+    if (filename)
+    {
+        Bmemset(spriteext, 0, sizeof(spriteext_t) * MAXSPRITES);
+        Bmemset(spritesmooth, 0, sizeof(spritesmooth_t) *(MAXSPRITES+MAXUNIQHUDID));
+        Bstrcpy(fn, filename);
+        script = scriptfile_fromfile(filename);
+    }
+    else if (fn[0])
+    {
+        // re-load
+        // XXX: what if we changed between levels? Could a wrong maphack be loaded?
+        script = scriptfile_fromfile(fn);
+    }
+
+    if (!script)
+    {
+        fn[0] = 0;
+        return -1;
+    }
+
+    while (1)
+    {
+        tok = scriptfile_gettoken(script);
+        if (!tok) break;
+        for (i=0; legaltokens[i].text; i++) if (!Bstrcasecmp(tok, legaltokens[i].text)) break;
+        cmdtokptr = script->ltextptr;
+
+        if (!filename && legaltokens[i].tokenid != T_LIGHT) continue;
+
+        switch (legaltokens[i].tokenid)
+        {
+        case T_SPRITE:     // sprite <xx>
+            if (scriptfile_getnumber(script, &whichsprite)) break;
+
+            if ((unsigned) whichsprite >= (unsigned) MAXSPRITES)
+            {
+                // sprite number out of range
+                initprintf("Sprite number out of range 0-%d on line %s:%d\n",
+                    MAXSPRITES-1, script->filename, scriptfile_getlinum(script, cmdtokptr));
+                whichsprite = -1;
+                break;
+            }
+
+            break;
+        case T_ANGOFF:     // angoff <xx>
+        {
+            int32_t ang;
+            if (scriptfile_getnumber(script, &ang)) break;
+
+            if (whichsprite < 0)
+            {
+                // no sprite directive preceeding
+                initprintf("Ignoring angle offset directive because of absent/invalid sprite number on line %s:%d\n",
+                    script->filename, scriptfile_getlinum(script, cmdtokptr));
+                break;
+            }
+            spriteext[whichsprite].angoff = (int16_t) ang;
+        }
+        break;
+        case T_NOMODEL:      // notmd
+            if (whichsprite < 0)
+            {
+                // no sprite directive preceeding
+                initprintf("Ignoring not-MD2/MD3 directive because of absent/invalid sprite number on line %s:%d\n",
+                    script->filename, scriptfile_getlinum(script, cmdtokptr));
+                break;
+            }
+            spriteext[whichsprite].flags |= SPREXT_NOTMD;
+            break;
+        case T_NOANIM:      // nomdanim
+            if (whichsprite < 0)
+            {
+                // no sprite directive preceeding
+                initprintf("Ignoring no-MD2/MD3-anim directive because of absent/invalid sprite number on line %s:%d\n",
+                    script->filename, scriptfile_getlinum(script, cmdtokptr));
+                break;
+            }
+            spriteext[whichsprite].flags |= SPREXT_NOMDANIM;
+            break;
+        case T_PITCH:     // pitch <xx>
+        {
+            int32_t pitch;
+            if (scriptfile_getnumber(script, &pitch)) break;
+
+            if (whichsprite < 0)
+            {
+                // no sprite directive preceeding
+                initprintf("Ignoring pitch directive because of absent/invalid sprite number on line %s:%d\n",
+                    script->filename, scriptfile_getlinum(script, cmdtokptr));
+                break;
+            }
+            spriteext[whichsprite].pitch = (int16_t) pitch;
+        }
+        break;
+        case T_ROLL:     // roll <xx>
+        {
+            int32_t roll;
+            if (scriptfile_getnumber(script, &roll)) break;
+
+            if (whichsprite < 0)
+            {
+                // no sprite directive preceeding
+                initprintf("Ignoring roll directive because of absent/invalid sprite number on line %s:%d\n",
+                    script->filename, scriptfile_getlinum(script, cmdtokptr));
+                break;
+            }
+            spriteext[whichsprite].roll = (int16_t) roll;
+        }
+        break;
+        case T_MDXOFF:     // mdxoff <xx>
+        {
+            int32_t i;
+            if (scriptfile_getnumber(script, &i)) break;
+
+            if (whichsprite < 0)
+            {
+                // no sprite directive preceeding
+                initprintf("Ignoring mdxoff directive because of absent/invalid sprite number on line %s:%d\n",
+                    script->filename, scriptfile_getlinum(script, cmdtokptr));
+                break;
+            }
+            spriteext[whichsprite].offset.x = i;
+        }
+        break;
+        case T_MDYOFF:     // mdyoff <xx>
+        {
+            int32_t i;
+            if (scriptfile_getnumber(script, &i)) break;
+
+            if (whichsprite < 0)
+            {
+                // no sprite directive preceeding
+                initprintf("Ignoring mdyoff directive because of absent/invalid sprite number on line %s:%d\n",
+                    script->filename, scriptfile_getlinum(script, cmdtokptr));
+                break;
+            }
+            spriteext[whichsprite].offset.y = i;
+        }
+        break;
+        case T_MDZOFF:     // mdzoff <xx>
+        {
+            int32_t i;
+            if (scriptfile_getnumber(script, &i)) break;
+
+            if (whichsprite < 0)
+            {
+                // no sprite directive preceeding
+                initprintf("Ignoring mdzoff directive because of absent/invalid sprite number on line %s:%d\n",
+                    script->filename, scriptfile_getlinum(script, cmdtokptr));
+                break;
+            }
+            spriteext[whichsprite].offset.z = i;
+        }
+        break;
+        case T_AWAY1:      // away1
+            if (whichsprite < 0)
+            {
+                // no sprite directive preceeding
+                initprintf("Ignoring moving away directive because of absent/invalid sprite number on line %s:%d\n",
+                    script->filename, scriptfile_getlinum(script, cmdtokptr));
+                break;
+            }
+            spriteext[whichsprite].flags |= SPREXT_AWAY1;
+            break;
+        case T_AWAY2:      // away2
+            if (whichsprite < 0)
+            {
+                // no sprite directive preceeding
+                initprintf("Ignoring moving away directive because of absent/invalid sprite number on line %s:%d\n",
+                    script->filename, scriptfile_getlinum(script, cmdtokptr));
+                break;
+            }
+            spriteext[whichsprite].flags |= SPREXT_AWAY2;
+            break;
+#ifdef POLYMER
+        case T_LIGHT:      // light sector x y z range r g b radius faderadius angle horiz minshade maxshade priority tilenum
+        {
+            int32_t value;
+            int16_t lightid;
+#pragma pack(push,1)
+            _prlight light;
+#pragma pack(pop)
+            if (toomanylights)
+                break;  // ignore further light defs
+
+            scriptfile_getnumber(script, &value);
+            light.sector = value;
+            scriptfile_getnumber(script, &value);
+            light.x = value;
+            scriptfile_getnumber(script, &value);
+            light.y = value;
+            scriptfile_getnumber(script, &value);
+            light.z = value;
+            scriptfile_getnumber(script, &value);
+            light.range = value;
+            scriptfile_getnumber(script, &value);
+            light.color[0] = value;
+            scriptfile_getnumber(script, &value);
+            light.color[1] = value;
+            scriptfile_getnumber(script, &value);
+            light.color[2] = value;
+            scriptfile_getnumber(script, &value);
+            light.radius = value;
+            scriptfile_getnumber(script, &value);
+            light.faderadius = value;
+            scriptfile_getnumber(script, &value);
+            light.angle = value;
+            scriptfile_getnumber(script, &value);
+            light.horiz = value;
+            scriptfile_getnumber(script, &value);
+            light.minshade = value;
+            scriptfile_getnumber(script, &value);
+            light.maxshade = value;
+            scriptfile_getnumber(script, &value);
+            light.priority = value;
+            scriptfile_getnumber(script, &value);
+            light.tilenum = value;
+
+            light.publicflags.emitshadow = 1;
+            light.publicflags.negative = 0;
+
+            if (getrendermode() == REND_POLYMER)
+            {
+                if (maphacklightcnt == PR_MAXLIGHTS)
+                {
+                    initprintf("warning: max light count %d exceeded, "
+                        "ignoring further light defs\n", PR_MAXLIGHTS);
+                    toomanylights = 1;
+                    break;
+                }
+
+                lightid = polymer_addlight(&light);
+                if (lightid>=0)
+                    maphacklight[maphacklightcnt++] = lightid;
+            }
+
+            break;
+        }
+#endif // POLYMER
+
+        default:
+            // unrecognised token
+            break;
+        }
+    }
+
+    scriptfile_close(script);
+    return 0;
+}
diff --git a/polymer/eduke32/build/src/screenshot.c b/polymer/eduke32/build/src/screenshot.c
index e6abdc59e..3d12fc2bb 100644
--- a/polymer/eduke32/build/src/screenshot.c
+++ b/polymer/eduke32/build/src/screenshot.c
@@ -3,7 +3,6 @@
 # include <string.h>
 #endif
 
-#include "compat.h"
 #include "build.h"
 #include "editor.h"
 
diff --git a/polymer/eduke32/eduke32.vcxproj b/polymer/eduke32/eduke32.vcxproj
index a34bc4436..6370afa95 100644
--- a/polymer/eduke32/eduke32.vcxproj
+++ b/polymer/eduke32/eduke32.vcxproj
@@ -105,6 +105,7 @@
     <ClInclude Include="build\include\build.h" />
     <ClInclude Include="build\include\buildtypes.h" />
     <ClInclude Include="build\include\cache1d.h" />
+    <ClInclude Include="build\include\clip.h" />
     <ClInclude Include="build\include\colmatch.h" />
     <ClInclude Include="build\include\compat.h" />
     <ClInclude Include="build\include\common.h" />
@@ -258,6 +259,7 @@
     <ClCompile Include="build\src\baselayer.c" />
     <ClCompile Include="build\src\build.c" />
     <ClCompile Include="build\src\cache1d.c" />
+    <ClCompile Include="build\src\clip.c" />
     <ClCompile Include="build\src\colmatch.c" />
     <ClCompile Include="build\src\common.c" />
     <ClCompile Include="build\src\compat.c" />
@@ -276,6 +278,7 @@
     <ClCompile Include="build\src\lzwnew.c" />
     <ClCompile Include="build\src\md4.c" />
     <ClCompile Include="build\src\mdsprite.c" />
+    <ClCompile Include="build\src\mhk.c" />
     <ClCompile Include="build\src\mutex.c" />
     <ClCompile Include="build\src\osd.c" />
     <ClCompile Include="build\src\palette.c" />
diff --git a/polymer/eduke32/eduke32.vcxproj.filters b/polymer/eduke32/eduke32.vcxproj.filters
index a68d72a20..68f748e66 100644
--- a/polymer/eduke32/eduke32.vcxproj.filters
+++ b/polymer/eduke32/eduke32.vcxproj.filters
@@ -537,6 +537,9 @@
     <ClInclude Include="build\include\colmatch.h">
       <Filter>build\headers</Filter>
     </ClInclude>
+    <ClInclude Include="build\include\clip.h">
+      <Filter>build\headers</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="build\src\a-c.c">
@@ -947,6 +950,12 @@
     <ClCompile Include="build\src\screenshot.c">
       <Filter>build\source</Filter>
     </ClCompile>
+    <ClCompile Include="build\src\mhk.c">
+      <Filter>build\source</Filter>
+    </ClCompile>
+    <ClCompile Include="build\src\clip.c">
+      <Filter>build\source</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <None Include="Makefile.msvc">