diff --git a/CMakeLists.txt b/CMakeLists.txt
index 0cffa367ecdfe4ad8dd473a4a216e371bd231b89..b8abe511d42f3bbbf01fd80f525f0978cbb573ca 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,173 +1,124 @@
-#
-# Simple CMakeLists for Sonic Robo Blast 2
-#
-PROJECT(SRB2)
-
-CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
-
-#
-# Dependencies
-#
-FIND_PACKAGE(SDL)
-FIND_PACKAGE(SDL_mixer)
-FIND_PACKAGE(PNG)
-
-#
-# Common stuff
-#
-
-# not added defines:
-# -DHAVE_PNG - does not build (incorrect use of PNG_EXPORT etc.)
-ADD_DEFINITIONS(-DDIRECTFULLSCREEN -DSDL -DHAVE_MIXER -DNOHW -DHW3SOUND -DHAVE_BLUA -DNOASM)
-
-SET(SDL_DIR sdl) # may be set to SDL2 optionally
-
-SET(COMMON_SRCS
-	src/${SDL_DIR}/dosstr.c
-	src/${SDL_DIR}/endtxt.c
-	src/${SDL_DIR}/hwsym_sdl.c
-	src/${SDL_DIR}/i_cdmus.c
-	src/${SDL_DIR}/i_main.c
-	src/${SDL_DIR}/i_net.c
-	src/${SDL_DIR}/i_system.c
-	src/${SDL_DIR}/i_video.c
-	src/${SDL_DIR}/mixer_sound.c
-	src/am_map.c
-	src/b_bot.c
-	src/blua/lapi.c
-	src/blua/lauxlib.c
-	src/blua/lbaselib.c
-	src/blua/lcode.c
-	src/blua/ldebug.c
-	src/blua/ldo.c
-	src/blua/ldump.c
-	src/blua/lfunc.c
-	src/blua/lgc.c
-	src/blua/linit.c
-	src/blua/llex.c
-	src/blua/lmem.c
-	src/blua/lobject.c
-	src/blua/lopcodes.c
-	src/blua/lparser.c
-	src/blua/lstate.c
-	src/blua/lstring.c
-	src/blua/lstrlib.c
-	src/blua/ltable.c
-	src/blua/ltablib.c
-	src/blua/ltm.c
-	src/blua/lundump.c
-	src/blua/lvm.c
-	src/blua/lzio.c
-	src/command.c
-	src/comptime.c
-	src/console.c
-	src/d_clisrv.c
-	src/d_main.c
-	src/d_net.c
-	src/d_netcmd.c
-	src/d_netfil.c
-	src/dehacked.c
-	src/f_finale.c
-	src/f_wipe.c
-	src/filesrch.c
-	src/g_game.c
-	src/g_input.c
-	src/hardware/hw3sound.c
-	src/hu_stuff.c
-	src/i_tcp.c
-	src/info.c
-	src/lua_baselib.c
-	src/lua_consolelib.c
-	src/lua_hooklib.c
-	src/lua_hudlib.c
-	src/lua_infolib.c
-	src/lua_maplib.c
-	src/lua_mathlib.c
-	src/lua_mobjlib.c
-	src/lua_playerlib.c
-	src/lua_script.c
-	src/lua_skinlib.c
-	src/lua_thinkerlib.c
-	src/lzf.c
-	src/m_anigif.c
-	src/m_argv.c
-	src/m_bbox.c
-	src/m_cheat.c
-	src/m_cond.c
-	src/m_fixed.c
-	src/m_menu.c
-	src/m_misc.c
-	src/m_queue.c
-	src/m_random.c
-	src/md5.c
-	src/mserv.c
-	src/p_ceilng.c
-	src/p_enemy.c
-	src/p_fab.c
-	src/p_floor.c
-	src/p_inter.c
-	src/p_lights.c
-	src/p_map.c
-	src/p_maputl.c
-	src/p_mobj.c
-	src/p_polyobj.c
-	src/p_saveg.c
-	src/p_setup.c
-	src/p_sight.c
-	src/p_spec.c
-	src/p_telept.c
-	src/p_tick.c
-	src/p_user.c
-	src/r_bsp.c
-	src/r_data.c
-	src/r_draw.c
-	src/r_main.c
-	src/r_plane.c
-	src/r_segs.c
-	src/r_sky.c
-	src/r_splats.c
-	src/r_things.c
-	src/s_sound.c
-	src/screen.c
-	src/sounds.c
-	src/st_stuff.c
-	src/string.c
-	src/tables.c
-	src/v_video.c
-	src/w_wad.c
-	src/y_inter.c
-	src/z_zone.c
-)
-
-#
-# Platform-specific stuff
-#
-
-MACRO(EXTRALIB NAME)
-	FIND_LIBRARY(${NAME}_LIBRARY NAMES ${NAME})
-	IF(${NAME}_LIBRARY)
-		MESSAGE(STATUS "Found lib${NAME}: ${${NAME}_LIBRARY}")
-		SET(EXTRA_LIBRARIES ${EXTRA_LIBRARIES} ${${NAME}_LIBRARY})
-	ELSE(${NAME}_LIBRARY)
-		MESSAGE(FATAL_ERROR "Could not find lib${NAME}!")
-	ENDIF(${NAME}_LIBRARY)
-ENDMACRO(EXTRALIB)
-
-IF(${CMAKE_SYSTEM} MATCHES "FreeBSD")
-	ADD_DEFINITIONS(-DUNIXCOMMON -DLINUX -DFREEBSD)
-	EXTRALIB(kvm)
-ELSEIF(${CMAKE_SYSTEM} MATCHES "Linux")
-	ADD_DEFINITIONS(-DUNIXCOMMON -DLINUX)
-	EXTRALIB(m)
-	EXTRALIB(rt)
-ELSE(${CMAKE_SYSTEM} MATCHES "FreeBSD")
-	ADD_DEFINITIONS(-DUNIXCOMMON -DLINUX)
-	MESSAGE(WARNING "No specific settings for you system, it may be not supported!")
-ENDIF(${CMAKE_SYSTEM} MATCHES "FreeBSD")
-
-#
-# Targets
-#
-INCLUDE_DIRECTORIES(${PNG_INCLUDE_DIRS} ${SDL_INCLUDE_DIR} ${SDL_MIXER_INCLUDE_DIRS})
-ADD_EXECUTABLE(SRB2 ${COMMON_SRCS})
-TARGET_LINK_LIBRARIES(SRB2 ${SDL_LIBRARY} ${SDL_MIXER_LIBRARIES} ${EXTRA_LIBRARIES})
+cmake_minimum_required(VERSION 3.0)
+project(SRB2
+	VERSION 2.1.14
+	LANGUAGES C)
+
+# Set up CMAKE path
+set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules/")
+
+### Useful functions
+
+# Prepend sources with current source directory
+function(prepend_sources SOURCE_FILES)
+	foreach(SOURCE_FILE ${${SOURCE_FILES}})
+		set(MODIFIED ${MODIFIED} ${CMAKE_CURRENT_SOURCE_DIR}/${SOURCE_FILE})
+	endforeach()
+	set(${SOURCE_FILES} ${MODIFIED} PARENT_SCOPE)
+endfunction()
+
+# Macro to add OSX framework
+macro(add_framework fwname appname)
+	find_library(FRAMEWORK_${fwname}
+    	NAMES ${fwname}
+    	PATHS ${CMAKE_OSX_SYSROOT}/System/Library
+    		${CMAKE_OSX_SYSROOT}/Library
+    		/System/Library
+    		/Library
+    	PATH_SUFFIXES Frameworks
+    	NO_DEFAULT_PATH)
+    if( ${FRAMEWORK_${fwname}} STREQUAL FRAMEWORK_${fwname}-NOTFOUND)
+        MESSAGE(ERROR ": Framework ${fwname} not found")
+    else()
+        TARGET_LINK_LIBRARIES(${appname} PRIVATE "${FRAMEWORK_${fwname}}/${fwname}")
+        MESSAGE(STATUS "Framework ${fwname} found at ${FRAMEWORK_${fwname}}")
+    endif()
+endmacro()
+
+# Macro to copy Windows DLLs to Debug/Release folder for easy debugging
+# Note: this is general purpose, we could copy anything. Just using for DLLs on MSVC though
+macro(copy_files_to_build_dir target dlllist_var)
+	if(MSVC)
+		# http://stackoverflow.com/a/26983405/3064195
+		foreach(dlllist_item ${${dlllist_var}})
+			get_filename_component(dllname ${dlllist_item} NAME)
+			add_custom_command(TARGET ${target} POST_BUILD
+				COMMAND ${CMAKE_COMMAND} -E copy_if_different
+				${dlllist_item}
+				${CMAKE_CURRENT_BINARY_DIR}/\$\(Configuration\)/${dllname}
+			)
+		endforeach()
+	endif()
+endmacro()
+
+# 64-bit check
+if(${CMAKE_SIZEOF_VOID_P} EQUAL 8)
+	message(STATUS "Target is 64-bit")
+	set(SRB2_SYSTEM_BITS 64)
+else()
+	set(SRB2_SYSTEM_BITS 32)
+endif()
+
+if(MSVC)
+	message(WARNING "!! MSVC BUILDS OF SRB2 CANNOT PLAY MULTIPLAYER !! You're more than welcome to try and fix this!")
+endif()
+
+# OS macros
+if (UNIX)
+	add_definitions(-DUNIXCOMMON)
+endif()
+
+if(CMAKE_COMPILER_IS_GNUCC)
+	find_program(OBJCOPY objcopy)
+endif()
+
+if(${CMAKE_SYSTEM} MATCHES "Linux")
+	add_definitions(-DLINUX)
+	if(${SRB2_SYSTEM_BITS} EQUAL 64)
+		add_definitions(-DLINUX64)
+	endif()
+endif()
+
+if(${CMAKE_SYSTEM} MATCHES "Darwin")
+	add_definitions(-DMACOSX)
+	if(${CMAKE_C_COMPILER_ID} MATCHES "Clang")
+		set(CLANG ON)
+	endif()
+endif()
+
+# Set EXE names so the assets CMakeLists can refer to its target
+set(SRB2_SDL2_EXE_NAME srb2)
+set(SRB2_WIN_EXE_NAME srb2dd)
+
+include_directories(${CMAKE_CURRENT_BINARY_DIR}/src)
+
+add_subdirectory(src)
+add_subdirectory(assets)
+
+
+## config.h generation
+set(GIT_EXECUTABLE "git" CACHE FILEPATH "Path to git binary")
+include(GitUtilities)
+git_describe(SRB2_COMP_REVISION "${CMAKE_CURRENT_SOURCE_DIR}")
+configure_file(${CMAKE_CURRENT_SOURCE_DIR}/src/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/src/config.h)
+
+##### PACKAGE CONFIGURATION #####
+
+if(${CMAKE_SYSTEM} MATCHES "Windows")
+	set(CPACK_GENERATOR "ZIP")
+endif()
+if(${CMAKE_SYSTEM} MATCHES "Linux")
+	set(CPACK_GENERATOR "TGZ")
+endif()
+if(${CMAKE_SYSTEM} MATCHES "Darwin")
+	set(CPACK_GENERATOR "DragNDrop")
+endif()
+
+set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Sonic Robo Blast 2")
+set(CPACK_PACKAGE_VENDOR "Sonic Team Jr.")
+#set(CPACK_PACKAGE_DESCRIPTION_FILE )
+set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE")
+set(CPACK_PACKAGE_VERSION_MAJOR ${SRB2_VERSION_MAJOR})
+set(CPACK_PACKAGE_VERSION_MINOR ${SRB2_VERSION_MINOR})
+set(CPACK_PACKAGE_VERSION_PATCH ${SRB2_VERSION_PATCH})
+set(CPACK_PACKAGE_INSTALL_DIRECTORY "CMake ${CMAKE_VERSION_MAJOR}.${CMAKE_VERSION_MINOR}")
+include(CPack)
diff --git a/assets/CMakeLists.txt b/assets/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..3ce133c6a67fde3d3ea55170bc7b8b24938fa8a6
--- /dev/null
+++ b/assets/CMakeLists.txt
@@ -0,0 +1,37 @@
+## Assets Target Configuration ##
+
+# MD5 generation
+set(SRB2_ASSET_ALL
+	${CMAKE_CURRENT_SOURCE_DIR}/srb2.srb
+	${CMAKE_CURRENT_SOURCE_DIR}/player.dta
+	${CMAKE_CURRENT_SOURCE_DIR}/rings.dta
+	${CMAKE_CURRENT_SOURCE_DIR}/zones.dta
+	${CMAKE_CURRENT_SOURCE_DIR}/patch.dta
+	${CMAKE_CURRENT_SOURCE_DIR}/music.dta
+)
+
+set(SRB2_ASSET_HASHED
+	srb2.srb
+	player.dta
+	rings.dta
+	zones.dta
+	patch.dta
+)
+
+foreach(SRB2_ASSET ${SRB2_ASSET_HASHED})
+	file(MD5 ${CMAKE_CURRENT_SOURCE_DIR}/${SRB2_ASSET} "SRB2_ASSET_${SRB2_ASSET}_HASH")
+	set(SRB2_ASSET_${SRB2_ASSET}_HASH ${SRB2_ASSET_${SRB2_ASSET}_HASH} PARENT_SCOPE)
+endforeach()
+
+# Installation
+
+if(CLANG)
+	get_target_property(outname ${SRB2_SDL2_EXE_NAME} OUTPUT_NAME)
+	install(FILES ${SRB2_ASSET_ALL}
+		DESTINATION "${outname}.app/Contents/Resources"
+	)
+else()
+	install(FILES ${SRB2_ASSET_ALL}
+		DESTINATION .
+	)
+endif()
diff --git a/cmake/Modules/CMakeASM_YASMInformation.cmake b/cmake/Modules/CMakeASM_YASMInformation.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..1765180853bb2d23217a1eb785f97737411e68b1
--- /dev/null
+++ b/cmake/Modules/CMakeASM_YASMInformation.cmake
@@ -0,0 +1,46 @@
+
+#=============================================================================
+# Copyright 2010 Kitware, Inc.
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+#  License text for the above reference.)
+
+# support for the yasm assembler
+
+set(CMAKE_ASM_YASM_SOURCE_FILE_EXTENSIONS nasm yasm asm)
+
+if(NOT CMAKE_ASM_YASM_OBJECT_FORMAT)
+  if(WIN32)
+    if(CMAKE_C_SIZEOF_DATA_PTR EQUAL 8)
+      set(CMAKE_ASM_YASM_OBJECT_FORMAT win64)
+    else()
+      set(CMAKE_ASM_YASM_OBJECT_FORMAT win32)
+    endif()
+  elseif(APPLE)
+    if(CMAKE_C_SIZEOF_DATA_PTR EQUAL 8)
+      set(CMAKE_ASM_YASM_OBJECT_FORMAT macho64)
+    else()
+      set(CMAKE_ASM_YASM_OBJECT_FORMAT macho)
+    endif()
+  else()
+    if(CMAKE_C_SIZEOF_DATA_PTR EQUAL 8)
+      set(CMAKE_ASM_YASM_OBJECT_FORMAT elf64)
+    else()
+      set(CMAKE_ASM_YASM_OBJECT_FORMAT elf)
+    endif()
+  endif()
+endif()
+
+set(CMAKE_ASM_YASM_COMPILE_OBJECT "<CMAKE_ASM_YASM_COMPILER> <FLAGS> -f ${CMAKE_ASM_YASM_OBJECT_FORMAT} -o <OBJECT> <SOURCE>")
+
+# Load the generic ASMInformation file:
+set(ASM_DIALECT "_YASM")
+include(CMakeASMInformation)
+set(ASM_DIALECT)
diff --git a/cmake/Modules/CMakeDetermineASM_YASMCompiler.cmake b/cmake/Modules/CMakeDetermineASM_YASMCompiler.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..a5e7c9e5801121f04411e5f1b1c6efa98736bcc1
--- /dev/null
+++ b/cmake/Modules/CMakeDetermineASM_YASMCompiler.cmake
@@ -0,0 +1,27 @@
+
+#=============================================================================
+# Copyright 2010 Kitware, Inc.
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+#  License text for the above reference.)
+
+# Find the nasm assembler. yasm (http://www.tortall.net/projects/yasm/) is nasm compatible
+
+set(CMAKE_ASM_YASM_COMPILER_LIST nasm yasm)
+
+if(NOT CMAKE_ASM_YASM_COMPILER)
+  find_program(CMAKE_ASM_YASM_COMPILER yasm
+    "$ENV{ProgramFiles}/YASM")
+endif()
+
+# Load the generic DetermineASM compiler file with the DIALECT set properly:
+set(ASM_DIALECT "_YASM")
+include(CMakeDetermineASMCompiler)
+set(ASM_DIALECT)
diff --git a/cmake/Modules/CMakeTestASM_YASMCompiler.cmake b/cmake/Modules/CMakeTestASM_YASMCompiler.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..745f7125c4a2f7a003c488b89d977b75a8eb3ebc
--- /dev/null
+++ b/cmake/Modules/CMakeTestASM_YASMCompiler.cmake
@@ -0,0 +1,23 @@
+
+#=============================================================================
+# Copyright 2010 Kitware, Inc.
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+#  License text for the above reference.)
+
+# This file is used by EnableLanguage in cmGlobalGenerator to
+# determine that the selected ASM_NASM "compiler" works.
+# For assembler this can only check whether the compiler has been found,
+# because otherwise there would have to be a separate assembler source file
+# for each assembler on every architecture.
+
+set(ASM_DIALECT "_YASM")
+include(CMakeTestASMCompiler)
+set(ASM_DIALECT)
diff --git a/cmake/Modules/FindGME.cmake b/cmake/Modules/FindGME.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..3b0c68de735e67458ce4652c600b5768c8124046
--- /dev/null
+++ b/cmake/Modules/FindGME.cmake
@@ -0,0 +1,23 @@
+include(LibFindMacros)
+
+libfind_pkg_check_modules(GME_PKGCONF GME)
+
+find_path(GME_INCLUDE_DIR
+	NAMES gme.h
+	PATHS
+		${GME_PKGCONF_INCLUDE_DIRS}
+		/usr/include/gme
+		/usr/local/include/gme
+)
+
+find_library(GME_LIBRARY
+	NAMES gme
+	PATHS
+		${GME_PKGCONF_LIBRARY_DIRS}
+		/usr/lib
+		/usr/local/lib
+)
+
+set(GME_PROCESS_INCLUDES GME_INCLUDE_DIR)
+set(GME_PROCESS_LIBS GME_LIBRARY)
+libfind_process(GME)
\ No newline at end of file
diff --git a/cmake/Modules/FindSDL2.cmake b/cmake/Modules/FindSDL2.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..faa556a883aae61ac482c304f32200a996b982de
--- /dev/null
+++ b/cmake/Modules/FindSDL2.cmake
@@ -0,0 +1,34 @@
+# Find SDL2
+# Once done, this will define
+# 
+#  SDL2_FOUND - system has SDL2
+#  SDL2_INCLUDE_DIRS - SDL2 include directories
+#  SDL2_LIBRARIES - link libraries
+
+include(LibFindMacros)
+
+libfind_pkg_check_modules(SDL2_PKGCONF SDL2)
+
+# includes
+find_path(SDL2_INCLUDE_DIR
+	NAMES SDL.h
+	PATHS
+		${SDL2_PKGCONF_INCLUDE_DIRS}
+		"/usr/include/SDL2"
+		"/usr/local/include/SDL2"
+)
+
+# library
+find_library(SDL2_LIBRARY
+	NAMES SDL2
+	PATHS
+		${SDL2_PKGCONF_LIBRARY_DIRS}
+		"/usr/lib"
+		"/usr/local/lib"
+)
+
+
+# set include dir variables
+set(SDL2_PROCESS_INCLUDES SDL2_INCLUDE_DIR)
+set(SDL2_PROCESS_LIBS SDL2_LIBRARY)
+libfind_process(SDL2)
diff --git a/cmake/Modules/FindSDL2_main.cmake b/cmake/Modules/FindSDL2_main.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..280e51e2e47b9555584af340b62d880422a21c3e
--- /dev/null
+++ b/cmake/Modules/FindSDL2_main.cmake
@@ -0,0 +1,34 @@
+# Find SDL2
+# Once done, this will define
+# 
+#  SDL2_MAIN_FOUND - system has SDL2
+#  SDL2_MAIN_INCLUDE_DIRS - SDL2 include directories
+#  SDL2_MAIN_LIBRARIES - link libraries
+
+include(LibFindMacros)
+
+libfind_pkg_check_modules(SDL2_MAIN_PKGCONF SDL2)
+
+# includes
+find_path(SDL2_MAIN_INCLUDE_DIR
+	NAMES SDL.h
+	PATHS
+		${SDL2_MAIN_PKGCONF_INCLUDE_DIRS}
+		"/usr/include/SDL2"
+		"/usr/local/include/SDL2"
+)
+
+# library
+find_library(SDL2_MAIN_LIBRARY
+	NAMES SDL2_main
+	PATHS
+		${SDL2_MAIN_PKGCONF_LIBRARY_DIRS}
+		"/usr/lib"
+		"/usr/local/lib"
+)
+
+
+# set include dir variables
+set(SDL2_MAIN_PROCESS_INCLUDES SDL2_MAIN_INCLUDE_DIR)
+set(SDL2_MAIN_PROCESS_LIBS SDL2_MAIN_LIBRARY)
+libfind_process(SDL2_MAIN)
diff --git a/cmake/Modules/FindSDL2_mixer.cmake b/cmake/Modules/FindSDL2_mixer.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..59b4823ed8ddb4406fd8dc8036675025c43d6fff
--- /dev/null
+++ b/cmake/Modules/FindSDL2_mixer.cmake
@@ -0,0 +1,34 @@
+# Find SDL2
+# Once done, this will define
+# 
+#  SDL2_MIXER_FOUND - system has SDL2
+#  SDL2_MIXER_INCLUDE_DIRS - SDL2 include directories
+#  SDL2_MIXER_LIBRARIES - link libraries
+
+include(LibFindMacros)
+
+libfind_pkg_check_modules(SDL2_MIXER_PKGCONF SDL2_mixer)
+
+# includes
+find_path(SDL2_MIXER_INCLUDE_DIR
+	NAMES SDL_mixer.h
+	PATHS
+		${SDL2_MIXER_PKGCONF_INCLUDE_DIRS}
+		"/usr/include/SDL2"
+		"/usr/local/include/SDL2"
+)
+
+# library
+find_library(SDL2_MIXER_LIBRARY
+	NAMES SDL2_mixer
+	PATHS
+		${SDL2_MIXER_PKGCONF_LIBRARY_DIRS}
+		"/usr/lib"
+		"/usr/local/lib"
+)
+
+
+# set include dir variables
+set(SDL2_MIXER_PROCESS_INCLUDES SDL2_MIXER_INCLUDE_DIR)
+set(SDL2_MIXER_PROCESS_LIBS SDL2_MIXER_LIBRARY)
+libfind_process(SDL2_MIXER)
diff --git a/cmake/Modules/GitUtilities.cmake b/cmake/Modules/GitUtilities.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..de4015b0d1e45be3afd1c858c373db4b3d36277c
--- /dev/null
+++ b/cmake/Modules/GitUtilities.cmake
@@ -0,0 +1,22 @@
+# Git utilities
+
+if(__GitUtilities)
+	return()
+endif()
+
+set(__GitUtilities ON)
+
+function(git_describe variable path)
+	execute_process(COMMAND "${GIT_EXECUTABLE}" "describe"
+		WORKING_DIRECTORY "${path}"
+		RESULT_VARIABLE result
+		OUTPUT_VARIABLE output
+		ERROR_QUIET
+		OUTPUT_STRIP_TRAILING_WHITESPACE
+	)
+	#if(NOT result EQUAL 0)
+	#	set(${variable} "GITERROR-${result}-NOTFOUND" CACHE STRING "revision" FORCE)
+	#endif()
+
+	set(${variable} "${output}" PARENT_SCOPE)
+endfunction()
diff --git a/cmake/Modules/LibFindMacros.cmake b/cmake/Modules/LibFindMacros.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..f6800aa7bd277e85ffa4297d27fbc980f0fda281
--- /dev/null
+++ b/cmake/Modules/LibFindMacros.cmake
@@ -0,0 +1,265 @@
+# Version 2.2
+# Public Domain, originally written by Lasse Kärkkäinen <tronic>
+# Maintained at https://github.com/Tronic/cmake-modules
+# Please send your improvements as pull requests on Github.
+
+# Find another package and make it a dependency of the current package.
+# This also automatically forwards the "REQUIRED" argument.
+# Usage: libfind_package(<prefix> <another package> [extra args to find_package])
+macro (libfind_package PREFIX PKG)
+  set(${PREFIX}_args ${PKG} ${ARGN})
+  if (${PREFIX}_FIND_REQUIRED)
+    set(${PREFIX}_args ${${PREFIX}_args} REQUIRED)
+  endif()
+  find_package(${${PREFIX}_args})
+  set(${PREFIX}_DEPENDENCIES ${${PREFIX}_DEPENDENCIES};${PKG})
+  unset(${PREFIX}_args)
+endmacro()
+
+# A simple wrapper to make pkg-config searches a bit easier.
+# Works the same as CMake's internal pkg_check_modules but is always quiet.
+macro (libfind_pkg_check_modules)
+  find_package(PkgConfig QUIET)
+  if (PKG_CONFIG_FOUND)
+    pkg_check_modules(${ARGN} QUIET)
+  endif()
+endmacro()
+
+# Avoid useless copy&pasta by doing what most simple libraries do anyway:
+# pkg-config, find headers, find library.
+# Usage: libfind_pkg_detect(<prefix> <pkg-config args> FIND_PATH <name> [other args] FIND_LIBRARY <name> [other args])
+# E.g. libfind_pkg_detect(SDL2 sdl2 FIND_PATH SDL.h PATH_SUFFIXES SDL2 FIND_LIBRARY SDL2)
+function (libfind_pkg_detect PREFIX)
+  # Parse arguments
+  set(argname pkgargs)
+  foreach (i ${ARGN})
+    if ("${i}" STREQUAL "FIND_PATH")
+      set(argname pathargs)
+    elseif ("${i}" STREQUAL "FIND_LIBRARY")
+      set(argname libraryargs)
+    else()
+      set(${argname} ${${argname}} ${i})
+    endif()
+  endforeach()
+  if (NOT pkgargs)
+    message(FATAL_ERROR "libfind_pkg_detect requires at least a pkg_config package name to be passed.")
+  endif()
+  # Find library
+  libfind_pkg_check_modules(${PREFIX}_PKGCONF ${pkgargs})
+  if (pathargs)
+    find_path(${PREFIX}_INCLUDE_DIR NAMES ${pathargs} HINTS ${${PREFIX}_PKGCONF_INCLUDE_DIRS})
+  endif()
+  if (libraryargs)
+    find_library(${PREFIX}_LIBRARY NAMES ${libraryargs} HINTS ${${PREFIX}_PKGCONF_LIBRARY_DIRS})
+  endif()
+endfunction()
+
+# Extracts a version #define from a version.h file, output stored to <PREFIX>_VERSION.
+# Usage: libfind_version_header(Foobar foobar/version.h FOOBAR_VERSION_STR)
+# Fourth argument "QUIET" may be used for silently testing different define names.
+# This function does nothing if the version variable is already defined.
+function (libfind_version_header PREFIX VERSION_H DEFINE_NAME)
+  # Skip processing if we already have a version or if the include dir was not found
+  if (${PREFIX}_VERSION OR NOT ${PREFIX}_INCLUDE_DIR)
+    return()
+  endif()
+  set(quiet ${${PREFIX}_FIND_QUIETLY})
+  # Process optional arguments
+  foreach(arg ${ARGN})
+    if (arg STREQUAL "QUIET")
+      set(quiet TRUE)
+    else()
+      message(AUTHOR_WARNING "Unknown argument ${arg} to libfind_version_header ignored.")
+    endif()
+  endforeach()
+  # Read the header and parse for version number
+  set(filename "${${PREFIX}_INCLUDE_DIR}/${VERSION_H}")
+  if (NOT EXISTS ${filename})
+    if (NOT quiet)
+      message(AUTHOR_WARNING "Unable to find ${${PREFIX}_INCLUDE_DIR}/${VERSION_H}")
+    endif()
+    return()
+  endif()
+  file(READ "${filename}" header)
+  string(REGEX REPLACE ".*#[ \t]*define[ \t]*${DEFINE_NAME}[ \t]*\"([^\n]*)\".*" "\\1" match "${header}")
+  # No regex match?
+  if (match STREQUAL header)
+    if (NOT quiet)
+      message(AUTHOR_WARNING "Unable to find \#define ${DEFINE_NAME} \"<version>\" from ${${PREFIX}_INCLUDE_DIR}/${VERSION_H}")
+    endif()
+    return()
+  endif()
+  # Export the version string
+  set(${PREFIX}_VERSION "${match}" PARENT_SCOPE)
+endfunction()
+
+# Do the final processing once the paths have been detected.
+# If include dirs are needed, ${PREFIX}_PROCESS_INCLUDES should be set to contain
+# all the variables, each of which contain one include directory.
+# Ditto for ${PREFIX}_PROCESS_LIBS and library files.
+# Will set ${PREFIX}_FOUND, ${PREFIX}_INCLUDE_DIRS and ${PREFIX}_LIBRARIES.
+# Also handles errors in case library detection was required, etc.
+function (libfind_process PREFIX)
+  # Skip processing if already processed during this configuration run
+  if (${PREFIX}_FOUND)
+    return()
+  endif()
+
+  set(found TRUE)  # Start with the assumption that the package was found
+
+  # Did we find any files? Did we miss includes? These are for formatting better error messages.
+  set(some_files FALSE)
+  set(missing_headers FALSE)
+
+  # Shorthands for some variables that we need often
+  set(quiet ${${PREFIX}_FIND_QUIETLY})
+  set(required ${${PREFIX}_FIND_REQUIRED})
+  set(exactver ${${PREFIX}_FIND_VERSION_EXACT})
+  set(findver "${${PREFIX}_FIND_VERSION}")
+  set(version "${${PREFIX}_VERSION}")
+
+  # Lists of config option names (all, includes, libs)
+  unset(configopts)
+  set(includeopts ${${PREFIX}_PROCESS_INCLUDES})
+  set(libraryopts ${${PREFIX}_PROCESS_LIBS})
+
+  # Process deps to add to 
+  foreach (i ${PREFIX} ${${PREFIX}_DEPENDENCIES})
+    if (DEFINED ${i}_INCLUDE_OPTS OR DEFINED ${i}_LIBRARY_OPTS)
+      # The package seems to export option lists that we can use, woohoo!
+      list(APPEND includeopts ${${i}_INCLUDE_OPTS})
+      list(APPEND libraryopts ${${i}_LIBRARY_OPTS})
+    else()
+      # If plural forms don't exist or they equal singular forms
+      if ((NOT DEFINED ${i}_INCLUDE_DIRS AND NOT DEFINED ${i}_LIBRARIES) OR
+          ({i}_INCLUDE_DIR STREQUAL ${i}_INCLUDE_DIRS AND ${i}_LIBRARY STREQUAL ${i}_LIBRARIES))
+        # Singular forms can be used
+        if (DEFINED ${i}_INCLUDE_DIR)
+          list(APPEND includeopts ${i}_INCLUDE_DIR)
+        endif()
+        if (DEFINED ${i}_LIBRARY)
+          list(APPEND libraryopts ${i}_LIBRARY)
+        endif()
+      else()
+        # Oh no, we don't know the option names
+        message(FATAL_ERROR "We couldn't determine config variable names for ${i} includes and libs. Aieeh!")
+      endif()
+    endif()
+  endforeach()
+  
+  if (includeopts)
+    list(REMOVE_DUPLICATES includeopts)
+  endif()
+  
+  if (libraryopts)
+    list(REMOVE_DUPLICATES libraryopts)
+  endif()
+
+  string(REGEX REPLACE ".*[ ;]([^ ;]*(_INCLUDE_DIRS|_LIBRARIES))" "\\1" tmp "${includeopts} ${libraryopts}")
+  if (NOT tmp STREQUAL "${includeopts} ${libraryopts}")
+    message(AUTHOR_WARNING "Plural form ${tmp} found in config options of ${PREFIX}. This works as before but is now deprecated. Please only use singular forms INCLUDE_DIR and LIBRARY, and update your find scripts for LibFindMacros > 2.0 automatic dependency system (most often you can simply remove the PROCESS variables entirely).")
+  endif()
+
+  # Include/library names separated by spaces (notice: not CMake lists)
+  unset(includes)
+  unset(libs)
+
+  # Process all includes and set found false if any are missing
+  foreach (i ${includeopts})
+    list(APPEND configopts ${i})
+    if (NOT "${${i}}" STREQUAL "${i}-NOTFOUND")
+      list(APPEND includes "${${i}}")
+    else()
+      set(found FALSE)
+      set(missing_headers TRUE)
+    endif()
+  endforeach()
+
+  # Process all libraries and set found false if any are missing
+  foreach (i ${libraryopts})
+    list(APPEND configopts ${i})
+    if (NOT "${${i}}" STREQUAL "${i}-NOTFOUND")
+      list(APPEND libs "${${i}}")
+    else()
+      set (found FALSE)
+    endif()
+  endforeach()
+
+  # Version checks
+  if (found AND findver)
+    if (NOT version)
+      message(WARNING "The find module for ${PREFIX} does not provide version information, so we'll just assume that it is OK. Please fix the module or remove package version requirements to get rid of this warning.")
+    elseif (version VERSION_LESS findver OR (exactver AND NOT version VERSION_EQUAL findver))
+      set(found FALSE)
+      set(version_unsuitable TRUE)
+    endif()
+  endif()
+
+  # If all-OK, hide all config options, export variables, print status and exit
+  if (found)
+    foreach (i ${configopts})
+      mark_as_advanced(${i})
+    endforeach()
+    if (NOT quiet)
+      message(STATUS "Found ${PREFIX} ${${PREFIX}_VERSION}")
+      if (LIBFIND_DEBUG)
+        message(STATUS "  ${PREFIX}_DEPENDENCIES=${${PREFIX}_DEPENDENCIES}")
+        message(STATUS "  ${PREFIX}_INCLUDE_OPTS=${includeopts}")
+        message(STATUS "  ${PREFIX}_INCLUDE_DIRS=${includes}")
+        message(STATUS "  ${PREFIX}_LIBRARY_OPTS=${libraryopts}")
+        message(STATUS "  ${PREFIX}_LIBRARIES=${libs}")
+      endif()
+      set (${PREFIX}_INCLUDE_OPTS ${includeopts} PARENT_SCOPE)
+      set (${PREFIX}_LIBRARY_OPTS ${libraryopts} PARENT_SCOPE)
+      set (${PREFIX}_INCLUDE_DIRS ${includes} PARENT_SCOPE)
+      set (${PREFIX}_LIBRARIES ${libs} PARENT_SCOPE)
+      set (${PREFIX}_FOUND TRUE PARENT_SCOPE)
+    endif()
+    return()    
+  endif()
+
+  # Format messages for debug info and the type of error
+  set(vars "Relevant CMake configuration variables:\n")
+  foreach (i ${configopts})
+    mark_as_advanced(CLEAR ${i})
+    set(val ${${i}})
+    if ("${val}" STREQUAL "${i}-NOTFOUND")
+      set (val "<not found>")
+    elseif (val AND NOT EXISTS ${val})
+      set (val "${val}  (does not exist)")
+    else()
+      set(some_files TRUE)
+    endif()
+    set(vars "${vars}  ${i}=${val}\n")
+  endforeach()
+  set(vars "${vars}You may use CMake GUI, cmake -D or ccmake to modify the values. Delete CMakeCache.txt to discard all values and force full re-detection if necessary.\n")
+  if (version_unsuitable)
+    set(msg "${PREFIX} ${${PREFIX}_VERSION} was found but")
+    if (exactver)
+      set(msg "${msg} only version ${findver} is acceptable.")
+    else()
+      set(msg "${msg} version ${findver} is the minimum requirement.")
+    endif()
+  else()
+    if (missing_headers)
+      set(msg "We could not find development headers for ${PREFIX}. Do you have the necessary dev package installed?")
+    elseif (some_files)
+      set(msg "We only found some files of ${PREFIX}, not all of them. Perhaps your installation is incomplete or maybe we just didn't look in the right place?")
+      if(findver)
+        set(msg "${msg} This could also be caused by incompatible version (if it helps, at least ${PREFIX} ${findver} should work).")
+      endif()
+    else()
+      set(msg "We were unable to find package ${PREFIX}.")
+    endif()
+  endif()
+
+  # Fatal error out if REQUIRED
+  if (required)
+    set(msg "REQUIRED PACKAGE NOT FOUND\n${msg} This package is REQUIRED and you need to install it or adjust CMake configuration in order to continue building ${CMAKE_PROJECT_NAME}.")
+    message(FATAL_ERROR "${msg}\n${vars}")
+  endif()
+  # Otherwise just print a nasty warning
+  if (NOT quiet)
+    message(WARNING "WARNING: MISSING PACKAGE\n${msg} This package is NOT REQUIRED and you may ignore this warning but by doing so you may miss some functionality of ${CMAKE_PROJECT_NAME}. \n${vars}")
+  endif()
+endfunction()
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..6c57440f1bb6ad8098c6619ab1aa9353a28fe05b
--- /dev/null
+++ b/src/CMakeLists.txt
@@ -0,0 +1,400 @@
+# SRB2 Core
+
+# Core sources
+set(SRB2_CORE_SOURCES
+	am_map.c
+	b_bot.c
+	command.c
+	comptime.c
+	console.c
+	d_clisrv.c
+	d_main.c
+	d_net.c
+	d_netcmd.c
+	d_netfil.c
+	dehacked.c
+	f_finale.c
+	f_wipe.c
+	filesrch.c
+	g_game.c
+	g_input.c
+	hu_stuff.c
+	i_tcp.c
+	info.c
+	lzf.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_queue.c
+	m_random.c
+	md5.c
+	mserv.c
+	p_ceilng.c
+	p_enemy.c
+	p_fab.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
+	r_bsp.c
+	r_data.c
+	r_draw.c
+	r_main.c
+	r_plane.c
+	r_segs.c
+	r_sky.c
+	r_splats.c
+	r_things.c
+	s_sound.c
+	screen.c
+	sounds.c
+	st_stuff.c
+	#string.c
+	tables.c
+	v_video.c
+	w_wad.c
+	y_inter.c
+	z_zone.c
+)
+
+set(SRB2_CORE_HEADERS
+	am_map.h
+	b_bot.h
+	byteptr.h
+	command.h
+	comptime.h
+	console.h
+	d_clisrv.h
+	d_event.h
+	d_main.h
+	d_net.h
+	d_netcmd.h
+	d_netfil.h
+	d_player.h
+	d_think.h
+	d_ticcmd.h
+	dehacked.h
+	doomdata.h
+	doomdef.h
+	doomstat.h
+	doomtype.h
+	endian.h
+	f_finale.h
+	fastcmp.h
+	filesrch.h
+	g_game.h
+	g_input.h
+	g_state.h
+	hu_stuff.h
+	i_joy.h
+	i_net.h
+	i_sound.h
+	i_system.h
+	i_tcp.h
+	i_video.h
+	info.h
+	keys.h
+	lzf.h
+	m_anigif.h
+	m_argv.h
+	m_bbox.h
+	m_cheat.h
+	m_cond.h
+	m_dllist.h
+	m_fixed.h
+	m_menu.h
+	m_misc.h
+	m_queue.h
+	m_random.h
+	m_swap.h
+	md5.h
+	mserv.h
+	p5prof.h
+	p_local.h
+	p_maputl.h
+	p_mobj.h
+	p_polyobj.h
+	p_pspr.h
+	p_saveg.h
+	p_setup.h
+	p_spec.h
+	p_tick.h
+	r_bsp.h
+	r_data.h
+	r_defs.h
+	r_draw.h
+	r_local.h
+	r_main.h
+	r_plane.h
+	r_segs.h
+	r_sky.h
+	r_splats.h
+	r_state.h
+	r_things.h
+	s_sound.h
+	screen.h
+	sounds.h
+	st_stuff.h
+	tables.h
+	v_video.h
+	w_wad.h
+	y_inter.h
+	z_zone.h
+)
+
+prepend_sources(SRB2_CORE_SOURCES)
+prepend_sources(SRB2_CORE_HEADERS)
+
+set(SRB2_CORE_HEADERS ${SRB2_CORE_HEADERS} ${CMAKE_CURRENT_BINARY_DIR}/config.h)
+
+set(SRB2_HWRENDER_SOURCES
+	hardware/hw_bsp.c
+	hardware/hw_cache.c
+	hardware/hw_draw.c
+	hardware/hw_light.c
+	hardware/hw_main.c
+	hardware/hw_md2.c
+	hardware/hw_trick.c
+)
+
+set (SRB2_HWRENDER_HEADERS
+	hardware/hw_data.h
+	hardware/hw_defs.h
+	hardware/hw_dll.h
+	hardware/hw_drv.h
+	hardware/hw_glide.h
+	hardware/hw_glob.h
+	hardware/hw_light.h
+	hardware/hw_main.h
+	hardware/hw_md2.h
+)
+
+prepend_sources(SRB2_HWRENDER_SOURCES)
+prepend_sources(SRB2_HWRENDER_HEADERS)
+
+set(SRB2_R_OPENGL_SOURCES
+	hardware/r_opengl/r_opengl.c
+)
+
+set(SRB2_R_OPENGL_HEADERS
+	hardware/r_opengl/r_opengl.h
+)
+
+prepend_sources(SRB2_R_OPENGL_SOURCES)
+prepend_sources(SRB2_R_OPENGL_HEADERS)
+
+set(SRB2_ASM_SOURCES
+	vid_copy.s
+)
+
+set(SRB2_NASM_SOURCES
+	tmap_mmx.nas
+	tmap.nas
+)
+
+if(MSVC)
+	list(APPEND SRB2_NASM_SOURCES tmap_vc.nas)
+endif()
+
+set(SRB2_NASM_OBJECTS
+	tmap_mmx.obj
+	tmap.obj
+)
+
+if(MSVC)
+	list(APPEND SRB2_NASM_OBJECTS tmap_vc.obj)
+endif()
+
+prepend_sources(SRB2_ASM_SOURCES)
+prepend_sources(SRB2_NASM_SOURCES)
+
+
+### Configuration
+set(SRB2_CONFIG_HAVE_BLUA ON CACHE BOOL
+	"Enable Lua interpreter support")
+set(SRB2_CONFIG_HAVE_PNG ON CACHE BOOL
+	"Enable PNG support. Depends on zlib, so will be disabled if you don't enable that too.")
+set(SRB2_CONFIG_HAVE_ZLIB ON CACHE BOOL
+	"Enable zlib support")
+set(SRB2_CONFIG_HAVE_GME ON CACHE BOOL
+	"Enable GME support")
+set(SRB2_CONFIG_HWRENDER ON CACHE BOOL
+	"Enable hardware rendering through OpenGL")
+set(SRB2_CONFIG_USEASM OFF CACHE BOOL
+	"Enable NASM tmap implementation for software mode speedup.")
+set(SRB2_CONFIG_YASM OFF CACHE BOOL
+	"Use YASM in place of NASM.")
+set(SRB2_CONFIG_STATIC_OPENGL OFF CACHE BOOL
+	"Use statically linked OpenGL. NOT RECOMMENDED.")
+
+if(${SRB2_CONFIG_HAVE_BLUA})
+	add_definitions(-DHAVE_BLUA)
+	set(SRB2_LUA_SOURCES
+		lua_baselib.c
+		lua_consolelib.c
+		lua_hooklib.c
+		lua_hudlib.c
+		lua_infolib.c
+		lua_maplib.c
+		lua_mathlib.c
+		lua_mobjlib.c
+		lua_playerlib.c
+		lua_script.c
+		lua_skinlib.c
+		lua_thinkerlib.c
+	)
+	set(SRB2_LUA_HEADERS
+		lua_hook.h
+		lua_hud.h
+		lua_libs.h
+		lua_script.h
+	)
+
+	prepend_sources(SRB2_LUA_SOURCES)
+	prepend_sources(SRB2_LUA_HEADERS)
+
+	set(SRB2_BLUA_SOURCES
+		blua/lapi.c
+		blua/lauxlib.c
+		blua/lbaselib.c
+		blua/lcode.c
+		blua/ldebug.c
+		blua/ldo.c
+		blua/ldump.c
+		blua/lfunc.c
+		blua/lgc.c
+		blua/linit.c
+		blua/llex.c
+		blua/lmem.c
+		blua/lobject.c
+		blua/lopcodes.c
+		blua/lparser.c
+		blua/lstate.c
+		blua/lstring.c
+		blua/lstrlib.c
+		blua/ltable.c
+		blua/ltablib.c
+		blua/ltm.c
+		blua/lundump.c
+		blua/lvm.c
+		blua/lzio.c
+	)
+	set(SRB2_BLUA_HEADERS
+		blua/lapi.h
+		blua/lauxlib.h
+		blua/lcode.h
+		blua/ldebug.h
+		blua/ldo.h
+		blua/lfunc.h
+		blua/lgc.h
+		blua/llex.h
+		blua/llimits.h
+		blua/lmem.h
+		blua/lobject.h
+		blua/lopcodes.h
+		blua/lparser.h
+		blua/lstate.h
+		blua/lstring.h
+		blua/ltable.h
+		blua/ltm.h
+		blua/lua.h
+		blua/luaconf.h
+		blua/lualib.h
+		blua/lundump.h
+		blua/lvm.h
+		blua/lzio.h
+	)
+	prepend_sources(SRB2_BLUA_SOURCES)
+	prepend_sources(SRB2_BLUA_HEADERS)
+endif()
+
+if(${SRB2_CONFIG_HAVE_GME})
+	find_package(GME)
+	if(${GME_FOUND})
+		set(SRB2_HAVE_GME ON)
+	else()
+		message(WARNING "You have specified that GME is available but it was not found.")
+	endif()
+endif()
+
+if(${SRB2_CONFIG_HAVE_ZLIB})
+	find_package(ZLIB)
+	if(${ZLIB_FOUND})
+		set(SRB2_HAVE_ZLIB ON)
+	else()
+		message(WARNING "You have specified that ZLIB is available but it was not found. SRB2 may not compile correctly.")
+	endif()
+endif()
+
+if(${SRB2_CONFIG_HAVE_PNG} AND ${SRB2_CONFIG_HAVE_ZLIB})
+	if (${ZLIB_FOUND})
+		find_package(PNG)
+		if(${PNG_FOUND})
+			set(SRB2_HAVE_PNG ON)
+			add_definitions(-DHAVE_PNG)
+			add_definitions(-D_LARGEFILE64_SOURCE)
+		else()
+			message(WARNING "You have specified that PNG is available but it was not found. SRB2 may not compile correctly.")
+		endif()
+	endif()
+endif()
+
+if(${SRB2_CONFIG_HWRENDER})
+	add_definitions(-DHWRENDER)
+endif()
+
+if(${SRB2_CONFIG_HWRENDER} AND ${SRB2_CONFIG_STATIC_OPENGL})
+	find_package(OpenGL)
+	if(${OPENGL_FOUND})
+		add_definitions(-DHWRENDER)
+		add_definitions(-DSTATIC_OPENGL)
+	else()
+		message(WARNING "You have specified static opengl but opengl was not found. Not setting HWRENDER.")
+	endif()
+endif()
+
+if(${SRB2_CONFIG_USEASM})
+	if(${SRB2_CONFIG_YASM})
+		set(CMAKE_ASM_YASM_SOURCE_FILE_EXTENSIONS ${CMAKE_ASM_YASM_SOURCE_FILE_EXTENSIONS} nas)
+		enable_language(ASM_YASM)
+	else()
+		set(CMAKE_ASM_NASM_SOURCE_FILE_EXTENSIONS ${CMAKE_ASM_NASM_SOURCE_FILE_EXTENSIONS} nas)
+		enable_language(ASM_NASM)
+	endif()
+	set(SRB2_USEASM ON)
+	add_definitions(-DUSEASM)
+else()
+	set(SRB2_USEASM OFF)
+	add_definitions(-DNOASM -DNONX86)
+endif()
+
+# Targets
+
+if(${CMAKE_SYSTEM} MATCHES Windows)
+	add_subdirectory(win32)
+endif()
+
+# Compatibility flag with later versions of GCC
+# We should really fix our code to not need this
+if(NOT CLANG AND NOT MSVC)
+	set(CMAKE_C_FLAGS ${CMAKE_C_FLAGS} -mno-ms-bitfields)
+endif()
+
+add_definitions(-DCMAKECONFIG)
+
+add_subdirectory(sdl)
diff --git a/src/Makefile b/src/Makefile
index d4cc64a4b6ff79da6672ee10df9ef30f574aca40..a1a8804e708b5ff1fa82918c23fea23895a126f2 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -585,6 +585,8 @@ $(BIN)/$(EXENAME): $(POS) $(OBJS)
 	-$(MKDIR) $(BIN)
 	@echo Linking $(EXENAME)...
 	$(LD) $(LDFLAGS) $(OBJS) -o $(BIN)/$(EXENAME) $(LIBS)
