diff --git a/bin/Resources/libgme64.dll b/bin/Resources/libgme64.dll
new file mode 100644
index 0000000000000000000000000000000000000000..2ba99450f5c7a9372a5eaa67ccdb1ee20dd5c81c
Binary files /dev/null and b/bin/Resources/libgme64.dll differ
diff --git a/libs/gme/win64/libgme.dll.a b/libs/gme/win64/libgme.dll.a
new file mode 100644
index 0000000000000000000000000000000000000000..38079dc2a2c01b010c94e78d5285ba3781c7eb9e
Binary files /dev/null and b/libs/gme/win64/libgme.dll.a differ
diff --git a/src/Makefile b/src/Makefile
index b159de3b8255c67b77e0891ef9d138289b3c33a2..b6d7c7fc5bd26d7419ce85c0053f5b70bdbcec9f 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -176,6 +176,11 @@ ifdef MINGW
 include win32/Makefile.cfg
 endif #ifdef MINGW
 
+ifdef MINGW64
+MINGW=1
+include win32/Makefile.cfg
+endif #ifdef MINGW64
+
 ifdef UNIX
 UNIXCOMMON=1
 endif
@@ -710,7 +715,6 @@ $(BIN)/s_openal.so: $(OBJDIR)/s_openal.o
 	-$(MKDIR) $(BIN)
 	@echo Linking S_OpenAL.so...
 	$(CC) --shared $^ -o $@ -g --nostartfiles -lm -lopenal
-
 endif
 
 else
diff --git a/src/Makefile.cfg b/src/Makefile.cfg
index 68cced815d53c7508bb08000845d402953545db9..b6928f1f914d9fdb586da629bcf8e52c09722e2e 100644
--- a/src/Makefile.cfg
+++ b/src/Makefile.cfg
@@ -235,6 +235,7 @@ ifndef LINUX
 ifndef FREEBSD
 ifndef CYGWIN32
 ifndef MINGW
+ifndef MINGW64
 ifndef SDL
 ifndef NDS
 ifndef DUMMY
@@ -252,6 +253,7 @@ endif
 endif
 endif
 endif
+endif
 
 #determine the interface directory (where you put all i_*.c)
 i_cdmus_o=$(OBJDIR)/i_cdmus.o
diff --git a/src/hardware/hw_draw.c b/src/hardware/hw_draw.c
index 33f5e0318978d9867fa281b04d5ed77ae8b91f9a..75523f3d2cfd5efceab6e46a85527f4d332b5c55 100644
--- a/src/hardware/hw_draw.c
+++ b/src/hardware/hw_draw.c
@@ -227,14 +227,14 @@ void HWR_DrawFixedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale,
 				Z_Free(realpatch);
 			}
 			// centre screen
-			if (vid.width != BASEVIDWIDTH * vid.dupx)
+			if ((float)vid.width != (float)BASEVIDWIDTH * dupx)
 			{
 				if (option & V_SNAPTORIGHT)
 					cx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx));
 				else if (!(option & V_SNAPTOLEFT))
 					cx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx))/2;
 			}
-			if (vid.height != BASEVIDHEIGHT * vid.dupy)
+			if ((float)vid.height != (float)BASEVIDHEIGHT * dupy)
 			{
 				if ((option & (V_SPLITSCREEN|V_SNAPTOBOTTOM)) == (V_SPLITSCREEN|V_SNAPTOBOTTOM))
 					cy += ((float)vid.height/2 - ((float)BASEVIDHEIGHT/2 * dupy));
@@ -375,14 +375,14 @@ void HWR_DrawCroppedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscal
 				Z_Free(realpatch);
 			}
 			// centre screen
-			if (vid.width != BASEVIDWIDTH * vid.dupx)
+			if ((float)vid.width != (float)BASEVIDWIDTH * dupx)
 			{
 				if (option & V_SNAPTORIGHT)
 					cx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx));
 				else if (!(option & V_SNAPTOLEFT))
 					cx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx))/2;
 			}
-			if (vid.height != BASEVIDHEIGHT * vid.dupy)
+			if ((float)vid.height != (float)BASEVIDHEIGHT * dupy)
 			{
 				if ((option & (V_SPLITSCREEN|V_SNAPTOBOTTOM)) == (V_SPLITSCREEN|V_SNAPTOBOTTOM))
 					cy += ((float)vid.height/2 - ((float)BASEVIDHEIGHT/2 * dupy));
@@ -846,14 +846,14 @@ void HWR_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 color)
 		fw *= dupx;
 		fh *= dupy;
 
-		if (vid.width != BASEVIDWIDTH * vid.dupx)
+		if ((float)vid.width != (float)BASEVIDWIDTH * dupx)
 		{
 			if (color & V_SNAPTORIGHT)
 				fx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx));
 			else if (!(color & V_SNAPTOLEFT))
 				fx += ((float)vid.width - ((float)BASEVIDWIDTH * dupx)) / 2;
 		}
