diff --git a/CMakeLists.txt b/CMakeLists.txt index 0cffa367e..b8abe511d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,173 +1,124 @@ -# -# Simple CMakeLists for Sonic Robo Blast 2 -# -PROJECT(SRB2) +cmake_minimum_required(VERSION 3.0) +project(SRB2 + VERSION 2.1.14 + LANGUAGES C) -CMAKE_MINIMUM_REQUIRED(VERSION 2.8) +# Set up CMAKE path +set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules/") -# -# Dependencies -# -FIND_PACKAGE(SDL) -FIND_PACKAGE(SDL_mixer) -FIND_PACKAGE(PNG) +### Useful functions -# -# Common stuff -# +# 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() -# 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) +# 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() -SET(SDL_DIR sdl) # may be set to SDL2 optionally +# 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() -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 -) +# 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() -# -# Platform-specific stuff -# +if(MSVC) + message(WARNING "!! MSVC BUILDS OF SRB2 CANNOT PLAY MULTIPLAYER !! You're more than welcome to try and fix this!") +endif() -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) +# OS macros +if (UNIX) + add_definitions(-DUNIXCOMMON) +endif() -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") +if(CMAKE_COMPILER_IS_GNUCC) + find_program(OBJCOPY objcopy) +endif() -# -# 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}) +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 000000000..3ce133c6a --- /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 000000000..176518085 --- /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 " -f ${CMAKE_ASM_YASM_OBJECT_FORMAT} -o ") + +# 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 000000000..a5e7c9e58 --- /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 000000000..745f7125c --- /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 000000000..3b0c68de7 --- /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 000000000..faa556a88 --- /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 000000000..280e51e2e --- /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 000000000..59b4823ed --- /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 000000000..de4015b0d --- /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 000000000..f6800aa7b --- /dev/null +++ b/cmake/Modules/LibFindMacros.cmake @@ -0,0 +1,265 @@ +# Version 2.2 +# Public Domain, originally written by Lasse Kärkkäinen +# 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( [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( FIND_PATH [other args] FIND_LIBRARY [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 _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} \"\" 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 "") + 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 000000000..6c57440f1 --- /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 d4cc64a4b..a1a8804e7 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 cd6bfd9bb..a4dc5b0f9 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 000000000..6e7c64da3 --- /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 95808b274..a959a8632 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 d14cd5ddb..4a6d6e576 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 6bc563527..ff4199775 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 69e956216..8e7c622c4 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 000000000..b4eeeeb5f --- /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 $ $.debug + COMMAND ${OBJCOPY} --strip-debug $ + COMMAND ${OBJCOPY} --add-gnu-debuglink=$.debug $ + ) + 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 8675301e8..567611ec5 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 #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 000000000..dacc8014b --- /dev/null +++ b/src/sdl/macosx/mac_resources.c @@ -0,0 +1,31 @@ +#include "mac_resources.h" +#include + +#include + +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 000000000..727ac9f6b --- /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 af4e48f75..7ac32f4b3 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 000000000..94c198299 --- /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