+	@echo $(LD) $(LDFLAGS) $(OBJS) -o $(BIN)/$(EXENAME) $(LIBS)
+	@echo $(CFLAGS)
 ifndef VALGRIND
 ifndef NOOBJDUMP
 	@echo Dumping debugging info
diff --git a/src/comptime.c b/src/comptime.c
index cd6bfd9bb24d6cbbbd1e3f60258e82de35344037..a4dc5b0f9637e60d761819792ee1f5dd4058656e 100644
--- a/src/comptime.c
+++ b/src/comptime.c
@@ -7,10 +7,16 @@
  *
  */
 
-#ifdef COMPVERSION
+#if (defined(CMAKECONFIG))
+#include "config.h"
+const char *comprevision = SRB2_COMP_REVISION;
+
+#elif (defined(COMPVERSION))
 #include "comptime.h"
+
 #else
 const char *comprevision = "illegal";
+
 #endif
 
 const char *compdate = __DATE__;
diff --git a/src/config.h.in b/src/config.h.in
new file mode 100644
index 0000000000000000000000000000000000000000..6e7c64da332e9e107aed89da9c5c23a7fc115612
--- /dev/null
+++ b/src/config.h.in
@@ -0,0 +1,27 @@
+/** SRB2 CMake Configuration */
+
+#ifndef __CONFIG_H__
+#define __CONFIG_H__
+
+#ifdef CMAKECONFIG
+
+#define ASSET_HASH_SRB2_SRB   "${SRB2_ASSET_srb2.srb_HASH}"
+#define ASSET_HASH_PLAYER_DTA "${SRB2_ASSET_player.dta_HASH}"
+#define ASSET_HASH_RINGS_DTA  "${SRB2_ASSET_rings.dta_HASH}"
+#define ASSET_HASH_ZONES_DTA  "${SRB2_ASSET_zones.dta_HASH}"
+#define ASSET_HASH_PATCH_DTA  "${SRB2_ASSET_patch.dta_HASH}"
+
+#define SRB2_COMP_REVISION    "${SRB2_COMP_REVISION}"
+
+#define CMAKE_ASSETS_DIR      "${CMAKE_SOURCE_DIR}/assets"
+
+#else
+
+#define ASSET_HASH_SRB2_SRB   "c1b9577687f8a795104aef4600720ea7"
+#define ASSET_HASH_ZONES_DTA  "303838c6c534d9540288360fa49cca60"
+#define ASSET_HASH_PLAYER_DTA "cfca0f1c73023cbbd8f844f45480f799"
+#define ASSET_HASH_RINGS_DTA  "85901ad4bf94637e5753d2ac2c03ea26"
+
+#define 
+#endif
+#endif
diff --git a/src/d_main.c b/src/d_main.c
index 95808b274ff111cb9146870f8530e5fe48686114..a959a86328e09d4a501c3c9b2eea52e197ed478d 100644
--- a/src/d_main.c
+++ b/src/d_main.c
@@ -74,6 +74,12 @@ int	snprintf(char *str, size_t n, const char *fmt, ...);
 #include "m_cond.h" // condition initialization
 #include "fastcmp.h"
 
