From b31056c7d977fe3c2a5e0637589fd9521f1f6c04 Mon Sep 17 00:00:00 2001
From: James R <justsomejames2@gmail.com>
Date: Sun, 2 May 2021 02:54:51 -0700
Subject: [PATCH] Rewrite Makefile to be modular as well as more automated

Some key points for programmers:
- Source code files are mostly listed in a 'Sourcefile'.
  So you no longer directly edit the object list. There
  can be multiple Sourcefiles and they can even live in
  subdirectories--the directory name will be prepended to
  every filename in the list. Of course, the Makefile
  still needs to be edited to read from each Sourcefile.
- Different rules are no longer required for source code
  files that live in subdirectories (such as sdl/ or
  hardware/). Subdirectories Just Work so go ham!

In addition to those points, another important change is
that the bin directory is no longer divided into platform
subdirectories (Linux64, Mingw, etc). Executables now go
directly into bin. If you use DEBUGMODE or target 64-bit,
then subdirectories for 'debug' and '64' will be made
though.

Oh by the way, I don't think make clean actually removed
files before on Windows. It should now. I also fixed as
many little inconsistencies like that as I noticed.

And now just an overview of the technical aspects that
shouldn't affect anyone who doesn't REALLY care about the
Makefile...

objs and dep directories have been moved to a make
directory. Makefile.cfg and its variants have been moved
out of their various subdirectories to src/Makefile.d
make distclean removes the bin and make directories
entirely, but make clean and cleandep still only affect
the current build target.

When I say automation, I mean that a lot of copy pasting
in the Makefile has been reduced.
---
 .gitignore                 |    4 +-
 CMakeLists.txt             |    2 +-
 src/Makefile               | 1007 +++++++++++-------------------------
 src/Makefile.d/detect.mk   |  104 ++++
 src/Makefile.d/features.mk |   76 +++
 src/Makefile.d/lua.mk      |   51 --
 src/Makefile.d/nix.mk      |   90 +---
 src/Makefile.d/platform.mk |   67 +++
 src/Makefile.d/sdl.mk      |  153 +++---
 src/Makefile.d/util.mk     |   89 ++++
 src/Makefile.d/versions.mk |  375 ++------------
 src/Makefile.d/win32.mk    |  177 +++----
 src/Sourcefile             |   87 ++++
 src/blua/Sourcefile        |   25 +
 src/hardware/Sourcefile    |   13 +
 src/sdl/Sourcefile         |    7 +
 16 files changed, 965 insertions(+), 1362 deletions(-)
 create mode 100644 src/Makefile.d/detect.mk
 create mode 100644 src/Makefile.d/features.mk
 delete mode 100644 src/Makefile.d/lua.mk
 create mode 100644 src/Makefile.d/platform.mk
 create mode 100644 src/Makefile.d/util.mk
 create mode 100644 src/Sourcefile
 create mode 100644 src/blua/Sourcefile
 create mode 100644 src/hardware/Sourcefile
 create mode 100644 src/sdl/Sourcefile

diff --git a/.gitignore b/.gitignore
index 3090417dd..7023aaa80 100644
--- a/.gitignore
+++ b/.gitignore
@@ -13,11 +13,11 @@ Win32_LIB_ASM_Release
 *.dgb
 *.debug
 *.debug.txt
-/bin/VC10/
-/objs/VC10/
 *.user
 *.db
 *.opendb
 /.vs
 /debian
 /assets/debian
+/make
+/bin
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 5d2d4a7e6..148f17ef0 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -119,7 +119,7 @@ set(SRB2_SDL2_EXE_NAME srb2 CACHE STRING "Executable binary output name")
 include_directories(${CMAKE_CURRENT_BINARY_DIR}/src)
 
 add_subdirectory(src)
-add_subdirectory(assets)
+#add_subdirectory(assets)
 
 
 ## config.h generation
diff --git a/src/Makefile b/src/Makefile
index cf06ce904..dafec3645 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -1,817 +1,402 @@
-
-#     GNU Make makefile for SRB2
-#############################################################################
-# Copyright (C) 1998-2000 by DooM Legacy Team.
-# Copyright (C) 2003-2021 by Sonic Team Junior.
+# GNU Makefile for SRB2
+# the poly3 Makefile adapted over and over...
+#
+# Copyright 1998-2000 DooM Legacy Team.
+# Copyright 2020-2021 James R.
+# Copyright 2003-2021 Sonic Team Junior.
 #
 # This program is free software distributed under the
 # terms of the GNU General Public License, version 2.
 # See the 'LICENSE' file for more details.
 #
-#     -DLINUX     -> use for the GNU/Linux specific
-#     -D_WINDOWS  -> use for the Win32/DirectX specific
-#     -DHAVE_SDL  -> use for the SDL interface
+# Special targets:
 #
-# Sets:
-#     Compile the SDL/Mingw version with 'make MINGW=1'
-#     Compile the SDL/Linux version with 'make LINUX=1'
-#     Compile the SDL/Solaris version with 'make SOLARIS=1'
-#     Compile the SDL/FreeBSD version with 'gmake FREEBSD=1'
-#     Compile the SDL/Cygwin version with 'make CYGWIN32=1'
-#     Compile the SDL/other version try with 'make SDL=1'
+# clean - remove executables and objects for this build
+# cleandep - remove dependency files for this build
+# distclean - remove entire executable, object and
+#             dependency file directory structure.
+# info - print settings
 #
-# 'Targets':
-#     clean
-#       Remove all object files
-#     cleandep
-#       Remove dependency files
-#     distclean
-#       Remove autogenerated files
-#     dll
-#       compile primary HW render DLL/SO
-#     all_dll
-#       compile all HW render and 3D sound DLLs for the set
-#     opengl_dll
-#       Pure Mingw only, compile OpenGL HW render DLL
-#     ds3d_dll
-#       Pure Mingw only, compile DirectX DirectSound HW sound DLL
-#     fmod_dll
-#       Pure Mingw only, compile FMOD HW sound DLL
-#     openal_dll
-#       Pure Mingw only, compile OpenAL HW sound DLL
-#     fmod_so
-#       Non-Mingw, compile FMOD HW sound SO
-#     openal_so
-#       Non-Mingw, compile OpenAL HW sound SO
+# This Makefile can automatically detect the host system
+# as well as the compiler version. If system or compiler
+# version cannot be detected, you may need to set a flag
+# manually.
 #
+# On Windows machines, 32-bit Windows is always targetted.
 #
-# Addon:
-#     To Cross-Compile, CC=gcc-version make * PREFIX=<dir>
-#     Compile with GCC 2.97 version, add 'GCC29=1'
-#     Compile with GCC 4.0x version, add 'GCC40=1'
-#     Compile with GCC 4.1x version, add 'GCC41=1'
-#     Compile with GCC 4.2x version, add 'GCC42=1'
-#     Compile with GCC 4.3x version, add 'GCC43=1'
-#     Compile with GCC 4.4x version, add 'GCC44=1'
-#     Compile with GCC 4.5x version, add 'GCC45=1'
-#     Compile with GCC 4.6x version, add 'GCC46=1'
-#     Compile a profile version, add 'PROFILEMODE=1'
-#     Compile a debug version, add 'DEBUGMODE=1'
-#     Compile with less warnings, add 'RELAXWARNINGS=1'
-#     Generate compiler errors for most compiler warnings, add 'ERRORMODE=1'
-#     Compile without NASM's tmap.nas, add 'NOASM=1'
-#     Compile without 3D hardware support, add 'NOHW=1'
-#     Compile with GDBstubs, add 'RDB=1'
-#     Compile without PNG, add 'NOPNG=1'
-#     Compile without zlib, add 'NOZLIB=1'
+# Platform/system flags:
 #
-# Addon for SDL:
-#     To Cross-Compile, add 'SDL_CONFIG=/usr/*/bin/sdl-config'
-#     Compile without SDL_Mixer, add 'NOMIXER=1'
-#     Compile without SDL_Mixer_X, add 'NOMIXERX=1' (Win32 only)
-#     Compile without GME, add 'NOGME=1'
-#     Compile without BSD API, add 'NONET=1'
-#     Compile without IPX/SPX, add 'NOIPX=1'
-#     Compile Mingw/SDL with S_DS3S, add 'DS3D=1'
-#     Compile without libopenmpt, add 'NOOPENMPT=1'
-#     Compile with S_FMOD3D, add 'FMOD=1' (WIP)
-#     Compile with S_OPENAL, add 'OPENAL=1' (WIP)
-#     To link with the whole SDL_Image lib to load Icons, add 'SDL_IMAGE=1' but it isn't not realy needed
-#     To link with SDLMain to hide console or make on a console-less binary, add 'SDLMAIN=1'
+# LINUX=1, LINUX64=1
+# MINGW=1, MINGW64=1 - Windows (MinGW toolchain)
+# UNIX=1 - Generic Unix like system
+# FREEBSD=1
+# SDL=1 - Use SDL backend. SDL is the only backend though
+#         and thus, always enabled.
 #
