From d7015d14929337b003d33d5fff2a2a840b5e4f16 Mon Sep 17 00:00:00 2001
From: Ronald Kinard <furyhunter600@gmail.com>
Date: Sun, 1 Feb 2015 21:25:02 -0600
Subject: [PATCH] cmake: Fix nasm/add yasm support

Tested to work on MSVC, mingw-gcc
---
 cmake/Modules/CMakeASM_YASMInformation.cmake  | 46 +++++++++++++++++++
 .../CMakeDetermineASM_YASMCompiler.cmake      | 27 +++++++++++
 cmake/Modules/CMakeTestASM_YASMCompiler.cmake | 23 ++++++++++
 src/CMakeLists.txt                            | 33 +++++++++++--
 src/sdl/CMakeLists.txt                        | 35 ++++++++++++++
 5 files changed, 161 insertions(+), 3 deletions(-)
 create mode 100644 cmake/Modules/CMakeASM_YASMInformation.cmake
 create mode 100644 cmake/Modules/CMakeDetermineASM_YASMCompiler.cmake
 create mode 100644 cmake/Modules/CMakeTestASM_YASMCompiler.cmake

diff --git a/cmake/Modules/CMakeASM_YASMInformation.cmake b/cmake/Modules/CMakeASM_YASMInformation.cmake
new file mode 100644
index 0000000000..1765180853
--- /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 0000000000..a5e7c9e580
--- /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 0000000000..745f7125c4
--- /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/src/CMakeLists.txt b/src/CMakeLists.txt
index b1e8e6f57b..6c57440f1b 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -198,13 +198,32 @@ set(SRB2_R_OPENGL_HEADERS
 prepend_sources(SRB2_R_OPENGL_SOURCES)
 prepend_sources(SRB2_R_OPENGL_HEADERS)
 
+set(SRB2_ASM_SOURCES
+	vid_copy.s
+)
+
 set(SRB2_NASM_SOURCES
-	tamp_mmx.nas
+	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")
@@ -218,6 +237,8 @@ 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.")
 
@@ -348,7 +369,13 @@ if(${SRB2_CONFIG_HWRENDER} AND ${SRB2_CONFIG_STATIC_OPENGL})
 endif()
 
 if(${SRB2_CONFIG_USEASM})
-	enable_language(ASM-NASM)
+	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()
@@ -365,7 +392,7 @@ endif()
 # Compatibility flag with later versions of GCC
 # We should really fix our code to not need this
 if(NOT CLANG AND NOT MSVC)
-	add_compile_options(-mno-ms-bitfields)
+	set(CMAKE_C_FLAGS ${CMAKE_C_FLAGS} -mno-ms-bitfields)
 endif()
 
 add_definitions(-DCMAKECONFIG)
diff --git a/src/sdl/CMakeLists.txt b/src/sdl/CMakeLists.txt
index 7df73acff9..dc93b6e480 100644
--- a/src/sdl/CMakeLists.txt
+++ b/src/sdl/CMakeLists.txt
@@ -75,6 +75,17 @@ if(${SDL2_FOUND})
 		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)
@@ -132,6 +143,30 @@ if(${SDL2_FOUND})
 
 	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)
-- 
GitLab