+#ifdef CMAKECONFIG
+#include "config.h"
+#else
+#include "config.h.in"
+#endif
+
 #ifdef _XBOX
 #include "sdl/SRB2XBOX/xboxhelp.h"
 #endif
@@ -1115,10 +1121,10 @@ void D_SRB2Main(void)
 #if 1 // md5s last updated 12/14/14
 
 	// Check MD5s of autoloaded files
-	W_VerifyFileMD5(0, "c1b9577687f8a795104aef4600720ea7"); // srb2.srb/srb2.wad
-	W_VerifyFileMD5(1, "303838c6c534d9540288360fa49cca60"); // zones.dta
-	W_VerifyFileMD5(2, "cfca0f1c73023cbbd8f844f45480f799"); // player.dta
-	W_VerifyFileMD5(3, "85901ad4bf94637e5753d2ac2c03ea26"); // rings.dta
+	W_VerifyFileMD5(0, ASSET_HASH_SRB2_SRB); // srb2.srb/srb2.wad
+	W_VerifyFileMD5(1, ASSET_HASH_ZONES_DTA); // zones.dta
+	W_VerifyFileMD5(2, ASSET_HASH_PLAYER_DTA); // player.dta
+	W_VerifyFileMD5(3, ASSET_HASH_RINGS_DTA); // rings.dta
 	//W_VerifyFileMD5(4, "0c66790502e648bfce90fdc5bb15722e"); // patch.dta
 	// don't check music.dta because people like to modify it, and it doesn't matter if they do
 	// ...except it does if they slip maps in there, and that's what W_VerifyNMUSlumps is for.