-#############################################################################
-
-,=,
-
-ifeq (,$(filter-out cleandep clean distclean,$(or $(MAKECMDGOALS),all)))
-CLEANONLY=1
-else ifndef SILENT
-echo=@echo "$(1)"
-ifndef MAKE_RESTARTS
-print=$(info $(1))
-endif
-endif
-
-ALL_SYSTEMS=\
-	PANDORA\
-	LINUX64\
-	MINGW64\
-	HAIKU\
-	DUMMY\
-	DJGPPDOS\
-	MINGW\
-	UNIX\
-	LINUX\
-	SOLARIS\
-	FREEBSD\
-	MACOSX\
-	SDL\
-
-# check for user specified system
-ifeq (,$(filter $(ALL_SYSTEMS),$(.VARIABLES)))
-ifeq ($(OS),Windows_NT) # all windows are Windows_NT...
-
- $(call print,Detected a Windows system$(,) compiling for 32-bit MinGW SDL2...)
-
- # go for a 32-bit sdl mingw exe by default
- MINGW=1
- WINDOWSHELL=1
-
-else # if you on the *nix
-
- system:=$(shell uname -s)
-
- ifeq ($(system),Linux)
- new_system=LINUX
- else
-
- $(error \
-	 Could not automatically detect your system,\
-	 try specifying a system manually)
-
- endif
-
- ifeq ($(shell getconf LONG_BIT),64)
- system+=64-bit
- new_system:=$(new_system)64
- endif
-
- $(call print,Detected $(system) ($(new_system))...)
- $(new_system)=1
-
-endif
-endif
-
-
-# SRB2 data files
-D_DIR?=../bin/Resources
-D_FILES=$(D_DIR)/srb2.pk3 \
-	$(D_DIR)/player.dta \
-	$(D_DIR)/zones.pk3 \
-	$(D_DIR)/music.dta \
-
-PKG_CONFIG?=pkg-config
-
-ifdef PANDORA
-LINUX=1
-endif
-
-ifdef LINUX64
-LINUX=1
-NONX86=1
-# LINUX64 does not imply X86_64=1; could mean ARM64 or Itanium
-endif
-
-ifdef MINGW64
-MINGW=1
-NONX86=1
-NOASM=1
-# MINGW64 should not necessarily imply X86_64=1, but we make that assumption elsewhere
-# Once that changes, remove this
-X86_64=1
-endif #ifdef MINGW64
-
-ifdef HAIKU
-SDL=1
-endif
-
-include Makefile.cfg
-
-ifdef DUMMY
-NOPNG=1
-NOZLIB=1
-NONET=1
-NOHW=1
-NOASM=1
-NOIPX=1
-EXENAME?=srb2dummy
-OBJS=$(OBJDIR)/i_video.o
-LIBS=-lm
-endif
+# A list of supported GCC versions can be found in
+# Makefile.d/detect.mk -- search 'gcc_versions'.
+#
+# Feature flags:
+#
+# Safe to use online
+# ------------------
+# NO_IPV6=1 - Disable IPv6 address support.
+# NOHW=1 - Disable OpenGL renderer.
+# ZDEBUG=1 - Enable more detailed memory debugging
+# HAVE_MINIUPNPC=1 - Enable automated port forwarding.
+#                    Already enabled by default for 32-bit
+#                    Windows.
+# NOASM=1 - Disable hand optimized assembly code for the
+#           Software renderer.
+# NOPNG=1 - Disable PNG graphics support. (TODO: double
+#           check netplay compatible.)
+# NOCURL=1 - Disable libcurl--HTTP capability.
+# NOGME=1 - Disable game music emu, retro VGM support.
+# NOOPENMPT=1 - Disable module (tracker) music support.
+# NOMIXER=1 - Disable SDL Mixer (audio playback).
+# NOMIXERX=1 - Forgo SDL Mixer X--revert to standard SDL
+#              Mixer. Mixer X is the default for Windows
+#              builds.
+# HAVE_MIXERX=1 - Enable SDL Mixer X. Outside of Windows
+#                 builds, SDL Mixer X is not the default.
+# NOTHREADS=1 - Disable multithreading.
+#
+# Netplay incompatible
+# --------------------
+# NONET=1 - Disable online capability.
+# NOMD5=1 - Disable MD5 checksum (validation tool).
+# NOPOSTPROCESSING=1 - ?
+# MOBJCONSISTANCY=1 - ??
+# PACKETDROP=1 - ??
+# DEBUGMODE=1 - Enable various debugging capabilities.
+#               Also disables optimizations.
+# NOZLIB=1 - Disable some compression capability. Implies
+#            NOPNG=1.
+#
+# Development flags:
+#
+# VALGRIND=1 - Enable Valgrind memory debugging support.
+# PROFILEMODE=1 - Enable performance profiling (gprof).
+#
+# General flags for building:
+#
+# STATIC=1 - Use static linking.
+# DISTCC=1
+# CCACHE=1
+# NOOBJDUMP=1 - Don't disassemble executable.
+# NOUPX=1 - Don't compress executable.
+# WINDOWSHELL=1 - Use Windows commands.
+# PREFIX= - Prefix to many commands, for cross compiling.
+# YASM=1 - Use Yasm instead of NASM assembler.
+# STABS=1 - ?
+# ECHO=1 - Print out each command in the build process.
+# NOECHOFILENAMES=1 - Don't print out each that is being
+#                     worked on.
+# SILENT=1 - Print absolutely nothing except errors.
+# RELAXWARNINGS=1 - Use less compiler warnings/errors.
+# ERRORMODE=1 - Treat most compiler warnings as errors.
+# NOCASTALIGNWARN=1 - ?
+# NOLDWARNING=1 - ?
+# NOSDLMAIN=1 - ?
+# SDLMAIN=1 - ?
+#
+# Library configuration flags:
+# Everything here is an override.
+#
+# PNG_PKGCONFIG= - libpng-config command.
+# PNG_CFLAGS=, PNG_LDFLAGS=
+#
+# CURLCONFIG= - curl-config command.
+# CURL_CFLAGS=, CURL_LDFLAGS=
+#
+# VALGRIND_PKGCONFIG= - pkg-config package name.
+# VALGRIND_CFLAGS=, VALGRIND_LDFLAGS=
+#
+# LIBGME_PKGCONFIG=, LIBGME_CFLAGS=, LIBGME_LDFLAGS=
 
-ifdef HAIKU
-NOIPX=1
-NOASM=1
-ifndef NONET
-LIBS=-lnetwork
-endif
-CFLAGS+=-DUNIXCOMMON
-PNG_CFLAGS?=
-PNG_LDFLAGS?=-lpng
-endif
+# LIBOPENMPT_PKGCONFIG=
+# LIBOPENMPT_CFLAGS=, LIBOPENMPT_LDFLAGS=
+#
+# ZLIB_PKGCONFIG=, ZLIB_CFLAGS=, ZLIB_LDFLAGS=
+#
+# SDL_PKGCONFIG=
+# SDL_CONFIG= - sdl-config command.
+# SDL_CFLAGS=, SDL_LDFLAGS=
 
-ifdef PANDORA
-NONX86=1
-NOHW=1
-endif
+clean_targets=cleandep clean distclean info
 
-ifndef NOOPENMPT
-HAVE_OPENMPT=1
-endif
+.PHONY : $(clean_targets) all
 
-ifdef MINGW
-include win32/Makefile.cfg
-endif #ifdef MINGW
+goals:=$(or $(MAKECMDGOALS),all)
+cleanonly:=$(filter $(clean_targets),$(goals))
+destructive:=$(filter-out info,$(cleanonly))
 
-ifdef UNIX
-UNIXCOMMON=1
-endif
+include Makefile.d/util.mk
 
-ifdef LINUX
-UNIXCOMMON=1
-ifndef NOGME
-HAVE_LIBGME=1
-endif
+ifdef PREFIX
+CC:=$(PREFIX)-gcc
 endif
 
-ifdef SOLARIS
-UNIXCOMMON=1
-endif
+OBJDUMP_OPTS?=--wide --source --line-numbers
 
-ifdef FREEBSD
-UNIXCOMMON=1
-endif
+OBJCOPY:=$(call Prefix,objcopy)
+OBJDUMP:=$(call Prefix,objdump) $(OBJDUMP_OPTS)
+WINDRES:=$(call Prefix,windres)
 
-ifdef MACOSX
-UNIXCOMMON=1
+ifdef YASM
+NASM?=yasm
+else
+NASM?=nasm
 endif
 
-ifdef SDL
-	include sdl/Makefile.cfg
-endif #ifdef SDL
-
-ifdef DISTCC
-        CC:=distcc $(CC)
+ifdef YASM
+ifdef STABS
+NASMOPTS?=-g stabs
+else
+NASMOPTS?=-g dwarf2
 endif
-
-ifdef CCACHE
-        CC:=ccache $(CC)
+else
+NASMOPTS?=-g
 endif
 
-MSGFMT?=msgfmt
-
+GZIP?=gzip
+GZIP_OPTS?=-9 -f -n
 ifdef WINDOWSHELL
-	COMPTIME=-..\comptime.bat
-else
-	COMPTIME=-../comptime.sh
+GZIP_OPTS+=--rsyncable
 endif
 
+UPX?=upx
+UPX_OPTS?=--best --preserve-build-id
 ifndef ECHO
-	NASM:=@$(NASM)
-	REMOVE:=@$(REMOVE)
-	CC:=@$(CC)
-	CXX:=@$(CXX)
-	OBJCOPY:=@$(OBJCOPY)
-	OBJDUMP:=@$(OBJDUMP)
-	STRIP:=@$(STRIP)
-	WINDRES:=@$(WINDRES)
-	MKDIR:=@$(MKDIR)
-	GZIP:=@$(GZIP)
-	MSGFMT:=@$(MSGFMT)
-	UPX:=@$(UPX)
-	UPX_OPTS+=-q
-	COMPTIME:=@$(COMPTIME)
-endif
-
-ifdef NONET
-	OPTS+=-DNONET
-	NOCURL=1
-else
-ifdef NO_IPV6
-	OPTS+=-DNO_IPV6
-endif
+UPX_OPTS+=-qq
 endif
 
-ifdef NOHW
-	OPTS+=-DNOHW
-else
-	OPTS+=-DHWRENDER
-	OBJS+=$(OBJDIR)/hw_bsp.o $(OBJDIR)/hw_draw.o $(OBJDIR)/hw_light.o \
-		 $(OBJDIR)/hw_main.o $(OBJDIR)/hw_clip.o $(OBJDIR)/hw_md2.o $(OBJDIR)/hw_cache.o \
-		 $(OBJDIR)/hw_md2load.o $(OBJDIR)/hw_md3load.o $(OBJDIR)/hw_model.o $(OBJDIR)/u_list.o $(OBJDIR)/hw_batching.o
-endif
+include Makefile.d/detect.mk
 
-OPTS += -DCOMPVERSION
+# make would try to remove the implicitly made directories
+.PRECIOUS : %/ comptime.c
 
-ifndef NONX86
-ifndef GCC29
-	ARCHOPTS?=-msse3 -mfpmath=sse
-else
-	ARCHOPTS?=-mpentium
-endif
-else
-ifdef X86_64
-	ARCHOPTS?=-march=nocona
-endif
-endif
+# very sophisticated dependency
+sources:=\
+	$(call List,Sourcefile)\
+	$(call List,blua/Sourcefile)\
 
-ifndef NOASM
-ifndef NONX86
-	OBJS+=$(OBJDIR)/tmap.o $(OBJDIR)/tmap_mmx.o
-	OPTS+=-DUSEASM
-endif
-endif
+makedir:=../make
 
-ifndef NOPNG
-OPTS+=-DHAVE_PNG
+# -DCOMPVERSION: flag to use comptime.h
+opts:=-DCOMPVERSION -g
+libs:=
 
-ifdef PNG_PKGCONFIG
-PNG_CFLAGS?=$(shell $(PKG_CONFIG) $(PNG_PKGCONFIG) --cflags)
-PNG_LDFLAGS?=$(shell $(PKG_CONFIG) $(PNG_PKGCONFIG) --libs)
-else
-ifdef PREFIX
-PNG_CONFIG?=$(PREFIX)-libpng-config
-else
-PNG_CONFIG?=libpng-config
-endif
+nasm_format:=
 
-ifdef PNG_STATIC
-PNG_CFLAGS?=$(shell $(PNG_CONFIG) --static --cflags)
-PNG_LDFLAGS?=$(shell $(PNG_CONFIG) --static --ldflags)
-else
-PNG_CFLAGS?=$(shell $(PNG_CONFIG) --cflags)
-PNG_LDFLAGS?=$(shell $(PNG_CONFIG) --ldflags)
-endif
-endif
+# This is a list of variables names, of which if defined,
+# also defines the name as a macro to the compiler.
+passthru_opts:=
 
-ifdef LINUX
-PNG_CFLAGS+=-D_LARGEFILE64_SOURCE
-endif
+include Makefile.d/platform.mk
+include Makefile.d/features.mk
+include Makefile.d/versions.mk
 
-LIBS+=$(PNG_LDFLAGS)
-CFLAGS+=$(PNG_CFLAGS)
-
-OBJS+=$(OBJDIR)/apng.o
+ifdef DEBUGMODE
+makedir:=$(makedir)/debug
 endif
 
-ifdef HAVE_LIBGME
-OPTS+=-DHAVE_LIBGME
+depdir:=$(makedir)/deps
+objdir:=$(makedir)/objs
 
-LIBGME_PKGCONFIG?=libgme
-LIBGME_CFLAGS?=$(shell $(PKG_CONFIG) $(LIBGME_PKGCONFIG) --cflags)
-LIBGME_LDFLAGS?=$(shell $(PKG_CONFIG) $(LIBGME_PKGCONFIG) --libs)
+depends:=$(basename $(filter %.c %.s,$(sources)))
+objects:=$(basename $(filter %.c %.s %.nas,$(sources)))
 
-LIBS+=$(LIBGME_LDFLAGS)
-CFLAGS+=$(LIBGME_CFLAGS)
-endif
+depends:=$(depends:%=$(depdir)/%.d)
 
-ifdef HAVE_OPENMPT
-OPTS+=-DHAVE_OPENMPT
+# comptime.o added directly to objects instead of thru
+# sources because comptime.c includes comptime.h, but
+# comptime.h may not exist yet. It's a headache so this is
+# easier.
+objects:=$(objects:=.o) comptime.o
 
-LIBOPENMPT_PKGCONFIG?=libopenmpt
-LIBOPENMPT_CFLAGS?=$(shell $(PKG_CONFIG) $(LIBOPENMPT_PKGCONFIG) --cflags)
-LIBOPENMPT_LDFLAGS?=$(shell $(PKG_CONFIG) $(LIBOPENMPT_PKGCONFIG) --libs)
-
-LIBS+=$(LIBOPENMPT_LDFLAGS)
-CFLAGS+=$(LIBOPENMPT_CFLAGS)
+# windows resource file
+rc_file:=$(basename $(filter %.rc,$(sources)))
+ifdef rc_file
+objects+=$(rc_file:=.res)
 endif
 
