summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore7
-rw-r--r--CMakeLists.txt226
-rw-r--r--cmake/AddCustomXXXTimestamp.cmake145
-rw-r--r--cmake/CompileFlags.cmake120
-rw-r--r--cmake/CreateGrfCommand.cmake50
-rw-r--r--cmake/CreateRegression.cmake86
-rw-r--r--cmake/Endian.cmake14
-rw-r--r--cmake/FindAllegro.cmake65
-rw-r--r--cmake/FindEditbin.cmake13
-rw-r--r--cmake/FindFluidsynth.cmake65
-rw-r--r--cmake/FindFontconfig.cmake101
-rw-r--r--cmake/FindGrfcodec.cmake13
-rw-r--r--cmake/FindICU.cmake64
-rw-r--r--cmake/FindIconv.cmake133
-rw-r--r--cmake/FindLZO.cmake89
-rw-r--r--cmake/FindSSE.cmake17
-rw-r--r--cmake/FindXDG_basedir.cmake65
-rw-r--r--cmake/FindXaudio2.cmake18
-rw-r--r--cmake/LinkPackage.cmake18
-rw-r--r--cmake/Options.cmake84
-rw-r--r--cmake/SourceList.cmake63
-rw-r--r--cmake/Static.cmake14
-rw-r--r--cmake/scripts/FindVersion.cmake134
-rw-r--r--media/baseset/CMakeLists.txt4
-rw-r--r--media/baseset/openttd/CMakeLists.txt6
-rw-r--r--media/baseset/orig_extra/CMakeLists.txt6
-rw-r--r--os/windows/openttd.manifest29
-rw-r--r--src/3rdparty/CMakeLists.txt3
-rw-r--r--src/3rdparty/md5/CMakeLists.txt4
-rw-r--r--src/3rdparty/os2/CMakeLists.txt7
-rw-r--r--src/3rdparty/squirrel/CMakeLists.txt3
-rw-r--r--src/3rdparty/squirrel/include/CMakeLists.txt6
-rw-r--r--src/3rdparty/squirrel/sqstdlib/CMakeLists.txt4
-rw-r--r--src/3rdparty/squirrel/squirrel/CMakeLists.txt30
-rw-r--r--src/CMakeLists.txt479
-rw-r--r--src/ai/CMakeLists.txt14
-rw-r--r--src/blitter/CMakeLists.txt55
-rw-r--r--src/core/CMakeLists.txt30
-rw-r--r--src/core/endian_type.hpp28
-rw-r--r--src/depend/depend.cpp1084
-rw-r--r--src/game/CMakeLists.txt14
-rw-r--r--src/lang/CMakeLists.txt122
-rw-r--r--src/linkgraph/CMakeLists.txt22
-rw-r--r--src/misc/CMakeLists.txt14
-rw-r--r--src/music/CMakeLists.txt54
-rw-r--r--src/network/CMakeLists.txt28
-rw-r--r--src/network/core/CMakeLists.txt27
-rw-r--r--src/os/CMakeLists.txt4
-rw-r--r--src/os/macosx/CMakeLists.txt11
-rw-r--r--src/os/os2/CMakeLists.txt4
-rw-r--r--src/os/unix/CMakeLists.txt9
-rw-r--r--src/os/windows/CMakeLists.txt8
-rw-r--r--src/os/windows/ottdres.rc.in14
-rw-r--r--src/pathfinder/CMakeLists.txt9
-rw-r--r--src/pathfinder/npf/CMakeLists.txt8
-rw-r--r--src/pathfinder/yapf/CMakeLists.txt20
-rw-r--r--src/rev.cpp.in12
-rw-r--r--src/saveload/CMakeLists.txt43
-rw-r--r--src/script/CMakeLists.txt23
-rw-r--r--src/script/api/CMakeLists.txt140
-rw-r--r--src/settingsgen/CMakeLists.txt13
-rw-r--r--src/sound/CMakeLists.txt37
-rw-r--r--src/spriteloader/CMakeLists.txt5
-rw-r--r--src/stdafx.h11
-rw-r--r--src/strgen/CMakeLists.txt25
-rw-r--r--src/table/CMakeLists.txt83
-rw-r--r--src/video/CMakeLists.txt35
-rw-r--r--src/video/cocoa/CMakeLists.txt8
-rw-r--r--src/widgets/CMakeLists.txt61
69 files changed, 3116 insertions, 1144 deletions
diff --git a/.gitignore b/.gitignore
index 3e74133df..156a9f7a6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -21,18 +21,13 @@ bin/scripts/*
!bin/scripts/*.example
!bin/scripts/readme.txt
-*.aps
bundle/*
bundles/*
docs/aidocs/*
docs/gamedocs/*
docs/source/*
-.kdev4
-.kdev4/*
-*.kdev4
media/openttd.desktop
media/openttd.desktop.install
-objs/*
projects/.vs
projects/Debug
projects/Release
@@ -44,8 +39,6 @@ projects/*.vcproj.*.user
projects/*.vcxproj.user
projects/*.VC.db
projects/*.VC.opendb
-src/rev.cpp
-src/os/windows/ottdres.rc
/Makefile*
!/Makefile.msvc
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 000000000..c1ffa9ecc
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,226 @@
+cmake_minimum_required(VERSION 3.5)
+
+project(OpenTTD)
+
+if (CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR)
+ message(FATAL_ERROR "In-source builds not allowed. Please run \"cmake ..\" from the bin directory")
+endif (CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR)
+
+set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake")
+
+include(Options)
+set_options()
+set_directory_options()
+
+include(Static)
+set_static_if_needed()
+
+# Prefer -pthread over -lpthread, which is often the better option of the two.
+set(CMAKE_THREAD_PREFER_PTHREAD YES)
+# Make sure we have Threads available.
+find_package(Threads REQUIRED)
+
+find_package(ZLIB)
+find_package(LibLZMA)
+find_package(LZO)
+find_package(PNG)
+if (NOT WIN32)
+ find_package(SDL2)
+ if (NOT SDL2_FOUND)
+ find_package(SDL)
+ endif( NOT SDL2_FOUND)
+ find_package(Allegro)
+ find_package(Fluidsynth)
+ find_package(Freetype)
+ find_package(Fontconfig)
+ find_package(ICU OPTIONAL_COMPONENTS i18n lx)
+ find_package(XDG_basedir)
+endif (NOT WIN32)
+if (APPLE)
+ find_package(Iconv)
+
+ find_library(AUDIOTOOLBOX_LIBRARY AudioToolbox)
+ find_library(AUDIOUNIT_LIBRARY AudioUnit)
+ find_library(COCOA_LIBRARY Cocoa)
+endif (APPLE)
+
+if (MSVC)
+ find_package(Editbin REQUIRED)
+endif (MSVC)
+
+find_package(SSE)
+find_package(Xaudio2)
+
+find_package(Grfcodec)
+
+# IPO is only properly supported from CMake 3.9. Despite the fact we are
+# CMake 3.5, still enable IPO if we detect we are 3.9+.
+if (POLICY CMP0069)
+ cmake_policy(SET CMP0069 NEW)
+ include(CheckIPOSupported)
+ check_ipo_supported(RESULT IPO_FOUND)
+endif (POLICY CMP0069)
+
+show_options()
+
+if (UNIX AND NOT APPLE AND NOT OPTION_DEDICATED)
+ if (NOT SDL_FOUND AND NOT SDL2_FOUND)
+ message(FATAL_ERROR "SDL or SDL2 is required for this platform")
+ endif (NOT SDL_FOUND AND NOT SDL2_FOUND)
+endif (UNIX AND NOT APPLE AND NOT OPTION_DEDICATED)
+if (APPLE)
+ if (NOT AUDIOTOOLBOX_LIBRARY)
+ message(FATAL_ERROR "AudioToolbox is required for this platform")
+ endif (NOT AUDIOTOOLBOX_LIBRARY)
+ if (NOT AUDIOUNIT_LIBRARY)
+ message(FATAL_ERROR "AudioUnit is required for this platform")
+ endif (NOT AUDIOUNIT_LIBRARY)
+ if (NOT COCOA_LIBRARY)
+ message(FATAL_ERROR "Cocoa is required for this platform")
+ endif (NOT COCOA_LIBRARY)
+endif (APPLE)
+
+if (MSVC)
+ # C++17 for MSVC
+ set(CMAKE_CXX_STANDARD 17)
+else (MSVC)
+ # C++11 for all other targets
+ set(CMAKE_CXX_STANDARD 11)
+endif (MSVC)
+
+set(CMAKE_CXX_STANDARD_REQUIRED YES)
+set(CMAKE_CXX_EXTENSIONS NO)
+
+list(APPEND GENERATED_SOURCE_FILES "${CMAKE_BINARY_DIR}/generated/rev.cpp")
+if (WIN32)
+ list(APPEND GENERATED_SOURCE_FILES "${CMAKE_BINARY_DIR}/generated/ottdres.rc")
+endif (WIN32)
+
+# Generate a target to determine version, which is execute every 'make' run
+add_custom_target(find_version
+ ${CMAKE_COMMAND}
+ -DFIND_VERSION_BINARY_DIR=${CMAKE_BINARY_DIR}/generated
+ -DCPACK_BINARY_DIR=${CMAKE_BINARY_DIR}
+ -P "${CMAKE_SOURCE_DIR}/cmake/scripts/FindVersion.cmake"
+ WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
+ BYPRODUCTS ${GENERATED_SOURCE_FILES}
+)
+
+include(SourceList)
+include(Endian)
+add_endian_definition()
+
+# Needed by rev.cpp
+include_directories(${CMAKE_SOURCE_DIR}/src)
+# Needed by everything that uses Squirrel
+include_directories(${CMAKE_SOURCE_DIR}/src/3rdparty/squirrel/include)
+
+include(CompileFlags)
+compile_flags()
+
+add_executable(openttd WIN32 ${GENERATED_SOURCE_FILES})
+# All other files are added via target_sources()
+
+include(AddCustomXXXTimestamp)
+add_subdirectory(${CMAKE_SOURCE_DIR}/src)
+add_subdirectory(${CMAKE_SOURCE_DIR}/media/baseset)
+
+add_dependencies(openttd
+ find_version)
+
+target_link_libraries(openttd
+ openttd::languages
+ openttd::settings
+ openttd::basesets
+ Threads::Threads
+)
+
+if (IPO_FOUND)
+ set_target_properties(openttd PROPERTIES INTERPROCEDURAL_OPTIMIZATION_RELEASE True)
+ set_target_properties(openttd PROPERTIES INTERPROCEDURAL_OPTIMIZATION_MINSIZEREL True)
+ set_target_properties(openttd PROPERTIES INTERPROCEDURAL_OPTIMIZATION_RELWITHDEBINFO True)
+endif (IPO_FOUND)
+set_target_properties(openttd PROPERTIES VS_DEBUGGER_WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}/bin")
+process_compile_flags()
+
+if (APPLE OR UNIX)
+ add_definitions(-DUNIX)
+endif (APPLE OR UNIX)
+
+include(LinkPackage)
+link_package(PNG TARGET PNG::PNG ENCOURAGED)
+link_package(ZLIB TARGET ZLIB::ZLIB ENCOURAGED)
+link_package(LIBLZMA TARGET LibLZMA::LibLZMA ENCOURAGED)
+link_package(LZO ENCOURAGED)
+link_package(XDG_basedir)
+
+if (NOT OPTION_DEDICATED)
+ link_package(Fluidsynth)
+ link_package(SDL)
+ link_package(SDL2)
+ link_package(Allegro)
+ link_package(FREETYPE TARGET Freetype::Freetype)
+ link_package(Fontconfig TARGET Fontconfig::Fontconfig)
+ link_package(ICU_lx)
+ link_package(ICU_i18n)
+endif (NOT OPTION_DEDICATED)
+
+if (APPLE)
+ link_package(Iconv TARGET Iconv::Iconv)
+
+ target_link_libraries(openttd
+ ${AUDIOTOOLBOX_LIBRARY}
+ ${AUDIOUNIT_LIBRARY}
+ ${COCOA_LIBRARY}
+ )
+
+ add_definitions(
+ -DWITH_COCOA
+ -DENABLE_COCOA_QUARTZ
+ )
+endif (APPLE)
+
+if (NOT PERSONAL_DIR STREQUAL "(not set)")
+ add_definitions(
+ -DWITH_PERSONAL_DIR
+ -DPERSONAL_DIR="${PERSONAL_DIR}"
+ )
+endif (NOT PERSONAL_DIR STREQUAL "(not set)")
+
+if (NOT SHARED_DIR STREQUAL "(not set)")
+ add_definitions(
+ -DWITH_SHARED_DIR
+ -DSHARED_DIR="${SHARED_DIR}"
+ )
+endif (NOT SHARED_DIR STREQUAL "(not set)")
+
+if (NOT GLOBAL_DIR STREQUAL "(not set)")
+ add_definitions(
+ -DGLOBAL_DATA_DIR="${GLOBAL_DIR}"
+ )
+endif (NOT GLOBAL_DIR STREQUAL "(not set)")
+
+link_package(SSE)
+
+add_definitions_based_on_options()
+
+if (WIN32)
+ add_definitions(
+ -DUNICODE
+ -D_UNICODE
+ -DWITH_UNISCRIBE
+ )
+
+ target_link_libraries(openttd
+ ws2_32
+ winmm
+ imm32
+ )
+endif (WIN32)
+
+if (CMAKE_SIZEOF_VOID_P EQUAL 8)
+ add_definitions(-D_SQ64)
+endif (CMAKE_SIZEOF_VOID_P EQUAL 8)
+
+include(CreateRegression)
+create_regression()
diff --git a/cmake/AddCustomXXXTimestamp.cmake b/cmake/AddCustomXXXTimestamp.cmake
new file mode 100644
index 000000000..ca9398873
--- /dev/null
+++ b/cmake/AddCustomXXXTimestamp.cmake
@@ -0,0 +1,145 @@
+macro(_parse_arguments_with_multi_hack ORIGINAL_COMMAND_LINE)
+ # cmake_parse_arguments() put all the MULTIS in a single variable; you
+ # lose the ability to see for example multiple COMMANDs. To be able to
+ # passthrough multiple MULTIS, we add a marker after every MULTI. This
+ # allows us to reassemble the correct amount again before giving it to
+ # the wrapped command with _reassemble_command_line().
+
+ set(COMMAND_LINE "${ORIGINAL_COMMAND_LINE}")
+
+ foreach(MULTI IN LISTS MULTIS)
+ string(REPLACE "${MULTI}" "${MULTI};:::" COMMAND_LINE "${COMMAND_LINE}")
+ endforeach(MULTI)
+
+ cmake_parse_arguments(PARAM "${OPTIONS}" "${SINGLES}" "${MULTIS}" ${COMMAND_LINE})
+endmacro()
+
+macro(_reassemble_command_line)
+ # Reassemble the command line as we original got it.
+ set(NEW_COMMAND_LINE ${PARAM_UNPARSED_ARGUMENTS})
+
+ foreach(OPTION IN LISTS OPTIONS)
+ if (PARAM_${OPTION})
+ list(APPEND NEW_COMMAND_LINE "${OPTION}")
+ endif (PARAM_${OPTION})
+ endforeach(OPTION)
+
+ foreach(SINGLE IN LISTS SINGLES)
+ if (PARAM_${SINGLE})
+ list(APPEND NEW_COMMAND_LINE "${SINGLE}" "${PARAM_${SINGLE}}")
+ endif (PARAM_${SINGLE})
+ endforeach(SINGLE)
+
+ foreach(MULTI IN LISTS MULTIS)
+ if (PARAM_${MULTI})
+ # Replace our special marker with the name of the MULTI again. This
+ # restores for example multiple COMMANDs again.
+ string(REPLACE ":::" "${MULTI}" PARAM_${MULTI} "${PARAM_${MULTI}}")
+ list(APPEND NEW_COMMAND_LINE "${PARAM_${MULTI}}")
+ endif (PARAM_${MULTI})
+ endforeach(MULTI)
+endmacro()
+
+# Generated files can be older than their dependencies, causing useless
+# regenerations. This function replaces each file in OUTPUT with a .timestamp
+# file, adds a command to touch it and move the original file in BYPRODUCTS,
+# before calling add_custom_command().
+#
+# Note: Any add_custom_target() depending on files in original OUTPUT must use
+# add_custom_target_timestamp() instead to have the correct dependencies.
+#
+# add_custom_command_timestamp(OUTPUT output1 [output2 ...]
+# COMMAND command1 [ARGS] [args1...]
+# [COMMAND command2 [ARGS] [args2...] ...]
+# [MAIN_DEPENDENCY depend]
+# [DEPENDS [depends...]]
+# [BYPRODUCTS [files...]]
+# [IMPLICIT_DEPENDS <lang1> depend1
+# [<lang2> depend2] ...]
+# [WORKING_DIRECTORY dir]
+# [COMMENT comment]
+# [VERBATIM] [APPEND] [USES_TERMINAL])
+function(add_custom_command_timestamp)
+ set(OPTIONS VERBATIM APPEND USES_TERMINAL)
+ set(SINGLES MAIN_DEPENDENCY WORKING_DIRECTORY COMMENT)
+ set(MULTIS OUTPUT COMMAND DEPENDS BYPRODUCTS IMPLICIT_DEPENDS)
+
+ _parse_arguments_with_multi_hack("${ARGN}")
+
+ # Create a list of all the OUTPUTs (by removing our magic marker)
+ string(REPLACE ":::;" "" OUTPUTS "${PARAM_OUTPUT}")
+
+ # Reset the OUTPUT and BYPRODUCTS as an empty list (if needed).
+ # Because they are MULTIS, we need to add our special marker here.
+ set(PARAM_OUTPUT ":::")
+ if (NOT PARAM_BYPRODUCTS)
+ set(PARAM_BYPRODUCTS ":::")
+ endif ()
+
+ foreach(OUTPUT IN LISTS OUTPUTS)
+ # For every output, we add a 'cmake -E touch' entry to update the
+ # timestamp on each run.
+ get_filename_component(OUTPUT_FILENAME ${OUTPUT} NAME)
+ string(APPEND PARAM_COMMAND ";:::;${CMAKE_COMMAND};-E;touch;${CMAKE_CURRENT_BINARY_DIR}/${OUTPUT_FILENAME}.timestamp")
+
+ # We change the OUTPUT to a '.timestamp' variant, and make the real
+ # output a byproduct.
+ list(APPEND PARAM_OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${OUTPUT_FILENAME}.timestamp)
+ list(APPEND PARAM_BYPRODUCTS ${OUTPUT})
+
+ # Mark this file as being a byproduct; we use this again with
+ # add_custom_target_timestamp() to know if we should point to the
+ # '.timestamp' variant or not.
+ set_source_files_properties(${OUTPUT} PROPERTIES BYPRODUCT ${CMAKE_CURRENT_BINARY_DIR}/${OUTPUT_FILENAME}.timestamp)
+ endforeach(OUTPUT)
+
+ # Reassemble and call the wrapped command
+ _reassemble_command_line()
+ add_custom_command(${NEW_COMMAND_LINE})
+endfunction(add_custom_command_timestamp)
+
+# Generated files can be older than their dependencies, causing useless
+# regenerations. This function adds a .timestamp file for each file in DEPENDS
+# replaced by add_custom_command_timestamp(), before calling add_custom_target().
+#
+# add_custom_target_timestamp(Name [ALL] [command1 [args1...]]
+# [COMMAND command2 [args2...] ...]
+# [DEPENDS depend depend depend ... ]
+# [BYPRODUCTS [files...]]
+# [WORKING_DIRECTORY dir]
+# [COMMENT comment]
+# [VERBATIM] [USES_TERMINAL]
+# [SOURCES src1 [src2...]])
+function(add_custom_target_timestamp)
+ set(OPTIONS VERBATIM USES_TERMINAL)
+ set(SINGLES WORKING_DIRECTORY COMMENT)
+ set(MULTIS COMMAND DEPENDS BYPRODUCTS SOURCES)
+ # ALL is missing, as the order is important here. It will be picked up
+ # by ${PARAM_UNPARSED_ARGUMENTS} when reassembling the command line.
+
+ _parse_arguments_with_multi_hack("${ARGN}")
+
+ # Create a list of all the DEPENDs (by removing our magic marker)
+ string(REPLACE ":::;" "" DEPENDS "${PARAM_DEPENDS}")
+
+ # Reset the DEPEND as an empty list.
+ # Because it is a MULTI, we need to add our special marker here.
+ set(PARAM_DEPENDS ":::")
+
+ foreach(DEPEND IN LISTS DEPENDS)
+ # Check if the output is produced by add_custom_command_timestamp()
+ get_source_file_property(BYPRODUCT ${DEPEND} BYPRODUCT)
+
+ if (BYPRODUCT STREQUAL "NOTFOUND")
+ # If it is not, just keep it as DEPEND
+ list(APPEND PARAM_DEPENDS "${DEPEND}")
+ else (BYPRODUCT STREQUAL "NOTFOUND")
+ # If it is, the BYPRODUCT property points to the timestamp we want to depend on
+ list(APPEND PARAM_DEPENDS "${BYPRODUCT}")
+ endif (BYPRODUCT STREQUAL "NOTFOUND")
+ endforeach(DEPEND)
+
+ # Reassemble and call the wrapped command
+ _reassemble_command_line()
+ add_custom_target(${NEW_COMMAND_LINE})
+endfunction(add_custom_target_timestamp)
diff --git a/cmake/CompileFlags.cmake b/cmake/CompileFlags.cmake
new file mode 100644
index 000000000..05c19abab
--- /dev/null
+++ b/cmake/CompileFlags.cmake
@@ -0,0 +1,120 @@
+# Macro which contains all bits to setup the compile flags correctly.
+#
+# compile_flags()
+#
+macro(compile_flags)
+ if (MSVC)
+ # Switch to MT (static) instead of MD (dynamic) binary
+
+ # For MSVC two generators are available
+ # - a command line generator (Ninja) using CMAKE_BUILD_TYPE to specify the
+ # configuration of the build tree
+ # - an IDE generator (Visual Studio) using CMAKE_CONFIGURATION_TYPES to
+ # specify all configurations that will be available in the generated solution
+ list(APPEND MSVC_CONFIGS "${CMAKE_BUILD_TYPE}" "${CMAKE_CONFIGURATION_TYPES}")
+
+ # Set usage of static runtime for all configurations
+ foreach(MSVC_CONFIG ${MSVC_CONFIGS})
+ string(TOUPPER "CMAKE_CXX_FLAGS_${MSVC_CONFIG}" MSVC_FLAGS)
+ string(REPLACE "/MD" "/MT" ${MSVC_FLAGS} "${${MSVC_FLAGS}}")
+ endforeach()
+
+ # "If /Zc:rvalueCast is specified, the compiler follows section 5.4 of the
+ # C++11 standard". We need C++11 for the way we use threads.
+ add_compile_options(/Zc:rvalueCast)
+
+ # Add DPI manifest to project; other WIN32 targets get this via ottdres.rc
+ list(APPEND GENERATED_SOURCE_FILES "${CMAKE_SOURCE_DIR}/os/windows/openttd.manifest")
+ endif (MSVC)
+
+ # Add some -D flags for Debug builds. We cannot use add_definitions(), because
+ # it does not appear to support the $<> tags.
+ add_compile_options(
+ "$<$<CONFIG:Debug>:-D_DEBUG>"
+ "$<$<CONFIG:Debug>:-D_FORTIFY_SOURCE=2>"
+ )
+
+ # Prepare a generator that checks if we are not a debug, and don't have asserts
+ # on. We need this later on to set some compile options for stable releases.
+ set(IS_STABLE_RELEASE "$<AND:$<NOT:$<CONFIG:Debug>>,$<NOT:$<BOOL:${OPTION_USE_ASSERTS}>>>")
+
+ if (MSVC)
+ add_compile_options(/W3)
+ elseif (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")
+ add_compile_options(
+ -W
+ -Wall
+ -Wcast-qual
+ -Wextra
+ -Wsign-compare
+ -Wundef
+ -Wpointer-arith
+ -Wwrite-strings
+ -Wredundant-decls
+ -Wformat-security
+ -Wformat=2
+ -Winit-self
+ -Wnon-virtual-dtor
+
+ # Often parameters are unused, which is fine.
+ -Wno-unused-parameter
+ # We use 'ABCD' multichar for SaveLoad chunks identifiers
+ -Wno-multichar
+
+ # Compilers complains about that we break strict-aliasing.
+ # On most places we don't see how to fix it, and it doesn't
+ # break anything. So disable strict-aliasing to make the
+ # compiler all happy.
+ -fno-strict-aliasing
+ )
+
+ add_compile_options(
+ # When we are a stable release (Release build + USE_ASSERTS not set),
+ # assertations are off, which trigger a lot of warnings. We disable
+ # these warnings for these releases.
+ "$<${IS_STABLE_RELEASE}:-Wno-unused-variable>"
+ "$<${IS_STABLE_RELEASE}:-Wno-unused-but-set-parameter>"
+ "$<${IS_STABLE_RELEASE}:-Wno-unused-but-set-variable>"
+ )
+
+ if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
+ include(CheckCXXCompilerFlag)
+ check_cxx_compiler_flag("-flifetime-dse=1" LIFETIME_DSE_FOUND)
+
+ add_compile_options(
+ # GCC 4.2+ automatically assumes that signed overflows do
+ # not occur in signed arithmetics, whereas we are not
+ # sure that they will not happen. It furthermore complains
+ # about its own optimized code in some places.
+ "-fno-strict-overflow"
+
+ # Prevent optimisation supposing enums are in a range specified by the standard
+ # For details, see http://gcc.gnu.org/PR43680
+ "-fno-tree-vrp"
+
+ # -flifetime-dse=2 (default since GCC 6) doesn't play
+ # well with our custom pool item allocator
+ "$<$<BOOL:${LIFETIME_DSE_FOUND}>:-flifetime-dse=1>"
+ )
+ endif (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
+ elseif (CMAKE_CXX_COMPILER_ID STREQUAL "Intel")
+ add_compile_options(
+ -Wall
+ # warning #873: function ... ::operator new ... has no corresponding operator delete ...
+ -wd873
+ # warning #1292: unknown attribute "fallthrough"
+ -wd1292
+ # warning #1899: multicharacter character literal (potential portability problem)
+ -wd1899
+ # warning #2160: anonymous union qualifier is ignored
+ -wd2160
+ )
+ else ()
+ message(FATAL_ERROR "No warning flags are set for this compiler yet; please consider creating a Pull Request to add support for this compiler.")
+ endif ()
+
+ if (NOT WIN32)
+ # rdynamic is used to get useful stack traces from crash reports.
+ set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -rdynamic")
+ endif (NOT WIN32)
+endmacro()
diff --git a/cmake/CreateGrfCommand.cmake b/cmake/CreateGrfCommand.cmake
new file mode 100644
index 000000000..25e599f56
--- /dev/null
+++ b/cmake/CreateGrfCommand.cmake
@@ -0,0 +1,50 @@
+# Macro which contains all bits and pieces to create a single grf file based
+# on NFO and PNG files.
+#
+# create_grf_command()
+#
+function(create_grf_command)
+ set(EXTRA_PNG_SOURCE_FILES ${ARGV})
+
+ get_filename_component(GRF_SOURCE_FOLDER_NAME "${CMAKE_CURRENT_SOURCE_DIR}" NAME)
+ get_filename_component(GRF_BINARY_FILE ${CMAKE_CURRENT_SOURCE_DIR}/../${GRF_SOURCE_FOLDER_NAME}.grf ABSOLUTE)
+ file(GLOB_RECURSE GRF_PNG_SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/*.png)
+ file(GLOB_RECURSE GRF_NFO_SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/*.nfo)
+ set(GRF_PNG_SOURCE_FILES ${GRF_PNG_SOURCE_FILES} ${EXTRA_PNG_SOURCE_FILES})
+
+ # Copy over all the PNG files to the correct folder
+ foreach(GRF_PNG_SOURCE_FILE IN LISTS GRF_PNG_SOURCE_FILES)
+ get_filename_component(GRF_PNG_SOURCE_FILE_NAME "${GRF_PNG_SOURCE_FILE}" NAME)
+ set(GRF_PNG_BINARY_FILE "${CMAKE_CURRENT_BINARY_DIR}/sprites/${GRF_PNG_SOURCE_FILE_NAME}")
+
+ add_custom_command(OUTPUT ${GRF_PNG_BINARY_FILE}
+ COMMAND ${CMAKE_COMMAND} -E copy
+ ${GRF_PNG_SOURCE_FILE}
+ ${GRF_PNG_BINARY_FILE}
+ MAIN_DEPENDENCY ${GRF_PNG_SOURCE_FILE}
+ COMMENT "Copying ${GRF_PNG_SOURCE_FILE_NAME} sprite file"
+ )
+
+ list(APPEND GRF_PNG_BINARY_FILES ${GRF_PNG_BINARY_FILE})
+ endforeach(GRF_PNG_SOURCE_FILE)
+
+ add_custom_command(OUTPUT ${GRF_BINARY_FILE}
+ COMMAND ${CMAKE_COMMAND}
+ -DGRF_SOURCE_FOLDER=${CMAKE_CURRENT_SOURCE_DIR}
+ -DGRF_BINARY_FILE=${GRF_BINARY_FILE}
+ -DNFORENUM_EXECUTABLE=${NFORENUM_EXECUTABLE}
+ -DGRFCODEC_EXECUTABLE=${GRFCODEC_EXECUTABLE}
+ -P ${CMAKE_SOURCE_DIR}/cmake/scripts/CreateGRF.cmake
+ MAIN_DEPENDENCY ${GRF_NFO_SOURCE_FILES}
+ DEPENDS ${GRF_PNG_BINARY_FILES}
+ ${CMAKE_SOURCE_DIR}/cmake/scripts/CreateGRF.cmake
+ WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+ COMMENT "Generating ${GRF_SOURCE_FOLDER_NAME}.grf"
+ )
+
+ # For conviance, if you want to only test building the GRF
+ add_custom_target(${GRF_SOURCE_FOLDER_NAME}.grf
+ DEPENDS
+ ${GRF_BINARY_FILE}
+ )
+endfunction()
diff --git a/cmake/CreateRegression.cmake b/cmake/CreateRegression.cmake
new file mode 100644
index 000000000..443332368
--- /dev/null
+++ b/cmake/CreateRegression.cmake
@@ -0,0 +1,86 @@
+# Macro which contains all bits and pieces to create the regression tests.
+# This creates both a standalone target 'regression', and it integrates with
+# 'ctest'. The first is prefered, as it is more verbose, and takes care of
+# dependencies correctly.
+#
+# create_regression()
+#
+macro(create_regression)
+ # Find all the files in the regression folder; they need to be copied to the
+ # build folder before we can run the regression
+ file(GLOB_RECURSE REGRESSION_SOURCE_FILES ${CMAKE_SOURCE_DIR}/regression/*)
+ foreach(REGRESSION_SOURCE_FILE IN LISTS REGRESSION_SOURCE_FILES)
+ string(REGEX REPLACE "^${CMAKE_SOURCE_DIR}/regression/" "${CMAKE_BINARY_DIR}/ai/" REGRESSION_BINARY_FILE "${REGRESSION_SOURCE_FILE}")
+ string(REGEX REPLACE "^${CMAKE_SOURCE_DIR}/regression/" "" REGRESSION_SOURCE_FILE_NAME "${REGRESSION_SOURCE_FILE}")
+
+ if ("${REGRESSION_SOURCE_FILE_NAME}" STREQUAL "regression.cfg")
+ continue()
+ endif ("${REGRESSION_SOURCE_FILE_NAME}" STREQUAL "regression.cfg")
+
+ add_custom_command(OUTPUT ${REGRESSION_BINARY_FILE}
+ COMMAND ${CMAKE_COMMAND} -E copy
+ ${REGRESSION_SOURCE_FILE}
+ ${REGRESSION_BINARY_FILE}
+ MAIN_DEPENDENCY ${REGRESSION_SOURCE_FILE}
+ COMMENT "Copying ${REGRESSION_SOURCE_FILE_NAME} regression file"
+ )
+
+ list(APPEND REGRESSION_BINARY_FILES ${REGRESSION_BINARY_FILE})
+ endforeach(REGRESSION_SOURCE_FILE)
+
+ # Copy the regression configuration in a special folder, so all autogenerated
+ # folders end up in the same place after running regression.
+ add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/regression/regression.cfg
+ COMMAND ${CMAKE_COMMAND} -E copy
+ ${CMAKE_SOURCE_DIR}/regression/regression.cfg
+ ${CMAKE_BINARY_DIR}/regression/regression.cfg
+ MAIN_DEPENDENCY ${CMAKE_SOURCE_DIR}/regression/regression.cfg
+ COMMENT "Copying ${REGRESSION_SOURCE_FILE_NAME} regression file"
+ )
+ list(APPEND REGRESSION_BINARY_FILES ${CMAKE_BINARY_DIR}/regression/regression.cfg)
+
+ # Create a new target which copies all regression files
+ add_custom_target(regression_files
+ ALL # this is needed because 'make test' doesn't resolve dependencies, and otherwise this is never executed
+ DEPENDS
+ ${REGRESSION_BINARY_FILES}
+ )
+
+ enable_testing()
+
+ # Find all the tests we have, and create a target for them
+ file(GLOB REGRESSION_TESTS ${CMAKE_SOURCE_DIR}/regression/*)
+ foreach(REGRESSION_TEST IN LISTS REGRESSION_TESTS)
+ get_filename_component(REGRESSION_TEST_NAME "${REGRESSION_TEST}" NAME)
+
+ if ("${REGRESSION_TEST_NAME}" STREQUAL "regression.cfg")
+ continue()
+ endif ("${REGRESSION_TEST_NAME}" STREQUAL "regression.cfg")
+
+ add_custom_target(regression_${REGRESSION_TEST_NAME}
+ COMMAND ${CMAKE_COMMAND}
+ -DOPENTTD_EXECUTABLE=$<TARGET_FILE:openttd>
+ -DEDITBIN_EXECUTABLE=${EDITBIN_EXECUTABLE}
+ -DREGRESSION_TEST=${REGRESSION_TEST_NAME}
+ -P "${CMAKE_SOURCE_DIR}/cmake/scripts/Regression.cmake"
+ DEPENDS openttd regression_files
+ WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
+ COMMENT "Running regression test ${REGRESSION_TEST_NAME}"
+ )
+
+ # Also make sure that 'make test' runs the regression
+ add_test(NAME regression_${REGRESSION_TEST_NAME}
+ COMMAND ${CMAKE_COMMAND}
+ -DOPENTTD_EXECUTABLE=$<TARGET_FILE:openttd>
+ -DEDITBIN_EXECUTABLE=${EDITBIN_EXECUTABLE}
+ -DREGRESSION_TEST=${REGRESSION_TEST_NAME}
+ -P "${CMAKE_SOURCE_DIR}/cmake/scripts/Regression.cmake"
+ WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
+
+ list(APPEND REGRESSION_TARGETS regression_${REGRESSION_TEST_NAME})
+ endforeach(REGRESSION_TEST)
+
+ # Create a new target which runs the regression
+ add_custom_target(regression
+ DEPENDS ${REGRESSION_TARGETS})
+endmacro()
diff --git a/cmake/Endian.cmake b/cmake/Endian.cmake
new file mode 100644
index 000000000..00cb97544
--- /dev/null
+++ b/cmake/Endian.cmake
@@ -0,0 +1,14 @@
+# Add the definitions to indicate which endian we are building for.
+#
+# add_endian_definition()
+#
+function(add_endian_definition)
+ include(TestBigEndian)
+ TEST_BIG_ENDIAN(IS_BIG_ENDIAN)
+
+ if (IS_BIG_ENDIAN)
+ add_definitions(-DTTD_ENDIAN=TTD_BIG_ENDIAN)
+ else (IS_BIG_ENDIAN)
+ add_definitions(-DTTD_ENDIAN=TTD_LITTLE_ENDIAN)
+ endif (IS_BIG_ENDIAN)
+endfunction()
diff --git a/cmake/FindAllegro.cmake b/cmake/FindAllegro.cmake
new file mode 100644
index 000000000..85b2ffd39
--- /dev/null
+++ b/cmake/FindAllegro.cmake
@@ -0,0 +1,65 @@
+#[=======================================================================[.rst:
+FindAllegro
+-------
+
+Finds the allegro library.
+
+Result Variables
+^^^^^^^^^^^^^^^^
+
+This will define the following variables:
+
+``Allegro_FOUND``
+ True if the system has the allegro library.
+``Allegro_INCLUDE_DIRS``
+ Include directories needed to use allegro.
+``Allegro_LIBRARIES``
+ Libraries needed to link to allegro.
+``Allegro_VERSION``
+ The version of the allegro library which was found.
+
+Cache Variables
+^^^^^^^^^^^^^^^
+
+The following cache variables may also be set:
+
+``Allegro_INCLUDE_DIR``
+ The directory containing ``allegro.h``.
+``Allegro_LIBRARY``
+ The path to the allegro library.
+
+#]=======================================================================]
+
+find_package(PkgConfig QUIET)
+pkg_check_modules(PC_Allegro QUIET allegro)
+
+find_path(Allegro_INCLUDE_DIR
+ NAMES allegro.h
+ PATHS ${PC_Allegro_INCLUDE_DIRS}
+)
+
+find_library(Allegro_LIBRARY
+ NAMES alleg
+ PATHS ${PC_Allegro_LIBRARY_DIRS}
+)
+
+set(Allegro_VERSION ${PC_Allegro_VERSION})
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(Allegro
+ FOUND_VAR Allegro_FOUND
+ REQUIRED_VARS
+ Allegro_LIBRARY
+ Allegro_INCLUDE_DIR
+ VERSION_VAR Allegro_VERSION
+)
+
+if (Allegro_FOUND)
+ set(Allegro_LIBRARIES ${Allegro_LIBRARY})
+ set(Allegro_INCLUDE_DIRS ${Allegro_INCLUDE_DIR})
+endif ()
+
+mark_as_advanced(
+ Allegro_INCLUDE_DIR
+ Allegro_LIBRARY
+)
diff --git a/cmake/FindEditbin.cmake b/cmake/FindEditbin.cmake
new file mode 100644
index 000000000..363bc0053
--- /dev/null
+++ b/cmake/FindEditbin.cmake
@@ -0,0 +1,13 @@
+# Autodetect editbin. Only useful for MSVC.
+
+get_filename_component(MSVC_COMPILE_DIRECTORY ${CMAKE_CXX_COMPILER} DIRECTORY)
+find_program(
+ EDITBIN_EXECUTABLE editbin.exe
+ HINTS ${MSVC_COMPILE_DIRECTORY}
+)
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(Editbin
+ FOUND_VAR EDITBIN_FOUND
+ REQUIRED_VARS EDITBIN_EXECUTABLE
+)
diff --git a/cmake/FindFluidsynth.cmake b/cmake/FindFluidsynth.cmake
new file mode 100644
index 000000000..063726dbe
--- /dev/null
+++ b/cmake/FindFluidsynth.cmake
@@ -0,0 +1,65 @@
+#[=======================================================================[.rst:
+FindFluidsynth
+-------
+
+Finds the fluidsynth library.
+
+Result Variables
+^^^^^^^^^^^^^^^^
+
+This will define the following variables:
+
+``Fluidsynth_FOUND``
+ True if the system has the fluidsynth library.
+``Fluidsynth_INCLUDE_DIRS``
+ Include directories needed to use fluidsynth.
+``Fluidsynth_LIBRARIES``
+ Libraries needed to link to fluidsynth.
+``Fluidsynth_VERSION``
+ The version of the fluidsynth library which was found.
+
+Cache Variables
+^^^^^^^^^^^^^^^
+
+The following cache variables may also be set:
+
+``Fluidsynth_INCLUDE_DIR``
+ The directory containing ``fluidsynth.h``.
+``Fluidsynth_LIBRARY``
+ The path to the fluidsynth library.
+
+#]=======================================================================]
+
+find_package(PkgConfig QUIET)
+pkg_check_modules(PC_Fluidsynth QUIET fluidsynth)
+
+find_path(Fluidsynth_INCLUDE_DIR
+ NAMES fluidsynth.h
+ PATHS ${PC_Fluidsynth_INCLUDE_DIRS}
+)
+
+find_library(Fluidsynth_LIBRARY
+ NAMES fluidsynth
+ PATHS ${PC_Fluidsynth_LIBRARY_DIRS}
+)
+
+set(Fluidsynth_VERSION ${PC_Fluidsynth_VERSION})
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(Fluidsynth
+ FOUND_VAR Fluidsynth_FOUND
+ REQUIRED_VARS
+ Fluidsynth_LIBRARY
+ Fluidsynth_INCLUDE_DIR
+ VERSION_VAR Fluidsynth_VERSION
+)
+
+if (Fluidsynth_FOUND)
+ set(Fluidsynth_LIBRARIES ${Fluidsynth_LIBRARY})
+ set(Fluidsynth_INCLUDE_DIRS ${Fluidsynth_INCLUDE_DIR})
+endif ()
+
+mark_as_advanced(
+ Fluidsynth_INCLUDE_DIR
+ Fluidsynth_LIBRARY
+)
diff --git a/cmake/FindFontconfig.cmake b/cmake/FindFontconfig.cmake
new file mode 100644
index 000000000..a6f0180b3
--- /dev/null
+++ b/cmake/FindFontconfig.cmake
@@ -0,0 +1,101 @@
+# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+# file Copyright.txt or https://cmake.org/licensing for details.
+
+#[=======================================================================[.rst:
+FindFontconfig
+--------------
+
+Find Fontconfig headers and library.
+
+Imported Targets
+^^^^^^^^^^^^^^^^
+
+``Fontconfig::Fontconfig``
+ The Fontconfig library, if found.
+
+Result Variables
+^^^^^^^^^^^^^^^^
+
+This will define the following variables in your project:
+
+``Fontconfig_FOUND``
+ true if (the requested version of) Fontconfig is available.
+``Fontconfig_VERSION``
+ the version of Fontconfig.
+``Fontconfig_LIBRARIES``
+ the libraries to link against to use Fontconfig.
+``Fontconfig_INCLUDE_DIRS``
+ where to find the Fontconfig headers.
+``Fontconfig_COMPILE_OPTIONS``
+ this should be passed to target_compile_options(), if the
+ target is not used for linking
+
+#]=======================================================================]
+
+
+# use pkg-config to get the directories and then use these values
+# in the FIND_PATH() and FIND_LIBRARY() calls
+find_package(PkgConfig QUIET)
+pkg_check_modules(PKG_FONTCONFIG QUIET fontconfig)
+set(Fontconfig_COMPILE_OPTIONS ${PKG_FONTCONFIG_CFLAGS_OTHER})
+set(Fontconfig_VERSION ${PKG_FONTCONFIG_VERSION})
+
+find_path( Fontconfig_INCLUDE_DIR
+ NAMES
+ fontconfig/fontconfig.h
+ HINTS
+ ${PKG_FONTCONFIG_INCLUDE_DIRS}
+ /usr/X11/include
+)
+
+find_library( Fontconfig_LIBRARY
+ NAMES
+ fontconfig
+ PATHS
+ ${PKG_FONTCONFIG_LIBRARY_DIRS}
+)
+
+if (Fontconfig_INCLUDE_DIR AND NOT Fontconfig_VERSION)
+ file(STRINGS ${Fontconfig_INCLUDE_DIR}/fontconfig/fontconfig.h _contents REGEX "^#define[ \t]+FC_[A-Z]+[ \t]+[0-9]+$")
+ unset(Fontconfig_VERSION)
+ foreach(VPART MAJOR MINOR REVISION)
+ foreach(VLINE ${_contents})
+ if(VLINE MATCHES "^#define[\t ]+FC_${VPART}[\t ]+([0-9]+)$")
+ set(Fontconfig_VERSION_PART "${CMAKE_MATCH_1}")
+ if(Fontconfig_VERSION)
+ string(APPEND Fontconfig_VERSION ".${Fontconfig_VERSION_PART}")
+ else()
+ set(Fontconfig_VERSION "${Fontconfig_VERSION_PART}")
+ endif()
+ endif()
+ endforeach()
+ endforeach()
+endif ()
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(Fontconfig
+ FOUND_VAR
+ Fontconfig_FOUND
+ REQUIRED_VARS
+ Fontconfig_LIBRARY
+ Fontconfig_INCLUDE_DIR
+ VERSION_VAR
+ Fontconfig_VERSION
+)
+
+
+if(Fontconfig_FOUND AND NOT TARGET Fontconfig::Fontconfig)
+ add_library(Fontconfig::Fontconfig UNKNOWN IMPORTED)
+ set_target_properties(Fontconfig::Fontconfig PROPERTIES
+ IMPORTED_LOCATION "${Fontconfig_LIBRARY}"
+ INTERFACE_COMPILE_OPTIONS "${Fontconfig_COMPILE_OPTIONS}"
+ INTERFACE_INCLUDE_DIRECTORIES "${Fontconfig_INCLUDE_DIR}"
+ )
+endif()
+
+mark_as_advanced(Fontconfig_LIBRARY Fontconfig_INCLUDE_DIR)
+
+if(Fontconfig_FOUND)
+ set(Fontconfig_LIBRARIES ${Fontconfig_LIBRARY})
+ set(Fontconfig_INCLUDE_DIRS ${Fontconfig_INCLUDE_DIR})
+endif()
diff --git a/cmake/FindGrfcodec.cmake b/cmake/FindGrfcodec.cmake
new file mode 100644
index 000000000..089f95670
--- /dev/null
+++ b/cmake/FindGrfcodec.cmake
@@ -0,0 +1,13 @@
+# Autodetect grfcodec and nforenum.
+#
+
+find_program(GRFCODEC_EXECUTABLE grfcodec)
+find_program(NFORENUM_EXECUTABLE nforenum)
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(Grfcodec
+ FOUND_VAR GRFCODEC_FOUND
+ REQUIRED_VARS
+ GRFCODEC_EXECUTABLE
+ NFORENUM_EXECUTABLE
+)
diff --git a/cmake/FindICU.cmake b/cmake/FindICU.cmake
new file mode 100644
index 000000000..471e43c1d
--- /dev/null
+++ b/cmake/FindICU.cmake
@@ -0,0 +1,64 @@
+#[=======================================================================[.rst:
+FindICU
+-------
+
+Finds components of the ICU library.
+
+Accepted components are: uc, i18n, le, lx, io
+
+Result Variables
+^^^^^^^^^^^^^^^^
+
+This will define the following variables:
+
+``ICU_FOUND``
+ True if components of ICU library are found.
+``ICU_VERSION``
+ The version of the ICU library which was found.
+``ICU_<c>_FOUND``
+ True if the system has the <c> component of ICU library.
+``ICU_<c>_INCLUDE_DIRS``
+ Include directories needed to use the <c> component of ICU library.
+``ICU_<c>_LIBRARIES``
+ Libraries needed to link to the <c> component of ICU library.
+
+#]=======================================================================]
+
+find_package(PkgConfig QUIET)
+
+set(ICU_KNOWN_COMPONENTS "uc" "i18n" "le" "lx" "io")
+
+foreach(MOD_NAME IN LISTS ICU_FIND_COMPONENTS)
+ if (NOT MOD_NAME IN_LIST ICU_KNOWN_COMPONENTS)
+ message(FATAL_ERROR "Unknown ICU component: ${MOD_NAME}")
+ endif()
+ pkg_check_modules(PC_ICU_${MOD_NAME} QUIET icu-${MOD_NAME})
+
+ # Check the libraries returned by pkg-config really exist.
+ unset(PC_LIBRARIES)
+ foreach(LIBRARY IN LISTS PC_ICU_${MOD_NAME}_LIBRARIES)
+ unset(PC_LIBRARY CACHE)
+ find_library(PC_LIBRARY NAMES ${LIBRARY})
+ if (NOT PC_LIBRARY)
+ unset(PC_ICU_${MOD_NAME}_FOUND)
+ endif()
+ list(APPEND PC_LIBRARIES ${PC_LIBRARY})
+ endforeach()
+ unset(PC_LIBRARY CACHE)
+
+ if (${PC_ICU_${MOD_NAME}_FOUND})
+ set(ICU_COMPONENT_FOUND TRUE)
+ set(ICU_${MOD_NAME}_FOUND TRUE)
+ set(ICU_${MOD_NAME}_LIBRARIES ${PC_LIBRARIES})
+ set(ICU_${MOD_NAME}_INCLUDE_DIRS ${PC_ICU_${MOD_NAME}_INCLUDE_DIRS})
+ set(ICU_VERSION ${PC_ICU_${MOD_NAME}_VERSION})
+ endif()
+endforeach()
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(ICU
+ FOUND_VAR ICU_FOUND
+ REQUIRED_VARS ICU_COMPONENT_FOUND
+ VERSION_VAR ICU_VERSION
+ HANDLE_COMPONENTS
+)
diff --git a/cmake/FindIconv.cmake b/cmake/FindIconv.cmake
new file mode 100644
index 000000000..5185601ab
--- /dev/null
+++ b/cmake/FindIconv.cmake
@@ -0,0 +1,133 @@
+# Distributed under the OSI-approved BSD 3-Clause License. See accompanying
+# file Copyright.txt or https://cmake.org/licensing for details.
+
+#[=======================================================================[.rst:
+FindIconv
+---------
+
+This module finds the ``iconv()`` POSIX.1 functions on the system.
+These functions might be provided in the regular C library or externally
+in the form of an additional library.
+
+The following variables are provided to indicate iconv support:
+
+.. variable:: Iconv_FOUND
+
+ Variable indicating if the iconv support was found.
+
+.. variable:: Iconv_INCLUDE_DIRS
+
+ The directories containing the iconv headers.
+
+.. variable:: Iconv_LIBRARIES
+
+ The iconv libraries to be linked.
+
+.. variable:: Iconv_IS_BUILT_IN
+
+ A variable indicating whether iconv support is stemming from the
+ C library or not. Even if the C library provides `iconv()`, the presence of
+ an external `libiconv` implementation might lead to this being false.
+
+Additionally, the following :prop_tgt:`IMPORTED` target is being provided:
+
+.. variable:: Iconv::Iconv
+
+ Imported target for using iconv.
+
+The following cache variables may also be set:
+
+.. variable:: Iconv_INCLUDE_DIR
+
+ The directory containing the iconv headers.
+
+.. variable:: Iconv_LIBRARY
+
+ The iconv library (if not implicitly given in the C library).
+
+.. note::
+ On POSIX platforms, iconv might be part of the C library and the cache
+ variables ``Iconv_INCLUDE_DIR`` and ``Iconv_LIBRARY`` might be empty.
+
+#]=======================================================================]
+
+include(CMakePushCheckState)
+if(CMAKE_C_COMPILER_LOADED)
+ include(CheckCSourceCompiles)
+elseif(CMAKE_CXX_COMPILER_LOADED)
+ include(CheckCXXSourceCompiles)
+else()
+ # If neither C nor CXX are loaded, implicit iconv makes no sense.
+ set(Iconv_IS_BUILT_IN FALSE)
+endif()
+
+# iconv can only be provided in libc on a POSIX system.
+# If any cache variable is already set, we'll skip this test.
+if(NOT DEFINED Iconv_IS_BUILT_IN)
+ if(UNIX AND NOT DEFINED Iconv_INCLUDE_DIR AND NOT DEFINED Iconv_LIBRARY)
+ cmake_push_check_state(RESET)
+ # We always suppress the message here: Otherwise on supported systems
+ # not having iconv in their C library (e.g. those using libiconv)
+ # would always display a confusing "Looking for iconv - not found" message
+ set(CMAKE_FIND_QUIETLY TRUE)
+ # The following code will not work, but it's sufficient to see if it compiles.
+ # Note: libiconv will define the iconv functions as macros, so CheckSymbolExists
+ # will not yield correct results.
+ set(Iconv_IMPLICIT_TEST_CODE
+ "
+ #include <stddef.h>
+ #include <iconv.h>
+ int main() {
+ char *a, *b;
+ size_t i, j;
+ iconv_t ic;
+ ic = iconv_open(\"to\", \"from\");
+ iconv(ic, &a, &i, &b, &j);
+ iconv_close(ic);
+ }
+ "
+ )
+ if(CMAKE_C_COMPILER_LOADED)
+ check_c_source_compiles("${Iconv_IMPLICIT_TEST_CODE}" Iconv_IS_BUILT_IN)
+ else()
+ check_cxx_source_compiles("${Iconv_IMPLICIT_TEST_CODE}" Iconv_IS_BUILT_IN)
+ endif()
+ cmake_pop_check_state()
+ else()
+ set(Iconv_IS_BUILT_IN FALSE)
+ endif()
+endif()
+
+if(NOT Iconv_IS_BUILT_IN)
+ find_path(Iconv_INCLUDE_DIR
+ NAMES "iconv.h"
+ DOC "iconv include directory")
+ set(Iconv_LIBRARY_NAMES "iconv" "libiconv")
+else()
+ set(Iconv_INCLUDE_DIR "" CACHE FILEPATH "iconv include directory")
+ set(Iconv_LIBRARY_NAMES "c")
+endif()
+
+find_library(Iconv_LIBRARY
+ NAMES ${Iconv_LIBRARY_NAMES}
+ DOC "iconv library (potentially the C library)")
+
+mark_as_advanced(Iconv_INCLUDE_DIR)
+mark_as_advanced(Iconv_LIBRARY)
+
+include(FindPackageHandleStandardArgs)
+if(NOT Iconv_IS_BUILT_IN)
+ find_package_handle_standard_args(Iconv REQUIRED_VARS Iconv_LIBRARY Iconv_INCLUDE_DIR)
+else()
+ find_package_handle_standard_args(Iconv REQUIRED_VARS Iconv_LIBRARY)
+endif()
+
+if(Iconv_FOUND)
+ set(Iconv_INCLUDE_DIRS "${Iconv_INCLUDE_DIR}")
+ set(Iconv_LIBRARIES "${Iconv_LIBRARY}")
+ if(NOT TARGET Iconv::Iconv)
+ add_library(Iconv::Iconv INTERFACE IMPORTED)
+ endif()
+ set_property(TARGET Iconv::Iconv PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${Iconv_INCLUDE_DIRS}")
+ set_property(TARGET Iconv::Iconv PROPERTY INTERFACE_LINK_LIBRARIES "${Iconv_LIBRARIES}")
+endif()
diff --git a/cmake/FindLZO.cmake b/cmake/FindLZO.cmake
new file mode 100644
index 000000000..9a409002d
--- /dev/null
+++ b/cmake/FindLZO.cmake
@@ -0,0 +1,89 @@
+#[=======================================================================[.rst:
+FindLZO
+-------
+
+Finds the LZO library.
+
+Result Variables
+^^^^^^^^^^^^^^^^
+
+This will define the following variables:
+
+``LZO_FOUND``
+ True if the system has the LZO library.
+``LZO_INCLUDE_DIRS``
+ Include directories needed to use LZO.
+``LZO_LIBRARIES``
+ Libraries needed to link to LZO.
+``LZO_VERSION``
+ The version of the LZO library which was found.
+
+Cache Variables
+^^^^^^^^^^^^^^^
+
+The following cache variables may also be set:
+
+``LZO_INCLUDE_DIR``
+ The directory containing ``lzo/lzo1x.h``.
+``LZO_LIBRARY``
+ The path to the LZO library.
+
+#]=======================================================================]
+
+find_package(PkgConfig QUIET)
+pkg_check_modules(PC_LZO QUIET lzo2)
+
+find_path(LZO_INCLUDE_DIR
+ NAMES lzo/lzo1x.h
+ PATHS ${PC_LZO_INCLUDE_DIRS}
+)
+
+find_library(LZO_LIBRARY
+ NAMES lzo2
+ PATHS ${PC_LZO_LIBRARY_DIRS}
+)
+
+# With vcpkg, the library path should contain both 'debug' and 'optimized'
+# entries (see target_link_libraries() documentation for more information)
+#
+# NOTE: we only patch up when using vcpkg; the same issue might happen
+# when not using vcpkg, but this is non-trivial to fix, as we have no idea
+# what the paths are. With vcpkg we do. And we only official support vcpkg
+# with Windows.
+#
+# NOTE: this is based on the assumption that the debug file has the same
+# name as the optimized file. This is not always the case, but so far
+# experiences has shown that in those case vcpkg CMake files do the right
+# thing.
+if (VCPKG_TOOLCHAIN AND LZO_LIBRARY)
+ if (LZO_LIBRARY MATCHES "/debug/")
+ set(LZO_LIBRARY_DEBUG ${LZO_LIBRARY})
+ string(REPLACE "/debug/lib/" "/lib/" LZO_LIBRARY_RELEASE ${LZO_LIBRARY})
+ else()
+ set(LZO_LIBRARY_RELEASE ${LZO_LIBRARY})
+ string(REPLACE "/lib/" "/debug/lib/" LZO_LIBRARY_DEBUG ${LZO_LIBRARY})
+ endif()
+ include(SelectLibraryConfigurations)
+ select_library_configurations(LZO)
+endif()
+
+set(LZO_VERSION ${PC_LZO_VERSION})
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(LZO
+ FOUND_VAR LZO_FOUND
+ REQUIRED_VARS
+ LZO_LIBRARY
+ LZO_INCLUDE_DIR
+ VERSION_VAR LZO_VERSION
+)
+
+if (LZO_FOUND)
+ set(LZO_LIBRARIES ${LZO_LIBRARY})
+ set(LZO_INCLUDE_DIRS ${LZO_INCLUDE_DIR})
+endif ()
+
+mark_as_advanced(
+ LZO_INCLUDE_DIR
+ LZO_LIBRARY
+)
diff --git a/cmake/FindSSE.cmake b/cmake/FindSSE.cmake
new file mode 100644
index 000000000..d0a57ccbb
--- /dev/null
+++ b/cmake/FindSSE.cmake
@@ -0,0 +1,17 @@
+# Autodetect if SSE4.1 can be used. If so, the assumption is, so can the other
+# SSE version (SSE 2.0, SSSE 3.0).
+
+include(CheckCXXSourceCompiles)
+set(CMAKE_REQUIRED_FLAGS "")
+
+if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")
+ set(CMAKE_REQUIRED_FLAGS "-msse4.1")
+endif (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")
+
+check_cxx_source_compiles("
+ #include <xmmintrin.h>
+ #include <smmintrin.h>
+ #include <tmmintrin.h>
+ int main() { return 0; }"
+ SSE_FOUND
+)
diff --git a/cmake/FindXDG_basedir.cmake b/cmake/FindXDG_basedir.cmake
new file mode 100644
index 000000000..913b425e2
--- /dev/null
+++ b/cmake/FindXDG_basedir.cmake
@@ -0,0 +1,65 @@
+#[=======================================================================[.rst:
+FindXDG_basedir
+-------
+
+Finds the xdg-basedir library.
+
+Result Variables
+^^^^^^^^^^^^^^^^
+
+This will define the following variables:
+
+``XDG_basedir_FOUND``
+ True if the system has the xdg-basedir library.
+``XDG_basedir_INCLUDE_DIRS``
+ Include directories needed to use xdg-basedir.
+``XDG_basedir_LIBRARIES``
+ Libraries needed to link to xdg-basedir.
+``XDG_basedir_VERSION``
+ The version of the xdg-basedir library which was found.
+
+Cache Variables
+^^^^^^^^^^^^^^^
+
+The following cache variables may also be set:
+
+``XDG_basedir_INCLUDE_DIR``
+ The directory containing ``xdg-basedir.h``.
+``XDG_basedir_LIBRARY``
+ The path to the xdg-basedir library.
+
+#]=======================================================================]
+
+find_package(PkgConfig QUIET)
+pkg_check_modules(PC_XDG_basedir QUIET libxdg-basedir)
+
+find_path(XDG_basedir_INCLUDE_DIR
+ NAMES basedir.h
+ PATHS ${PC_XDG_basedir_INCLUDE_DIRS}
+)
+
+find_library(XDG_basedir_LIBRARY
+ NAMES xdg-basedir
+ PATHS ${PC_XDG_basedir_LIBRARY_DIRS}
+)
+
+set(XDG_basedir_VERSION ${PC_XDG_basedir_VERSION})
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(XDG_basedir
+ FOUND_VAR XDG_basedir_FOUND
+ REQUIRED_VARS
+ XDG_basedir_LIBRARY
+ XDG_basedir_INCLUDE_DIR
+ VERSION_VAR XDG_basedir_VERSION
+)
+
+if (XDG_basedir_FOUND)
+ set(XDG_basedir_LIBRARIES ${XDG_basedir_LIBRARY})
+ set(XDG_basedir_INCLUDE_DIRS ${XDG_basedir_INCLUDE_DIR})
+endif ()
+
+mark_as_advanced(
+ XDG_basedir_INCLUDE_DIR
+ XDG_basedir_LIBRARY
+)
diff --git a/cmake/FindXaudio2.cmake b/cmake/FindXaudio2.cmake
new file mode 100644
index 000000000..065e2d358
--- /dev/null
+++ b/cmake/FindXaudio2.cmake
@@ -0,0 +1,18 @@
+# Autodetect if xaudio2 can be used.
+
+include(CheckCXXSourceCompiles)
+set(CMAKE_REQUIRED_FLAGS "")
+
+check_cxx_source_compiles("
+ #include <windows.h>
+
+ #undef NTDDI_VERSION
+ #undef _WIN32_WINNT
+
+ #define NTDDI_VERSION NTDDI_WIN8
+ #define _WIN32_WINNT _WIN32_WINNT_WIN8
+
+ #include <xaudio2.h>
+ int main() { return 0; }"
+ XAUDIO2_FOUND
+)
diff --git a/cmake/LinkPackage.cmake b/cmake/LinkPackage.cmake
new file mode 100644
index 000000000..f64ccfd51
--- /dev/null
+++ b/cmake/LinkPackage.cmake
@@ -0,0 +1,18 @@
+function(link_package NAME)
+ cmake_parse_arguments(LP "ENCOURAGED" "TARGET" "" ${ARGN})
+
+ if (${NAME}_FOUND)
+ string(TOUPPER "${NAME}" UCNAME)
+ add_definitions(-DWITH_${UCNAME})
+ if (LP_TARGET AND TARGET ${LP_TARGET})
+ target_link_libraries(openttd ${LP_TARGET})
+ message(STATUS "${NAME} found -- -DWITH_${UCNAME} -- ${LP_TARGET}")
+ else()
+ include_directories(${${NAME}_INCLUDE_DIRS} ${${NAME}_INCLUDE_DIR})
+ target_link_libraries(openttd ${${NAME}_LIBRARIES} ${${NAME}_LIBRARY})
+ message(STATUS "${NAME} found -- -DWITH_${UCNAME} -- ${${NAME}_INCLUDE_DIRS} ${${NAME}_INCLUDE_DIR} -- ${${NAME}_LIBRARIES} ${${NAME}_LIBRARY}")
+ endif()
+ elseif (LP_ENCOURAGED)
+ message(WARNING "${NAME} not found; compiling OpenTTD without ${NAME} is strongly disencouraged")
+ endif()
+endfunction()
diff --git a/cmake/Options.cmake b/cmake/Options.cmake
new file mode 100644
index 000000000..b292567f0
--- /dev/null
+++ b/cmake/Options.cmake
@@ -0,0 +1,84 @@
+# Set the options for the directories (personal, shared, global).
+#
+# set_directory_options()
+#
+function(set_directory_options)
+ if (APPLE)
+ set(DEFAULT_PERSONAL_DIR "Documents/OpenTTD")
+ set(DEFAULT_SHARED_DIR "/Library/Application Support/OpenTTD")
+ set(DEFAULT_GLOBAL_DIR "(not set)")
+ elseif (WIN32)
+ set(DEFAULT_PERSONAL_DIR "OpenTTD")
+ set(DEFAULT_SHARED_DIR "(not set)")
+ set(DEFAULT_GLOBAL_DIR "(not set)")
+ elseif (UNIX)
+ set(DEFAULT_PERSONAL_DIR ".openttd")
+ set(DEFAULT_SHARED_DIR "(not set)")
+ set(DEFAULT_GLOBAL_DIR "${CMAKE_INSTALL_PREFIX}/share/games/openttd")
+ else ()
+ message(FATAL_ERROR "Unknown OS found; please consider creating a Pull Request to add support for this OS.")
+ endif ()
+
+ if (NOT PERSONAL_DIR)
+ set(PERSONAL_DIR "${DEFAULT_PERSONAL_DIR}" CACHE STRING "Personal directory")
+ message(STATUS "Detecting Personal Data directory - ${PERSONAL_DIR}")
+ endif (NOT PERSONAL_DIR)
+
+ if (NOT SHARED_DIR)
+ set(SHARED_DIR "${DEFAULT_SHARED_DIR}" CACHE STRING "Shared directory")
+ message(STATUS "Detecting Shared Data directory - ${SHARED_DIR}")
+ endif (NOT SHARED_DIR)
+
+ if (NOT GLOBAL_DIR)
+ set(GLOBAL_DIR "${DEFAULT_GLOBAL_DIR}" CACHE STRING "Global directory")
+ message(STATUS "Detecting Global Data directory - ${GLOBAL_DIR}")
+ endif (NOT GLOBAL_DIR)
+endfunction()
+
+# Set some generic options that influence what is being build.
+#
+# set_options()
+#
+function(set_options)
+ if (UNIX AND NOT APPLE)
+ set(DEFAULT_OPTION_INSTALL_FHS YES)
+ else (UNIX AND NOT APPLE)
+ set(DEFAULT_OPTION_INSTALL_FHS NO)
+ endif (UNIX AND NOT APPLE)
+
+ option(OPTION_DEDICATED "Build dedicated server only (no GUI)" NO)
+ option(OPTION_INSTALL_FHS "Install with Filesstem Hierarchy Standard folders" ${DEFAULT_OPTION_INSTALL_FHS})
+ option(OPTION_USE_ASSERTS "Use assertions; leave enabled for nightlies, betas, and RCs" YES)
+ option(OPTION_USE_THREADS "Use threads" YES)
+endfunction()
+
+# Show the values of the generic options.
+#
+# show_options()
+#
+function(show_options)
+ message(STATUS "Option Dedicated - ${OPTION_DEDICATED}")
+ message(STATUS "Option Install FHS - ${OPTION_INSTALL_FHS}")
+ message(STATUS "Option Use assert - ${OPTION_USE_ASSERTS}")
+ message(STATUS "Option Use threads - ${OPTION_USE_THREADS}")
+endfunction()
+
+# Add the definitions for the options that are selected.
+#
+# add_definitions_based_on_options()
+#
+function(add_definitions_based_on_options)
+ if (OPTION_DEDICATED)
+ add_definitions(-DDEDICATED)
+ endif (OPTION_DEDICATED)
+
+ if (NOT OPTION_USE_THREADS)
+ add_definitions(-DNO_THREADS)
+ endif (NOT OPTION_USE_THREADS)
+
+ if (OPTION_USE_ASSERTS)
+ add_definitions(-DWITH_ASSERT)
+ else (OPTION_USE_ASSERTS)
+ add_definitions(-DNDEBUG)
+ endif (OPTION_USE_ASSERTS)
+endfunction()
diff --git a/cmake/SourceList.cmake b/cmake/SourceList.cmake
new file mode 100644
index 000000000..6300a19a4
--- /dev/null
+++ b/cmake/SourceList.cmake
@@ -0,0 +1,63 @@
+# Add a file to be compiled.
+#
+# add_files([file1 ...] CONDITION condition [condition ...])
+#
+# CONDITION is a complete statement that can be evaluated with if().
+# If it evaluates true, the source files will be added; otherwise not.
+# For example: ADD_IF SDL_FOUND AND Allegro_FOUND
+#
+function(add_files)
+ cmake_parse_arguments(PARAM "" "" "CONDITION" ${ARGN})
+ set(PARAM_FILES "${PARAM_UNPARSED_ARGUMENTS}")
+
+ if (PARAM_CONDITION)
+ if (NOT (${PARAM_CONDITION}))
+ return()
+ endif (NOT (${PARAM_CONDITION}))
+ endif (PARAM_CONDITION)
+
+ foreach(FILE IN LISTS PARAM_FILES)
+ target_sources(openttd PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/${FILE})
+ endforeach()
+endfunction(add_files)
+
+# This function works around an 'issue' with CMake, where
+# set_source_files_properties() only works in the scope of the file. We want
+# to set properties for the source file on a more global level. To solve this,
+# this function records the flags you want, and a macro adds them in the root
+# CMakeLists.txt.
+# See this URL for more information on the issue:
+# http://cmake.3232098.n2.nabble.com/scope-of-set-source-files-properties-td4766111.html
+#
+# set_compile_flags([file1 ...] COMPILE_FLAGS cflag [cflag ...])
+#
+function(set_compile_flags)
+ cmake_parse_arguments(PARAM "" "" "COMPILE_FLAGS" ${ARGN})
+ set(PARAM_FILES "${PARAM_UNPARSED_ARGUMENTS}")
+
+ get_property(SOURCE_PROPERTIES GLOBAL PROPERTY source_properties)
+
+ foreach(FILE IN LISTS PARAM_FILES)
+ list(APPEND SOURCE_PROPERTIES "${CMAKE_CURRENT_SOURCE_DIR}/${FILE}::${PARAM_COMPILE_FLAGS}")
+ endforeach()
+
+ set_property(GLOBAL PROPERTY source_properties "${SOURCE_PROPERTIES}")
+endfunction(set_compile_flags)
+
+# Call this macro in the same CMakeLists.txt and after add_executable().
+# This makes sure all the COMPILE_FLAGS of set_compile_flags() are set
+# correctly.
+#
+# process_compile_flags()
+#
+function(process_compile_flags)
+ get_property(SOURCE_PROPERTIES GLOBAL PROPERTY source_properties)
+
+ foreach(ENTRY ${SOURCE_PROPERTIES})
+ string(REPLACE "::" ";" ENTRY "${ENTRY}")
+ list(GET ENTRY 0 FILE)
+ list(GET ENTRY 1 PROPERTIES)
+
+ set_source_files_properties(${FILE} PROPERTIES COMPILE_FLAGS ${PROPERTIES})
+ endforeach()
+endfunction(process_compile_flags)
diff --git a/cmake/Static.cmake b/cmake/Static.cmake
new file mode 100644
index 000000000..7648d05e7
--- /dev/null
+++ b/cmake/Static.cmake
@@ -0,0 +1,14 @@
+# Set static linking if the platform requires it.
+#
+# set_static()
+#
+function(set_static_if_needed)
+ if (MINGW)
+ # Let exectutables run outside MinGW environment
+ # Force searching static libs
+ set(CMAKE_FIND_LIBRARY_SUFFIXES ".a" PARENT_SCOPE)
+
+ # Force static linking
+ link_libraries(-static -static-libgcc -static-libstdc++)
+ endif()
+endfunction()
diff --git a/cmake/scripts/FindVersion.cmake b/cmake/scripts/FindVersion.cmake
new file mode 100644
index 000000000..5edabeb19
--- /dev/null
+++ b/cmake/scripts/FindVersion.cmake
@@ -0,0 +1,134 @@
+cmake_minimum_required(VERSION 3.5)
+
+#
+# Finds the current version of the current folder.
+#
+
+find_package(Git QUIET)
+# ${CMAKE_SOURCE_DIR}/.git may be a directory or a regular file
+if (GIT_FOUND AND EXISTS "${CMAKE_SOURCE_DIR}/.git")
+ # Make sure LC_ALL is set to something desirable
+ set(SAVED_LC_ALL "$ENV{LC_ALL}")
+ set(ENV{LC_ALL} C)
+
+ # Assume the dir is not modified
+ set(REV_MODIFIED 0)
+
+ # Refresh the index to make sure file stat info is in sync, then look for modifications
+ execute_process(COMMAND ${GIT_EXECUTABLE} update-index --refresh
+ WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
+ OUTPUT_QUIET
+ )
+
+ # See if git tree is modified
+ execute_process(COMMAND ${GIT_EXECUTABLE} diff-index HEAD
+ OUTPUT_VARIABLE IS_MODIFIED
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
+ )
+ if (NOT IS_MODIFIED STREQUAL "")
+ set(REV_MODIFIED 2)
+ endif()
+
+ # Get last commit hash
+ execute_process(COMMAND ${GIT_EXECUTABLE} rev-parse --verify HEAD
+ OUTPUT_VARIABLE FULLHASH
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
+ ERROR_QUIET
+ )
+ set(REV_HASH "${FULLHASH}")
+
+ string(SUBSTRING "${FULLHASH}" 0 10 SHORTHASH)
+
+ # Get the last commit date
+ execute_process(COMMAND ${GIT_EXECUTABLE} show -s --pretty=format:%ci HEAD
+ OUTPUT_VARIABLE COMMITDATE
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
+ )
+ string(REGEX REPLACE "([0-9]+)-([0-9]+)-([0-9]+).*" "\\1\\2\\3" COMMITDATE "${COMMITDATE}")
+ set(REV_ISODATE "${COMMITDATE}")
+ string(SUBSTRING REV_ISODATE 1 4 REV_YEAR)
+
+ # Get the branch
+ execute_process(COMMAND ${GIT_EXECUTABLE} symbolic-ref -q HEAD
+ OUTPUT_VARIABLE BRANCH
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
+ ERROR_QUIET
+ )
+ string(REGEX REPLACE ".*/" "" BRANCH "${BRANCH}")
+
+ # Get the tag
+ execute_process(COMMAND ${GIT_EXECUTABLE} name-rev --name-only --tags --no-undefined HEAD
+ OUTPUT_VARIABLE TAG
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
+ ERROR_QUIET
+ )
+ string(REGEX REPLACE "\^0$" "" TAG "${TAG}")
+
+ if (REV_MODIFIED EQUAL 0)
+ set(HASHPREFIX "-g")
+ elseif (REV_MODIFIED EQUAL 2)
+ set(HASHPREFIX "-m")
+ else ()
+ set(HASHPREFIX "-u")
+ endif()
+
+ # Set the version string
+ if (NOT TAG STREQUAL "")
+ set(REV_VERSION "${TAG}")
+ set(REV_ISTAG 1)
+
+ string(REGEX REPLACE "^[0-9.]*$" "" STABLETAG "${TAG}")
+ if (NOT STABLETAG STREQUAL "")
+ set(REV_ISSTABLETAG 1)
+ else ()
+ set(REV_ISSTABLETAG 0)
+ endif ()
+ else ()
+ set(REV_VERSION "${REV_ISODATE}-${BRANCH}${HASHPREFIX}${SHORTHASH}")
+ set(REV_ISTAG 0)
+ set(REV_ISSTABLETAG 0)
+ endif ()
+
+ # Restore LC_ALL
+ set(ENV{LC_ALL} "${SAVED_LC_ALL}")
+elseif (EXISTS "${CMAKE_SOURCE_DIR}/.ottdrev")
+ file(READ "${CMAKE_SOURCE_DIR}/.ottdrev" OTTDREV)
+ string(REPLACE "\t" ";" OTTDREV "${OTTDREV}")
+ list(GET OTTDREV 0 REV_VERSION)
+ list(GET OTTDREV 1 REV_ISODATE)
+ list(GET OTTDREV 2 REV_MODIFIED)
+ list(GET OTTDREV 3 REV_HASH)
+ list(GET OTTDREV 4 REV_ISTAG)
+ list(GET OTTDREV 5 REV_ISSTABLETAG)
+ list(GET OTTDREV 6 REV_YEAR)
+else ()
+ message(WARNING "No version detected; this build will NOT be network compatible")
+ set(REV_VERSION "norev0000")
+ set(REV_ISODATE "19700101")
+ set(REV_MODIFIED 1)
+ set(REV_HASH "unknown")
+ set(REV_ISTAG 0)
+ set(REV_ISSTABLETAG 0)
+ set(REV_YEAR "1970")
+endif ()
+
+message(STATUS "Version string: ${REV_VERSION}")
+
+message(STATUS "Generating rev.cpp")
+configure_file("${CMAKE_SOURCE_DIR}/src/rev.cpp.in"
+ "${FIND_VERSION_BINARY_DIR}/rev.cpp")
+
+if (WIN32)
+ message(STATUS "Generating ottdres.rc")
+ configure_file("${CMAKE_SOURCE_DIR}/src/os/windows/ottdres.rc.in"
+ "${FIND_VERSION_BINARY_DIR}/ottdres.rc")
+endif (WIN32)
+
+message(STATUS "Generating CPackProperties.cmake")
+configure_file("${CMAKE_SOURCE_DIR}/CPackProperties.cmake.in"
+ "${CPACK_BINARY_DIR}/CPackProperties.cmake" @ONLY)
diff --git a/media/baseset/CMakeLists.txt b/media/baseset/CMakeLists.txt
index 309ac7a49..c3fe34ce4 100644
--- a/media/baseset/CMakeLists.txt
+++ b/media/baseset/CMakeLists.txt
@@ -20,13 +20,13 @@ set(BASESET_OTHER_SOURCE_FILES
)
# Done by the subdirectories, if nforenum / grfcodec is installed
-if (NFORENUM_FOUND AND GRFCODEC_FOUND)
+if (GRFCODEC_FOUND)
set_source_files_properties(${CMAKE_CURRENT_SOURCE_DIR}/openttd.grf PROPERTIES GENERATED TRUE)
set_source_files_properties(${CMAKE_CURRENT_SOURCE_DIR}/orig_extra.grf PROPERTIES GENERATED TRUE)
list(APPEND BASESET_BINARY_FILES openttd.grf)
list(APPEND BASESET_BINARY_FILES orig_extra.grf)
-endif (NFORENUM_FOUND AND GRFCODEC_FOUND)
+endif (GRFCODEC_FOUND)
set(BASESET_EXTRAGRF_FILE ${CMAKE_CURRENT_SOURCE_DIR}/orig_extra.grf)
diff --git a/media/baseset/openttd/CMakeLists.txt b/media/baseset/openttd/CMakeLists.txt
index 42d62dd7c..c4f8d61ad 100644
--- a/media/baseset/openttd/CMakeLists.txt
+++ b/media/baseset/openttd/CMakeLists.txt
@@ -3,7 +3,7 @@
# This is mainly because not many people have both of these tools installed,
# so it is cheaper to cache them in git, and only regenerate when you are
# working on it / have the tools installed.
-if (NFORENUM_FOUND AND GRFCODEC_FOUND)
- include(CreateGrfCommand REQUIRED)
+if (GRFCODEC_FOUND)
+ include(CreateGrfCommand)
create_grf_command()
-endif (NFORENUM_FOUND AND GRFCODEC_FOUND)
+endif (GRFCODEC_FOUND)
diff --git a/media/baseset/orig_extra/CMakeLists.txt b/media/baseset/orig_extra/CMakeLists.txt
index f865a8dd0..36a25329f 100644
--- a/media/baseset/orig_extra/CMakeLists.txt
+++ b/media/baseset/orig_extra/CMakeLists.txt
@@ -3,12 +3,12 @@
# This is mainly because not many people have both of these tools installed,
# so it is cheaper to cache them in git, and only regenerate when you are
# working on it / have the tools installed.
-if (NFORENUM_FOUND AND GRFCODEC_FOUND)
- include(CreateGrfCommand REQUIRED)
+if (GRFCODEC_FOUND)
+ include(CreateGrfCommand)
create_grf_command(
# We share some files with 'openttd' grf
${CMAKE_CURRENT_SOURCE_DIR}/../openttd/airports.png
${CMAKE_CURRENT_SOURCE_DIR}/../openttd/canals.png
${CMAKE_CURRENT_SOURCE_DIR}/../openttd/chars.png
)
-endif (NFORENUM_FOUND AND GRFCODEC_FOUND)
+endif (GRFCODEC_FOUND)
diff --git a/os/windows/openttd.manifest b/os/windows/openttd.manifest
new file mode 100644
index 000000000..ee1c7ea22
--- /dev/null
+++ b/os/windows/openttd.manifest
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
+ <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
+ <security>
+ <requestedPrivileges>
+ <requestedExecutionLevel level="asInvoker" uiAccess="false" />
+ </requestedPrivileges>
+ </security>
+ </trustInfo>
+ <application xmlns="urn:schemas-microsoft-com:asm.v3">
+ <windowsSettings>
+ <dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">True/PM</dpiAware>
+ </windowsSettings>
+ </application>
+ <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
+ <application>
+ <!--This Id value indicates the application supports Windows Vista functionality -->
+ <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
+ <!--This Id value indicates the application supports Windows 7 functionality-->
+ <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
+ <!--This Id value indicates the application supports Windows 8 functionality-->
+ <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
+ <!--This Id value indicates the application supports Windows 8.1 functionality-->
+ <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
+ <!--This Id value indicates the application supports Windows 10 functionality-->
+ <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
+ </application>
+ </compatibility>
+</assembly>
diff --git a/src/3rdparty/CMakeLists.txt b/src/3rdparty/CMakeLists.txt
new file mode 100644
index 000000000..e3927fa21
--- /dev/null
+++ b/src/3rdparty/CMakeLists.txt
@@ -0,0 +1,3 @@
+add_subdirectory(md5)
+add_subdirectory(squirrel)
+add_subdirectory(os2)
diff --git a/src/3rdparty/md5/CMakeLists.txt b/src/3rdparty/md5/CMakeLists.txt
new file mode 100644
index 000000000..58720ca2d
--- /dev/null
+++ b/src/3rdparty/md5/CMakeLists.txt
@@ -0,0 +1,4 @@
+add_files(
+ md5.cpp
+ md5.h
+)
diff --git a/src/3rdparty/os2/CMakeLists.txt b/src/3rdparty/os2/CMakeLists.txt
new file mode 100644
index 000000000..8edc63479
--- /dev/null
+++ b/src/3rdparty/os2/CMakeLists.txt
@@ -0,0 +1,7 @@
+add_files(
+ getaddrinfo.c
+ getaddrinfo.h
+ getnameinfo.c
+ getnameinfo.h
+ CONDITION OPTION_OS2
+)
diff --git a/src/3rdparty/squirrel/CMakeLists.txt b/src/3rdparty/squirrel/CMakeLists.txt
new file mode 100644
index 000000000..9602087cd
--- /dev/null
+++ b/src/3rdparty/squirrel/CMakeLists.txt
@@ -0,0 +1,3 @@
+add_subdirectory(include)
+add_subdirectory(sqstdlib)
+add_subdirectory(squirrel)
diff --git a/src/3rdparty/squirrel/include/CMakeLists.txt b/src/3rdparty/squirrel/include/CMakeLists.txt
new file mode 100644
index 000000000..5237360d3
--- /dev/null
+++ b/src/3rdparty/squirrel/include/CMakeLists.txt
@@ -0,0 +1,6 @@
+add_files(
+ sqstdaux.h
+ sqstdmath.h
+ sqstdstring.h
+ squirrel.h
+)
diff --git a/src/3rdparty/squirrel/sqstdlib/CMakeLists.txt b/src/3rdparty/squirrel/sqstdlib/CMakeLists.txt
new file mode 100644
index 000000000..2b3bd6bb3
--- /dev/null
+++ b/src/3rdparty/squirrel/sqstdlib/CMakeLists.txt
@@ -0,0 +1,4 @@
+add_files(
+ sqstdaux.cpp
+ sqstdmath.cpp
+)
diff --git a/src/3rdparty/squirrel/squirrel/CMakeLists.txt b/src/3rdparty/squirrel/squirrel/CMakeLists.txt
new file mode 100644
index 000000000..a86a92b7d
--- /dev/null
+++ b/src/3rdparty/squirrel/squirrel/CMakeLists.txt
@@ -0,0 +1,30 @@
+add_files(
+ sqapi.cpp
+ sqarray.h
+ sqbaselib.cpp
+ sqclass.cpp
+ sqclass.h
+ sqclosure.h
+ sqcompiler.cpp
+ sqcompiler.h
+ sqdebug.cpp
+ sqfuncproto.h
+ sqfuncstate.cpp
+ sqfuncstate.h
+ sqlexer.cpp
+ sqlexer.h
+ sqmem.cpp
+ sqobject.cpp
+ sqobject.h
+ sqopcodes.h
+ sqpcheader.h
+ sqstate.cpp
+ sqstate.h
+ sqstring.h
+ sqtable.cpp
+ sqtable.h
+ squserdata.h
+ squtils.h
+ sqvm.cpp
+ sqvm.h
+)
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
new file mode 100644
index 000000000..0ccf650ab
--- /dev/null
+++ b/src/CMakeLists.txt
@@ -0,0 +1,479 @@
+add_subdirectory(3rdparty)
+add_subdirectory(ai)
+add_subdirectory(blitter)
+add_subdirectory(core)
+add_subdirectory(game)
+add_subdirectory(lang)
+add_subdirectory(linkgraph)
+add_subdirectory(misc)
+add_subdirectory(music)
+add_subdirectory(network)
+add_subdirectory(os)
+add_subdirectory(pathfinder)
+add_subdirectory(saveload)
+add_subdirectory(script)
+add_subdirectory(settingsgen)
+add_subdirectory(sound)
+add_subdirectory(spriteloader)
+add_subdirectory(strgen)
+add_subdirectory(table)
+add_subdirectory(video)
+add_subdirectory(widgets)
+
+add_files(
+ viewport_sprite_sorter_sse4.cpp
+ CONDITION SSE_FOUND
+)
+if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")
+ set_compile_flags(
+ viewport_sprite_sorter_sse4.cpp
+ COMPILE_FLAGS -msse4.1)
+endif (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")
+
+add_files(
+ aircraft.h
+ aircraft_cmd.cpp
+ aircraft_gui.cpp
+ airport.cpp
+ airport.h
+ airport_gui.cpp
+ animated_tile.cpp
+ animated_tile_func.h
+ articulated_vehicles.cpp
+ articulated_vehicles.h
+ autoreplace.cpp
+ autoreplace_base.h
+ autoreplace_cmd.cpp
+ autoreplace_func.h
+ autoreplace_gui.cpp
+ autoreplace_gui.h
+ autoreplace_type.h
+ autoslope.h
+ base_consist.cpp
+ base_consist.h
+ base_media_base.h
+ base_media_func.h
+ base_station_base.h
+ bitmap_type.h
+ bmp.cpp
+ bmp.h
+ bootstrap_gui.cpp
+ bridge.h
+ bridge_gui.cpp
+ bridge_map.cpp
+ bridge_map.h
+ build_vehicle_gui.cpp
+ cargo_type.h
+ cargoaction.cpp
+ cargoaction.h
+ cargomonitor.cpp
+ cargomonitor.h
+ cargopacket.cpp
+ cargopacket.h
+ cargotype.cpp
+ cargotype.h
+ cheat.cpp
+ cheat_func.h
+ cheat_gui.cpp
+ cheat_type.h
+ clear_cmd.cpp
+ clear_func.h
+ clear_map.h
+ cmd_helper.h
+ command.cpp
+ command_func.h
+ command_type.h
+ company_base.h
+ company_cmd.cpp
+ company_func.h
+ company_gui.cpp
+ company_gui.h
+ company_manager_face.h
+ company_type.h
+ console.cpp
+ console_cmds.cpp
+ console_func.h
+ console_gui.cpp
+ console_gui.h
+ console_internal.h
+ console_type.h
+ cpu.cpp
+ cpu.h
+ crashlog.cpp
+ crashlog.h
+ currency.cpp
+ currency.h
+ date.cpp
+ date_func.h
+ date_gui.cpp
+ date_gui.h
+ date_type.h
+ debug.cpp
+ debug.h
+ dedicated.cpp
+ depot.cpp
+ depot_base.h
+ depot_cmd.cpp
+ depot_func.h
+ depot_gui.cpp
+ depot_map.h
+ depot_type.h
+ direction_func.h
+ direction_type.h
+ disaster_vehicle.cpp
+ disaster_vehicle.h
+ dock_gui.cpp
+ driver.cpp
+ driver.h
+ economy.cpp
+ economy_base.h
+ economy_func.h
+ economy_type.h
+ effectvehicle.cpp
+ effectvehicle_base.h
+ effectvehicle_func.h
+ elrail.cpp
+ elrail_func.h
+ engine.cpp
+ engine_base.h
+ engine_func.h
+ engine_gui.cpp
+ engine_gui.h
+ engine_type.h
+ error.h
+ error_gui.cpp
+ fileio.cpp
+ fileio_func.h
+ fileio_type.h
+ fios.cpp
+ fios.h
+ fios_gui.cpp
+ fontcache.cpp
+ fontcache.h
+ fontdetection.cpp
+ fontdetection.h
+ framerate_gui.cpp
+ framerate_type.h
+ gamelog.cpp
+ gamelog.h
+ gamelog_internal.h
+ genworld.cpp
+ genworld.h
+ genworld_gui.cpp
+ gfx.cpp
+ gfx_func.h
+ gfx_layout.cpp
+ gfx_layout.h
+ gfx_type.h
+ gfxinit.cpp
+ gfxinit.h
+ goal.cpp
+ goal_base.h
+ goal_gui.cpp
+ goal_type.h
+ graph_gui.cpp
+ graph_gui.h
+ ground_vehicle.cpp
+ ground_vehicle.hpp
+ group.h
+ group_cmd.cpp
+ group_gui.cpp
+ group_gui.h
+ group_type.h
+ gui.h
+ guitimer_func.h
+ heightmap.cpp
+ heightmap.h
+ highscore.cpp
+ highscore.h
+ highscore_gui.cpp
+ hotkeys.cpp
+ hotkeys.h
+ house.h
+ house_type.h
+ industry.h
+ industry_cmd.cpp
+ industry_gui.cpp
+ industry_map.h
+ industry_type.h
+ industrytype.h
+ ini.cpp
+ ini_load.cpp
+ ini_type.h
+ intro_gui.cpp
+ landscape.cpp
+ landscape.h
+ landscape_type.h
+ language.h
+ livery.h
+ main_gui.cpp
+ map.cpp
+ map_func.h
+ map_type.h
+ misc.cpp
+ misc_cmd.cpp
+ misc_gui.cpp
+ mixer.cpp
+ mixer.h
+ music.cpp
+ music_gui.cpp
+ newgrf.cpp
+ newgrf.h
+ newgrf_airport.cpp
+ newgrf_airport.h
+ newgrf_airporttiles.cpp
+ newgrf_airporttiles.h
+ newgrf_animation_base.h
+ newgrf_animation_type.h
+ newgrf_callbacks.h
+ newgrf_canal.cpp
+ newgrf_canal.h
+ newgrf_cargo.cpp
+ newgrf_cargo.h
+ newgrf_class.h
+ newgrf_class_func.h
+ newgrf_commons.cpp
+ newgrf_commons.h
+ newgrf_config.cpp
+ newgrf_config.h
+ newgrf_debug.h
+ newgrf_debug_gui.cpp
+ newgrf_engine.cpp
+ newgrf_engine.h
+ newgrf_generic.cpp
+ newgrf_generic.h
+ newgrf_gui.cpp
+ newgrf_house.cpp
+ newgrf_house.h
+ newgrf_industries.cpp
+ newgrf_industries.h
+ newgrf_industrytiles.cpp
+ newgrf_industrytiles.h
+ newgrf_object.cpp
+ newgrf_object.h
+ newgrf_profiling.cpp
+ newgrf_profiling.h
+ newgrf_properties.h
+ newgrf_railtype.cpp
+ newgrf_railtype.h
+ newgrf_roadtype.cpp
+ newgrf_roadtype.h
+ newgrf_sound.cpp
+ newgrf_sound.h
+ newgrf_spritegroup.cpp
+ newgrf_spritegroup.h
+ newgrf_station.cpp
+ newgrf_station.h
+ newgrf_storage.cpp
+ newgrf_storage.h
+ newgrf_text.cpp
+ newgrf_text.h
+ newgrf_town.cpp
+ newgrf_town.h
+ newgrf_townname.cpp
+ newgrf_townname.h
+ news_func.h
+ news_gui.cpp
+ news_gui.h
+ news_type.h
+ object.h
+ object_base.h
+ object_cmd.cpp
+ object_gui.cpp
+ object_map.h
+ object_type.h
+ openttd.cpp
+ openttd.h
+ order_backup.cpp
+ order_backup.h
+ order_base.h
+ order_cmd.cpp
+ order_func.h
+ order_gui.cpp
+ order_type.h
+ osk_gui.cpp
+ pbs.cpp
+ pbs.h
+ progress.cpp
+ progress.h
+ querystring_gui.h
+ rail.cpp
+ rail.h
+ rail_cmd.cpp
+ rail_gui.cpp
+ rail_gui.h
+ rail_map.h
+ rail_type.h
+ rev.h
+ road.cpp
+ road.h
+ road_cmd.cpp
+ road_cmd.h
+ road_func.h
+ road_gui.cpp
+ road_gui.h
+ road_internal.h
+ road_map.cpp
+ road_map.h
+ road_type.h
+ roadstop.cpp
+ roadstop_base.h
+ roadveh.h
+ roadveh_cmd.cpp
+ roadveh_gui.cpp
+ safeguards.h
+ screenshot_gui.cpp
+ screenshot_gui.h
+ screenshot.cpp
+ screenshot.h
+ settings.cpp
+ settings_func.h
+ settings_gui.cpp
+ settings_gui.h
+ settings_internal.h
+ settings_type.h
+ ship.h
+ ship_cmd.cpp
+ ship_gui.cpp
+ signal.cpp
+ signal_func.h
+ signal_type.h
+ signs.cpp
+ signs_base.h
+ signs_cmd.cpp
+ signs_func.h
+ signs_gui.cpp
+ signs_type.h
+ slope_func.h
+ slope_type.h
+ smallmap_gui.cpp
+ smallmap_gui.h
+ sortlist_type.h
+ sound.cpp
+ sound_func.h
+ sound_type.h
+ sprite.cpp
+ sprite.h
+ spritecache.cpp
+ spritecache.h
+ station.cpp
+ station_base.h
+ station_cmd.cpp
+ station_func.h
+ station_gui.cpp
+ station_gui.h
+ station_kdtree.h
+ station_map.h
+ station_type.h
+ statusbar_gui.cpp
+ statusbar_gui.h
+ stdafx.h
+ story.cpp
+ story_base.h
+ story_gui.cpp
+ story_type.h
+ strgen/strgen.h
+ string.cpp
+ string_base.h
+ string_func.h
+ string_type.h
+ stringfilter.cpp
+ stringfilter_type.h
+ strings.cpp
+ strings_func.h
+ strings_type.h
+ subsidy.cpp
+ subsidy_base.h
+ subsidy_func.h
+ subsidy_gui.cpp
+ subsidy_type.h
+ tar_type.h
+ terraform_cmd.cpp
+ terraform_gui.cpp
+ terraform_gui.h
+ textbuf.cpp
+ textbuf_gui.h
+ textbuf_type.h
+ texteff.cpp
+ texteff.hpp
+ textfile_gui.cpp
+ textfile_gui.h
+ textfile_type.h
+ tgp.cpp
+ tgp.h
+ thread.h
+ tile_cmd.h
+ tile_map.cpp
+ tile_map.h
+ tile_type.h
+ tilearea.cpp
+ tilearea_type.h
+ tilehighlight_func.h
+ tilehighlight_type.h
+ tilematrix_type.hpp
+ timetable.h
+ timetable_cmd.cpp
+ timetable_gui.cpp
+ toolbar_gui.cpp
+ toolbar_gui.h
+ town.h
+ town_cmd.cpp
+ town_gui.cpp
+ town_kdtree.h
+ town_map.h
+ town_type.h
+ townname.cpp
+ townname_func.h
+ townname_type.h
+ track_func.h
+ track_type.h
+ train.h
+ train_cmd.cpp
+ train_gui.cpp
+ transparency.h
+ transparency_gui.cpp
+ transparency_gui.h
+ transport_type.h
+ tree_cmd.cpp
+ tree_gui.cpp
+ tree_map.h
+ tunnel_map.cpp
+ tunnel_map.h
+ tunnelbridge.h
+ tunnelbridge_cmd.cpp
+ tunnelbridge_map.h
+ vehicle.cpp
+ vehicle_base.h
+ vehicle_cmd.cpp
+ vehicle_func.h
+ vehicle_gui.cpp
+ vehicle_gui.h
+ vehicle_gui_base.h
+ vehicle_type.h
+ vehiclelist.cpp
+ vehiclelist.h
+ viewport.cpp
+ viewport_func.h
+ viewport_gui.cpp
+ viewport_kdtree.h
+ viewport_sprite_sorter.h
+ viewport_type.h
+ void_cmd.cpp
+ void_map.h
+ water.h
+ water_cmd.cpp
+ water_map.h
+ waypoint.cpp
+ waypoint_base.h
+ waypoint_cmd.cpp
+ waypoint_func.h
+ waypoint_gui.cpp
+ widget.cpp
+ widget_type.h
+ window.cpp
+ window_func.h
+ window_gui.h
+ window_type.h
+ zoom_func.h
+ zoom_type.h
+)
diff --git a/src/ai/CMakeLists.txt b/src/ai/CMakeLists.txt
new file mode 100644
index 000000000..cab886b26
--- /dev/null
+++ b/src/ai/CMakeLists.txt
@@ -0,0 +1,14 @@
+add_files(
+ ai.hpp
+ ai_config.cpp
+ ai_config.hpp
+ ai_core.cpp
+ ai_gui.cpp
+ ai_gui.hpp
+ ai_info.cpp
+ ai_info.hpp
+ ai_instance.cpp
+ ai_instance.hpp
+ ai_scanner.cpp
+ ai_scanner.hpp
+)
diff --git a/src/blitter/CMakeLists.txt b/src/blitter/CMakeLists.txt
new file mode 100644
index 000000000..2abe6aec0
--- /dev/null
+++ b/src/blitter/CMakeLists.txt
@@ -0,0 +1,55 @@
+add_files(
+ 32bpp_anim.cpp
+ 32bpp_anim.hpp
+ 32bpp_base.cpp
+ 32bpp_base.hpp
+ 32bpp_optimized.cpp
+ 32bpp_optimized.hpp
+ 32bpp_simple.cpp
+ 32bpp_simple.hpp
+ 8bpp_base.cpp
+ 8bpp_base.hpp
+ 8bpp_optimized.cpp
+ 8bpp_optimized.hpp
+ 8bpp_simple.cpp
+ 8bpp_simple.hpp
+ CONDITION NOT OPTION_DEDICATED
+)
+
+add_files(
+ 32bpp_anim_sse2.cpp
+ 32bpp_anim_sse2.hpp
+ 32bpp_anim_sse4.cpp
+ 32bpp_anim_sse4.hpp
+ 32bpp_sse2.cpp
+ 32bpp_sse2.hpp
+ 32bpp_sse4.cpp
+ 32bpp_sse4.hpp
+ 32bpp_sse_func.hpp
+ 32bpp_sse_type.h
+ 32bpp_ssse3.cpp
+ 32bpp_ssse3.hpp
+ CONDITION NOT OPTION_DEDICATED AND SSE_FOUND
+)
+
+if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")
+ set_compile_flags(
+ 32bpp_anim_sse2.cpp
+ 32bpp_sse2.cpp
+ COMPILE_FLAGS -msse2)
+ set_compile_flags(
+ 32bpp_ssse3.cpp
+ COMPILE_FLAGS -mssse3)
+ set_compile_flags(
+ 32bpp_anim_sse4.cpp
+ 32bpp_sse4.cpp
+ COMPILE_FLAGS -msse4.1)
+endif (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")
+
+add_files(
+ base.hpp
+ common.hpp
+ factory.hpp
+ null.cpp
+ null.hpp
+)
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
new file mode 100644
index 000000000..96da08932
--- /dev/null
+++ b/src/core/CMakeLists.txt
@@ -0,0 +1,30 @@
+add_files(
+ alloc_func.cpp
+ alloc_func.hpp
+ alloc_type.hpp
+ backup_type.hpp
+ bitmath_func.cpp
+ bitmath_func.hpp
+ endian_func.hpp
+ endian_type.hpp
+ enum_type.hpp
+ geometry_func.cpp
+ geometry_func.hpp
+ geometry_type.hpp
+ kdtree.hpp
+ math_func.cpp
+ math_func.hpp
+ mem_func.hpp
+ multimap.hpp
+ overflowsafe_type.hpp
+ pool_func.cpp
+ pool_func.hpp
+ pool_type.hpp
+ random_func.cpp
+ random_func.hpp
+ smallmap_type.hpp
+ smallmatrix_type.hpp
+ smallstack_type.hpp
+ smallvec_type.hpp
+ string_compare_type.hpp
+)
diff --git a/src/core/endian_type.hpp b/src/core/endian_type.hpp
index 1b927ef45..e1add251e 100644
--- a/src/core/endian_type.hpp
+++ b/src/core/endian_type.hpp
@@ -23,30 +23,8 @@
/** Big endian builds use this for TTD_ENDIAN. */
#define TTD_BIG_ENDIAN 1
-/* Windows has always LITTLE_ENDIAN */
-#if defined(_WIN32) || defined(__OS2__) || defined(__HAIKU__)
-# define TTD_ENDIAN TTD_LITTLE_ENDIAN
-#elif defined(OSX)
-# include <sys/types.h>
-# if __DARWIN_BYTE_ORDER == __DARWIN_LITTLE_ENDIAN
-# define TTD_ENDIAN TTD_LITTLE_ENDIAN
-# else
-# define TTD_ENDIAN TTD_BIG_ENDIAN
-# endif
-#elif defined(__OpenBSD__)
-# include <endian.h>
-# if BYTE_ORDER == LITTLE_ENDIAN
-# define TTD_ENDIAN TTD_LITTLE_ENDIAN
-# else
-# define TTD_ENDIAN TTD_BIG_ENDIAN
-# endif
-#elif !defined(TESTING)
-# include <sys/param.h>
-# if __BYTE_ORDER == __LITTLE_ENDIAN
-# define TTD_ENDIAN TTD_LITTLE_ENDIAN
-# else
-# define TTD_ENDIAN TTD_BIG_ENDIAN
-# endif
-#endif /* _WIN32 || __OS2__ */
+#if !defined(TTD_ENDIAN)
+# error "TTD_ENDIAN is not defined; please set it to either TTD_LITTLE_ENDIAN or TTD_BIG_ENDIAN"
+#endif /* !TTD_ENDIAN */
#endif /* ENDIAN_TYPE_HPP */
diff --git a/src/depend/depend.cpp b/src/depend/depend.cpp
deleted file mode 100644
index 5a3bd868d..000000000
--- a/src/depend/depend.cpp
+++ /dev/null
@@ -1,1084 +0,0 @@
-/*
- * This file is part of OpenTTD.
- * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
- * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
- */
-
-/**
- * @file depend/depend.cpp Custom implementation of Makedepend.
- *
- * We previously used makedepend, but that could not handle the amount of
- * files we have and does not handle conditional includes in a sane manner.
- * This caused many link problems because not enough files were recompiled.
- * This has lead to the development of our own dependency generator. It is
- * meant to be a substitute to the (relatively slow) dependency generation
- * via gcc. It thus helps speeding up compilation. It will also ignore
- * system headers making it less error prone when system headers are moved
- * or renamed.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#include <limits.h>
-#include <unistd.h>
-#include <map>
-#include <set>
-#include <stack>
-#include <cassert>
-
-/**
- * Return the length of an fixed size array.
- * Unlike sizeof this function returns the number of elements
- * of the given type.
- *
- * @param x The pointer to the first element of the array
- * @return The number of elements
- */
-#define lengthof(x) (sizeof(x) / sizeof(x[0]))
-
-/**
- * Get the last element of an fixed size array.
- *
- * @param x The pointer to the first element of the array
- * @return The pointer to the last element of the array
- */
-#define lastof(x) (&x[lengthof(x) - 1])
-
-/**
- * Copies characters from one buffer to another.
- *
- * Copies the source string to the destination buffer with respect of the
- * terminating null-character and the last pointer to the last element in
- * the destination buffer. If the last pointer is set to nullptr no boundary
- * check is performed.
- *
- * @note usage: strecpy(dst, src, lastof(dst));
- * @note lastof() applies only to fixed size arrays
- *
- * @param dst The destination buffer
- * @param src The buffer containing the string to copy
- * @param last The pointer to the last element of the destination buffer
- * @return The pointer to the terminating null-character in the destination buffer
- */
-char *strecpy(char *dst, const char *src, const char *last)
-{
- assert(dst <= last);
- while (dst != last && *src != '\0') {
- *dst++ = *src++;
- }
- *dst = '\0';
-
- if (dst == last && *src != '\0') {
- fprintf(stderr, "String too long for destination buffer\n");
- exit(-3);
- }
- return dst;
-}
-
-/**
- * Appends characters from one string to another.
- *
- * Appends the source string to the destination string with respect of the
- * terminating null-character and and the last pointer to the last element
- * in the destination buffer. If the last pointer is set to nullptr no
- * boundary check is performed.
- *
- * @note usage: strecat(dst, src, lastof(dst));
- * @note lastof() applies only to fixed size arrays
- *
- * @param dst The buffer containing the target string
- * @param src The buffer containing the string to append
- * @param last The pointer to the last element of the destination buffer
- * @return The pointer to the terminating null-character in the destination buffer
- */
-static char *strecat(char *dst, const char *src, const char *last)
-{
- assert(dst <= last);
- while (*dst != '\0') {
- if (dst == last) return dst;
- dst++;
- }
-
- return strecpy(dst, src, last);
-}
-
-#if defined(__CYGWIN__)
-/**
- * Version of strdup copied from glibc.
- * Duplicate S, returning an identical malloc'd string.
- * @param s The string to duplicate.
- */
-char *
-strdup (const char *s)
-{
- size_t len = strlen(s) + 1;
- void *n = malloc(len);
-
- if (n == NULL) return NULL;
- return (char *) memcpy(n, s, len);
-}
-#endif
-
-/**
- * Version of the standard free that accepts const pointers.
- * @param ptr The data to free.
- */
-static inline void free(const void *ptr)
-{
- free(const_cast<void *>(ptr));
-}
-
-#ifndef PATH_MAX
-/** The maximum length of paths, if we don't know it. */
-# define PATH_MAX 260
-#endif
-
-/** Simple string comparator using strcmp as implementation */
-struct StringCompare {
- /**
- * Compare a to b using strcmp.
- * @param a string to compare.
- * @param b string to compare.
- * @return whether a is less than b.
- */
- bool operator () (const char *a, const char *b) const
- {
- return strcmp(a, b) < 0;
- }
-};
-/** Set of C-style strings. */
-typedef std::set<const char*, StringCompare> StringSet;
-/** Mapping of C-style string to a set of C-style strings. */
-typedef std::map<const char*, StringSet*, StringCompare> StringMap;
-/** Pair of C-style string and a set of C-style strings. */
-typedef std::pair<const char*, StringSet*> StringMapItem;
-
-/** Include directory to search in. */
-static StringSet _include_dirs;
-/** Files that have been parsed/handled with their dependencies. */
-static StringMap _files;
-/** Dependencies of headers. */
-static StringMap _headers;
-/** The current 'active' defines. */
-static StringSet _defines;
-
-/**
- * Helper class to read a file.
- */
-class File {
-public:
- /**
- * Create the helper by opening the given file.
- * @param filename the file to open
- * @post the file is open; otherwise the application is killed.
- */
- File(const char *filename)
- {
- this->fp = fopen(filename, "r");
- if (this->fp == nullptr) {
- fprintf(stdout, "Could not open %s for reading\n", filename);
- exit(1);
- }
- this->dirname = strdup(filename);
- char *last = strrchr(this->dirname, '/');
- if (last != nullptr) {
- *last = '\0';
- } else {
- *this->dirname = '\0';
- }
- }
-
- /** Free everything we have allocated. */
- ~File()
- {
- fclose(this->fp);
- free(this->dirname);
- }
-
- /**
- * Get a single character from the file.
- * If we are reading beyond the end of the file '\0' is returned.
- * @return the read character.
- */
- char GetChar() const
- {
- int c = fgetc(this->fp);
- return (c == EOF) ? '\0' : c;
- }
-
- /**
- * Get the directory name of the file.
- * @return the directory name.
- */
- const char *GetDirname() const
- {
- return this->dirname;
- }
-
-private:
- FILE *fp; ///< The currently opened file.
- char *dirname; ///< The directory of the file.
-};
-
-/** A token returned by the tokenizer. */
-enum Token {
- TOKEN_UNKNOWN, ///< Unknown token
- TOKEN_END, ///< End of document
- TOKEN_EOL, ///< End of line
- TOKEN_SHARP, ///< # character, usually telling something important comes.
- TOKEN_LOCAL, ///< Read a local include
- TOKEN_GLOBAL, ///< Read a global include
- TOKEN_IDENTIFIER, ///< Identifier within the data.
- TOKEN_DEFINE, ///< \c \#define in code
- TOKEN_IF, ///< \c \#if in code
- TOKEN_IFDEF, ///< \c \#ifdef in code
- TOKEN_IFNDEF, ///< \c \#ifndef in code
- TOKEN_ELIF, ///< \c \#elif in code
- TOKEN_ELSE, ///< \c \#else in code
- TOKEN_ENDIF, ///< \c \#endif in code
- TOKEN_UNDEF, ///< \c \#undef in code
- TOKEN_OR, ///< '||' within \c \#if expression
- TOKEN_AND, ///< '&&' within \c \#if expression
- TOKEN_DEFINED, ///< 'defined' within \c \#if expression
- TOKEN_OPEN, ///< '(' within \c \#if expression
- TOKEN_CLOSE, ///< ')' within \c \#if expression
- TOKEN_NOT, ///< '!' within \c \#if expression
- TOKEN_ZERO, ///< '0' within \c \#if expression
- TOKEN_INCLUDE, ///< \c \#include in code
-};
-
-/** Mapping from a C-style keyword representation to a Token. */
-typedef std::map<const char*, Token, StringCompare> KeywordList;
-
-/**
- * Lexer of a file.
- */
-class Lexer {
-public:
- /**
- * Create the lexer and fill the keywords table.
- * @param file the file to read from.
- */
- Lexer(const File *file) : file(file), current_char('\0'), string(nullptr), token(TOKEN_UNKNOWN)
- {
- this->keywords["define"] = TOKEN_DEFINE;
- this->keywords["defined"] = TOKEN_DEFINED;
- this->keywords["if"] = TOKEN_IF;
- this->keywords["ifdef"] = TOKEN_IFDEF;
- this->keywords["ifndef"] = TOKEN_IFNDEF;
- this->keywords["include"] = TOKEN_INCLUDE;
- this->keywords["elif"] = TOKEN_ELIF;
- this->keywords["else"] = TOKEN_ELSE;
- this->keywords["endif"] = TOKEN_ENDIF;
- this->keywords["undef"] = TOKEN_UNDEF;
-
- /* Initialise currently read character. */
- this->Next();
-
- /* Allocate the buffer. */
- this->buf_len = 32;
- this->buf = (char*)malloc(sizeof(*this->buf) * this->buf_len);
- }
-
- /** Free everything */
- ~Lexer()
- {
- free(this->buf);
- }
-
- /**
- * Read the next character into 'current_char'.
- */
- void Next()
- {
- this->current_char = this->file->GetChar();
- }
-
- /**
- * Get the current token.
- * @return the token.
- */
- Token GetToken() const
- {
- return this->token;
- }
-
- /**
- * Read the currently processed string.
- * @return the string, can be nullptr.
- */
- const char *GetString() const
- {
- return this->string;
- }
-
- /**
- * Perform the lexing/tokenizing of the file till we can return something
- * that must be parsed.
- */
- void Lex()
- {
- for (;;) {
- free(this->string);
- this->string = nullptr;
- this->token = TOKEN_UNKNOWN;
-
- switch (this->current_char) {
- /* '\0' means End-Of-File */
- case '\0': this->token = TOKEN_END; return;
-
- /* Skip some chars, as they don't do anything */
- case '\t': this->Next(); break;
- case '\r': this->Next(); break;
- case ' ': this->Next(); break;
-
- case '\\':
- this->Next();
- if (this->current_char == '\n') this->Next();
- break;
-
- case '\n':
- this->token = TOKEN_EOL;
- this->Next();
- return;
-
- case '#':
- this->token = TOKEN_SHARP;
- this->Next();
- return;
-
- case '"':
- this->ReadString('"', TOKEN_LOCAL);
- this->Next();
- return;
-
- case '<':
- this->ReadString('>', TOKEN_GLOBAL);
- this->Next();
- return;
-
- case '&':
- this->Next();
- if (this->current_char == '&') {
- this->Next();
- this->token = TOKEN_AND;
- return;
- }
- break;
-
- case '|':
- this->Next();
- if (this->current_char == '|') {
- this->Next();
- this->token = TOKEN_OR;
- return;
- }
- break;
-
- case '(':
- this->Next();
- this->token = TOKEN_OPEN;
- return;
-
- case ')':
- this->Next();
- this->token = TOKEN_CLOSE;
- return;
-
- case '!':
- this->Next();
- if (this->current_char != '=') {
- this->token = TOKEN_NOT;
- return;
- }
- break;
-
- /* Possible begin of comment */
- case '/':
- this->Next();
- switch (this->current_char) {
- case '*': {
- this->Next();
- char previous_char = '\0';
- while ((this->current_char != '/' || previous_char != '*') && this->current_char != '\0') {
- previous_char = this->current_char;
- this->Next();
- }
- this->Next();
- break;
- }
- case '/': while (this->current_char != '\n' && this->current_char != '\0') this->Next(); break;
- default: break;
- }
- break;
-
- default:
- if (isalpha(this->current_char) || this->current_char == '_') {
- /* If the name starts with a letter, it is an identifier */
- this->ReadIdentifier();
- return;
- }
- if (isdigit(this->current_char)) {
- bool zero = this->current_char == '0';
- this->Next();
- if (this->current_char == 'x' || this->current_char == 'X') Next();
- while (isdigit(this->current_char) || this->current_char == '.' || (this->current_char >= 'a' && this->current_char <= 'f') || (this->current_char >= 'A' && this->current_char <= 'F')) {
- zero &= this->current_char == '0';
- this->Next();
- }
- if (zero) this->token = TOKEN_ZERO;
- return;
- }
- this->Next();
- break;
- }
- }
- }
-
-private:
- /**
- * The token based on keyword with a given name.
- * @param name the actual keyword.
- * @return the token of the keyword.
- */
- Token FindKeyword(const char *name) const
- {
- KeywordList::const_iterator it = this->keywords.find(name);
- if (it == this->keywords.end()) return TOKEN_IDENTIFIER;
- return (*it).second;
- }
-
- /**
- * Read an identifier.
- */
- void ReadIdentifier()
- {
- size_t count = 0;
-
- /* Read the rest of the identifier */
- do {
- this->buf[count++] = this->current_char;
- this->Next();
-
- if (count >= buf_len) {
- /* Scale the buffer if required */
- this->buf_len *= 2;
- this->buf = (char *)realloc(this->buf, sizeof(*this->buf) * this->buf_len);
- }
- } while ((isalpha(this->current_char) || this->current_char == '_' || isdigit(this->current_char)));
- this->buf[count] = '\0';
-
- free(this->string);
- this->string = strdup(this->buf);
- this->token = FindKeyword(this->string);
- }
-
- /**
- * Read a string up to a given character, then set the given token.
- * @param end the 'marker' for the end of the string.
- * @param token the token to set after returning.
- */
- void ReadString(char end, Token token)
- {
- size_t count = 0;
- this->Next();
- while (this->current_char != end && this->current_char != ')' && this->current_char != '\n' && this->current_char != '\0') {
- this->buf[count++] = this->current_char;
- this->Next();
-
- if (count >= this->buf_len) {
- /* Scale the buffer if required */
- this->buf_len *= 2;
- this->buf = (char *)realloc(this->buf, sizeof(*this->buf) * this->buf_len);
- }
- }
- this->buf[count] = '\0';
- free(this->string);
- this->string = strdup(this->buf);
- this->token = token;
- }
-
- const File *file; ///< The file to read from.
- char current_char; ///< The current character to process.
- char *string; ///< Currently processed string.
- Token token; ///< The current token to process.
- char *buf; ///< Temporary buffer.
- size_t buf_len; ///< Length of the temporary buffer.
- KeywordList keywords; ///< All keywords we know of.
-};
-
-/**
- * Generate a path from a directory name and a relative filename.
- * If the file is not local the include directory names will be used instead
- * of the passed parameter with directory name. If the file is local both will
- * be queried where the parameter takes precedence.
- * @param dirname the directory to look in.
- * @param filename the file to look for.
- * @param local whether to look locally (in dirname) for the file.
- * @return the absolute path, or nullptr if the file doesn't exist.
- */
-const char *GeneratePath(const char *dirname, const char *filename, bool local)
-{
- /* Ignore C++ standard library headers. */
- if (strchr(filename, '.') == nullptr) return nullptr;
-
- if (local) {
- if (access(filename, R_OK) == 0) return strdup(filename);
-
- char path[PATH_MAX];
- strecpy(path, dirname, lastof(path));
- const char *p = filename;
- /* Remove '..' from the begin of the filename. */
- while (*p == '.') {
- if (*(++p) == '.') {
- char *s = strrchr(path, '/');
- if (s != nullptr) *s = '\0';
- p += 2;
- }
- }
- strecat(path, "/", lastof(path));
- strecat(path, p, lastof(path));
-
- if (access(path, R_OK) == 0) return strdup(path);
- }
-
- for (StringSet::iterator it = _include_dirs.begin(); it != _include_dirs.end(); it++) {
- char path[PATH_MAX];
- strecpy(path, *it, lastof(path));
- const char *p = filename;
- /* Remove '..' from the begin of the filename. */
- while (*p == '.') {
- if (*(++p) == '.') {
- char *s = strrchr(path, '/');
- if (s != nullptr) *s = '\0';
- p += 2;
- }
- }
- strecat(path, "/", lastof(path));
- strecat(path, p, lastof(path));
-
- if (access(path, R_OK) == 0) return strdup(path);
- }
-
- return nullptr;
-}
-
-/**
- * Try to parse a 'defined(expr)' expression.
- * @param lexer the lexer to get tokens from.
- * @param defines the set of known defines.
- * @param verbose whether to give verbose debugging information.
- * @return the value of the expression.
- */
-bool ExpressionDefined(Lexer *lexer, StringSet *defines, bool verbose);
-
-/**
- * Try to parse a 'expr || expr' expression.
- * @param lexer the lexer to get tokens from.
- * @param defines the set of known defines.
- * @param verbose whether to give verbose debugging information.
- * @return the value of the expression.
- */
-bool ExpressionOr(Lexer *lexer, StringSet *defines, bool verbose);
-
-/**
- * Try to parse a '!expr' expression. Also parses the '(expr)', '0' and
- * identifiers. Finally it also consumes any unknown tokens.
- * @param lexer the lexer to get tokens from.
- * @param defines the set of known defines.
- * @param verbose whether to give verbose debugging information.
- * @return the value of the expression.
- */
-bool ExpressionNot(Lexer *lexer, StringSet *defines, bool verbose)
-{
- if (lexer->GetToken() == TOKEN_NOT) {
- if (verbose) fprintf(stderr, "!");
- lexer->Lex();
- bool value = !ExpressionDefined(lexer, defines, verbose);
- if (verbose) fprintf(stderr, "[%d]", value);
- return value;
- }
-
- if (lexer->GetToken() == TOKEN_OPEN) {
- if (verbose) fprintf(stderr, "(");
- lexer->Lex();
- bool value = ExpressionOr(lexer, defines, verbose);
- if (verbose) fprintf(stderr, ")[%d]", value);
- lexer->Lex();
- return value;
- }
-
- if (lexer->GetToken() == TOKEN_ZERO) {
- if (verbose) fprintf(stderr, "0");
- lexer->Lex();
- if (verbose) fprintf(stderr, "[0]");
- return false;
- }
-
- bool first = true;
- while (lexer->GetToken() == TOKEN_UNKNOWN || lexer->GetToken() == TOKEN_IDENTIFIER) {
- if (verbose && first) fprintf(stderr, "<assumed true>");
- first = false;
- lexer->Lex();
- }
-
- return true;
-}
-
-/**
- * Try to parse a 'defined(expr)' expression.
- * @param lexer the lexer to get tokens from.
- * @param defines the set of known defines.
- * @param verbose whether to give verbose debugging information.
- * @return the value of the expression.
- */
-bool ExpressionDefined(Lexer *lexer, StringSet *defines, bool verbose)
-{
- bool value = ExpressionNot(lexer, defines, verbose);
-
- if (lexer->GetToken() != TOKEN_DEFINED) return value;
- lexer->Lex();
- if (verbose) fprintf(stderr, "defined");
- bool open = (lexer->GetToken() == TOKEN_OPEN);
- if (open) lexer->Lex();
- if (verbose) fprintf(stderr, open ? "(" : " ");
- if (lexer->GetToken() == TOKEN_IDENTIFIER) {
- if (verbose) fprintf(stderr, "%s", lexer->GetString());
- value = defines->find(lexer->GetString()) != defines->end();
- }
- if (open) {
- if (verbose) fprintf(stderr, ")");
- lexer->Lex();
- }
- lexer->Lex();
- if (verbose) fprintf(stderr, "[%d]", value);
- return value;
-}
-
-/**
- * Try to parse a 'expr && expr' expression.
- * @param lexer the lexer to get tokens from.
- * @param defines the set of known defines.
- * @param verbose whether to give verbose debugging information.
- * @return the value of the expression.
- */
-bool ExpressionAnd(Lexer *lexer, StringSet *defines, bool verbose)
-{
- bool value = ExpressionDefined(lexer, defines, verbose);
-
- for (;;) {
- if (lexer->GetToken() != TOKEN_AND) return value;
- if (verbose) fprintf(stderr, " && ");
- lexer->Lex();
- value = value && ExpressionDefined(lexer, defines, verbose);
- }
-}
-
-/**
- * Try to parse a 'expr || expr' expression.
- * @param lexer the lexer to get tokens from.
- * @param defines the set of known defines.
- * @param verbose whether to give verbose debugging information.
- * @return the value of the expression.
- */
-bool ExpressionOr(Lexer *lexer, StringSet *defines, bool verbose)
-{
- bool value = ExpressionAnd(lexer, defines, verbose);
-
- for (;;) {
- if (lexer->GetToken() != TOKEN_OR) return value;
- if (verbose) fprintf(stderr, " || ");
- lexer->Lex();
- value = value || ExpressionAnd(lexer, defines, verbose);
- }
-}
-
-/** Enumerator to tell how long to ignore 'stuff'. */
-enum Ignore {
- NOT_IGNORE, ///< No ignoring.
- IGNORE_UNTIL_ELSE, ///< Ignore till a \c \#else is reached.
- IGNORE_UNTIL_ENDIF, ///< Ignore till a \c \#endif is reached.
-};
-
-/**
- * Scan a file for includes, defines and the lot.
- * @param filename the name of the file to scan.
- * @param ext the extension of the filename.
- * @param header whether the file is a header or not.
- * @param verbose whether to give verbose debugging information.
- */
-void ScanFile(const char *filename, const char *ext, bool header, bool verbose)
-{
- static StringSet defines;
- static std::stack<Ignore> ignore;
- /* Copy in the default defines (parameters of depend) */
- if (!header) {
- for (StringSet::iterator it = _defines.begin(); it != _defines.end(); it++) {
- defines.insert(strdup(*it));
- }
- }
-
- File file(filename);
- Lexer lexer(&file);
-
- /* Start the lexing! */
- lexer.Lex();
-
- while (lexer.GetToken() != TOKEN_END) {
- switch (lexer.GetToken()) {
- /* We reached the end of the file... yay, we're done! */
- case TOKEN_END: break;
-
- /* The line started with a # (minus whitespace) */
- case TOKEN_SHARP:
- lexer.Lex();
- switch (lexer.GetToken()) {
- case TOKEN_INCLUDE:
- if (verbose) fprintf(stderr, "%s #include ", filename);
- lexer.Lex();
- switch (lexer.GetToken()) {
- case TOKEN_LOCAL:
- case TOKEN_GLOBAL: {
- if (verbose) fprintf(stderr, "%s", lexer.GetString());
- if (!ignore.empty() && ignore.top() != NOT_IGNORE) {
- if (verbose) fprintf(stderr, " (ignored)");
- break;
- }
- const char *h = GeneratePath(file.GetDirname(), lexer.GetString(), lexer.GetToken() == TOKEN_LOCAL);
- if (h != nullptr) {
- StringMap::iterator it = _headers.find(h);
- if (it == _headers.end()) {
- it = (_headers.insert(StringMapItem(strdup(h), new StringSet()))).first;
- if (verbose) fprintf(stderr, "\n");
- ScanFile(h, ext, true, verbose);
- }
- StringMap::iterator curfile;
- if (header) {
- curfile = _headers.find(filename);
- } else {
- /* Replace the extension with the provided extension of '.o'. */
- char path[PATH_MAX];
- strecpy(path, filename, lastof(path));
- *(strrchr(path, '.')) = '\0';
- strecat(path, ext != nullptr ? ext : ".o", lastof(path));
- curfile = _files.find(path);
- if (curfile == _files.end()) {
- curfile = (_files.insert(StringMapItem(strdup(path), new StringSet()))).first;
- }
- }
- if (it != _headers.end()) {
- for (StringSet::iterator header = it->second->begin(); header != it->second->end(); header++) {
- if (curfile->second->find(*header) == curfile->second->end()) curfile->second->insert(strdup(*header));
- }
- }
- if (curfile->second->find(h) == curfile->second->end()) curfile->second->insert(strdup(h));
- free(h);
- }
- }
- /* FALL THROUGH */
- default: break;
- }
- break;
-
- case TOKEN_DEFINE:
- if (verbose) fprintf(stderr, "%s #define ", filename);
- lexer.Lex();
- if (lexer.GetToken() == TOKEN_IDENTIFIER) {
- if (verbose) fprintf(stderr, "%s", lexer.GetString());
- if (!ignore.empty() && ignore.top() != NOT_IGNORE) {
- if (verbose) fprintf(stderr, " (ignored)");
- break;
- }
- if (defines.find(lexer.GetString()) == defines.end()) defines.insert(strdup(lexer.GetString()));
- lexer.Lex();
- }
- break;
-
- case TOKEN_UNDEF:
- if (verbose) fprintf(stderr, "%s #undef ", filename);
- lexer.Lex();
- if (lexer.GetToken() == TOKEN_IDENTIFIER) {
- if (verbose) fprintf(stderr, "%s", lexer.GetString());
- if (!ignore.empty() && ignore.top() != NOT_IGNORE) {
- if (verbose) fprintf(stderr, " (ignored)");
- break;
- }
- StringSet::iterator it = defines.find(lexer.GetString());
- if (it != defines.end()) {
- free(*it);
- defines.erase(it);
- }
- lexer.Lex();
- }
- break;
-
- case TOKEN_ENDIF:
- if (verbose) fprintf(stderr, "%s #endif", filename);
- lexer.Lex();
- if (!ignore.empty()) ignore.pop();
- if (verbose) fprintf(stderr, " -> %signore", (!ignore.empty() && ignore.top() != NOT_IGNORE) ? "" : "not ");
- break;
-
- case TOKEN_ELSE: {
- if (verbose) fprintf(stderr, "%s #else", filename);
- lexer.Lex();
- Ignore last = ignore.empty() ? NOT_IGNORE : ignore.top();
- if (!ignore.empty()) ignore.pop();
- if (ignore.empty() || ignore.top() == NOT_IGNORE) {
- ignore.push(last == IGNORE_UNTIL_ELSE ? NOT_IGNORE : IGNORE_UNTIL_ENDIF);
- } else {
- ignore.push(IGNORE_UNTIL_ENDIF);
- }
- if (verbose) fprintf(stderr, " -> %signore", (!ignore.empty() && ignore.top() != NOT_IGNORE) ? "" : "not ");
- break;
- }
-
- case TOKEN_ELIF: {
- if (verbose) fprintf(stderr, "%s #elif ", filename);
- lexer.Lex();
- Ignore last = ignore.empty() ? NOT_IGNORE : ignore.top();
- if (!ignore.empty()) ignore.pop();
- if (ignore.empty() || ignore.top() == NOT_IGNORE) {
- bool value = ExpressionOr(&lexer, &defines, verbose);
- ignore.push(last == IGNORE_UNTIL_ELSE ? (value ? NOT_IGNORE : IGNORE_UNTIL_ELSE) : IGNORE_UNTIL_ENDIF);
- } else {
- ignore.push(IGNORE_UNTIL_ENDIF);
- }
- if (verbose) fprintf(stderr, " -> %signore", (!ignore.empty() && ignore.top() != NOT_IGNORE) ? "" : "not ");
- break;
- }
-
- case TOKEN_IF: {
- if (verbose) fprintf(stderr, "%s #if ", filename);
- lexer.Lex();
- if (ignore.empty() || ignore.top() == NOT_IGNORE) {
- bool value = ExpressionOr(&lexer, &defines, verbose);
- ignore.push(value ? NOT_IGNORE : IGNORE_UNTIL_ELSE);
- } else {
- ignore.push(IGNORE_UNTIL_ENDIF);
- }
- if (verbose) fprintf(stderr, " -> %signore", (!ignore.empty() && ignore.top() != NOT_IGNORE) ? "" : "not ");
- break;
- }
-
- case TOKEN_IFDEF:
- if (verbose) fprintf(stderr, "%s #ifdef ", filename);
- lexer.Lex();
- if (lexer.GetToken() == TOKEN_IDENTIFIER) {
- bool value = defines.find(lexer.GetString()) != defines.end();
- if (verbose) fprintf(stderr, "%s[%d]", lexer.GetString(), value);
- if (ignore.empty() || ignore.top() == NOT_IGNORE) {
- ignore.push(value ? NOT_IGNORE : IGNORE_UNTIL_ELSE);
- } else {
- ignore.push(IGNORE_UNTIL_ENDIF);
- }
- }
- if (verbose) fprintf(stderr, " -> %signore", (!ignore.empty() && ignore.top() != NOT_IGNORE) ? "" : "not ");
- break;
-
- case TOKEN_IFNDEF:
- if (verbose) fprintf(stderr, "%s #ifndef ", filename);
- lexer.Lex();
- if (lexer.GetToken() == TOKEN_IDENTIFIER) {
- bool value = defines.find(lexer.GetString()) != defines.end();
- if (verbose) fprintf(stderr, "%s[%d]", lexer.GetString(), value);
- if (ignore.empty() || ignore.top() == NOT_IGNORE) {
- ignore.push(!value ? NOT_IGNORE : IGNORE_UNTIL_ELSE);
- } else {
- ignore.push(IGNORE_UNTIL_ENDIF);
- }
- }
- if (verbose) fprintf(stderr, " -> %signore", (!ignore.empty() && ignore.top() != NOT_IGNORE) ? "" : "not ");
- break;
-
- default:
- if (verbose) fprintf(stderr, "%s #<unknown>", filename);
- lexer.Lex();
- break;
- }
- if (verbose) fprintf(stderr, "\n");
- /* FALL THROUGH */
- default:
- /* Ignore the rest of the garbage on this line */
- while (lexer.GetToken() != TOKEN_EOL && lexer.GetToken() != TOKEN_END) lexer.Lex();
- lexer.Lex();
- break;
- }
- }
-
- if (!header) {
- for (StringSet::iterator it = defines.begin(); it != defines.end(); it++) {
- free(*it);
- }
- defines.clear();
- while (!ignore.empty()) ignore.pop();
- }
-}
-
-/**
- * Entry point. Arguably the most common function in all applications.
- * @param argc the number of arguments.
- * @param argv the actual arguments.
- * @return return value for the caller to tell we succeed or not.
- */
-int main(int argc, char *argv[])
-{
- bool ignorenext = true;
- char *filename = nullptr;
- char *ext = nullptr;
- char *delimiter = nullptr;
- bool append = false;
- bool verbose = false;
-
- for (int i = 0; i < argc; i++) {
- if (ignorenext) {
- ignorenext = false;
- continue;
- }
- if (argv[i][0] == '-') {
- /* Append */
- if (strncmp(argv[i], "-a", 2) == 0) append = true;
- /* Include dir */
- if (strncmp(argv[i], "-I", 2) == 0) {
- if (argv[i][2] == '\0') {
- i++;
- _include_dirs.insert(strdup(argv[i]));
- } else {
- _include_dirs.insert(strdup(&argv[i][2]));
- }
- continue;
- }
- /* Define */
- if (strncmp(argv[i], "-D", 2) == 0) {
- char *p = strchr(argv[i], '=');
- if (p != nullptr) *p = '\0';
- _defines.insert(strdup(&argv[i][2]));
- continue;
- }
- /* Output file */
- if (strncmp(argv[i], "-f", 2) == 0) {
- if (filename != nullptr) continue;
- filename = strdup(&argv[i][2]);
- continue;
- }
- /* Object file extension */
- if (strncmp(argv[i], "-o", 2) == 0) {
- if (ext != nullptr) continue;
- ext = strdup(&argv[i][2]);
- continue;
- }
- /* Starting string delimiter */
- if (strncmp(argv[i], "-s", 2) == 0) {
- if (delimiter != nullptr) continue;
- delimiter = strdup(&argv[i][2]);
- continue;
- }
- /* Verbose */
- if (strncmp(argv[i], "-v", 2) == 0) verbose = true;
- continue;
- }
- ScanFile(argv[i], ext, false, verbose);
- }
-
- /* Default output file is Makefile */
- if (filename == nullptr) filename = strdup("Makefile");
-
- /* Default delimiter string */
- if (delimiter == nullptr) delimiter = strdup("# DO NOT DELETE");
-
- char backup[PATH_MAX];
- strecpy(backup, filename, lastof(backup));
- strecat(backup, ".bak", lastof(backup));
-
- char *content = nullptr;
- long size = 0;
-
- /* Read in the current file; so we can overwrite everything from the
- * end of non-depend data marker down till the end. */
- FILE *src = fopen(filename, "rb");
- if (src != nullptr) {
- fseek(src, 0, SEEK_END);
- if ((size = ftell(src)) < 0) {
- fprintf(stderr, "Could not read %s\n", filename);
- exit(-2);
- }
- rewind(src);
- content = (char*)malloc(size * sizeof(*content));
- if (fread(content, 1, size, src) != (size_t)size) {
- fprintf(stderr, "Could not read %s\n", filename);
- exit(-2);
- }
- fclose(src);
- }
-
- FILE *dst = fopen(filename, "w");
- bool found_delimiter = false;
-
- if (size != 0) {
- src = fopen(backup, "wb");
- if (fwrite(content, 1, size, src) != (size_t)size) {
- fprintf(stderr, "Could not write %s\n", filename);
- exit(-2);
- }
- fclose(src);
-
- /* Then append it to the real file. */
- src = fopen(backup, "r");
- while (fgets(content, size, src) != nullptr) {
- fputs(content, dst);
- if (!strncmp(content, delimiter, strlen(delimiter))) found_delimiter = true;
- if (!append && found_delimiter) break;
- }
- fclose(src);
- }
- if (!found_delimiter) fprintf(dst, "\n%s\n", delimiter);
-
- for (StringMap::iterator it = _files.begin(); it != _files.end(); it++) {
- for (StringSet::iterator h = it->second->begin(); h != it->second->end(); h++) {
- fprintf(dst, "%s: %s\n", it->first, *h);
- }
- }
-
- /* Clean up our mess. */
- fclose(dst);
-
- free(delimiter);
- free(filename);
- free(ext);
- free(content);
-
- for (StringMap::iterator it = _files.begin(); it != _files.end(); it++) {
- for (StringSet::iterator h = it->second->begin(); h != it->second->end(); h++) {
- free(*h);
- }
- it->second->clear();
- delete it->second;
- free(it->first);
- }
- _files.clear();
-
- for (StringMap::iterator it = _headers.begin(); it != _headers.end(); it++) {
- for (StringSet::iterator h = it->second->begin(); h != it->second->end(); h++) {
- free(*h);
- }
- it->second->clear();
- delete it->second;
- free(it->first);
- }
- _headers.clear();
-
- for (StringSet::iterator it = _defines.begin(); it != _defines.end(); it++) {
- free(*it);
- }
- _defines.clear();
-
- for (StringSet::iterator it = _include_dirs.begin(); it != _include_dirs.end(); it++) {
- free(*it);
- }
- _include_dirs.clear();
-
- return 0;
-}
diff --git a/src/game/CMakeLists.txt b/src/game/CMakeLists.txt
new file mode 100644
index 000000000..aafb5a7b8
--- /dev/null
+++ b/src/game/CMakeLists.txt
@@ -0,0 +1,14 @@
+add_files(
+ game.hpp
+ game_config.cpp
+ game_config.hpp
+ game_core.cpp
+ game_info.cpp
+ game_info.hpp
+ game_instance.cpp
+ game_instance.hpp
+ game_scanner.cpp
+ game_scanner.hpp
+ game_text.cpp
+ game_text.hpp
+)
diff --git a/src/lang/CMakeLists.txt b/src/lang/CMakeLists.txt
new file mode 100644
index 000000000..00b554126
--- /dev/null
+++ b/src/lang/CMakeLists.txt
@@ -0,0 +1,122 @@
+set(LANG_SOURCE_FILES
+ ${CMAKE_CURRENT_SOURCE_DIR}/afrikaans.txt
+ ${CMAKE_CURRENT_SOURCE_DIR}/arabic_egypt.txt
+ ${CMAKE_CURRENT_SOURCE_DIR}/basque.txt
+ ${CMAKE_CURRENT_SOURCE_DIR}/belarusian.txt
+ ${CMAKE_CURRENT_SOURCE_DIR}/brazilian_portuguese.txt
+ ${CMAKE_CURRENT_SOURCE_DIR}/bulgarian.txt
+ ${CMAKE_CURRENT_SOURCE_DIR}/catalan.txt
+ ${CMAKE_CURRENT_SOURCE_DIR}/croatian.txt
+ ${CMAKE_CURRENT_SOURCE_DIR}/czech.txt
+ ${CMAKE_CURRENT_SOURCE_DIR}/danish.txt
+ ${CMAKE_CURRENT_SOURCE_DIR}/dutch.txt
+ ${CMAKE_CURRENT_SOURCE_DIR}/english.txt
+ ${CMAKE_CURRENT_SOURCE_DIR}/english_AU.txt
+ ${CMAKE_CURRENT_SOURCE_DIR}/english_US.txt
+ ${CMAKE_CURRENT_SOURCE_DIR}/esperanto.txt
+ ${CMAKE_CURRENT_SOURCE_DIR}/estonian.txt
+ ${CMAKE_CURRENT_SOURCE_DIR}/faroese.txt
+ ${CMAKE_CURRENT_SOURCE_DIR}/finnish.txt
+ ${CMAKE_CURRENT_SOURCE_DIR}/french.txt
+ ${CMAKE_CURRENT_SOURCE_DIR}/gaelic.txt
+ ${CMAKE_CURRENT_SOURCE_DIR}/galician.txt
+ ${CMAKE_CURRENT_SOURCE_DIR}/german.txt
+ ${CMAKE_CURRENT_SOURCE_DIR}/greek.txt
+ ${CMAKE_CURRENT_SOURCE_DIR}/hebrew.txt
+ ${CMAKE_CURRENT_SOURCE_DIR}/hungarian.txt
+ ${CMAKE_CURRENT_SOURCE_DIR}/icelandic.txt
+ ${CMAKE_CURRENT_SOURCE_DIR}/indonesian.txt
+ ${CMAKE_CURRENT_SOURCE_DIR}/irish.txt
+ ${CMAKE_CURRENT_SOURCE_DIR}/italian.txt
+ ${CMAKE_CURRENT_SOURCE_DIR}/japanese.txt
+ ${CMAKE_CURRENT_SOURCE_DIR}/korean.txt
+ ${CMAKE_CURRENT_SOURCE_DIR}/latin.txt
+ ${CMAKE_CURRENT_SOURCE_DIR}/latvian.txt
+ ${CMAKE_CURRENT_SOURCE_DIR}/lithuanian.txt
+ ${CMAKE_CURRENT_SOURCE_DIR}/luxembourgish.txt
+ ${CMAKE_CURRENT_SOURCE_DIR}/malay.txt
+ ${CMAKE_CURRENT_SOURCE_DIR}/norwegian_bokmal.txt
+ ${CMAKE_CURRENT_SOURCE_DIR}/norwegian_nynorsk.txt
+ ${CMAKE_CURRENT_SOURCE_DIR}/polish.txt
+ ${CMAKE_CURRENT_SOURCE_DIR}/portuguese.txt
+ ${CMAKE_CURRENT_SOURCE_DIR}/romanian.txt
+ ${CMAKE_CURRENT_SOURCE_DIR}/russian.txt
+ ${CMAKE_CURRENT_SOURCE_DIR}/serbian.txt
+ ${CMAKE_CURRENT_SOURCE_DIR}/simplified_chinese.txt
+ ${CMAKE_CURRENT_SOURCE_DIR}/slovak.txt
+ ${CMAKE_CURRENT_SOURCE_DIR}/slovenian.txt
+ ${CMAKE_CURRENT_SOURCE_DIR}/spanish.txt
+ ${CMAKE_CURRENT_SOURCE_DIR}/spanish_MX.txt
+ ${CMAKE_CURRENT_SOURCE_DIR}/swedish.txt
+ ${CMAKE_CURRENT_SOURCE_DIR}/tamil.txt
+ ${CMAKE_CURRENT_SOURCE_DIR}/thai.txt
+ ${CMAKE_CURRENT_SOURCE_DIR}/traditional_chinese.txt
+ ${CMAKE_CURRENT_SOURCE_DIR}/turkish.txt
+ ${CMAKE_CURRENT_SOURCE_DIR}/ukrainian.txt
+ ${CMAKE_CURRENT_SOURCE_DIR}/vietnamese.txt
+ ${CMAKE_CURRENT_SOURCE_DIR}/welsh.txt
+)
+
+set(LANG_BINARY_DIR ${CMAKE_BINARY_DIR}/lang)
+
+# Walk over all the (finished) language files, and generate a command to compile them
+foreach(LANG_SOURCE_FILE IN LISTS LANG_SOURCE_FILES)
+ get_filename_component(LANG_SOURCE_FILE_NAME_WE ${LANG_SOURCE_FILE} NAME_WE)
+
+ set(LANG_BINARY_FILE ${LANG_BINARY_DIR}/${LANG_SOURCE_FILE_NAME_WE}.lng)
+
+ add_custom_command(OUTPUT ${LANG_BINARY_FILE}
+ COMMAND ${CMAKE_COMMAND} -E make_directory ${LANG_BINARY_DIR}
+ COMMAND strgen
+ -s ${CMAKE_CURRENT_SOURCE_DIR}
+ -d ${LANG_BINARY_DIR}
+ ${LANG_SOURCE_FILE}
+ DEPENDS strgen
+ MAIN_DEPENDENCY ${LANG_SOURCE_FILE}
+ WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+ COMMENT "Compiling language ${LANG_SOURCE_FILE_NAME_WE}"
+ )
+
+ list(APPEND LANG_BINARY_FILES ${LANG_BINARY_FILE})
+endforeach(LANG_SOURCE_FILE)
+
+# Create a new target which compiles all language files
+add_custom_target(language_files
+ DEPENDS
+ ${LANG_BINARY_FILES}
+)
+set_target_properties(language_files
+ PROPERTIES LANG_SOURCE_FILES "${LANG_SOURCE_FILES}"
+)
+
+
+set(GENERATED_BINARY_DIR ${CMAKE_BINARY_DIR}/generated)
+set(TABLE_BINARY_DIR ${GENERATED_BINARY_DIR}/table)
+
+# Generate a command and target to create the strings table
+add_custom_command_timestamp(OUTPUT ${TABLE_BINARY_DIR}/strings.h
+ COMMAND ${CMAKE_COMMAND} -E make_directory ${TABLE_BINARY_DIR}
+ COMMAND strgen
+ -s ${CMAKE_CURRENT_SOURCE_DIR}
+ -d ${TABLE_BINARY_DIR}
+ DEPENDS strgen ${LANG_SOURCE_FILES}
+ WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+ COMMENT "Generating table/strings.h"
+)
+add_custom_target_timestamp(table_strings
+ DEPENDS
+ ${TABLE_BINARY_DIR}/strings.h
+)
+
+add_library(languages
+ INTERFACE
+)
+target_include_directories(languages
+ INTERFACE
+ ${GENERATED_BINARY_DIR}
+)
+add_dependencies(languages
+ language_files
+ table_strings
+)
+add_library(openttd::languages ALIAS languages)
diff --git a/src/linkgraph/CMakeLists.txt b/src/linkgraph/CMakeLists.txt
new file mode 100644
index 000000000..c3d73a15e
--- /dev/null
+++ b/src/linkgraph/CMakeLists.txt
@@ -0,0 +1,22 @@
+add_files(
+ demands.cpp
+ demands.h
+ flowmapper.cpp
+ flowmapper.h
+ init.h
+ linkgraph.cpp
+ linkgraph.h
+ linkgraph_base.h
+ linkgraph_gui.cpp
+ linkgraph_gui.h
+ linkgraph_type.h
+ linkgraphjob.cpp
+ linkgraphjob.h
+ linkgraphjob_base.h
+ linkgraphschedule.cpp
+ linkgraphschedule.h
+ mcf.cpp
+ mcf.h
+ refresh.cpp
+ refresh.h
+)
diff --git a/src/misc/CMakeLists.txt b/src/misc/CMakeLists.txt
new file mode 100644
index 000000000..3a5363e7b
--- /dev/null
+++ b/src/misc/CMakeLists.txt
@@ -0,0 +1,14 @@
+add_files(
+ array.hpp
+ binaryheap.hpp
+ blob.hpp
+ countedobj.cpp
+ countedptr.hpp
+ dbg_helpers.cpp
+ dbg_helpers.h
+ fixedsizearray.hpp
+ getoptdata.cpp
+ getoptdata.h
+ hashtable.hpp
+ str.hpp
+)
diff --git a/src/music/CMakeLists.txt b/src/music/CMakeLists.txt
new file mode 100644
index 000000000..0ae15fde2
--- /dev/null
+++ b/src/music/CMakeLists.txt
@@ -0,0 +1,54 @@
+if (NOT OPTION_DEDICATED)
+ add_files(
+ allegro_m.cpp
+ allegro_m.h
+ CONDITION Allegro_FOUND
+ )
+
+ add_files(
+ fluidsynth.cpp
+ fluidsynth.h
+ CONDITION Fluidsynth_FOUND
+ )
+
+ add_files(
+ cocoa_m.cpp
+ cocoa_m.h
+ CONDITION APPLE
+ )
+
+ add_files(
+ dmusic.cpp
+ dmusic.h
+ win32_m.cpp
+ win32_m.h
+ CONDITION WIN32
+ )
+
+ add_files(
+ extmidi.cpp
+ extmidi.h
+ CONDITION UNIX
+ )
+
+ add_files(
+ bemidi.cpp
+ bemidi.h
+ CONDITION OPTION_HAIKU
+ )
+
+ add_files(
+ os2_m.cpp
+ os2_m.h
+ CONDITION OPTION_OS2
+ )
+endif (NOT OPTION_DEDICATED)
+
+add_files(
+ midi.h
+ midifile.cpp
+ midifile.hpp
+ music_driver.hpp
+ null_m.cpp
+ null_m.h
+)
diff --git a/src/network/CMakeLists.txt b/src/network/CMakeLists.txt
new file mode 100644
index 000000000..1c27d6206
--- /dev/null
+++ b/src/network/CMakeLists.txt
@@ -0,0 +1,28 @@
+add_subdirectory(core)
+
+add_files(
+ network.cpp
+ network.h
+ network_admin.cpp
+ network_admin.h
+ network_base.h
+ network_chat_gui.cpp
+ network_client.cpp
+ network_client.h
+ network_command.cpp
+ network_content.cpp
+ network_content.h
+ network_content_gui.cpp
+ network_content_gui.h
+ network_func.h
+ network_gamelist.cpp
+ network_gamelist.h
+ network_gui.cpp
+ network_gui.h
+ network_internal.h
+ network_server.cpp
+ network_server.h
+ network_type.h
+ network_udp.cpp
+ network_udp.h
+)
diff --git a/src/network/core/CMakeLists.txt b/src/network/core/CMakeLists.txt
new file mode 100644
index 000000000..777d15d84
--- /dev/null
+++ b/src/network/core/CMakeLists.txt
@@ -0,0 +1,27 @@
+add_files(
+ address.cpp
+ address.h
+ config.h
+ core.cpp
+ core.h
+ game.h
+ host.cpp
+ host.h
+ os_abstraction.h
+ packet.cpp
+ packet.h
+ tcp.cpp
+ tcp.h
+ tcp_admin.cpp
+ tcp_admin.h
+ tcp_connect.cpp
+ tcp_content.cpp
+ tcp_content.h
+ tcp_game.cpp
+ tcp_game.h
+ tcp_http.cpp
+ tcp_http.h
+ tcp_listen.h
+ udp.cpp
+ udp.h
+)
diff --git a/src/os/CMakeLists.txt b/src/os/CMakeLists.txt
new file mode 100644
index 000000000..e302c448b
--- /dev/null
+++ b/src/os/CMakeLists.txt
@@ -0,0 +1,4 @@
+add_subdirectory(macosx)
+add_subdirectory(os2)
+add_subdirectory(unix)
+add_subdirectory(windows)
diff --git a/src/os/macosx/CMakeLists.txt b/src/os/macosx/CMakeLists.txt
new file mode 100644
index 000000000..e6b6c237b
--- /dev/null
+++ b/src/os/macosx/CMakeLists.txt
@@ -0,0 +1,11 @@
+add_files(
+ crashlog_osx.cpp
+ macos.h
+ macos.mm
+ osx_stdafx.h
+ splash.cpp
+ splash.h
+ string_osx.cpp
+ string_osx.h
+ CONDITION APPLE
+)
diff --git a/src/os/os2/CMakeLists.txt b/src/os/os2/CMakeLists.txt
new file mode 100644
index 000000000..52534dbcb
--- /dev/null
+++ b/src/os/os2/CMakeLists.txt
@@ -0,0 +1,4 @@
+add_files(
+ os2.cpp
+ CONDITION OPTION_OS2
+)
diff --git a/src/os/unix/CMakeLists.txt b/src/os/unix/CMakeLists.txt
new file mode 100644
index 000000000..b548d3bb2
--- /dev/null
+++ b/src/os/unix/CMakeLists.txt
@@ -0,0 +1,9 @@
+add_files(
+ crashlog_unix.cpp
+ CONDITION UNIX AND NOT APPLE AND NOT OPTION_OS2
+)
+
+add_files(
+ unix.cpp
+ CONDITION UNIX AND NOT OPTION_OS2
+)
diff --git a/src/os/windows/CMakeLists.txt b/src/os/windows/CMakeLists.txt
new file mode 100644
index 000000000..19d1bd46e
--- /dev/null
+++ b/src/os/windows/CMakeLists.txt
@@ -0,0 +1,8 @@
+add_files(
+ crashlog_win.cpp
+ string_uniscribe.cpp
+ string_uniscribe.h
+ win32.cpp
+ win32.h
+ CONDITION WIN32
+)
diff --git a/src/os/windows/ottdres.rc.in b/src/os/windows/ottdres.rc.in
index a2f8c28f5..741fa0e10 100644
--- a/src/os/windows/ottdres.rc.in
+++ b/src/os/windows/ottdres.rc.in
@@ -37,7 +37,7 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_DEFAULT
// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.
-100 ICON DISCARDABLE "../../../media/openttd.ico"
+100 ICON DISCARDABLE "${CMAKE_SOURCE_DIR}/os/windows/openttd.ico"
/////////////////////////////////////////////////////////////////////////////
//
@@ -77,8 +77,8 @@ END
//
VS_VERSION_INFO VERSIONINFO
- FILEVERSION 1,11,0,!!ISODATE!!
- PRODUCTVERSION 1,11,0,!!ISODATE!!
+ FILEVERSION 1,11,0,${REV_ISODATE}
+ PRODUCTVERSION 1,11,0,${REV_ISODATE}
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
@@ -96,14 +96,14 @@ BEGIN
VALUE "Comments", "This program is licensed under the GNU General Public License version 2.\0"
VALUE "CompanyName", "OpenTTD Development Team\0"
VALUE "FileDescription", "OpenTTD\0"
- VALUE "FileVersion", "!!VERSION!!\0"
+ VALUE "FileVersion", "${REV_VERSION}\0"
VALUE "InternalName", "openttd\0"
- VALUE "LegalCopyright", "Copyright \xA9 OpenTTD Developers 2002-!!YEAR!!. All Rights Reserved.\0"
+ VALUE "LegalCopyright", "Copyright \xA9 OpenTTD Developers 2002-${REV_YEAR}. All Rights Reserved.\0"
VALUE "LegalTrademarks", "\0"
VALUE "OriginalFilename", "openttd.exe\0"
VALUE "PrivateBuild", "\0"
VALUE "ProductName", "OpenTTD\0"
- VALUE "ProductVersion", "!!VERSION!!\0"
+ VALUE "ProductVersion", "${REV_VERSION}\0"
VALUE "SpecialBuild", "-\0"
END
END
@@ -116,7 +116,7 @@ END
#endif // !_MAC
#ifdef __MINGW32__
-1 24 "..\\..\\..\\projects\\dpi_aware.manifest"
+1 24 "${CMAKE_SOURCE_DIR}/os/windows/openttd.manifest"
#endif
#endif // Neutral (Default) resources
diff --git a/src/pathfinder/CMakeLists.txt b/src/pathfinder/CMakeLists.txt
new file mode 100644
index 000000000..2e275706f
--- /dev/null
+++ b/src/pathfinder/CMakeLists.txt
@@ -0,0 +1,9 @@
+add_subdirectory(npf)
+add_subdirectory(yapf)
+
+add_files(
+ follow_track.hpp
+ pathfinder_func.h
+ pathfinder_type.h
+ pf_performance_timer.hpp
+)
diff --git a/src/pathfinder/npf/CMakeLists.txt b/src/pathfinder/npf/CMakeLists.txt
new file mode 100644
index 000000000..e3ace57e5
--- /dev/null
+++ b/src/pathfinder/npf/CMakeLists.txt
@@ -0,0 +1,8 @@
+add_files(
+ aystar.cpp
+ aystar.h
+ npf.cpp
+ npf_func.h
+ queue.cpp
+ queue.h
+)
diff --git a/src/pathfinder/yapf/CMakeLists.txt b/src/pathfinder/yapf/CMakeLists.txt
new file mode 100644
index 000000000..170c1ad61
--- /dev/null
+++ b/src/pathfinder/yapf/CMakeLists.txt
@@ -0,0 +1,20 @@
+add_files(
+ nodelist.hpp
+ yapf.h
+ yapf.hpp
+ yapf_base.hpp
+ yapf_cache.h
+ yapf_common.hpp
+ yapf_costbase.hpp
+ yapf_costcache.hpp
+ yapf_costrail.hpp
+ yapf_destrail.hpp
+ yapf_node.hpp
+ yapf_node_rail.hpp
+ yapf_node_road.hpp
+ yapf_node_ship.hpp
+ yapf_rail.cpp
+ yapf_road.cpp
+ yapf_ship.cpp
+ yapf_type.hpp
+)
diff --git a/src/rev.cpp.in b/src/rev.cpp.in
index 3f5b126dc..16c403a67 100644
--- a/src/rev.cpp.in
+++ b/src/rev.cpp.in
@@ -35,7 +35,7 @@ bool IsReleasedVersion()
*
* <modified> shows a "M", if the binary is made from modified source code.
*/
-const char _openttd_revision[] = "!!VERSION!!";
+const char _openttd_revision[] = "${REV_VERSION}";
/**
* The text version of OpenTTD's build date.
@@ -48,12 +48,12 @@ const char _openttd_build_date[] = __DATE__ " " __TIME__;
/**
* The git revision hash of this version.
*/
-const char _openttd_revision_hash[] = "!!GITHASH!!";
+const char _openttd_revision_hash[] = "${REV_HASH}";
/**
* The year of this version.
*/
-const char _openttd_revision_year[] = "!!YEAR!!";
+const char _openttd_revision_year[] = "${REV_YEAR}";
/**
* Let us know if current build was modified. This detection
@@ -63,14 +63,14 @@ const char _openttd_revision_year[] = "!!YEAR!!";
* (compiling from sources without any version control software)
* and 2 is for modified revision.
*/
-const byte _openttd_revision_modified = !!MODIFIED!!;
+const byte _openttd_revision_modified = ${REV_MODIFIED};
/**
* Indicate whether this is a tagged version.
* If this is non-0, then _openttd_revision is the name of the tag,
* and the version is likely a beta, release candidate, or real release.
*/
-const byte _openttd_revision_tagged = !!ISTAG!!;
+const byte _openttd_revision_tagged = ${REV_ISTAG};
/**
* The NewGRF revision of OTTD:
@@ -85,4 +85,4 @@ const byte _openttd_revision_tagged = !!ISTAG!!;
* final release will always have a lower version number than the released
* version, thus making comparisons on specific revisions easy.
*/
-const uint32 _openttd_newgrf_version = 1 << 28 | 11 << 24 | 0 << 20 | !!ISSTABLETAG!! << 19 | 28004;
+const uint32 _openttd_newgrf_version = 1 << 28 | 11 << 24 | 0 << 20 | ${REV_ISSTABLETAG} << 19 | 28004;
diff --git a/src/saveload/CMakeLists.txt b/src/saveload/CMakeLists.txt
new file mode 100644
index 000000000..52f103fa7
--- /dev/null
+++ b/src/saveload/CMakeLists.txt
@@ -0,0 +1,43 @@
+add_files(
+ afterload.cpp
+ ai_sl.cpp
+ airport_sl.cpp
+ animated_tile_sl.cpp
+ autoreplace_sl.cpp
+ cargomonitor_sl.cpp
+ cargopacket_sl.cpp
+ cheat_sl.cpp
+ company_sl.cpp
+ depot_sl.cpp
+ economy_sl.cpp
+ engine_sl.cpp
+ game_sl.cpp
+ gamelog_sl.cpp
+ goal_sl.cpp
+ group_sl.cpp
+ industry_sl.cpp
+ labelmaps_sl.cpp
+ linkgraph_sl.cpp
+ map_sl.cpp
+ misc_sl.cpp
+ newgrf_sl.cpp
+ newgrf_sl.h
+ object_sl.cpp
+ oldloader.cpp
+ oldloader.h
+ oldloader_sl.cpp
+ order_sl.cpp
+ saveload.cpp
+ saveload.h
+ saveload_filter.h
+ saveload_internal.h
+ signs_sl.cpp
+ station_sl.cpp
+ storage_sl.cpp
+ strings_sl.cpp
+ story_sl.cpp
+ subsidy_sl.cpp
+ town_sl.cpp
+ vehicle_sl.cpp
+ waypoint_sl.cpp
+)
diff --git a/src/script/CMakeLists.txt b/src/script/CMakeLists.txt
new file mode 100644
index 000000000..e5915332c
--- /dev/null
+++ b/src/script/CMakeLists.txt
@@ -0,0 +1,23 @@
+add_subdirectory(api)
+
+add_files(
+ script_config.cpp
+ script_config.hpp
+ script_fatalerror.hpp
+ script_info.cpp
+ script_info.hpp
+ script_info_dummy.cpp
+ script_instance.cpp
+ script_instance.hpp
+ script_scanner.cpp
+ script_scanner.hpp
+ script_storage.hpp
+ script_suspend.hpp
+ squirrel.cpp
+ squirrel.hpp
+ squirrel_class.hpp
+ squirrel_helper.hpp
+ squirrel_helper_type.hpp
+ squirrel_std.cpp
+ squirrel_std.hpp
+)
diff --git a/src/script/api/CMakeLists.txt b/src/script/api/CMakeLists.txt
new file mode 100644
index 000000000..9c665293c
--- /dev/null
+++ b/src/script/api/CMakeLists.txt
@@ -0,0 +1,140 @@
+add_files(
+ ai_changelog.hpp
+ game_changelog.hpp
+ script_accounting.hpp
+ script_admin.hpp
+ script_airport.hpp
+ script_base.hpp
+ script_basestation.hpp
+ script_bridge.hpp
+ script_bridgelist.hpp
+ script_cargo.hpp
+ script_cargolist.hpp
+ script_cargomonitor.hpp
+ script_client.hpp
+ script_clientlist.hpp
+ script_company.hpp
+ script_companymode.hpp
+ script_controller.hpp
+ script_date.hpp
+ script_depotlist.hpp
+ script_engine.hpp
+ script_enginelist.hpp
+ script_error.hpp
+ script_event.hpp
+ script_event_types.hpp
+ script_execmode.hpp
+ script_game.hpp
+ script_gamesettings.hpp
+ script_goal.hpp
+ script_group.hpp
+ script_grouplist.hpp
+ script_industry.hpp
+ script_industrylist.hpp
+ script_industrytype.hpp
+ script_industrytypelist.hpp
+ script_info_docs.hpp
+ script_infrastructure.hpp
+ script_list.hpp
+ script_log.hpp
+ script_map.hpp
+ script_marine.hpp
+ script_news.hpp
+ script_object.hpp
+ script_order.hpp
+ script_priorityqueue.hpp
+ script_rail.hpp
+ script_railtypelist.hpp
+ script_road.hpp
+ script_roadtypelist.hpp
+ script_sign.hpp
+ script_signlist.hpp
+ script_station.hpp
+ script_stationlist.hpp
+ script_story_page.hpp
+ script_storypagelist.hpp
+ script_storypageelementlist.hpp
+ script_subsidy.hpp
+ script_subsidylist.hpp
+ script_testmode.hpp
+ script_text.hpp
+ script_tile.hpp
+ script_tilelist.hpp
+ script_town.hpp
+ script_townlist.hpp
+ script_tunnel.hpp
+ script_types.hpp
+ script_vehicle.hpp
+ script_vehiclelist.hpp
+ script_viewport.hpp
+ script_waypoint.hpp
+ script_waypointlist.hpp
+ script_window.hpp
+ script_accounting.cpp
+ script_admin.cpp
+ script_airport.cpp
+ script_base.cpp
+ script_basestation.cpp
+ script_bridge.cpp
+ script_bridgelist.cpp
+ script_cargo.cpp
+ script_cargolist.cpp
+ script_cargomonitor.cpp
+ script_client.cpp
+ script_clientlist.cpp
+ script_company.cpp
+ script_companymode.cpp
+ script_controller.cpp
+ script_date.cpp
+ script_depotlist.cpp
+ script_engine.cpp
+ script_enginelist.cpp
+ script_error.cpp
+ script_event.cpp
+ script_event_types.cpp
+ script_execmode.cpp
+ script_game.cpp
+ script_gamesettings.cpp
+ script_goal.cpp
+ script_group.cpp
+ script_grouplist.cpp
+ script_industry.cpp
+ script_industrylist.cpp
+ script_industrytype.cpp
+ script_industrytypelist.cpp
+ script_infrastructure.cpp
+ script_list.cpp
+ script_log.cpp
+ script_map.cpp
+ script_marine.cpp
+ script_news.cpp
+ script_object.cpp
+ script_order.cpp
+ script_priorityqueue.cpp
+ script_rail.cpp
+ script_railtypelist.cpp
+ script_road.cpp
+ script_roadtypelist.cpp
+ script_sign.cpp
+ script_signlist.cpp
+ script_station.cpp
+ script_stationlist.cpp
+ script_story_page.cpp
+ script_storypagelist.cpp
+ script_storypageelementlist.cpp
+ script_subsidy.cpp
+ script_subsidylist.cpp
+ script_testmode.cpp
+ script_text.cpp
+ script_tile.cpp
+ script_tilelist.cpp
+ script_town.cpp
+ script_townlist.cpp
+ script_tunnel.cpp
+ script_vehicle.cpp
+ script_vehiclelist.cpp
+ script_viewport.cpp
+ script_waypoint.cpp
+ script_waypointlist.cpp
+ script_window.cpp
+)
diff --git a/src/settingsgen/CMakeLists.txt b/src/settingsgen/CMakeLists.txt
new file mode 100644
index 000000000..e17b8ad6b
--- /dev/null
+++ b/src/settingsgen/CMakeLists.txt
@@ -0,0 +1,13 @@
+cmake_minimum_required(VERSION 3.5)
+
+project(settingsgen)
+
+set(sourcefiles
+ settingsgen.cpp
+ ../core/alloc_func.cpp
+ ../misc/getoptdata.cpp
+ ../ini_load.cpp
+ ../string.cpp
+)
+add_definitions(-DSETTINGSGEN)
+add_executable(settingsgen ${sourcefiles})
diff --git a/src/sound/CMakeLists.txt b/src/sound/CMakeLists.txt
new file mode 100644
index 000000000..35f65d120
--- /dev/null
+++ b/src/sound/CMakeLists.txt
@@ -0,0 +1,37 @@
+if (NOT OPTION_DEDICATED)
+ add_files(
+ allegro_s.cpp
+ allegro_s.h
+ CONDITION Allegro_FOUND
+ )
+
+ add_files(
+ sdl_s.cpp
+ sdl_s.h
+ CONDITION SDL_FOUND
+ )
+
+ add_files(
+ cocoa_s.cpp
+ cocoa_s.h
+ CONDITION APPLE
+ )
+
+ add_files(
+ win32_s.cpp
+ win32_s.h
+ CONDITION WIN32
+ )
+
+ add_files(
+ xaudio2_s.cpp
+ xaudio2_s.h
+ CONDITION WIN32 AND XAUDIO2_FOUND
+ )
+endif (NOT OPTION_DEDICATED)
+
+add_files(
+ sound_driver.hpp
+ null_s.cpp
+ null_s.h
+)
diff --git a/src/spriteloader/CMakeLists.txt b/src/spriteloader/CMakeLists.txt
new file mode 100644
index 000000000..5d6a2f865
--- /dev/null
+++ b/src/spriteloader/CMakeLists.txt
@@ -0,0 +1,5 @@
+add_files(
+ grf.cpp
+ grf.hpp
+ spriteloader.hpp
+)
diff --git a/src/stdafx.h b/src/stdafx.h
index 4fb84a956..c52092553 100644
--- a/src/stdafx.h
+++ b/src/stdafx.h
@@ -424,17 +424,14 @@ void NORETURN CDECL usererror(const char *str, ...) WARN_FORMAT(1, 2);
void NORETURN CDECL error(const char *str, ...) WARN_FORMAT(1, 2);
#define NOT_REACHED() error("NOT_REACHED triggered at line %i of %s", __LINE__, __FILE__)
-/* For non-debug builds with assertions enabled use the special assertion handler:
- * - For MSVC: NDEBUG is set for all release builds and WITH_ASSERT overrides the disabling of asserts.
- * - For non MSVC: NDEBUG is set when assertions are disables, _DEBUG is set for non-release builds.
- */
-#if (defined(_MSC_VER) && defined(NDEBUG) && defined(WITH_ASSERT)) || (!defined(_MSC_VER) && !defined(NDEBUG) && !defined(_DEBUG))
+/* For non-debug builds with assertions enabled use the special assertion handler. */
+#if defined(NDEBUG) && defined(WITH_ASSERT)
#undef assert
#define assert(expression) if (!(expression)) error("Assertion failed at line %i of %s: %s", __LINE__, __FILE__, #expression);
#endif
-/* Asserts are enabled if NDEBUG isn't defined, or if we are using MSVC and WITH_ASSERT is defined. */
-#if !defined(NDEBUG) || (defined(_MSC_VER) && defined(WITH_ASSERT))
+/* Asserts are enabled if NDEBUG isn't defined or WITH_ASSERT is defined. */
+#if !defined(NDEBUG) || defined(WITH_ASSERT)
#define OTTD_ASSERT
#endif
diff --git a/src/strgen/CMakeLists.txt b/src/strgen/CMakeLists.txt
new file mode 100644
index 000000000..b8f61cde3
--- /dev/null
+++ b/src/strgen/CMakeLists.txt
@@ -0,0 +1,25 @@
+cmake_minimum_required(VERSION 3.5)
+
+project(strgen)
+
+set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/../../cmake")
+
+set(sourcefiles
+ strgen.cpp
+ strgen_base.cpp
+ ../core/alloc_func.cpp
+ ../misc/getoptdata.cpp
+ ../string.cpp
+)
+add_definitions(-DSTRGEN)
+add_executable(strgen ${sourcefiles})
+
+include(Endian)
+add_endian_definition()
+
+
+# Source Files
+add_files(strgen_base.cpp)
+
+# Header Files
+add_files(strgen.h)
diff --git a/src/table/CMakeLists.txt b/src/table/CMakeLists.txt
new file mode 100644
index 000000000..23b4724e3
--- /dev/null
+++ b/src/table/CMakeLists.txt
@@ -0,0 +1,83 @@
+set(GENERATED_BINARY_DIR ${CMAKE_BINARY_DIR}/generated)
+set(TABLE_BINARY_DIR ${GENERATED_BINARY_DIR}/table)
+
+set(TABLE_INI_SOURCE_FILES
+ ${CMAKE_CURRENT_SOURCE_DIR}/company_settings.ini
+ ${CMAKE_CURRENT_SOURCE_DIR}/currency_settings.ini
+ ${CMAKE_CURRENT_SOURCE_DIR}/gameopt_settings.ini
+ ${CMAKE_CURRENT_SOURCE_DIR}/misc_settings.ini
+ ${CMAKE_CURRENT_SOURCE_DIR}/settings.ini
+ ${CMAKE_CURRENT_SOURCE_DIR}/win32_settings.ini
+ ${CMAKE_CURRENT_SOURCE_DIR}/window_settings.ini
+)
+
+# Generate a command and target to create the settings table
+add_custom_command_timestamp(OUTPUT ${TABLE_BINARY_DIR}/settings.h
+ COMMAND ${CMAKE_COMMAND} -E make_directory ${TABLE_BINARY_DIR}
+ COMMAND settingsgen
+ -o ${TABLE_BINARY_DIR}/settings.h
+ -b ${CMAKE_SOURCE_DIR}/src/table/settings.h.preamble
+ -a ${CMAKE_SOURCE_DIR}/src/table/settings.h.postamble
+ ${TABLE_INI_SOURCE_FILES}
+ DEPENDS settingsgen ${TABLE_INI_SOURCE_FILES}
+ ${CMAKE_SOURCE_DIR}/src/table/settings.h.preamble
+ ${CMAKE_SOURCE_DIR}/src/table/settings.h.postamble
+ WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+ COMMENT "Generating table/settings.h"
+)
+add_custom_target_timestamp(table_settings
+ DEPENDS
+ ${TABLE_BINARY_DIR}/settings.h
+)
+
+add_library(settings
+ INTERFACE
+)
+target_include_directories(settings
+ INTERFACE
+ ${GENERATED_BINARY_DIR}
+)
+add_dependencies(settings
+ table_settings
+)
+add_library(openttd::settings ALIAS settings)
+
+add_files(
+ airport_defaults.h
+ airport_movement.h
+ airporttile_ids.h
+ airporttiles.h
+ animcursors.h
+ autorail.h
+ bridge_land.h
+ build_industry.h
+ cargo_const.h
+ clear_land.h
+ control_codes.h
+ elrail_data.h
+ engines.h
+ genland.h
+ heightmap_colours.h
+ industry_land.h
+ landscape_sprite.h
+ newgrf_debug_data.h
+ object_land.h
+ palette_convert.h
+ palettes.h
+ pricebase.h
+ railtypes.h
+ road_land.h
+ roadtypes.h
+ roadveh_movement.h
+ sprites.h
+ station_land.h
+ strgen_tables.h
+ string_colours.h
+ town_land.h
+ townname.h
+ track_land.h
+ train_cmd.h
+ tree_land.h
+ unicode.h
+ water_land.h
+)
diff --git a/src/video/CMakeLists.txt b/src/video/CMakeLists.txt
new file mode 100644
index 000000000..c6251e939
--- /dev/null
+++ b/src/video/CMakeLists.txt
@@ -0,0 +1,35 @@
+add_subdirectory(cocoa)
+
+if (NOT OPTION_DEDICATED)
+ add_files(
+ allegro_v.cpp
+ allegro_v.h
+ CONDITION Allegro_FOUND
+ )
+
+ add_files(
+ sdl_v.cpp
+ sdl_v.h
+ CONDITION SDL_FOUND
+ )
+
+ add_files(
+ sdl2_v.cpp
+ sdl2_v.h
+ CONDITION SDL2_FOUND
+ )
+
+ add_files(
+ win32_v.cpp
+ win32_v.h
+ CONDITION WIN32
+ )
+endif (NOT OPTION_DEDICATED)
+
+add_files(
+ dedicated_v.cpp
+ dedicated_v.h
+ null_v.cpp
+ null_v.h
+ video_driver.hpp
+)
diff --git a/src/video/cocoa/CMakeLists.txt b/src/video/cocoa/CMakeLists.txt
new file mode 100644
index 000000000..4fff132f3
--- /dev/null
+++ b/src/video/cocoa/CMakeLists.txt
@@ -0,0 +1,8 @@
+add_files(
+ cocoa_keys.h
+ cocoa_v.h
+ cocoa_v.mm
+ event.mm
+ wnd_quartz.mm
+ CONDITION APPLE
+)
diff --git a/src/widgets/CMakeLists.txt b/src/widgets/CMakeLists.txt
new file mode 100644
index 000000000..18ecd529e
--- /dev/null
+++ b/src/widgets/CMakeLists.txt
@@ -0,0 +1,61 @@
+add_files(
+ ai_widget.h
+ airport_widget.h
+ autoreplace_widget.h
+ bootstrap_widget.h
+ bridge_widget.h
+ build_vehicle_widget.h
+ cheat_widget.h
+ company_widget.h
+ console_widget.h
+ date_widget.h
+ depot_widget.h
+ dock_widget.h
+ dropdown.cpp
+ dropdown_func.h
+ dropdown_type.h
+ dropdown_widget.h
+ engine_widget.h
+ error_widget.h
+ fios_widget.h
+ framerate_widget.h
+ genworld_widget.h
+ goal_widget.h
+ graph_widget.h
+ group_widget.h
+ highscore_widget.h
+ industry_widget.h
+ intro_widget.h
+ link_graph_legend_widget.h
+ main_widget.h
+ misc_widget.h
+ music_widget.h
+ network_chat_widget.h
+ network_content_widget.h
+ network_widget.h
+ newgrf_debug_widget.h
+ newgrf_widget.h
+ news_widget.h
+ object_widget.h
+ order_widget.h
+ osk_widget.h
+ rail_widget.h
+ road_widget.h
+ screenshot_widget.h
+ settings_widget.h
+ sign_widget.h
+ smallmap_widget.h
+ station_widget.h
+ statusbar_widget.h
+ story_widget.h
+ subsidy_widget.h
+ terraform_widget.h
+ timetable_widget.h
+ toolbar_widget.h
+ town_widget.h
+ transparency_widget.h
+ tree_widget.h
+ vehicle_widget.h
+ viewport_widget.h
+ waypoint_widget.h
+)