diff --git a/src/doomdef.h b/src/doomdef.h
index d14cd5ddbb452465964d6f9ecb8a16f52a4d6458..4a6d6e5764bc48198d034f2e2e98ce8c5ac9ab26 100644
--- a/src/doomdef.h
+++ b/src/doomdef.h
@@ -146,6 +146,7 @@ extern FILE *logstream;
 #define VERSION    201 // Game version
 #define SUBVERSION 14  // more precise version number
 #define VERSIONSTRING "v2.1.14"
+#define VERSIONSTRINGW L"v2.1.14"
 // Hey! If you change this, add 1 to the MODVERSION below!
 // Otherwise we can't force updates!
 #endif
diff --git a/src/doomtype.h b/src/doomtype.h
index 6bc563527775983c185113f01dbca2092ecebd26..ff4199775f03c104ac86f51f23998f167c137ac7 100644
--- a/src/doomtype.h
+++ b/src/doomtype.h
@@ -100,9 +100,9 @@ typedef long ssize_t;
 
 #if defined (_MSC_VER) || defined (__OS2__)
 	// Microsoft VisualC++
-#ifdef _MSC_VER
+#if (_MSC_VER <= 1800) // MSVC 2013 and back
 	#define snprintf                _snprintf
-#if (_MSC_VER <= 1200)
+#if (_MSC_VER <= 1200) // MSVC 2012 and back
 	#define vsnprintf               _vsnprintf
 #endif
 #endif
