diff --git a/appveyor.yml b/appveyor.yml
index d58976fd5fc543844aba2fa5ec495458e7ac3a0a..90ee0048a4a26ea8fcce9b0b94f868f9c8cef60d 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -1,145 +1,145 @@
-version: 2.1.25.{branch}-{build}
-os: MinGW
-
-environment:
- CC: ccache
- CCACHE_CC: i686-w64-mingw32-gcc
- CCACHE_CC_64: x86_64-w64-mingw32-gcc
- WINDRES: windres
- # c:\mingw-w64 i686 has gcc 6.3.0, so use c:\msys64 7.3.0 instead
- MINGW_SDK: c:\msys64\mingw32
- # c:\msys64 x86_64 has gcc 8.2.0, so use c:\mingw-w64 7.3.0 instead
- MINGW_SDK_64: C:\mingw-w64\x86_64-7.3.0-posix-seh-rt_v5-rev0\mingw64
- CFLAGS: -Wall -W -Werror -Wno-error=implicit-fallthrough -Wimplicit-fallthrough=3 -Wno-tautological-compare -Wno-error=suggest-attribute=noreturn
- NASM_ZIP: nasm-2.12.01
- NASM_URL: http://www.nasm.us/pub/nasm/releasebuilds/2.12.01/win64/nasm-2.12.01-win64.zip
- UPX_ZIP: upx391w
- UPX_URL: http://upx.sourceforge.net/download/upx391w.zip
- CCACHE_EXE: ccache.exe
- CCACHE_URL: http://alam.srb2.org/ccache.exe
- CCACHE_COMPRESS: true
- CCACHE_DIR: C:\Users\appveyor\.ccache
- # Disable UPX by default. The user can override this in their Appveyor project settings
- NOUPX: 1
- ##############################
- # DEPLOYER VARIABLES
- # DPL_ENABLED=1 builds installers for branch names starting with `deployer`.
- # DPL_TAG_ENABLED=1 will also build installers for release tags. DPL_ENABLED=1 must also be set.
- # Set these in the Appveyor project settings
- ##############################
- DPL_ENABLED: 0
- DPL_TAG_ENABLED: 0
- DPL_INSTALLER_NAME: SRB2-v2123
- # Asset handling is barebones vs. Travis Deployer. We operate on 7z only.
- # Include the README files and the OpenGL batch in the main and patch archives.
- # The x86/x64 archives contain the DLL binaries.
- ASSET_ARCHIVE_PATH: https://github.com/mazmazz/SRB2/releases/download/SRB2_assets/SRB2-v2122-assets.7z
- ASSET_ARCHIVE_PATCH_PATH: https://github.com/mazmazz/SRB2/releases/download/SRB2_assets/SRB2-v2122-patch-assets.7z
- ASSET_ARCHIVE_X86_PATH: https://github.com/mazmazz/SRB2/releases/download/SRB2_assets/SRB2-v2122-x86-assets.7z
- ASSET_ARCHIVE_X64_PATH: https://github.com/mazmazz/SRB2/releases/download/SRB2_assets/SRB2-v2122-x64-assets.7z
- ASSET_ARCHIVE_OPTIONAL_PATH: https://github.com/mazmazz/SRB2/releases/download/SRB2_assets/SRB2-v2122-optional-assets.7z
- # This is overridden to 1 for release tag builds
- ASSET_FILES_OPTIONAL_GET: 0
- # For patches, also include the X86/X64 DLLs.
- PACKAGE_PATCH_DLL_GET: 0
- # Delete all asset downloads so they can be redownloaded
- ASSET_CLEAN: 0
-
-cache:
-- nasm-2.12.01.zip
-- upx391w.zip
-- ccache.exe
-- C:\Users\appveyor\.ccache
-- C:\Users\appveyor\srb2_cache
-
-install:
-- if [%CONFIGURATION%] == [SDL64] ( set "X86_64=1" )
-- if [%CONFIGURATION%] == [SDL64] ( set "CONFIGURATION=SDL" )
-- if [%CONFIGURATION%] == [DD64] ( set "X86_64=1" )
-- if [%CONFIGURATION%] == [DD64] ( set "CONFIGURATION=DD" )
-- if [%X86_64%] == [1] ( set "MINGW_SDK=%MINGW_SDK_64%" )
-- if [%X86_64%] == [1] ( set "CCACHE_CC=%CCACHE_CC_64%" )
-
-- if not exist "%NASM_ZIP%.zip" appveyor DownloadFile "%NASM_URL%" -FileName "%NASM_ZIP%.zip"
-- 7z x -y "%NASM_ZIP%.zip" -o%TMP% >null
-- robocopy /S /xx /ns /nc /nfl /ndl /np /njh /njs "%TMP%\%NASM_ZIP%" "%MINGW_SDK%\bin" nasm.exe || exit 0
-
-- if not exist "%UPX_ZIP%.zip" appveyor DownloadFile "%UPX_URL%" -FileName "%UPX_ZIP%.zip"
-- 7z x -y "%UPX_ZIP%.zip" -o%TMP% >null
-- robocopy /S /xx /ns /nc /nfl /ndl /np /njh /njs "%TMP%\%UPX_ZIP%" "%MINGW_SDK%\bin" upx.exe || exit 0
-
-- if not exist "%CCACHE_EXE%" appveyor DownloadFile "%CCACHE_URL%" -FileName "%CCACHE_EXE%"
-- ccache -M 99M
-- xcopy /Y /V /I ccache.exe "%MINGW_SDK%\bin"
-
-configuration:
-- SDL
-- SDL64
-- DD
-- DD64
-
-matrix:
-  allow_failures:
-    - configuration: DD
-    - configuration: DD64
-
-before_build:
-- set "Path=%MINGW_SDK%\bin;%Path%"
-- if [%X86_64%] == [1] ( x86_64-w64-mingw32-gcc --version ) else ( i686-w64-mingw32-gcc --version )
-- mingw32-make --version
-- if not [%X86_64%] == [1] ( nasm -v )
-- if not [%NOUPX%] == [1] ( upx -V )
-- ccache -V
-- ccache -s
-- if [%NOUPX%] == [1] ( set "NOUPX=NOUPX=1" ) else ( set "NOUPX=" )
-- set "SRB2_MFLAGS=-C src WARNINGMODE=1 CCACHE=1 GCC73=1 NOOBJDUMP=1 %NOUPX%"
-- if [%X86_64%] == [1] ( set "MINGW_FLAGS=MINGW64=1 X86_64=1" ) else ( set "MINGW_FLAGS=MINGW=1 GCC91=1" )
-- set "SRB2_MFLAGS=%SRB2_MFLAGS% %MINGW_FLAGS% %CONFIGURATION%=1"
-
-build_script:
-- cmd: mingw32-make.exe %SRB2_MFLAGS% clean
-- cmd: mingw32-make.exe %SRB2_MFLAGS% ERRORMODE=1 -k
-
-after_build:
-- if [%X86_64%] == [1] (
-    set "BUILD_PATH=bin\Mingw64\Release"
-  ) else (
-    set "BUILD_PATH=bin\Mingw\Release"
-  )
-- if [%X86_64%] == [1] ( set "CONFIGURATION=%CONFIGURATION%64" )
-- ccache -s
-- cmd: git rev-parse --short %APPVEYOR_REPO_COMMIT%>%TMP%/gitshort.txt
-- cmd: set /P GITSHORT=<%TMP%/gitshort.txt
-- set BUILD_ARCHIVE=%APPVEYOR_REPO_BRANCH%-%GITSHORT%-%CONFIGURATION%.7z
-- set BUILDSARCHIVE=%APPVEYOR_REPO_BRANCH%-%CONFIGURATION%.7z
-- cmd: 7z a %BUILD_ARCHIVE% %BUILD_PATH% -xr!.gitignore
-- appveyor PushArtifact %BUILD_ARCHIVE%
-- cmd: copy %BUILD_ARCHIVE% %BUILDSARCHIVE%
-- appveyor PushArtifact %BUILDSARCHIVE%
-##############################
-# DEPLOYER SCRIPT
-##############################
-- if [%DPL_ENABLED%] == [1] ( call "deployer\appveyor\deployer.bat" )
-
-test: off
-
-#deploy:
-#  - provider: FTP
-#    protocol: ftps
-#    host:
-#      secure: NsLJEPIBvmwCOj8Tg8RoRQ==
-#    username:
-#      secure: ejxi5mvk7oLYu7QtbYojajEPigMy0mokaKhuEVuDZcA=
-#    password:
-#      secure: Hbn6Uy3lT0YZ88yFJ3aW4w==
-#    folder: appveyor
-#    application:
-#    active_mode: false
-#    on:
-#      branch: master
-#      appveyor_repo_tag: true
-
-
-on_finish:
-#- cmd: echo xfreerdp /u:appveyor /cert-ignore +clipboard /v:<ip>:<port>
-#- ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
+version: 2.2.0.{branch}-{build}
+os: MinGW
+
+environment:
+ CC: ccache
+ CCACHE_CC: i686-w64-mingw32-gcc
+ CCACHE_CC_64: x86_64-w64-mingw32-gcc
+ WINDRES: windres
+ # c:\mingw-w64 i686 has gcc 6.3.0, so use c:\msys64 7.3.0 instead
+ MINGW_SDK: c:\msys64\mingw32
+ # c:\msys64 x86_64 has gcc 8.2.0, so use c:\mingw-w64 7.3.0 instead
+ MINGW_SDK_64: C:\mingw-w64\x86_64-7.3.0-posix-seh-rt_v5-rev0\mingw64
+ CFLAGS: -Wall -W -Werror -Wno-error=implicit-fallthrough -Wimplicit-fallthrough=3 -Wno-tautological-compare -Wno-error=suggest-attribute=noreturn
+ NASM_ZIP: nasm-2.12.01
+ NASM_URL: http://www.nasm.us/pub/nasm/releasebuilds/2.12.01/win64/nasm-2.12.01-win64.zip
+ UPX_ZIP: upx391w
+ UPX_URL: http://upx.sourceforge.net/download/upx391w.zip
+ CCACHE_EXE: ccache.exe
+ CCACHE_URL: http://alam.srb2.org/ccache.exe
+ CCACHE_COMPRESS: true
+ CCACHE_DIR: C:\Users\appveyor\.ccache
+ # Disable UPX by default. The user can override this in their Appveyor project settings
+ NOUPX: 1
+ ##############################
+ # DEPLOYER VARIABLES
+ # DPL_ENABLED=1 builds installers for branch names starting with `deployer`.
+ # DPL_TAG_ENABLED=1 will also build installers for release tags. DPL_ENABLED=1 must also be set.
+ # Set these in the Appveyor project settings
+ ##############################
+ DPL_ENABLED: 0
+ DPL_TAG_ENABLED: 0
+ DPL_INSTALLER_NAME: SRB2-v2123
+ # Asset handling is barebones vs. Travis Deployer. We operate on 7z only.
+ # Include the README files and the OpenGL batch in the main and patch archives.
+ # The x86/x64 archives contain the DLL binaries.
+ ASSET_ARCHIVE_PATH: https://github.com/mazmazz/SRB2/releases/download/SRB2_assets/SRB2-v2122-assets.7z
+ ASSET_ARCHIVE_PATCH_PATH: https://github.com/mazmazz/SRB2/releases/download/SRB2_assets/SRB2-v2122-patch-assets.7z
+ ASSET_ARCHIVE_X86_PATH: https://github.com/mazmazz/SRB2/releases/download/SRB2_assets/SRB2-v2122-x86-assets.7z
+ ASSET_ARCHIVE_X64_PATH: https://github.com/mazmazz/SRB2/releases/download/SRB2_assets/SRB2-v2122-x64-assets.7z
+ ASSET_ARCHIVE_OPTIONAL_PATH: https://github.com/mazmazz/SRB2/releases/download/SRB2_assets/SRB2-v2122-optional-assets.7z
+ # This is overridden to 1 for release tag builds
+ ASSET_FILES_OPTIONAL_GET: 0
+ # For patches, also include the X86/X64 DLLs.
+ PACKAGE_PATCH_DLL_GET: 0
+ # Delete all asset downloads so they can be redownloaded
+ ASSET_CLEAN: 0
+
+cache:
+- nasm-2.12.01.zip
+- upx391w.zip
+- ccache.exe
+- C:\Users\appveyor\.ccache
+- C:\Users\appveyor\srb2_cache
+
+install:
+- if [%CONFIGURATION%] == [SDL64] ( set "X86_64=1" )
+- if [%CONFIGURATION%] == [SDL64] ( set "CONFIGURATION=SDL" )
+- if [%CONFIGURATION%] == [DD64] ( set "X86_64=1" )
+- if [%CONFIGURATION%] == [DD64] ( set "CONFIGURATION=DD" )
+- if [%X86_64%] == [1] ( set "MINGW_SDK=%MINGW_SDK_64%" )
+- if [%X86_64%] == [1] ( set "CCACHE_CC=%CCACHE_CC_64%" )
+
+- if not exist "%NASM_ZIP%.zip" appveyor DownloadFile "%NASM_URL%" -FileName "%NASM_ZIP%.zip"
+- 7z x -y "%NASM_ZIP%.zip" -o%TMP% >null
+- robocopy /S /xx /ns /nc /nfl /ndl /np /njh /njs "%TMP%\%NASM_ZIP%" "%MINGW_SDK%\bin" nasm.exe || exit 0
+
+- if not exist "%UPX_ZIP%.zip" appveyor DownloadFile "%UPX_URL%" -FileName "%UPX_ZIP%.zip"
+- 7z x -y "%UPX_ZIP%.zip" -o%TMP% >null
+- robocopy /S /xx /ns /nc /nfl /ndl /np /njh /njs "%TMP%\%UPX_ZIP%" "%MINGW_SDK%\bin" upx.exe || exit 0
+
+- if not exist "%CCACHE_EXE%" appveyor DownloadFile "%CCACHE_URL%" -FileName "%CCACHE_EXE%"
+- ccache -M 99M
+- xcopy /Y /V /I ccache.exe "%MINGW_SDK%\bin"
+
+configuration:
+- SDL
+- SDL64
+- DD
+- DD64
+
+matrix:
+  allow_failures:
+    - configuration: DD
+    - configuration: DD64
+
+before_build:
+- set "Path=%MINGW_SDK%\bin;%Path%"
+- if [%X86_64%] == [1] ( x86_64-w64-mingw32-gcc --version ) else ( i686-w64-mingw32-gcc --version )
+- mingw32-make --version
+- if not [%X86_64%] == [1] ( nasm -v )
+- if not [%NOUPX%] == [1] ( upx -V )
+- ccache -V
+- ccache -s
+- if [%NOUPX%] == [1] ( set "NOUPX=NOUPX=1" ) else ( set "NOUPX=" )
+- set "SRB2_MFLAGS=-C src WARNINGMODE=1 CCACHE=1 GCC73=1 NOOBJDUMP=1 %NOUPX%"
+- if [%X86_64%] == [1] ( set "MINGW_FLAGS=MINGW64=1 X86_64=1" ) else ( set "MINGW_FLAGS=MINGW=1 GCC91=1" )
+- set "SRB2_MFLAGS=%SRB2_MFLAGS% %MINGW_FLAGS% %CONFIGURATION%=1"
+
+build_script:
+- cmd: mingw32-make.exe %SRB2_MFLAGS% clean
+- cmd: mingw32-make.exe %SRB2_MFLAGS% ERRORMODE=1 -k
+
+after_build:
+- if [%X86_64%] == [1] (
+    set "BUILD_PATH=bin\Mingw64\Release"
+  ) else (
+    set "BUILD_PATH=bin\Mingw\Release"
+  )
+- if [%X86_64%] == [1] ( set "CONFIGURATION=%CONFIGURATION%64" )
+- ccache -s
+- cmd: git rev-parse --short %APPVEYOR_REPO_COMMIT%>%TMP%/gitshort.txt
+- cmd: set /P GITSHORT=<%TMP%/gitshort.txt
+- set BUILD_ARCHIVE=%APPVEYOR_REPO_BRANCH%-%GITSHORT%-%CONFIGURATION%.7z
+- set BUILDSARCHIVE=%APPVEYOR_REPO_BRANCH%-%CONFIGURATION%.7z
+- cmd: 7z a %BUILD_ARCHIVE% %BUILD_PATH% -xr!.gitignore
+- appveyor PushArtifact %BUILD_ARCHIVE%
+- cmd: copy %BUILD_ARCHIVE% %BUILDSARCHIVE%
+- appveyor PushArtifact %BUILDSARCHIVE%
+##############################
+# DEPLOYER SCRIPT
+##############################
+- if [%DPL_ENABLED%] == [1] ( call "deployer\appveyor\deployer.bat" )
+
+test: off
+
+#deploy:
+#  - provider: FTP
+#    protocol: ftps
+#    host:
+#      secure: NsLJEPIBvmwCOj8Tg8RoRQ==
+#    username:
+#      secure: ejxi5mvk7oLYu7QtbYojajEPigMy0mokaKhuEVuDZcA=
+#    password:
+#      secure: Hbn6Uy3lT0YZ88yFJ3aW4w==
+#    folder: appveyor
+#    application:
+#    active_mode: false
+#    on:
+#      branch: master
+#      appveyor_repo_tag: true
+
+
+on_finish:
+#- cmd: echo xfreerdp /u:appveyor /cert-ignore +clipboard /v:<ip>:<port>
+#- ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
diff --git a/extras/conf/SRB2-22.cfg b/extras/conf/SRB2-22.cfg
index e31402a6c1f32a7c08a9fec4346ce613954b7515..5bc48211c60e8acfacbded90dd0b750d1745a984 100644
--- a/extras/conf/SRB2-22.cfg
+++ b/extras/conf/SRB2-22.cfg
@@ -3389,14 +3389,14 @@ thingtypes
 		}
 		118
 		{
-			title = "CastleBot FaceStabber";
+			title = "Lance-a-Bot";
 			sprite = "CBFSA1";
 			width = 32;
 			height = 72;
 		}
 		1113
 		{
-			title = "Suspicious FaceStabber Statue";
+			title = "Suspicious Lance-a-Bot Statue";
 			sprite = "CBBSA1";
 			width = 32;
 			height = 72;
@@ -5006,7 +5006,7 @@ thingtypes
 		{
 			arrow = 1;
 			blocking = 2;
-			title = "FaceStabber Statue";
+			title = "Lance-a-Bot Statue";
 			sprite = "CBBSA1";
 			width = 32;
 			height = 72;
diff --git a/src/d_clisrv.c b/src/d_clisrv.c
index 8b51a2b278498159d334f8a2c55cc80508ccfff4..0deb20e54dcb4419fd11c722887b08dd31697cd8 100644
--- a/src/d_clisrv.c
+++ b/src/d_clisrv.c
@@ -1300,6 +1300,8 @@ static void SV_SendServerInfo(INT32 node, tic_t servertime)
 
 	M_Memcpy(netbuffer->u.serverinfo.mapmd5, mapmd5, 16);
 
+	memset(netbuffer->u.serverinfo.maptitle, 0, sizeof netbuffer->u.serverinfo.maptitle);
+
 	if (mapheaderinfo[gamemap-1] && *mapheaderinfo[gamemap-1]->lvlttl)
 	{
 		char *read = mapheaderinfo[gamemap-1]->lvlttl, *writ = netbuffer->u.serverinfo.maptitle;
@@ -1318,8 +1320,6 @@ static void SV_SendServerInfo(INT32 node, tic_t servertime)
 	else
 		strncpy(netbuffer->u.serverinfo.maptitle, "UNKNOWN", 32);
 
-	netbuffer->u.serverinfo.maptitle[32] = '\0';
-
 	if (mapheaderinfo[gamemap-1] && !(mapheaderinfo[gamemap-1]->levelflags & LF_NOZONE))
 		netbuffer->u.serverinfo.iszone = 1;
 	else
diff --git a/src/dehacked.c b/src/dehacked.c
index bcf842c8dac23c1fd530684e3c6f415e2bcbd9ac..175c1fcfac2264ba105b6559e83bc186ff300383 100644
--- a/src/dehacked.c
+++ b/src/dehacked.c
@@ -242,6 +242,7 @@ INT32 flags;         Bits = 3232              MF_SOLID|MF_SHOOTABLE|MF_DROPOFF|M
 INT32 raisestate;    Respawn frame = 32       S_NULL          // raisestate
                                          }, */
 
+#ifdef HWRENDER
 static INT32 searchvalue(const char *s)
 {
 	while (s[0] != '=' && s[0])
@@ -255,7 +256,6 @@ static INT32 searchvalue(const char *s)
 	}
 }
 
-#ifdef HWRENDER
 static float searchfvalue(const char *s)
 {
 	while (s[0] != '=' && s[0])
@@ -886,7 +886,9 @@ static void readspriteinfo(MYFILE *f, INT32 num, boolean sprite2)
 	char *s = Z_Malloc(MAXLINELEN, PU_STATIC, NULL);
 	char *word, *word2;
 	char *tmp;
+#ifdef HWRENDER
 	INT32 value;
+#endif
 	char *lastline;
 	INT32 skinnumbers[MAXSKINS];
 	INT32 foundskins = 0;
@@ -947,9 +949,9 @@ static void readspriteinfo(MYFILE *f, INT32 num, boolean sprite2)
 					break;
 			}
 			strupr(word);
+#ifdef HWRENDER
 			value = atoi(word2); // used for numerical settings
 
-#ifdef HWRENDER
 			if (fastcmp(word, "LIGHTTYPE"))
 			{
 				if (sprite2)
diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c
index 9d9171cea468c2b6b9d676d085a88fd3dde885db..fea7f50bd6f9cc703deed73cfad02583f1cd5f85 100644
--- a/src/hardware/hw_md2.c
+++ b/src/hardware/hw_md2.c
@@ -729,6 +729,41 @@ static void HWR_CreateBlendedTexture(GLPatch_t *gpatch, GLPatch_t *blendgpatch,
 			cur++; image++; blendimage++;
 		}
 	}
+	else if (skinnum == TC_DASHMODE)
+	{
+		while (size--)
+		{
+			if (image->s.alpha == 0 && blendimage->s.alpha == 0)
+			{
+				// Don't bother with blending the pixel if the alpha of the blend pixel is 0
+				cur->rgba = image->rgba;
+			}
+			else
+			{
+				UINT8 ialpha = 255 - blendimage->s.alpha, balpha = blendimage->s.alpha;
+				RGBA_t icolor = *image, bcolor;
+
+				memset(&bcolor, 0x00, sizeof(RGBA_t));
+
+				if (blendimage->s.alpha)
+				{
+					bcolor.s.blue = 0;
+					bcolor.s.red = 255;
+					bcolor.s.green = (blendimage->s.red + blendimage->s.green + blendimage->s.blue) / 3;
+				}
+				if (image->s.alpha && image->s.red > image->s.green << 1) // this is pretty arbitrary, but it works well for Metal Sonic
+				{
+					icolor.s.red = image->s.blue;
+					icolor.s.blue = image->s.red;
+				}
+				cur->s.red = (ialpha * icolor.s.red + balpha * bcolor.s.red)/255;
+				cur->s.green = (ialpha * icolor.s.green + balpha * bcolor.s.green)/255;
+				cur->s.blue = (ialpha * icolor.s.blue + balpha * bcolor.s.blue)/255;
+				cur->s.alpha = image->s.alpha;
+			}
+			cur++; image++; blendimage++;
+		}
+	}
 	else
 	{
 		while (size--)
diff --git a/src/p_setup.c b/src/p_setup.c
index 3c45509eeb152ebefab7cb23c54b0ce748188c74..8a927d65a5561c072bbfca5756543403c2549c39 100644
--- a/src/p_setup.c
+++ b/src/p_setup.c
@@ -672,7 +672,7 @@ INT32 P_AddLevelFlat(const char *flatname, levelflat_t *levelflat)
 //
 INT32 P_AddLevelFlatRuntime(const char *flatname)
 {
-	return Ploadflat(0, flatname);
+	return Ploadflat(levelflats, flatname);
 }
 
 // help function for $$$.sav checking