diff --git a/source/build/src/engine.cpp b/source/build/src/engine.cpp
index b63047ea2..89fba4f17 100644
--- a/source/build/src/engine.cpp
+++ b/source/build/src/engine.cpp
@@ -29,6 +29,7 @@
 #include "gamestate.h"
 #include "inputstate.h"
 #include "printf.h"
+#include "gamecontrol.h"
 
 #ifdef USE_OPENGL
 # include "mdsprite.h"
@@ -1777,371 +1778,6 @@ killsprite:
 }
 
 
-//==========================================================================
-//
-//
-//
-//==========================================================================
-
-void FillPolygon(int* rx1, int* ry1, int* xb1, int32_t npoints, int picnum, int palette, int shade, int props, const FVector2& xtex, const FVector2& ytex, const FVector2& otex,
-    int clipx1, int clipy1, int clipx2, int clipy2)
-{
-    //Convert int32_t to float (in-place)
-    TArray<FVector4> points(npoints, true);
-    using Point = std::pair<float, float>;
-    std::vector<std::vector<Point>> polygon;
-    std::vector<Point>* curPoly;
-
-    polygon.resize(1);
-    curPoly = &polygon.back();
-
-    for (bssize_t i = 0; i < npoints; ++i)
-    {
-        auto X = ((float)rx1[i]) * (1.0f / 4096.f);
-        auto Y = ((float)ry1[i]) * (1.0f / 4096.f);
-        curPoly->push_back(std::make_pair(X, Y));
-        if (xb1[i] < i && i < npoints - 1)
-        {
-            polygon.resize(polygon.size() + 1);
-            curPoly = &polygon.back();
-        }
-    }
-    // Now make sure that the outer boundary is the first polygon by picking a point that's as much to the outside as possible.
-    int outer = 0;
-    float minx = FLT_MAX;
-    float miny = FLT_MAX;
-    for (size_t a = 0; a < polygon.size(); a++)
-    {
-        for (auto& pt : polygon[a])
-        {
-            if (pt.first < minx || (pt.first == minx && pt.second < miny))
-            {
-                minx = pt.first;
-                miny = pt.second;
-                outer = a;
-            }
-        }
-    }
-    if (outer != 0) std::swap(polygon[0], polygon[outer]);
-    auto indices = mapbox::earcut(polygon);
-
-    int p = 0;
-    for (size_t a = 0; a < polygon.size(); a++)
-    {
-        for (auto& pt : polygon[a])
-        {
-            FVector4 point = { pt.first, pt.second, float(pt.first * xtex.X + pt.second * ytex.X + otex.X), float(pt.first * xtex.Y + pt.second * ytex.Y + otex.Y) };
-            points[p++] = point;
-        }
-    }
-
-    int maskprops = (props >> 7) & DAMETH_MASKPROPS;
-    FRenderStyle rs = LegacyRenderStyles[STYLE_Translucent];
-    double alpha = 1.;
-    if (maskprops > DAMETH_MASK)
-    {
-        rs = GetRenderStyle(0, maskprops == DAMETH_TRANS2);
-        alpha = GetAlphaFromBlend(maskprops, 0);
-    }
-    int translation = TRANSLATION(Translation_Remap + curbasepal, palette);
-    int light = clamp(scale((numshades - shade), 255, numshades), 0, 255);
-    PalEntry pe = PalEntry(uint8_t(alpha*255), light, light, light);
-
-    twod->AddPoly(tileGetTexture(picnum), points.Data(), points.Size(), indices.data(), indices.size(), translation, pe, rs, clipx1, clipy1, clipx2, clipy2);
-}
-
-void drawlinergb(int32_t x1, int32_t y1, int32_t x2, int32_t y2, PalEntry p)
-{
-    twod->AddLine(x1 / 4096.f, y1 / 4096.f, x2 / 4096.f, y2 / 4096.f, windowxy1.x, windowxy1.y, windowxy2.x, windowxy2.y, p);
-}
-
-void drawlinergb(int32_t x1, int32_t y1, int32_t x2, int32_t y2, palette_t p)
-{
-    drawlinergb(x1, y1, x2, y2, PalEntry(p.r, p.g, p.b));
-}
-
-void renderDrawLine(int32_t x1, int32_t y1, int32_t x2, int32_t y2, uint8_t col)
-{
-    drawlinergb(x1, y1, x2, y2, GPalette.BaseColors[GPalette.Remap[col]]);
-}
-
-
-//==========================================================================
-//
-//
-//
-//==========================================================================
-
-
-#include "build.h"
-#include "../src/engine_priv.h"
-
-
-//
-// fillpolygon (internal)
-//
-static void renderFillPolygon(int32_t npoints)
-{
-    // fix for bad next-point (xb1) values...
-    for (int z = 0; z < npoints; z++)
-        if ((unsigned)xb1[z] >= (unsigned)npoints)
-            xb1[z] = 0;
-
-    FVector2 xtex, ytex, otex;
-    int x1 = mulscale16(globalx1, xyaspect);
-    int y2 = mulscale16(globaly2, xyaspect);
-    xtex.X = ((float)asm1) * (1.f / 4294967296.f);
-    xtex.Y = ((float)asm2) * (1.f / 4294967296.f);
-    ytex.X = ((float)x1) * (1.f / 4294967296.f);
-    ytex.Y = ((float)y2) * (-1.f / 4294967296.f);
-    otex.X = (fxdim * xtex.X + fydim * ytex.X) * -0.5f + fglobalposx * (1.f / 4294967296.f);
-    otex.Y = (fxdim * xtex.Y + fydim * ytex.Y) * -0.5f - fglobalposy * (1.f / 4294967296.f);
-    FillPolygon(rx1, ry1, xb1, npoints, globalpicnum, globalpal, globalshade, globalorientation, xtex, ytex, otex, windowxy1.x, windowxy1.y, windowxy2.x, windowxy2.y);
-}
-
-//
-// drawmapview
-//
-void renderDrawMapView(int32_t dax, int32_t day, int32_t zoome, int16_t ang)
-{
-    int32_t i, j, k, l;
-    int32_t x, y;
-    int32_t s, ox, oy;
-
-    int32_t const oyxaspect = yxaspect, oviewingrange = viewingrange;
-
-    renderSetAspect(65536, divscale16((320*5)/8, 200));
-
-    Bmemset(gotsector, 0, sizeof(gotsector));
-
-    vec2_t const c1 = { (windowxy1.x<<12), (windowxy1.y<<12) };
-    vec2_t const c2 = { ((windowxy2.x+1)<<12)-1, ((windowxy2.y+1)<<12)-1 };
-
-    zoome <<= 8;
-
-    vec2_t const bakgvect = { divscale28(sintable[(1536 - ang) & 2047], zoome),
-                        divscale28(sintable[(2048 - ang) & 2047], zoome) };
-    vec2_t const vect = { mulscale8(sintable[(2048 - ang) & 2047], zoome), mulscale8(sintable[(1536 - ang) & 2047], zoome) };
-    vec2_t const vect2 = { mulscale16(vect.x, yxaspect), mulscale16(vect.y, yxaspect) };
-
-    int32_t sortnum = 0;
-
-    usectorptr_t sec;
-
-    for (s=0,sec=(usectorptr_t)&sector[s]; s<numsectors; s++,sec++)
-        if (gFullMap || show2dsector[s])
-        {
-            int32_t npoints = 0; i = 0;
-            int32_t startwall = sec->wallptr;
-            j = startwall; l = 0;
-            uwallptr_t wal;
-            int32_t w;
-            for (w=sec->wallnum,wal=(uwallptr_t)&wall[startwall]; w>0; w--,wal++,j++)
-            {
-                k = lastwall(j);
-                if ((k > j) && (npoints > 0)) { xb1[npoints-1] = l; l = npoints; } //overwrite point2
-                //wall[k].x wal->x wall[wal->point2].x
-                //wall[k].y wal->y wall[wal->point2].y
-                if (!dmulscale1(wal->x-wall[k].x,wall[wal->point2].y-wal->y,-(wal->y-wall[k].y),wall[wal->point2].x-wal->x)) continue;
-                ox = wal->x - dax; oy = wal->y - day;
-                x = dmulscale16(ox,vect.x,-oy,vect.y) + (xdim<<11);
-                y = dmulscale16(oy,vect2.x,ox,vect2.y) + (ydim<<11);
-                i |= getclipmask(x-c1.x,c2.x-x,y-c1.y,c2.y-y);
-                rx1[npoints] = x;
-                ry1[npoints] = y;
-                xb1[npoints] = npoints+1;
-                npoints++;
-            }
-            if (npoints > 0) xb1[npoints-1] = l; //overwrite point2
-
-            vec2_t bak = { rx1[0], mulscale16(ry1[0]-(ydim<<11),xyaspect)+(ydim<<11) };
-
-
-            //Collect floor sprites to draw
-            for (i=headspritesect[s]; i>=0; i=nextspritesect[i])
-            {
-                if (sprite[i].cstat & 32768)
-                    continue;
-
-                if ((sprite[i].cstat & 48) == 32)
-                {
-                    if ((sprite[i].cstat & (64 + 8)) == (64 + 8))
-                        continue;
-                    tsprite[sortnum++].owner = i;
-                }
-            }
-            gotsector[s>>3] |= pow2char[s&7];
-
-            globalorientation = (int32_t)sec->floorstat;
-            if ((globalorientation&1) != 0) continue;
-
-            globalpal = sec->floorpal;
-
-            globalpicnum = sec->floorpicnum;
-            if ((unsigned)globalpicnum >= (unsigned)MAXTILES) globalpicnum = 0;
-            tileUpdatePicnum(&globalpicnum, s);
-            setgotpic(globalpicnum);
-            if ((tilesiz[globalpicnum].x <= 0) || (tilesiz[globalpicnum].y <= 0)) continue;
-
-			globalshade = max(min<int>(sec->floorshade, numshades - 1), 0);
-            if ((globalorientation&64) == 0)
-            {
-                set_globalpos(dax, day, globalposz);
-                globalx1 = bakgvect.x; globaly1 = bakgvect.y;
-                globalx2 = bakgvect.x; globaly2 = bakgvect.y;
-            }
-            else
-            {
-                ox = wall[wall[startwall].point2].x - wall[startwall].x;
-                oy = wall[wall[startwall].point2].y - wall[startwall].y;
-                i = nsqrtasm(uhypsq(ox,oy)); if (i == 0) continue;
-                i = 1048576/i;
-                globalx1 = mulscale10(dmulscale10(ox,bakgvect.x,oy,bakgvect.y),i);
-                globaly1 = mulscale10(dmulscale10(ox,bakgvect.y,-oy,bakgvect.x),i);
-                ox = (bak.x>>4)-(xdim<<7); oy = (bak.y>>4)-(ydim<<7);
-                globalposx = dmulscale28(-oy, globalx1, -ox, globaly1);
-                globalposy = dmulscale28(-ox, globalx1, oy, globaly1);
-                globalx2 = -globalx1;
-                globaly2 = -globaly1;
-
-                int32_t const daslope = sector[s].floorheinum;
-                i = nsqrtasm(daslope*daslope+16777216);
-                set_globalpos(globalposx, mulscale12(globalposy,i), globalposz);
-                globalx2 = mulscale12(globalx2,i);
-                globaly2 = mulscale12(globaly2,i);
-            }
-
-            calc_globalshifts();
-
-            if ((globalorientation&0x4) > 0)
-            {
-                i = globalposx; globalposx = -globalposy; globalposy = -i;
-                i = globalx2; globalx2 = globaly1; globaly1 = i;
-                i = globalx1; globalx1 = -globaly2; globaly2 = -i;
-            }
-            if ((globalorientation&0x10) > 0) globalx1 = -globalx1, globaly1 = -globaly1, globalposx = -globalposx;
-            if ((globalorientation&0x20) > 0) globalx2 = -globalx2, globaly2 = -globaly2, globalposy = -globalposy;
-            asm1 = (globaly1<<globalxshift);
-            asm2 = (globalx2<<globalyshift);
-            globalx1 <<= globalxshift;
-            globaly2 <<= globalyshift;
-            set_globalpos(((int64_t) globalposx<<(20+globalxshift))+(((uint32_t) sec->floorxpanning)<<24),
-                ((int64_t) globalposy<<(20+globalyshift))-(((uint32_t) sec->floorypanning)<<24),
-                globalposz);
-            renderFillPolygon(npoints);
-        }
-
-    //Sort sprite list
-    int32_t gap = 1;
-
-    while (gap < sortnum) gap = (gap << 1) + 1;
-
-    for (gap>>=1; gap>0; gap>>=1)
-        for (i=0; i<sortnum-gap; i++)
-            for (j=i; j>=0; j-=gap)
-            {
-                if (sprite[tsprite[j].owner].z <= sprite[tsprite[j+gap].owner].z) break;
-                swapshort(&tsprite[j].owner,&tsprite[j+gap].owner);
-            }
-
-    for (s=sortnum-1; s>=0; s--)
-    {
-        auto const spr = (uspritetype * )&sprite[tsprite[s].owner];
-        if ((spr->cstat&48) == 32)
-        {
-            const int32_t xspan = tilesiz[spr->picnum].x;
-
-            int32_t npoints = 0;
-            vec2_t v1 = { spr->x, spr->y }, v2, v3, v4;
-
-            get_floorspr_points(spr, 0, 0, &v1.x, &v2.x, &v3.x, &v4.x,
-                                &v1.y, &v2.y, &v3.y, &v4.y);
-
-            xb1[0] = 1; xb1[1] = 2; xb1[2] = 3; xb1[3] = 0;
-            npoints = 4;
-
-            i = 0;
-
-            ox = v1.x - dax; oy = v1.y - day;
-            x = dmulscale16(ox,vect.x,-oy,vect.y) + (xdim<<11);
-            y = dmulscale16(oy,vect2.x,ox,vect2.y) + (ydim<<11);
-            i |= getclipmask(x-c1.x,c2.x-x,y-c1.y,c2.y-y);
-            rx1[0] = x; ry1[0] = y;
-
-            ox = v2.x - dax; oy = v2.y - day;
-            x = dmulscale16(ox,vect.x,-oy,vect.y) + (xdim<<11);
-            y = dmulscale16(oy,vect2.x,ox,vect2.y) + (ydim<<11);
-            i |= getclipmask(x-c1.x,c2.x-x,y-c1.y,c2.y-y);
-            rx1[1] = x; ry1[1] = y;
-
-            ox = v3.x - dax; oy = v3.y - day;
-            x = dmulscale16(ox,vect.x,-oy,vect.y) + (xdim<<11);
-            y = dmulscale16(oy,vect2.x,ox,vect2.y) + (ydim<<11);
-            i |= getclipmask(x-c1.x,c2.x-x,y-c1.y,c2.y-y);
-            rx1[2] = x; ry1[2] = y;
-
-            x = rx1[0]+rx1[2]-rx1[1];
-            y = ry1[0]+ry1[2]-ry1[1];
-            i |= getclipmask(x-c1.x,c2.x-x,y-c1.y,c2.y-y);
-            rx1[3] = x; ry1[3] = y;
-
-
-            vec2_t bak = { rx1[0], mulscale16(ry1[0] - (ydim << 11), xyaspect) + (ydim << 11) };
-
-
-            globalpicnum = spr->picnum;
-            globalpal = spr->pal; // GL needs this, software doesn't
-            if ((unsigned)globalpicnum >= (unsigned)MAXTILES) globalpicnum = 0;
-            tileUpdatePicnum(&globalpicnum, s);
-            setgotpic(globalpicnum);
-            if ((tilesiz[globalpicnum].x <= 0) || (tilesiz[globalpicnum].y <= 0)) continue;
-
-            if ((sector[spr->sectnum].ceilingstat&1) > 0)
-                globalshade = ((int32_t)sector[spr->sectnum].ceilingshade);
-            else
-                globalshade = ((int32_t)sector[spr->sectnum].floorshade);
-            globalshade = max(min(globalshade+spr->shade+6,numshades-1),0);
-
-            //relative alignment stuff
-            ox = v2.x-v1.x; oy = v2.y-v1.y;
-            i = ox*ox+oy*oy; if (i == 0) continue; i = 65536*16384 / i;
-            globalx1 = mulscale10(dmulscale10(ox,bakgvect.x,oy,bakgvect.y),i);
-            globaly1 = mulscale10(dmulscale10(ox,bakgvect.y,-oy,bakgvect.x),i);
-            ox = v1.y-v4.y; oy = v4.x-v1.x;
-            i = ox*ox+oy*oy; if (i == 0) continue; i = 65536 * 16384 / i;
-            globalx2 = mulscale10(dmulscale10(ox,bakgvect.x,oy,bakgvect.y),i);
-            globaly2 = mulscale10(dmulscale10(ox,bakgvect.y,-oy,bakgvect.x),i);
-
-            ox = widthBits(globalpicnum); 
-            oy = heightBits(globalpicnum);
-            if ((1 << ox) != xspan)
-            {
-                ox++;
-                globalx1 = mulscale(globalx1,xspan,ox);
-                globaly1 = mulscale(globaly1,xspan,ox);
-            }
-
-            bak.x = (bak.x>>4)-(xdim<<7); bak.y = (bak.y>>4)-(ydim<<7);
-            globalposx = dmulscale28(-bak.y,globalx1,-bak.x,globaly1);
-            globalposy = dmulscale28(bak.x,globalx2,-bak.y,globaly2);
-
-            if ((spr->cstat&0x4) > 0) globalx1 = -globalx1, globaly1 = -globaly1, globalposx = -globalposx;
-            asm1 = (globaly1<<2); globalx1 <<= 2; globalposx <<= (20+2);
-            asm2 = (globalx2<<2); globaly2 <<= 2; globalposy <<= (20+2);
-
-            set_globalpos(globalposx, globalposy, globalposz);
-
-            // so polymost can get the translucency. ignored in software mode:
-            globalorientation = ((spr->cstat&2)<<7) | ((spr->cstat&512)>>2);
-            renderFillPolygon(npoints);
-        }
-    }
-
-
-        renderSetAspect(oviewingrange, oyxaspect);
-}
-
-//////////////////// LOADING AND SAVING ROUTINES ////////////////////
 
 static FORCE_INLINE int32_t have_maptext(void)
 {
@@ -2151,10 +1787,7 @@ static FORCE_INLINE int32_t have_maptext(void)
 static void enginePrepareLoadBoard(FileReader & fr, vec3_t *dapos, int16_t *daang, int16_t *dacursectnum)
 {
     initspritelists();
-
-    show2dsector.Zero();
-    Bmemset(show2dsprite, 0, sizeof(show2dsprite));
-    Bmemset(show2dwall, 0, sizeof(show2dwall));
+    ClearAutomap();
 
 #ifdef USE_OPENGL
     Polymost_prepare_loadboard();
diff --git a/source/core/savegamehelp.cpp b/source/core/savegamehelp.cpp
index f8f99fc9f..4e9f0b66a 100644
--- a/source/core/savegamehelp.cpp
+++ b/source/core/savegamehelp.cpp
@@ -486,11 +486,6 @@ void SaveEngineState()
 	fw->Write(&pskybits_override, sizeof(pskybits_override));
 	WriteMagic(fw);
 
-	fw->Write(show2dwall, sizeof(show2dwall));
-	fw->Write(show2dsprite, sizeof(show2dsprite));
-	fw->Write(&show2dsector, sizeof(show2dsector));
-	WriteMagic(fw);
-
 	fw->Write(&Numsprites, sizeof(Numsprites));
 	sv_prespriteextsave();
 	fw->Write(spriteext, sizeof(spriteext_t) * MAXSPRITES);
@@ -549,11 +544,6 @@ void LoadEngineState()
 		fr.Read(&pskybits_override, sizeof(pskybits_override));
 		CheckMagic(fr);
 
-		fr.Read(show2dwall, sizeof(show2dwall));
-		fr.Read(show2dsprite, sizeof(show2dsprite));
-		fr.Read(&show2dsector, sizeof(show2dsector));
-		CheckMagic(fr);
-
 		fr.Read(&Numsprites, sizeof(Numsprites));
 		fr.Read(spriteext, sizeof(spriteext_t) * MAXSPRITES);
 		fr.Read(wallext, sizeof(wallext_t) * MAXWALLS);
diff --git a/source/games/duke/src/funct.h b/source/games/duke/src/funct.h
index 1d9755557..295194dc8 100644
--- a/source/games/duke/src/funct.h
+++ b/source/games/duke/src/funct.h
@@ -205,7 +205,6 @@ void OffBoat(player_struct *pl);
 
 void drawstatusbar_d(int snum);
 void drawstatusbar_r(int snum);
-void drawoverheadmap(int cposx, int cposy, int czoom, int cang);
 void cameratext(int i);
 void dobonus(int bonusonly, const CompletionFunc& completion);
 void dobonus_d(int bonusonly, const CompletionFunc& completion);
diff --git a/source/sw/CMakeLists.txt b/source/sw/CMakeLists.txt
index c3a4aeb6c..8b9930cdd 100644
--- a/source/sw/CMakeLists.txt
+++ b/source/sw/CMakeLists.txt
@@ -26,7 +26,6 @@ set( PCH_SOURCES
 	src/jweapon.cpp
 	src/lava.cpp
 	src/light.cpp
-	src/map2d.cpp
 	src/mclip.cpp
 	src/menus.cpp
 	src/miscactr.cpp
diff --git a/source/sw/src/draw.cpp b/source/sw/src/draw.cpp
index c12464e40..e694925be 100644
--- a/source/sw/src/draw.cpp
+++ b/source/sw/src/draw.cpp
@@ -1788,33 +1788,10 @@ drawscreen(PLAYERp pp, double smoothratio)
 #endif
 
 
-    i = pp->cursectnum;
-
-    if (i >= 0)
-    {
-        show2dsector.Set(i);
-        walltype *wal = &wall[sector[i].wallptr];
-        for (j=sector[i].wallnum; j>0; j--,wal++)
-        {
-            i = wal->nextsector;
-            if (i < 0) continue;
-            if (wal->cstat&0x0071) continue;
-            uint16_t const nextwall = wal->nextwall;
-            if (nextwall < MAXWALLS && wall[nextwall].cstat&0x0071) continue;
-            if (sector[i].lotag == 32767) continue;
-            if (sector[i].ceilingz >= sector[i].floorz) continue;
-            show2dsector.Set(i);
-        }
-    }
+    MarkSectorSeen(pp->cursectnum);
 
     if ((automapMode != am_off) && pp == Player+myconnectindex)
     {
-        if (automapFollow)
-        {
-            tx = Follow_posx;
-            ty = Follow_posy;
-        }
-
         for (j = 0; j < MAXSPRITES; j++)
         {
             // Don't show sprites tagged with 257
@@ -1827,16 +1804,7 @@ drawscreen(PLAYERp pp, double smoothratio)
                 }
             }
         }
-
-        if (automapMode == am_full)
-        {
-            // only clear the actual window.
-            twod->AddColorOnlyQuad(windowxy1.x, windowxy1.y, (windowxy2.x + 1) - windowxy1.x, (windowxy2.y + 1) - windowxy1.y, 0xff000000);
-            renderDrawMapView(tx, ty, zoom*2, FixedToInt(tq16ang));
-        }
-
-        // Draw the line map on top of texture 2d map or just stand alone
-        drawoverheadmap(tx, ty, zoom*2, FixedToInt(tq16ang));
+        DrawOverheadMap(tx, ty, FixedToInt(tq16ang));
     }
 
     for (j = 0; j < MAXSPRITES; j++)
@@ -1872,8 +1840,6 @@ drawscreen(PLAYERp pp, double smoothratio)
     SyncStatMessage();
 #endif
 
-    zoom = GetAutomapZoom(zoom);
-
     restoreinterpolations();                 // Stick at end of drawscreen
     short_restoreinterpolations();                 // Stick at end of drawscreen
     if (cl_sointerpolation)
diff --git a/source/sw/src/game.cpp b/source/sw/src/game.cpp
index 537d612a1..f6bf7063a 100644
--- a/source/sw/src/game.cpp
+++ b/source/sw/src/game.cpp
@@ -106,7 +106,6 @@ SWBOOL SavegameLoaded = false;
 SWBOOL FinishedLevel = false;
 short screenpeek = 0;
 
-void drawoverheadmap(int cposx, int cposy, int czoom, short cang);
 SWBOOL PreCaching = TRUE;
 int GodMode = false;
 short Skill = 2;
@@ -266,7 +265,6 @@ void InitLevelGlobals(void)
 {
     ChopTics = 0;
     automapMode = am_off;
-    zoom = 768 / 2;
     PlayerGravity = 24;
     wait_active_check_offset = 0;
     PlaxCeilGlobZadjust = PlaxFloorGlobZadjust = Z(500);
diff --git a/source/sw/src/game.h b/source/sw/src/game.h
index 5a5e529d4..6fa650b8e 100644
--- a/source/sw/src/game.h
+++ b/source/sw/src/game.h
@@ -2052,8 +2052,6 @@ extern char keys[];
 
 extern short screenpeek;
 
-extern int zoom;
-
 #define STAT_DAMAGE_LIST_SIZE 20
 extern int16_t StatDamageList[STAT_DAMAGE_LIST_SIZE];
 
@@ -2086,7 +2084,6 @@ int BunnyHatch2(short Weapon);  // bunny.c
 int DoSkullBeginDeath(int16_t SpriteNum); // skull.c
 
 void TerminateLevel(void);  // game.c
-void drawoverheadmap(int cposx,int cposy,int czoom,short cang); // game.c
 void DrawMenuLevelScreen(void); // game.c
 void DebugWriteString(char *string);    // game.c
 
diff --git a/source/sw/src/input.cpp b/source/sw/src/input.cpp
index 64adcb94b..d086b4f38 100644
--- a/source/sw/src/input.cpp
+++ b/source/sw/src/input.cpp
@@ -107,12 +107,6 @@ static void getinput(InputPacket *loc)
     if (paused)
         return;
 
-    // If in 2D follow mode, scroll around using glob vars
-    // Tried calling this in domovethings, but key response it too poor, skips key presses
-    // Note: this get called only during follow mode
-    if (automapFollow && automapMode != am_off && pp == Player + myconnectindex && !Prediction)
-        MoveScrollMode2D(Player + myconnectindex);
-
     // !JIM! Added M_Active() so that you don't move at all while using menus
     if (M_Active() || (automapFollow && automapMode != am_off))
         return;
diff --git a/source/sw/src/map2d.cpp b/source/sw/src/map2d.cpp
deleted file mode 100644
index db1e2774d..000000000
--- a/source/sw/src/map2d.cpp
+++ /dev/null
@@ -1,378 +0,0 @@
-//-------------------------------------------------------------------------
-/*
-Copyright (C) 1997, 2005 - 3D Realms Entertainment
-
-This file is part of Shadow Warrior version 1.2
-
-Shadow Warrior is free software; you can redistribute it and/or
-modify it under the terms of the GNU General Public License
-as published by the Free Software Foundation; either version 2
-of the License, or (at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
-See the GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-
-Original Source: 1997 - Frank Maddin and Jim Norwood
-Prepared for public release: 03/28/2005 - Charlie Wiederhold, 3D Realms
-*/
-//-------------------------------------------------------------------------
-
-#include "ns.h"
-#include "build.h"
-#include "game.h"
-#include "menus.h"
-#include "network.h"
-#include "pal.h"
-#include "v_draw.h"
-
-BEGIN_SW_NS
-
-extern SWBOOL mapcheat;
-
-enum
-{
-    MAP_WHITE_SECTOR    = (LT_GREY + 2),
-    MAP_RED_SECTOR      = (RED + 6),
-    MAP_FLOOR_SPRITE    = (RED + 8),
-    MAP_ENEMY           = (RED + 10),
-    MAP_SPRITE          = (FIRE + 8),
-    MAP_PLAYER          = (GREEN + 6),
-    
-    MAP_BLOCK_SPRITE    = (DK_BLUE + 6),
-};
-
-void drawoverheadmap(int cposx, int cposy, int czoom, short cang)
-{
-    int i, j, k, l, x1, y1, x2, y2, x3, y3, x4, y4, ox, oy, xoff, yoff;
-    int dax, day, cosang, sinang, xspan, yspan, sprx, spry;
-    int xrepeat, yrepeat, z1, z2, startwall, endwall, tilenum, daang;
-    int xvect, yvect, xvect2, yvect2;
-    char col;
-    walltype *wal, *wal2;
-    spritetype *spr;
-    short p;
-    static int pspr_ndx[8]= {0,0,0,0,0,0,0,0};
-    SWBOOL sprisplayer = FALSE;
-    short txt_x, txt_y;
-
-    int32_t tmpydim = (xdim * 5) / 8;
-    renderSetAspect(65536, divscale16(tmpydim * 320, xdim * 200));
-
-    xvect = sintable[(2048 - cang) & 2047] * czoom;
-    yvect = sintable[(1536 - cang) & 2047] * czoom;
-    xvect2 = mulscale16(xvect, yxaspect);
-    yvect2 = mulscale16(yvect, yxaspect);
-
-    // Draw red lines
-    for (i = 0; i < numsectors; i++)
-    {
-        startwall = sector[i].wallptr;
-        endwall = sector[i].wallptr + sector[i].wallnum - 1;
-
-        z1 = sector[i].ceilingz;
-        z2 = sector[i].floorz;
-
-        for (j = startwall, wal = &wall[startwall]; j <= endwall; j++, wal++)
-        {
-            k = wal->nextwall;
-            if ((unsigned)k >= MAXWALLS)
-                continue;
-
-            if (!mapcheat)
-            {
-                if ((show2dwall[j >> 3] & (1 << (j & 7))) == 0)
-                    continue;
-                if ((k > j) && ((show2dwall[k >> 3] & (1 << (k & 7))) > 0))
-                    continue;
-            }
-
-            if (sector[wal->nextsector].ceilingz == z1)
-                if (sector[wal->nextsector].floorz == z2)
-                    if (((wal->cstat | wall[wal->nextwall].cstat) & (16 + 32)) == 0)
-                        continue;
-
-            col = 152;
-
-            if (automapMode == am_full)
-            {
-                if (sector[i].floorz != sector[i].ceilingz)
-                    if (sector[wal->nextsector].floorz != sector[wal->nextsector].ceilingz)
-                        if (((wal->cstat | wall[wal->nextwall].cstat) & (16 + 32)) == 0)
-                            if (sector[i].floorz == sector[wal->nextsector].floorz)
-                                continue;
-                if (sector[i].floorpicnum != sector[wal->nextsector].floorpicnum)
-                    continue;
-                if (sector[i].floorshade != sector[wal->nextsector].floorshade)
-                    continue;
-                col = 12;  // 1=white / 31=black / 44=green / 56=pink / 128=yellow / 210=blue / 248=orange / 255=purple
-            }
-
-            ox = wal->x - cposx;
-            oy = wal->y - cposy;
-            x1 = mulscale16(ox, xvect) - mulscale16(oy, yvect);
-            y1 = mulscale16(oy, xvect2) + mulscale16(ox, yvect2);
-
-            wal2 = &wall[wal->point2];
-            ox = wal2->x - cposx;
-            oy = wal2->y - cposy;
-            x2 = mulscale16(ox, xvect) - mulscale16(oy, yvect);
-            y2 = mulscale16(oy, xvect2) + mulscale16(ox, yvect2);
-
-            renderDrawLine(x1 + (xdim << 11), y1 + (ydim << 11), x2 + (xdim << 11), y2 + (ydim << 11), col);
-        }
-    }
-
-    // Draw sprites
-    k = Player[screenpeek].PlayerSprite;
-    for (i = 0; i < numsectors; i++)
-        for (j = headspritesect[i]; j >= 0; j = nextspritesect[j])
-        {
-            for (p=connecthead; p >= 0; p=connectpoint2[p])
-            {
-                if (Player[p].PlayerSprite == j)
-                {
-                    if (sprite[Player[p].PlayerSprite].xvel > 16)
-                        pspr_ndx[myconnectindex] = ((PlayClock >> 4)&3);
-                    sprisplayer = TRUE;
-
-                    goto SHOWSPRITE;
-                }
-            }
-            if (mapcheat || (show2dsprite[j >> 3] & (1 << (j & 7))) > 0)
-            {
-SHOWSPRITE:
-                spr = &sprite[j];
-
-                col = 56; // 1=white / 31=black / 44=green / 56=pink / 128=yellow / 210=blue / 248=orange / 255=purple
-                if ((spr->cstat & 1) > 0)
-                    col = 248;
-                if (j == k)
-                    col = 31;
-
-                sprx = spr->x;
-                spry = spr->y;
-
-                k = spr->statnum;
-                if ((k >= 1) && (k <= 8) && (k != 2))   // Interpolate moving
-                {
-                    sprx = sprite[j].x;
-                    spry = sprite[j].y;
-                }
-
-                switch (spr->cstat & 48)
-                {
-                case 0:  // Regular sprite
-                    if (Player[p].PlayerSprite == j)
-                    {
-                        ox = sprx - cposx;
-                        oy = spry - cposy;
-                        x1 = mulscale16(ox, xvect) - mulscale16(oy, yvect);
-                        y1 = mulscale16(oy, xvect2) + mulscale16(ox, yvect2);
-
-                        if (automapMode == am_overlay && (gNet.MultiGameType != MULTI_GAME_COMMBAT || j == Player[screenpeek].PlayerSprite))
-                        {
-                            ox = (sintable[(spr->ang + 512) & 2047] >> 7);
-                            oy = (sintable[(spr->ang) & 2047] >> 7);
-                            x2 = mulscale16(ox, xvect) - mulscale16(oy, yvect);
-                            y2 = mulscale16(oy, xvect) + mulscale16(ox, yvect);
-
-                            if (j == Player[screenpeek].PlayerSprite)
-                            {
-                                x2 = 0L;
-                                y2 = -(czoom << 5);
-                            }
-
-                            x3 = mulscale16(x2, yxaspect);
-                            y3 = mulscale16(y2, yxaspect);
-
-                            renderDrawLine(x1 - x2 + (xdim << 11), y1 - y3 + (ydim << 11),
-                                           x1 + x2 + (xdim << 11), y1 + y3 + (ydim << 11), col);
-                            renderDrawLine(x1 - y2 + (xdim << 11), y1 + x3 + (ydim << 11),
-                                           x1 + x2 + (xdim << 11), y1 + y3 + (ydim << 11), col);
-                            renderDrawLine(x1 + y2 + (xdim << 11), y1 - x3 + (ydim << 11),
-                                           x1 + x2 + (xdim << 11), y1 + y3 + (ydim << 11), col);
-                        }
-                        else
-                        {
-                            if (((gotsector[i >> 3] & (1 << (i & 7))) > 0) && (czoom > 192))
-                            {
-                                daang = (spr->ang - cang) & 2047;
-                                if (j == Player[screenpeek].PlayerSprite)
-                                {
-                                    x1 = 0;
-                                    //y1 = (yxaspect << 2);
-                                    y1 = 0;
-                                    daang = 0;
-                                }
-
-                                // Special case tiles
-                                if (spr->picnum == 3123) break;
-
-                                int spnum = -1;
-                                if (sprisplayer)
-                                {
-                                    if (gNet.MultiGameType != MULTI_GAME_COMMBAT || j == Player[screenpeek].PlayerSprite)
-                                        spnum = 1196 + pspr_ndx[myconnectindex];
-                                }
-                                else spnum = spr->picnum;
-
-                                double xd = ((x1 << 4) + (xdim << 15)) / 65536.;
-                                double yd = ((y1 << 4) + (ydim << 15)) / 65536.;
-                                double sc = mulscale16(czoom * (spr->yrepeat), yxaspect) / 65536.;
-                                if (spnum >= 0)
-                                {
-                                    DrawTexture(twod, tileGetTexture(5407, true), xd, yd, DTA_FullscreenScale, FSMode_Fit320x200,
-                                        DTA_CenterOffsetRel, true, DTA_TranslationIndex, TRANSLATION(Translation_Remap, spr->pal), DTA_Color, shadeToLight(spr->shade),
-                                        DTA_Alpha, (spr->cstat & 2) ? 0.33 : 1., TAG_DONE);
-                                }
-                            }
-                        }
-                    }
-                    break;
-                case 16: // Rotated sprite
-                    x1 = sprx;
-                    y1 = spry;
-                    tilenum = spr->picnum;
-                    xoff = (int)tileLeftOffset(tilenum) + (int)spr->xoffset;
-                    if ((spr->cstat & 4) > 0)
-                        xoff = -xoff;
-                    k = spr->ang;
-                    l = spr->xrepeat;
-                    dax = sintable[k & 2047] * l;
-                    day = sintable[(k + 1536) & 2047] * l;
-                    l = tilesiz[tilenum].x;
-                    k = (l >> 1) + xoff;
-                    x1 -= mulscale16(dax, k);
-                    x2 = x1 + mulscale16(dax, l);
-                    y1 -= mulscale16(day, k);
-                    y2 = y1 + mulscale16(day, l);
-
-                    ox = x1 - cposx;
-                    oy = y1 - cposy;
-                    x1 = mulscale16(ox, xvect) - mulscale16(oy, yvect);
-                    y1 = mulscale16(oy, xvect2) + mulscale16(ox, yvect2);
-
-                    ox = x2 - cposx;
-                    oy = y2 - cposy;
-                    x2 = mulscale16(ox, xvect) - mulscale16(oy, yvect);
-                    y2 = mulscale16(oy, xvect2) + mulscale16(ox, yvect2);
-
-                    renderDrawLine(x1 + (xdim << 11), y1 + (ydim << 11),
-                                   x2 + (xdim << 11), y2 + (ydim << 11), col);
-
-                    break;
-                case 32:    // Floor sprite
-                    if (automapMode == am_overlay)
-                    {
-                        tilenum = spr->picnum;
-                        xoff = (int)tileLeftOffset(tilenum) + (int)spr->xoffset;
-                        yoff = (int)tileTopOffset(tilenum) + (int)spr->yoffset;
-                        if ((spr->cstat & 4) > 0)
-                            xoff = -xoff;
-                        if ((spr->cstat & 8) > 0)
-                            yoff = -yoff;
-
-                        k = spr->ang;
-                        cosang = sintable[(k + 512) & 2047];
-                        sinang = sintable[k];
-                        xspan = tilesiz[tilenum].x;
-                        xrepeat = spr->xrepeat;
-                        yspan = tilesiz[tilenum].y;
-                        yrepeat = spr->yrepeat;
-
-                        dax = ((xspan >> 1) + xoff) * xrepeat;
-                        day = ((yspan >> 1) + yoff) * yrepeat;
-                        x1 = sprx + mulscale16(sinang, dax) + mulscale16(cosang, day);
-                        y1 = spry + mulscale16(sinang, day) - mulscale16(cosang, dax);
-                        l = xspan * xrepeat;
-                        x2 = x1 - mulscale16(sinang, l);
-                        y2 = y1 + mulscale16(cosang, l);
-                        l = yspan * yrepeat;
-                        k = -mulscale16(cosang, l);
-                        x3 = x2 + k;
-                        x4 = x1 + k;
-                        k = -mulscale16(sinang, l);
-                        y3 = y2 + k;
-                        y4 = y1 + k;
-
-                        ox = x1 - cposx;
-                        oy = y1 - cposy;
-                        x1 = mulscale16(ox, xvect) - mulscale16(oy, yvect);
-                        y1 = mulscale16(oy, xvect2) + mulscale16(ox, yvect2);
-
-                        ox = x2 - cposx;
-                        oy = y2 - cposy;
-                        x2 = mulscale16(ox, xvect) - mulscale16(oy, yvect);
-                        y2 = mulscale16(oy, xvect2) + mulscale16(ox, yvect2);
-
-                        ox = x3 - cposx;
-                        oy = y3 - cposy;
-                        x3 = mulscale16(ox, xvect) - mulscale16(oy, yvect);
-                        y3 = mulscale16(oy, xvect2) + mulscale16(ox, yvect2);
-
-                        ox = x4 - cposx;
-                        oy = y4 - cposy;
-                        x4 = mulscale16(ox, xvect) - mulscale16(oy, yvect);
-                        y4 = mulscale16(oy, xvect2) + mulscale16(ox, yvect2);
-
-                        renderDrawLine(x1 + (xdim << 11), y1 + (ydim << 11),
-                                       x2 + (xdim << 11), y2 + (ydim << 11), col);
-
-                        renderDrawLine(x2 + (xdim << 11), y2 + (ydim << 11),
-                                       x3 + (xdim << 11), y3 + (ydim << 11), col);
-
-                        renderDrawLine(x3 + (xdim << 11), y3 + (ydim << 11),
-                                       x4 + (xdim << 11), y4 + (ydim << 11), col);
-
-                        renderDrawLine(x4 + (xdim << 11), y4 + (ydim << 11),
-                                       x1 + (xdim << 11), y1 + (ydim << 11), col);
-
-                    }
-                    break;
-                }
-            }
-        }
-    // Draw white lines
-    for (i = 0; i < numsectors; i++)
-    {
-        startwall = sector[i].wallptr;
-        endwall = sector[i].wallptr + sector[i].wallnum - 1;
-
-        for (j = startwall, wal = &wall[startwall]; j <= endwall; j++, wal++)
-        {
-            if ((uint16_t)wal->nextwall < MAXWALLS)
-                continue;
-
-            if (!mapcheat && (show2dwall[j >> 3] & (1 << (j & 7))) == 0)
-                continue;
-
-            if (!tileGetTexture(wal->picnum)->isValid()) continue;
-
-            ox = wal->x - cposx;
-            oy = wal->y - cposy;
-            x1 = mulscale16(ox, xvect) - mulscale16(oy, yvect);
-            y1 = mulscale16(oy, xvect2) + mulscale16(ox, yvect2);
-
-            wal2 = &wall[wal->point2];
-            ox = wal2->x - cposx;
-            oy = wal2->y - cposy;
-            x2 = mulscale16(ox, xvect) - mulscale16(oy, yvect);
-            y2 = mulscale16(oy, xvect2) + mulscale16(ox, yvect2);
-
-            renderDrawLine(x1 + (xdim << 11), y1 + (ydim << 11), x2 + (xdim << 11), y2 + (ydim << 11), 24);
-        }
-    }
-
-    videoSetCorrectedAspect();
-
-}
-
-END_SW_NS
-
diff --git a/source/sw/src/player.cpp b/source/sw/src/player.cpp
index 2869decdc..7a2794d76 100644
--- a/source/sw/src/player.cpp
+++ b/source/sw/src/player.cpp
@@ -126,7 +126,6 @@ extern SWBOOL DebugOperate;
 
 //unsigned char synctics, lastsynctics;
 
-int zoom;
 int ChopTics;
 
 PLAYER Player[MAX_SW_PLAYERS_REG + 1];
@@ -2434,94 +2433,6 @@ void PlayerCheckValidMove(PLAYERp pp)
     }
 }
 