diff --git a/src/f_wipe.c b/src/f_wipe.c
index 69e956216225003bdaaaf94920a28e43d5c5354e..8e7c622c43a393276c6c9dffd9b515a36b3114b6 100644
--- a/src/f_wipe.c
+++ b/src/f_wipe.c
@@ -210,8 +210,8 @@ static void F_DoWipe(fademask_t *fademask)
 		UINT32 draw_linestogo, draw_rowstogo;
 
 		// rectangle coordinates, etc.
-		UINT16 scrxpos[fademask->width  + 1];
-		UINT16 scrypos[fademask->height + 1];
+		UINT16* scrxpos = (UINT16*)malloc((fademask->width + 1)  * sizeof(UINT16));
+		UINT16* scrypos = (UINT16*)malloc((fademask->height + 1) * sizeof(UINT16));
 		UINT16 maskx, masky;
 		UINT32 relativepos;
 
@@ -263,6 +263,9 @@ static void F_DoWipe(fademask_t *fademask)
 			if (++maskx >= fademask->width)
 				++masky, maskx = 0;
 		} while (++mask < maskend);
+
+		free(scrxpos);
+		free(scrypos);
 	}
 }
 #endif
diff --git a/src/sdl/CMakeLists.txt b/src/sdl/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..b4eeeeb5fb1c0e778be6a6a16758e0c116d9ad53
--- /dev/null
+++ b/src/sdl/CMakeLists.txt
@@ -0,0 +1,276 @@
+# Declare SDL2 interface sources
+
+set(SRB2_CONFIG_SDL2_USEMIXER ON CACHE BOOL "Use SDL2_mixer or regular sdl sound")
+
+if(${SRB2_CONFIG_SDL2_USEMIXER})
+	find_package(SDL2_mixer)
+	if(${SDL2_MIXER_FOUND})
+		set(SRB2_HAVE_MIXER ON)
+		set(SRB2_SDL2_SOUNDIMPL mixer_sound.c)
+	else()
+		message(WARNING "You specified that SDL2_mixer is available, but it was not found. Falling back to sdl sound.")
+		set(SRB2_SDL2_SOUNDIMPL sdl_sound.c)
+	endif()
+else()
+	set(SRB2_SDL2_SOUNDIMPL sdl_sound.c)
+endif()
+
+set(SRB2_SDL2_SOURCES
+	dosstr.c
+	endtxt.c
+	hwsym_sdl.c
+	i_cdmus.c
+	i_main.c
+	i_net.c
+	i_system.c
+	i_ttf.c
+	i_video.c
+	#IMG_xpm.c
+	ogl_sdl.c
+
+	${SRB2_SDL2_SOUNDIMPL}
+)
+
+set(SRB2_SDL2_HEADERS
+	endtxt.h
+	hwsym_sdl.h
+	i_ttf.h
+	ogl_sdl.h
+	sdlmain.h
+)
+
+prepend_sources(SRB2_SDL2_SOURCES)
+prepend_sources(SRB2_SDL2_HEADERS)
+
+# Dependency
+find_package(SDL2)
+
+if(${SDL2_FOUND})
+	set(SRB2_SDL2_TOTAL_SOURCES
+		${SRB2_CORE_SOURCES}
+		${SRB2_CORE_HEADERS}
+		${SRB2_SDL2_SOURCES}
+		${SRB2_SDL2_HEADERS}
+	)
+
+	if(${SRB2_CONFIG_HWRENDER})
+		set(SRB2_SDL2_TOTAL_SOURCES ${SRB2_SDL2_TOTAL_SOURCES}
+			${SRB2_HWRENDER_SOURCES}
+			${SRB2_HWRENDER_HEADERS}
+			${SRB2_R_OPENGL_SOURCES}
+			${SRB2_R_OPENGL_HEADERS}
+		)
+	endif()
+
+	if(${SRB2_CONFIG_HAVE_BLUA})
+		set(SRB2_SDL2_TOTAL_SOURCES ${SRB2_SDL2_TOTAL_SOURCES}
+			${SRB2_LUA_SOURCES}
+			${SRB2_LUA_HEADERS}
+			${SRB2_BLUA_SOURCES}
+			${SRB2_BLUA_HEADERS}
+		)
+	endif()
+
+	if(${SRB2_USEASM})
+		set(SRB2_SDL2_TOTAL_SOURCES ${SRB2_SDL2_TOTAL_SOURCES}
+			${SRB2_NASM_SOURCES}
+		)
+		if(MSVC)
+			set(SRB2_SDL2_TOTAL_SOURCES ${SRB2_SDL2_TOTAL_SOURCES}
+				${SRB2_NASM_OBJECTS}
+			)
+			set_source_files_properties(${SRB2_NASM_OBJECTS} PROPERTIES GENERATED ON)
+		else()
+			list(APPEND SRB2_SDL2_TOTAL_SOURCES ${SRB2_ASM_SOURCES})
+			set_source_files_properties(${SRB2_ASM_SOURCES} PROPERTIES LANGUAGE C)
+			set_source_files_properties(${SRB2_ASM_SOURCES} PROPERTIES COMPILE_FLAGS "-x assembler-with-cpp")
+		endif()
+
+	endif()
+
+	if(${CMAKE_SYSTEM} MATCHES Windows)
+		set(SRB2_SDL2_TOTAL_SOURCES ${SRB2_SDL2_TOTAL_SOURCES}
+			${CMAKE_SOURCE_DIR}/src/win32/win_dbg.c
+			${CMAKE_SOURCE_DIR}/src/win32/Srb2win.rc
+		)
+	endif()
+	if(NOT CLANG)
+		set(SRB2_SDL2_TOTAL_SOURCES ${SRB2_SDL2_TOTAL_SOURCES}
+			${CMAKE_SOURCE_DIR}/src/string.c
+		)
+	endif()
+
+	if(${CMAKE_SYSTEM} MATCHES Darwin)
+		set(MACOSX_BUNDLE_ICON_FILE Srb2mac.icns)
+		set_source_files_properties(macosx/Srb2mac.icns PROPERTIES MACOSX_PACKAGE_LOCATION "Resources")
+		set(SRB2_SDL2_TOTAL_SOURCES ${SRB2_SDL2_TOTAL_SOURCES}
+			macosx/mac_alert.c
+			macosx/mac_alert.h
+			macosx/mac_resources.c
+			macosx/mac_resources.h
+			macosx/Srb2mac.icns
+		)
+	endif()
+
+	if(CLANG)
+		add_executable(${SRB2_SDL2_EXE_NAME} MACOSX_BUNDLE ${SRB2_SDL2_TOTAL_SOURCES})
+		add_framework(CoreFoundation ${SRB2_SDL2_EXE_NAME})
+		add_framework(SDL2 ${SRB2_SDL2_EXE_NAME})
+		add_framework(SDL2_mixer ${SRB2_SDL2_EXE_NAME})
+		target_link_libraries(${SRB2_SDL2_EXE_NAME} PRIVATE
+			${PNG_LIBRARIES}
+			${ZLIB_LIBRARIES}
+			${OPENGL_LIBRARIES}
+		)
+		set_target_properties(${SRB2_SDL2_EXE_NAME} PROPERTIES OUTPUT_NAME "Sonic Robo Blast 2")
+	else()
+		add_executable(${SRB2_SDL2_EXE_NAME} WIN32 ${SRB2_SDL2_TOTAL_SOURCES})
+
+		target_link_libraries(${SRB2_SDL2_EXE_NAME} PRIVATE
+			${SDL2_LIBRARIES}
+			${SDL2_MIXER_LIBRARIES}
+			${PNG_LIBRARIES}
+			${ZLIB_LIBRARIES}
+			${OPENGL_LIBRARIES}
+		)
+
+		if(${CMAKE_SYSTEM} MATCHES Linux)
+			target_link_libraries(${SRB2_SDL2_EXE_NAME} PRIVATE
+				m
+				rt
+			)
+		endif()
+
+	endif()
+
+	if(${SRB2_USEASM})
+		if(${SRB2_CONFIG_YASM})
+			set(ASM_ASSEMBLER_TEMP ${CMAKE_ASM_YASM_COMPILER})
+			set(ASM_ASSEMBLER_OBJFORMAT ${CMAKE_ASM_YASM_OBJECT_FORMAT})
+			set_source_files_properties(${SRB2_NASM_SOURCES} LANGUAGE ASM_YASM)
+		else()
+			set(ASM_ASSEMBLER_TEMP ${CMAKE_ASM_NASM_COMPILER})
+			set(ASM_ASSEMBLER_OBJFORMAT ${CMAKE_ASM_NASM_OBJECT_FORMAT})
+			set_source_files_properties(${SRB2_NASM_SOURCES} LANGUAGE ASM_NASM)
+		endif()
+
+		if(MSVC)
+			# using assembler with msvc doesn't work, must do it manually
+			foreach(ASMFILE ${SRB2_NASM_SOURCES})
+				get_filename_component(ASMFILE_NAME ${ASMFILE} NAME_WE)
+				set(ASMFILE_NAME ${ASMFILE_NAME}.obj)
+				add_custom_command(TARGET ${SRB2_SDL2_EXE_NAME} PRE_LINK
+					COMMAND ${ASM_ASSEMBLER_TEMP} ARGS -f ${ASM_ASSEMBLER_OBJFORMAT} -o ${CMAKE_CURRENT_BINARY_DIR}/${ASMFILE_NAME} ${ASMFILE}
+					COMMENT "assemble ${ASMFILE_NAME}."
+				)
+			endforeach()
+		endif()
+	endif()
+
+	set_target_properties(${SRB2_SDL2_EXE_NAME} PROPERTIES VERSION ${SRB2_VERSION})
+
+	if(${CMAKE_SYSTEM} MATCHES Windows)
+		target_link_libraries(${SRB2_SDL2_EXE_NAME} PRIVATE
+			ws2_32
+		)
+		target_compile_options(${SRB2_SDL2_EXE_NAME} PRIVATE
+			-U_WINDOWS
+		)
+	endif()
+
+	if(MSVC)
+		find_package(SDL2_MAIN REQUIRED)
+		target_link_libraries(${SRB2_SDL2_EXE_NAME} PRIVATE
+			${SDL2_MAIN_LIBRARIES}
+		)
+		target_compile_options(${SRB2_SDL2_EXE_NAME} PRIVATE
+			/Umain
+			/D_CRT_SECURE_NO_WARNINGS # something about string functions.
+			/D_CRT_NONSTDC_NO_DEPRECATE
+			/DSDLMAIN
+			/D_WINSOCK_DEPRECATED_NO_WARNINGS # Don't care
+		)
+	endif()
+
+	target_include_directories(${SRB2_SDL2_EXE_NAME} PRIVATE
+		${SDL2_INCLUDE_DIRS}
+		${SDL2_MIXER_INCLUDE_DIRS}
+		${PNG_INCLUDE_DIRS}
+		${ZLIB_INCLUDE_DIRS}
+		${OPENGL_INCLUDE_DIRS}
+	)
+
+	if(${SRB2_HAVE_MIXER})
+		target_compile_definitions(${SRB2_SDL2_EXE_NAME} PRIVATE -DHAVE_MIXER -DSOUND=SOUND_MIXER)
+	endif()
+
+	target_compile_definitions(${SRB2_SDL2_EXE_NAME} PRIVATE
+		-DHAVE_SDL
+	)
+
+	## strip debug symbols into separate file when using gcc
+	if(CMAKE_COMPILER_IS_GNUCC)
+		if(${CMAKE_BUILD_TYPE} MATCHES Debug)
+			message(STATUS "Will make separate debug symbols in *.debug")
+			add_custom_command(TARGET ${SRB2_SDL2_EXE_NAME} POST_BUILD
+				COMMAND ${OBJCOPY} --only-keep-debug $<TARGET_FILE:${SRB2_SDL2_EXE_NAME}> $<TARGET_FILE:${SRB2_SDL2_EXE_NAME}>.debug
+				COMMAND ${OBJCOPY} --strip-debug $<TARGET_FILE:${SRB2_SDL2_EXE_NAME}>
+				COMMAND ${OBJCOPY} --add-gnu-debuglink=$<TARGET_FILE_NAME:${SRB2_SDL2_EXE_NAME}>.debug $<TARGET_FILE:${SRB2_SDL2_EXE_NAME}>
+			)
+		endif()
+	endif()
+
+	#### Installation ####
+	if (CLANG)
+		install(TARGETS ${SRB2_SDL2_EXE_NAME}
+			BUNDLE DESTINATION .
+		)
+	else()
+		install(TARGETS ${SRB2_SDL2_EXE_NAME} ${SRB2_SDL2_EXE_NAME}
+			RUNTIME DESTINATION .
+		)
+	endif()
+
+	if(${CMAKE_SYSTEM} MATCHES Windows)
+		set(win_extra_dll_list "")
+		macro(getwinlib dllname defaultname)
+			find_library(SRB2_SDL2_DLL_${dllname} "${defaultname}")
+			list(APPEND win_extra_dll_list ${SRB2_SDL2_DLL_${dllname}})
+		endmacro()
+		getwinlib(SDL2 "SDL2.dll")
+		if(${SRB2_CONFIG_SDL2_USEMIXER})
+			getwinlib(SDL2_mixer "SDL2_mixer.dll")
+			getwinlib(libmikmod-2 "libmikmod-2.dll")
+			getwinlib(libogg_0 "libogg-0.dll")
+			getwinlib(libvorbis_0 "libvorbis-0.dll")
+			getwinlib(libvorbisfile_3 "libvorbisfile-3.dll")
+			getwinlib(smpeg2 "smpeg2.dll")
+		endif()
+		if(${SRB2_CONFIG_HAVE_GME})
+			getwinlib(libgme "libgme.dll")
+		endif()
+
+		install(PROGRAMS
+			${win_extra_dll_list}
+			DESTINATION .
+		)
+
+		# We also want to copy those DLLs to build directories on MSVC.
+		# So we'll add a post_build step.
+		copy_files_to_build_dir(${SRB2_SDL2_EXE_NAME} win_extra_dll_list)
+	endif()
+
+	
+	# Mac bundle fixup
+	if(CLANG)
+		install(CODE "
+			include(BundleUtilities)
+			fixup_bundle(\"${CMAKE_INSTALL_PREFIX}/Sonic Robo Blast 2.app\"
+				\"\"
+				/Library/Frameworks
+			)"
+		)
+	endif()
+else()
+	message(WARNING "SDL2 wasn't found, so ${SRB2_SDL2_EXE_NAME} won't be available")
+endif()
diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c
index 8675301e826a347eb989ee2e3015ca70ffc8f7f5..567611ec5ea76e8121f71f3816e9c7649711484a 100644
--- a/src/sdl/i_system.c
+++ b/src/sdl/i_system.c
@@ -20,6 +20,8 @@
 /// \file
 /// \brief SRB2 system stuff for SDL
 
