diff --git a/.travis.yml b/.travis.yml
index 01660248354c2204e8774eb9abf88a7e4fd37700..f1996215bd10f5bd1b00dc6114b9c246b0e4be94 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -42,4 +42,4 @@ before_install:
   - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then curl -O -L https://www.libsdl.org/projects/SDL_mixer/release/SDL2_mixer-2.0.1.dmg; hdiutil attach SDL2_mixer-2.0.1.dmg; sudo cp -a /Volumes/SDL2_mixer/SDL2_mixer.framework /Library/Frameworks/; fi
   - mkdir -p $HOME/srb2_cache
 
-script: make
+script: make -k
diff --git a/appveyor.yml b/appveyor.yml
index f9e7b3ba0fc7e932dacfa35cd73b9d9d28b63170..fd949dbb3244dab193e9b12194d6cc790b2a41f2 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -51,7 +51,7 @@ before_build:
 
 build_script:
 - cmd: mingw32-make.exe %SRB2_MFLAGS% %CONFIGURATION%=1 clean
-- cmd: mingw32-make.exe %SRB2_MFLAGS% %CONFIGURATION%=1 ERRORMODE=1
+- cmd: mingw32-make.exe %SRB2_MFLAGS% %CONFIGURATION%=1 ERRORMODE=1 -k
 
 after_build:
 - ccache -s
diff --git a/src/Makefile b/src/Makefile
index 463afccc86335faed2f9362b8dbd1f4fbc20ebc3..f43e3c24d16624a54b409f143856fbccedc14a47 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -372,7 +372,7 @@ else
 
 	# build a normal optimised version
 	WINDRESFLAGS = -DNDEBUG
-	#CFLAGS+=-O2
+	CFLAGS+=-O3
 endif
 	CFLAGS+=-g $(OPTS) $(M5) $(WINDRESFLAGS)
 
diff --git a/src/Makefile.cfg b/src/Makefile.cfg
index fa8896a7c200f03acea8fa722568dd0da11d0075..347efa5e4450651d679cec537522a9dd4c21d51b 100644
--- a/src/Makefile.cfg
+++ b/src/Makefile.cfg
@@ -173,6 +173,9 @@ endif
 ifdef GCC43
  #WFLAGS+=-Wno-error=clobbered
 endif
+ifdef GCC46
+ WFLAGS+=-Wno-error=suggest-attribute=noreturn
+endif
 WFLAGS+=$(OLDWFLAGS)
 
 
diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c
index 1a6974894a8cd64df09099b133d5a300671b3547..34fce21bcec92b3693566c0f1ccdc0ae16962717 100644
--- a/src/hardware/hw_main.c
+++ b/src/hardware/hw_main.c
@@ -3280,16 +3280,18 @@ static void HWR_AddPolyObjectPlanes(void)
 			if (po_ptrs[i]->translucency > 0)
 			{
 				FSurfaceInfo Surf;
-				FBITFIELD blendmode = HWR_TranstableToAlpha(po_ptrs[i]->translucency, &Surf);
+				FBITFIELD blendmode;
+				memset(&Surf, 0x00, sizeof(Surf));
+				blendmode = HWR_TranstableToAlpha(po_ptrs[i]->translucency, &Surf);
 				HWR_AddTransparentPolyobjectFloor(levelflats[polyobjsector->ceilingpic].lumpnum, po_ptrs[i], polyobjsector->ceilingheight,
-													polyobjsector->lightlevel, Surf.FlatColor.s.alpha, polyobjsector, blendmode, NULL);
+				                                  polyobjsector->lightlevel, Surf.FlatColor.s.alpha, polyobjsector, blendmode, NULL);
 			}
 			else
 			{
 				HWR_GetFlat(levelflats[polyobjsector->ceilingpic].lumpnum);
 				HWR_RenderPolyObjectPlane(po_ptrs[i], polyobjsector->ceilingheight, PF_Occlude,
-										polyobjsector->lightlevel, levelflats[polyobjsector->floorpic].lumpnum,
-										polyobjsector, 255, NULL);
+				                          polyobjsector->lightlevel, levelflats[polyobjsector->floorpic].lumpnum,
+				                          polyobjsector, 255, NULL);
 			}
 		}
 	}
diff --git a/src/hardware/hw_md2.c b/src/hardware/hw_md2.c
index dfa36f1de251bcda8d1f23cb424f7fd16fa98740..6628d131720e3f11ec250c72e080d76eb6593b81 100644
--- a/src/hardware/hw_md2.c
+++ b/src/hardware/hw_md2.c
@@ -1377,10 +1377,7 @@ void HWR_DrawMD2(gr_vissprite_t *spr)
 		// SRB2CBTODO: MD2 scaling support
 		finalscale *= FIXED_TO_FLOAT(spr->mobj->scale);
 
-		if (postimgtype == postimg_flip)
-			p.flip = true;
-		else
-			p.flip = false;
+		p.flip = atransform.flip;
 
 		HWD.pfnDrawMD2i(buff, curr, durs, tics, next, &p, finalscale, flip, color);
 	}
diff --git a/src/p_saveg.c b/src/p_saveg.c
index 9dfd691c2807d99aad08173f9fb9f5d6fc85c00d..48f283bd3dbd480710ac72cd2571a48a82d48214 100644
--- a/src/p_saveg.c
+++ b/src/p_saveg.c
@@ -108,7 +108,7 @@ static inline void P_UnArchivePlayer(void)
 //
 // P_NetArchivePlayers
 //