-		if (vid.height != BASEVIDHEIGHT * dupy)
+		if ((float)vid.height != (float)BASEVIDHEIGHT * dupy)
 		{
 			// same thing here
 			if (color & V_SNAPTOBOTTOM)
diff --git a/src/p_setup.c b/src/p_setup.c
index f00781a5ddb7172b8fb8179c1ce13298039eb69d..9f3ff423a55884b46fe1dfb21bd05eedea429181 100644
--- a/src/p_setup.c
+++ b/src/p_setup.c
@@ -2477,6 +2477,43 @@ static void P_LoadNightsGhosts(void)
 	free(gpath);
 }
 
+static void P_SetupCamera(void)
+{
+	if (players[displayplayer].mo && (server || addedtogame))
+	{
+		camera.x = players[displayplayer].mo->x;
+		camera.y = players[displayplayer].mo->y;
+		camera.z = players[displayplayer].mo->z;
+		camera.angle = players[displayplayer].mo->angle;
+		camera.subsector = R_PointInSubsector(camera.x, camera.y); // make sure camera has a subsector set -- Monster Iestyn (12/11/18)
+	}
+	else
+	{
+		mapthing_t *thing;
+
+		switch (gametype)
+		{
+		case GT_MATCH:
+		case GT_TAG:
+			thing = deathmatchstarts[0];
+			break;
+
+		default:
+			thing = playerstarts[0];
+			break;
+		}
+
+		if (thing)
+		{
+			camera.x = thing->x;
+			camera.y = thing->y;
+			camera.z = thing->z;
+			camera.angle = FixedAngle((fixed_t)thing->angle << FRACBITS);
+			camera.subsector = R_PointInSubsector(camera.x, camera.y); // make sure camera has a subsector set -- Monster Iestyn (12/11/18)
+		}
+	}
+}
+
 /** Loads a level from a lump or external wad.
   *
   * \param skipprecip If true, don't spawn precipitation.
@@ -2814,37 +2851,7 @@ boolean P_SetupLevel(boolean skipprecip)
 
 	if (!dedicated)
 	{
-		if (players[displayplayer].mo && (server || addedtogame))
-		{
-			camera.x = players[displayplayer].mo->x;
-			camera.y = players[displayplayer].mo->y;
-			camera.z = players[displayplayer].mo->z;
-			camera.angle = players[displayplayer].mo->angle;
-		}
-		else
-		{
-			mapthing_t *thing;
-
-			switch (gametype)
-			{
-			case GT_MATCH:
-			case GT_TAG:
-				thing = deathmatchstarts[0];
-				break;
-
-			default:
-				thing = playerstarts[0];
-				break;
-			}
-
-			if (thing)
-			{
-				camera.x = thing->x;
-				camera.y = thing->y;
-				camera.z = thing->z;
-				camera.angle = FixedAngle((fixed_t)thing->angle << FRACBITS);
-			}
-		}
+		P_SetupCamera();
 
 		if (!cv_cam_height.changed)
 			CV_Set(&cv_cam_height, cv_cam_height.defaultvalue);
diff --git a/src/screen.c b/src/screen.c
index fdd8eb7bd8afadac8e749b7af8fb6bdc174c193a..ada9af7c9548d739d56522a5b6a8e4b4ba18531f 100644
--- a/src/screen.c
+++ b/src/screen.c
@@ -280,7 +280,10 @@ void SCR_Recalc(void)
 	vid.fdupy = FixedDiv(vid.height*FRACUNIT, BASEVIDHEIGHT*FRACUNIT);
 
 #ifdef HWRENDER
-	if (rendermode != render_opengl && rendermode != render_none) // This was just placing it incorrectly at non aspect correct resolutions in opengl
+	//if (rendermode != render_opengl && rendermode != render_none) // This was just placing it incorrectly at non aspect correct resolutions in opengl
+	// 13/11/18:
+	// The above is no longer necessary, since we want OpenGL to be just like software now
+	// -- Monster Iestyn
 #endif
 		vid.fdupx = vid.fdupy = (vid.fdupx < vid.fdupy ? vid.fdupx : vid.fdupy);
 
diff --git a/src/win32/Makefile.cfg b/src/win32/Makefile.cfg
index 749734a727512fe87d3856d74e94a2902b31cb3a..a73858bd46c41a1abac7da190aee236423f1fbe8 100644
--- a/src/win32/Makefile.cfg
+++ b/src/win32/Makefile.cfg
@@ -9,6 +9,9 @@
 ifdef MINGW64
 	NOASM=1
 	NONX86=1
+	HAVE_LIBGME=1
+	LIBGME_CFLAGS=-I../libs/gme/include
+	LIBGME_LDFLAGS=-L../libs/gme/win64 -lgme
 	SDL_CFLAGS?=-I../libs/SDL2/x86_64-w64-mingw32/include/SDL2 -I../libs/SDL2_mixer/x86_64-w64-mingw32/include/SDL2 -Dmain=SDL_main
 	SDL_LDFLAGS?=-L../libs/SDL2/x86_64-w64-mingw32/lib -L../libs/SDL2_mixer/x86_64-w64-mingw32/lib -lmingw32 -lSDL2main -lSDL2 -mwindows
 else
@@ -23,7 +26,9 @@ ifndef NOASM
 	USEASM=1
 endif
 
+ifndef MINGW64 #miniupnc is broken with MINGW64
 	HAVE_MINIUPNPC=1
+endif
 
 	OPTS=-DSTDC_HEADERS