+#include "config.h"
+
 #ifndef _WIN32_WCE
 #include <signal.h>
 #endif
@@ -145,6 +147,10 @@ void __set_fpscr(long); // in libgcc / kernel's startup.s?
 #define O_BINARY 0
 #endif
 
+#ifdef __APPLE__
+#include "macosx/mac_resources.h"
+#endif
+
 // Locations for searching the srb2.srb
 #ifdef _arch_dreamcast
 #define DEFAULTWADLOCATION1 "/cd"
@@ -661,17 +667,9 @@ static void I_StartupConsole(void)
 {
 	HANDLE ci, co;
 	const INT32 ded = M_CheckParm("-dedicated");
-#ifdef SDLMAIN
 	BOOL gotConsole = FALSE;
 	if (M_CheckParm("-console") || ded)
 		gotConsole = AllocConsole();
-#else
-	BOOL gotConsole = TRUE;
-	if (M_CheckParm("-detachconsole"))
-	{
-		FreeConsole();
-		gotConsole = AllocConsole();
-	}
 #ifdef _DEBUG
 	else if (M_CheckParm("-noconsole") && !ded)
 #else
@@ -681,7 +679,6 @@ static void I_StartupConsole(void)
 		FreeConsole();
 		gotConsole = FALSE;
 	}