-ifndef NOZLIB
-OPTS+=-DHAVE_ZLIB
-ZLIB_PKGCONFIG?=zlib
-ZLIB_CFLAGS?=$(shell $(PKG_CONFIG) $(ZLIB_PKGCONFIG) --cflags)
-ZLIB_LDFLAGS?=$(shell $(PKG_CONFIG) $(ZLIB_PKGCONFIG) --libs)
+objects:=$(addprefix $(objdir)/,$(objects))
 
-LIBS+=$(ZLIB_LDFLAGS)
-CFLAGS+=$(ZLIB_CFLAGS)
+ifdef DEBUGMODE
+bin:=../bin/debug
 else
-NOPNG=1
+bin:=../bin
 endif
 
-ifndef NOCURL
-OPTS+=-DHAVE_CURL
-CURLCONFIG?=curl-config
-CURL_CFLAGS?=$(shell $(CURLCONFIG) --cflags)
-CURL_LDFLAGS?=$(shell $(CURLCONFIG) --libs)
-
-LIBS+=$(CURL_LDFLAGS)
-CFLAGS+=$(CURL_CFLAGS)
-endif
+# default EXENAME (usually set by platform)
+EXENAME?=srb2
+DBGNAME?=$(EXENAME).debug
 
-ifdef STATIC
-LIBS:=-static $(LIBS)
-endif
+exe:=$(bin)/$(EXENAME)
+dbg:=$(bin)/$(DBGNAME)
 
-ifdef HAVE_MINIUPNPC
-ifdef NONET
-HAVE_MINIUPNPC=''
-else
-LIBS+=-lminiupnpc
-ifdef MINGW
-LIBS+=-lws2_32 -liphlpapi
-endif
-CFLAGS+=-DHAVE_MINIUPNPC
-endif
-endif
+build_done=Build is done, please look for $(<F) in $(<D)
 
-include blua/Makefile.cfg
+all : $(exe)
+	$(call Echo,$(build_done))
 
-ifdef NOMD5
-	OPTS+=-DNOMD5
-else
-	OBJS:=$(OBJDIR)/md5.o $(OBJS)
+ifndef VALGRIND
+ifndef NOOBJDUMP
+all : $(dbg).txt
 endif
-
-ifdef NOPOSTPROCESSING
-	OPTS+=-DNOPOSTPROCESSING
 endif
 
-	OPTS:=-fno-exceptions $(OPTS)
-
-ifdef MOBJCONSISTANCY
-	OPTS+=-DMOBJCONSISTANCY
+ifdef STATIC
+libs+=-static
 endif
 
-ifdef PACKETDROP
-	OPTS+=-DPACKETDROP
+# build with profiling information
+ifdef PROFILEMODE
+opts+=-pg
+libs+=-pg
 endif
 
 ifdef DEBUGMODE
-
-	# build with debugging information
-	WINDRESFLAGS = -D_DEBUG
-ifdef GCC48
-	CFLAGS+=-Og
-else
-	CFLAGS+=-O0
+debug_opts=-D_DEBUG
+else # build a normal optimized version
+debug_opts=-DNDEBUG
+opts+=-O3
 endif
-	CFLAGS+= -Wall -DPARANOIA -DRANGECHECK -DPACKETDROP -DMOBJCONSISTANCY
-else
 
+# debug_opts also get passed to windres
+opts+=$(debug_opts)
 
-	# build a normal optimised version
-	WINDRESFLAGS = -DNDEBUG
-	CFLAGS+=-O3
-endif
-	CFLAGS+=-g $(OPTS) $(ARCHOPTS) $(WINDRESFLAGS)
+opts+=$(foreach v,$(passthru_opts),$(if $($(v)),-D$(v)))
 
-ifdef YASM
-ifdef STABS
-	NASMOPTS?= -g stabs
-else
-	NASMOPTS?= -g dwarf2
-endif
-else
-	NASMOPTS?= -g
-endif
+CFLAGS:=$(opts) $(WFLAGS) $(CPPFLAGS) $(CFLAGS)
+LDFLAGS:=$(libs) $(LDFLAGS)
+ASFLAGS+=-x assembler-with-cpp
 
-ifdef PROFILEMODE
-	# build with profiling information
-	CFLAGS+=-pg
-	LDFLAGS+=-pg
+ifdef DISTCC
+CC:=distcc $(CC)
 endif
 
-ifdef ZDEBUG
-	CPPFLAGS+=-DZDEBUG
+ifdef CCACHE
+CC:=ccache $(CC)
 endif
 
-OPTS+=$(CPPFLAGS)
-
-# default EXENAME if all else fails
-EXENAME?=srb2
-DBGNAME?=$(EXENAME).debug
-
-# $(OBJDIR)/dstrings.o \
-
-# not too sophisticated dependency
-OBJS:=$(i_main_o) \
-		$(OBJDIR)/string.o   \
-		$(OBJDIR)/d_main.o   \
-		$(OBJDIR)/d_clisrv.o \
-		$(OBJDIR)/d_net.o    \
-		$(OBJDIR)/d_netfil.o \
-		$(OBJDIR)/d_netcmd.o \
-		$(OBJDIR)/dehacked.o \
-		$(OBJDIR)/z_zone.o   \
-		$(OBJDIR)/f_finale.o \
-		$(OBJDIR)/f_wipe.o   \
-		$(OBJDIR)/g_demo.o   \
-		$(OBJDIR)/g_game.o   \
-		$(OBJDIR)/g_input.o  \
-		$(OBJDIR)/am_map.o   \
-		$(OBJDIR)/command.o  \
-		$(OBJDIR)/console.o  \
-		$(OBJDIR)/hu_stuff.o \
-		$(OBJDIR)/y_inter.o  \
-		$(OBJDIR)/st_stuff.o \
-		$(OBJDIR)/m_aatree.o \
-		$(OBJDIR)/m_anigif.o \
-		$(OBJDIR)/m_argv.o   \
-		$(OBJDIR)/m_bbox.o   \
-		$(OBJDIR)/m_cheat.o  \
-		$(OBJDIR)/m_cond.o   \
-		$(OBJDIR)/m_fixed.o  \
-		$(OBJDIR)/m_menu.o   \
-		$(OBJDIR)/m_misc.o   \
-		$(OBJDIR)/m_random.o \
-		$(OBJDIR)/m_queue.o  \
-		$(OBJDIR)/info.o     \
-		$(OBJDIR)/p_ceilng.o \
-		$(OBJDIR)/p_enemy.o  \
-		$(OBJDIR)/p_floor.o  \
-		$(OBJDIR)/p_inter.o  \
-		$(OBJDIR)/p_lights.o \
-		$(OBJDIR)/p_map.o    \
-		$(OBJDIR)/p_maputl.o \
-		$(OBJDIR)/p_mobj.o   \
-		$(OBJDIR)/p_polyobj.o\
-		$(OBJDIR)/p_saveg.o  \
-		$(OBJDIR)/p_setup.o  \
-		$(OBJDIR)/p_sight.o  \
-		$(OBJDIR)/p_spec.o   \
-		$(OBJDIR)/p_telept.o \
-		$(OBJDIR)/p_tick.o   \
-		$(OBJDIR)/p_user.o   \
-		$(OBJDIR)/p_slopes.o \
-		$(OBJDIR)/tables.o   \
-		$(OBJDIR)/r_bsp.o    \
-		$(OBJDIR)/r_data.o   \
-		$(OBJDIR)/r_draw.o   \
-		$(OBJDIR)/r_main.o   \
-		$(OBJDIR)/r_plane.o  \
-		$(OBJDIR)/r_segs.o   \
-		$(OBJDIR)/r_skins.o  \
-		$(OBJDIR)/r_sky.o    \
-		$(OBJDIR)/r_splats.o \
-		$(OBJDIR)/r_things.o \
-		$(OBJDIR)/r_textures.o \
-		$(OBJDIR)/r_picformats.o \
-		$(OBJDIR)/r_portal.o \
-		$(OBJDIR)/screen.o   \
-		$(OBJDIR)/v_video.o  \
-		$(OBJDIR)/s_sound.o  \
-		$(OBJDIR)/sounds.o   \
-		$(OBJDIR)/w_wad.o    \
-		$(OBJDIR)/filesrch.o \
-		$(OBJDIR)/mserv.o    \
-		$(OBJDIR)/http-mserv.o\
-		$(OBJDIR)/i_tcp.o    \
-		$(OBJDIR)/lzf.o	     \
-		$(OBJDIR)/vid_copy.o \
-		$(OBJDIR)/b_bot.o \
-		$(i_net_o)      \
-		$(i_system_o)   \
-		$(i_sound_o)    \
-		$(OBJS)
-
-DEPS:=$(patsubst $(OBJDIR)/%.o,$(DEPDIR)/%.d,$(filter %.o,$(OBJS)))
-OBJS+=$(OBJDIR)/comptime.o
-
 ifndef SILENT
-ifndef ECHO
-ifndef NOECHOFILENAMES
-define echoName =
-	@echo -- $< ...
-endef
-endif
-endif
-endif
+# makefile will 'restart' when it finishes including the
+# dependencies.
+ifndef MAKE_RESTARTS
+ifndef destrutive
+$(shell $(CC) -v)
+define flags =
 
-# List of languages to compile.
-# For reference, this is the command I use to build a srb2.pot file from the source code.
-# (The listed source files are the ones containing translated strings).
-# FILES=""; for file in `find ./ | grep "\.c" | grep -v svn`; do [ "`grep "M_GetText(" $file`" ] && FILES="$FILES $file"; done; xgettext -d srb2 -o locale/srb2.pot -kM_GetText -F --no-wrap $FILES
-ifdef GETTEXT
-POS:=$(BIN)/en.mo
+CC ........ $(CC)
 
-OPTS+=-DGETTEXT
-endif
-
-ifdef PANDORA
-all: $(BIN)/$(PNDNAME)
-endif
+CFLAGS .... $(CFLAGS)
 
+LDFLAGS ... $(LDFLAGS)
 
-ifdef SDL
-all: $(BIN)/$(EXENAME)
+endef
+$(info $(flags))
 endif
-
-ifdef DUMMY
-all:	$(BIN)/$(EXENAME)
+# don't generate dependency files if only cleaning
+ifndef cleanonly
+$(info Checking dependency files...)
+include $(depends)
 endif
