shithub: choc

Download patch

ref: a0056875827f1e6efb74834cc8ac051ecc2d765c
parent: dd283bcfdcb1eee83e76228d5818d1ad031adf17
parent: d0497ad2cd385bbfe741542052cef91339d1dd3d
author: Simon Howard <[email protected]>
date: Mon Jun 4 16:54:04 EDT 2018

Merge pull request #1054 from AlexMax/cmake

CMake Build FIles - Visual Studio project replacement

--- a/.gitignore
+++ b/.gitignore
@@ -28,6 +28,7 @@
 HTIC*.pcx
 HEXEN*.pcx
 STRIFE*.pcx
+/build*
 
 # These are the default patterns globally ignored by Subversion:
 *.o
--- /dev/null
+++ b/CMakeLists.txt
@@ -1,0 +1,70 @@
+set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
+
+cmake_minimum_required(VERSION 3.7.2)
+project("Chocolate Doom" VERSION 3.0.0 LANGUAGES C)
+
+# Autotools variables
+set(top_srcdir ${CMAKE_CURRENT_SOURCE_DIR})
+set(top_builddir ${CMAKE_CURRENT_BINARY_DIR})
+
+# AC_INIT variables
+set(PACKAGE_NAME "${PROJECT_NAME}")
+set(PACKAGE_TARNAME "chocolate-doom")
+set(PACKAGE_VERSION "${PROJECT_VERSION}")
+set(PACKAGE_STRING "${PROJECT_NAME} ${PROJECT_VERSION}")
+set(PACKAGE_BUGREPORT "[email protected]")
+
+string(REGEX REPLACE " Doom$" "" PACKAGE_SHORTNAME "${PACKAGE_NAME}")
+set(PACKAGE_COPYRIGHT "Copyright (C) 1993-2017")
+set(PACKAGE_LICENSE "GNU General Public License, version 2")
+
+# Any settings that should apply to all targets in this directory and all
+# subdirectories should go here.  Use judiciously.
+if(MSVC)
+    add_definitions("/D_CRT_SECURE_NO_WARNINGS" "/D_CRT_SECURE_NO_DEPRECATE"
+                    "/D_CRT_NONSTDC_NO_DEPRECATE")
+else()
+    add_compile_options("-Wall" "-Wdeclaration-after-statement"
+                        "-Wredundant-decls")
+endif()
+
+find_package(SDL2 2.0.1)
+find_package(SDL2_mixer 2.0.0)
+find_package(SDL2_net 2.0.0)
+
+# Check for libsamplerate.
+find_package(samplerate)
+if(SAMPLERATE_FOUND)
+    set(HAVE_LIBSAMPLERATE TRUE)
+endif()
+
+# Check for libpng.
+find_package(PNG)
+if(PNG_FOUND)
+    set(HAVE_LIBPNG TRUE)
+endif()
+
+find_package(m)
+
+include(CheckSymbolExists)
+check_symbol_exists(strcasecmp "strings.h" HAVE_DECL_STRCASECMP)
+check_symbol_exists(strncasecmp "strings.h" HAVE_DECL_STRNCASECMP)
+
+string(CONCAT WINDOWS_RC_VERSION "${PROJECT_VERSION_MAJOR}, "
+    "${PROJECT_VERSION_MINOR}, ${PROJECT_VERSION_PATCH}, 0")
+
+# Without a hyphen. This is used for the bash-completion scripts.
+string(TOLOWER "${PACKAGE_SHORTNAME}" PROGRAM_SPREFIX)
+
+# With a hyphen, used almost everywhere else.
+set(PROGRAM_PREFIX "${PROGRAM_SPREFIX}-")
+
+configure_file(cmake/config.h.cin config.h)
+
+configure_file(src/resource.rc.in src/resource.rc)
+configure_file(src/setup-res.rc.in src/setup-res.rc)
+configure_file(src/setup/setup-manifest.xml.in src/setup/setup-manifest.xml)
+
+foreach(SUBDIR textscreen midiproc opl pcsound src)
+    add_subdirectory("${SUBDIR}")
+endforeach()
--- /dev/null
+++ b/cmake/FindSDL2.cmake
@@ -1,0 +1,97 @@
+# FindSDL2.cmake
+#
+# Copyright (c) 2018, Alex Mayfield <[email protected]>
+# All rights reserved.
+# 
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#     * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above copyright
+#       notice, this list of conditions and the following disclaimer in the
+#       documentation and/or other materials provided with the distribution.
+#     * Neither the name of the <organization> nor the
+#       names of its contributors may be used to endorse or promote products
+#       derived from this software without specific prior written permission.
+# 
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# Currently works with the following generators:
+# - Unix Makefiles
+# - Ninja
+# - Visual Studio
+
+# Cache variable that allows you to point CMake at a directory containing
+# an extracted development library.
+set(SDL2_DIR "${SDL2_DIR}" CACHE PATH "Location of SDL2 library directory")
+
+# Use pkg-config to find library locations in *NIX environments.
+find_package(PkgConfig QUIET)
+if(PKG_CONFIG_FOUND)
+    pkg_search_module(PC_SDL2 QUIET sdl2)
+endif()
+
+# Find the include directory.
+find_path(SDL2_INCLUDE_DIR "SDL_version.h"
+    HINTS "${SDL2_DIR}/include" ${PC_SDL2_INCLUDE_DIRS})
+
+# Find the version.  Taken and modified from CMake's FindSDL.cmake.
+if(SDL2_INCLUDE_DIR AND EXISTS "${SDL2_INCLUDE_DIR}/SDL_version.h")
+    file(STRINGS "${SDL2_INCLUDE_DIR}/SDL_version.h" SDL2_VERSION_MAJOR_LINE REGEX "^#define[ \t]+SDL_MAJOR_VERSION[ \t]+[0-9]+$")
+    file(STRINGS "${SDL2_INCLUDE_DIR}/SDL_version.h" SDL2_VERSION_MINOR_LINE REGEX "^#define[ \t]+SDL_MINOR_VERSION[ \t]+[0-9]+$")
+    file(STRINGS "${SDL2_INCLUDE_DIR}/SDL_version.h" SDL2_VERSION_PATCH_LINE REGEX "^#define[ \t]+SDL_PATCHLEVEL[ \t]+[0-9]+$")
+    string(REGEX REPLACE "^#define[ \t]+SDL_MAJOR_VERSION[ \t]+([0-9]+)$" "\\1" SDL2_VERSION_MAJOR "${SDL2_VERSION_MAJOR_LINE}")
+    string(REGEX REPLACE "^#define[ \t]+SDL_MINOR_VERSION[ \t]+([0-9]+)$" "\\1" SDL2_VERSION_MINOR "${SDL2_VERSION_MINOR_LINE}")
+    string(REGEX REPLACE "^#define[ \t]+SDL_PATCHLEVEL[ \t]+([0-9]+)$" "\\1" SDL2_VERSION_PATCH "${SDL2_VERSION_PATCH_LINE}")
+    set(SDL2_VERSION "${SDL2_VERSION_MAJOR}.${SDL2_VERSION_MINOR}.${SDL2_VERSION_PATCH}")
+    unset(SDL2_VERSION_MAJOR_LINE)
+    unset(SDL2_VERSION_MINOR_LINE)
+    unset(SDL2_VERSION_PATCH_LINE)
+    unset(SDL2_VERSION_MAJOR)
+    unset(SDL2_VERSION_MINOR)
+    unset(SDL2_VERSION_PATCH)
+endif()
+
+# Find the SDL2 and SDL2main libraries
+if(CMAKE_SIZEOF_VOID_P STREQUAL 8)
+    find_library(SDL2_LIBRARY "SDL2"
+        HINTS "${SDL2_DIR}/lib/x64" ${PC_SDL2_LIBRARY_DIRS})
+    find_library(SDL2_MAIN_LIBRARY "SDL2main"
+        HINTS "${SDL2_DIR}/lib/x64" ${PC_SDL2_LIBRARY_DIRS})
+else()
+    find_library(SDL2_LIBRARY "SDL2"
+        HINTS "${SDL2_DIR}/lib/x86" ${PC_SDL2_LIBRARY_DIRS})
+    find_library(SDL2_MAIN_LIBRARY "SDL2main"
+        HINTS "${SDL2_DIR}/lib/x86" ${PC_SDL2_LIBRARY_DIRS})
+endif()
+set(SDL2_LIBRARIES "${SDL2_MAIN_LIBRARY}" "${SDL2_LIBRARY}")
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(SDL2
+    FOUND_VAR SDL2_FOUND
+    REQUIRED_VARS SDL2_INCLUDE_DIR SDL2_LIBRARIES
+    VERSION_VAR SDL2_VERSION
+)
+
+if(SDL2_FOUND)
+    # SDL2 imported target.
+    add_library(SDL2::SDL2 UNKNOWN IMPORTED)
+    set_target_properties(SDL2::SDL2 PROPERTIES
+                          INTERFACE_COMPILE_OPTIONS "${PC_SDL2_CFLAGS_OTHER}"
+                          INTERFACE_INCLUDE_DIRECTORIES "${SDL2_INCLUDE_DIR}"
+                          IMPORTED_LOCATION "${SDL2_LIBRARY}")
+
+    # SDL2main imported target.
+    add_library(SDL2::SDL2main UNKNOWN IMPORTED)
+    set_target_properties(SDL2::SDL2main PROPERTIES
+                          IMPORTED_LOCATION "${SDL2_MAIN_LIBRARY}")
+endif()
--- /dev/null
+++ b/cmake/FindSDL2_mixer.cmake
@@ -1,0 +1,88 @@
+# FindSDL2_mixer.cmake
+#
+# Copyright (c) 2018, Alex Mayfield <[email protected]>
+# All rights reserved.
+# 
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#     * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above copyright
+#       notice, this list of conditions and the following disclaimer in the
+#       documentation and/or other materials provided with the distribution.
+#     * Neither the name of the <organization> nor the
+#       names of its contributors may be used to endorse or promote products
+#       derived from this software without specific prior written permission.
+# 
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# Currently works with the following generators:
+# - Unix Makefiles
+# - Ninja
+# - Visual Studio
+
+# Cache variable that allows you to point CMake at a directory containing
+# an extracted development library.
+set(SDL2_MIXER_DIR "${SDL2_MIXER_DIR}" CACHE PATH "Location of SDL2_mixer library directory")
+
+# Use pkg-config to find library locations in *NIX environments.
+find_package(PkgConfig QUIET)
+if(PKG_CONFIG_FOUND)
+    pkg_search_module(PC_SDL2_MIXER QUIET SDL2_mixer)
+endif()
+
+# Find the include directory.
+find_path(SDL2_MIXER_INCLUDE_DIR "SDL_mixer.h"
+    HINTS "${SDL2_MIXER_DIR}/include" ${PC_SDL2_MIXER_INCLUDE_DIRS})
+
+# Find the version.  Taken and modified from CMake's FindSDL.cmake.
+if(SDL2_MIXER_INCLUDE_DIR AND EXISTS "${SDL2_MIXER_INCLUDE_DIR}/SDL_mixer.h")
+    file(STRINGS "${SDL2_MIXER_INCLUDE_DIR}/SDL_mixer.h" SDL2_MIXER_VERSION_MAJOR_LINE REGEX "^#define[ \t]+SDL_MIXER_MAJOR_VERSION[ \t]+[0-9]+$")
+    file(STRINGS "${SDL2_MIXER_INCLUDE_DIR}/SDL_mixer.h" SDL2_MIXER_VERSION_MINOR_LINE REGEX "^#define[ \t]+SDL_MIXER_MINOR_VERSION[ \t]+[0-9]+$")
+    file(STRINGS "${SDL2_MIXER_INCLUDE_DIR}/SDL_mixer.h" SDL2_MIXER_VERSION_PATCH_LINE REGEX "^#define[ \t]+SDL_MIXER_PATCHLEVEL[ \t]+[0-9]+$")
+    string(REGEX REPLACE "^#define[ \t]+SDL_MIXER_MAJOR_VERSION[ \t]+([0-9]+)$" "\\1" SDL2_MIXER_VERSION_MAJOR "${SDL2_MIXER_VERSION_MAJOR_LINE}")
+    string(REGEX REPLACE "^#define[ \t]+SDL_MIXER_MINOR_VERSION[ \t]+([0-9]+)$" "\\1" SDL2_MIXER_VERSION_MINOR "${SDL2_MIXER_VERSION_MINOR_LINE}")
+    string(REGEX REPLACE "^#define[ \t]+SDL_MIXER_PATCHLEVEL[ \t]+([0-9]+)$" "\\1" SDL2_MIXER_VERSION_PATCH "${SDL2_MIXER_VERSION_PATCH_LINE}")
+    set(SDL2_MIXER_VERSION "${SDL2_MIXER_VERSION_MAJOR}.${SDL2_MIXER_VERSION_MINOR}.${SDL2_MIXER_VERSION_PATCH}")
+    unset(SDL2_MIXER_VERSION_MAJOR_LINE)
+    unset(SDL2_MIXER_VERSION_MINOR_LINE)
+    unset(SDL2_MIXER_VERSION_PATCH_LINE)
+    unset(SDL2_MIXER_VERSION_MAJOR)
+    unset(SDL2_MIXER_VERSION_MINOR)
+    unset(SDL2_MIXER_VERSION_PATCH)
+endif()
+
+# Find the library.
+if(CMAKE_SIZEOF_VOID_P STREQUAL 8)
+    find_library(SDL2_MIXER_LIBRARY "SDL2_mixer"
+        HINTS "${SDL2_MIXER_DIR}/lib/x64" ${PC_SDL2_MIXER_LIBRARY_DIRS})
+else()
+    find_library(SDL2_MIXER_LIBRARY "SDL2_mixer"
+        HINTS "${SDL2_MIXER_DIR}/lib/x86" ${PC_SDL2_MIXER_LIBRARY_DIRS})
+endif()
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(SDL2_mixer
+    FOUND_VAR SDL2_MIXER_FOUND
+    REQUIRED_VARS SDL2_MIXER_INCLUDE_DIR SDL2_MIXER_LIBRARY
+    VERSION_VAR SDL2_MIXER_VERSION
+)
+
+if(SDL2_MIXER_FOUND)
+    # Imported target.
+    add_library(SDL2::mixer UNKNOWN IMPORTED)
+    set_target_properties(SDL2::mixer PROPERTIES
+                          INTERFACE_COMPILE_OPTIONS "${PC_SDL2_MIXER_CFLAGS_OTHER}"
+                          INTERFACE_INCLUDE_DIRECTORIES "${SDL2_MIXER_INCLUDE_DIR}"
+                          INTERFACE_LINK_LIBRARIES SDL2::SDL2
+                          IMPORTED_LOCATION "${SDL2_MIXER_LIBRARY}")
+endif()
--- /dev/null
+++ b/cmake/FindSDL2_net.cmake
@@ -1,0 +1,88 @@
+# FindSDL2_net.cmake
+#
+# Copyright (c) 2018, Alex Mayfield <[email protected]>
+# All rights reserved.
+# 
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#     * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above copyright
+#       notice, this list of conditions and the following disclaimer in the
+#       documentation and/or other materials provided with the distribution.
+#     * Neither the name of the <organization> nor the
+#       names of its contributors may be used to endorse or promote products
+#       derived from this software without specific prior written permission.
+# 
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# Currently works with the following generators:
+# - Unix Makefiles
+# - Ninja
+# - Visual Studio
+
+# Cache variable that allows you to point CMake at a directory containing
+# an extracted development library.
+set(SDL2_NET_DIR "${SDL2_NET_DIR}" CACHE PATH "Location of SDL2_net library directory")
+
+# Use pkg-config to find library locations in *NIX environments.
+find_package(PkgConfig QUIET)
+if(PKG_CONFIG_FOUND)
+    pkg_search_module(PC_SDL2_NET QUIET SDL2_net)
+endif()
+
+# Find the include directory.
+find_path(SDL2_NET_INCLUDE_DIR "SDL_net.h"
+    HINTS "${SDL2_NET_DIR}/include" ${PC_SDL2_NET_INCLUDE_DIRS})
+
+# Find the version.  Taken and modified from CMake's FindSDL.cmake.
+if(SDL2_NET_INCLUDE_DIR AND EXISTS "${SDL2_NET_INCLUDE_DIR}/SDL_net.h")
+    file(STRINGS "${SDL2_NET_INCLUDE_DIR}/SDL_net.h" SDL2_NET_VERSION_MAJOR_LINE REGEX "^#define[ \t]+SDL_NET_MAJOR_VERSION[ \t]+[0-9]+$")
+    file(STRINGS "${SDL2_NET_INCLUDE_DIR}/SDL_net.h" SDL2_NET_VERSION_MINOR_LINE REGEX "^#define[ \t]+SDL_NET_MINOR_VERSION[ \t]+[0-9]+$")
+    file(STRINGS "${SDL2_NET_INCLUDE_DIR}/SDL_net.h" SDL2_NET_VERSION_PATCH_LINE REGEX "^#define[ \t]+SDL_NET_PATCHLEVEL[ \t]+[0-9]+$")
+    string(REGEX REPLACE "^#define[ \t]+SDL_NET_MAJOR_VERSION[ \t]+([0-9]+)$" "\\1" SDL2_NET_VERSION_MAJOR "${SDL2_NET_VERSION_MAJOR_LINE}")
+    string(REGEX REPLACE "^#define[ \t]+SDL_NET_MINOR_VERSION[ \t]+([0-9]+)$" "\\1" SDL2_NET_VERSION_MINOR "${SDL2_NET_VERSION_MINOR_LINE}")
+    string(REGEX REPLACE "^#define[ \t]+SDL_NET_PATCHLEVEL[ \t]+([0-9]+)$" "\\1" SDL2_NET_VERSION_PATCH "${SDL2_NET_VERSION_PATCH_LINE}")
+    set(SDL2_NET_VERSION "${SDL2_NET_VERSION_MAJOR}.${SDL2_NET_VERSION_MINOR}.${SDL2_NET_VERSION_PATCH}")
+    unset(SDL2_NET_VERSION_MAJOR_LINE)
+    unset(SDL2_NET_VERSION_MINOR_LINE)
+    unset(SDL2_NET_VERSION_PATCH_LINE)
+    unset(SDL2_NET_VERSION_MAJOR)
+    unset(SDL2_NET_VERSION_MINOR)
+    unset(SDL2_NET_VERSION_PATCH)
+endif()
+
+# Find the library.
+if(CMAKE_SIZEOF_VOID_P STREQUAL 8)
+    find_library(SDL2_NET_LIBRARY "SDL2_net"
+        HINTS "${SDL2_NET_DIR}/lib/x64" ${PC_SDL2_NET_LIBRARY_DIRS})
+else()
+    find_library(SDL2_NET_LIBRARY "SDL2_net"
+        HINTS "${SDL2_NET_DIR}/lib/x86" ${PC_SDL2_NET_LIBRARY_DIRS})
+endif()
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(SDL2_net
+    FOUND_VAR SDL2_NET_FOUND
+    REQUIRED_VARS SDL2_NET_INCLUDE_DIR SDL2_NET_LIBRARY
+    VERSION_VAR SDL2_NET_VERSION
+)
+
+if(SDL2_NET_FOUND)
+    # Imported target.
+    add_library(SDL2::net UNKNOWN IMPORTED)
+    set_target_properties(SDL2::net PROPERTIES
+                          INTERFACE_COMPILE_OPTIONS "${PC_SDL2_NET_CFLAGS_OTHER}"
+                          INTERFACE_INCLUDE_DIRECTORIES "${SDL2_NET_INCLUDE_DIR}"
+                          INTERFACE_LINK_LIBRARIES SDL2::SDL2
+                          IMPORTED_LOCATION "${SDL2_NET_LIBRARY}")
+endif()
--- /dev/null
+++ b/cmake/Findm.cmake
@@ -1,0 +1,36 @@
+# Findm.cmake
+#
+# Copyright (c) 2018, Alex Mayfield <[email protected]>
+# All rights reserved.
+# 
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#     * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above copyright
+#       notice, this list of conditions and the following disclaimer in the
+#       documentation and/or other materials provided with the distribution.
+#     * Neither the name of the <organization> nor the
+#       names of its contributors may be used to endorse or promote products
+#       derived from this software without specific prior written permission.
+# 
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# Finds libm, so we can link against it for math functions.  If libm doesn't
+# exist, linking against the m target will have no effect.
+
+find_library(M_LIBRARY m)
+
+add_library(m INTERFACE)
+if(M_LIBRARY)
+    target_link_libraries(m INTERFACE "${M_LIBRARY}")
+endif()
--- /dev/null
+++ b/cmake/Findsamplerate.cmake
@@ -1,0 +1,67 @@
+# Findsamplerate.cmake
+#
+# Copyright (c) 2018, Alex Mayfield <[email protected]>
+# All rights reserved.
+# 
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#     * Redistributions of source code must retain the above copyright
+#       notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above copyright
+#       notice, this list of conditions and the following disclaimer in the
+#       documentation and/or other materials provided with the distribution.
+#     * Neither the name of the <organization> nor the
+#       names of its contributors may be used to endorse or promote products
+#       derived from this software without specific prior written permission.
+# 
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+# DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# Currently works with the following generators:
+# - Unix Makefiles
+# - Ninja
+# - Visual Studio
+
+# Use pkg-config to find library locations in *NIX environments.
+find_package(PkgConfig QUIET)
+if(PKG_CONFIG_FOUND)
+    pkg_search_module(PC_SAMPLERATE QUIET samplerate)
+endif()
+
+# Find the include directory.
+find_path(SAMPLERATE_INCLUDE_DIR "samplerate.h"
+    HINTS ${PC_SAMPLERATE_INCLUDE_DIRS})
+
+# Find the version.  I don't know if there is a correct way to find this on
+# Windows - the config.h in the tarball is wrong for 0.1.19.
+if(PC_SAMPLERATE_VERSION)
+    set(SAMPLERATE_VERSION "${PC_SAMPLERATE_VERSION}")
+endif()
+
+# Find the library.
+find_library(SAMPLERATE_LIBRARY "samplerate"
+    HINTS ${PC_SAMPLERATE_LIBRARY_DIRS})
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(samplerate
+    FOUND_VAR SAMPLERATE_FOUND
+    REQUIRED_VARS SAMPLERATE_INCLUDE_DIR SAMPLERATE_LIBRARY
+    VERSION_VAR SAMPLERATE_VERSION
+)
+
+if(SAMPLERATE_FOUND)
+    # Imported target.
+    add_library(samplerate::samplerate UNKNOWN IMPORTED)
+    set_target_properties(samplerate::samplerate PROPERTIES
+        INTERFACE_COMPILE_OPTIONS "${PC_SAMPLERATE_CFLAGS_OTHER}"
+        INTERFACE_INCLUDE_DIRECTORIES "${SAMPLERATE_INCLUDE_DIR}"
+        IMPORTED_LOCATION "${SAMPLERATE_LIBRARY}")
+endif()
--- /dev/null
+++ b/cmake/config.h.cin
@@ -1,0 +1,10 @@
+#cmakedefine PACKAGE_NAME "@PACKAGE_NAME@"
+#cmakedefine PACKAGE_TARNAME "@PACKAGE_TARNAME@"
+#cmakedefine PACKAGE_VERSION "@PACKAGE_VERSION@"
+#cmakedefine PACKAGE_STRING "@PACKAGE_STRING@"
+#cmakedefine PROGRAM_PREFIX "@PROGRAM_PREFIX@"
+
+#cmakedefine HAVE_LIBSAMPLERATE
+#cmakedefine HAVE_LIBPNG
+#cmakedefine01 HAVE_DECL_STRCASECMP
+#cmakedefine01 HAVE_DECL_STRNCASECMP
--- /dev/null
+++ b/midiproc/CMakeLists.txt
@@ -1,0 +1,6 @@
+if(WIN32)
+    add_executable("${PROGRAM_PREFIX}midiproc" WIN32 buffer.c buffer.h main.c proto.h)
+    target_include_directories("${PROGRAM_PREFIX}midiproc"
+                               PRIVATE "../src/" "${CMAKE_CURRENT_BINARY_DIR}/../")
+    target_link_libraries("${PROGRAM_PREFIX}midiproc" SDL2::SDL2main SDL2::mixer)
+endif()
--- /dev/null
+++ b/opl/CMakeLists.txt
@@ -1,0 +1,15 @@
+add_library(opl STATIC
+            opl_internal.h
+            opl.c           opl.h
+            opl_linux.c
+            opl_obsd.c
+            opl_queue.c     opl_queue.h
+            opl_sdl.c
+            opl_timer.c     opl_timer.h
+            opl_win32.c
+            ioperm_sys.c    ioperm_sys.h
+            opl3.c          opl3.h)
+target_include_directories(opl
+                           INTERFACE "."
+                           PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/../")
+target_link_libraries(opl SDL2::mixer)
--- /dev/null
+++ b/pcsound/CMakeLists.txt
@@ -1,0 +1,11 @@
+add_library(pcsound STATIC
+            pcsound.c       pcsound.h
+            pcsound_bsd.c
+            pcsound_sdl.c
+            pcsound_linux.c
+            pcsound_win32.c
+                            pcsound_internal.h)
+target_include_directories(pcsound
+                           INTERFACE "."
+                           PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/../")
+target_link_libraries(pcsound SDL2::mixer)
--- a/src/.gitignore
+++ b/src/.gitignore
@@ -16,6 +16,7 @@
 *.exe
 *.desktop
 *.txt
+!CMakeLists.txt
 *.appdata.xml
 tags
 TAGS
--- /dev/null
+++ b/src/CMakeLists.txt
@@ -1,0 +1,215 @@
+foreach(SUBDIR doom heretic hexen strife setup)
+    add_subdirectory("${SUBDIR}")
+endforeach()
+
+# Common source files used by absolutely everything:
+
+set(COMMON_SOURCE_FILES
+    i_main.c
+    i_system.c           i_system.h
+    m_argv.c             m_argv.h
+    m_misc.c             m_misc.h)
+
+# Dedicated server (chocolate-server):
+
+set(DEDSERV_FILES
+    d_dedicated.c
+    d_mode.c             d_mode.h
+    i_timer.c            i_timer.h
+    net_common.c         net_common.h
+    net_dedicated.c      net_dedicated.h
+    net_io.c             net_io.h
+    net_packet.c         net_packet.h
+    net_sdl.c            net_sdl.h
+    net_query.c          net_query.h
+    net_server.c         net_server.h
+    net_structrw.c       net_structrw.h
+    z_native.c           z_zone.h)
+
+add_executable("${PROGRAM_PREFIX}server" WIN32 ${COMMON_SOURCE_FILES} ${DEDSERV_FILES})
+target_include_directories("${PROGRAM_PREFIX}server"
+                           PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/../")
+target_link_libraries("${PROGRAM_PREFIX}server" SDL2::SDL2main SDL2::net)
+
+# Source files used by the game binaries (chocolate-doom, etc.)
+
+set(GAME_SOURCE_FILES
+    aes_prng.c          aes_prng.h
+    d_event.c           d_event.h
+                        doomkeys.h
+                        doomtype.h
+    d_iwad.c            d_iwad.h
+    d_loop.c            d_loop.h
+    d_mode.c            d_mode.h
+                        d_ticcmd.h
+    deh_str.c           deh_str.h
+    gusconf.c           gusconf.h
+    i_cdmus.c           i_cdmus.h
+    i_endoom.c          i_endoom.h
+    i_input.c           i_input.h
+    i_joystick.c        i_joystick.h
+                        i_swap.h
+    i_midipipe.c        i_midipipe.h
+    i_oplmusic.c
+    i_pcsound.c
+    i_sdlmusic.c
+    i_sdlsound.c
+    i_sound.c           i_sound.h
+    i_timer.c           i_timer.h
+    i_video.c           i_video.h
+    i_videohr.c         i_videohr.h
+    midifile.c          midifile.h
+    mus2mid.c           mus2mid.h
+    m_bbox.c            m_bbox.h
+    m_cheat.c           m_cheat.h
+    m_config.c          m_config.h
+    m_controls.c        m_controls.h
+    m_fixed.c           m_fixed.h
+    net_client.c        net_client.h
+    net_common.c        net_common.h
+    net_dedicated.c     net_dedicated.h
+                        net_defs.h
+    net_gui.c           net_gui.h
+    net_io.c            net_io.h
+    net_loop.c          net_loop.h
+    net_packet.c        net_packet.h
+    net_query.c         net_query.h
+    net_sdl.c           net_sdl.h
+    net_server.c        net_server.h
+    net_structrw.c      net_structrw.h
+    sha1.c              sha1.h
+    memio.c             memio.h
+    tables.c            tables.h
+    v_diskicon.c        v_diskicon.h
+    v_video.c           v_video.h
+                        v_patch.h
+    w_checksum.c        w_checksum.h
+    w_main.c            w_main.h
+    w_wad.c             w_wad.h
+    w_file.c            w_file.h
+    w_file_stdc.c
+    w_file_posix.c
+    w_file_win32.c
+    w_merge.c           w_merge.h
+    z_zone.c            z_zone.h)
+
+set(DEHACKED_SOURCE_FILES
+                        deh_defs.h
+    deh_io.c            deh_io.h
+    deh_main.c          deh_main.h
+    deh_mapping.c       deh_mapping.h
+    deh_text.c)
+
+# Some games support dehacked patches, some don't:
+
+set(SOURCE_FILES ${COMMON_SOURCE_FILES} ${GAME_SOURCE_FILES})
+set(SOURCE_FILES_WITH_DEH ${SOURCE_FILES} ${DEHACKED_SOURCE_FILES})
+
+set(EXTRA_LIBS textscreen pcsound opl SDL2::SDL2main SDL2::SDL2 SDL2::mixer SDL2::net)
+if(SAMPLERATE_FOUND)
+    list(APPEND EXTRA_LIBS samplerate::samplerate)
+endif()
+if(PNG_FOUND)
+    list(APPEND EXTRA_LIBS PNG::PNG)
+endif()
+
+if(WIN32)
+    add_executable("${PROGRAM_PREFIX}doom" WIN32 ${SOURCE_FILES_WITH_DEH} "${CMAKE_CURRENT_BINARY_DIR}/resource.rc")
+else()
+    add_executable("${PROGRAM_PREFIX}doom" ${SOURCE_FILES_WITH_DEH})
+endif()
+
+target_include_directories("${PROGRAM_PREFIX}doom"
+                           PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/../")
+target_link_libraries("${PROGRAM_PREFIX}doom" doom ${EXTRA_LIBS})
+
+if(MSVC)
+    set_target_properties("${PROGRAM_PREFIX}doom" PROPERTIES
+                          LINK_FLAGS "/MANIFEST:NO")
+endif()
+
+if(WIN32)
+    add_executable("${PROGRAM_PREFIX}heretic" WIN32 ${SOURCE_FILES_WITH_DEH} "${CMAKE_CURRENT_BINARY_DIR}/resource.rc")
+else()
+    add_executable("${PROGRAM_PREFIX}heretic" ${SOURCE_FILES_WITH_DEH})
+endif()
+
+target_include_directories("${PROGRAM_PREFIX}heretic"
+                           PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/../")
+target_link_libraries("${PROGRAM_PREFIX}heretic" heretic ${EXTRA_LIBS})
+
+if(MSVC)
+    set_target_properties("${PROGRAM_PREFIX}heretic" PROPERTIES
+                          LINK_FLAGS "/MANIFEST:NO")
+endif()
+
+if(WIN32)
+    add_executable("${PROGRAM_PREFIX}hexen" WIN32 ${SOURCE_FILES} "${CMAKE_CURRENT_BINARY_DIR}/resource.rc")
+else()
+    add_executable("${PROGRAM_PREFIX}hexen" ${SOURCE_FILES})
+endif()
+
+target_include_directories("${PROGRAM_PREFIX}hexen"
+                           PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/../")
+target_link_libraries("${PROGRAM_PREFIX}hexen" hexen ${EXTRA_LIBS})
+
+if(MSVC)
+    set_target_properties("${PROGRAM_PREFIX}hexen" PROPERTIES
+                          LINK_FLAGS "/MANIFEST:NO")
+endif()
+
+if(WIN32)
+    add_executable("${PROGRAM_PREFIX}strife" WIN32 ${SOURCE_FILES_WITH_DEH} "${CMAKE_CURRENT_BINARY_DIR}/resource.rc")
+else()
+    add_executable("${PROGRAM_PREFIX}strife" ${SOURCE_FILES_WITH_DEH})
+endif()
+
+target_include_directories("${PROGRAM_PREFIX}strife"
+                           PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/../")
+target_link_libraries("${PROGRAM_PREFIX}strife" strife ${EXTRA_LIBS})
+
+if(MSVC)
+    set_target_properties("${PROGRAM_PREFIX}strife" PROPERTIES
+                          LINK_FLAGS "/MANIFEST:NO")
+endif()
+
+# Source files needed for chocolate-setup:
+
+set(SETUP_FILES
+    deh_str.c           deh_str.h
+    d_mode.c            d_mode.h
+    d_iwad.c            d_iwad.h
+    i_timer.c           i_timer.h
+    m_config.c          m_config.h
+    m_controls.c        m_controls.h
+    net_io.c            net_io.h
+    net_packet.c        net_packet.h
+    net_sdl.c           net_sdl.h
+    net_query.c         net_query.h
+    net_structrw.c      net_structrw.h
+    z_native.c          z_zone.h)
+
+if(WIN32)
+    add_executable("${PROGRAM_PREFIX}setup" WIN32 ${SETUP_FILES} ${COMMON_SOURCE_FILES} "${CMAKE_CURRENT_BINARY_DIR}/setup-res.rc")
+else()
+    add_executable("${PROGRAM_PREFIX}setup" ${SETUP_FILES} ${COMMON_SOURCE_FILES})
+endif()
+
+target_include_directories("${PROGRAM_PREFIX}setup"
+                           PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/../")
+target_link_libraries("${PROGRAM_PREFIX}setup" setup textscreen SDL2::SDL2main SDL2::SDL2 SDL2::mixer SDL2::net)
+
+if(MSVC)
+    set_target_properties("${PROGRAM_PREFIX}setup" PROPERTIES
+                          LINK_FLAGS "/MANIFEST:NO")
+endif()
+
+add_executable(midiread midifile.c z_native.c i_system.c m_argv.c m_misc.c)
+target_compile_definitions(midiread PRIVATE "-DTEST")
+target_include_directories(midiread PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/../")
+target_link_libraries(midiread PRIVATE SDL2::SDL2)
+
+add_executable(mus2mid mus2mid.c memio.c z_native.c i_system.c m_argv.c m_misc.c)
+target_compile_definitions(mus2mid PRIVATE "-DSTANDALONE")
+target_include_directories(mus2mid PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/../")
+target_link_libraries(mus2mid PRIVATE SDL2::SDL2)
--- /dev/null
+++ b/src/doom/CMakeLists.txt
@@ -1,0 +1,71 @@
+add_library(doom STATIC
+            am_map.c        am_map.h
+            deh_ammo.c
+            deh_bexstr.c
+            deh_cheat.c
+            deh_doom.c
+            deh_frame.c
+            deh_misc.c      deh_misc.h
+            deh_ptr.c
+            deh_sound.c
+            deh_thing.c
+            deh_weapon.c
+                            d_englsh.h
+            d_items.c       d_items.h
+            d_main.c        d_main.h
+            d_net.c
+                            doomdata.h
+            doomdef.c       doomdef.h
+            doomstat.c      doomstat.h
+                            d_player.h
+            dstrings.c      dstrings.h
+                            d_textur.h
+                            d_think.h
+            f_finale.c      f_finale.h
+            f_wipe.c        f_wipe.h
+            g_game.c        g_game.h
+            hu_lib.c        hu_lib.h
+            hu_stuff.c      hu_stuff.h
+            info.c          info.h
+            m_menu.c        m_menu.h
+            m_random.c      m_random.h
+            p_ceilng.c
+            p_doors.c
+            p_enemy.c
+            p_floor.c
+            p_inter.c       p_inter.h
+            p_lights.c
+                            p_local.h
+            p_map.c
+            p_maputl.c
+            p_mobj.c        p_mobj.h
+            p_plats.c
+            p_pspr.c        p_pspr.h
+            p_saveg.c       p_saveg.h
+            p_setup.c       p_setup.h
+            p_sight.c
+            p_spec.c        p_spec.h
+            p_switch.c
+            p_telept.c
+            p_tick.c        p_tick.h
+            p_user.c
+            r_bsp.c         r_bsp.h
+            r_data.c        r_data.h
+                            r_defs.h
+            r_draw.c        r_draw.h
+                            r_local.h
+            r_main.c        r_main.h
+            r_plane.c       r_plane.h
+            r_segs.c        r_segs.h
+            r_sky.c         r_sky.h
+                            r_state.h
+            r_things.c      r_things.h
+            s_sound.c       s_sound.h
+            sounds.c        sounds.h
+            statdump.c      statdump.h
+            st_lib.c        st_lib.h
+            st_stuff.c      st_stuff.h
+            wi_stuff.c      wi_stuff.h)
+
+target_include_directories(doom PRIVATE "../" "${CMAKE_CURRENT_BINARY_DIR}/../../")
+target_link_libraries(doom SDL2::SDL2 SDL2::mixer SDL2::net)
--- /dev/null
+++ b/src/heretic/CMakeLists.txt
@@ -1,0 +1,57 @@
+add_library(heretic STATIC
+            am_data.h
+            am_map.c            am_map.h
+            ct_chat.c           ct_chat.h
+            deh_ammo.c
+            deh_frame.c
+            deh_htext.c
+            deh_htic.c          deh_htic.h
+            deh_sound.c
+            deh_thing.c
+            deh_weapon.c
+            d_main.c
+            d_net.c
+                                doomdata.h
+                                doomdef.h
+                                dstrings.h
+            f_finale.c
+            g_game.c
+            info.c              info.h
+            in_lude.c
+            m_random.c          m_random.h
+            mn_menu.c
+                                p_action.h
+            p_ceilng.c
+            p_doors.c
+            p_enemy.c
+            p_floor.c
+            p_inter.c
+            p_lights.c
+            p_local.h
+            p_map.c
+            p_maputl.c
+            p_mobj.c
+            p_plats.c
+            p_pspr.c
+            p_saveg.c
+            p_setup.c
+            p_sight.c
+            p_spec.c            p_spec.h
+            p_switch.c
+            p_telept.c
+            p_tick.c
+            p_user.c
+            r_bsp.c
+            r_data.c
+            r_draw.c
+                                r_local.h
+            r_main.c
+            r_plane.c
+            r_segs.c
+            r_things.c
+            sb_bar.c
+            sounds.c            sounds.h
+            s_sound.c           s_sound.h)
+
+target_include_directories(heretic PRIVATE "../" "${CMAKE_CURRENT_BINARY_DIR}/../../")
+target_link_libraries(heretic textscreen SDL2::SDL2 SDL2::mixer SDL2::net)
--- /dev/null
+++ b/src/hexen/CMakeLists.txt
@@ -1,0 +1,58 @@
+add_library(hexen STATIC
+            a_action.c
+                                am_data.h
+            am_map.c            am_map.h
+            ct_chat.c
+                                ct_chat.h
+            d_net.c
+            f_finale.c
+            g_game.c
+                                h2def.h
+            h2_main.c
+            info.c              info.h
+            in_lude.c
+            m_random.c          m_random.h
+            mn_menu.c
+            p_acs.c
+            p_anim.c
+            p_ceilng.c
+            p_doors.c
+            p_enemy.c
+            p_floor.c
+            p_inter.c
+            p_lights.c
+                                p_local.h
+            p_map.c
+            p_maputl.c
+            p_mobj.c
+            po_man.c
+            p_plats.c
+            p_pspr.c
+            p_setup.c
+            p_sight.c
+            p_spec.c           p_spec.h
+            p_switch.c
+            p_telept.c
+            p_things.c
+            p_tick.c
+            p_user.c
+            r_bsp.c
+            r_data.c
+            r_draw.c
+                                r_local.h
+            r_main.c
+            r_plane.c
+            r_segs.c
+            r_things.c
+            s_sound.c           s_sound.h
+            sb_bar.c
+            sc_man.c
+            sn_sonix.c
+            sounds.c            sounds.h
+            st_start.c          st_start.h
+            sv_save.c
+                                textdefs.h
+                                xddefs.h)
+
+target_include_directories(hexen PRIVATE "../" "${CMAKE_CURRENT_BINARY_DIR}/../../")
+target_link_libraries(hexen SDL2::SDL2 SDL2::mixer SDL2::net)
--- /dev/null
+++ b/src/setup/CMakeLists.txt
@@ -1,0 +1,18 @@
+add_library(setup STATIC
+            compatibility.c     compatibility.h
+            display.c           display.h
+            joystick.c          joystick.h
+            keyboard.c          keyboard.h
+            mainmenu.c
+            mode.c              mode.h
+            mouse.c             mouse.h
+            multiplayer.c       multiplayer.h
+            sound.c             sound.h
+            execute.c           execute.h
+            txt_joyaxis.c       txt_joyaxis.h
+            txt_joybinput.c     txt_joybinput.h
+            txt_keyinput.c      txt_keyinput.h
+            txt_mouseinput.c    txt_mouseinput.h)
+
+target_include_directories(setup PRIVATE "../" "${CMAKE_CURRENT_BINARY_DIR}/../../")
+target_link_libraries(setup textscreen SDL2::SDL2 SDL2::mixer)
--- /dev/null
+++ b/src/strife/CMakeLists.txt
@@ -1,0 +1,75 @@
+set(STRIFE_SOURCES
+    am_map.c        am_map.h
+    deh_ammo.c
+    deh_cheat.c
+    deh_strife.c
+    deh_frame.c
+    deh_misc.c      deh_misc.h
+    deh_ptr.c
+    deh_sound.c
+    deh_thing.c
+    deh_weapon.c
+                    d_englsh.h
+    d_items.c       d_items.h
+    d_main.c        d_main.h
+    d_net.c
+                    doomdata.h
+    doomdef.c       doomdef.h
+    doomstat.c      doomstat.h
+                    d_player.h
+    dstrings.c      dstrings.h
+                    d_textur.h
+                    d_think.h
+    f_finale.c      f_finale.h
+    f_wipe.c        f_wipe.h
+    g_game.c        g_game.h
+    hu_lib.c        hu_lib.h
+    hu_stuff.c      hu_stuff.h
+    info.c          info.h
+    m_menu.c        m_menu.h
+    m_random.c      m_random.h
+    m_saves.c       m_saves.h
+    p_ceilng.c
+    p_dialog.c      p_dialog.h
+    p_doors.c
+    p_enemy.c
+    p_floor.c
+    p_inter.c       p_inter.h
+    p_lights.c
+                    p_local.h
+    p_map.c
+    p_maputl.c
+    p_mobj.c        p_mobj.h
+    p_plats.c
+    p_pspr.c        p_pspr.h
+    p_saveg.c       p_saveg.h
+    p_setup.c       p_setup.h
+    p_sight.c
+    p_spec.c        p_spec.h
+    p_switch.c
+    p_telept.c
+    p_tick.c        p_tick.h
+    p_user.c
+    r_bsp.c         r_bsp.h
+    r_data.c        r_data.h
+                    r_defs.h
+    r_draw.c        r_draw.h
+                    r_local.h
+    r_main.c        r_main.h
+    r_plane.c       r_plane.h
+    r_segs.c        r_segs.h
+    r_sky.c         r_sky.h
+                    r_state.h
+    r_things.c      r_things.h
+    s_sound.c       s_sound.h
+    sounds.c        sounds.h
+    st_lib.c        st_lib.h
+    st_stuff.c      st_stuff.h
+    wi_stuff.c      wi_stuff.h)
+if(MSVC)
+    list(APPEND STRIFE_SOURCES "../../win32/win_opendir.c" "../../win32/win_opendir.h")
+endif()
+add_library(strife STATIC ${STRIFE_SOURCES})
+
+target_include_directories(strife PRIVATE "../" "../../win32/" "${CMAKE_CURRENT_BINARY_DIR}/../../")
+target_link_libraries(strife textscreen SDL2::SDL2 SDL2::mixer SDL2::net)
--- a/src/v_video.c
+++ b/src/v_video.c
@@ -20,6 +20,7 @@
 //
 
 #include <stdio.h>
+#include <stdlib.h>
 #include <string.h>
 #include <math.h>
 
--- /dev/null
+++ b/textscreen/CMakeLists.txt
@@ -1,0 +1,28 @@
+add_library(textscreen
+            textscreen.h
+            txt_conditional.c   txt_conditional.h
+            txt_checkbox.c      txt_checkbox.h
+            txt_desktop.c       txt_desktop.h
+            txt_dropdown.c      txt_dropdown.h
+            txt_fileselect.c    txt_fileselect.h
+            txt_gui.c           txt_gui.h
+            txt_inputbox.c      txt_inputbox.h
+            txt_io.c            txt_io.h
+                                txt_main.h
+            txt_button.c        txt_button.h
+            txt_label.c         txt_label.h
+            txt_radiobutton.c   txt_radiobutton.h
+            txt_scrollpane.c    txt_scrollpane.h
+            txt_separator.c     txt_separator.h
+            txt_spinctrl.c      txt_spinctrl.h
+            txt_sdl.c           txt_sdl.h
+            txt_strut.c         txt_strut.h
+            txt_table.c         txt_table.h
+            txt_utf8.c          txt_utf8.h
+            txt_widget.c        txt_widget.h
+            txt_window.c        txt_window.h
+            txt_window_action.c txt_window_action.h)
+target_include_directories(textscreen
+                           INTERFACE "."
+                           PRIVATE "../src/")
+target_link_libraries(textscreen m SDL2::SDL2)
--- /dev/null
+++ b/win32/win_opendir.c
@@ -1,0 +1,336 @@
+//
+// 03/10/2006 James Haley
+//
+// For this module only: 
+// This code is public domain. No change sufficient enough to constitute a
+// significant or original work has been made, and thus it remains as such.
+//
+//
+// DESCRIPTION:
+//
+// Implementation of POSIX opendir for Visual C++.
+// Derived from the MinGW C Library Extensions Source (released to the
+// public domain). As with other Win32 modules, don't include most DOOM
+// headers into this or conflicts will occur.
+//
+// Original Header:
+//
+// * dirent.c
+// * This file has no copyright assigned and is placed in the Public Domain.
+// * This file is a part of the mingw-runtime package.
+// * No warranty is given; refer to the file DISCLAIMER within the package.
+// *
+// * Derived from DIRLIB.C by Matt J. Weinstein 
+// * This note appears in the DIRLIB.H
+// * DIRLIB.H by M. J. Weinstein   Released to public domain 1-Jan-89
+// *
+// * Updated by Jeremy Bettis <[email protected]>
+// * Significantly revised and rewinddir, seekdir and telldir added by Colin
+// * Peters <[email protected]>
+//
+
+#ifndef _MSC_VER
+#error i_opndir.c is for Microsoft Visual C++ only
+#endif
+
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h> /* for GetFileAttributes */
+
+#include <tchar.h>
+#define SUFFIX	_T("*")
+#define	SLASH	_T("\\")
+
+#include "win_opendir.h"
+
+//
+// opendir
+// 
+// Returns a pointer to a DIR structure appropriately filled in to begin
+// searching a directory.
+//
+DIR *opendir(const _TCHAR *szPath)
+{
+   DIR *nd;
+   unsigned int rc;
+   _TCHAR szFullPath[MAX_PATH];
+	
+   errno = 0;
+   
+   if(!szPath)
+   {
+      errno = EFAULT;
+      return (DIR *)0;
+   }
+   
+   if(szPath[0] == _T('\0'))
+   {
+      errno = ENOTDIR;
+      return (DIR *)0;
+   }
+
+   /* Attempt to determine if the given path really is a directory. */
+   rc = GetFileAttributes(szPath);
+   if(rc == (unsigned int)-1)
+   {
+      /* call GetLastError for more error info */
+      errno = ENOENT;
+      return (DIR *)0;
+   }
+   if(!(rc & FILE_ATTRIBUTE_DIRECTORY))
+   {
+      /* Error, entry exists but not a directory. */
+      errno = ENOTDIR;
+      return (DIR *)0;
+   }
+
+   /* Make an absolute pathname.  */
+   _tfullpath(szFullPath, szPath, MAX_PATH);
+
+   /* Allocate enough space to store DIR structure and the complete
+   * directory path given. */
+   nd = (DIR *)(malloc(sizeof(DIR) + (_tcslen(szFullPath)
+                                       + _tcslen(SLASH)
+                                       + _tcslen(SUFFIX) + 1)
+                                     * sizeof(_TCHAR)));
+
+   if(!nd)
+   {
+      /* Error, out of memory. */
+      errno = ENOMEM;
+      return (DIR *)0;
+   }
+
+   /* Create the search expression. */
+   _tcscpy(nd->dd_name, szFullPath);
+
+   /* Add on a slash if the path does not end with one. */
+   if(nd->dd_name[0] != _T('\0')
+      && _tcsrchr(nd->dd_name, _T('/'))  != nd->dd_name
+					    + _tcslen(nd->dd_name) - 1
+      && _tcsrchr(nd->dd_name, _T('\\')) != nd->dd_name
+      					    + _tcslen(nd->dd_name) - 1)
+   {
+      _tcscat(nd->dd_name, SLASH);
+   }
+
+   /* Add on the search pattern */
+   _tcscat(nd->dd_name, SUFFIX);
+   
+   /* Initialize handle to -1 so that a premature closedir doesn't try
+   * to call _findclose on it. */
+   nd->dd_handle = -1;
+
+   /* Initialize the status. */
+   nd->dd_stat = 0;
+
+   /* Initialize the dirent structure. ino and reclen are invalid under
+    * Win32, and name simply points at the appropriate part of the
+    * findfirst_t structure. */
+   nd->dd_dir.d_ino = 0;
+   nd->dd_dir.d_reclen = 0;
+   nd->dd_dir.d_namlen = 0;
+   memset(nd->dd_dir.d_name, 0, FILENAME_MAX);
+  
+   return nd;
+}
+
+//
+// readdir
+//
+// Return a pointer to a dirent structure filled with the information on the
+// next entry in the directory.
+//
+struct dirent *readdir(DIR *dirp)
+{
+   errno = 0;
+   
+   /* Check for valid DIR struct. */
+   if(!dirp)
+   {
+      errno = EFAULT;
+      return (struct dirent *)0;
+   }
+
+   if (dirp->dd_stat < 0)
+   {
+     /* We have already returned all files in the directory
+      * (or the structure has an invalid dd_stat). */
+      return (struct dirent *)0;
+   }
+   else if (dirp->dd_stat == 0)
+   {
+      /* We haven't started the search yet. */
+      /* Start the search */
+      dirp->dd_handle = _tfindfirst(dirp->dd_name, &(dirp->dd_dta));
+
+      if(dirp->dd_handle == -1)
+      {
+         /* Whoops! Seems there are no files in that
+          * directory. */
+         dirp->dd_stat = -1;
+      }
+      else
+      {
+         dirp->dd_stat = 1;
+      }
+   }
+   else
+   {
+      /* Get the next search entry. */
+      if(_tfindnext(dirp->dd_handle, &(dirp->dd_dta)))
+      {
+         /* We are off the end or otherwise error.	
+            _findnext sets errno to ENOENT if no more file
+            Undo this. */ 
+         DWORD winerr = GetLastError();
+         if(winerr == ERROR_NO_MORE_FILES)
+            errno = 0;
+         _findclose(dirp->dd_handle);
+         dirp->dd_handle = -1;
+         dirp->dd_stat = -1;
+      }
+      else
+      {
+         /* Update the status to indicate the correct
+          * number. */
+         dirp->dd_stat++;
+      }
+   }
+
+   if (dirp->dd_stat > 0)
+   {
+      /* Successfully got an entry. Everything about the file is
+       * already appropriately filled in except the length of the
+       * file name. */
+      dirp->dd_dir.d_namlen = _tcslen(dirp->dd_dta.name);
+      _tcscpy(dirp->dd_dir.d_name, dirp->dd_dta.name);
+      return &dirp->dd_dir;
+   }
+
+   return (struct dirent *)0;
+}
+
+
+//
+// closedir
+//
+// Frees up resources allocated by opendir.
+//
+int closedir(DIR *dirp)
+{
+   int rc;
+   
+   errno = 0;
+   rc = 0;
+   
+   if(!dirp)
+   {
+      errno = EFAULT;
+      return -1;
+   }
+
+   if(dirp->dd_handle != -1)
+   {
+      rc = _findclose(dirp->dd_handle);
+   }
+
+   /* Delete the dir structure. */
+   free(dirp);
+   
+   return rc;
+}
+
+//
+// rewinddir
+//
+// Return to the beginning of the directory "stream". We simply call findclose
+// and then reset things like an opendir.
+//
+void rewinddir(DIR * dirp)
+{
+   errno = 0;
+   
+   if(!dirp)
+   {
+      errno = EFAULT;
+      return;
+   }
+
+   if(dirp->dd_handle != -1)
+   {
+      _findclose(dirp->dd_handle);
+   }
+   
+   dirp->dd_handle = -1;
+   dirp->dd_stat = 0;
+}
+
+//
+// telldir
+//
+// Returns the "position" in the "directory stream" which can be used with
+// seekdir to go back to an old entry. We simply return the value in stat.
+//
+long telldir(DIR *dirp)
+{
+   errno = 0;
+   
+   if(!dirp)
+   {
+      errno = EFAULT;
+      return -1;
+   }
+   return dirp->dd_stat;
+}
+
+//
+// seekdir
+//
+// Seek to an entry previously returned by telldir. We rewind the directory
+// and call readdir repeatedly until either dd_stat is the position number
+// or -1 (off the end). This is not perfect, in that the directory may
+// have changed while we weren't looking. But that is probably the case with
+// any such system.
+//
+void seekdir(DIR *dirp, long lPos)
+{
+   errno = 0;
+   
+   if(!dirp)
+   {
+      errno = EFAULT;
+      return;
+   }
+
+   if(lPos < -1)
+   {
+      /* Seeking to an invalid position. */
+      errno = EINVAL;
+      return;
+   }
+   else if(lPos == -1)
+   {
+      /* Seek past end. */
+      if(dirp->dd_handle != -1)
+      {
+         _findclose(dirp->dd_handle);
+      }
+      dirp->dd_handle = -1;
+      dirp->dd_stat = -1;
+   }
+   else
+   {
+      /* Rewind and read forward to the appropriate index. */
+      rewinddir(dirp);
+      
+      while((dirp->dd_stat < lPos) && readdir(dirp))
+         ; /* do-nothing loop */
+   }
+}
+
+// EOF
+
--- /dev/null
+++ b/win32/win_opendir.h
@@ -1,0 +1,73 @@
+//
+// 03/10/2006 James Haley
+//
+// For this module only: 
+// This code is public domain. No change sufficient enough to constitute a
+// significant or original work has been made, and thus it remains as such.
+//
+//
+// DESCRIPTION:
+//
+// Implementation of POSIX opendir for Visual C++.
+// Derived from the MinGW C Library Extensions Source (released to the
+//  public domain).
+//
+
+#ifndef I_OPNDIR_H__
+#define I_OPNDIR_H__
+
+#include <io.h>
+
+#ifndef FILENAME_MAX
+#define FILENAME_MAX 260
+#endif
+
+struct dirent
+{
+   long		  d_ino;    /* Always zero. */
+   unsigned short d_reclen; /* Always zero. */
+   unsigned short d_namlen; /* Length of name in d_name. */
+   char           d_name[FILENAME_MAX]; /* File name. */
+};
+
+/*
+ * This is an internal data structure. Good programmers will not use it
+ * except as an argument to one of the functions below.
+ * dd_stat field is now int (was short in older versions).
+ */
+typedef struct
+{
+   /* disk transfer area for this dir */
+   struct _finddata_t dd_dta;
+
+   /* dirent struct to return from dir (NOTE: this makes this thread
+    * safe as long as only one thread uses a particular DIR struct at
+    * a time) */
+   struct dirent dd_dir;
+
+   /* _findnext handle */
+   intptr_t	dd_handle;
+
+   /*
+    * Status of search:
+    *   0 = not started yet (next entry to read is first entry)
+    *  -1 = off the end
+    *   positive = 0 based index of next entry
+    */
+   int dd_stat;
+
+   /* given path for dir with search pattern (struct is extended) */
+   char dd_name[1];
+} DIR;
+
+DIR *opendir(const char *);
+struct dirent *readdir(DIR *);
+int closedir(DIR *);
+void rewinddir(DIR *);
+long telldir(DIR *);
+void seekdir(DIR *, long);
+
+#endif
+
+// EOF
+