-#endif
 
 	if (gotConsole)
 	{
@@ -1661,7 +1658,7 @@ void I_UpdateMumble(const mobj_t *mobj, const listener_t listener)
 		return;
 
 	if(mumble->uiVersion != 2) {
-		wcsncpy(mumble->name, L"SRB2 "VERSIONSTRING, 256);
+		wcsncpy(mumble->name, L"SRB2 "VERSIONSTRINGW, 256);
 		wcsncpy(mumble->description, L"Sonic Robo Blast 2 with integrated Mumble Link support.", 2048);
 		mumble->uiVersion = 2;
 	}
@@ -2758,6 +2755,28 @@ static const char *locateWad(void)
 	if (isWadPathOk(returnWadPath))
 		return NULL;
 #endif
+    
+    
+#ifdef CMAKECONFIG
+#ifndef NDEBUG
+    I_OutputMsg(","CMAKE_ASSETS_DIR);
+    strcpy(returnWadPath, CMAKE_ASSETS_DIR);
+    if (isWadPathOk(returnWadPath))
+    {
+        return returnWadPath;
+    }
+#endif
+#endif
+    
+#ifdef __APPLE__
+    OSX_GetResourcesPath(returnWadPath);
+    I_OutputMsg(",%s", returnWadPath);
+    if (isWadPathOk(returnWadPath))
+    {
+        return returnWadPath;
+    }
+    
+#endif
 
 	// examine default dirs
 #ifdef DEFAULTWADLOCATION1
diff --git a/src/sdl/macosx/mac_resources.c b/src/sdl/macosx/mac_resources.c
new file mode 100644
index 0000000000000000000000000000000000000000..dacc8014ba8da8fcd48ccbfe56a7772c4ec6c0fc
--- /dev/null
+++ b/src/sdl/macosx/mac_resources.c
@@ -0,0 +1,31 @@
+#include "mac_resources.h"
+#include <string.h>
+
+#include <CoreFoundation/CoreFoundation.h>
+
+void OSX_GetResourcesPath(char * buffer)
+{
+    CFBundleRef mainBundle;
+    mainBundle = CFBundleGetMainBundle();
+    if (mainBundle)
+    {
+        CFURLRef appUrlRef = CFBundleCopyBundleURL(mainBundle);
+        CFStringRef macPath = CFURLCopyFileSystemPath(appUrlRef, kCFURLPOSIXPathStyle);
+        CFStringRef resources = CFStringCreateWithCString(kCFAllocatorMalloc, "/Contents/Resources", kCFStringEncodingASCII);
+        const void* rawarray[2] = {macPath, resources};
+        CFArrayRef array = CFArrayCreate(kCFAllocatorMalloc, rawarray, 2, NULL);
+        CFStringRef separator = CFStringCreateWithCString(kCFAllocatorMalloc, "", kCFStringEncodingASCII);
+        CFStringRef fullPath = CFStringCreateByCombiningStrings(kCFAllocatorMalloc, array, separator);
+        const char * path = CFStringGetCStringPtr(fullPath, kCFStringEncodingASCII);
+        strcpy(buffer, path);
+        CFRelease(fullPath);
+        path = NULL;
+        CFRelease(array);
+        CFRelease(resources);
+        CFRelease(macPath);
+        CFRelease(appUrlRef);
+        //CFRelease(mainBundle);
+        CFRelease(separator);
+    }
+
+}
\ No newline at end of file
diff --git a/src/sdl/macosx/mac_resources.h b/src/sdl/macosx/mac_resources.h
new file mode 100644
index 0000000000000000000000000000000000000000..727ac9f6b091cec94d0cc10c23de7ef8580d9c4f
--- /dev/null
+++ b/src/sdl/macosx/mac_resources.h
@@ -0,0 +1,5 @@
+#ifndef __MAC_RESOURCES_H__
+#define __MAC_RESOURCES_H__
+
+void OSX_GetResourcesPath(char * buffer);
+#endif
\ No newline at end of file
diff --git a/src/sdl/sdlmain.h b/src/sdl/sdlmain.h
index af4e48f750c0533c8db014720cba663ce68665a3..7ac32f4b3bf0268be5aaada164426a207195d790 100644
--- a/src/sdl/sdlmain.h
+++ b/src/sdl/sdlmain.h
@@ -25,7 +25,11 @@ extern SDL_bool framebuffer;
 #include "../m_fixed.h"
 
 // SDL2 stub macro
-#define SDL2STUB(name) CONS_Printf("SDL2: stubbed: %s:%d\n", __func__, __LINE__)
+#ifdef _MSC_VER
+#define SDL2STUB() CONS_Printf("SDL2: stubbed: %s:%d\n", __FUNCTION__, __LINE__)
+#else
+#define SDL2STUB() CONS_Printf("SDL2: stubbed: %s:%d\n", __func__, __LINE__)
+#endif
 
 /**	\brief	The JoyInfo_s struct
 
diff --git a/src/win32/CMakeLists.txt b/src/win32/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..94c198299add6162c63a69324207ba048d73cf01
--- /dev/null
+++ b/src/win32/CMakeLists.txt
@@ -0,0 +1,11 @@
+add_executable(${SRB2_WIN_EXE_NAME} EXCLUDE_FROM_ALL
+	${SRB2_CORE_SOURCES}
+	${SRB2_CORE_HEADERS}
+	${SRB2_LUA_SOURCES}
+	${SRB2_LUA_HEADERS}
+	${SRB2_BLUA_SOURCES}
+	${SRB2_BLUA_HEADERS})
+
+target_compile_definitions(${SRB2_WIN_EXE_NAME} PRIVATE
+	-D_WINDOWS
+)
\ No newline at end of file