-static inline void P_NetArchivePlayers(void)
+static void P_NetArchivePlayers(void)
 {
 	INT32 i, j;
 	UINT16 flags;
@@ -280,7 +280,7 @@ static inline void P_NetArchivePlayers(void)
 //
 // P_NetUnArchivePlayers
 //
-static inline void P_NetUnArchivePlayers(void)
+static void P_NetUnArchivePlayers(void)
 {
 	INT32 i, j;
 	UINT16 flags;
diff --git a/src/p_user.c b/src/p_user.c
index e6dbb020cd1835fd7b870219535dba4e2f4226e4..02e3308d06460c45923de558a377457ceb53779f 100644
--- a/src/p_user.c
+++ b/src/p_user.c
@@ -8150,6 +8150,8 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
 	{
 		fixed_t myfloorz, myceilingz;
 		fixed_t midz = thiscam->z + (thiscam->z - mo->z)/2;
+		fixed_t midx = ((mo->x>>FRACBITS) + (thiscam->x>>FRACBITS))<<(FRACBITS-1);
+		fixed_t midy = ((mo->y>>FRACBITS) + (thiscam->y>>FRACBITS))<<(FRACBITS-1);
 
 		// Cameras use the heightsec's heights rather then the actual sector heights.
 		// If you can see through it, why not move the camera through it too?
@@ -8165,8 +8167,8 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
 		}
 		else
 		{
-			myfloorz = newsubsec->sector->floorheight;
-			myceilingz = newsubsec->sector->ceilingheight;
+			myfloorz = P_CameraGetFloorZ(thiscam, newsubsec->sector, midx, midy, NULL);
+			myceilingz = P_CameraGetCeilingZ(thiscam, newsubsec->sector, midx, midy, NULL);
 		}
 
 		// Check list of fake floors and see if floorz/ceilingz need to be altered.
@@ -8178,17 +8180,21 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
 
 			for (rover = newsubsec->sector->ffloors; rover; rover = rover->next)
 			{
+				fixed_t topheight, bottomheight;
 				if (!(rover->flags & FF_BLOCKOTHERS) || !(rover->flags & FF_EXISTS) || !(rover->flags & FF_RENDERALL) || GETSECSPECIAL(rover->master->frontsector->special, 4) == 12)
 					continue;
 
-				delta1 = midz - (*rover->bottomheight
-					+ ((*rover->topheight - *rover->bottomheight)/2));
-				delta2 = thingtop - (*rover->bottomheight
-					+ ((*rover->topheight - *rover->bottomheight)/2));
-				if (*rover->topheight > myfloorz && abs(delta1) < abs(delta2))
-					myfloorz = *rover->topheight;
-				if (*rover->bottomheight < myceilingz && abs(delta1) >= abs(delta2))
-					myceilingz = *rover->bottomheight;
+				topheight = P_CameraGetFOFTopZ(thiscam, newsubsec->sector, rover, midx, midy, NULL);
+				bottomheight = P_CameraGetFOFBottomZ(thiscam, newsubsec->sector, rover, midx, midy, NULL);
+
+				delta1 = midz - (bottomheight
+					+ ((topheight - bottomheight)/2));
+				delta2 = thingtop - (bottomheight
+					+ ((topheight - bottomheight)/2));
+				if (topheight > myfloorz && abs(delta1) < abs(delta2))
+					myfloorz = topheight;
+				if (bottomheight < myceilingz && abs(delta1) >= abs(delta2))
+					myceilingz = bottomheight;
 			}
 		}
 
@@ -8302,18 +8308,22 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
 
 			for (rover = newsubsec->sector->ffloors; rover; rover = rover->next)
 			{
+				fixed_t topheight, bottomheight;
 				if ((rover->flags & FF_BLOCKOTHERS) && (rover->flags & FF_RENDERALL) && (rover->flags & FF_EXISTS) && GETSECSPECIAL(rover->master->frontsector->special, 4) != 12)
 				{
-					if (*rover->bottomheight - thiscam->height < z
-						&& midz < *rover->bottomheight)
-						z = *rover->bottomheight - thiscam->height-FixedMul(11*FRACUNIT, mo->scale);
+					topheight = P_CameraGetFOFTopZ(thiscam, newsubsec->sector, rover, midx, midy, NULL);
+					bottomheight = P_CameraGetFOFBottomZ(thiscam, newsubsec->sector, rover, midx, midy, NULL);
 
-					else if (*rover->topheight + thiscam->height > z
-						&& midz > *rover->topheight)
-						z = *rover->topheight;
+					if (bottomheight - thiscam->height < z
+						&& midz < bottomheight)
+						z = bottomheight - thiscam->height-FixedMul(11*FRACUNIT, mo->scale);
 
-					if ((mo->z >= *rover->topheight && midz < *rover->bottomheight)
-						|| ((mo->z < *rover->bottomheight && mo->z+mo->height < *rover->topheight) && midz >= *rover->topheight))
+					else if (topheight + thiscam->height > z
+						&& midz > topheight)
+						z = topheight;
+
+					if ((mo->z >= topheight && midz < bottomheight)
+						|| ((mo->z < bottomheight && mo->z+mo->height < topheight) && midz >= topheight))
 					{
 						// Can't see
 						if (!resetcalled)