-
-cleandep:
-	$(REMOVE) $(DEPS)
-	$(REMOVE) comptime.h
-
-clean:
-	$(REMOVE) *~ *.flc
-	$(REMOVE) $(OBJDIR)/*.o
-
-distclean: clean cleandep
-
-ifdef MINGW
-	$(REMOVE) $(OBJDIR)/*.res
 endif
-
-ifdef CYGWIN32
-	$(REMOVE) $(OBJDIR)/*.res
 endif
 
-#make a big srb2.s that is the disasm of the exe (dos only ?)
-asm:
-	$(CC) $(LDFLAGS) $(OBJS) -o $(OBJDIR)/tmp.exe $(LIBS)
-	$(OBJDUMP) -d $(OBJDIR)/tmp.exe --no-show-raw-insn > srb2.s
-	$(REMOVE) $(OBJDIR)/tmp.exe
+LD:=$(CC)
+CC:=$(CC) $(CFLAGS)
+NASM:=$(NASM) $(NASMOPTS) -f $(nasm_format)
+GZIP:=$(GZIP) $(GZIP_OPTS)
+UPX:=$(UPX) $(UPX_OPTS)
+WINDRES:=$(WINDRES) $(WINDRESFLAGS)\
+	$(debug_opts) --include-dir=win32 -O coff
 
-# executable
-# NOTE: DJGPP's objcopy do not have --add-gnu-debuglink
+%/ :
+	$(.)$(mkdir) $@
 
-$(BIN)/$(EXENAME): $(POS) $(OBJS)
-	-$(MKDIR) $(BIN)
-	$(call echo,Linking $(EXENAME)...)
-	$(LD) $(LDFLAGS) $(OBJS) -o $(BIN)/$(EXENAME) $(LIBS)
-ifndef VALGRIND
-ifndef NOOBJDUMP
-	$(call echo,Dumping debugging info)
-	$(OBJDUMP) $(OBJDUMP_OPTS) $(BIN)/$(EXENAME) > $(BIN)/$(DBGNAME).txt
-ifdef WINDOWSHELL
-	-$(GZIP) $(GZIP_OPTS) $(BIN)/$(DBGNAME).txt
-else
-	-$(GZIP) $(GZIP_OPT2) $(BIN)/$(DBGNAME).txt
-endif
-endif
+# this is needed so the target can be referenced in the
+# prerequisites
+.SECONDEXPANSION :
 
-# mac os x lsdlsrb2 does not like objcopy
-ifndef MACOSX
-	$(OBJCOPY) $(BIN)/$(EXENAME) $(BIN)/$(DBGNAME)
-	$(OBJCOPY) --strip-debug $(BIN)/$(EXENAME)
-	-$(OBJCOPY) --add-gnu-debuglink=$(BIN)/$(DBGNAME) $(BIN)/$(EXENAME)
-endif
+# executable stripped of debugging symbols
+$(exe) : $(dbg) | $$(@D)/
+	$(.)$(OBJCOPY) --strip-debug $< $@
+	$(.)-$(OBJCOPY) --add-gnu-debuglink=$< $@
 ifndef NOUPX
-	-$(UPX) $(UPX_OPTS) $(BIN)/$(EXENAME)
-endif
+	$(call Echo,Compressing final executable...)
+	$(.)-$(UPX) $@
 endif
-	$(call echo,Build is done$(,) please look for $(EXENAME) in $(BIN)$(,) (checking for post steps))
 
-reobjdump:
-	$(call echo,Redumping debugging info)
-	$(OBJDUMP) $(OBJDUMP_OPTS) $(BIN)/$(DBGNAME) > $(BIN)/$(DBGNAME).txt
-ifdef WINDOWSHELL
-	-$(GZIP) $(GZIP_OPTS) $(BIN)/$(DBGNAME).txt
-else
-	-$(GZIP) $(GZIP_OPT2) $(BIN)/$(DBGNAME).txt
-endif
+# original executable with debugging symbols
+$(dbg) : $(objects) | $$(@D)/
+	$(call Echo,Linking $(@F)...)
+	$(.)$(LD) -o $@ $^ $(LDFLAGS)
 
-$(OBJDIR):
-	-$(MKDIR) $(OBJDIR)
-
-ifdef SDL
-ifdef MINGW
-$(OBJDIR)/r_opengl.o: hardware/r_opengl/r_opengl.c hardware/r_opengl/r_opengl.h \
- doomdef.h doomtype.h g_state.h m_swap.h hardware/hw_drv.h screen.h \
- command.h hardware/hw_data.h hardware/hw_defs.h \
- hardware/hw_md2.h hardware/hw_glob.h hardware/hw_main.h hardware/hw_clip.h \
- hardware/hw_md2load.h hardware/hw_md3load.h hardware/hw_model.h hardware/u_list.h \
- am_map.h d_event.h d_player.h p_pspr.h m_fixed.h tables.h info.h d_think.h \
- p_mobj.h doomdata.h d_ticcmd.h r_defs.h hardware/hw_dll.h
-	$(echoName)
-	$(CC) $(CFLAGS) $(WFLAGS) -c $< -o $@
-else
-$(OBJDIR)/r_opengl.o: hardware/r_opengl/r_opengl.c hardware/r_opengl/r_opengl.h \
- doomdef.h doomtype.h g_state.h m_swap.h hardware/hw_drv.h screen.h \
- command.h hardware/hw_data.h hardware/hw_defs.h \
- hardware/hw_md2.h hardware/hw_glob.h hardware/hw_main.h hardware/hw_clip.h \
- hardware/hw_md2load.h hardware/hw_md3load.h hardware/hw_model.h hardware/u_list.h \
- am_map.h d_event.h d_player.h p_pspr.h m_fixed.h tables.h info.h d_think.h \
- p_mobj.h doomdata.h d_ticcmd.h r_defs.h hardware/hw_dll.h
-	$(echoName)
-	$(CC) $(CFLAGS) $(WFLAGS) -I/usr/X11R6/include -c $< -o $@
-endif
-endif
+# disassembly of executable
+$(dbg).txt : $(dbg)
+	$(call Echo,Dumping debugging info...)
+	$(.)$(OBJDUMP) $< > $@
+	$(.)$(GZIP) $@
 
-#dependecy made by gcc itself !
-ifndef DUMMY
-ifndef CLEANONLY
-$(call print,Checking dependency files...)
--include $(DEPS)
-endif
+# '::' means run unconditionally
+# this really updates comptime.h
+comptime.c ::
+ifdef WINDOWSHELL
+	$(.)..\comptime.bat .
+else
+	$(.)../comptime.sh .
 endif
 
-undefine deps_rule
+# I wish I could make dependencies out of rc files :(
+$(objdir)/win32/Srb2win.res : \
+	win32/afxres.h win32/resource.h
 
-# windows makes it too hard !
+# dependency recipe template
+# 1: source file suffix
+# 2: extra flags to gcc
+define _recipe =
+$(depdir)/%.d : %.$(1) | $$$$(@D)/
 ifndef WINDOWSHELL
-ifdef echoName
-define deps_rule =
-	@printf "%-20.20s\r" $<
-
-endef
+ifdef Echo_name
+	@printf '%-20.20s\r' $$<
 endif
 endif
-
-define deps_rule +=
-	$(CC) $(CFLAGS) -M -MF $@ -MT $(OBJDIR)/$(<:.c=.o) $<
+	$(.)$(CC) -MM -MF $$@ -MT $(objdir)/$$(*F).o $(2) $$<
 endef
 
-$(DEPDIR)/%.d: %.c
-	$(deps_rule)
-
-$(DEPDIR)/%.d: $(INTERFACE)/%.c
-	$(deps_rule)
-
-$(DEPDIR)/%.d: hardware/%.c
-	$(deps_rule)
-
-$(DEPDIR)/%.d: blua/%.c
-	$(deps_rule)
-
-ifdef VALGRIND
-$(OBJDIR)/z_zone.o: z_zone.c
-	$(echoName)
-	$(CC) $(CFLAGS) $(WFLAGS) -DHAVE_VALGRIND $(VALGRIND_CFLAGS) -c $< -o $@
-endif
-
-$(OBJDIR)/comptime.o::
-ifdef echoName
-	@echo -- comptime.c ...
-endif
-	$(COMPTIME) .
-	$(CC) $(CFLAGS) $(WFLAGS) -c comptime.c -o $@
-
-$(BIN)/%.mo: locale/%.po
-	-$(MKDIR) $(BIN)
-	$(echoName)
-	$(MSGFMT) -f -o $@ $<
-
-$(OBJDIR)/%.o: %.c
-	$(echoName)
-	$(CC) $(CFLAGS) $(WFLAGS) -c $< -o $@
-
-$(OBJDIR)/%.o: $(INTERFACE)/%.c
-	$(echoName)
-	$(CC) $(CFLAGS) $(WFLAGS) -c $< -o $@
-
-ifdef MACOSX
-$(OBJDIR)/%.o: sdl/macosx/%.c
-	$(echoName)
-	$(CC) $(CFLAGS) $(WFLAGS) -c $< -o $@
-endif
-
-$(OBJDIR)/%.o: hardware/%.c
-	$(echoName)
-	$(CC) $(CFLAGS) $(WFLAGS) -c $< -o $@
-
-$(OBJDIR)/%.o: blua/%.c
-	$(echoName)
-	$(CC) $(CFLAGS) $(LUA_CFLAGS) $(WFLAGS) -c $< -o $@
-
-$(OBJDIR)/%.o: %.nas
-	$(echoName)
-	$(NASM) $(NASMOPTS) -o $@ -f $(NASMFORMAT) $<
-
-$(OBJDIR)/vid_copy.o: vid_copy.s asm_defs.inc
-	$(echoName)
-	$(CC) $(OPTS) $(ASFLAGS) -x assembler-with-cpp -c $< -o $@
-
-$(OBJDIR)/%.o: %.s
-	$(echoName)
-	$(CC) $(OPTS) -x assembler-with-cpp -c $< -o $@
+$(eval $(call _recipe,c))
+$(eval $(call _recipe,s,$(ASFLAGS)))
+
+# compiling recipe template
+# 1: target file suffix
+# 2: source file suffix
+# 3: compile command
+define _recipe =
+$(objdir)/%.$(1) : %.$(2) | $$$$(@D)/
+	$(call Echo_name,$$<)
+	$(.)$(3)
+endef
 
-$(OBJDIR)/SRB2.res: win32/Srb2win.rc win32/afxres.h win32/resource.h
-	$(echoName)
-	$(WINDRES) -i $< -O rc $(WINDRESFLAGS) --include-dir=win32 -o $@ -O coff
+$(eval $(call _recipe,o,c,$(CC) -c -o $$@ $$<))
+$(eval $(call _recipe,o,nas,$(NASM) -o $$@ $$<))
+$(eval $(call _recipe,o,s,$(CC) $(ASFLAGS) -c -o $$@ $$<))
+$(eval $(call _recipe,res,rc,$(WINDRES) -i $$< -o $$@))
 
+cleandep :
+	$(.)$(rmrf) $(depends) comptime.h
 
-ifdef SDL
+clean :
+	$(.)$(rmrf) $(exe) $(dbg) $(dbg).txt $(objects)
 
-ifdef MINGW
-$(OBJDIR)/win_dbg.o: win32/win_dbg.c
-	$(echoName)
-	$(CC) $(CFLAGS) $(WFLAGS) -c $< -o $@
-endif
+distclean :
+	$(.)$(rmrf) ../bin ../objs ../deps comptime.h
 
-ifdef STATICHS
-$(OBJDIR)/s_openal.o: hardware/s_openal/s_openal.c hardware/hw3dsdrv.h \
- hardware/hw_dll.h
-	$(echoName)
-	$(CC) $(CFLAGS) $(WFLAGS) -c $< -o $@
-
-$(OBJDIR)/s_fmod.o: hardware/s_fmod/s_fmod.c hardware/hw3dsdrv.h \
- hardware/hw_dll.h
-	$(echoName)
-	$(CC) $(CFLAGS) $(WFLAGS) -c $< -o $@
-
-ifdef MINGW
-$(OBJDIR)/s_ds3d.o: hardware/s_ds3d/s_ds3d.c hardware/hw3dsdrv.h \
- hardware/hw_dll.h
-	$(echoName)
-	$(CC) $(CFLAGS) $(WFLAGS) -c $< -o $@
-endif
+info:
+ifdef WINDOWSHELL
+	@REM
 else
-
-$(OBJDIR)/s_fmod.o: hardware/s_fmod/s_fmod.c hardware/hw3dsdrv.h \
- hardware/hw_dll.h
-	$(echoName)
-	$(CC) $(ARCHOPTS) -Os -o $(OBJDIR)/s_fmod.o -DHW3SOUND -DUNIXCOMMON -shared -nostartfiles -c hardware/s_fmod/s_fmod.c
-
-$(OBJDIR)/s_openal.o: hardware/s_openal/s_openal.c hardware/hw3dsdrv.h \
- hardware/hw_dll.h
-	$(echoName)
-	$(CC) $(ARCHOPTS) -Os -o $(OBJDIR)/s_openal.o -DHW3SOUND -DUNIXCOMMON -shared -nostartfiles -c hardware/s_openal/s_openal.c
-endif
+	@:
 endif
-
-#############################################################
-#
-#############################################################
diff --git a/src/Makefile.d/detect.mk b/src/Makefile.d/detect.mk
new file mode 100644
index 000000000..f576bcf78
--- /dev/null
+++ b/src/Makefile.d/detect.mk
@@ -0,0 +1,104 @@
+#
+# Detect the host system and compiler version.
+#
+
+# Previously featured:\
+	PANDORA\
+	HAIKU\
+	DUMMY\
+	DJGPPDOS\
+	SOLARIS\
+	MACOSX\
+
+all_systems:=\
+	LINUX64\
+	MINGW64\
+	MINGW\
+	UNIX\
+	LINUX\
+	FREEBSD\
+	SDL\
+
+# check for user specified system
+ifeq (,$(filter $(all_systems),$(.VARIABLES)))
+ifeq ($(OS),Windows_NT) # all windows are Windows_NT...
+
+_m=Detected a Windows system,\
+	compiling for 32-bit MinGW SDL...)
+$(call Print,$(_m))
+
+# go for a 32-bit sdl mingw exe by default
+MINGW:=1
+WINDOWSHELL:=1
+
+else # if you on the *nix
+
+system:=$(shell uname -s)
+
+ifeq ($(system),Linux)
+new_system:=LINUX
+else
+
+$(error \
+	Could not automatically detect your system,\
+	try specifying a system manually)
+
+endif
+
+ifeq ($(shell getconf LONG_BIT),64)
+system+=64-bit
+new_system:=$(new_system)64
+endif
+
+$(call Print,Detected $(system) ($(new_system))...)
+$(new_system):=1
+
+endif
+endif
+
+# This must have high to low order.
+gcc_versions:=\
+	102 101\
+	93 92 91\
+	84 83 82 81\
+	75 74 73 72 71\
+	64 63 62 61\
+	55 54 53 52 51\
+	49 48 47 46 45 44 43 42 41 40
+
+latest_gcc_version:=10.2
+
+# Automatically set version flag, but not if one was
+# manually set. And don't bother if this is a clean only
+# run.
+ifeq (,$(call Wildvar,GCC% destructive))
+version:=$(shell $(CC) --version)
+
+# check if this is in fact GCC
+ifneq (,$(or $(findstring gcc,$(version)),\
+	$(findstring GCC,$(version))))
+
+version:=$(shell $(CC) -dumpversion)
+
+# Turn version into words of major, minor
+v:=$(subst ., ,$(version))
+# concat. major minor
+v:=$(word 1,$(v))$(word 2,$(v))
+
+# If this version is not in the list,
+# default to the latest supported
+ifeq (,$(filter $(v),$(gcc_versions)))
+define line =
+Your compiler version, GCC $(version), \
+is not supported by the Makefile.
+The Makefile will assume GCC $(latest_gcc_version).))
+endef
+$(call Print,$(line))
+GCC$(subst .,,$(latest_gcc_version)):=1
+else
+$(call Print,Detected GCC $(version) (GCC$(v)))
+GCC$(v):=1
+endif
+
+endif
+endif
diff --git a/src/Makefile.d/features.mk b/src/Makefile.d/features.mk
new file mode 100644
index 000000000..abdc342b7
--- /dev/null
+++ b/src/Makefile.d/features.mk
@@ -0,0 +1,76 @@
+#
+# Makefile for feature flags.
+#
+
+passthru_opts+=\
+	NONET NO_IPV6 NOHW NOMD5 NOPOSTPROCESSING\
+	MOBJCONSISTANCY PACKETDROP ZDEBUG\
+	HAVE_MINIUPNPC\
+
+# build with debugging information
+ifdef DEBUGMODE
+MOBJCONSISTANCY=1
+PACKETDROP=1
+opts+=-DPARANOIA -DRANGECHECK
+endif
+
+ifndef NOHW
+opts+=-DHWRENDER
+sources+=$(call List,hardware/Sourcefile)
+endif
+
+ifndef NOASM
+ifndef NONX86
+sources+=tmap.nas tmap_mmx.nas
+opts+=-DUSEASM
+endif
+endif
+
+ifndef NOMD5
+sources+=md5.c
+endif
+
+ifndef NOZLIB
+ifndef NOPNG
+ifdef PNG_PKGCONFIG
+$(eval $(call Use_pkg_config,PNG_PKGCONFIG))
+else
+PNG_CONFIG?=$(call Prefix,libpng-config)
+$(eval $(call Configure,PNG,$(PNG_CONFIG) \
+	$(if $(PNG_STATIC),--static),,--ldflags))
+endif
+ifdef LINUX
+opts+=-D_LARGFILE64_SOURCE
+endif
+opts+=-DHAVE_PNG
+sources+=apng.c
+endif
+endif
+
+ifndef NONET
+ifndef NOCURL
+CURLCONFIG?=curl-config
+$(eval $(call Configure,CURL,$(CURLCONFIG)))
+opts+=-DHAVE_CURL
+endif
+endif
+
+ifdef HAVE_MINIUPNPC
+libs+=-lminiupnpc
+endif
+
+# (Valgrind is a memory debugger.)
+ifdef VALGRIND
+VALGRIND_PKGCONFIG?=valgrind
+$(eval $(call Use_pkg_config,VALGRIND))
+ZDEBUG=1
+opts+=-DHAVE_VALGRIND
+endif
+
+default_packages:=\
+	GME/libgme/LIBGME\
+	OPENMPT/libopenmpt/LIBOPENMPT\
+	ZLIB/zlib\
+
+$(foreach p,$(default_packages),\
+	$(eval $(call Check_pkg_config,$(p))))
diff --git a/src/Makefile.d/lua.mk b/src/Makefile.d/lua.mk
deleted file mode 100644
index 12ea064b4..000000000
--- a/src/Makefile.d/lua.mk
+++ /dev/null
@@ -1,51 +0,0 @@
-ifdef UNIXCOMMON
-LUA_CFLAGS+=-DLUA_USE_POSIX
-endif
-ifdef LINUX
-LUA_CFLAGS+=-DLUA_USE_POSIX
-endif
-ifdef GCC43
-ifndef GCC44
-WFLAGS+=-Wno-logical-op
-endif
-endif
-
-OBJS:=$(OBJS) \
-	$(OBJDIR)/lapi.o \
-	$(OBJDIR)/lbaselib.o \
-	$(OBJDIR)/ldo.o \
-	$(OBJDIR)/lfunc.o \
-	$(OBJDIR)/linit.o \
-	$(OBJDIR)/liolib.o \
-	$(OBJDIR)/llex.o \
-	$(OBJDIR)/lmem.o \
-	$(OBJDIR)/lobject.o \
-	$(OBJDIR)/lstate.o \
-	$(OBJDIR)/lstrlib.o \
-	$(OBJDIR)/ltablib.o \
-	$(OBJDIR)/lundump.o \
-	$(OBJDIR)/lzio.o \
-	$(OBJDIR)/lauxlib.o \
-	$(OBJDIR)/lcode.o \
-	$(OBJDIR)/ldebug.o \
-	$(OBJDIR)/ldump.o \
-	$(OBJDIR)/lgc.o \
-	$(OBJDIR)/lopcodes.o \
-	$(OBJDIR)/lparser.o \
-	$(OBJDIR)/lstring.o \
-	$(OBJDIR)/ltable.o \
-	$(OBJDIR)/ltm.o \
-	$(OBJDIR)/lvm.o \
-	$(OBJDIR)/lua_script.o \
-	$(OBJDIR)/lua_baselib.o \
-	$(OBJDIR)/lua_mathlib.o \
-	$(OBJDIR)/lua_hooklib.o \
-	$(OBJDIR)/lua_consolelib.o \
-	$(OBJDIR)/lua_infolib.o \
-	$(OBJDIR)/lua_mobjlib.o \
-	$(OBJDIR)/lua_playerlib.o \
-	$(OBJDIR)/lua_skinlib.o \
-	$(OBJDIR)/lua_thinkerlib.o \
-	$(OBJDIR)/lua_maplib.o \
-	$(OBJDIR)/lua_blockmaplib.o \
-	$(OBJDIR)/lua_hudlib.o
diff --git a/src/Makefile.d/nix.mk b/src/Makefile.d/nix.mk
index 47c944eb5..fdcd40d4d 100644
--- a/src/Makefile.d/nix.mk
+++ b/src/Makefile.d/nix.mk
@@ -1,74 +1,40 @@
 #
-# sdl/makeNIX.cfg for SRB2/?nix
+# Makefile options for unices (linux, bsd...)
 #
 
-#Valgrind support
-ifdef VALGRIND
-VALGRIND_PKGCONFIG?=valgrind
-VALGRIND_CFLAGS?=$(shell $(PKG_CONFIG) $(VALGRIND_PKGCONFIG) --cflags)
-VALGRIND_LDFLAGS?=$(shell $(PKG_CONFIG) $(VALGRIND_PKGCONFIG) --libs)
-ZDEBUG=1
-LIBS+=$(VALGRIND_LDFLAGS)
-ifdef GCC46
-WFLAGS+=-Wno-error=unused-but-set-variable
-WFLAGS+=-Wno-unused-but-set-variable
-endif
-endif
-
-#
-#here is GNU/Linux and other
-#
-
-	OPTS=-DUNIXCOMMON
+EXENAME?=lsdl2srb2
 
-	#LDFLAGS = -L/usr/local/lib
-	LIBS=-lm
-ifdef LINUX
-	LIBS+=-lrt
-ifdef NOTERMIOS
-	OPTS+=-DNOTERMIOS
-endif
-endif
+opts+=-DUNIXCOMMON -DLUA_USE_POSIX
+libs+=-lm
 
-ifdef LINUX64
-	OPTS+=-DLINUX64
+ifndef nasm_format
+nasm_format:=elf -DLINUX
 endif
 
-#
-#here is Solaris
-#
-ifdef SOLARIS
-	NOIPX=1
-	NOASM=1
-	OPTS+=-DSOLARIS -DINADDR_NONE=INADDR_ANY -DBSD_COMP
-	OPTS+=-I/usr/local/include -I/opt/sfw/include
-	LDFLAGS+=-L/opt/sfw/lib
-	LIBS+=-lsocket -lnsl
-endif
-
-#
-#here is FreeBSD
-#
-ifdef FREEBSD
-	OPTS+=-DLINUX -DFREEBSD -I/usr/X11R6/include
-	SDL_CONFIG?=sdl11-config
-	LDFLAGS+=-L/usr/X11R6/lib
-	LIBS+=-lipx -lkvm
+ifndef NOHW
+opts+=-I/usr/X11R6/include
+libs+=-L/usr/X11R6/lib
 endif
 
-#
-#here is Mac OS X
-#
-ifdef MACOSX
-	OBJS+=$(OBJDIR)/mac_resources.o
-	OBJS+=$(OBJDIR)/mac_alert.o
-	LIBS+=-framework CoreFoundation
-endif
+SDL=1
 
-ifndef NOHW
-	OPTS+=-I/usr/X11R6/include
-	LDFLAGS+=-L/usr/X11R6/lib
+# In common usage.
+ifdef LINUX
+libs+=-lrt
+passthru_opts+=NOTERMIOS
 endif
 
-	# name of the exefile
-	EXENAME?=lsdl2srb2
+# Tested by Steel, as of release 2.2.8.
+ifdef FREEBSD
+opts+=-I/usr/X11R6/include -DLINUX -DFREEBSD
+libs+=-L/usr/X11R6/lib -lipx -lkvm
+endif
+
+# FIXME
+#ifdef SOLARIS
+#NOIPX=1
+#NOASM=1
+#opts+=-I/usr/local/include -I/opt/sfw/include \
+#		-DSOLARIS -DINADDR_NONE=INADDR_ANY -DBSD_COMP
+#libs+=-L/opt/sfw/lib -lsocket -lnsl
+#endif
diff --git a/src/Makefile.d/platform.mk b/src/Makefile.d/platform.mk
new file mode 100644
index 000000000..ca00806d9
--- /dev/null
+++ b/src/Makefile.d/platform.mk
@@ -0,0 +1,67 @@
+#
+# Platform specific options.
+#
+
+PKG_CONFIG?=pkg-config
+
+ifdef WINDOWSHELL
+rmrf?=DEL /S /Q
+mkdir?=MD
+else
+rmrf?=rm -rf
+mkdir?=mkdir -p
+endif
+
+ifdef LINUX64
+LINUX=1
+endif
+
+ifdef MINGW64
+MINGW=1
+endif
+
+ifdef LINUX
+UNIX=1
+ifdef LINUX64
+NONX86=1
+# LINUX64 does not imply X86_64=1;
+# could mean ARM64 or Itanium
+platform=linux/64
+else
+platform=linux
+endif
+else ifdef FREEBSD
+UNIX=1
+platform=freebsd
+else ifdef SOLARIS # FIXME
+UNIX=1
+platform=solaris
+else ifdef CYGWIN32 # FIXME
+nasm_format=win32
+platform=cygwin
+else ifdef MINGW
+ifdef MINGW64
+NONX86=1
+NOASM=1
+# MINGW64 should not necessarily imply X86_64=1,
+# but we make that assumption elsewhere
+# Once that changes, remove this
+X86_64=1
+platform=mingw
+else
+platform=mingw/64
+endif
+include Makefile.d/win32.mk
+endif
+
+ifdef platform
+makedir:=$(makedir)/$(platform)
+endif
+
+ifdef UNIX
+include Makefile.d/nix.mk
+endif
+
+ifdef SDL
+include Makefile.d/sdl.mk
+endif
diff --git a/src/Makefile.d/sdl.mk b/src/Makefile.d/sdl.mk
index 45d0d6ba7..43a2ffced 100644
--- a/src/Makefile.d/sdl.mk
+++ b/src/Makefile.d/sdl.mk
@@ -1,125 +1,98 @@
 #
-# sdl/makefile.cfg for SRB2/SDL
+# Makefile options for SDL2 backend.
 #
 
 #
-#SDL...., *looks at Alam*, THIS IS A MESS!
+# SDL...., *looks at Alam*, THIS IS A MESS!
+# 
+# ...a little bird flexes its muscles...
 #
 
-ifdef UNIXCOMMON
-include sdl/MakeNIX.cfg
-endif
+makedir:=$(makedir)/SDL
 
-ifdef PANDORA
-include sdl/SRB2Pandora/Makefile.cfg
-endif #ifdef PANDORA
+sources+=$(call List,sdl/Sourcefile)
+opts+=-DDIRECTFULLSCREEN -DHAVE_SDL
 
-ifdef CYGWIN32
-include sdl/MakeCYG.cfg
-endif #ifdef CYGWIN32
+# FIXME
+#ifdef PANDORA
+#include sdl/SRB2Pandora/Makefile.cfg
+#endif #ifdef PANDORA
 
-ifdef SDL_PKGCONFIG
-SDL_CFLAGS?=$(shell $(PKG_CONFIG) $(SDL_PKGCONFIG) --cflags)
-SDL_LDFLAGS?=$(shell $(PKG_CONFIG) $(SDL_PKGCONFIG) --libs)
-else
-ifdef PREFIX
-	SDL_CONFIG?=$(PREFIX)-sdl2-config
-else
-	SDL_CONFIG?=sdl2-config
-endif
-
-ifdef STATIC
-	SDL_CFLAGS?=$(shell $(SDL_CONFIG) --cflags)
-	SDL_LDFLAGS?=$(shell $(SDL_CONFIG) --static-libs)
-else
-	SDL_CFLAGS?=$(shell $(SDL_CONFIG) --cflags)
-	SDL_LDFLAGS?=$(shell $(SDL_CONFIG) --libs)
-endif
-endif
-
-
-	#use the x86 asm code
-ifndef CYGWIN32
-ifndef NOASM
-	USEASM=1
-endif
-endif
-
-	OBJS+=$(OBJDIR)/i_video.o $(OBJDIR)/dosstr.o $(OBJDIR)/endtxt.o $(OBJDIR)/hwsym_sdl.o
-
-	OPTS+=-DDIRECTFULLSCREEN -DHAVE_SDL
+# FIXME
+#ifdef CYGWIN32
+#include sdl/MakeCYG.cfg
+#endif #ifdef CYGWIN32
 
 ifndef NOHW
-	OBJS+=$(OBJDIR)/r_opengl.o $(OBJDIR)/ogl_sdl.o
+sources+=sdl/ogl_sdl.c
 endif
 
 ifdef NOMIXER
-	i_sound_o=$(OBJDIR)/sdl_sound.o
-else
-	i_sound_o=$(OBJDIR)/mixer_sound.o
-	OPTS+=-DHAVE_MIXER
-ifdef HAVE_MIXERX
-	OPTS+=-DHAVE_MIXERX
-	SDL_LDFLAGS+=-lSDL2_mixer_ext
+sources+=sdl/sdl_sound.c
 else
-	SDL_LDFLAGS+=-lSDL2_mixer
-endif
+opts+=-DHAVE_MIXER
+sources+=sdl/mixer_sound.c
+
+  ifdef HAVE_MIXERX
+  opts+=-DHAVE_MIXERX
+  libs+=-lSDL2_mixer_ext
+  else
+  libs+=-lSDL2_mixer
+  endif
 endif
 
 ifndef NOTHREADS
-	OPTS+=-DHAVE_THREADS
-	OBJS+=$(OBJDIR)/i_threads.o
+opts+=-DHAVE_THREADS
+sources+=sdl/i_threads.c
 endif
 
-ifdef SDL_TTF
-	OPTS+=-DHAVE_TTF
-	SDL_LDFLAGS+=-lSDL2_ttf -lfreetype -lz
-	OBJS+=$(OBJDIR)/i_ttf.o
+ifdef SDL_PKGCONFIG
+$(eval $(call Use_pkg_config,SDL))
+else
+SDL_CONFIG?=$(call Prefix,sdl2-config)
+SDL_CFLAGS?=$(shell $(SDL_CONFIG) --cflags)
+SDL_LDFLAGS?=$(shell $(SDL_CONFIG) \
+		$(if $(STATIC),--static-libs,--libs))
+$(eval $(call Propogate_flags,SDL))
 endif
 
-ifdef SDL_IMAGE
-	OPTS+=-DHAVE_IMAGE
-	SDL_LDFLAGS+=-lSDL2_image
+# use the x86 asm code
+ifndef CYGWIN32
+ifndef NOASM
+USEASM=1
 endif
-
-ifdef SDL_NET
-	OPTS+=-DHAVE_SDLNET
-	SDL_LDFLAGS+=-lSDL2_net
 endif
 
+# FIXME
+#ifdef SDL_TTF
+#	OPTS+=-DHAVE_TTF
+#	SDL_LDFLAGS+=-lSDL2_ttf -lfreetype -lz
+#	OBJS+=$(OBJDIR)/i_ttf.o
+#endif
+
+# FIXME
+#ifdef SDL_IMAGE
+#	OPTS+=-DHAVE_IMAGE
+#	SDL_LDFLAGS+=-lSDL2_image
+#endif
+
+# FIXME
+#ifdef SDL_NET
+#	OPTS+=-DHAVE_SDLNET
+#	SDL_LDFLAGS+=-lSDL2_net
+#endif
+
 ifdef MINGW
 ifndef NOSDLMAIN
-	SDLMAIN=1
+SDLMAIN=1
 endif
 endif
 
 ifdef SDLMAIN
-	OPTS+=-DSDLMAIN
-else
-ifdef MINGW
-	SDL_CFLAGS+=-Umain
-	SDL_LDFLAGS+=-mconsole
-endif
-endif
-
-ifndef NOHW
-ifdef OPENAL
-ifdef MINGW
-	LIBS:=-lopenal32 $(LIBS)
-else
-	LIBS:=-lopenal $(LIBS)
-endif
+opts+=-DSDLMAIN
 else
 ifdef MINGW
-ifdef DS3D
-	LIBS:=-ldsound -luuid $(LIBS)
-endif
-endif
+opts+=-Umain
+libs+=-mconsole
 endif
 endif
-
-CFLAGS+=$(SDL_CFLAGS)
-LIBS:=$(SDL_LDFLAGS) $(LIBS)
-ifdef STATIC
-	LIBS+=$(shell $(SDL_CONFIG) --static-libs)
-endif
diff --git a/src/Makefile.d/util.mk b/src/Makefile.d/util.mk
new file mode 100644
index 000000000..88f141bee
--- /dev/null
+++ b/src/Makefile.d/util.mk
@@ -0,0 +1,89 @@
+#
+# Utility macros for the rest of the Makefiles.
+#
+
+Ifnot=$(if $(1),$(3),$(2))
+Ifndef=$(call Ifnot,$($(1)),$(2),$(3))
+
+# Match and expand a list of variables by pattern.
+Wildvar=$(foreach v,$(filter $(1),$(.VARIABLES)),$($(v)))
+
+# Read a list of words from file and prepend each with the
+# directory of the file.
+List=$(addprefix $(dir $(1)),$(file < $(1)))
+
+define Propogate_flags =
+opts+=$$($(1)_CFLAGS)
+libs+=$$($(1)_LDFLAGS)
+endef
+
+# Set library's _CFLAGS and _LDFLAGS from some command.
+# Automatically propogates the flags too.
+# 1: variable prefix (e.g. CURL)
+# 2: start of command (e.g. curl-config)
+# --- optional ----
+# 3: CFLAGS command arguments, default '--cflags'
+# 4: LDFLAGS command arguments, default '--libs'
+# 5: common command arguments at the end of command
+define Configure =
+$(1)_CFLAGS?=$$(shell $(2) $(or $(3),--cflags) $(5))
+$(1)_LDFLAGS?=$$(shell $(2) $(or $(4),--libs) $(5))
+$(call Propogate_flags,$(1))
+endef
+
+# Configure library with pkg-config. The package name is
+# taken from a _PKGCONFIG variable.
+# 1: variable prefix
+#
+#     LIBGME_PKGCONFIG=libgme
+#     $(eval $(call Use_pkg_config,LIBGME))
+define Use_pkg_config =
+$(call Configure,$(1),$(PKG_CONFIG),,,$($(1)_PKGCONFIG))
+endef
+
+# Check disabling flag and configure package in one step
+# according to delimited argument.
+# (There is only one argument, but it split by slash.)
+# 1/: short form library name (uppercase). This is
+#     prefixed with 'NO' and 'HAVE_'. E.g. NOGME, HAVE_GME
+# /2: package name (e.g. libgme)
+# /3: variable prefix
+#
+# The following example would check if NOGME is not
+# defined before attempting to define LIBGME_CFLAGS and
+# LIBGME_LDFLAGS as with Use_pkg_config.
+#
+#     $(eval $(call Check_pkg_config,GME/libgme/LIBGME))
+define Check_pkg_config =
+_p:=$(subst /, ,$(1))
+_v1:=$$(word 1,$$(_p))
+_v2:=$$(or $$(word 3,$$(_p)),$$(_v1))
+ifndef NO$$(_v1)
+$$(_v2)_PKGCONFIG?=$$(word 2,$$(_p))
+$$(eval $$(call Use_pkg_config,$$(_v2)))
+opts+=-DHAVE_$$(_v1)
+endif
+endef
+
+#     $(call Prefix,gcc)
+Prefix=$(if $(PREFIX),$(PREFIX)-)$(1)
+
+Echo=
+Echo_name=
+Print=
+
+ifndef SILENT
+Echo=@echo "$(1)"
+ifndef ECHO
+ifndef NOECHOFILENAMES
+Echo_name=$(call Echo,-- $(1) ...)
+endif
+endif
+ifndef MAKE_RESTARTS
+ifndef destructive
+Print=$(info $(1))
+endif
+endif
+endif
+
+.=$(call Ifndef,ECHO,@)
diff --git a/src/Makefile.d/versions.mk b/src/Makefile.d/versions.mk
index 075cd2d3a..fe2b6b851 100644
--- a/src/Makefile.d/versions.mk
+++ b/src/Makefile.d/versions.mk
@@ -1,215 +1,23 @@
-# vim: ft=make
 #
-# Makefile.cfg for SRB2
+# Flags to put a sock in GCC!
 #
 
-#
-# GNU compiler & tools' flags
-# and other things
-#
-
-# See the following variable don't start with 'GCC'. This is
-# to avoid a false positive with the version detection...
-
-SUPPORTED_GCC_VERSIONS:=\
-	101 102\
-	91 92 93\
-	81 82 83 84\
-	71 72 73 74 75\
-	61 62 63 64\
-	51 52 53 54 55\
-	40 41 42 43 44 45 46 47 48 49
-
-LATEST_GCC_VERSION=10.2
-
-# gcc or g++
-ifdef PREFIX
-	CC=$(PREFIX)-gcc
-	CXX=$(PREFIX)-g++
-	OBJCOPY=$(PREFIX)-objcopy
-	OBJDUMP=$(PREFIX)-objdump
-	STRIP=$(PREFIX)-strip
-	WINDRES=$(PREFIX)-windres
-else
-	OBJCOPY=objcopy
-	OBJDUMP=objdump
-	STRIP=strip
-	WINDRES=windres
-endif
-
-# because Apple screws with us on this
-# need to get bintools from homebrew
-ifdef MACOSX
-	CC=clang
-	CXX=clang
-	OBJCOPY=gobjcopy
-	OBJDUMP=gobjdump
-endif
-
-# Automatically set version flag, but not if one was manually set
-# And don't bother if this is a clean only run
-ifeq   (,$(filter GCC% CLEANONLY,$(.VARIABLES)))
- version:=$(shell $(CC) --version)
- # check if this is in fact GCC
- ifneq (,$(or $(findstring gcc,$(version)),$(findstring GCC,$(version))))
-  version:=$(shell $(CC) -dumpversion)
-
-  # Turn version into words of major, minor
-  v:=$(subst ., ,$(version))
-  # concat. major minor
-  v:=$(word 1,$(v))$(word 2,$(v))
-
-  # If this version is not in the list, default to the latest supported
-  ifeq (,$(filter $(v),$(SUPPORTED_GCC_VERSIONS)))
-	define line =
-	Your compiler version, GCC $(version), is not supported by the Makefile.
-	The Makefile will assume GCC $(LATEST_GCC_VERSION).))
-	endef
-   $(call print,$(line))
-   GCC$(subst .,,$(LATEST_GCC_VERSION))=1
-  else
-   $(call print,Detected GCC $(version) (GCC$(v)))
-   GCC$(v)=1
-  endif
- endif
-endif
-
-ifdef GCC102
-GCC101=1
+# See the versions list in detect.mk
+# This will define all version flags going backward.
+# Yes, it's magic.
+define _predecessor =
+ifdef GCC$(firstword $(1))
+GCC$(lastword $(1)):=1
 endif
+endef
+_n:=$(words $(gcc_versions))
+$(foreach v,$(join $(wordlist 2,$(_n),- $(gcc_versions)),\
+	$(addprefix =,$(wordlist 2,$(_n),$(gcc_versions)))),\
+	$(and $(findstring =,$(v)),\
+	$(eval $(call _predecessor,$(subst =, ,$(v))))))
 
-ifdef GCC101
-GCC93=1
-endif
-
-ifdef GCC93
-GCC92=1
-endif
-
-ifdef GCC92
-GCC91=1
-endif
-
-ifdef GCC91
-GCC84=1
-endif
-
-ifdef GCC84
-GCC83=1
-endif
-
-ifdef GCC83
-GCC82=1
-endif
-
-ifdef GCC82
-GCC81=1
-endif
-
-ifdef GCC81
-GCC75=1
-endif
-
-ifdef GCC75
-GCC74=1
-endif
-
-ifdef GCC74
-GCC73=1
-endif
-
-ifdef GCC73
-GCC72=1
-endif
-
-ifdef GCC72
-GCC71=1
-endif
-
-ifdef GCC71
-GCC64=1
-endif
-
-ifdef GCC64
-GCC63=1
-endif
-
-ifdef GCC63
-GCC62=1
-endif
-
-ifdef GCC62
-GCC61=1
-endif
-
-ifdef GCC61
-GCC55=1
-endif
-
-ifdef GCC55
-GCC54=1
-endif
-
-ifdef GCC54
-GCC53=1
-endif
-
-ifdef GCC53
-GCC52=1
-endif
-
-ifdef GCC52
-GCC51=1
-endif
-
-ifdef GCC51
-GCC49=1
-endif
-
-ifdef GCC49
-GCC48=1
-endif
-
-ifdef GCC48
-GCC47=1
-endif
-
-ifdef GCC47
-GCC46=1
-endif
-
-ifdef GCC46
-GCC45=1
-endif
-
-ifdef GCC45
-GCC44=1
-endif
-
-ifdef GCC44
-GCC43=1
-endif
-
-ifdef GCC43
-GCC42=1
-endif
-
-ifdef GCC42
-GCC41=1
-endif
-
-ifdef GCC41
-GCC40=1
-VCHELP=1
-endif
-
-ifdef GCC295
-GCC29=1
-endif
-
-OLDWFLAGS:=$(WFLAGS)
 # -W -Wno-unused
-WFLAGS=-Wall
+WFLAGS:=-Wall
 ifndef GCC295
 #WFLAGS+=-Wno-packed
 endif
@@ -222,15 +30,13 @@ endif
 #WFLAGS+=-Wsystem-headers
 WFLAGS+=-Wfloat-equal
 #WFLAGS+=-Wtraditional
-ifdef VCHELP
- WFLAGS+=-Wdeclaration-after-statement
- WFLAGS+=-Wno-error=declaration-after-statement
-endif
  WFLAGS+=-Wundef
 ifndef GCC295
  WFLAGS+=-Wendif-labels
 endif
 ifdef GCC41
+ WFLAGS+=-Wdeclaration-after-statement
+ WFLAGS+=-Wno-error=declaration-after-statement
  WFLAGS+=-Wshadow
 endif
 #WFLAGS+=-Wlarger-than-%len%
@@ -308,8 +114,6 @@ ifdef ERRORMODE
 WFLAGS+=-Werror
 endif
 
-WFLAGS+=$(OLDWFLAGS)
-
 ifdef GCC43
  #WFLAGS+=-Wno-error=clobbered
 endif
@@ -338,141 +142,36 @@ ifdef GCC81
  WFLAGS+=-Wno-error=multistatement-macros
 endif
 
-
-#indicate platform and what interface use with
-ifndef LINUX
-ifndef FREEBSD
-ifndef CYGWIN32
-ifndef MINGW
-ifndef MINGW64
-ifndef SDL
-ifndef DUMMY
-$(error No interface or platform flag defined)
-endif
-endif
-endif
-endif
-endif
-endif
-endif
-
-#determine the interface directory (where you put all i_*.c)
-i_net_o=$(OBJDIR)/i_net.o
-i_system_o=$(OBJDIR)/i_system.o
-i_sound_o=$(OBJDIR)/i_sound.o
-i_main_o=$(OBJDIR)/i_main.o
-#set OBJDIR and BIN's starting place
-OBJDIR=../objs
-BIN=../bin
-DEPDIR=../dep
-#Nasm ASM and rm
-ifdef YASM
-NASM?=yasm
-else
-NASM?=nasm
-endif
-REMOVE?=rm -f
-MKDIR?=mkdir -p
-GZIP?=gzip
-GZIP_OPTS?=-9 -f -n
-GZIP_OPT2=$(GZIP_OPTS) --rsyncable
-UPX?=upx
-UPX_OPTS?=--best --preserve-build-id
-ifndef ECHO
-UPX_OPTS+=-q
-endif
-
-#Interface Setup
-ifdef DUMMY
-	INTERFACE=dummy
-	OBJDIR:=$(OBJDIR)/dummy
-	BIN:=$(BIN)/dummy
-	DEPDIR:=$(DEPDIR)/dummy
-else
-ifdef LINUX
-	NASMFORMAT=elf -DLINUX
-	SDL=1
-ifdef LINUX64
-	OBJDIR:=$(OBJDIR)/Linux64
-	BIN:=$(BIN)/Linux64
-	DEPDIR:=$(DEPDIR)/Linux64
+ifdef NONX86
+  ifdef X86_64 # yeah that SEEMS contradictory
+  opts+=-march=nocona
+  endif
 else
-	OBJDIR:=$(OBJDIR)/Linux
-	BIN:=$(BIN)/Linux
-	DEPDIR:=$(DEPDIR)/Linux
+  ifndef GCC29
+  opts+=-msse3 -mfpmath=sse
+  else
+  opts+=-mpentium
+  endif
 endif
-else
-ifdef FREEBSD
-	INTERFACE=sdl
-	NASMFORMAT=elf -DLINUX
-	SDL=1
-
-	OBJDIR:=$(OBJDIR)/FreeBSD
-	BIN:=$(BIN)/FreeBSD
-	DEPDIR:=$(DEPDIR)/Linux
-else
-ifdef SOLARIS
-	INTERFACE=sdl
-	NASMFORMAT=elf -DLINUX
-	SDL=1
 
-	OBJDIR:=$(OBJDIR)/Solaris
-	BIN:=$(BIN)/Solaris
-	DEPDIR:=$(DEPDIR)/Solaris
-else
-ifdef CYGWIN32
-	INTERFACE=sdl
-	NASMFORMAT=win32
-	SDL=1
-
-	OBJDIR:=$(OBJDIR)/cygwin
-	BIN:=$(BIN)/Cygwin
-	DEPDIR:=$(DEPDIR)/Cygwin
-else
-ifdef MINGW64
-	#NASMFORMAT=win64
-	SDL=1
-	OBJDIR:=$(OBJDIR)/Mingw64
-	BIN:=$(BIN)/Mingw64
-	DEPDIR:=$(DEPDIR)/Mingw64
+ifdef DEBUGMODE
+ifdef GCC48
+opts+=-Og
 else
-ifdef MINGW
-	NASMFORMAT=win32
-	SDL=1
-	OBJDIR:=$(OBJDIR)/Mingw
-	BIN:=$(BIN)/Mingw
-	DEPDIR:=$(DEPDIR)/Mingw
-endif
-endif
-endif
-endif
-endif
+opts+=O0
 endif
 endif
 
-ifdef ARCHNAME
-	OBJDIR:=$(OBJDIR)/$(ARCHNAME)
-	BIN:=$(BIN)/$(ARCHNAME)
-	DEPDIR:=$(DEPDIR)/$(ARCHNAME)
+ifdef VALGRIND
+ifdef GCC46
+WFLAGS+=-Wno-error=unused-but-set-variable
+WFLAGS+=-Wno-unused-but-set-variable
 endif
-
-OBJDUMP_OPTS?=--wide --source --line-numbers
-LD=$(CC)
-
-ifdef SDL
-	INTERFACE=sdl
-	OBJDIR:=$(OBJDIR)/SDL
-	DEPDIR:=$(DEPDIR)/SDL
 endif
 
-ifndef DUMMY
-ifdef DEBUGMODE
-	OBJDIR:=$(OBJDIR)/Debug
-	BIN:=$(BIN)/Debug
-	DEPDIR:=$(DEPDIR)/Debug
-else
-	OBJDIR:=$(OBJDIR)/Release
-	BIN:=$(BIN)/Release
-	DEPDIR:=$(DEPDIR)/Release
+# Lua
+ifdef GCC43
+ifndef GCC44
+WFLAGS+=-Wno-logical-op
 endif
 endif
diff --git a/src/Makefile.d/win32.mk b/src/Makefile.d/win32.mk
index 702ae3765..0c671b268 100644
--- a/src/Makefile.d/win32.mk
+++ b/src/Makefile.d/win32.mk
@@ -1,136 +1,99 @@
 #
-# win32/Makefile.cfg for SRB2/Minwgw
+# Mingw, if you don't know, that's Win32/Win64
 #
 
-#
-#Mingw, if you don't know, that's Win32/Win64
-#
-
-ifdef MINGW64
-	HAVE_LIBGME=1
-	LIBGME_CFLAGS=-I../libs/gme/include
-	LIBGME_LDFLAGS=-L../libs/gme/win64 -lgme
-ifdef HAVE_OPENMPT
-	LIBOPENMPT_CFLAGS?=-I../libs/libopenmpt/inc
-	LIBOPENMPT_LDFLAGS?=-L../libs/libopenmpt/lib/x86_64/mingw -lopenmpt
-endif
-ifndef NOMIXERX
-	HAVE_MIXERX=1
-	SDL_CFLAGS?=-I../libs/SDL2/x86_64-w64-mingw32/include/SDL2 -I../libs/SDLMixerX/x86_64-w64-mingw32/include/SDL2 -Dmain=SDL_main
-	SDL_LDFLAGS?=-L../libs/SDL2/x86_64-w64-mingw32/lib -L../libs/SDLMixerX/x86_64-w64-mingw32/lib -lmingw32 -lSDL2main -lSDL2 -mwindows
-else
-	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
-endif
-else
-	HAVE_LIBGME=1
-	LIBGME_CFLAGS=-I../libs/gme/include
-	LIBGME_LDFLAGS=-L../libs/gme/win32 -lgme
-ifdef HAVE_OPENMPT
-	LIBOPENMPT_CFLAGS?=-I../libs/libopenmpt/inc
-	LIBOPENMPT_LDFLAGS?=-L../libs/libopenmpt/lib/x86/mingw -lopenmpt
-endif
-ifndef NOMIXERX
-	HAVE_MIXERX=1
-	SDL_CFLAGS?=-I../libs/SDL2/i686-w64-mingw32/include/SDL2 -I../libs/SDLMixerX/i686-w64-mingw32/include/SDL2 -Dmain=SDL_main
-	SDL_LDFLAGS?=-L../libs/SDL2/i686-w64-mingw32/lib -L../libs/SDLMixerX/i686-w64-mingw32/lib -lmingw32 -lSDL2main -lSDL2 -mwindows
+ifndef MINGW64
+EXENAME?=srb2win.exe
 else
-	SDL_CFLAGS?=-I../libs/SDL2/i686-w64-mingw32/include/SDL2 -I../libs/SDL2_mixer/i686-w64-mingw32/include/SDL2 -Dmain=SDL_main
-	SDL_LDFLAGS?=-L../libs/SDL2/i686-w64-mingw32/lib -L../libs/SDL2_mixer/i686-w64-mingw32/lib -lmingw32 -lSDL2main -lSDL2 -mwindows
-endif
+EXENAME?=srb2win64.exe
 endif
 
-ifndef NOASM
-	USEASM=1
-endif
+sources+=win32/Srb2win.rc
+opts+=-DSTDC_HEADERS
+libs+=-ladvapi32 -lkernel32 -lmsvcrt -luser32
 
-ifndef NONET
-ifndef MINGW64 #miniupnc is broken with MINGW64
-	HAVE_MINIUPNPC=1
-endif
-endif
+nasm_format:=win32
 
-	OPTS=-DSTDC_HEADERS
+SDL=1
 
-ifndef GCC44
-	#OPTS+=-mms-bitfields
+ifndef NOHW
+opts+=-DUSE_WGL_SWAP
 endif
 
-	LIBS+=-ladvapi32 -lkernel32 -lmsvcrt -luser32
 ifdef MINGW64
-	LIBS+=-lws2_32
+libs+=-lws2_32
 else
 ifdef NO_IPV6
-	LIBS+=-lwsock32
+libs+=-lwsock32
 else
-	LIBS+=-lws2_32
+libs+=-lws2_32
 endif
 endif
 
-	# name of the exefile
-	EXENAME?=srb2win.exe
-
-ifdef SDL
-	i_system_o+=$(OBJDIR)/SRB2.res
-	#i_main_o+=$(OBJDIR)/win_dbg.o
-ifndef NOHW
-	OPTS+=-DUSE_WGL_SWAP
+ifndef NONET
+ifndef MINGW64 # miniupnc is broken with MINGW64
+opts+=-I../libs -DSTATIC_MINIUPNPC
+libs+=-L../libs/miniupnpc/mingw$(32) -lws2_32 -liphlpapi
 endif
 endif
 
-
-ZLIB_CFLAGS?=-I../libs/zlib
-ifdef MINGW64
-ZLIB_LDFLAGS?=-L../libs/zlib/win32 -lz64
+ifndef MINGW64
+32=32
+x86=x86
+i686=i686
 else
-ZLIB_LDFLAGS?=-L../libs/zlib/win32 -lz32
+32=64
+x86=x86_64
+i686=x86_64
 endif
 
-ifndef NOPNG
-ifndef PNG_CONFIG
-	PNG_CFLAGS?=-I../libs/libpng-src
-ifdef MINGW64
-	PNG_LDFLAGS?=-L../libs/libpng-src/projects -lpng64
-else
-	PNG_LDFLAGS?=-L../libs/libpng-src/projects -lpng32
-endif #MINGW64
-endif #PNG_CONFIG
-endif #NOPNG
-
-ifdef GETTEXT
-ifndef CCBS
-	MSGFMT?=../libs/gettext/bin32/msgfmt.exe
-endif
-ifdef MINGW64
-	CPPFLAGS+=-I../libs/gettext/include64
-	LDFLAGS+=-L../libs/gettext/lib64
-	LIBS+=-lmingwex
-else
-	CPPFLAGS+=-I../libs/gettext/include32
-	LDFLAGS+=-L../libs/gettext/lib32
-	STATIC_GETTEXT=1
-endif #MINGW64
-ifdef STATIC_GETTEXT
-	LIBS+=-lasprintf -lintl
-else
-	LIBS+=-lintl.dll
-endif #STATIC_GETTEXT
-endif #GETTEXT
+mingw:=$(i686)-w64-mingw32
 
-ifdef HAVE_MINIUPNPC
-	CPPFLAGS+=-I../libs/ -DSTATIC_MINIUPNPC
-ifdef MINGW64
-	LDFLAGS+=-L../libs/miniupnpc/mingw64
+define _set =
+$(1)_CFLAGS?=$($(1)_opts)
+$(1)_LDFLAGS?=$($(1)_libs)
+endef
+
+lib:=../libs/gme
+LIBGME_opts:=-I$(lib)/include
+LIBGME_libs:=-L$(lib)/win$(32) -lgme
+$(eval $(call _set,LIBGME))
+
+lib:=../libs/libopenmpt
+LIBOPENMPT_opts:=-I$(lib)/inc
+LIBOPENMPT_libs:=-L$(lib)/lib/$(x86)/mingw -lopenmpt
+$(eval $(call _set,LIBOPENMPT))
+
+ifndef NOMIXERX
+HAVE_MIXERX=1
+lib:=../libs/SDLMixerX/$(mingw)
 else
-	LDFLAGS+=-L../libs/miniupnpc/mingw32
-endif #MINGW64
+lib:=../libs/SDL2_mixer/$(mingw)
 endif
 
-ifndef NOCURL
-	CURL_CFLAGS+=-I../libs/curl/include
-ifdef MINGW64
-	CURL_LDFLAGS+=-L../libs/curl/lib64 -lcurl
-else
-	CURL_LDFLAGS+=-L../libs/curl/lib32 -lcurl
-endif #MINGW64
+mixer_opts:=-I$(lib)/include/SDL2
+mixer_libs:=-L$(lib)/lib
+
+lib:=../libs/SDL2/$(mingw)
+SDL_opts:=-I$(lib)/include/SDL2\
+	$(mixer_opts) -Dmain=SDL_main
+SDL_libs:=-L$(lib)/lib $(mixer_libs)\
+	-lmingw32 -lSDL2main -lSDL2 -mwindows
+$(eval $(call _set,SDL))
+
+lib:=../libs/zlib
+ZLIB_opts:=-I$(lib)
+ZLIB_libs:=-L$(lib)/win32 -lz$(32)
+$(eval $(call _set,ZLIB))
+
+ifndef PNG_CONFIG
+lib:=../libs/libpng-src
+PNG_opts:=-I$(lib)
+PNG_libs:=-L$(lib)/projects -lpng$(32)
+$(eval $(call _set,PNG))
 endif
+
+lib:=../libs/curl
+CURL_opts:=-I$(lib)/include
+CURL_libs:=-L$(lib)/lib$(32) -lcurl
+$(eval $(call _set,CURL))
diff --git a/src/Sourcefile b/src/Sourcefile
new file mode 100644
index 000000000..9f27f2810
--- /dev/null
+++ b/src/Sourcefile
@@ -0,0 +1,87 @@
+string.c
+d_main.c
+d_clisrv.c
+d_net.c
+d_netfil.c
+d_netcmd.c
+dehacked.c
+z_zone.c
+f_finale.c
+f_wipe.c
+g_demo.c
+g_game.c
+g_input.c
+am_map.c
+command.c
+console.c
+hu_stuff.c
+y_inter.c
+st_stuff.c
+m_aatree.c
+m_anigif.c
+m_argv.c
+m_bbox.c
+m_cheat.c
+m_cond.c
+m_fixed.c
+m_menu.c
+m_misc.c
+m_random.c
+m_queue.c
+info.c
+p_ceilng.c
+p_enemy.c
+p_floor.c
+p_inter.c
+p_lights.c
+p_map.c
+p_maputl.c
+p_mobj.c
+p_polyobj.c
+p_saveg.c
+p_setup.c
+p_sight.c
+p_spec.c
+p_telept.c
+p_tick.c
+p_user.c
+p_slopes.c
+tables.c
+r_bsp.c
+r_data.c
+r_draw.c
+r_main.c
+r_plane.c
+r_segs.c
+r_skins.c
+r_sky.c
+r_splats.c
+r_things.c
+r_textures.c
+r_picformats.c
+r_portal.c
+screen.c
+v_video.c
+s_sound.c
+sounds.c
+w_wad.c
+filesrch.c
+mserv.c
+http-mserv.c
+i_tcp.c
+lzf.c
+vid_copy.s
+b_bot.c
+lua_script.c
+lua_baselib.c
+lua_mathlib.c
+lua_hooklib.c
+lua_consolelib.c
+lua_infolib.c
+lua_mobjlib.c
+lua_playerlib.c
+lua_skinlib.c
+lua_thinkerlib.c
+lua_maplib.c
+lua_blockmaplib.c
+lua_hudlib.c
diff --git a/src/blua/Sourcefile b/src/blua/Sourcefile
new file mode 100644
index 000000000..f99c89c8d
--- /dev/null
+++ b/src/blua/Sourcefile
@@ -0,0 +1,25 @@
+lapi.c
+lbaselib.c
+ldo.c
+lfunc.c
+linit.c
+liolib.c
+llex.c
+lmem.c
+lobject.c
+lstate.c
+lstrlib.c
+ltablib.c
+lundump.c
+lzio.c
+lauxlib.c
+lcode.c
+ldebug.c
+ldump.c
+lgc.c
+lopcodes.c
+lparser.c
+lstring.c
+ltable.c
+ltm.c
+lvm.c
diff --git a/src/hardware/Sourcefile b/src/hardware/Sourcefile
new file mode 100644
index 000000000..1c05de76c
--- /dev/null
+++ b/src/hardware/Sourcefile
@@ -0,0 +1,13 @@
+hw_bsp.c
+hw_draw.c
+hw_light.c
+hw_main.c
+hw_clip.c
+hw_md2.c
+hw_cache.c
+hw_md2load.c
+hw_md3load.c
+hw_model.c
+u_list.c
+hw_batching.c
+r_opengl/r_opengl.c
diff --git a/src/sdl/Sourcefile b/src/sdl/Sourcefile
new file mode 100644
index 000000000..82d5ce073
--- /dev/null
+++ b/src/sdl/Sourcefile
@@ -0,0 +1,7 @@
+i_net.c
+i_system.c
+i_main.c
+i_video.c
+dosstr.c
+endtxt.c
+hwsym_sdl.c
-- 
GitLab