-void
-MoveScrollMode2D(PLAYERp pp)
-{
-#define TURBOTURNTIME (120/8)
-#define NORMALTURN   (12+6)
-#define RUNTURN      (28)
-#define PREAMBLETURN 3
-#define NORMALKEYMOVE 35
-#define MAXVEL       ((NORMALKEYMOVE*2)+10)
-#define MAXSVEL      ((NORMALKEYMOVE*2)+10)
-#define MAXANGVEL    100
-
-    ControlInfo scrl_input;
-    int32_t keymove;
-    int32_t momx, momy;
-    static int mfvel=0, mfsvel=0;
-
-    CONTROL_GetInput(&scrl_input);
-
-    mfsvel = mfvel = 0;
-
-    if (M_Active())
-        return;
-
-    if (buttonMap.ButtonDown(gamefunc_Strafe))
-        mfsvel -= scrl_input.dyaw / 4;
-    mfsvel -= scrl_input.dx / 4;
-    mfvel = -scrl_input.dz /4;
-
-    keymove = NORMALKEYMOVE;
-
-    if (buttonMap.ButtonDown(gamefunc_Turn_Left))
-    {
-        mfsvel -= -keymove;
-    }
-    if (buttonMap.ButtonDown(gamefunc_Turn_Right))
-    {
-        mfsvel -= keymove;
-    }
-
-    if (buttonMap.ButtonDown(gamefunc_Strafe_Left))
-    {
-        mfsvel += keymove;
-    }
-
-    if (buttonMap.ButtonDown(gamefunc_Strafe_Right))
-    {
-        mfsvel += -keymove;
-    }
-
-    if (buttonMap.ButtonDown(gamefunc_Move_Forward))
-    {
-        mfvel += keymove;
-    }
-
-    if (buttonMap.ButtonDown(gamefunc_Move_Backward))
-    {
-        mfvel += -keymove;
-    }
-
-    if (mfvel < -MAXVEL)
-        mfvel = -MAXVEL;
-    if (mfvel > MAXVEL)
-        mfvel = MAXVEL;
-    if (mfsvel < -MAXSVEL)
-        mfsvel = -MAXSVEL;
-    if (mfsvel > MAXSVEL)
-        mfsvel = MAXSVEL;
-
-    momx = mulscale9(mfvel, sintable[NORM_ANGLE(FixedToInt(pp->q16ang) + 512)]);
-    momy = mulscale9(mfvel, sintable[NORM_ANGLE(FixedToInt(pp->q16ang))]);
-
-    momx += mulscale9(mfsvel, sintable[NORM_ANGLE(FixedToInt(pp->q16ang))]);
-    momy += mulscale9(mfsvel, sintable[NORM_ANGLE(FixedToInt(pp->q16ang) + 1536)]);
-
-    //mfvel = momx;
-    //mfsvel = momy;
-
-    Follow_posx += momx;
-    Follow_posy += momy;
-
-    Follow_posx = max(Follow_posx, x_min_bound);
-    Follow_posy = max(Follow_posy, y_min_bound);
-    Follow_posx = min(Follow_posx, x_max_bound);
-    Follow_posy = min(Follow_posy, y_max_bound);
-
-}
-
 void PlayerSectorBound(PLAYERp pp, int amt)
 {
     if (pp->cursectnum < 9)